diff --git a/packages/plasma-new-hope/src/components/Loader/Loader.styles.ts b/packages/plasma-new-hope/src/components/Loader/Loader.styles.ts index db1b7fca21..b0f97042cb 100644 --- a/packages/plasma-new-hope/src/components/Loader/Loader.styles.ts +++ b/packages/plasma-new-hope/src/components/Loader/Loader.styles.ts @@ -5,7 +5,7 @@ import { spinnerConfig, spinnerTokens } from '../Spinner'; import { progressBarCircularConfig, progressBarCircularTokens } from '../ProgressBarCircular'; import { component, mergeConfig } from '../../engines'; -import { tokens } from './Loader.tokens'; +import { tokens, classes } from './Loader.tokens'; const mergedSpinnerConfig = mergeConfig(spinnerConfig); const Spinner = component(mergedSpinnerConfig); @@ -21,6 +21,14 @@ export const base = css` width: var(${tokens.width}); height: var(${tokens.height}); + + &.${classes.loaderHorizontal} { + flex-direction: row; + } + + &.${classes.loaderVertical} { + flex-direction: column; + } `; export const StyledSpinner = styled(Spinner)` @@ -77,3 +85,23 @@ export const LoaderContentWrapper = styled.div` position: relative; z-index: 1; `; + +export const LoaderText = styled.div` + color: var(${tokens.textColor}); + font-family: var(${tokens.textFontFamily}); + font-size: var(${tokens.textFontSize}); + font-style: var(${tokens.textFontStyle}); + font-weight: var(${tokens.textFontWeight}); + letter-spacing: var(${tokens.textLetterSpacing}); + line-height: var(${tokens.textLineHeight}); + + &.${classes.loaderHorizontal} { + margin-left: var(${tokens.textMarginLeft}); + margin-top: 0; + } + + &.${classes.loaderVertical} { + margin-left: 0; + margin-top: var(${tokens.textMarginTop}); + } +`; diff --git a/packages/plasma-new-hope/src/components/Loader/Loader.tokens.ts b/packages/plasma-new-hope/src/components/Loader/Loader.tokens.ts index c7e36b302d..2b9efda2b7 100644 --- a/packages/plasma-new-hope/src/components/Loader/Loader.tokens.ts +++ b/packages/plasma-new-hope/src/components/Loader/Loader.tokens.ts @@ -1,5 +1,7 @@ export const classes = { loaderOverlay: '--plasma-loader-overlay', + loaderHorizontal: '--plasma-loader-horizontal', + loaderVertical: '--plasma-loader-vertical', }; export const tokens = { @@ -28,6 +30,16 @@ export const tokens = { spinnerSize: '--plasma-loader-spinner-size', spinnerColor: '--plasma-loader-spinner-color', + + textColor: '--plasma-loader-text-color', + textFontFamily: '--plasma-loader-text-font-family', + textFontSize: '--plasma-loader-text-font-size', + textFontStyle: '--plasma-loader-text-font-style', + textFontWeight: '--plasma-loader-text-font-weight', + textLetterSpacing: '--plasma-loader-text-letter-spacing', + textLineHeight: '--plasma-loader-text-line-height', + textMarginLeft: '--plasma-loader-text-margin-left', + textMarginTop: '--plasma-loader-text-margin-top', }; export const privateTokens = {}; diff --git a/packages/plasma-new-hope/src/components/Loader/Loader.tsx b/packages/plasma-new-hope/src/components/Loader/Loader.tsx index ce99473744..5e70c3c8d1 100644 --- a/packages/plasma-new-hope/src/components/Loader/Loader.tsx +++ b/packages/plasma-new-hope/src/components/Loader/Loader.tsx @@ -1,4 +1,5 @@ import React, { forwardRef } from 'react'; +import cls from 'classnames'; import type { RootProps } from '../../engines'; import { DEFAULT_Z_INDEX } from '../Popup/utils'; @@ -13,6 +14,7 @@ import { StyledOverlay, StyledProgressBarCircular, StyledSpinner, + LoaderText, } from './Loader.styles'; import { classes, tokens } from './Loader.tokens'; @@ -34,11 +36,30 @@ export const loaderRoot = (Root: RootProps) => style, zIndex = DEFAULT_Z_INDEX, onOverlayClick, + text, + textPosition = 'bottom', ...rest } = props; + const isHorizontalLayout = text && textPosition === 'right'; + const isVerticalLayout = text && textPosition === 'bottom'; + + const loaderClassName = [ + isHorizontalLayout && classes.loaderHorizontal, + isVerticalLayout && classes.loaderVertical, + ] + .filter(Boolean) + .join(' '); + const loaderContent = ( - + {type === 'spinner' ? ( ) : ( @@ -53,6 +74,7 @@ export const loaderRoot = (Root: RootProps) => {children} )} + {text && {text}} ); diff --git a/packages/plasma-new-hope/src/components/Loader/Loader.types.ts b/packages/plasma-new-hope/src/components/Loader/Loader.types.ts index 1d3281ed18..6d3ad5eba0 100644 --- a/packages/plasma-new-hope/src/components/Loader/Loader.types.ts +++ b/packages/plasma-new-hope/src/components/Loader/Loader.types.ts @@ -58,6 +58,15 @@ export type CustomLoaderProps = { * Контент в центре progress bar */ children?: ReactNode; + /** + * Текст, отображаемый рядом с loader + */ + text?: ReactNode; + /** + * Положение текста относительно loader + * @default bottom + */ + textPosition?: 'right' | 'bottom'; }; export type LoaderProps = HTMLAttributes & CustomLoaderProps; diff --git a/packages/plasma-new-hope/src/examples/components/Loader/Loader.config.ts b/packages/plasma-new-hope/src/examples/components/Loader/Loader.config.ts index ddac5158f4..6d9e7d89ad 100644 --- a/packages/plasma-new-hope/src/examples/components/Loader/Loader.config.ts +++ b/packages/plasma-new-hope/src/examples/components/Loader/Loader.config.ts @@ -17,6 +17,8 @@ export const config = { ${loaderTokens.spinnerColor}: var(--text-primary); ${loaderTokens.overlayColor}: var(--overlay-soft); + + ${loaderTokens.textColor}: var(--text-primary); `, secondary: css` ${loaderTokens.progressBarCircularBackgroundStroke}: var(--surface-transparent-tertiary); @@ -26,6 +28,8 @@ export const config = { ${loaderTokens.spinnerColor}: var(--text-secondary); ${loaderTokens.overlayColor}: var(--overlay-soft); + + ${loaderTokens.textColor}: var(--text-primary); `, accent: css` ${loaderTokens.progressBarCircularBackgroundStroke}: var(--surface-transparent-tertiary); @@ -35,6 +39,8 @@ export const config = { ${loaderTokens.spinnerColor}: var(--text-accent); ${loaderTokens.overlayColor}: var(--overlay-soft); + + ${loaderTokens.textColor}: var(--text-primary); `, positive: css` ${loaderTokens.progressBarCircularBackgroundStroke}: var(--surface-transparent-tertiary); @@ -44,6 +50,8 @@ export const config = { ${loaderTokens.spinnerColor}: var(--text-positive); ${loaderTokens.overlayColor}: var(--overlay-soft); + + ${loaderTokens.textColor}: var(--text-primary); `, warning: css` ${loaderTokens.progressBarCircularBackgroundStroke}: var(--surface-transparent-tertiary); @@ -53,6 +61,8 @@ export const config = { ${loaderTokens.spinnerColor}: var(--text-warning); ${loaderTokens.overlayColor}: var(--overlay-soft); + + ${loaderTokens.textColor}: var(--text-primary); `, negative: css` ${loaderTokens.progressBarCircularBackgroundStroke}: var(--surface-transparent-tertiary); @@ -62,6 +72,8 @@ export const config = { ${loaderTokens.spinnerColor}: var(--text-negative); ${loaderTokens.overlayColor}: var(--overlay-soft); + + ${loaderTokens.textColor}: var(--text-primary); `, info: css` ${loaderTokens.progressBarCircularBackgroundStroke}: var(--surface-transparent-tertiary); @@ -71,6 +83,8 @@ export const config = { ${loaderTokens.spinnerColor}: var(--text-info); ${loaderTokens.overlayColor}: var(--overlay-soft); + + ${loaderTokens.textColor}: var(--text-primary); `, }, size: { @@ -91,6 +105,24 @@ export const config = { ${loaderTokens.progressBarCircularContentLineHeight}: var(--plasma-typo-h2-line-height); ${loaderTokens.spinnerSize}: 8rem; + + ${loaderTokens.textFontFamily}: var(--plasma-typo-body-l-font-family); + ${loaderTokens.textFontSize}: var(--plasma-typo-body-l-font-size); + ${loaderTokens.textFontStyle}: var(--plasma-typo-body-l-font-style); + ${loaderTokens.textFontWeight}: var(--plasma-typo-body-l-font-weight); + ${loaderTokens.textLetterSpacing}: var(--plasma-typo-body-l-letter-spacing); + ${loaderTokens.textLineHeight}: var(--plasma-typo-body-l-line-height); + ${loaderTokens.textMarginLeft}: 1rem; + ${loaderTokens.textMarginTop}: 1rem; + + ${loaderTokens.textFontFamily}: var(--plasma-typo-body-l-font-family); + ${loaderTokens.textFontSize}: var(--plasma-typo-body-l-font-size); + ${loaderTokens.textFontStyle}: var(--plasma-typo-body-l-font-style); + ${loaderTokens.textFontWeight}: var(--plasma-typo-body-l-font-weight); + ${loaderTokens.textLetterSpacing}: var(--plasma-typo-body-l-letter-spacing); + ${loaderTokens.textLineHeight}: var(--plasma-typo-body-l-line-height); + ${loaderTokens.textMarginLeft}: 1rem; + ${loaderTokens.textMarginTop}: 1rem; `, xl: css` ${loaderTokens.width}: 100%; @@ -109,6 +141,15 @@ export const config = { ${loaderTokens.progressBarCircularContentLineHeight}: var(--plasma-typo-h5-line-height); ${loaderTokens.spinnerSize}: 5.5rem; + + ${loaderTokens.textFontFamily}: var(--plasma-typo-body-l-font-family); + ${loaderTokens.textFontSize}: var(--plasma-typo-body-l-font-size); + ${loaderTokens.textFontStyle}: var(--plasma-typo-body-l-font-style); + ${loaderTokens.textFontWeight}: var(--plasma-typo-body-l-font-weight); + ${loaderTokens.textLetterSpacing}: var(--plasma-typo-body-l-letter-spacing); + ${loaderTokens.textLineHeight}: var(--plasma-typo-body-l-line-height); + ${loaderTokens.textMarginLeft}: 1rem; + ${loaderTokens.textMarginTop}: 1rem; `, l: css` ${loaderTokens.width}: 100%; @@ -127,6 +168,15 @@ export const config = { ${loaderTokens.progressBarCircularContentLineHeight}: var(--plasma-typo-body-l-line-height); ${loaderTokens.spinnerSize}: 3.5rem; + + ${loaderTokens.textFontFamily}: var(--plasma-typo-body-l-font-family); + ${loaderTokens.textFontSize}: var(--plasma-typo-body-l-font-size); + ${loaderTokens.textFontStyle}: var(--plasma-typo-body-l-font-style); + ${loaderTokens.textFontWeight}: var(--plasma-typo-body-l-font-weight); + ${loaderTokens.textLetterSpacing}: var(--plasma-typo-body-l-letter-spacing); + ${loaderTokens.textLineHeight}: var(--plasma-typo-body-l-line-height); + ${loaderTokens.textMarginLeft}: 1rem; + ${loaderTokens.textMarginTop}: 1rem; `, m: css` ${loaderTokens.width}: 100%; @@ -145,6 +195,15 @@ export const config = { ${loaderTokens.progressBarCircularContentLineHeight}: var(--plasma-typo-body-m-line-height); ${loaderTokens.spinnerSize}: 3rem; + + ${loaderTokens.textFontFamily}: var(--plasma-typo-body-m-font-family); + ${loaderTokens.textFontSize}: var(--plasma-typo-body-m-font-size); + ${loaderTokens.textFontStyle}: var(--plasma-typo-body-m-font-style); + ${loaderTokens.textFontWeight}: var(--plasma-typo-body-m-font-weight); + ${loaderTokens.textLetterSpacing}: var(--plasma-typo-body-m-letter-spacing); + ${loaderTokens.textLineHeight}: var(--plasma-typo-body-m-line-height); + ${loaderTokens.textMarginLeft}: 0.75rem; + ${loaderTokens.textMarginTop}: 0.625rem; `, s: css` ${loaderTokens.width}: 100%; @@ -163,6 +222,15 @@ export const config = { ${loaderTokens.progressBarCircularContentLineHeight}: var(--plasma-typo-body-s-line-height); ${loaderTokens.spinnerSize}: 2.25rem; + + ${loaderTokens.textFontFamily}: var(--plasma-typo-body-s-font-family); + ${loaderTokens.textFontSize}: var(--plasma-typo-body-s-font-size); + ${loaderTokens.textFontStyle}: var(--plasma-typo-body-s-font-style); + ${loaderTokens.textFontWeight}: var(--plasma-typo-body-s-font-weight); + ${loaderTokens.textLetterSpacing}: var(--plasma-typo-body-s-letter-spacing); + ${loaderTokens.textLineHeight}: var(--plasma-typo-body-s-line-height); + ${loaderTokens.textMarginLeft}: 0.5rem; + ${loaderTokens.textMarginTop}: 0.5rem; `, xs: css` ${loaderTokens.width}: 100%; @@ -181,6 +249,15 @@ export const config = { ${loaderTokens.progressBarCircularContentLineHeight}: var(--plasma-typo-body-xs-line-height); ${loaderTokens.spinnerSize}: 1.5rem; + + ${loaderTokens.textFontFamily}: var(--plasma-typo-body-xs-font-family); + ${loaderTokens.textFontSize}: var(--plasma-typo-body-xs-font-size); + ${loaderTokens.textFontStyle}: var(--plasma-typo-body-xs-font-style); + ${loaderTokens.textFontWeight}: var(--plasma-typo-body-xs-font-weight); + ${loaderTokens.textLetterSpacing}: var(--plasma-typo-body-xs-letter-spacing); + ${loaderTokens.textLineHeight}: var(--plasma-typo-body-xs-line-height); + ${loaderTokens.textMarginLeft}: 0.5rem; + ${loaderTokens.textMarginTop}: 0.5rem; `, xxs: css` ${loaderTokens.width}: 100%; @@ -199,6 +276,15 @@ export const config = { ${loaderTokens.progressBarCircularContentLineHeight}: var(--plasma-typo-body-xxs-line-height); ${loaderTokens.spinnerSize}: 1rem; + + ${loaderTokens.textFontFamily}: var(--plasma-typo-body-xxs-font-family); + ${loaderTokens.textFontSize}: var(--plasma-typo-body-xxs-font-size); + ${loaderTokens.textFontStyle}: var(--plasma-typo-body-xxs-font-style); + ${loaderTokens.textFontWeight}: var(--plasma-typo-body-xxs-font-weight); + ${loaderTokens.textLetterSpacing}: var(--plasma-typo-body-xxs-letter-spacing); + ${loaderTokens.textLineHeight}: var(--plasma-typo-body-xxs-line-height); + ${loaderTokens.textMarginLeft}: 0.5rem; + ${loaderTokens.textMarginTop}: 0.5rem; `, }, }, diff --git a/packages/plasma-new-hope/src/examples/components/Loader/Loader.stories.tsx b/packages/plasma-new-hope/src/examples/components/Loader/Loader.stories.tsx index 2fadf66ca2..5fc64a68a5 100644 --- a/packages/plasma-new-hope/src/examples/components/Loader/Loader.stories.tsx +++ b/packages/plasma-new-hope/src/examples/components/Loader/Loader.stories.tsx @@ -69,7 +69,6 @@ const meta: Meta = { control: { type: 'boolean', }, - description: 'Наличие overlay на фоне', }, overlayColor: { control: { @@ -84,7 +83,6 @@ const meta: Meta = { control: { type: 'boolean', }, - description: 'Применить blur эффект к overlay', if: { arg: 'hasOverlay', eq: true, @@ -94,12 +92,25 @@ const meta: Meta = { control: { type: 'text', }, - description: 'Z-index для loader и overlay', if: { arg: 'hasOverlay', eq: true, }, }, + text: { + control: { + type: 'text', + }, + }, + textPosition: { + options: ['bottom', 'right'], + control: { + type: 'radio', + }, + if: { + arg: 'text', + }, + }, }, }; @@ -164,6 +175,51 @@ export const Default: StoryObj = { hasOverlay: false, type: 'spinner', hasTrack: true, + text: '', + textPosition: 'bottom', + }, + render: ({ ...args }) => { + return ; + }, +}; + +export const WithTextBottom: StoryObj = { + args: { + view: 'default', + spinnerSize: 'm', + hasOverlay: false, + type: 'spinner', + text: 'Загрузка данных...', + textPosition: 'bottom', + }, + render: ({ ...args }) => { + return ; + }, +}; + +export const WithTextRight: StoryObj = { + args: { + view: 'default', + spinnerSize: 's', + hasOverlay: false, + type: 'spinner', + text: 'Загрузка...', + textPosition: 'right', + }, + render: ({ ...args }) => { + return ; + }, +}; + +export const WithTextProgress: StoryObj = { + args: { + view: 'default', + progressSize: 'l', + hasOverlay: false, + type: 'progress', + hasTrack: true, + text: 'Обработка файлов', + textPosition: 'bottom', }, render: ({ ...args }) => { return ; diff --git a/packages/sdds-cs/src/components/Loader/Loader.config.ts b/packages/sdds-cs/src/components/Loader/Loader.config.ts new file mode 100644 index 0000000000..a659eeac0b --- /dev/null +++ b/packages/sdds-cs/src/components/Loader/Loader.config.ts @@ -0,0 +1,131 @@ +import { css, loaderTokens } from '@salutejs/plasma-new-hope/styled-components'; + +export const config = { + defaults: { + view: 'default', + size: 'm', + }, + variations: { + view: { + default: css` + ${loaderTokens.progressBarCircularBackgroundStroke}: var(--surface-transparent-tertiary); + ${loaderTokens.progressBarCircularStroke}: var(--surface-solid-default); + ${loaderTokens.progressBarCircularContentColor}: var(--text-primary); + + ${loaderTokens.spinnerColor}: #657179; + + ${loaderTokens.overlayColor}: var(--overlay-soft); + `, + secondary: css` + ${loaderTokens.progressBarCircularBackgroundStroke}: var(--surface-transparent-tertiary); + ${loaderTokens.progressBarCircularStroke}: var(--surface-transparent-secondary); + ${loaderTokens.progressBarCircularContentColor}: var(--text-primary); + + ${loaderTokens.spinnerColor}: var(--text-secondary); + + ${loaderTokens.overlayColor}: var(--overlay-soft); + `, + accent: css` + ${loaderTokens.progressBarCircularBackgroundStroke}: var(--surface-transparent-tertiary); + ${loaderTokens.progressBarCircularStroke}: var(--surface-accent); + ${loaderTokens.progressBarCircularContentColor}: var(--text-primary); + + ${loaderTokens.spinnerColor}: var(--text-accent); + + ${loaderTokens.overlayColor}: var(--overlay-soft); + `, + positive: css` + ${loaderTokens.progressBarCircularBackgroundStroke}: var(--surface-transparent-tertiary); + ${loaderTokens.progressBarCircularStroke}: var(--surface-positive); + ${loaderTokens.progressBarCircularContentColor}: var(--text-primary); + + ${loaderTokens.spinnerColor}: var(--text-positive); + + ${loaderTokens.overlayColor}: var(--overlay-soft); + `, + warning: css` + ${loaderTokens.progressBarCircularBackgroundStroke}: var(--surface-transparent-tertiary); + ${loaderTokens.progressBarCircularStroke}: var(--surface-warning); + ${loaderTokens.progressBarCircularContentColor}: var(--text-primary); + + ${loaderTokens.spinnerColor}: var(--text-warning); + + ${loaderTokens.overlayColor}: var(--overlay-soft); + `, + negative: css` + ${loaderTokens.progressBarCircularBackgroundStroke}: var(--surface-transparent-tertiary); + ${loaderTokens.progressBarCircularStroke}: var(--surface-negative); + ${loaderTokens.progressBarCircularContentColor}: var(--text-primary); + + ${loaderTokens.spinnerColor}: var(--text-negative); + + ${loaderTokens.overlayColor}: var(--overlay-soft); + `, + info: css` + ${loaderTokens.progressBarCircularBackgroundStroke}: var(--surface-transparent-tertiary); + ${loaderTokens.progressBarCircularStroke}: var(--surface-info); + ${loaderTokens.progressBarCircularContentColor}: var(--text-primary); + + ${loaderTokens.spinnerColor}: var(--text-info); + + ${loaderTokens.overlayColor}: var(--overlay-soft); + `, + }, + size: { + xl: css` + ${loaderTokens.width}: 100%; + ${loaderTokens.height}: 100%; + + ${loaderTokens.progressBarCircularSize}: 88; + ${loaderTokens.progressBarCircularHeight}: 5.5rem; + ${loaderTokens.progressBarCircularWidth}: 5.5rem; + ${loaderTokens.progressBarCircularStrokeWidth}: 0.25rem; + ${loaderTokens.progressBarCircularStrokeSize}: 4; + ${loaderTokens.progressBarCircularContentFontFamily}: var(--plasma-typo-h5-font-family); + ${loaderTokens.progressBarCircularContentFontSize}: var(--plasma-typo-h5-font-size); + ${loaderTokens.progressBarCircularContentFontStyle}: var(--plasma-typo-h5-font-style); + ${loaderTokens.progressBarCircularContentFontWeight}: var(--plasma-typo-h5-bold-font-weight); + ${loaderTokens.progressBarCircularContentLetterSpacing}: var(--plasma-typo-h5-letter-spacing); + ${loaderTokens.progressBarCircularContentLineHeight}: var(--plasma-typo-h5-line-height); + + ${loaderTokens.spinnerSize}: 5.5rem; + `, + l: css` + ${loaderTokens.width}: 100%; + ${loaderTokens.height}: 100%; + + ${loaderTokens.progressBarCircularSize}: 48; + ${loaderTokens.progressBarCircularHeight}: 3rem; + ${loaderTokens.progressBarCircularWidth}: 3rem; + ${loaderTokens.progressBarCircularStrokeWidth}: 0.125rem; + ${loaderTokens.progressBarCircularStrokeSize}: 2; + ${loaderTokens.progressBarCircularContentFontFamily}: var(--plasma-typo-body-l-font-family); + ${loaderTokens.progressBarCircularContentFontSize}: var(--plasma-typo-body-l-font-size); + ${loaderTokens.progressBarCircularContentFontStyle}: var(--plasma-typo-body-l-font-style); + ${loaderTokens.progressBarCircularContentFontWeight}: var(--plasma-typo-body-l-body-font-weight); + ${loaderTokens.progressBarCircularContentLetterSpacing}: var(--plasma-typo-body-l-letter-spacing); + ${loaderTokens.progressBarCircularContentLineHeight}: var(--plasma-typo-body-l-line-height); + + ${loaderTokens.spinnerSize}: 3rem; + `, + s: css` + ${loaderTokens.width}: 100%; + ${loaderTokens.height}: 100%; + + ${loaderTokens.progressBarCircularSize}: 24; + ${loaderTokens.progressBarCircularHeight}: 1.5rem; + ${loaderTokens.progressBarCircularWidth}: 1.5rem; + ${loaderTokens.progressBarCircularStrokeWidth}: 0.125rem; + ${loaderTokens.progressBarCircularStrokeSize}: 2; + ${loaderTokens.progressBarCircularContentFontFamily}: var(--plasma-typo-body-s-font-family); + ${loaderTokens.progressBarCircularContentFontSize}: var(--plasma-typo-body-s-font-size); + ${loaderTokens.progressBarCircularContentFontStyle}: var(--plasma-typo-body-s-font-style); + ${loaderTokens.progressBarCircularContentFontWeight}: var(--plasma-typo-body-s-body-font-weight); + ${loaderTokens.progressBarCircularContentLetterSpacing}: var(--plasma-typo-body-s-letter-spacing); + ${loaderTokens.progressBarCircularContentLineHeight}: var(--plasma-typo-body-s-line-height); + + ${loaderTokens.spinnerSize}: 1.5rem; + `, + }, + }, +}; diff --git a/packages/sdds-cs/src/components/Loader/Loader.stories.tsx b/packages/sdds-cs/src/components/Loader/Loader.stories.tsx new file mode 100644 index 0000000000..abaaab22ee --- /dev/null +++ b/packages/sdds-cs/src/components/Loader/Loader.stories.tsx @@ -0,0 +1,123 @@ +import type { StoryObj, Meta } from '@storybook/react-vite'; +import { InSpacingDecorator, getConfigVariations, disableProps } from '@salutejs/plasma-sb-utils'; +import React, { ComponentProps, useEffect } from 'react'; +import { IconCross } from '@salutejs/plasma-icons'; + +import { Button } from '../Button'; + +import { config } from './Loader.config'; + +import { Loader } from '.'; + +const { views, sizes } = getConfigVariations(config); + +const sizeSpinner = ['s', 'l', 'xl']; + +type StoryPropsDefault = ComponentProps & { + progressSize?: string; + spinnerSize?: string; +}; + +const meta: Meta = { + title: 'Overlay/Loader', + component: Loader, + decorators: [InSpacingDecorator], + argTypes: { + view: { + options: views, + control: { + type: 'select', + }, + }, + spinnerSize: { + options: sizeSpinner, + control: { + type: 'select', + }, + }, + type: { + options: ['spinner'], + control: { + type: 'select', + }, + }, + hasOverlay: { + control: { + type: 'boolean', + }, + description: 'Наличие overlay на фоне', + }, + overlayColor: { + control: { + type: 'color', + }, + if: { + arg: 'hasOverlay', + eq: true, + }, + }, + withBlur: { + control: { + type: 'boolean', + }, + description: 'Применить blur эффект к overlay', + if: { + arg: 'hasOverlay', + eq: true, + }, + }, + zIndex: { + control: { + type: 'text', + }, + description: 'Z-index для loader і overlay', + if: { + arg: 'hasOverlay', + eq: true, + }, + }, + ...disableProps(['type', 'progressSize', 'hasTrack', 'strokeSize']), + }, +}; + +export default meta; + +const LoaderContent = (args) => { + const [progress, setProgress] = React.useState(0); + const [toggle, setToggle] = React.useState(false); + + useEffect(() => { + let counter = 0; + const interval = setInterval(() => { + if (counter < 100 && toggle) { + counter++; + setProgress(counter); + } else if (counter === 100 && toggle) { + counter++; + clearInterval(interval); + setTimeout(() => { + setProgress(0); + setToggle(false); + }, 300); + } + }, 300); + }, [toggle, setProgress]); + + return ( +
+ + {toggle && } +
+ ); +}; + +export const Default: StoryObj = { + args: { + view: 'default', + spinnerSize: 's', + hasOverlay: false, + }, + render: ({ ...args }) => { + return ; + }, +}; diff --git a/packages/sdds-cs/src/components/Loader/Loader.ts b/packages/sdds-cs/src/components/Loader/Loader.ts new file mode 100644 index 0000000000..d3a34e0652 --- /dev/null +++ b/packages/sdds-cs/src/components/Loader/Loader.ts @@ -0,0 +1,7 @@ +import { loaderConfig, component, mergeConfig } from '@salutejs/plasma-new-hope/styled-components'; + +import { config } from './Loader.config'; + +const mergedConfig = mergeConfig(loaderConfig, config); + +export const Loader = component(mergedConfig); diff --git a/packages/sdds-cs/src/components/Loader/index.ts b/packages/sdds-cs/src/components/Loader/index.ts new file mode 100644 index 0000000000..2de78b4ea2 --- /dev/null +++ b/packages/sdds-cs/src/components/Loader/index.ts @@ -0,0 +1,3 @@ +export { Loader } from './Loader'; + +export type { LoaderProps } from '@salutejs/plasma-new-hope/styled-components';