diff --git a/.loki/reference/chrome_iphone7_entities_Article_ArticleDetailsDeprecated_Error.png b/.loki/reference/chrome_iphone7_entities_Article_ArticleDetailsDeprecated_Error.png new file mode 100644 index 00000000..d69c3484 Binary files /dev/null and b/.loki/reference/chrome_iphone7_entities_Article_ArticleDetailsDeprecated_Error.png differ diff --git a/.loki/reference/chrome_iphone7_entities_Article_ArticleDetailsDeprecated_Loading.png b/.loki/reference/chrome_iphone7_entities_Article_ArticleDetailsDeprecated_Loading.png new file mode 100644 index 00000000..4145795e Binary files /dev/null and b/.loki/reference/chrome_iphone7_entities_Article_ArticleDetailsDeprecated_Loading.png differ diff --git a/.loki/reference/chrome_iphone7_entities_Article_ArticleDetailsDeprecated_Normal.png b/.loki/reference/chrome_iphone7_entities_Article_ArticleDetailsDeprecated_Normal.png new file mode 100644 index 00000000..5b670f98 Binary files /dev/null and b/.loki/reference/chrome_iphone7_entities_Article_ArticleDetailsDeprecated_Normal.png differ diff --git a/.loki/reference/chrome_iphone7_entities_Article_ArticleDetailsRedesigned_Error.png b/.loki/reference/chrome_iphone7_entities_Article_ArticleDetailsRedesigned_Error.png new file mode 100644 index 00000000..5cb82f00 Binary files /dev/null and b/.loki/reference/chrome_iphone7_entities_Article_ArticleDetailsRedesigned_Error.png differ diff --git a/.loki/reference/chrome_iphone7_entities_Article_ArticleDetailsRedesigned_Loading.png b/.loki/reference/chrome_iphone7_entities_Article_ArticleDetailsRedesigned_Loading.png new file mode 100644 index 00000000..843f49ad Binary files /dev/null and b/.loki/reference/chrome_iphone7_entities_Article_ArticleDetailsRedesigned_Loading.png differ diff --git a/.loki/reference/chrome_iphone7_entities_Article_ArticleDetailsRedesigned_Normal.png b/.loki/reference/chrome_iphone7_entities_Article_ArticleDetailsRedesigned_Normal.png new file mode 100644 index 00000000..e22c4f8f Binary files /dev/null and b/.loki/reference/chrome_iphone7_entities_Article_ArticleDetailsRedesigned_Normal.png differ diff --git a/.loki/reference/chrome_iphone7_shared_redesigned_Code_Normal.png b/.loki/reference/chrome_iphone7_shared_redesigned_Code_Normal.png new file mode 100644 index 00000000..892785eb Binary files /dev/null and b/.loki/reference/chrome_iphone7_shared_redesigned_Code_Normal.png differ diff --git a/.loki/reference/chrome_laptop_entities_Article_ArticleDetailsDeprecated_Error.png b/.loki/reference/chrome_laptop_entities_Article_ArticleDetailsDeprecated_Error.png new file mode 100644 index 00000000..967052a4 Binary files /dev/null and b/.loki/reference/chrome_laptop_entities_Article_ArticleDetailsDeprecated_Error.png differ diff --git a/.loki/reference/chrome_laptop_entities_Article_ArticleDetailsDeprecated_Loading.png b/.loki/reference/chrome_laptop_entities_Article_ArticleDetailsDeprecated_Loading.png new file mode 100644 index 00000000..a1adb65b Binary files /dev/null and b/.loki/reference/chrome_laptop_entities_Article_ArticleDetailsDeprecated_Loading.png differ diff --git a/.loki/reference/chrome_laptop_entities_Article_ArticleDetailsDeprecated_Normal.png b/.loki/reference/chrome_laptop_entities_Article_ArticleDetailsDeprecated_Normal.png new file mode 100644 index 00000000..30b7c5be Binary files /dev/null and b/.loki/reference/chrome_laptop_entities_Article_ArticleDetailsDeprecated_Normal.png differ diff --git a/.loki/reference/chrome_laptop_entities_Article_ArticleDetailsRedesigned_Error.png b/.loki/reference/chrome_laptop_entities_Article_ArticleDetailsRedesigned_Error.png new file mode 100644 index 00000000..6629a742 Binary files /dev/null and b/.loki/reference/chrome_laptop_entities_Article_ArticleDetailsRedesigned_Error.png differ diff --git a/.loki/reference/chrome_laptop_entities_Article_ArticleDetailsRedesigned_Loading.png b/.loki/reference/chrome_laptop_entities_Article_ArticleDetailsRedesigned_Loading.png new file mode 100644 index 00000000..95f8f73b Binary files /dev/null and b/.loki/reference/chrome_laptop_entities_Article_ArticleDetailsRedesigned_Loading.png differ diff --git a/.loki/reference/chrome_laptop_entities_Article_ArticleDetailsRedesigned_Normal.png b/.loki/reference/chrome_laptop_entities_Article_ArticleDetailsRedesigned_Normal.png new file mode 100644 index 00000000..4131326e Binary files /dev/null and b/.loki/reference/chrome_laptop_entities_Article_ArticleDetailsRedesigned_Normal.png differ diff --git a/.loki/reference/chrome_laptop_shared_redesigned_Code_Normal.png b/.loki/reference/chrome_laptop_shared_redesigned_Code_Normal.png new file mode 100644 index 00000000..a5391e86 Binary files /dev/null and b/.loki/reference/chrome_laptop_shared_redesigned_Code_Normal.png differ diff --git a/cypress/e2e/articles/article-details.cy.ts b/cypress/e2e/articles/article-details.cy.ts index 7f6d94a0..1af8844c 100644 --- a/cypress/e2e/articles/article-details.cy.ts +++ b/cypress/e2e/articles/article-details.cy.ts @@ -14,7 +14,7 @@ describe('article details testing', () => { }); it('should see a content of the article', () => { - cy.getByTestId('ArticleDetails.title').should('exist'); + cy.getByTestId('ArticleDetailsDeprecated.title').should('exist'); }); it('should see a list of recommendations', () => { @@ -22,7 +22,7 @@ describe('article details testing', () => { }); it('leaves a comment', () => { - cy.getByTestId('ArticleDetails.title'); + cy.getByTestId('ArticleDetailsDeprecated.title'); cy.getByTestId('AddCommentForm').scrollIntoView(); cy.addComment('text'); @@ -33,7 +33,7 @@ describe('article details testing', () => { it('leaves a rate', () => { // cy.intercept('GET', '**/articles/*', { fixture: 'article-details.json' }); - cy.getByTestId('ArticleDetails.title'); + cy.getByTestId('ArticleDetailsDeprecated.title'); cy.getByTestId('RatingCard').scrollIntoView(); cy.setRate(5, 'feedback'); diff --git a/json-server/db.json b/json-server/db.json index 4bb1b5ab..d8362d89 100644 --- a/json-server/db.json +++ b/json-server/db.json @@ -755,7 +755,7 @@ "isAppRedesigned": true }, "jsonSettings": { - "theme": "app_dark_theme", + "theme": "app_light_theme", "isFirstVisit": true, "settingsPageHasBeenOpen": false, "isArticlesPageWasOpened": true diff --git a/src/app/styles/reset.scss b/src/app/styles/reset.scss index d94dda65..332501db 100644 --- a/src/app/styles/reset.scss +++ b/src/app/styles/reset.scss @@ -19,3 +19,12 @@ select { a { text-decoration: none; } + +h1, +h2, +h3, +h4, +h5, +h6 { + font-weight: normal; +} diff --git a/src/entities/Article/README.md b/src/entities/Article/README.md index 571d6634..d0859812 100644 --- a/src/entities/Article/README.md +++ b/src/entities/Article/README.md @@ -5,7 +5,7 @@ Article Entity for Blog #### Public api - Components - - `ArticleDetails` - Component with article information + - `ArticleDetailsDeprecated` - Component with article information - `ArticleList` - Component with list of articles - `ArticleViewSelector` - Component - switcher for displaying a list of articles (tile, list) - `ArticleSortSelector` - Component with a choice of sorting for a list of articles diff --git a/src/entities/Article/ui/ArticleCodeBlockComponent/ArticleCodeBlockComponent.tsx b/src/entities/Article/ui/ArticleCodeBlockComponent/ArticleCodeBlockComponent.tsx index aee48be5..9a593099 100644 --- a/src/entities/Article/ui/ArticleCodeBlockComponent/ArticleCodeBlockComponent.tsx +++ b/src/entities/Article/ui/ArticleCodeBlockComponent/ArticleCodeBlockComponent.tsx @@ -1,7 +1,9 @@ import { memo } from 'react'; import { classNames } from '@/shared/lib/classNames'; -import { Code } from '@/shared/ui/deprecated/Code'; +import { Code as CodeDeprecated } from '@/shared/ui/deprecated/Code'; +import { Code } from '@/shared/ui/redesigned/Code'; +import { ToggleFeatures } from '@/shared/lib/features'; import { ArticleCodeBlock } from '../../model/types/article'; import cls from './ArticleCodeBlockComponent.module.scss'; @@ -15,9 +17,19 @@ export const ArticleCodeBlockComponent = memo((props: ArticleCodeBlockComponentP const { className, block } = props; return ( -
- -
+ + + + } + off={ +
+ +
+ } + /> ); }); diff --git a/src/entities/Article/ui/ArticleDetails/ArticleDetails.tsx b/src/entities/Article/ui/ArticleDetails/ArticleDetails.tsx index 147251fd..a04d6332 100644 --- a/src/entities/Article/ui/ArticleDetails/ArticleDetails.tsx +++ b/src/entities/Article/ui/ArticleDetails/ArticleDetails.tsx @@ -1,123 +1,23 @@ -import { memo, useCallback, useEffect } from 'react'; -import { useSelector } from 'react-redux'; -import { useTranslation } from 'react-i18next'; +import { memo } from 'react'; -import { classNames } from '@/shared/lib/classNames'; -import { - DynamicModuleLoader, - ReducersList, -} from '@/shared/lib/components/DynamicModuleLoader/DynamicModuleLoader'; -import { useAppDispatch } from '@/shared/lib/hooks/useAppDispatch/useAppDispatch'; -import { Text, TextAlign, TextSize } from '@/shared/ui/deprecated/Text'; -import { Skeleton } from '@/shared/ui/deprecated/Skeleton'; -import { Avatar } from '@/shared/ui/deprecated/Avatar'; -import { Icon } from '@/shared/ui/deprecated/Icon'; -import EyeIcon from '@/shared/assets/icons/eye-20-20.svg'; -import CalendarIcon from '@/shared/assets/icons/date-20-20.svg'; -import { HStack, VStack } from '@/shared/ui/redesigned/Stack'; - -import { ArticleBlockType } from '../../model/consts/consts'; -import { ArticleImageBlockComponent } from '../ArticleImageBlockComponent/ArticleImageBlockComponent'; -import { ArticleCodeBlockComponent } from '../ArticleCodeBlockComponent/ArticleCodeBlockComponent'; -import { ArticleTextBlockComponent } from '../ArticleTextBlockComponent/ArticleTextBlockComponent'; -import { ArticleBlock } from '../../model/types/article'; -import { fetchArticleById } from '../../model/services/fetchArticleById/fetchArticleById'; -import { - getArticleDetails, - getArticleDetailsError, - getArticleDetailsIsLoading, -} from '../../model/selectors/getArticleDetails/getArticleDetails'; -import cls from './ArticleDetails.module.scss'; -import { articleDetailsReducer } from '../../model/slice/articleDetailsSlice'; +import { ToggleFeatures } from '@/shared/lib/features'; +import { ArticleDetailsRedesigned } from '@/entities/Article/ui/ArticleDetails/ArticleDetailsRedesigned/ArticleDetailsRedesigned'; +import { ArticleDetailsDeprecated } from '@/entities/Article/ui/ArticleDetails/ArticleDetailsDeprecated/ArticleDetailsDeprecated'; interface ArticleDetailsProps { className?: string; id: string; } -const reducers: ReducersList = { - articleDetails: articleDetailsReducer, -}; - export const ArticleDetails = memo((props: ArticleDetailsProps) => { const { className, id } = props; - const { t } = useTranslation('articles'); - const dispatch = useAppDispatch(); - const article = useSelector(getArticleDetails); - const isLoading = useSelector(getArticleDetailsIsLoading); - const error = useSelector(getArticleDetailsError); - - const renderBlock = useCallback((block: ArticleBlock) => { - switch (block.type) { - case ArticleBlockType.TEXT: - return ; - case ArticleBlockType.CODE: - return ; - case ArticleBlockType.IMAGE: - return ; - default: - return null; - } - }, []); - - useEffect(() => { - if (__PROJECT__ !== 'storybook') { - dispatch(fetchArticleById(id)); - } - }, [dispatch, id]); - - let content; - - if (isLoading) { - content = ( - <> - - - - - - - ); - } else if (error) { - content = ; - } else { - content = ( - <> - - - - - - - - - - - - - - - - - - - {article?.blocks.map(renderBlock)} - - ); - } - return ( - - - {content} - - + } + off={} + /> ); }); diff --git a/src/entities/Article/ui/ArticleDetails/ArticleDetails.module.scss b/src/entities/Article/ui/ArticleDetails/ArticleDetailsDeprecated/ArticleDetailsDeprecated.module.scss similarity index 100% rename from src/entities/Article/ui/ArticleDetails/ArticleDetails.module.scss rename to src/entities/Article/ui/ArticleDetails/ArticleDetailsDeprecated/ArticleDetailsDeprecated.module.scss diff --git a/src/entities/Article/ui/ArticleDetails/ArticleDetails.stories.tsx b/src/entities/Article/ui/ArticleDetails/ArticleDetailsDeprecated/ArticleDetailsDeprecated.stories.tsx similarity index 65% rename from src/entities/Article/ui/ArticleDetails/ArticleDetails.stories.tsx rename to src/entities/Article/ui/ArticleDetails/ArticleDetailsDeprecated/ArticleDetailsDeprecated.stories.tsx index e5523af3..3366e8a9 100644 --- a/src/entities/Article/ui/ArticleDetails/ArticleDetails.stories.tsx +++ b/src/entities/Article/ui/ArticleDetails/ArticleDetailsDeprecated/ArticleDetailsDeprecated.stories.tsx @@ -2,18 +2,20 @@ import type { ComponentMeta, ComponentStory } from '@storybook/react'; import { StoreDecorator } from '@/shared/config/storybook/StoreDecorator/StoreDecorator'; -import { ArticleDetails } from './ArticleDetails'; -import { article } from '../../mocks/data'; +import { ArticleDetailsDeprecated } from './ArticleDetailsDeprecated'; +import { article } from '../../../mocks/data'; export default { - title: 'entities/Article/ArticleDetails', - component: ArticleDetails, + title: 'entities/Article/ArticleDetailsDeprecated', + component: ArticleDetailsDeprecated, argTypes: { backgroundColor: { control: 'color' }, }, -} as ComponentMeta; +} as ComponentMeta; -const Template: ComponentStory = (args) => ; +const Template: ComponentStory = (args) => ( + +); export const Normal = Template.bind({}); Normal.args = {}; diff --git a/src/entities/Article/ui/ArticleDetails/ArticleDetailsDeprecated/ArticleDetailsDeprecated.tsx b/src/entities/Article/ui/ArticleDetails/ArticleDetailsDeprecated/ArticleDetailsDeprecated.tsx new file mode 100644 index 00000000..7456ae43 --- /dev/null +++ b/src/entities/Article/ui/ArticleDetails/ArticleDetailsDeprecated/ArticleDetailsDeprecated.tsx @@ -0,0 +1,124 @@ +import { memo, useCallback, useEffect } from 'react'; +import { useSelector } from 'react-redux'; +import { useTranslation } from 'react-i18next'; + +import { classNames } from '@/shared/lib/classNames'; +import { + DynamicModuleLoader, + ReducersList, +} from '@/shared/lib/components/DynamicModuleLoader/DynamicModuleLoader'; +import { useAppDispatch } from '@/shared/lib/hooks/useAppDispatch/useAppDispatch'; +import { Text, TextAlign, TextSize } from '@/shared/ui/deprecated/Text'; +import { Skeleton } from '@/shared/ui/deprecated/Skeleton'; +import { Avatar } from '@/shared/ui/deprecated/Avatar'; +import { Icon } from '@/shared/ui/deprecated/Icon'; +import EyeIcon from '@/shared/assets/icons/eye-20-20.svg'; +import CalendarIcon from '@/shared/assets/icons/date-20-20.svg'; +import { HStack, VStack } from '@/shared/ui/redesigned/Stack'; + +import { ArticleBlockType } from '../../../model/consts/consts'; +import { ArticleImageBlockComponent } from '../../ArticleImageBlockComponent/ArticleImageBlockComponent'; +import { ArticleCodeBlockComponent } from '../../ArticleCodeBlockComponent/ArticleCodeBlockComponent'; +import { ArticleTextBlockComponent } from '../../ArticleTextBlockComponent/ArticleTextBlockComponent'; +import { ArticleBlock } from '../../../model/types/article'; +import { fetchArticleById } from '../../../model/services/fetchArticleById/fetchArticleById'; +import { + getArticleDetails, + getArticleDetailsError, + getArticleDetailsIsLoading, +} from '../../../model/selectors/getArticleDetails/getArticleDetails'; +import cls from './ArticleDetailsDeprecated.module.scss'; +import { articleDetailsReducer } from '../../../model/slice/articleDetailsSlice'; + +interface ArticleDetailsProps { + className?: string; + id: string; +} + +const reducers: ReducersList = { + articleDetails: articleDetailsReducer, +}; + +export const ArticleDetailsDeprecated = memo((props: ArticleDetailsProps) => { + const { className, id } = props; + + const { t } = useTranslation('articles'); + const dispatch = useAppDispatch(); + const article = useSelector(getArticleDetails); + const isLoading = useSelector(getArticleDetailsIsLoading); + const error = useSelector(getArticleDetailsError); + + const renderBlock = useCallback((block: ArticleBlock) => { + switch (block.type) { + case ArticleBlockType.TEXT: + return ; + case ArticleBlockType.CODE: + return ; + case ArticleBlockType.IMAGE: + return ; + default: + return null; + } + }, []); + + useEffect(() => { + if (__PROJECT__ !== 'storybook') { + dispatch(fetchArticleById(id)); + } + }, [dispatch, id]); + + let content; + + if (isLoading) { + content = ( + <> + + + + + + + ); + } else if (error) { + content = ; + } else { + content = ( + <> + + + + + + + + + + + + + + + + + + + {article?.blocks.map(renderBlock)} + + ); + } + + return ( + + + {content} + + + ); +}); + +ArticleDetailsDeprecated.displayName = 'ArticleDetailsDeprecated'; diff --git a/src/entities/Article/ui/ArticleDetails/ArticleDetailsRedesigned/ArticleDetailsRedesigned.module.scss b/src/entities/Article/ui/ArticleDetails/ArticleDetailsRedesigned/ArticleDetailsRedesigned.module.scss new file mode 100644 index 00000000..91fcd98f --- /dev/null +++ b/src/entities/Article/ui/ArticleDetails/ArticleDetailsRedesigned/ArticleDetailsRedesigned.module.scss @@ -0,0 +1,13 @@ +.articleDetails { + min-height: 100%; +} + +.avatar { + margin: 0 auto; +} + +.img { + max-height: 420px; + max-width: 100%; + margin: 0 auto; +} diff --git a/src/entities/Article/ui/ArticleDetails/ArticleDetailsRedesigned/ArticleDetailsRedesigned.stories.tsx b/src/entities/Article/ui/ArticleDetails/ArticleDetailsRedesigned/ArticleDetailsRedesigned.stories.tsx new file mode 100644 index 00000000..9ff69065 --- /dev/null +++ b/src/entities/Article/ui/ArticleDetails/ArticleDetailsRedesigned/ArticleDetailsRedesigned.stories.tsx @@ -0,0 +1,48 @@ +import type { ComponentMeta, ComponentStory } from '@storybook/react'; + +import { StoreDecorator } from '@/shared/config/storybook/StoreDecorator/StoreDecorator'; + +import { ArticleDetailsRedesigned } from './ArticleDetailsRedesigned'; +import { article } from '../../../mocks/data'; + +export default { + title: 'entities/Article/ArticleDetailsRedesigned', + component: ArticleDetailsRedesigned, + argTypes: { + backgroundColor: { control: 'color' }, + }, +} as ComponentMeta; + +const Template: ComponentStory = (args) => ( + +); + +export const Normal = Template.bind({}); +Normal.args = {}; +Normal.decorators = [ + StoreDecorator({ + articleDetails: { + data: article, + }, + }), +]; + +export const Loading = Template.bind({}); +Loading.args = {}; +Loading.decorators = [ + StoreDecorator({ + articleDetails: { + isLoading: true, + }, + }), +]; + +export const Error = Template.bind({}); +Error.args = {}; +Error.decorators = [ + StoreDecorator({ + articleDetails: { + error: 'Error', + }, + }), +]; diff --git a/src/entities/Article/ui/ArticleDetails/ArticleDetailsRedesigned/ArticleDetailsRedesigned.tsx b/src/entities/Article/ui/ArticleDetails/ArticleDetailsRedesigned/ArticleDetailsRedesigned.tsx new file mode 100644 index 00000000..ff1b1afd --- /dev/null +++ b/src/entities/Article/ui/ArticleDetails/ArticleDetailsRedesigned/ArticleDetailsRedesigned.tsx @@ -0,0 +1,107 @@ +import { memo, useCallback, useEffect } from 'react'; +import { useSelector } from 'react-redux'; +import { useTranslation } from 'react-i18next'; + +import { classNames } from '@/shared/lib/classNames'; +import { + DynamicModuleLoader, + ReducersList, +} from '@/shared/lib/components/DynamicModuleLoader/DynamicModuleLoader'; +import { useAppDispatch } from '@/shared/lib/hooks/useAppDispatch/useAppDispatch'; +import { Text } from '@/shared/ui/redesigned/Text'; +import { Skeleton } from '@/shared/ui/redesigned/Skeleton'; +import { VStack } from '@/shared/ui/redesigned/Stack'; +import { AppImage } from '@/shared/ui/redesigned/AppImage'; + +import { ArticleBlockType } from '../../../model/consts/consts'; +import { ArticleImageBlockComponent } from '../../ArticleImageBlockComponent/ArticleImageBlockComponent'; +import { ArticleCodeBlockComponent } from '../../ArticleCodeBlockComponent/ArticleCodeBlockComponent'; +import { ArticleTextBlockComponent } from '../../ArticleTextBlockComponent/ArticleTextBlockComponent'; +import { ArticleBlock } from '../../../model/types/article'; +import { fetchArticleById } from '../../../model/services/fetchArticleById/fetchArticleById'; +import { + getArticleDetails, + getArticleDetailsError, + getArticleDetailsIsLoading, +} from '../../../model/selectors/getArticleDetails/getArticleDetails'; +import cls from './ArticleDetailsRedesigned.module.scss'; +import { articleDetailsReducer } from '../../../model/slice/articleDetailsSlice'; + +interface ArticleDetailsProps { + className?: string; + id: string; +} + +const reducers: ReducersList = { + articleDetails: articleDetailsReducer, +}; + +export const ArticleDetailsRedesigned = memo((props: ArticleDetailsProps) => { + const { className, id } = props; + + const { t } = useTranslation('articles'); + const dispatch = useAppDispatch(); + const article = useSelector(getArticleDetails); + const isLoading = useSelector(getArticleDetailsIsLoading); + const error = useSelector(getArticleDetailsError); + + const renderBlock = useCallback((block: ArticleBlock) => { + switch (block.type) { + case ArticleBlockType.TEXT: + return ; + case ArticleBlockType.CODE: + return ; + case ArticleBlockType.IMAGE: + return ; + default: + return null; + } + }, []); + + useEffect(() => { + if (__PROJECT__ !== 'storybook') { + dispatch(fetchArticleById(id)); + } + }, [dispatch, id]); + + let content; + + if (isLoading) { + content = ( + <> + + + + + + + ); + } else if (error) { + content = ; + } else { + content = ( + <> + + + + } + /> + + {article?.blocks.map(renderBlock)} + + ); + } + + return ( + + + {content} + + + ); +}); + +ArticleDetailsRedesigned.displayName = 'ArticleDetailsRedesigned'; diff --git a/src/entities/Article/ui/ArticleImageBlockComponent/ArticleImageBlockComponent.tsx b/src/entities/Article/ui/ArticleImageBlockComponent/ArticleImageBlockComponent.tsx index b88883fd..2a673784 100644 --- a/src/entities/Article/ui/ArticleImageBlockComponent/ArticleImageBlockComponent.tsx +++ b/src/entities/Article/ui/ArticleImageBlockComponent/ArticleImageBlockComponent.tsx @@ -1,7 +1,9 @@ import { memo } from 'react'; import { classNames } from '@/shared/lib/classNames'; -import { Text, TextAlign } from '@/shared/ui/deprecated/Text'; +import { Text as TextDeprecated, TextAlign } from '@/shared/ui/deprecated/Text'; +import { Text } from '@/shared/ui/redesigned/Text'; +import { ToggleFeatures } from '@/shared/lib/features'; import { ArticleImageBlock } from '../../model/types/article'; import cls from './ArticleImageBlockComponent.module.scss'; @@ -18,7 +20,13 @@ export const ArticleImageBlockComponent = memo((props: ArticleImageBlockComponen
{block.title} - {block.title && } + {block.title && ( + } + off={} + /> + )}
); }); diff --git a/src/entities/Article/ui/ArticleListItem/ArticleListItemRedesigned/ArticleListItemRedesigned.module.scss b/src/entities/Article/ui/ArticleListItem/ArticleListItemRedesigned/ArticleListItemRedesigned.module.scss index 13354a1d..44351338 100644 --- a/src/entities/Article/ui/ArticleListItem/ArticleListItemRedesigned/ArticleListItemRedesigned.module.scss +++ b/src/entities/Article/ui/ArticleListItem/ArticleListItemRedesigned/ArticleListItemRedesigned.module.scss @@ -38,4 +38,8 @@ height: 100%; justify-content: flex-end; } + + .avatar { + margin-left: 8px; + } } diff --git a/src/entities/Article/ui/ArticleListItem/ArticleListItemRedesigned/ArticleListItemRedesigned.tsx b/src/entities/Article/ui/ArticleListItem/ArticleListItemRedesigned/ArticleListItemRedesigned.tsx index 01a4ab52..35243aa8 100644 --- a/src/entities/Article/ui/ArticleListItem/ArticleListItemRedesigned/ArticleListItemRedesigned.tsx +++ b/src/entities/Article/ui/ArticleListItem/ArticleListItemRedesigned/ArticleListItemRedesigned.tsx @@ -32,7 +32,12 @@ export const ArticleListItemRedesigned = memo((props: ArticleListItemProps) => { const userInfo = ( <> - + ); @@ -96,7 +101,7 @@ export const ArticleListItemRedesigned = memo((props: ArticleListItemProps) => { > } + fallback={} className={cls.img} src={article.img} alt={article.title} diff --git a/src/entities/Article/ui/ArticleTextBlockComponent/ArticleTextBlockComponent.tsx b/src/entities/Article/ui/ArticleTextBlockComponent/ArticleTextBlockComponent.tsx index a9ef0a45..1dc12596 100644 --- a/src/entities/Article/ui/ArticleTextBlockComponent/ArticleTextBlockComponent.tsx +++ b/src/entities/Article/ui/ArticleTextBlockComponent/ArticleTextBlockComponent.tsx @@ -1,7 +1,9 @@ import { memo } from 'react'; import { classNames } from '@/shared/lib/classNames'; -import { Text } from '@/shared/ui/deprecated/Text'; +import { Text as TextDeprecated } from '@/shared/ui/deprecated/Text'; +import { Text } from '@/shared/ui/redesigned/Text'; +import { ToggleFeatures } from '@/shared/lib/features'; import cls from './ArticleTextBlockComponent.module.scss'; import { ArticleTextBlock } from '../../model/types/article'; @@ -15,12 +17,25 @@ export const ArticleTextBlockComponent = memo((props: ArticleTextBlockComponentP const { className, block } = props; return ( -
- {block.title && } - {block.paragraphs.map((paragraph) => ( - - ))} -
+ + {block.title && } + {block.paragraphs.map((paragraph) => ( + + ))} + + } + off={ +
+ {block.title && } + {block.paragraphs.map((paragraph) => ( + + ))} +
+ } + /> ); }); diff --git a/src/shared/assets/icons/copy.svg b/src/shared/assets/icons/copy.svg new file mode 100644 index 00000000..4c109d9b --- /dev/null +++ b/src/shared/assets/icons/copy.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/shared/ui/redesigned/Code/index.ts b/src/shared/ui/redesigned/Code/index.ts new file mode 100644 index 00000000..b71d6f64 --- /dev/null +++ b/src/shared/ui/redesigned/Code/index.ts @@ -0,0 +1 @@ +export { Code } from './ui/Code'; diff --git a/src/shared/ui/redesigned/Code/ui/Code.module.scss b/src/shared/ui/redesigned/Code/ui/Code.module.scss new file mode 100644 index 00000000..b9d73dce --- /dev/null +++ b/src/shared/ui/redesigned/Code/ui/Code.module.scss @@ -0,0 +1,14 @@ +.code { + border: 1px solid var(--accent-redesigned); + padding: 20px; + position: relative; + background: var(--light-bg-redesigned); + overflow: auto; + border-radius: 16px; +} + +.copyBtn { + position: absolute; + right: 20px; + top: 20px; +} diff --git a/src/shared/ui/redesigned/Code/ui/Code.stories.tsx b/src/shared/ui/redesigned/Code/ui/Code.stories.tsx new file mode 100644 index 00000000..1c271b57 --- /dev/null +++ b/src/shared/ui/redesigned/Code/ui/Code.stories.tsx @@ -0,0 +1,29 @@ +import type { ComponentMeta, ComponentStory } from '@storybook/react'; + +import { Code } from './Code'; + +export default { + title: 'shared/redesigned/Code', + component: Code, + argTypes: { + backgroundColor: { control: 'color' }, + }, +} as ComponentMeta; + +const Template: ComponentStory = (args) => ; + +export const Normal = Template.bind({}); +Normal.args = { + text: + 'export default {\n' + + " title: 'shared/Code',\n" + + ' component: Code,\n' + + ' argTypes: {\n' + + " backgroundColor: { control: 'color' },\n" + + ' },\n' + + '} as ComponentMeta;\n' + + '\n' + + 'const Template: ComponentStory = (args) => ;\n' + + '\n' + + 'export const Normal = Template.bind({});', +}; diff --git a/src/shared/ui/redesigned/Code/ui/Code.tsx b/src/shared/ui/redesigned/Code/ui/Code.tsx new file mode 100644 index 00000000..9905e0ae --- /dev/null +++ b/src/shared/ui/redesigned/Code/ui/Code.tsx @@ -0,0 +1,30 @@ +import { memo, useCallback } from 'react'; + +import { classNames } from '@/shared/lib/classNames'; +import CopyIcon from '@/shared/assets/icons/copy.svg'; +import { Icon } from '@/shared/ui/redesigned/Icon'; + +import cls from './Code.module.scss'; + +interface CodeProps { + className?: string; + text: string; +} + +export const Code = memo((props: CodeProps) => { + const { className, text } = props; + + const onCopy = useCallback(() => { + navigator.clipboard.writeText(text); + }, [text]); + + return ( +
+      
+
+      {text}
+    
+ ); +}); + +Code.displayName = 'Code';