diff --git a/src/entities/Article/ui/ArticleDetails/ArticleDetails.tsx b/src/entities/Article/ui/ArticleDetails/ArticleDetails.tsx index 3af6b98..247ad52 100644 --- a/src/entities/Article/ui/ArticleDetails/ArticleDetails.tsx +++ b/src/entities/Article/ui/ArticleDetails/ArticleDetails.tsx @@ -32,7 +32,7 @@ import { Text, } from '@/shared/ui/deprecated/Text'; import { Skeleton } from '@/shared/ui/deprecated/Skeleton'; -import { HStack, VStack } from '@/shared/ui/deprecated/Stack'; +import { HStack, VStack } from '@/shared/ui/redesigned/Stack'; interface ArticleDetailsProps { className?: string; diff --git a/src/entities/Article/ui/ArticleListItem/ArticleListItem.tsx b/src/entities/Article/ui/ArticleListItem/ArticleListItem.tsx index f5b6881..f3aa7f5 100644 --- a/src/entities/Article/ui/ArticleListItem/ArticleListItem.tsx +++ b/src/entities/Article/ui/ArticleListItem/ArticleListItem.tsx @@ -2,7 +2,6 @@ import { useTranslation } from 'react-i18next'; import { HTMLAttributeAnchorTarget, memo } from 'react'; import { Button, ButtonTheme } from '@/shared/ui/deprecated/Button'; import { AppLink } from '@/shared/ui/deprecated/AppLink'; -import { AppImage } from '@/shared/ui/deprecated/AppImage'; import { Text } from '@/shared/ui/deprecated/Text'; import { Skeleton } from '@/shared/ui/deprecated/Skeleton'; import { classNames } from '@/shared/lib/classNames/classNames'; @@ -15,6 +14,7 @@ import { getRouteArticleDetails } from '@/shared/const/router'; import { Icon } from '@/shared/ui/deprecated/Icon'; import { Card } from '@/shared/ui/deprecated/Card'; import { Avatar } from '@/shared/ui/deprecated/Avatar'; +import { AppImage } from '@/shared/ui/redesigned/AppImage'; interface ArticleListItemProps { className?: string; diff --git a/src/entities/Comment/ui/CommentCard/CommentCard.tsx b/src/entities/Comment/ui/CommentCard/CommentCard.tsx index 1ad638a..d7bb823 100644 --- a/src/entities/Comment/ui/CommentCard/CommentCard.tsx +++ b/src/entities/Comment/ui/CommentCard/CommentCard.tsx @@ -1,7 +1,7 @@ import { useTranslation } from 'react-i18next'; import { memo } from 'react'; +import { VStack } from '@/shared/ui/redesigned/Stack'; import { AppLink } from '@/shared/ui/deprecated/AppLink'; -import { VStack } from '@/shared/ui/deprecated/Stack'; import { classNames } from '@/shared/lib/classNames/classNames'; import cls from './CommentCard.module.scss'; import { Comment } from '../../model/types/comment'; diff --git a/src/entities/Comment/ui/CommentList/CommentList.tsx b/src/entities/Comment/ui/CommentList/CommentList.tsx index 12582b6..219ffd4 100644 --- a/src/entities/Comment/ui/CommentList/CommentList.tsx +++ b/src/entities/Comment/ui/CommentList/CommentList.tsx @@ -1,6 +1,6 @@ import { useTranslation } from 'react-i18next'; import { memo } from 'react'; -import { VStack } from '@/shared/ui/deprecated/Stack'; +import { VStack } from '@/shared/ui/redesigned/Stack'; import { classNames } from '@/shared/lib/classNames/classNames'; import { Text } from '@/shared/ui/deprecated/Text/Text'; import { CommentCard } from '../CommentCard/CommentCard'; diff --git a/src/entities/Notification/ui/NotificationItem/NotificationItem.tsx b/src/entities/Notification/ui/NotificationItem/NotificationItem.tsx index 19e6fd9..b4aeee5 100644 --- a/src/entities/Notification/ui/NotificationItem/NotificationItem.tsx +++ b/src/entities/Notification/ui/NotificationItem/NotificationItem.tsx @@ -1,9 +1,12 @@ import { memo } from 'react'; -import { Card, CardTheme } from '@/shared/ui/deprecated/Card'; -import { Text } from '@/shared/ui/deprecated/Text'; +import { Card as DeprecatedCard, CardTheme } from '@/shared/ui/deprecated/Card'; +import { Text as DeprecatedText } from '@/shared/ui/deprecated/Text'; +import { Text } from '@/shared/ui/redesigned/Text'; import { classNames } from '@/shared/lib/classNames/classNames'; import { Notification } from '../../model/types/notification'; import cls from './NotificationItem.module.scss'; +import { ToggleFeatures } from '@/shared/lib/features'; +import { Card } from '@/shared/ui/redesigned/Card'; interface NotificationItemProps { className?: string; @@ -14,15 +17,34 @@ export const NotificationItem = memo((props: NotificationItemProps) => { const { className, notification } = props; const content = ( - - - + + + + } + off={ + + + + } + /> ); if (notification?.href) { diff --git a/src/entities/Notification/ui/NotificationList/NotificationList.tsx b/src/entities/Notification/ui/NotificationList/NotificationList.tsx index be86ee1..c88bed8 100644 --- a/src/entities/Notification/ui/NotificationList/NotificationList.tsx +++ b/src/entities/Notification/ui/NotificationList/NotificationList.tsx @@ -1,5 +1,5 @@ import { memo } from 'react'; -import { VStack } from '@/shared/ui/deprecated/Stack'; +import { VStack } from '@/shared/ui/redesigned/Stack'; import { Skeleton } from '@/shared/ui/deprecated/Skeleton'; import { classNames } from '@/shared/lib/classNames/classNames'; import { NotificationItem } from '../../ui/NotificationItem/NotificationItem'; diff --git a/src/entities/Profile/ui/ProfileCard/ProfileCard.tsx b/src/entities/Profile/ui/ProfileCard/ProfileCard.tsx index 347e8d9..19dfd89 100644 --- a/src/entities/Profile/ui/ProfileCard/ProfileCard.tsx +++ b/src/entities/Profile/ui/ProfileCard/ProfileCard.tsx @@ -1,7 +1,7 @@ import { useTranslation } from 'react-i18next'; +import { HStack, VStack } from '@/shared/ui/redesigned/Stack'; import { Avatar } from '@/shared/ui/deprecated/Avatar'; import { Text, TextAlign, TextTheme } from '@/shared/ui/deprecated/Text'; -import { HStack, VStack } from '@/shared/ui/deprecated/Stack'; import { classNames, Mods } from '@/shared/lib/classNames/classNames'; import { Country, CountrySelect } from '../../../Country'; import { Currency, CurrencySelect } from '../../../Currency'; diff --git a/src/entities/Rating/ui/RatingCard.tsx b/src/entities/Rating/ui/RatingCard.tsx index 07b41dc..0603e61 100644 --- a/src/entities/Rating/ui/RatingCard.tsx +++ b/src/entities/Rating/ui/RatingCard.tsx @@ -1,9 +1,9 @@ import { useTranslation } from 'react-i18next'; import { memo, useCallback, useState } from 'react'; import { BrowserView, MobileView } from 'react-device-detect'; +import { HStack, VStack } from '@/shared/ui/redesigned/Stack'; import { Card } from '@/shared/ui/deprecated/Card'; import { Button, ButtonSize, ButtonTheme } from '@/shared/ui/deprecated/Button'; -import { HStack, VStack } from '@/shared/ui/deprecated/Stack'; import { Text } from '@/shared/ui/deprecated/Text'; import { StarRating } from '@/shared/ui/deprecated/StarRating'; import { classNames } from '@/shared/lib/classNames/classNames'; diff --git a/src/features/addCommentForm/ui/AddCommentForm/AddCommentForm.tsx b/src/features/addCommentForm/ui/AddCommentForm/AddCommentForm.tsx index d12c6b1..253462f 100644 --- a/src/features/addCommentForm/ui/AddCommentForm/AddCommentForm.tsx +++ b/src/features/addCommentForm/ui/AddCommentForm/AddCommentForm.tsx @@ -1,8 +1,8 @@ import { useTranslation } from 'react-i18next'; import { memo, useCallback } from 'react'; import { useSelector } from 'react-redux'; +import { HStack } from '@/shared/ui/redesigned/Stack'; import { Button, ButtonTheme } from '@/shared/ui/deprecated/Button'; -import { HStack } from '@/shared/ui/deprecated/Stack'; import { classNames } from '@/shared/lib/classNames/classNames'; import { useAppDispatch } from '@/shared/lib/hook/useAppDispatch/useAppDispatch'; import { diff --git a/src/features/articleRecommendationsList/ui/ArticleRecommendationsList/ArticleRecommendationsList.tsx b/src/features/articleRecommendationsList/ui/ArticleRecommendationsList/ArticleRecommendationsList.tsx index 8d89bfd..331e6e2 100644 --- a/src/features/articleRecommendationsList/ui/ArticleRecommendationsList/ArticleRecommendationsList.tsx +++ b/src/features/articleRecommendationsList/ui/ArticleRecommendationsList/ArticleRecommendationsList.tsx @@ -1,7 +1,7 @@ import { useTranslation } from 'react-i18next'; import { memo } from 'react'; +import { VStack } from '@/shared/ui/redesigned/Stack'; import { Text, TextSize } from '@/shared/ui/deprecated/Text'; -import { VStack } from '@/shared/ui/deprecated/Stack'; import { classNames } from '@/shared/lib/classNames/classNames'; import { ArticleList } from '../../../../entities/Article'; import { useArticleRecommendaionsList } from '../../api/ArticleRecommendationsApi'; diff --git a/src/features/avatarDropdown/ui/AvatarDropDown/AvatarDropDown.tsx b/src/features/avatarDropdown/ui/AvatarDropDown/AvatarDropDown.tsx index dc09525..21ccf08 100644 --- a/src/features/avatarDropdown/ui/AvatarDropDown/AvatarDropDown.tsx +++ b/src/features/avatarDropdown/ui/AvatarDropDown/AvatarDropDown.tsx @@ -1,8 +1,8 @@ import React, { memo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { useSelector } from 'react-redux'; -import { Avatar } from '@/shared/ui/deprecated/Avatar'; -import { Dropdown } from '@/shared/ui/deprecated/Popups'; +import { Avatar as AvatarDeprecated } from '@/shared/ui/deprecated/Avatar'; +import { Dropdown as DropdownDeprecated } from '@/shared/ui/deprecated/Popups'; import { useAppDispatch } from '@/shared/lib/hook/useAppDispatch/useAppDispatch'; import { getUserAuthData, @@ -11,6 +11,9 @@ import { userActions, } from '../../../../entities/User'; import { getRouteAdminPanel, getRouteProfile } from '@/shared/const/router'; +import { ToggleFeatures } from '@/shared/lib/features'; +import { Dropdown } from '@/shared/ui/redesigned/Popups'; +import { Avatar } from '@/shared/ui/redesigned/Avatar'; export const AvatarDropDown = memo(() => { const { t } = useTranslation(); @@ -31,29 +34,46 @@ export const AvatarDropDown = memo(() => { return null; } + const items = [ + ...(isAdminPanelAvailable + ? [ + { + content: t('Admin panel'), + href: getRouteAdminPanel(), + }, + ] + : []), + { + content: t('Profile'), + href: getRouteProfile(authData.id), + }, + { + content: t('Exit'), + onClick: onLogout, + }, + ]; return ( - + } + /> + } + off={ + + } + /> } /> ); diff --git a/src/features/editableProfileCard/ui/EditableProfileCard/EditableProfileCard.tsx b/src/features/editableProfileCard/ui/EditableProfileCard/EditableProfileCard.tsx index 77e1044..3ffeed3 100644 --- a/src/features/editableProfileCard/ui/EditableProfileCard/EditableProfileCard.tsx +++ b/src/features/editableProfileCard/ui/EditableProfileCard/EditableProfileCard.tsx @@ -1,8 +1,8 @@ import { useTranslation } from 'react-i18next'; import { memo, useCallback } from 'react'; import { useSelector } from 'react-redux'; +import { VStack } from '@/shared/ui/redesigned/Stack'; import { Text, TextTheme } from '@/shared/ui/deprecated/Text'; -import { VStack } from '@/shared/ui/deprecated/Stack'; import { useAppDispatch } from '@/shared/lib/hook/useAppDispatch/useAppDispatch'; import { classNames } from '@/shared/lib/classNames/classNames'; import { useInitialEffect } from '@/shared/lib/hook/useInitialEffect/useInitialEffect'; diff --git a/src/features/editableProfileCard/ui/EditableProfileCardHeader/EditableProfileCardHeader.tsx b/src/features/editableProfileCard/ui/EditableProfileCardHeader/EditableProfileCardHeader.tsx index e95557a..de06d08 100644 --- a/src/features/editableProfileCard/ui/EditableProfileCardHeader/EditableProfileCardHeader.tsx +++ b/src/features/editableProfileCard/ui/EditableProfileCardHeader/EditableProfileCardHeader.tsx @@ -1,8 +1,8 @@ import { useTranslation } from 'react-i18next'; import { memo, useCallback } from 'react'; import { useSelector } from 'react-redux'; +import { HStack } from '@/shared/ui/redesigned/Stack'; import { Button, ButtonTheme } from '@/shared/ui/deprecated/Button'; -import { HStack } from '@/shared/ui/deprecated/Stack'; import { Text } from '@/shared/ui/deprecated/Text'; import { classNames } from '@/shared/lib/classNames/classNames'; import { useAppDispatch } from '@/shared/lib/hook/useAppDispatch/useAppDispatch'; diff --git a/src/features/notificationButton/ui/NotificationButton/NotificationButton.tsx b/src/features/notificationButton/ui/NotificationButton/NotificationButton.tsx index a155509..17742c4 100644 --- a/src/features/notificationButton/ui/NotificationButton/NotificationButton.tsx +++ b/src/features/notificationButton/ui/NotificationButton/NotificationButton.tsx @@ -1,12 +1,19 @@ import React, { memo, useCallback, useState } from 'react'; import { BrowserView, MobileView } from 'react-device-detect'; -import { Button, ButtonTheme } from '@/shared/ui/deprecated/Button'; -import { Popover } from '@/shared/ui/deprecated/Popups'; -import NotificationIcon from '@/shared/assets/icons/notification-20-20.svg'; +import { + ButtonTheme, + Button as ButtonDeprecated, +} from '@/shared/ui/deprecated/Button'; +import { Popover as PopoverDeprecated } from '@/shared/ui/deprecated/Popups'; +import NotificationIconDeprecated from '@/shared/assets/icons/notification-20-20.svg'; +import NotificationIcon from '@/shared/assets/icons/notification.svg'; import { NotificationList } from '../../../../entities/Notification'; import cls from './NotificationButton.module.scss'; -import { Drawer } from '@/shared/ui/deprecated/Drawer'; -import { Icon } from '@/shared/ui/deprecated/Icon'; +import { Drawer as DrawerDeprecated } from '@/shared/ui/deprecated/Drawer'; +import { ToggleFeatures } from '@/shared/lib/features'; +import { Icon as IconDeprecated } from '@/shared/ui/deprecated/Icon'; +import { Icon } from '@/shared/ui/redesigned/Icon'; +import { Popover } from '@/shared/ui/redesigned/Popups'; export const NotificationButton = memo(() => { const [isOpen, setIsOpen] = useState(false); @@ -20,23 +27,47 @@ export const NotificationButton = memo(() => { }, []); const trigger = ( - + + } + off={ + + + + } + /> ); return (
- - - + + + + } + off={ + + + + } + /> {trigger} - + - +
); diff --git a/src/pages/ArticlesDetailsPage/ui/ArticleDetailsComments/ArticleDetailsComments.tsx b/src/pages/ArticlesDetailsPage/ui/ArticleDetailsComments/ArticleDetailsComments.tsx index dc91e40..23e2400 100644 --- a/src/pages/ArticlesDetailsPage/ui/ArticleDetailsComments/ArticleDetailsComments.tsx +++ b/src/pages/ArticlesDetailsPage/ui/ArticleDetailsComments/ArticleDetailsComments.tsx @@ -2,7 +2,6 @@ import { useTranslation } from 'react-i18next'; import { memo, Suspense, useCallback } from 'react'; import { useSelector } from 'react-redux'; import { Text, TextSize } from '@/shared/ui/deprecated/Text'; -import { VStack } from '@/shared/ui/deprecated/Stack'; import { classNames } from '@/shared/lib/classNames/classNames'; import { AddCommentForm } from '@/features/addCommentForm'; import { useAppDispatch } from '@/shared/lib/hook/useAppDispatch/useAppDispatch'; @@ -13,6 +12,7 @@ import { addCommentForArticle } from '../../model/services/addCommetForArticle/a import { getArticleComments } from '../../model/slices/ArticleDetailsCommentsSlice'; import { getArticleCommentsIsLoading } from '../../model/selectors/comments'; import { Loader } from '@/shared/ui/deprecated/Loader'; +import { VStack } from '@/shared/ui/redesigned/Stack'; interface ArticleDetailsCommentsProps { className?: string; diff --git a/src/pages/ArticlesDetailsPage/ui/ArticlesDetailsPage/ArticlesDetailsPage.tsx b/src/pages/ArticlesDetailsPage/ui/ArticlesDetailsPage/ArticlesDetailsPage.tsx index 56dd3d1..7787a17 100644 --- a/src/pages/ArticlesDetailsPage/ui/ArticlesDetailsPage/ArticlesDetailsPage.tsx +++ b/src/pages/ArticlesDetailsPage/ui/ArticlesDetailsPage/ArticlesDetailsPage.tsx @@ -1,8 +1,8 @@ import { memo } from 'react'; import { useParams } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; +import { VStack } from '@/shared/ui/redesigned/Stack'; import { Card } from '@/shared/ui/deprecated/Card'; -import { VStack } from '@/shared/ui/deprecated/Stack'; import { DynamicModuleLoader, ReducersList, diff --git a/src/pages/ArticlesDetailsPage/ui/ArticlesDetailsPageHeader/ArticlesDetailsPageHeader.tsx b/src/pages/ArticlesDetailsPage/ui/ArticlesDetailsPageHeader/ArticlesDetailsPageHeader.tsx index b6547c4..88cff88 100644 --- a/src/pages/ArticlesDetailsPage/ui/ArticlesDetailsPageHeader/ArticlesDetailsPageHeader.tsx +++ b/src/pages/ArticlesDetailsPage/ui/ArticlesDetailsPageHeader/ArticlesDetailsPageHeader.tsx @@ -2,8 +2,8 @@ import { useTranslation } from 'react-i18next'; import { memo, useCallback } from 'react'; import { useNavigate } from 'react-router-dom'; import { useSelector } from 'react-redux'; +import { HStack } from '@/shared/ui/redesigned/Stack'; import { Button, ButtonTheme } from '@/shared/ui/deprecated/Button'; -import { HStack } from '@/shared/ui/deprecated/Stack'; import { classNames } from '@/shared/lib/classNames/classNames'; import { getCanEditArticle } from '../../model/selectors/article'; import { getArticlesDetailsData } from '../../../../entities/Article'; diff --git a/src/pages/ProfilePage/ui/ProfilePage.tsx b/src/pages/ProfilePage/ui/ProfilePage.tsx index b8307b3..4df604e 100644 --- a/src/pages/ProfilePage/ui/ProfilePage.tsx +++ b/src/pages/ProfilePage/ui/ProfilePage.tsx @@ -1,6 +1,6 @@ import { memo } from 'react'; import { useParams } from 'react-router-dom'; -import { VStack } from '@/shared/ui/deprecated/Stack'; +import { VStack } from '@/shared/ui/redesigned/Stack'; import { classNames } from '@/shared/lib/classNames/classNames'; import { EditableProfileCard } from '@/features/editableProfileCard'; import { Page } from '@/widgets/Page'; diff --git a/src/shared/layouts/MainLayout/MainLayout.module.scss b/src/shared/layouts/MainLayout/MainLayout.module.scss index 2c917b2..edd1bcc 100644 --- a/src/shared/layouts/MainLayout/MainLayout.module.scss +++ b/src/shared/layouts/MainLayout/MainLayout.module.scss @@ -2,12 +2,13 @@ min-height: 100vh; display: grid; grid-template-areas: "sidebar content rightbar"; - grid-template-columns: 284px 1fr 100px; + grid-template-columns: min-content 1fr 100px; } .sidebar { grid-area: sidebar; padding: 32px; + max-width: 284px; } .content { diff --git a/src/shared/ui/deprecated/Avatar/Avatar.tsx b/src/shared/ui/deprecated/Avatar/Avatar.tsx index 308d664..1050c68 100644 --- a/src/shared/ui/deprecated/Avatar/Avatar.tsx +++ b/src/shared/ui/deprecated/Avatar/Avatar.tsx @@ -1,7 +1,7 @@ import { CSSProperties, useMemo } from 'react'; import { classNames, Mods } from '@/shared/lib/classNames/classNames'; import cls from './Avatar.module.scss'; -import { AppImage } from '../AppImage'; +import { AppImage } from '../../redesigned/AppImage'; import UserIcon from '../../../assets/icons/user-filled.svg'; import { Skeleton } from '../Skeleton'; import { Icon } from '../Icon'; diff --git a/src/shared/ui/deprecated/Drawer/Drawer.tsx b/src/shared/ui/deprecated/Drawer/Drawer.tsx index 591adc1..7ea3832 100644 --- a/src/shared/ui/deprecated/Drawer/Drawer.tsx +++ b/src/shared/ui/deprecated/Drawer/Drawer.tsx @@ -4,9 +4,9 @@ import { AnimationProvider, useAnimationLibs, } from '@/shared/lib/components/AnimationProvider'; -import { Overlay } from '../Overlay/Overlay'; +import { Overlay } from '../../redesigned/Overlay/Overlay'; import cls from './Drawer.module.scss'; -import { Portal } from '../Portal/Portal'; +import { Portal } from '../../redesigned/Portal/Portal'; import { useTheme } from '@/shared/lib/hook/useTheme/useTheme'; interface DrawerProps { diff --git a/src/shared/ui/deprecated/Modal/Modal.tsx b/src/shared/ui/deprecated/Modal/Modal.tsx index 993fc95..ab7b991 100644 --- a/src/shared/ui/deprecated/Modal/Modal.tsx +++ b/src/shared/ui/deprecated/Modal/Modal.tsx @@ -1,8 +1,8 @@ import React, { ReactNode } from 'react'; import { classNames, Mods } from '@/shared/lib/classNames/classNames'; import { useModal } from '@/shared/lib/hook/useModal/useModal'; -import { Overlay } from '../Overlay/Overlay'; -import { Portal } from '../Portal/Portal'; +import { Overlay } from '../../redesigned/Overlay/Overlay'; +import { Portal } from '../../redesigned/Portal/Portal'; import cls from './Modal.module.scss'; import { useTheme } from '@/shared/lib/hook/useTheme/useTheme'; diff --git a/src/shared/ui/deprecated/Popups/ui/ListBox/ListBox.tsx b/src/shared/ui/deprecated/Popups/ui/ListBox/ListBox.tsx index b91f3ae..3f6ddcc 100644 --- a/src/shared/ui/deprecated/Popups/ui/ListBox/ListBox.tsx +++ b/src/shared/ui/deprecated/Popups/ui/ListBox/ListBox.tsx @@ -6,7 +6,7 @@ import popupCls from '../../styles/popup.module.scss'; import { mapDirectionClass } from '../../styles/consts'; import { Button } from '../../../Button/Button'; import cls from './ListBox.module.scss'; -import { HStack } from '../../../Stack'; +import { HStack } from '../../../../redesigned/Stack'; export interface ListBoxItems { value: string; diff --git a/src/shared/ui/deprecated/AppImage/AppImage.stories.tsx b/src/shared/ui/redesigned/AppImage/AppImage.stories.tsx similarity index 100% rename from src/shared/ui/deprecated/AppImage/AppImage.stories.tsx rename to src/shared/ui/redesigned/AppImage/AppImage.stories.tsx diff --git a/src/shared/ui/deprecated/AppImage/AppImage.tsx b/src/shared/ui/redesigned/AppImage/AppImage.tsx similarity index 88% rename from src/shared/ui/deprecated/AppImage/AppImage.tsx rename to src/shared/ui/redesigned/AppImage/AppImage.tsx index 016d370..cb184c8 100644 --- a/src/shared/ui/deprecated/AppImage/AppImage.tsx +++ b/src/shared/ui/redesigned/AppImage/AppImage.tsx @@ -42,10 +42,6 @@ export const AppImage = memo((props: AppImageProps) => { if (hasError && errorFallback) { return errorFallback; } - /** - * Устарел, используем новые компоненты из папки redesigned - * @deprecated - */ return {alt}; }); diff --git a/src/shared/ui/deprecated/AppImage/index.ts b/src/shared/ui/redesigned/AppImage/index.ts similarity index 100% rename from src/shared/ui/deprecated/AppImage/index.ts rename to src/shared/ui/redesigned/AppImage/index.ts diff --git a/src/shared/ui/redesigned/AppLogo/AppLogo.tsx b/src/shared/ui/redesigned/AppLogo/AppLogo.tsx index 16614e8..18bf71d 100644 --- a/src/shared/ui/redesigned/AppLogo/AppLogo.tsx +++ b/src/shared/ui/redesigned/AppLogo/AppLogo.tsx @@ -1,6 +1,6 @@ import React, { memo } from 'react'; import cls from './AppLogo.module.scss'; -import { HStack } from '../../deprecated/Stack'; +import { HStack } from '../Stack'; import AppSvg from '@/shared/assets/icons/app-image.svg'; import { classNames } from '@/shared/lib/classNames/classNames'; diff --git a/src/shared/ui/redesigned/Avatar/Avatar.module.scss b/src/shared/ui/redesigned/Avatar/Avatar.module.scss new file mode 100644 index 0000000..e7fcb2a --- /dev/null +++ b/src/shared/ui/redesigned/Avatar/Avatar.module.scss @@ -0,0 +1,5 @@ +.Avatar { + border-radius: 50%; + width: 100px; + height: 100px; +} diff --git a/src/shared/ui/redesigned/Avatar/Avatar.stories.tsx b/src/shared/ui/redesigned/Avatar/Avatar.stories.tsx new file mode 100644 index 0000000..f07f84e --- /dev/null +++ b/src/shared/ui/redesigned/Avatar/Avatar.stories.tsx @@ -0,0 +1,30 @@ +import { ComponentMeta, ComponentStory } from '@storybook/react'; +import { Avatar } from './Avatar'; + +export default { + title: 'shared/Avatar', + component: Avatar, + argTypes: { + backgroundColor: { control: 'color' }, + }, +} as ComponentMeta; + +const Template: ComponentStory = (args) => ; + +export const Primary = Template.bind({}); +Primary.args = { + size: 150, + src: 'https://pic.rutubelist.ru/user/3b/27/3b2758ad5492a76b578f7ee072e4e894.jpg', +}; + +export const Small = Template.bind({}); +Small.args = { + size: 50, + src: 'https://pic.rutubelist.ru/user/3b/27/3b2758ad5492a76b578f7ee072e4e894.jpg', +}; + +export const ImageEmpty = Template.bind({}); +ImageEmpty.args = { + size: 50, + alt: 'image', +}; diff --git a/src/shared/ui/redesigned/Avatar/Avatar.tsx b/src/shared/ui/redesigned/Avatar/Avatar.tsx new file mode 100644 index 0000000..6bac335 --- /dev/null +++ b/src/shared/ui/redesigned/Avatar/Avatar.tsx @@ -0,0 +1,41 @@ +import { CSSProperties, useMemo } from 'react'; +import { classNames, Mods } from '@/shared/lib/classNames/classNames'; +import cls from './Avatar.module.scss'; +import { AppImage } from '../../redesigned/AppImage'; +import UserIcon from '../../../assets/icons/user-filled.svg'; +import { Icon } from '../Icon'; +import { Skeleton } from '../../deprecated/Skeleton'; + +export interface AvatarProps { + className?: string; + src?: string; + size?: number; + alt?: string; +} + +export const Avatar = (props: AvatarProps) => { + const { className, src, size = 100, alt } = props; + const mods: Mods = {}; + + const styles = useMemo( + () => ({ + width: size, + height: size, + }), + [size], + ); + + const fallback = ; + const errorFallback = ; + + return ( + + ); +}; diff --git a/src/shared/ui/redesigned/Avatar/index.ts b/src/shared/ui/redesigned/Avatar/index.ts new file mode 100644 index 0000000..27700fe --- /dev/null +++ b/src/shared/ui/redesigned/Avatar/index.ts @@ -0,0 +1 @@ +export * from './Avatar'; diff --git a/src/shared/ui/redesigned/Card/Card.module.scss b/src/shared/ui/redesigned/Card/Card.module.scss new file mode 100644 index 0000000..f828b1b --- /dev/null +++ b/src/shared/ui/redesigned/Card/Card.module.scss @@ -0,0 +1,40 @@ +.Card { + padding: 24px; + border-radius: 12px; +} + +.withoutPaddings { + padding: 0; +} + +.normal { + background: var(--dark-bg-redesigned); +} + +.light { + background: var(--light-bg-redesigned); +} + +.outlined { + border: 1px solid var(--accent-redesigned); +} + +.max { + width: 100%; +} + +.gap_0 { + padding: 0; +} + +.gap_8 { + padding: 8px; +} + +.gap_16 { + padding: 16px; +} + +.gap_24 { + padding: 24px; +} diff --git a/src/shared/ui/redesigned/Card/Card.stories.tsx b/src/shared/ui/redesigned/Card/Card.stories.tsx new file mode 100644 index 0000000..5d9e2f8 --- /dev/null +++ b/src/shared/ui/redesigned/Card/Card.stories.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { ComponentStory, ComponentMeta } from '@storybook/react'; + +import { Text } from '../Text/Text'; +import { Card } from './Card'; + +export default { + title: 'shared/Card', + component: Card, + argTypes: { + backgroundColor: { control: 'color' }, + }, +} as ComponentMeta; + +const Template: ComponentStory = (args) => ; + +export const Normal = Template.bind({}); +Normal.args = { + children: , +}; diff --git a/src/shared/ui/redesigned/Card/Card.tsx b/src/shared/ui/redesigned/Card/Card.tsx new file mode 100644 index 0000000..36d8dde --- /dev/null +++ b/src/shared/ui/redesigned/Card/Card.tsx @@ -0,0 +1,47 @@ +import { HTMLAttributes, memo, ReactNode } from 'react'; +import { classNames } from '@/shared/lib/classNames/classNames'; +import cls from './Card.module.scss'; + +export type CardVariant = 'normal' | 'outlined' | 'light'; +export type CardPadding = '0' | '8' | '16' | '24'; + +interface CardProps extends HTMLAttributes { + className?: string; + children: ReactNode; + variant?: CardVariant; + max?: boolean; + padding?: CardPadding; +} + +const mapPaddingToClass: Record = { + '0': 'gap_0', + '8': 'gap_8', + '16': 'gap_16', + '24': 'gap_24', +}; + +export const Card = memo((props: CardProps) => { + const { + className, + children, + variant = 'normal', + max, + padding = '8', + ...otherProps + } = props; + + const paddingClass = mapPaddingToClass[padding]; + + return ( +
+ {children} +
+ ); +}); diff --git a/src/shared/ui/redesigned/Card/index.ts b/src/shared/ui/redesigned/Card/index.ts new file mode 100644 index 0000000..ca0b060 --- /dev/null +++ b/src/shared/ui/redesigned/Card/index.ts @@ -0,0 +1 @@ +export * from './Card'; diff --git a/src/shared/ui/deprecated/Overlay/Overlay.module.scss b/src/shared/ui/redesigned/Overlay/Overlay.module.scss similarity index 100% rename from src/shared/ui/deprecated/Overlay/Overlay.module.scss rename to src/shared/ui/redesigned/Overlay/Overlay.module.scss diff --git a/src/shared/ui/deprecated/Overlay/Overlay.tsx b/src/shared/ui/redesigned/Overlay/Overlay.tsx similarity index 76% rename from src/shared/ui/deprecated/Overlay/Overlay.tsx rename to src/shared/ui/redesigned/Overlay/Overlay.tsx index b3bae47..df5be9a 100644 --- a/src/shared/ui/deprecated/Overlay/Overlay.tsx +++ b/src/shared/ui/redesigned/Overlay/Overlay.tsx @@ -9,10 +9,7 @@ interface OverlayProps { export const Overlay = memo((props: OverlayProps) => { const { className, onClick } = props; - /** - * Устарел, используем новые компоненты из папки redesigned - * @deprecated - */ + return (
= { + 'bottom left': cls.optionsBottomLeft, + 'bottom right': cls.optionsBottomRight, + 'top right': cls.optionsTopRight, + 'top left': cls.optionsTopLeft, +}; diff --git a/src/shared/ui/redesigned/Popups/styles/popup.module.scss b/src/shared/ui/redesigned/Popups/styles/popup.module.scss new file mode 100644 index 0000000..bf76f25 --- /dev/null +++ b/src/shared/ui/redesigned/Popups/styles/popup.module.scss @@ -0,0 +1,46 @@ +.popup { + position: relative; +} + +.menu { + border-radius: 18px; + border: 1px solid var(--accent-redesigned); + overflow: hidden; +} + +.trigger { + background: none; + outline: none; + margin: 0; + padding: 0; + border: none; + cursor: pointer; +} + +.active { + background: var(--light-bg-redesigned); +} + +.optionsBottomLeft { + top: 100%; + right: 0; +} + +.optionsBottomRight { + top: 100%; + left: 0; +} + +.optionsTopRight { + bottom: 100%; + left: 0; +} + +.optionsTopLeft { + right: 0; + bottom: 100%; +} + +.disabled { + opacity: 0.7; +} diff --git a/src/shared/ui/redesigned/Popups/ui/Dropdown/Dropdown.module.scss b/src/shared/ui/redesigned/Popups/ui/Dropdown/Dropdown.module.scss new file mode 100644 index 0000000..b77f9e5 --- /dev/null +++ b/src/shared/ui/redesigned/Popups/ui/Dropdown/Dropdown.module.scss @@ -0,0 +1,17 @@ +.menu { + background: var(--dark-bg-redesigned); + position: absolute; + z-index: 10000; + flex-direction: column; + display: flex; +} + +.item { + padding: 10px 25px; + width: 100%; + border: none; + background: none; + outline: none; + color: var(--text-redesigned); + cursor: pointer; +} diff --git a/src/shared/ui/redesigned/Popups/ui/Dropdown/Dropdown.stories.tsx b/src/shared/ui/redesigned/Popups/ui/Dropdown/Dropdown.stories.tsx new file mode 100644 index 0000000..4c8f2ac --- /dev/null +++ b/src/shared/ui/redesigned/Popups/ui/Dropdown/Dropdown.stories.tsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { ComponentStory, ComponentMeta } from '@storybook/react'; + +import { Button } from '../../../Button/Button'; +import { Dropdown } from './Dropdown'; + +export default { + title: 'shared/Dropdown', + component: Dropdown, + argTypes: { + backgroundColor: { control: 'color' }, + }, +} as ComponentMeta; + +const Template: ComponentStory = (args) => ( + +); + +export const Basic = Template.bind({}); +Basic.args = { + items: [ + { content: 'Option 1', onClick: () => {} }, + { content: 'Option 2', onClick: () => {} }, + { + content: 'Option 3', + onClick: () => {}, + disabled: true, + }, + { + content: 'Option 4', + onClick: () => {}, + href: 'https://google.com', + }, + ], + trigger: , +}; diff --git a/src/shared/ui/redesigned/Popups/ui/Dropdown/Dropdown.tsx b/src/shared/ui/redesigned/Popups/ui/Dropdown/Dropdown.tsx new file mode 100644 index 0000000..5918e87 --- /dev/null +++ b/src/shared/ui/redesigned/Popups/ui/Dropdown/Dropdown.tsx @@ -0,0 +1,79 @@ +import { Menu } from '@headlessui/react'; +import { Fragment, ReactNode } from 'react'; +import { classNames } from '@/shared/lib/classNames/classNames'; +import { DropDownDirection } from '@/shared/types/ui'; +import { mapDirectionClass } from '../../styles/consts'; +import { AppLink } from '../../../AppLink/AppLink'; +import cls from './Dropdown.module.scss'; +import popupCls from '../../styles/popup.module.scss'; + +export interface DropdownItem { + disabled?: boolean; + content?: ReactNode; + onClick?: () => void; + href?: string; +} + +interface DropdownProps { + className?: string; + items: DropdownItem[]; + direction?: DropDownDirection; + trigger: ReactNode; +} + +export function Dropdown(props: DropdownProps) { + const { className, trigger, items, direction = 'bottom right' } = props; + + const menuClasses = [mapDirectionClass[direction], popupCls.menu]; + + return ( + + {trigger} + + {items.map((item, index) => { + const content = ({ active }: { active: boolean }) => ( + + ); + + if (item.href) { + return ( + + {content} + + ); + } + + return ( + + {content} + + ); + })} + + + ); +} diff --git a/src/shared/ui/redesigned/Popups/ui/ListBox/ListBox.module.scss b/src/shared/ui/redesigned/Popups/ui/ListBox/ListBox.module.scss new file mode 100644 index 0000000..ca4d8a0 --- /dev/null +++ b/src/shared/ui/redesigned/Popups/ui/ListBox/ListBox.module.scss @@ -0,0 +1,19 @@ +.trigger { + background: none; + border: none; + outline: none; + padding: 0; + margin: 0; +} + +.options { + background: var(--dark-bg-redesigned-bg); + position: absolute; + z-index: 10000; + border-radius: 12px; + box-shadow: 4px 4px 8px var(--dark-bg-redesigned); +} + +.item { + padding: 10px 20px; +} diff --git a/src/shared/ui/redesigned/Popups/ui/ListBox/ListBox.stories.tsx b/src/shared/ui/redesigned/Popups/ui/ListBox/ListBox.stories.tsx new file mode 100644 index 0000000..9b357cc --- /dev/null +++ b/src/shared/ui/redesigned/Popups/ui/ListBox/ListBox.stories.tsx @@ -0,0 +1,75 @@ +import React from 'react'; +import { ComponentStory, ComponentMeta } from '@storybook/react'; + +import { action } from '@storybook/addon-actions'; +// eslint-disable-next-line paths-fixes/layer-imports +import { Country } from '@/entities/Country'; +import { ListBox } from './ListBox'; + +export default { + title: 'shared/ListBox', + component: ListBox, + argTypes: { + backgroundColor: { control: 'color' }, + }, + decorators: [(story) =>
{story()}
], +} as ComponentMeta; + +const Template: ComponentStory = (args) => ( + +); + +const items = [ + { value: Country.Armenia, content: Country.Armenia }, + { value: Country.Ukraine, content: Country.Ukraine }, + { value: Country.Belarus, content: Country.Belarus }, + { value: Country.Kazakhstan, content: Country.Kazakhstan }, + { value: Country.Russia, content: Country.Russia }, +]; + +export const Default = Template.bind({}); +Default.args = { + items, + onChange: action('onChange'), + defaultValue: 'defaultValues', +}; + +export const ReadOnly = Template.bind({}); +ReadOnly.args = { + items, + value: 'item1', + onChange: action('onChange'), + readonly: true, +}; + +export const TopRightDirection = Template.bind({}); +TopRightDirection.args = { + items, + value: 'item1', + onChange: action('onChange'), + direction: 'top right', +}; + +export const TopLeftDirection = Template.bind({}); +TopLeftDirection.args = { + items, + value: 'item1', + onChange: action('onChange'), + direction: 'top left', +}; + +export const BottomLeftDirection = Template.bind({}); +BottomLeftDirection.args = { + items, + value: 'item1', + onChange: action('onChange'), + direction: 'bottom left', +}; + +export const BottomRightDirection = Template.bind({}); +BottomRightDirection.args = { + items, + value: 'item1', + onChange: action('onChange'), + direction: 'bottom right', +}; diff --git a/src/shared/ui/redesigned/Popups/ui/ListBox/ListBox.tsx b/src/shared/ui/redesigned/Popups/ui/ListBox/ListBox.tsx new file mode 100644 index 0000000..76f9259 --- /dev/null +++ b/src/shared/ui/redesigned/Popups/ui/ListBox/ListBox.tsx @@ -0,0 +1,88 @@ +import { Fragment, memo, ReactNode } from 'react'; +import { Listbox as HListBox } from '@headlessui/react'; +import { classNames } from '@/shared/lib/classNames/classNames'; +import { DropDownDirection } from '@/shared/types/ui'; +import popupCls from '../../styles/popup.module.scss'; +import { mapDirectionClass } from '../../styles/consts'; +import { Button } from '../../../Button/Button'; +import cls from './ListBox.module.scss'; +import { HStack } from '../../../../redesigned/Stack'; + +export interface ListBoxItems { + value: string; + content: ReactNode; + disabled?: boolean; +} + +interface ListBoxProps { + items: ListBoxItems[]; + className?: string; + value?: string; + defaultValue?: string; + onChange: (value: T) => void; + readonly?: boolean; + direction?: DropDownDirection; + label?: string; +} + +export const ListBox = memo((props: ListBoxProps) => { + const { + className, + items, + value, + onChange, + defaultValue, + readonly, + direction = 'bottom right', + label, + } = props; + + const optionsClasses = [mapDirectionClass[direction], popupCls.menu]; + + return ( + + {label && {`${label}>`}} + + + + + + {items.map((item) => ( + + {({ active, selected }) => ( +
  • + {item.content} +
  • + )} +
    + ))} +
    +
    +
    + ); +}); diff --git a/src/shared/ui/redesigned/Popups/ui/Popover/Popover.module.scss b/src/shared/ui/redesigned/Popups/ui/Popover/Popover.module.scss new file mode 100644 index 0000000..b34aabd --- /dev/null +++ b/src/shared/ui/redesigned/Popups/ui/Popover/Popover.module.scss @@ -0,0 +1,7 @@ +.panel { + background: var(--dark-bg-redesigned); + position: absolute; + z-index: 10000; + border-radius: 8px; + padding: 15px; +} diff --git a/src/shared/ui/redesigned/Popups/ui/Popover/Popover.stories.tsx b/src/shared/ui/redesigned/Popups/ui/Popover/Popover.stories.tsx new file mode 100644 index 0000000..e3c2a79 --- /dev/null +++ b/src/shared/ui/redesigned/Popups/ui/Popover/Popover.stories.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { ComponentStory, ComponentMeta } from '@storybook/react'; + +import { Popover } from './Popover'; + +export default { + title: 'shared/Popover', + component: Popover, + argTypes: { + backgroundColor: { control: 'color' }, + }, +} as ComponentMeta; + +const Template: ComponentStory = (args) => ( + +); + +export const Normal = Template.bind({}); +Normal.args = { + trigger: , + children:
    Popover content
    , +}; diff --git a/src/shared/ui/redesigned/Popups/ui/Popover/Popover.tsx b/src/shared/ui/redesigned/Popups/ui/Popover/Popover.tsx new file mode 100644 index 0000000..d560e3d --- /dev/null +++ b/src/shared/ui/redesigned/Popups/ui/Popover/Popover.tsx @@ -0,0 +1,34 @@ +import { memo, ReactNode } from 'react'; +import { Popover as HPopover } from '@headlessui/react'; +import { DropDownDirection } from '@/shared/types/ui'; +import { classNames } from '@/shared/lib/classNames/classNames'; +import { mapDirectionClass } from '../../styles/consts'; +import popupCls from '../../styles/popup.module.scss'; +import cls from './Popover.module.scss'; + +interface PopoverProps { + className?: string; + direction?: DropDownDirection; + trigger: ReactNode; + children: ReactNode; +} + +export const Popover = memo((props: PopoverProps) => { + const { className, trigger, direction = 'bottom right', children } = props; + + const menuClasses = [mapDirectionClass[direction], popupCls.menu]; + + return ( + + + {trigger} + + + + {children} + + + ); +}); diff --git a/src/shared/ui/deprecated/Portal/Portal.tsx b/src/shared/ui/redesigned/Portal/Portal.tsx similarity index 69% rename from src/shared/ui/deprecated/Portal/Portal.tsx rename to src/shared/ui/redesigned/Portal/Portal.tsx index 59eb6ea..880506c 100644 --- a/src/shared/ui/deprecated/Portal/Portal.tsx +++ b/src/shared/ui/redesigned/Portal/Portal.tsx @@ -8,9 +8,6 @@ interface PortalProps { export const Portal = (props: PortalProps) => { const { children, element = document.body } = props; - /** - * Устарел, используем новые компоненты из папки redesigned - * @deprecated - */ + return createPortal(children, element); }; diff --git a/src/shared/ui/deprecated/Portal/index.ts b/src/shared/ui/redesigned/Portal/index.ts similarity index 100% rename from src/shared/ui/deprecated/Portal/index.ts rename to src/shared/ui/redesigned/Portal/index.ts diff --git a/src/shared/ui/redesigned/Skeleton/Skeleton.module.scss b/src/shared/ui/redesigned/Skeleton/Skeleton.module.scss new file mode 100644 index 0000000..41d6076 --- /dev/null +++ b/src/shared/ui/redesigned/Skeleton/Skeleton.module.scss @@ -0,0 +1,29 @@ +.Skeleton { + width: 100%; + height: 50px; + position: relative; + box-shadow: 0 2px 10px 0 var(--skeleton-shadow); + overflow: hidden; + + &::before { + content: ""; + display: block; + position: absolute; + left: -150px; + top: 0; + height: 100%; + width: 80%; + background: linear-gradient(to right, transparent 0%, var(--skeleton-color) 50%, transparent 100%); + animation: load 1s cubic-bezier(0.4, 0, 0.2, 1) infinite; + } +} + +@keyframes load { + from { + left: -150px; + } + + to { + left: 100%; + } +} diff --git a/src/shared/ui/redesigned/Skeleton/Skeleton.stories.tsx b/src/shared/ui/redesigned/Skeleton/Skeleton.stories.tsx new file mode 100644 index 0000000..df29654 --- /dev/null +++ b/src/shared/ui/redesigned/Skeleton/Skeleton.stories.tsx @@ -0,0 +1,43 @@ +import React from 'react'; +import { ComponentMeta, ComponentStory } from '@storybook/react'; + +import { ThemeDecorator } from '@/shared/config/storybook/ThemeDecorator/ThemeDecorator'; +import { Skeleton } from './Skeleton'; +import { Theme } from '@/shared/const/theme'; + +export default { + title: 'shared/Skeleton', + component: Skeleton, + argTypes: { + backgroundColor: { control: 'color' }, + }, +} as ComponentMeta; + +const Template: ComponentStory = (args) => ( + +); + +export const Normal = Template.bind({}); +Normal.args = { + width: '100%', + height: 200, +}; +export const Circle = Template.bind({}); +Circle.args = { + border: '50%', + width: 100, + height: 100, +}; +export const NormalDark = Template.bind({}); +NormalDark.args = { + width: '100%', + height: 200, +}; +NormalDark.decorators = [ThemeDecorator(Theme.DARK)]; +export const CircleDark = Template.bind({}); +CircleDark.args = { + border: '50%', + width: 100, + height: 100, +}; +CircleDark.decorators = [ThemeDecorator(Theme.DARK)]; diff --git a/src/shared/ui/redesigned/Skeleton/Skeleton.tsx b/src/shared/ui/redesigned/Skeleton/Skeleton.tsx new file mode 100644 index 0000000..bddfddd --- /dev/null +++ b/src/shared/ui/redesigned/Skeleton/Skeleton.tsx @@ -0,0 +1,27 @@ +import { CSSProperties, memo } from 'react'; +import { classNames } from '@/shared/lib/classNames/classNames'; +import cls from './Skeleton.module.scss'; + +interface SkeletonProps { + className?: string; + height?: string | number; + width?: string | number; + border?: string; +} + +export const Skeleton = memo((props: SkeletonProps) => { + const { border, height, width, className } = props; + + const styles: CSSProperties = { + width, + height, + borderRadius: border, + }; + + return ( +
    + ); +}); diff --git a/src/shared/ui/redesigned/Skeleton/index.ts b/src/shared/ui/redesigned/Skeleton/index.ts new file mode 100644 index 0000000..66bc08d --- /dev/null +++ b/src/shared/ui/redesigned/Skeleton/index.ts @@ -0,0 +1 @@ +export * from './Skeleton'; diff --git a/src/shared/ui/deprecated/Stack/Flex/Flex.module.scss b/src/shared/ui/redesigned/Stack/Flex/Flex.module.scss similarity index 100% rename from src/shared/ui/deprecated/Stack/Flex/Flex.module.scss rename to src/shared/ui/redesigned/Stack/Flex/Flex.module.scss diff --git a/src/shared/ui/deprecated/Stack/Flex/Flex.stories.tsx b/src/shared/ui/redesigned/Stack/Flex/Flex.stories.tsx similarity index 100% rename from src/shared/ui/deprecated/Stack/Flex/Flex.stories.tsx rename to src/shared/ui/redesigned/Stack/Flex/Flex.stories.tsx diff --git a/src/shared/ui/deprecated/Stack/Flex/Flex.tsx b/src/shared/ui/redesigned/Stack/Flex/Flex.tsx similarity index 93% rename from src/shared/ui/deprecated/Stack/Flex/Flex.tsx rename to src/shared/ui/redesigned/Stack/Flex/Flex.tsx index bc4782e..31fd6a8 100644 --- a/src/shared/ui/deprecated/Stack/Flex/Flex.tsx +++ b/src/shared/ui/redesigned/Stack/Flex/Flex.tsx @@ -69,10 +69,7 @@ export const Flex = (props: FlexProps) => { const mods: Mods = { [cls.max]: max, }; - /** - * Устарел, используем новые компоненты из папки redesigned - * @deprecated - */ + return (
    {children} diff --git a/src/shared/ui/deprecated/Stack/HStack/HStack.tsx b/src/shared/ui/redesigned/Stack/HStack/HStack.tsx similarity index 64% rename from src/shared/ui/deprecated/Stack/HStack/HStack.tsx rename to src/shared/ui/redesigned/Stack/HStack/HStack.tsx index 81e227f..e88045a 100644 --- a/src/shared/ui/deprecated/Stack/HStack/HStack.tsx +++ b/src/shared/ui/redesigned/Stack/HStack/HStack.tsx @@ -2,10 +2,7 @@ import { memo } from 'react'; import { Flex, FlexProps } from '../Flex/Flex'; type HStackProps = Omit; -/** - * Устарел, используем новые компоненты из папки redesigned - * @deprecated - */ + export const HStack = memo((props: HStackProps) => ( )); diff --git a/src/shared/ui/deprecated/Stack/VStack/VStack.tsx b/src/shared/ui/redesigned/Stack/VStack/VStack.tsx similarity index 70% rename from src/shared/ui/deprecated/Stack/VStack/VStack.tsx rename to src/shared/ui/redesigned/Stack/VStack/VStack.tsx index fbf2ddb..d7a3d9b 100644 --- a/src/shared/ui/deprecated/Stack/VStack/VStack.tsx +++ b/src/shared/ui/redesigned/Stack/VStack/VStack.tsx @@ -2,10 +2,7 @@ import { memo } from 'react'; import { Flex, FlexProps } from '../Flex/Flex'; type VStackProps = Omit; -/** - * Устарел, используем новые компоненты из папки redesigned - * @deprecated - */ + export const VStack = memo((props: VStackProps) => { const { align = 'start' } = props; return ; diff --git a/src/shared/ui/deprecated/Stack/index.ts b/src/shared/ui/redesigned/Stack/index.ts similarity index 100% rename from src/shared/ui/deprecated/Stack/index.ts rename to src/shared/ui/redesigned/Stack/index.ts diff --git a/src/shared/ui/redesigned/Text/Text.module.scss b/src/shared/ui/redesigned/Text/Text.module.scss new file mode 100644 index 0000000..86d2bd8 --- /dev/null +++ b/src/shared/ui/redesigned/Text/Text.module.scss @@ -0,0 +1,69 @@ +.title { + color: var(--text-redesigned); +} + +.text { + color: var(--text-redesigned); +} + +.error { + .title { + color: var(--red-light); + } + + .text { + color: var(--red-dark); + } +} + +.accent { + .title { + color: var(--accent-redesigned); + } + + .text { + color: var(--accent-redesigned); + } +} + +.left { + text-align: left; +} + +.right { + text-align: right; +} + +.center { + text-align: center; +} + +.size_s { + .title { + font: var(--font-m-redesigned); + } + + .text { + font: var(--font-s-redesigned); + } +} + +.size_m { + .title { + font: var(--font-l-redesigned); + } + + .text { + font: var(--font-m-redesigned); + } +} + +.size_l { + .title { + font: var(--font-xl-redesigned); + } + + .text { + font: var(--font-l-redesigned); + } +} diff --git a/src/shared/ui/redesigned/Text/Text.stories.tsx b/src/shared/ui/redesigned/Text/Text.stories.tsx new file mode 100644 index 0000000..712efbc --- /dev/null +++ b/src/shared/ui/redesigned/Text/Text.stories.tsx @@ -0,0 +1,66 @@ +import React from 'react'; +import { ComponentMeta, ComponentStory } from '@storybook/react'; +import { ThemeDecorator } from '@/shared/config/storybook/ThemeDecorator/ThemeDecorator'; +import { Text, TextSize, TextTheme } from './Text'; +import { Theme } from '@/shared/const/theme'; + +export default { + title: 'shared/Text', + component: Text, + argTypes: { + backgroundColor: { control: 'color' }, + }, +} as ComponentMeta; + +const Template: ComponentStory = (args) => ; + +export const Primary = Template.bind({}); +Primary.args = { + title: 'title title title', + text: 'description description description', +}; + +export const PrimaryDark = Template.bind({}); +PrimaryDark.args = { + title: 'title title title', + text: 'description description description', +}; +PrimaryDark.decorators = [ThemeDecorator(Theme.DARK)]; + +export const onlyTitle = Template.bind({}); +onlyTitle.args = { + title: 'onlyTitle', +}; + +export const onlyDescription = Template.bind({}); +onlyDescription.args = { + text: 'onlyDescription', +}; + +export const Error = Template.bind({}); +Error.args = { + title: 'title title title', + text: 'description description description', + theme: TextTheme.ERROR, +}; + +export const sizeL = Template.bind({}); +sizeL.args = { + title: 'title title title', + text: 'description description description', + size: TextSize.L, +}; + +export const sizeM = Template.bind({}); +sizeM.args = { + title: 'title title title', + text: 'description description description', + size: TextSize.M, +}; + +export const sizeS = Template.bind({}); +sizeS.args = { + title: 'title title title', + text: 'description description description', + size: TextSize.S, +}; diff --git a/src/shared/ui/redesigned/Text/Text.tsx b/src/shared/ui/redesigned/Text/Text.tsx new file mode 100644 index 0000000..bbd5ae7 --- /dev/null +++ b/src/shared/ui/redesigned/Text/Text.tsx @@ -0,0 +1,69 @@ +import { memo } from 'react'; +import { classNames } from '@/shared/lib/classNames/classNames'; +import cls from './Text.module.scss'; + +export type TextVariant = 'primary' | 'error' | 'accent'; + +export type TextAlign = 'right' | 'left' | 'center'; + +export type TextSize = 's' | 'm' | 'l'; + +interface TextProps { + className?: string; + title?: string; + text?: string; + variant?: TextVariant; + align?: TextAlign; + size?: TextSize; + + 'data-testid'?: string; +} + +type HeaderTagType = 'h1' | 'h2' | 'h3'; + +const mapSizeToClass: Record = { + s: 'size_s', + m: 'size_m', + l: 'size_l', +}; + +const mapSizeToHeaderTag: Record = { + s: 'h3', + m: 'h2', + l: 'h1', +}; + +export const Text = memo((props: TextProps) => { + const { + className, + text, + title, + variant = 'primary', + align = 'left', + size = 'm', + 'data-testid': dataTestId = 'Text', + } = props; + + const HeaderTag = mapSizeToHeaderTag[size]; + const sizeClass = mapSizeToClass[size]; + + const additionalClasses = [className, cls[variant], cls[align], sizeClass]; + + return ( +
    + {title && ( + + {title} + + )} + {text && ( +

    + {text} +

    + )} +
    + ); +}); diff --git a/src/shared/ui/redesigned/Text/index.ts b/src/shared/ui/redesigned/Text/index.ts new file mode 100644 index 0000000..b0c76af --- /dev/null +++ b/src/shared/ui/redesigned/Text/index.ts @@ -0,0 +1 @@ +export * from './Text'; diff --git a/src/widgets/Navbar/ui/Navbar.tsx b/src/widgets/Navbar/ui/Navbar.tsx index b071edf..bf2da6c 100644 --- a/src/widgets/Navbar/ui/Navbar.tsx +++ b/src/widgets/Navbar/ui/Navbar.tsx @@ -1,10 +1,10 @@ import React, { memo, useCallback, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useSelector } from 'react-redux'; +import { HStack } from '@/shared/ui/redesigned/Stack'; import { Button, ButtonTheme } from '@/shared/ui/deprecated/Button'; import { AppLink, AppLinkTheme } from '@/shared/ui/deprecated/AppLink'; import { Text, TextTheme } from '@/shared/ui/deprecated/Text'; -import { HStack } from '@/shared/ui/deprecated/Stack'; import { classNames } from '@/shared/lib/classNames/classNames'; import { LoginModal } from '@/features/AuthByUsername'; import { NotificationButton } from '@/features/notificationButton'; diff --git a/src/widgets/Sidebar/ui/Sidebar/Sidebar.tsx b/src/widgets/Sidebar/ui/Sidebar/Sidebar.tsx index c588100..03b50b5 100644 --- a/src/widgets/Sidebar/ui/Sidebar/Sidebar.tsx +++ b/src/widgets/Sidebar/ui/Sidebar/Sidebar.tsx @@ -1,7 +1,7 @@ import { memo, useMemo, useState } from 'react'; import { useSelector } from 'react-redux'; +import { VStack } from '@/shared/ui/redesigned/Stack'; import { Button, ButtonSize, ButtonTheme } from '@/shared/ui/deprecated/Button'; -import { VStack } from '@/shared/ui/deprecated/Stack'; import { classNames } from '@/shared/lib/classNames/classNames'; import { getSidebarItems } from '../../model/selectors/getSidebarItems'; import { SidebarItem } from '../SidebarItem/SidebarItem';