From 8d996b8e85ca5b897c20f29787c858782cd4c933 Mon Sep 17 00:00:00 2001 From: Alesya Volosach Date: Fri, 2 Oct 2026 17:04:46 +0300 Subject: [PATCH 1/4] =?UTF-8?q?feat(button):=20=D0=BE=D0=B1=D0=BD=D0=BE?= =?UTF-8?q?=D0=B2=D0=BB=D1=91=D0=BD=20API=20=D0=B8=20=D0=BF=D0=BE=D0=B2?= =?UTF-8?q?=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BA=D0=BD=D0=BE=D0=BF?= =?UTF-8?q?=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .storybook/storybook.requires.ts | 52 ++--- src/components/Button/Button.tsx | 6 +- src/components/Button/ButtonBadge.tsx | 4 +- src/components/Button/ButtonSeverity.tsx | 40 ++-- .../Button/__tests__/Button.test.tsx | 36 ++- .../__tests__/ButtonInteraction.test.tsx | 207 +++++++++++++++++ .../Button/__tests__/ButtonSeverity.test.tsx | 15 +- src/components/Button/index.ts | 1 + .../Button/{ => internal}/BaseButton.tsx | 51 +++- .../components}/ButtonActivityIndicator.tsx | 7 +- .../components}/ButtonContainer.tsx | 82 ++++--- .../Button/internal/components/ButtonIcon.tsx | 217 ++++++++++++++++++ .../components}/ButtonLabel.tsx | 69 +++++- .../components}/ButtonLeftArea.tsx | 6 +- .../components}/ButtonRightArea.tsx | 6 +- .../{utils => internal/components}/index.ts | 0 .../contexts}/ButtonPressedContext.ts | 0 .../contexts}/ButtonVariantContext.ts | 2 +- .../Button/internal/resolveButtonProps.ts | 28 +++ .../Button/{ => stories}/Button.stories.tsx | 17 +- .../{ => stories}/ButtonBadge.stories.tsx | 13 +- .../{ => stories}/ButtonSeverity.stories.tsx | 21 +- src/components/Button/types.ts | 15 +- src/components/Button/utils/ButtonIcon.tsx | 158 ------------- 24 files changed, 737 insertions(+), 316 deletions(-) create mode 100644 src/components/Button/__tests__/ButtonInteraction.test.tsx rename src/components/Button/{ => internal}/BaseButton.tsx (53%) rename src/components/Button/{utils => internal/components}/ButtonActivityIndicator.tsx (82%) rename src/components/Button/{utils => internal/components}/ButtonContainer.tsx (84%) create mode 100644 src/components/Button/internal/components/ButtonIcon.tsx rename src/components/Button/{utils => internal/components}/ButtonLabel.tsx (68%) rename src/components/Button/{utils => internal/components}/ButtonLeftArea.tsx (82%) rename src/components/Button/{utils => internal/components}/ButtonRightArea.tsx (82%) rename src/components/Button/{utils => internal/components}/index.ts (100%) rename src/components/Button/{utils => internal/contexts}/ButtonPressedContext.ts (100%) rename src/components/Button/{utils => internal/contexts}/ButtonVariantContext.ts (79%) create mode 100644 src/components/Button/internal/resolveButtonProps.ts rename src/components/Button/{ => stories}/Button.stories.tsx (82%) rename src/components/Button/{ => stories}/ButtonBadge.stories.tsx (88%) rename src/components/Button/{ => stories}/ButtonSeverity.stories.tsx (80%) delete mode 100644 src/components/Button/utils/ButtonIcon.tsx diff --git a/.storybook/storybook.requires.ts b/.storybook/storybook.requires.ts index fa27ce80..d4f273b4 100644 --- a/.storybook/storybook.requires.ts +++ b/.storybook/storybook.requires.ts @@ -1,56 +1,48 @@ /* do not change this file, it is auto generated by storybook. */ /// -import { start, updateView, View, type Features } from '@storybook/react-native'; +import { start, updateView, View, type Features } from '@storybook/react-native' -import "@storybook/addon-ondevice-notes/register"; -import "@storybook/addon-ondevice-controls/register"; -import "@storybook/addon-ondevice-actions/register"; +import '@storybook/addon-ondevice-notes/register' +import '@storybook/addon-ondevice-controls/register' +import '@storybook/addon-ondevice-actions/register' const normalizedStories = [ { - titlePrefix: "", - directory: "./src", - files: "**/*.stories.?(ts|tsx|js|jsx)", - importPathMatcher: /^\.(?:(?:^|\/|(?:(?:(?!(?:^|\/)\.).)*?)\/)(?!\.)(?=.)[^/]*?\.stories\.(?:ts|tsx|js|jsx)?)$/, + titlePrefix: '', + directory: './src', + files: '**/*.stories.?(ts|tsx|js|jsx)', + importPathMatcher: + /^\.(?:(?:^|\/|(?:(?:(?!(?:^|\/)\.).)*?)\/)(?!\.)(?=.)[^/]*?\.stories\.(?:ts|tsx|js|jsx)?)$/, req: require.context( '../src', true, /^\.(?:(?:^|\/|(?:(?:(?!(?:^|\/)\.).)*?)\/)(?!\.)(?=.)[^/]*?\.stories\.(?:ts|tsx|js|jsx)?)$/ ), - } -]; - + }, +] declare global { - var view: View; - var STORIES: typeof normalizedStories; + var view: View + var STORIES: typeof normalizedStories var STORYBOOK_WEBSOCKET: | { host?: string; port?: number; secured?: boolean } - | undefined; - var FEATURES: Features; + | undefined + var FEATURES: Features } - const annotations = [ require('./preview'), - require("@storybook/react-native/preview") -]; - -globalThis.STORIES = normalizedStories; - - -module?.hot?.accept?.(); + require('@storybook/react-native/preview'), +] +globalThis.STORIES = normalizedStories +module?.hot?.accept?.() if (!globalThis.view) { - globalThis.view = start({ - annotations, - storyEntries: normalizedStories, - - }); + globalThis.view = start({ annotations, storyEntries: normalizedStories }) } else { - updateView(globalThis.view, annotations, normalizedStories); + updateView(globalThis.view, annotations, normalizedStories) } -export const view: View = globalThis.view; +export const view: View = globalThis.view diff --git a/src/components/Button/Button.tsx b/src/components/Button/Button.tsx index bb3320ac..487e3186 100644 --- a/src/components/Button/Button.tsx +++ b/src/components/Button/Button.tsx @@ -1,13 +1,13 @@ import { memo, useMemo } from 'react' -import { BaseButton } from './BaseButton' +import { BaseButton } from './internal/BaseButton' +import { ButtonVariantContext } from './internal/contexts/ButtonVariantContext' import type { ButtonBaseVariant, ButtonProps } from './types' -import { ButtonVariantContext } from './utils/ButtonVariantContext' /** * Button component * @param size - button size - * @param shape - button shape + * @param rounded - rounded corners * @param loading - button loading state * @param variant - button variant * @param disabled - button disabled state diff --git a/src/components/Button/ButtonBadge.tsx b/src/components/Button/ButtonBadge.tsx index 5519b079..7afbce54 100644 --- a/src/components/Button/ButtonBadge.tsx +++ b/src/components/Button/ButtonBadge.tsx @@ -5,9 +5,9 @@ import { StyleSheet } from 'react-native-unistyles' import { Badge, type BadgeProps } from '../Badge' -import { BaseButton } from './BaseButton' +import { BaseButton } from './internal/BaseButton' +import { ButtonVariantContext } from './internal/contexts/ButtonVariantContext' import type { ButtonBadgeProps, ButtonBaseVariant, ButtonProps } from './types' -import { ButtonVariantContext } from './utils/ButtonVariantContext' /** * Button component with badge diff --git a/src/components/Button/ButtonSeverity.tsx b/src/components/Button/ButtonSeverity.tsx index 978588ce..0e40750e 100644 --- a/src/components/Button/ButtonSeverity.tsx +++ b/src/components/Button/ButtonSeverity.tsx @@ -1,19 +1,20 @@ import { memo, useMemo } from 'react' -import { BaseButton } from './BaseButton' +import { BaseButton } from './internal/BaseButton' +import { ButtonVariantContext } from './internal/contexts/ButtonVariantContext' +import { resolveButtonSeverityVariant } from './internal/resolveButtonProps' import type { ButtonProps, ButtonSeverityProps, ButtonSeverityVariant, } from './types' -import { ButtonVariantContext } from './utils/ButtonVariantContext' /** * Button component * @param size - button size - * @param shape - button shape + * @param rounded - rounded corners * @param loading - button loading state - * @param variant - button variant + * @param appearance - button presentation * @param disabled - button disabled state * @param iconOnly - button with only Icon * @param iconPosition - icon position @@ -25,15 +26,24 @@ import { ButtonVariantContext } from './utils/ButtonVariantContext' */ export const ButtonSeverity = memo< ButtonProps & ButtonSeverityProps ->(({ severity, variant = 'basic', ...props }) => { - const variantContextValue = useMemo( - () => ({ variant, severity }), - [severity, variant] - ) +>( + ({ + severity, + appearance, + // eslint-disable-next-line @typescript-eslint/no-deprecated -- Preserve the alias until 2.0. + variant: deprecatedVariant, + ...props + }) => { + const variant = resolveButtonSeverityVariant(appearance, deprecatedVariant) + const variantContextValue = useMemo( + () => ({ variant, severity }), + [severity, variant] + ) - return ( - - - - ) -}) + return ( + + + + ) + } +) diff --git a/src/components/Button/__tests__/Button.test.tsx b/src/components/Button/__tests__/Button.test.tsx index 024a869a..2b633160 100644 --- a/src/components/Button/__tests__/Button.test.tsx +++ b/src/components/Button/__tests__/Button.test.tsx @@ -4,33 +4,23 @@ import { render, userEvent } from '@testing-library/react-native' import { Button } from '../Button' describe('Button', () => { - test.each(['small', 'base', 'large', 'xlarge'] as const)( - 'отображает текст для размера %s', - (size) => { - const { getByText } = render(