From af4fa8b1c76fbec097f98e453dd2cc38ce7f74f2 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 27 Oct 2026 13:42:52 +0300 Subject: [PATCH 01/19] =?UTF-8?q?docs(input):=20=D0=B2=D0=BE=D1=81=D1=81?= =?UTF-8?q?=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20=D1=81?= =?UTF-8?q?=D1=82=D0=BE=D1=80=D0=B8=20=D0=B3=D1=80=D1=83=D0=BF=D0=BF=D1=8B?= =?UTF-8?q?=20Input?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Input/stories/InputGroup.stories.tsx | 56 ++++++++ .../Input/stories/InputMask.stories.tsx | 123 ++++++++++++++++++ .../Input/stories/InputText.stories.tsx | 57 ++++++++ 3 files changed, 236 insertions(+) create mode 100644 src/components/Input/stories/InputGroup.stories.tsx create mode 100644 src/components/Input/stories/InputMask.stories.tsx create mode 100644 src/components/Input/stories/InputText.stories.tsx diff --git a/src/components/Input/stories/InputGroup.stories.tsx b/src/components/Input/stories/InputGroup.stories.tsx new file mode 100644 index 00000000..75403c3b --- /dev/null +++ b/src/components/Input/stories/InputGroup.stories.tsx @@ -0,0 +1,56 @@ +import { useArgs } from '@storybook/preview-api' +import type { Meta, StoryObj } from '@storybook/react' +import { IconLock, IconUser } from '@tabler/icons-react-native' +import { useCallback } from 'react' + +import { LegacyInputGroup as InputGroup } from '../deprecated/LegacyInputGroup' + +const meta: Meta = { + title: 'Legacy/InputGroup', + args: { + clearable: true, + disabled: false, + state: 'default', + floatLabel: false, + placeholder: 'Placeholder', + value: '', + size: 'base', + }, + argTypes: { + state: { control: 'radio', options: ['default', 'danger'] }, + size: { control: 'radio', options: ['base', 'medium', 'large', 'xlarge'] }, + }, + render: (args) => { + const [, updateArgs] = useArgs() + + const onChangeText = useCallback( + (nextValue: string) => updateArgs({ value: nextValue }), + [updateArgs] + ) + + return + }, +} + +export default meta + +type Story = StoryObj + +const InputGroupStory: Story = { + args: { left: 'left text', right: 'right text' }, + argTypes: { + left: { + options: ['text', 'IconUser', 'IconLock'], + control: { type: 'radio' }, + mapping: { text: 'left text', IconUser, IconLock }, + defaultValue: 'text', + }, + right: { + options: ['text', 'IconUser', 'IconLock'], + control: { type: 'radio' }, + mapping: { text: 'right text', IconUser, IconLock }, + }, + }, +} + +export { InputGroupStory as InputGroup } diff --git a/src/components/Input/stories/InputMask.stories.tsx b/src/components/Input/stories/InputMask.stories.tsx new file mode 100644 index 00000000..4a6e0da7 --- /dev/null +++ b/src/components/Input/stories/InputMask.stories.tsx @@ -0,0 +1,123 @@ +import type { Meta, StoryObj } from '@storybook/react' +import { + type ComponentProps, + type ComponentType, + type RefObject, + useCallback, + useState, +} from 'react' +import { View } from 'react-native' +import { + MaskedTextInput, + type MaskedTextInputProps, + type MaskedTextInputRef, +} from 'react-native-advanced-input-mask' + +import { Body } from '../../Typography' +import { LegacyInputText as InputText } from '../deprecated/LegacyInputText' + +type InputTextProps = ComponentProps + +type MaskedInputProps = Omit & + Pick & { + readonly Control: ComponentType + } + +/** + * Пример реализации компонента для ввода текста с маской. + * Основана на пакете react-native-advanced-input-mask + */ +const MaskedInput = ({ + mask, + onChangeText: onChangeTextProp, + Control, + ...other +}: MaskedInputProps) => { + const [value, setValue] = useState('') + + // Коллбэк, адаптированный для использования как с MaskedTextInput, так и с дефолтным TextInput + const onChangeText = useCallback( + ( + formatted: string, + extracted: string, + tailPlacehilder: string, + complete: boolean + ) => { + setValue(formatted) + onChangeTextProp?.( + formatted, + extracted ?? formatted, + tailPlacehilder, + complete + ) + }, + [onChangeTextProp] + ) + + return ( + ( + } + onChangeText={onChangeText} + /> + )} + value={value} + // Передаем коллбэк для поддержания дополнительной логики в разных видах контролов. Например, для очистки поля + onChangeText={onChangeText} + /> + ) +} + +const meta: Meta = { + title: 'Legacy/InputMask', + args: { + clearable: true, + disabled: false, + state: 'default', + placeholder: 'Placeholder', + floatLabel: false, + mask: '+7 ([000]) [000]-[00]-[00]', + size: 'base', + }, + argTypes: { + state: { control: 'radio', options: ['default', 'danger'] }, + size: { control: 'radio', options: ['base', 'large', 'xlarge'] }, + mask: { + control: 'radio', + options: [ + '+7 ([000]) [000]-[00]-[00]', + '[00]/[00]/[0000]', + '[000]-[000]', + ], + }, + }, + render: (args) => { + const [formatted, setFormatted] = useState('') + const [extracted, setExtracted] = useState('') + + const onChangeText = useCallback((formatted: string, extracted: string) => { + setFormatted(formatted) + setExtracted(extracted) + }, []) + + return ( + + Formatted Text: "{formatted}" + Extracted Text: "{extracted}" + + + ) + }, +} + +export default meta + +type Story = StoryObj + +const MaskedInputStory: Story = {} + +export { MaskedInputStory as InputMask } diff --git a/src/components/Input/stories/InputText.stories.tsx b/src/components/Input/stories/InputText.stories.tsx new file mode 100644 index 00000000..a9abdc40 --- /dev/null +++ b/src/components/Input/stories/InputText.stories.tsx @@ -0,0 +1,57 @@ +import { useArgs } from '@storybook/preview-api' +import type { Meta, StoryObj } from '@storybook/react' +import { useCallback, useEffect, useState } from 'react' + +import type { InputTextBase } from '../deprecated/InputTextBase/InputTextBase' +import { LegacyInputText as InputText } from '../deprecated/LegacyInputText' + +const meta: Meta = { + title: 'Legacy/InputText', + args: { + clearable: true, + disabled: false, + state: 'default', + placeholder: 'Placeholder', + value: '', + floatLabel: false, + secureTextEntry: false, + loading: false, + editable: true, + size: 'base', + }, + argTypes: { + state: { control: 'radio', options: ['default', 'danger'] }, + secureTextEntry: { + control: 'radio', + options: ['true', 'false', 'toggleable'], + mapping: { true: true, false: false, toggleable: 'toggleable' }, + }, + size: { control: 'radio', options: ['base', 'medium', 'large', 'xlarge'] }, + }, + render: (args) => { + const [, updateArgs] = useArgs() + const [value, setValue] = useState(args.value) + + const onChangeText = useCallback( + (nextValue: string) => { + setValue(nextValue) + updateArgs({ value: nextValue }) + }, + [updateArgs] + ) + + useEffect(() => { + setValue(args.value) + }, [args.value]) + + return + }, +} + +export default meta + +type Story = StoryObj + +const InputTextStory: Story = {} + +export { InputTextStory as InputText } From 861aef46747ce07280ffb25a24dbafe2e8aa9505 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 27 Oct 2026 13:43:00 +0300 Subject: [PATCH 02/19] =?UTF-8?q?docs(input-switch):=20=D0=B2=D0=BE=D1=81?= =?UTF-8?q?=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20?= =?UTF-8?q?=D1=81=D1=82=D0=BE=D1=80=D0=B8=20InputSwitch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../InputSwitch/InputSwitch.stories.tsx | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/components/InputSwitch/InputSwitch.stories.tsx diff --git a/src/components/InputSwitch/InputSwitch.stories.tsx b/src/components/InputSwitch/InputSwitch.stories.tsx new file mode 100644 index 00000000..75b7c3eb --- /dev/null +++ b/src/components/InputSwitch/InputSwitch.stories.tsx @@ -0,0 +1,39 @@ +import { useArgs } from '@storybook/preview-api' +import type { Meta, StoryObj } from '@storybook/react' +import { useCallback } from 'react' + +import { InputSwitch } from './InputSwitch' + +const meta: Meta = { + title: 'Legacy/InputSwitch', + component: InputSwitch, + args: { disabled: false, danger: false, checked: false }, + argTypes: { + disabled: { control: 'boolean' }, + danger: { control: 'boolean' }, + checked: { control: 'boolean' }, + onCheckedChange: { action: 'onCheckedChange', control: false }, + }, + render: (args) => { + const { onCheckedChange: onCheckedChangeAction } = args + const [, updateArgs] = useArgs() + + const onCheckedChange = useCallback( + (nextValue: boolean) => { + updateArgs({ checked: nextValue }) + onCheckedChangeAction?.(nextValue) + }, + [onCheckedChangeAction, updateArgs] + ) + + return + }, +} + +export default meta + +type Story = StoryObj + +const InputSwitchStory: Story = { name: 'InputSwitch' } + +export { InputSwitchStory as InputSwitch } From bddbc93bd9a2221718d102bb7c276726f21d68f3 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 27 Oct 2026 13:43:10 +0300 Subject: [PATCH 03/19] =?UTF-8?q?docs(typography):=20=D0=B4=D0=BE=D0=B1?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D1=81=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D0=B8=20Overview=20=D0=B4=D0=BB=D1=8F=20=D1=82=D0=B8=D0=BF?= =?UTF-8?q?=D0=BE=D0=B3=D1=80=D0=B0=D1=84=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Typography/Typography.stories.tsx | 295 ++++++++++++++++++ 1 file changed, 295 insertions(+) create mode 100644 src/components/Typography/Typography.stories.tsx diff --git a/src/components/Typography/Typography.stories.tsx b/src/components/Typography/Typography.stories.tsx new file mode 100644 index 00000000..33472b97 --- /dev/null +++ b/src/components/Typography/Typography.stories.tsx @@ -0,0 +1,295 @@ +import type { Meta, StoryObj } from '@storybook/react' +import { IconArrowUpRight, IconInfoCircle } from '@tabler/icons-react-native' +import type { ReactNode } from 'react' +import { ScrollView, View } from 'react-native' +import { StyleSheet, useUnistyles } from 'react-native-unistyles' + +import { Anchor, Body, Caption, Service, Subtitle, Title } from './index' + +interface OverviewArgs { + readonly sampleText: string + readonly showDetails: boolean + readonly onLinkPress: () => void +} + +const titleLevels = [ + 'd1', + 'd2', + 'd3', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', +] as const +const bodySizes = ['xl', 'lg', 'base'] as const +const textColors = ['default', 'secondary', 'primary'] as const +const statuses = [ + { variant: 'success', text: 'Посылка доставлена' }, + { variant: 'info', text: 'Курьер уже в пути' }, + { variant: 'warning', text: 'Проверьте адрес доставки' }, + { variant: 'danger', text: 'Не удалось сохранить изменения' }, + { variant: 'help', text: 'Поможем разобраться' }, +] as const + +const Section = ({ + number, + title, + description, + children, +}: { + readonly number: string + readonly title: string + readonly description: string + readonly children: ReactNode +}) => ( + + + {number} + {title} + {description} + + {children} + +) + +const Specimen = ({ + label, + showDetails, + children, +}: { + readonly label: string + readonly showDetails: boolean + readonly children: ReactNode +}) => ( + + {showDetails ? {label} : null} + {children} + +) + +const TypographyOverview = ({ + sampleText, + showDetails, + onLinkPress, +}: OverviewArgs) => { + const { theme } = useUnistyles() + + return ( + + + Основы дизайн-системы + Типографика + + От первого заголовка до последней подписи. Одна шкала — разные роли. + + + + Заголовки + {theme.fonts.fontFamily.heading} + Аа Бб Вв · Aa Bb Cc · 0123 + + + Текст и интерфейс + {theme.fonts.fontFamily.base} + Аа Бб Вв · Aa Bb Cc · 0123 + + + + +
+ {titleLevels.map((level) => ( + + {sampleText} + + ))} +
+ +
+ {[true, false].map((base) => ( + + {sampleText} + + ))} +
+ +
+ {bodySizes.map((size) => ( + + {showDetails ? ( + {size.toUpperCase()} + ) : null} + {sampleText} + + {sampleText} + + + ))} + + Текст в контексте + Ближе, чем кажется + + За каждой посылкой — чья-то история. Книга для друга, подарок к + празднику или вещь, которую давно ждали. Мы помогаем важному + оказаться рядом. + + + Узнать больше + + + + {textColors.map((color) => ( + + {sampleText} + + ))} + Прежнее значение + Недоступное действие + +
+ +
+ {textColors.map((color) => ( + + {sampleText} + + ))} + + Срок хранения — 7 дней + + + Информация появится позже + +
+ +
+ {statuses.map(({ variant, text }) => ( + + + {text} + + + {text} + + + ))} +
+ +
+ + Отследить посылку + + Найти ближайший пункт + + + Условия доставки + + + + Продолжая, вы принимаете{' '} + + условия сервиса + {' '} + и соглашаетесь с правилами доставки. + +
+
+ ) +} + +const meta = { + title: 'Typography/Overview', + component: TypographyOverview, + args: { sampleText: 'Доставка без границ', showDetails: true }, + argTypes: { + sampleText: { control: 'text' }, + showDetails: { control: 'boolean' }, + onLinkPress: { action: 'onLinkPress' }, + }, + parameters: { controls: { exclude: ['onLinkPress'] } }, +} satisfies Meta + +export default meta + +type Story = StoryObj + +export const Overview: Story = {} + +const styles = StyleSheet.create(({ semantic }) => ({ + content: { + width: '100%', + maxWidth: 720, + alignSelf: 'center', + gap: semantic.dimension.space[800], + paddingBottom: semantic.dimension.space[800], + }, + intro: { gap: semantic.dimension.space[350] }, + families: { + flexDirection: 'row', + flexWrap: 'wrap', + gap: semantic.dimension.space[200], + marginTop: semantic.dimension.space[200], + }, + family: { + flexGrow: 1, + flexBasis: 150, + gap: semantic.dimension.space[200], + padding: semantic.dimension.space[350], + borderRadius: semantic.dimension.borderRadius[300], + backgroundColor: semantic.colorScheme.color.bg.neutral.weak.default, + }, + section: { gap: semantic.dimension.space[350] }, + sectionHeading: { gap: semantic.dimension.space[100] }, + specimen: { + gap: semantic.dimension.space[200], + paddingVertical: semantic.dimension.space[350], + borderTopWidth: StyleSheet.hairlineWidth, + borderColor: semantic.colorScheme.color.border.neutral.default, + }, + readingSample: { + gap: semantic.dimension.space[350], + padding: semantic.dimension.space[600], + marginVertical: semantic.dimension.space[200], + borderRadius: semantic.dimension.borderRadius[400], + backgroundColor: semantic.colorScheme.color.bg.neutral.weak.default, + }, +})) From 20389bae33a32a0294088dd216ad946147ffa2cf Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 27 Oct 2026 16:05:01 +0300 Subject: [PATCH 04/19] =?UTF-8?q?feat(storybook):=20=D0=B4=D0=BE=D0=B1?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=BC=D0=B5=D1=82=D0=BA?= =?UTF-8?q?=D0=B8=20=D1=81=D0=BE=D1=81=D1=82=D0=BE=D1=8F=D0=BD=D0=B8=D1=8F?= =?UTF-8?q?=20=D0=BA=D0=BE=D0=BC=D0=BF=D0=BE=D0=BD=D0=B5=D0=BD=D1=82=D0=BE?= =?UTF-8?q?=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .storybook/StorybookStatusUI.tsx | 40 +++++++++++++++ .storybook/StorybookTags.tsx | 51 +++++++++++++++++++ .storybook/index.tsx | 4 ++ package.json | 1 + src/components/Badge/Badge.stories.tsx | 1 + .../Button/stories/Button.stories.tsx | 1 + .../Button/stories/ButtonSeverity.stories.tsx | 1 + .../InputCaption/InputCaption.stories.tsx | 1 + .../Input/InputGroup/InputGroup.stories.tsx | 1 + .../Input/InputText/InputText.stories.tsx | 1 + .../InputText/InputTextMasked.stories.tsx | 1 + .../Input/Password/Password.stories.tsx | 1 + .../Input/stories/InputGroup.stories.tsx | 1 + .../Input/stories/InputMask.stories.tsx | 1 + .../Input/stories/InputText.stories.tsx | 1 + .../InputSwitch/InputSwitch.stories.tsx | 1 + src/components/Skeleton/Skeleton.stories.tsx | 1 + src/components/Tag/Tag.stories.ts | 1 + .../ToggleSwitch/ToggleSwitch.stories.tsx | 1 + yarn.lock | 3 +- 20 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 .storybook/StorybookStatusUI.tsx create mode 100644 .storybook/StorybookTags.tsx diff --git a/.storybook/StorybookStatusUI.tsx b/.storybook/StorybookStatusUI.tsx new file mode 100644 index 00000000..16e678b8 --- /dev/null +++ b/.storybook/StorybookStatusUI.tsx @@ -0,0 +1,40 @@ +import { FullUI } from '@storybook/react-native-ui' +import { type ComponentProps, useMemo } from 'react' +import { Text } from 'react-native' + +import { StorybookTags } from './StorybookTags' +import { view } from './storybook.requires' + +export const StorybookStatusUI = ({ + storyHash, + ...props +}: ComponentProps) => { + const taggedStoryHash = useMemo( + () => + Object.fromEntries( + Object.entries(storyHash).map(([id, entry]) => { + if (entry.type !== 'story') return [id, entry] + + // eslint-disable-next-line no-underscore-dangle -- RN 10.3 хранит CSF-теги только в подготовленных сторис. + const tags = view._idToPrepared[id].tags + + return [ + id, + { + ...entry, + tags, + renderLabel: (item: { name: string }) => ( + + {item.name} + + + ), + }, + ] + }) + ), + [storyHash] + ) + + return +} diff --git a/.storybook/StorybookTags.tsx b/.storybook/StorybookTags.tsx new file mode 100644 index 00000000..eb424b28 --- /dev/null +++ b/.storybook/StorybookTags.tsx @@ -0,0 +1,51 @@ +import { Text } from 'react-native' +import { StyleSheet } from 'react-native-unistyles' + +import type { ThemeType } from '../src/theme' + +type TagTone = keyof ThemeType['components']['tag']['colorScheme'] + +const tagDefinitions: Record< + string, + { label: string; tone: TagTone } | undefined +> = { + deprecated: { label: 'deprecated', tone: 'warn' }, + 'version:2.0': { label: '2.0', tone: 'info' }, + 'design:pending': { label: 'Design pending', tone: 'secondary' }, +} + +const StorybookTag = ({ tag }: { readonly tag: string }) => { + const definition = tagDefinitions[tag] + + if (!definition) return null + + return ( + + {' '} + + {` ${definition.label} `} + + + ) +} + +export const StorybookTags = ({ + tags, +}: { + readonly tags: readonly string[] +}) => ( + <> + {tags.map((tag) => ( + + ))} + +) + +const styles = StyleSheet.create(({ components, fonts, semantic }) => ({ + badge: (tone: TagTone) => ({ + fontSize: components.tag.root.fontSize - 1, + fontWeight: fonts.fontWeight.demibold, + color: semantic.colorScheme.color.fg.default, + backgroundColor: components.tag.colorScheme[tone].background, + }), +})) diff --git a/.storybook/index.tsx b/.storybook/index.tsx index 3867df20..65accd9d 100644 --- a/.storybook/index.tsx +++ b/.storybook/index.tsx @@ -1,10 +1,14 @@ +import '../src/theme/ThemeContext' + import { createAsyncStorage } from '@react-native-async-storage/async-storage' +import { StorybookStatusUI } from './StorybookStatusUI' import { view } from './storybook.requires' const storage = createAsyncStorage('storybook') const StorybookUIRoot = view.getStorybookUI({ + CustomUIComponent: StorybookStatusUI, storage, theme: { typography: { diff --git a/package.json b/package.json index 43ed6de6..6e41480f 100644 --- a/package.json +++ b/package.json @@ -78,6 +78,7 @@ "@storybook/core": "8.6.14", "@storybook/preview-api": "8.6.14", "@storybook/react-native": "10.3.2", + "@storybook/react-native-ui": "10.3.2", "@stylistic/eslint-plugin": "5.6.1", "@testing-library/react-native": "13.3.3", "@types/jest": "29.5.14", diff --git a/src/components/Badge/Badge.stories.tsx b/src/components/Badge/Badge.stories.tsx index c359c814..4d196016 100644 --- a/src/components/Badge/Badge.stories.tsx +++ b/src/components/Badge/Badge.stories.tsx @@ -12,6 +12,7 @@ const styles = StyleSheet.create({ const meta: Meta = { title: 'Misc/Badge', + tags: ['version:2.0'], component: Badge, args: { children: 'Badge', severity: 'primary', size: 'base' }, argTypes: { diff --git a/src/components/Button/stories/Button.stories.tsx b/src/components/Button/stories/Button.stories.tsx index 80a9b47a..f18226fa 100644 --- a/src/components/Button/stories/Button.stories.tsx +++ b/src/components/Button/stories/Button.stories.tsx @@ -27,6 +27,7 @@ const styles = StyleSheet.create({ const meta: Meta = { title: 'Button/Button', + tags: ['version:2.0'], component: Button, args: { size: 'base', diff --git a/src/components/Button/stories/ButtonSeverity.stories.tsx b/src/components/Button/stories/ButtonSeverity.stories.tsx index 11ebd207..724cc10e 100644 --- a/src/components/Button/stories/ButtonSeverity.stories.tsx +++ b/src/components/Button/stories/ButtonSeverity.stories.tsx @@ -33,6 +33,7 @@ const styles = StyleSheet.create({ const meta: Meta = { title: 'Button/ButtonSeverity', + tags: ['version:2.0'], component: ButtonSeverity, args: { size: 'base', diff --git a/src/components/Input/InputCaption/InputCaption.stories.tsx b/src/components/Input/InputCaption/InputCaption.stories.tsx index b0ba46f5..413d79b2 100644 --- a/src/components/Input/InputCaption/InputCaption.stories.tsx +++ b/src/components/Input/InputCaption/InputCaption.stories.tsx @@ -6,6 +6,7 @@ import { InputCaption } from './InputCaption' const meta: Meta = { title: 'Input/InputCaption', + tags: ['version:2.0', 'design:pending'], component: InputCaption, args: { children: 'Подсказка к полю', variant: 'base', showIcon: false }, argTypes: { diff --git a/src/components/Input/InputGroup/InputGroup.stories.tsx b/src/components/Input/InputGroup/InputGroup.stories.tsx index f3702d62..1e6c57a1 100644 --- a/src/components/Input/InputGroup/InputGroup.stories.tsx +++ b/src/components/Input/InputGroup/InputGroup.stories.tsx @@ -54,6 +54,7 @@ type StoryArgs = Omit, 'rightAddon'> & { const meta = { title: 'Input/InputGroup', + tags: ['version:2.0', 'design:pending'], component: InputGroup, args: { labelMode: 'none', diff --git a/src/components/Input/InputText/InputText.stories.tsx b/src/components/Input/InputText/InputText.stories.tsx index 3163bdf2..fef957ab 100644 --- a/src/components/Input/InputText/InputText.stories.tsx +++ b/src/components/Input/InputText/InputText.stories.tsx @@ -15,6 +15,7 @@ type StoryArgs = InputLabelStoryArgs const meta = { title: 'Input/InputText', + tags: ['version:2.0', 'design:pending'], component: InputText, args: { labelMode: 'label', diff --git a/src/components/Input/InputText/InputTextMasked.stories.tsx b/src/components/Input/InputText/InputTextMasked.stories.tsx index 2bd053ca..939368a4 100644 --- a/src/components/Input/InputText/InputTextMasked.stories.tsx +++ b/src/components/Input/InputText/InputTextMasked.stories.tsx @@ -75,6 +75,7 @@ const MaskedControl = ({ const meta = { ...inputTextMeta, title: 'Input/Input Text With Mask', + tags: ['version:2.0', 'design:pending'], args: { ...inputTextMeta.args, labelText: 'Значение', diff --git a/src/components/Input/Password/Password.stories.tsx b/src/components/Input/Password/Password.stories.tsx index 2a999d2b..9aa5c32f 100644 --- a/src/components/Input/Password/Password.stories.tsx +++ b/src/components/Input/Password/Password.stories.tsx @@ -24,6 +24,7 @@ type StoryArgs = InputLabelStoryArgs & { const meta: InputStoryMeta = { title: 'Input/Password', + tags: ['version:2.0', 'design:pending'], component: Password, args: { labelMode: 'label', diff --git a/src/components/Input/stories/InputGroup.stories.tsx b/src/components/Input/stories/InputGroup.stories.tsx index 75403c3b..a05e66a7 100644 --- a/src/components/Input/stories/InputGroup.stories.tsx +++ b/src/components/Input/stories/InputGroup.stories.tsx @@ -7,6 +7,7 @@ import { LegacyInputGroup as InputGroup } from '../deprecated/LegacyInputGroup' const meta: Meta = { title: 'Legacy/InputGroup', + tags: ['deprecated'], args: { clearable: true, disabled: false, diff --git a/src/components/Input/stories/InputMask.stories.tsx b/src/components/Input/stories/InputMask.stories.tsx index 4a6e0da7..b87a14cf 100644 --- a/src/components/Input/stories/InputMask.stories.tsx +++ b/src/components/Input/stories/InputMask.stories.tsx @@ -74,6 +74,7 @@ const MaskedInput = ({ const meta: Meta = { title: 'Legacy/InputMask', + tags: ['deprecated'], args: { clearable: true, disabled: false, diff --git a/src/components/Input/stories/InputText.stories.tsx b/src/components/Input/stories/InputText.stories.tsx index a9abdc40..998e9b6b 100644 --- a/src/components/Input/stories/InputText.stories.tsx +++ b/src/components/Input/stories/InputText.stories.tsx @@ -7,6 +7,7 @@ import { LegacyInputText as InputText } from '../deprecated/LegacyInputText' const meta: Meta = { title: 'Legacy/InputText', + tags: ['deprecated'], args: { clearable: true, disabled: false, diff --git a/src/components/InputSwitch/InputSwitch.stories.tsx b/src/components/InputSwitch/InputSwitch.stories.tsx index 75b7c3eb..8f8d0f3a 100644 --- a/src/components/InputSwitch/InputSwitch.stories.tsx +++ b/src/components/InputSwitch/InputSwitch.stories.tsx @@ -6,6 +6,7 @@ import { InputSwitch } from './InputSwitch' const meta: Meta = { title: 'Legacy/InputSwitch', + tags: ['deprecated'], component: InputSwitch, args: { disabled: false, danger: false, checked: false }, argTypes: { diff --git a/src/components/Skeleton/Skeleton.stories.tsx b/src/components/Skeleton/Skeleton.stories.tsx index accee6bc..9d286d5d 100644 --- a/src/components/Skeleton/Skeleton.stories.tsx +++ b/src/components/Skeleton/Skeleton.stories.tsx @@ -11,6 +11,7 @@ const styles = StyleSheet.create({ const meta: Meta = { title: 'Misc/Skeleton', + tags: ['version:2.0'], component: Skeleton, render: () => ( = { title: 'Misc/Tag', + tags: ['design:pending'], component: Tag, args: { text: 'Tag', rounded: false, severity: 'primary', showIcon: true }, argTypes: { diff --git a/src/components/ToggleSwitch/ToggleSwitch.stories.tsx b/src/components/ToggleSwitch/ToggleSwitch.stories.tsx index ecc9b3ba..e3092802 100644 --- a/src/components/ToggleSwitch/ToggleSwitch.stories.tsx +++ b/src/components/ToggleSwitch/ToggleSwitch.stories.tsx @@ -6,6 +6,7 @@ import type { ToggleSwitchProps } from './types' const meta: Meta = { title: 'Form/ToggleSwitch', + tags: ['version:2.0', 'design:pending'], component: ToggleSwitch, args: { checked: false, diff --git a/yarn.lock b/yarn.lock index d17ddfa0..f4758a53 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2836,6 +2836,7 @@ __metadata: "@storybook/core": "npm:8.6.14" "@storybook/preview-api": "npm:8.6.14" "@storybook/react-native": "npm:10.3.2" + "@storybook/react-native-ui": "npm:10.3.2" "@stylistic/eslint-plugin": "npm:5.6.1" "@tabler/icons-react-native": "npm:^3.36.0" "@testing-library/react-native": "npm:13.3.3" @@ -5643,7 +5644,7 @@ __metadata: languageName: node linkType: hard -"@storybook/react-native-ui@npm:^10.3.2": +"@storybook/react-native-ui@npm:10.3.2, @storybook/react-native-ui@npm:^10.3.2": version: 10.3.2 resolution: "@storybook/react-native-ui@npm:10.3.2" dependencies: From 284ff687378c443447b2038eee6393d14697726f Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 27 Oct 2026 16:05:02 +0300 Subject: [PATCH 05/19] =?UTF-8?q?chore(storybook):=20=D0=BD=D0=B0=D1=81?= =?UTF-8?q?=D1=82=D1=80=D0=BE=D0=B5=D0=BD=20=D0=BF=D0=BE=D1=80=D1=8F=D0=B4?= =?UTF-8?q?=D0=BE=D0=BA=20=D1=80=D0=B0=D0=B7=D0=B4=D0=B5=D0=BB=D0=BE=D0=B2?= =?UTF-8?q?=20=D0=B8=20=D1=81=D1=82=D0=BE=D1=80=D0=B8=D1=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .storybook/preview.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index aad256fd..2a697340 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -31,7 +31,13 @@ const preview: Preview = { }, ], parameters: { - options: { storySort: { method: 'alphabetical', includeNames: true } }, + options: { + storySort: { + method: 'alphabetical', + includeNames: true, + order: ['*', 'Typography', ['Overview', '*'], 'Legacy'], + }, + }, actions: { argTypesRegex: '^on[A-Z].*' }, controls: { matchers: { color: /(background|color)$/i, date: /Date$/ } }, }, From 1400dee72634187b6666e642278c78a701e1b91d Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 27 Oct 2026 16:05:03 +0300 Subject: [PATCH 06/19] =?UTF-8?q?docs(storybook):=20=D0=BE=D0=B1=D1=8A?= =?UTF-8?q?=D0=B5=D0=B4=D0=B8=D0=BD=D0=B5=D0=BD=D1=8B=20=D1=81=D1=82=D0=BE?= =?UTF-8?q?=D1=80=D0=B8=D1=81=20=D0=BA=D0=BE=D0=BC=D0=BF=D0=BE=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D1=82=D0=BE=D0=B2=20=D1=84=D0=BE=D1=80=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Checkbox/Checkbox.stories.ts | 2 +- src/components/InputOtp/InputOtp.stories.tsx | 2 +- src/components/RadioButton/RadioButton.stories.ts | 2 +- src/components/SelectButton/SelectButton.stories.tsx | 2 +- src/components/Slider/Slider.stories.tsx | 2 +- src/components/ToggleButton/ToggleButton.stories.ts | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/Checkbox/Checkbox.stories.ts b/src/components/Checkbox/Checkbox.stories.ts index 81f77364..56d13b3d 100644 --- a/src/components/Checkbox/Checkbox.stories.ts +++ b/src/components/Checkbox/Checkbox.stories.ts @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react' import { Checkbox } from './Checkbox' const meta: Meta = { - title: 'Other Form/Checkbox', + title: 'Form/Checkbox', component: Checkbox, args: { checked: false, diff --git a/src/components/InputOtp/InputOtp.stories.tsx b/src/components/InputOtp/InputOtp.stories.tsx index b6f50856..b0600197 100644 --- a/src/components/InputOtp/InputOtp.stories.tsx +++ b/src/components/InputOtp/InputOtp.stories.tsx @@ -14,7 +14,7 @@ const validateOtp = () => }) const meta: Meta = { - title: 'Other Form/InputOtp', + title: 'Form/InputOtp', component: InputOtp, args: { disabled: false, error: false, length: 4, value: '' }, render: (args) => { diff --git a/src/components/RadioButton/RadioButton.stories.ts b/src/components/RadioButton/RadioButton.stories.ts index 56efc0a2..d47ce90c 100644 --- a/src/components/RadioButton/RadioButton.stories.ts +++ b/src/components/RadioButton/RadioButton.stories.ts @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react' import { RadioButton } from './RadioButton' const meta: Meta = { - title: 'Other Form/RadioButton', + title: 'Form/RadioButton', component: RadioButton, args: { checked: false, disabled: false, state: 'default' }, argTypes: { state: { control: 'radio', options: ['default', 'danger'] } }, diff --git a/src/components/SelectButton/SelectButton.stories.tsx b/src/components/SelectButton/SelectButton.stories.tsx index cb7f230c..5d736c08 100644 --- a/src/components/SelectButton/SelectButton.stories.tsx +++ b/src/components/SelectButton/SelectButton.stories.tsx @@ -39,7 +39,7 @@ const AnimatedExample = ({ buttons, ...props }: CommonProps) => { } const meta: Meta = { - title: 'Other Form/SelectButton', + title: 'Form/SelectButton', component: SelectButton, args: { buttons, size: 'base', disabled: false }, argTypes: { diff --git a/src/components/Slider/Slider.stories.tsx b/src/components/Slider/Slider.stories.tsx index 11733182..acabcb08 100644 --- a/src/components/Slider/Slider.stories.tsx +++ b/src/components/Slider/Slider.stories.tsx @@ -7,7 +7,7 @@ import { StyleSheet } from 'react-native-unistyles' import { Slider, type SliderProps } from './Slider' const meta: Meta = { - title: 'Other Form/Slider', + title: 'Form/Slider', component: Slider, args: { disabled: false }, render: (args) => Template(args), diff --git a/src/components/ToggleButton/ToggleButton.stories.ts b/src/components/ToggleButton/ToggleButton.stories.ts index 119572b1..d7598359 100644 --- a/src/components/ToggleButton/ToggleButton.stories.ts +++ b/src/components/ToggleButton/ToggleButton.stories.ts @@ -8,7 +8,7 @@ const svgIcons = { IconArrowDownRight, IconUser, none: undefined } const imageIcons = { hotels: require('./hotels.png'), none: undefined } const meta: Meta = { - title: 'Other Form/ToggleButton', + title: 'Form/ToggleButton', component: ToggleButton, args: { checked: false, From b4a5eb54db53c9a8c36695ed84e5d20fb16303b7 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 27 Oct 2026 16:05:04 +0300 Subject: [PATCH 07/19] =?UTF-8?q?docs(storybook):=20=D1=81=D0=B3=D1=80?= =?UTF-8?q?=D1=83=D0=BF=D0=BF=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D1=8B=20?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D1=8E=20=D0=B8=20=D0=B2=D0=BA=D0=BB=D0=B0?= =?UTF-8?q?=D0=B4=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/List/Base/ListBase.stories.tsx | 2 +- .../MenuItem/Template/MenuItemTemplate.stories.tsx | 2 +- src/components/Tabs/Tabs.stories.tsx | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/List/Base/ListBase.stories.tsx b/src/components/List/Base/ListBase.stories.tsx index 920a812b..d05d3702 100644 --- a/src/components/List/Base/ListBase.stories.tsx +++ b/src/components/List/Base/ListBase.stories.tsx @@ -17,7 +17,7 @@ const Extras = { } const meta: Meta = { - title: 'Templates/List', + title: 'Menu/List', component: ListBase, args: { iconAlignment: 'top', diff --git a/src/components/MenuItem/Template/MenuItemTemplate.stories.tsx b/src/components/MenuItem/Template/MenuItemTemplate.stories.tsx index ceb4145e..b0411704 100644 --- a/src/components/MenuItem/Template/MenuItemTemplate.stories.tsx +++ b/src/components/MenuItem/Template/MenuItemTemplate.stories.tsx @@ -18,7 +18,7 @@ const Extras = { } const meta: Meta = { - title: 'Mixins/MenuItemTemplate', + title: 'Menu/MenuItemTemplate', component: MenuItemTemplate, args: { title: 'Menu Item', diff --git a/src/components/Tabs/Tabs.stories.tsx b/src/components/Tabs/Tabs.stories.tsx index 3da12fa2..a6497354 100644 --- a/src/components/Tabs/Tabs.stories.tsx +++ b/src/components/Tabs/Tabs.stories.tsx @@ -7,7 +7,7 @@ import { Badge } from '../Badge' import { Tabs, TabPanel } from '.' -const meta: Meta = { title: 'Menu/Tab', component: Tabs } +const meta: Meta = { title: 'Panel/Tabs', component: Tabs } export default meta type Story = StoryObj @@ -42,9 +42,9 @@ const TabsExample = ({ disabled }: { readonly disabled?: boolean }) => { ) } -const TabStory: Story = { +const TabsStory: Story = { args: { disabled: false }, render: (args) => , } -export { TabStory as Tab } +export { TabsStory as Tabs } From 9e654bc2f00c9eaf79159af9dfa03fc102a3a141 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Tue, 27 Oct 2026 16:05:05 +0300 Subject: [PATCH 08/19] =?UTF-8?q?docs(dialog):=20=D0=BE=D0=B1=D1=8A=D0=B5?= =?UTF-8?q?=D0=B4=D0=B8=D0=BD=D0=B5=D0=BD=D1=8B=20=D0=B2=D0=B0=D1=80=D0=B8?= =?UTF-8?q?=D0=B0=D0=BD=D1=82=D1=8B=20=D0=B4=D0=B8=D0=B0=D0=BB=D0=BE=D0=B3?= =?UTF-8?q?=D0=B0=20=D0=B2=20=D0=BE=D0=B4=D0=BD=D0=BE=D0=B9=20=D1=81=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Dialog/Dialog.stories.tsx | 117 ++++++++++-------- .../Dialog/DialogComponent.stories.tsx | 66 ---------- 2 files changed, 66 insertions(+), 117 deletions(-) delete mode 100644 src/components/Dialog/DialogComponent.stories.tsx diff --git a/src/components/Dialog/Dialog.stories.tsx b/src/components/Dialog/Dialog.stories.tsx index 539536d0..7aa57952 100644 --- a/src/components/Dialog/Dialog.stories.tsx +++ b/src/components/Dialog/Dialog.stories.tsx @@ -1,10 +1,24 @@ +import { useArgs } from '@storybook/preview-api' import type { Meta, StoryObj } from '@storybook/react' -import { useCallback, useState } from 'react' -import { Text, TouchableOpacity, View } from 'react-native' +import { useCallback } from 'react' +import { View } from 'react-native' +import { StyleSheet } from 'react-native-unistyles' + +import { Button } from '../Button' +import { Body } from '../Typography' import { Dialog, type DialogProps } from './Dialog' +import { DialogComponent } from './DialogComponent' import { DialogHeader, type DialogHeaderProps } from './DialogHeader' +type DialogStoryArgs = DialogProps & Pick + +const DialogBody = () => ( + Войдите в приложение, чтобы заказ сохранился в списке заказов +) + +const InlineFooter = () =>