diff --git a/app/soapbox/components/ui/button/useButtonStyles.ts b/app/soapbox/components/ui/button/useButtonStyles.ts index ecec3de1f..4dc38997d 100644 --- a/app/soapbox/components/ui/button/useButtonStyles.ts +++ b/app/soapbox/components/ui/button/useButtonStyles.ts @@ -1,12 +1,32 @@ import classNames from 'clsx'; -type ButtonThemes = 'primary' | 'secondary' | 'tertiary' | 'accent' | 'danger' | 'transparent' | 'outline' -type ButtonSizes = 'sm' | 'md' | 'lg' +const themes = { + primary: + 'bg-primary-500 hover:bg-primary-400 dark:hover:bg-primary-600 border-transparent focus:bg-primary-500 text-gray-100 focus:ring-primary-300', + secondary: + 'border-transparent bg-primary-100 dark:bg-primary-800 hover:bg-primary-50 dark:hover:bg-primary-700 focus:bg-primary-100 dark:focus:bg-primary-800 text-primary-500 dark:text-primary-200', + tertiary: + 'bg-transparent border-gray-400 dark:border-gray-800 hover:border-primary-300 dark:hover:border-primary-700 focus:border-primary-500 text-gray-900 dark:text-gray-100 focus:ring-primary-500', + accent: 'border-transparent bg-secondary-500 hover:bg-secondary-400 focus:bg-secondary-500 text-gray-100 focus:ring-secondary-300', + danger: 'border-transparent bg-danger-100 dark:bg-danger-900 text-danger-600 dark:text-danger-200 hover:bg-danger-600 hover:text-gray-100 dark:hover:text-gray-100 dark:hover:bg-danger-500 focus:bg-danger-800 dark:focus:bg-danger-600', + transparent: 'border-transparent text-gray-800 backdrop-blur-sm bg-white/75 hover:bg-white/80', + outline: 'border-gray-100 border-2 bg-transparent text-gray-100 hover:bg-white/10', +}; + +const sizes = { + xs: 'px-3 py-1 text-xs', + sm: 'px-3 py-1.5 text-xs leading-4', + md: 'px-4 py-2 text-sm', + lg: 'px-6 py-3 text-base', +}; + +type ButtonSizes = keyof typeof sizes +type ButtonThemes = keyof typeof themes type IButtonStyles = { - theme: ButtonThemes, - block: boolean, - disabled: boolean, + theme: ButtonThemes + block: boolean + disabled: boolean size: ButtonSizes } @@ -17,26 +37,6 @@ const useButtonStyles = ({ disabled, size, }: IButtonStyles) => { - const themes = { - primary: - 'bg-primary-500 hover:bg-primary-400 dark:hover:bg-primary-600 border-transparent focus:bg-primary-500 text-gray-100 focus:ring-primary-300', - secondary: - 'border-transparent bg-primary-100 dark:bg-primary-800 hover:bg-primary-50 dark:hover:bg-primary-700 focus:bg-primary-100 dark:focus:bg-primary-800 text-primary-500 dark:text-primary-200', - tertiary: - 'bg-transparent border-gray-400 dark:border-gray-800 hover:border-primary-300 dark:hover:border-primary-700 focus:border-primary-500 text-gray-900 dark:text-gray-100 focus:ring-primary-500', - accent: 'border-transparent bg-secondary-500 hover:bg-secondary-400 focus:bg-secondary-500 text-gray-100 focus:ring-secondary-300', - danger: 'border-transparent bg-danger-100 dark:bg-danger-900 text-danger-600 dark:text-danger-200 hover:bg-danger-600 hover:text-gray-100 dark:hover:text-gray-100 dark:hover:bg-danger-500 focus:bg-danger-800 dark:focus:bg-danger-600', - transparent: 'border-transparent text-gray-800 backdrop-blur-sm bg-white/75 hover:bg-white/80', - outline: 'border-gray-100 border-2 bg-transparent text-gray-100 hover:bg-white/10', - }; - - const sizes = { - xs: 'px-3 py-1 text-xs', - sm: 'px-3 py-1.5 text-xs leading-4', - md: 'px-4 py-2 text-sm', - lg: 'px-6 py-3 text-base', - }; - const buttonStyle = classNames({ 'inline-flex items-center border font-medium rounded-full focus:outline-none focus:ring-2 focus:ring-offset-2 appearance-none transition-all': true, 'select-none disabled:opacity-75 disabled:cursor-default': disabled, diff --git a/app/soapbox/components/ui/card/card.tsx b/app/soapbox/components/ui/card/card.tsx index 816627326..59f6ee1bc 100644 --- a/app/soapbox/components/ui/card/card.tsx +++ b/app/soapbox/components/ui/card/card.tsx @@ -18,13 +18,13 @@ const messages = defineMessages({ interface ICard { /** The type of card. */ - variant?: 'default' | 'rounded', + variant?: 'default' | 'rounded' /** Card size preset. */ - size?: 'md' | 'lg' | 'xl', + size?: keyof typeof sizes /** Extra classnames for the
element. */ - className?: string, + className?: string /** Elements inside the card. */ - children: React.ReactNode, + children: React.ReactNode } /** An opaque backdrop to hold a collection of related elements. */ diff --git a/app/soapbox/components/ui/hstack/hstack.tsx b/app/soapbox/components/ui/hstack/hstack.tsx index f959cdd51..a109da608 100644 --- a/app/soapbox/components/ui/hstack/hstack.tsx +++ b/app/soapbox/components/ui/hstack/hstack.tsx @@ -17,7 +17,7 @@ const alignItemsOptions = { }; const spaces = { - '0.5': 'space-x-0.5', + [0.5]: 'space-x-0.5', 1: 'space-x-1', 1.5: 'space-x-1.5', 2: 'space-x-2', @@ -29,21 +29,21 @@ const spaces = { interface IHStack { /** Vertical alignment of children. */ - alignItems?: 'top' | 'bottom' | 'center' | 'start', + alignItems?: keyof typeof alignItemsOptions /** Extra class names on the
element. */ - className?: string, + className?: string /** Children */ - children?: React.ReactNode, + children?: React.ReactNode /** Horizontal alignment of children. */ - justifyContent?: 'between' | 'center' | 'start' | 'end' | 'around', + justifyContent?: keyof typeof justifyContentOptions /** Size of the gap between elements. */ - space?: 0.5 | 1 | 1.5 | 2 | 3 | 4 | 6 | 8, + space?: keyof typeof spaces /** Whether to let the flexbox grow. */ - grow?: boolean, + grow?: boolean /** Extra CSS styles for the
*/ style?: React.CSSProperties /** Whether to let the flexbox wrap onto multiple lines. */ - wrap?: boolean, + wrap?: boolean } /** Horizontal row of child elements. */ diff --git a/app/soapbox/components/ui/modal/modal.tsx b/app/soapbox/components/ui/modal/modal.tsx index e203a1460..969f7ae65 100644 --- a/app/soapbox/components/ui/modal/modal.tsx +++ b/app/soapbox/components/ui/modal/modal.tsx @@ -10,8 +10,6 @@ const messages = defineMessages({ confirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' }, }); -type Widths = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' - const widths = { xs: 'max-w-xs', sm: 'max-w-sm', @@ -51,7 +49,7 @@ interface IModal { skipFocus?: boolean, /** Title text for the modal. */ title?: React.ReactNode, - width?: Widths, + width?: keyof typeof widths, } /** Displays a modal dialog box. */ diff --git a/app/soapbox/components/ui/stack/stack.tsx b/app/soapbox/components/ui/stack/stack.tsx index 64257ecf9..b161d4949 100644 --- a/app/soapbox/components/ui/stack/stack.tsx +++ b/app/soapbox/components/ui/stack/stack.tsx @@ -1,13 +1,11 @@ import classNames from 'clsx'; import React from 'react'; -type SIZES = 0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 10 - const spaces = { 0: 'space-y-0', - '0.5': 'space-y-0.5', + [0.5]: 'space-y-0.5', 1: 'space-y-1', - '1.5': 'space-y-1.5', + [1.5]: 'space-y-1.5', 2: 'space-y-2', 3: 'space-y-3', 4: 'space-y-4', @@ -25,15 +23,15 @@ const alignItemsOptions = { interface IStack extends React.HTMLAttributes { /** Size of the gap between elements. */ - space?: SIZES, + space?: keyof typeof spaces /** Horizontal alignment of children. */ - alignItems?: 'center', + alignItems?: 'center' /** Vertical alignment of children. */ - justifyContent?: 'center', + justifyContent?: 'center' /** Extra class names on the
element. */ - className?: string, + className?: string /** Whether to let the flexbox grow. */ - grow?: boolean, + grow?: boolean } /** Vertical stack of child elements. */ diff --git a/app/soapbox/components/ui/text/text.tsx b/app/soapbox/components/ui/text/text.tsx index 2e0736809..7669f3d2a 100644 --- a/app/soapbox/components/ui/text/text.tsx +++ b/app/soapbox/components/ui/text/text.tsx @@ -1,16 +1,6 @@ import classNames from 'clsx'; import React from 'react'; -type Themes = 'default' | 'danger' | 'primary' | 'muted' | 'subtle' | 'success' | 'inherit' | 'white' -type Weights = 'normal' | 'medium' | 'semibold' | 'bold' -export type Sizes = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' -type Alignments = 'left' | 'center' | 'right' -type TrackingSizes = 'normal' | 'wide' -type TransformProperties = 'uppercase' | 'normal' -type Families = 'sans' | 'mono' -type Tags = 'abbr' | 'p' | 'span' | 'pre' | 'time' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'label' -type Directions = 'ltr' | 'rtl' - const themes = { default: 'text-gray-900 dark:text-gray-100', danger: 'text-danger-600', @@ -60,15 +50,19 @@ const families = { mono: 'font-mono', }; +export type Sizes = keyof typeof sizes +type Tags = 'abbr' | 'p' | 'span' | 'pre' | 'time' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'label' +type Directions = 'ltr' | 'rtl' + interface IText extends Pick, 'dangerouslySetInnerHTML'> { /** How to align the text. */ - align?: Alignments, + align?: keyof typeof alignments, /** Extra class names for the outer element. */ className?: string, /** Text direction. */ direction?: Directions, /** Typeface of the text. */ - family?: Families, + family?: keyof typeof families, /** The "for" attribute specifies which form element a label is bound to. */ htmlFor?: string, /** Font size of the text. */ @@ -76,15 +70,15 @@ interface IText extends Pick, 'danger /** HTML element name of the outer element. */ tag?: Tags, /** Theme for the text. */ - theme?: Themes, + theme?: keyof typeof themes, /** Letter-spacing of the text. */ - tracking?: TrackingSizes, + tracking?: keyof typeof trackingSizes, /** Transform (eg uppercase) for the text. */ - transform?: TransformProperties, + transform?: keyof typeof transformProperties, /** Whether to truncate the text if its container is too small. */ truncate?: boolean, /** Font weight of the text. */ - weight?: Weights, + weight?: keyof typeof weights, /** Tooltip title. */ title?: string, }