diff --git a/packages/design-system-react-native/src/components/TextButton/TextButton.types.ts b/packages/design-system-react-native/src/components/TextButton/TextButton.types.ts index 95ab92abe..34da309a5 100644 --- a/packages/design-system-react-native/src/components/TextButton/TextButton.types.ts +++ b/packages/design-system-react-native/src/components/TextButton/TextButton.types.ts @@ -1,3 +1,5 @@ +import type { TextButtonPropsShared } from '@metamask/design-system-shared'; + import type { TextProps } from '../Text'; /** @@ -7,13 +9,10 @@ import type { TextProps } from '../Text'; export type TextButtonProps = Omit< TextProps, 'children' | 'color' | 'onPress' -> & { - /** - * Content shown as the label. - */ - children: React.ReactNode; - /** - * Called when the user presses the label. Primary interaction for this control. - */ - onPress?: TextProps['onPress']; -}; +> & + TextButtonPropsShared & { + /** + * Called when the user presses the label. Primary interaction for this control. + */ + onPress?: TextProps['onPress']; + }; diff --git a/packages/design-system-react-native/src/components/TextButton/index.ts b/packages/design-system-react-native/src/components/TextButton/index.ts index aa885336a..d718d3906 100644 --- a/packages/design-system-react-native/src/components/TextButton/index.ts +++ b/packages/design-system-react-native/src/components/TextButton/index.ts @@ -1,2 +1,3 @@ +export { TextButtonSize } from '@metamask/design-system-shared'; export { TextButton } from './TextButton'; export type { TextButtonProps } from './TextButton.types'; diff --git a/packages/design-system-react-native/src/components/index.ts b/packages/design-system-react-native/src/components/index.ts index 64fcf61c0..40e861962 100644 --- a/packages/design-system-react-native/src/components/index.ts +++ b/packages/design-system-react-native/src/components/index.ts @@ -166,7 +166,7 @@ export type { SensitiveTextProps } from './SensitiveText'; export { TabEmptyState } from './TabEmptyState'; export type { TabEmptyStateProps } from './TabEmptyState'; -export { TextButton } from './TextButton'; +export { TextButton, TextButtonSize } from './TextButton'; export type { TextButtonProps } from './TextButton'; export { diff --git a/packages/design-system-react/src/components/TextButton/TextButton.constants.ts b/packages/design-system-react/src/components/TextButton/TextButton.constants.ts index c97d52541..364f54d27 100644 --- a/packages/design-system-react/src/components/TextButton/TextButton.constants.ts +++ b/packages/design-system-react/src/components/TextButton/TextButton.constants.ts @@ -1,4 +1,5 @@ -import { TextButtonSize } from '../../types'; +import { TextButtonSize } from '@metamask/design-system-shared'; + import { TextVariant } from '../Text'; export const MAP_TEXTBUTTON_SIZE_TEXTVARIANT: Record< diff --git a/packages/design-system-react/src/components/TextButton/TextButton.stories.tsx b/packages/design-system-react/src/components/TextButton/TextButton.stories.tsx index cc7f0560b..1fc15900d 100644 --- a/packages/design-system-react/src/components/TextButton/TextButton.stories.tsx +++ b/packages/design-system-react/src/components/TextButton/TextButton.stories.tsx @@ -1,7 +1,7 @@ +import { TextButtonSize } from '@metamask/design-system-shared'; import type { Meta, StoryObj } from '@storybook/react-vite'; import React from 'react'; -import { TextButtonSize } from '../../types'; import { IconName } from '../Icon'; import { Text, TextVariant } from '../Text'; @@ -114,7 +114,7 @@ export const AsChild: Story = { export const IsInverse: Story = { render: (args) => ( -
+
Inverse Button diff --git a/packages/design-system-react/src/components/TextButton/TextButton.test.tsx b/packages/design-system-react/src/components/TextButton/TextButton.test.tsx index 1ca98ec1c..77d0234d6 100644 --- a/packages/design-system-react/src/components/TextButton/TextButton.test.tsx +++ b/packages/design-system-react/src/components/TextButton/TextButton.test.tsx @@ -1,7 +1,7 @@ +import { TextButtonSize } from '@metamask/design-system-shared'; import { render, screen } from '@testing-library/react'; import React from 'react'; -import { TextButtonSize } from '../../types'; import { IconName } from '../Icon'; import { Text, TextVariant } from '../Text'; diff --git a/packages/design-system-react/src/components/TextButton/TextButton.tsx b/packages/design-system-react/src/components/TextButton/TextButton.tsx index f027ea3e7..4ebaff73c 100644 --- a/packages/design-system-react/src/components/TextButton/TextButton.tsx +++ b/packages/design-system-react/src/components/TextButton/TextButton.tsx @@ -1,6 +1,6 @@ +import { TextButtonSize } from '@metamask/design-system-shared'; import React, { forwardRef } from 'react'; -import { TextButtonSize } from '../../types'; import { twMerge } from '../../utils/tw-merge'; import { ButtonBase } from '../ButtonBase'; @@ -30,11 +30,11 @@ export const TextButton = forwardRef( // Hover/Active states - only applied when interactive !isDisabled && [ !isInverse && [ - 'hover:text-primary-default-hover hover:underline hover:decoration-primary-default-hover hover:decoration-2 hover:underline-offset-4', + 'hover:text-primary-default-hover hover:decoration-primary-default-hover hover:underline hover:decoration-2 hover:underline-offset-4', 'active:text-primary-default-pressed active:decoration-primary-default-pressed', ], isInverse && [ - 'hover:text-primary-inverse hover:underline hover:decoration-primary-inverse hover:decoration-2 hover:underline-offset-4', + 'hover:text-primary-inverse hover:decoration-primary-inverse hover:underline hover:decoration-2 hover:underline-offset-4', 'active:text-primary-inverse active:decoration-primary-inverse', ], ], diff --git a/packages/design-system-react/src/components/TextButton/TextButton.types.ts b/packages/design-system-react/src/components/TextButton/TextButton.types.ts index 03a035ddf..df14399ba 100644 --- a/packages/design-system-react/src/components/TextButton/TextButton.types.ts +++ b/packages/design-system-react/src/components/TextButton/TextButton.types.ts @@ -1,4 +1,8 @@ -import type { TextButtonSize } from '../../types'; +import type { + TextButtonPropsShared, + TextButtonSize, +} from '@metamask/design-system-shared'; + import type { ButtonBaseProps } from '../ButtonBase'; export type TextButtonProps = Omit< @@ -11,32 +15,27 @@ export type TextButtonProps = Omit< | 'loadingTextProps' | 'style' | 'size' -> & { - /** - * Optional prop for additional CSS classes to be applied to the TextButton component - */ - className?: string; - /** - * Optional prop that when true, applies inverse styling to the button - * - * @default false - */ - isInverse?: boolean; - /** - * Optional prop that when true, disables the button - * - * @default false - */ - isDisabled?: boolean; - /** - * Optional prop to specify the size of the TextButton - * - * @default TextButtonSize.BodyMd - */ - size?: TextButtonSize; - /** - * Optional CSS styles to be applied to the component. - * Should be used sparingly and only for dynamic styles that can't be achieved with className. - */ - style?: React.CSSProperties; -}; +> & + TextButtonPropsShared & { + /** + * Optional prop for additional CSS classes to be applied to the TextButton component + */ + className?: string; + /** + * Optional prop that when true, applies inverse styling to the button + * + * @default false + */ + isInverse?: boolean; + /** + * Optional prop to specify the size of the TextButton + * + * @default TextButtonSize.BodyMd + */ + size?: TextButtonSize; + /** + * Optional CSS styles to be applied to the component. + * Should be used sparingly and only for dynamic styles that can't be achieved with className. + */ + style?: React.CSSProperties; + }; diff --git a/packages/design-system-react/src/components/TextButton/index.ts b/packages/design-system-react/src/components/TextButton/index.ts index 1fdb22ff1..d718d3906 100644 --- a/packages/design-system-react/src/components/TextButton/index.ts +++ b/packages/design-system-react/src/components/TextButton/index.ts @@ -1,3 +1,3 @@ -export { TextButtonSize } from '../../types'; +export { TextButtonSize } from '@metamask/design-system-shared'; export { TextButton } from './TextButton'; export type { TextButtonProps } from './TextButton.types'; diff --git a/packages/design-system-react/src/types/index.ts b/packages/design-system-react/src/types/index.ts index 5803ebfa0..50d365b3e 100644 --- a/packages/design-system-react/src/types/index.ts +++ b/packages/design-system-react/src/types/index.ts @@ -430,16 +430,6 @@ export enum FontFamily { Hero = 'font-hero', } -/** - * TextButton - size - */ -export enum TextButtonSize { - BodyLg = 'body-lg', - BodyMd = 'body-md', - BodySm = 'body-sm', - BodyXs = 'body-xs', -} - /** * Icon - size */ diff --git a/packages/design-system-shared/src/index.ts b/packages/design-system-shared/src/index.ts index 5aaa91632..09821b5f0 100644 --- a/packages/design-system-shared/src/index.ts +++ b/packages/design-system-shared/src/index.ts @@ -68,3 +68,6 @@ export { AvatarAccountVariant, type AvatarAccountPropsShared, } from './types/AvatarAccount'; + +// TextButton types (ADR-0003 + ADR-0004) +export { TextButtonSize, type TextButtonPropsShared } from './types/TextButton'; diff --git a/packages/design-system-shared/src/types/TextButton/TextButton.types.ts b/packages/design-system-shared/src/types/TextButton/TextButton.types.ts new file mode 100644 index 000000000..39bd9a237 --- /dev/null +++ b/packages/design-system-shared/src/types/TextButton/TextButton.types.ts @@ -0,0 +1,43 @@ +import type { ReactNode } from 'react'; + +/** + * TextButton - size + * Convert from enum to const object (ADR-0003) + */ +export const TextButtonSize = { + /** + * Large body text size + */ + BodyLg: 'body-lg', + /** + * Medium body text size (default) + */ + BodyMd: 'body-md', + /** + * Small body text size + */ + BodySm: 'body-sm', + /** + * Extra small body text size + */ + BodyXs: 'body-xs', +} as const; +export type TextButtonSize = + (typeof TextButtonSize)[keyof typeof TextButtonSize]; + +/** + * TextButton component shared props (ADR-0004) + * Platform-independent properties shared across React and React Native + */ +export type TextButtonPropsShared = { + /** + * The content to be rendered within the TextButton. + */ + children: ReactNode; + /** + * Optional prop that when true, disables the button. + * + * @default false + */ + isDisabled?: boolean; +}; diff --git a/packages/design-system-shared/src/types/TextButton/index.ts b/packages/design-system-shared/src/types/TextButton/index.ts new file mode 100644 index 000000000..0c393145d --- /dev/null +++ b/packages/design-system-shared/src/types/TextButton/index.ts @@ -0,0 +1 @@ +export { TextButtonSize, type TextButtonPropsShared } from './TextButton.types';