diff --git a/src/components/Button.tsx b/src/components/Button.tsx index 68cee437..e401bda2 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -27,7 +27,7 @@ export type ButtonColor = | 'gradient_sunset' | 'gradient_nordic' | 'gradient_bonfire' -export type ButtonSize = 'small' | 'large' +export type ButtonSize = 'tiny' | 'small' | 'large' export type ButtonShape = 'round' | 'square' | 'default' export type VariantProps = { /** @@ -48,25 +48,32 @@ export type VariantProps = { shape?: ButtonShape } -export type ButtonProps = React.PropsWithChildren< - Pick & - AccessibilityProps & - VariantProps & { - testID?: string - label: string - style?: StyleProp - } -> +export type ButtonState = { + hovered: boolean + focused: boolean + pressed: boolean + disabled: boolean +} + +export type ButtonContext = VariantProps & ButtonState + +export type ButtonProps = Pick< + PressableProps, + 'disabled' | 'onPress' | 'testID' +> & + AccessibilityProps & + VariantProps & { + testID?: string + label: string + style?: StyleProp + children: + | React.ReactNode + | string + | ((context: ButtonContext) => React.ReactNode | string) + } export type ButtonTextProps = TextProps & VariantProps & {disabled?: boolean} -const Context = React.createContext< - VariantProps & { - hovered: boolean - focused: boolean - pressed: boolean - disabled: boolean - } ->({ +const Context = React.createContext({ hovered: false, focused: false, pressed: false, @@ -277,6 +284,8 @@ export function Button({ baseStyles.push({paddingVertical: 15}, a.px_2xl, a.rounded_sm, a.gap_md) } else if (size === 'small') { baseStyles.push({paddingVertical: 9}, a.px_lg, a.rounded_sm, a.gap_sm) + } else if (size === 'tiny') { + baseStyles.push({paddingVertical: 4}, a.px_sm, a.rounded_xs, a.gap_xs) } } else if (shape === 'round' || shape === 'square') { if (size === 'large') { @@ -287,12 +296,18 @@ export function Button({ } } else if (size === 'small') { baseStyles.push({height: 40, width: 40}) + } else if (size === 'tiny') { + baseStyles.push({height: 20, width: 20}) } if (shape === 'round') { baseStyles.push(a.rounded_full) } else if (shape === 'square') { - baseStyles.push(a.rounded_sm) + if (size === 'tiny') { + baseStyles.push(a.rounded_xs) + } else { + baseStyles.push(a.rounded_sm) + } } } @@ -338,7 +353,7 @@ export function Button({ } }, [variant, color]) - const context = React.useMemo( + const context = React.useMemo( () => ({ ...state, variant, @@ -349,6 +364,8 @@ export function Button({ [state, variant, color, size, disabled], ) + const flattenedBaseStyles = flatten(baseStyles) + return ( {variant === 'gradient' && ( - + + + )} {typeof children === 'string' ? ( {children} + ) : typeof children === 'function' ? ( + children(context) ) : ( children )} @@ -493,6 +519,8 @@ export function useSharedButtonTextStyles() { if (size === 'large') { baseStyles.push(a.text_md, android({paddingBottom: 1})) + } else if (size === 'tiny') { + baseStyles.push(a.text_xs, android({paddingBottom: 1})) } else { baseStyles.push(a.text_sm, android({paddingBottom: 1})) } @@ -514,9 +542,11 @@ export function ButtonText({children, style, ...rest}: ButtonTextProps) { export function ButtonIcon({ icon: Comp, position, + size: iconSize, }: { icon: React.ComponentType position?: 'left' | 'right' + size?: SVGIconProps['size'] }) { const {size, disabled} = useButtonContext() const textStyles = useSharedButtonTextStyles() @@ -532,7 +562,9 @@ export function ButtonIcon({ }, ]}>