diff --git a/src/components/Button.tsx b/src/components/Button.tsx index 982f422134..deac450eea 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -88,336 +88,355 @@ export function useButtonContext() { return React.useContext(Context) } -export function Button({ - children, - variant, - color, - size, - shape = 'default', - label, - disabled = false, - style, - hoverStyle: hoverStyleProp, - ...rest -}: ButtonProps) { - const t = useTheme() - const [state, setState] = React.useState({ - pressed: false, - hovered: false, - focused: false, - }) - - const onPressIn = React.useCallback(() => { - setState(s => ({ - ...s, - pressed: true, - })) - }, [setState]) - const onPressOut = React.useCallback(() => { - setState(s => ({ - ...s, - pressed: false, - })) - }, [setState]) - const onHoverIn = React.useCallback(() => { - setState(s => ({ - ...s, - hovered: true, - })) - }, [setState]) - const onHoverOut = React.useCallback(() => { - setState(s => ({ - ...s, - hovered: false, - })) - }, [setState]) - const onFocus = React.useCallback(() => { - setState(s => ({ - ...s, - focused: true, - })) - }, [setState]) - const onBlur = React.useCallback(() => { - setState(s => ({ - ...s, - focused: false, - })) - }, [setState]) - - const {baseStyles, hoverStyles} = React.useMemo(() => { - const baseStyles: ViewStyle[] = [] - const hoverStyles: ViewStyle[] = [] - const light = t.name === 'light' - - if (color === 'primary') { - if (variant === 'solid') { - if (!disabled) { - baseStyles.push({ - backgroundColor: t.palette.primary_500, - }) - hoverStyles.push({ - backgroundColor: t.palette.primary_600, - }) - } else { - baseStyles.push({ - backgroundColor: t.palette.primary_700, - }) - } - } else if (variant === 'outline') { - baseStyles.push(a.border, t.atoms.bg, { - borderWidth: 1, - }) - - if (!disabled) { - baseStyles.push(a.border, { - borderColor: t.palette.primary_500, - }) - hoverStyles.push(a.border, { - backgroundColor: light - ? t.palette.primary_50 - : t.palette.primary_950, - }) - } else { - baseStyles.push(a.border, { - borderColor: light ? t.palette.primary_200 : t.palette.primary_900, - }) - } - } else if (variant === 'ghost') { - if (!disabled) { - baseStyles.push(t.atoms.bg) - hoverStyles.push({ - backgroundColor: light - ? t.palette.primary_100 - : t.palette.primary_900, - }) - } - } - } else if (color === 'secondary') { - if (variant === 'solid') { - if (!disabled) { - baseStyles.push({ - backgroundColor: t.palette.contrast_25, - }) - hoverStyles.push({ - backgroundColor: t.palette.contrast_50, - }) - } else { - baseStyles.push({ - backgroundColor: t.palette.contrast_100, - }) - } - } else if (variant === 'outline') { - baseStyles.push(a.border, t.atoms.bg, { - borderWidth: 1, - }) - - if (!disabled) { - baseStyles.push(a.border, { - borderColor: t.palette.contrast_300, - }) - hoverStyles.push(t.atoms.bg_contrast_50) - } else { - baseStyles.push(a.border, { - borderColor: t.palette.contrast_200, - }) - } - } else if (variant === 'ghost') { - if (!disabled) { - baseStyles.push(t.atoms.bg) - hoverStyles.push({ - backgroundColor: t.palette.contrast_100, - }) - } - } - } else if (color === 'negative') { - if (variant === 'solid') { - if (!disabled) { - baseStyles.push({ - backgroundColor: t.palette.negative_500, - }) - hoverStyles.push({ - backgroundColor: t.palette.negative_600, - }) - } else { - baseStyles.push({ - backgroundColor: t.palette.negative_700, - }) - } - } else if (variant === 'outline') { - baseStyles.push(a.border, t.atoms.bg, { - borderWidth: 1, - }) - - if (!disabled) { - baseStyles.push(a.border, { - borderColor: t.palette.negative_500, - }) - hoverStyles.push(a.border, { - backgroundColor: light - ? t.palette.negative_50 - : t.palette.negative_975, - }) - } else { - baseStyles.push(a.border, { - borderColor: light - ? t.palette.negative_200 - : t.palette.negative_900, - }) - } - } else if (variant === 'ghost') { - if (!disabled) { - baseStyles.push(t.atoms.bg) - hoverStyles.push({ - backgroundColor: light - ? t.palette.negative_100 - : t.palette.negative_975, - }) - } - } - } - - if (shape === 'default') { - if (size === 'large') { - baseStyles.push({paddingVertical: 15}, a.px_2xl, a.rounded_sm, a.gap_md) - } else if (size === 'medium') { - baseStyles.push({paddingVertical: 12}, 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 === 'xsmall') { - baseStyles.push({paddingVertical: 6}, a.px_sm, 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') { - if (shape === 'round') { - baseStyles.push({height: 54, width: 54}) - } else { - baseStyles.push({height: 50, width: 50}) - } - } else if (size === 'small') { - baseStyles.push({height: 34, width: 34}) - } else if (size === 'xsmall') { - baseStyles.push({height: 28, width: 28}) - } else if (size === 'tiny') { - baseStyles.push({height: 20, width: 20}) - } - - if (shape === 'round') { - baseStyles.push(a.rounded_full) - } else if (shape === 'square') { - if (size === 'tiny') { - baseStyles.push(a.rounded_xs) - } else { - baseStyles.push(a.rounded_sm) - } - } - } - - return { - baseStyles, - hoverStyles, - } - }, [t, variant, color, size, shape, disabled]) - - const {gradientColors, gradientHoverColors, gradientLocations} = - React.useMemo(() => { - const colors: string[] = [] - const hoverColors: string[] = [] - const locations: number[] = [] - const gradient = { - primary: tokens.gradients.sky, - secondary: tokens.gradients.sky, - negative: tokens.gradients.sky, - gradient_sky: tokens.gradients.sky, - gradient_midnight: tokens.gradients.midnight, - gradient_sunrise: tokens.gradients.sunrise, - gradient_sunset: tokens.gradients.sunset, - gradient_nordic: tokens.gradients.nordic, - gradient_bonfire: tokens.gradients.bonfire, - }[color || 'primary'] - - if (variant === 'gradient') { - colors.push(...gradient.values.map(([_, color]) => color)) - hoverColors.push(...gradient.values.map(_ => gradient.hover_value)) - locations.push(...gradient.values.map(([location, _]) => location)) - } - - return { - gradientColors: colors, - gradientHoverColors: hoverColors, - gradientLocations: locations, - } - }, [variant, color]) - - const context = React.useMemo( - () => ({ - ...state, +export const Button = React.forwardRef( + ( + { + children, variant, color, size, - disabled: disabled || false, - }), - [state, variant, color, size, disabled], - ) + shape = 'default', + label, + disabled = false, + style, + hoverStyle: hoverStyleProp, + ...rest + }, + ref, + ) => { + const t = useTheme() + const [state, setState] = React.useState({ + pressed: false, + hovered: false, + focused: false, + }) - const flattenedBaseStyles = flatten(baseStyles) + const onPressIn = React.useCallback(() => { + setState(s => ({ + ...s, + pressed: true, + })) + }, [setState]) + const onPressOut = React.useCallback(() => { + setState(s => ({ + ...s, + pressed: false, + })) + }, [setState]) + const onHoverIn = React.useCallback(() => { + setState(s => ({ + ...s, + hovered: true, + })) + }, [setState]) + const onHoverOut = React.useCallback(() => { + setState(s => ({ + ...s, + hovered: false, + })) + }, [setState]) + const onFocus = React.useCallback(() => { + setState(s => ({ + ...s, + focused: true, + })) + }, [setState]) + const onBlur = React.useCallback(() => { + setState(s => ({ + ...s, + focused: false, + })) + }, [setState]) - return ( - { + const baseStyles: ViewStyle[] = [] + const hoverStyles: ViewStyle[] = [] + const light = t.name === 'light' + + if (color === 'primary') { + if (variant === 'solid') { + if (!disabled) { + baseStyles.push({ + backgroundColor: t.palette.primary_500, + }) + hoverStyles.push({ + backgroundColor: t.palette.primary_600, + }) + } else { + baseStyles.push({ + backgroundColor: t.palette.primary_700, + }) + } + } else if (variant === 'outline') { + baseStyles.push(a.border, t.atoms.bg, { + borderWidth: 1, + }) + + if (!disabled) { + baseStyles.push(a.border, { + borderColor: t.palette.primary_500, + }) + hoverStyles.push(a.border, { + backgroundColor: light + ? t.palette.primary_50 + : t.palette.primary_950, + }) + } else { + baseStyles.push(a.border, { + borderColor: light + ? t.palette.primary_200 + : t.palette.primary_900, + }) + } + } else if (variant === 'ghost') { + if (!disabled) { + baseStyles.push(t.atoms.bg) + hoverStyles.push({ + backgroundColor: light + ? t.palette.primary_100 + : t.palette.primary_900, + }) + } + } + } else if (color === 'secondary') { + if (variant === 'solid') { + if (!disabled) { + baseStyles.push({ + backgroundColor: t.palette.contrast_25, + }) + hoverStyles.push({ + backgroundColor: t.palette.contrast_50, + }) + } else { + baseStyles.push({ + backgroundColor: t.palette.contrast_100, + }) + } + } else if (variant === 'outline') { + baseStyles.push(a.border, t.atoms.bg, { + borderWidth: 1, + }) + + if (!disabled) { + baseStyles.push(a.border, { + borderColor: t.palette.contrast_300, + }) + hoverStyles.push(t.atoms.bg_contrast_50) + } else { + baseStyles.push(a.border, { + borderColor: t.palette.contrast_200, + }) + } + } else if (variant === 'ghost') { + if (!disabled) { + baseStyles.push(t.atoms.bg) + hoverStyles.push({ + backgroundColor: t.palette.contrast_100, + }) + } + } + } else if (color === 'negative') { + if (variant === 'solid') { + if (!disabled) { + baseStyles.push({ + backgroundColor: t.palette.negative_500, + }) + hoverStyles.push({ + backgroundColor: t.palette.negative_600, + }) + } else { + baseStyles.push({ + backgroundColor: t.palette.negative_700, + }) + } + } else if (variant === 'outline') { + baseStyles.push(a.border, t.atoms.bg, { + borderWidth: 1, + }) + + if (!disabled) { + baseStyles.push(a.border, { + borderColor: t.palette.negative_500, + }) + hoverStyles.push(a.border, { + backgroundColor: light + ? t.palette.negative_50 + : t.palette.negative_975, + }) + } else { + baseStyles.push(a.border, { + borderColor: light + ? t.palette.negative_200 + : t.palette.negative_900, + }) + } + } else if (variant === 'ghost') { + if (!disabled) { + baseStyles.push(t.atoms.bg) + hoverStyles.push({ + backgroundColor: light + ? t.palette.negative_100 + : t.palette.negative_975, + }) + } + } + } + + if (shape === 'default') { + if (size === 'large') { + baseStyles.push( + {paddingVertical: 15}, + a.px_2xl, + a.rounded_sm, + a.gap_md, + ) + } else if (size === 'medium') { + baseStyles.push( + {paddingVertical: 12}, + 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 === 'xsmall') { + baseStyles.push({paddingVertical: 6}, a.px_sm, 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') { + if (shape === 'round') { + baseStyles.push({height: 54, width: 54}) + } else { + baseStyles.push({height: 50, width: 50}) + } + } else if (size === 'small') { + baseStyles.push({height: 34, width: 34}) + } else if (size === 'xsmall') { + baseStyles.push({height: 28, width: 28}) + } else if (size === 'tiny') { + baseStyles.push({height: 20, width: 20}) + } + + if (shape === 'round') { + baseStyles.push(a.rounded_full) + } else if (shape === 'square') { + if (size === 'tiny') { + baseStyles.push(a.rounded_xs) + } else { + baseStyles.push(a.rounded_sm) + } + } + } + + return { + baseStyles, + hoverStyles, + } + }, [t, variant, color, size, shape, disabled]) + + const {gradientColors, gradientHoverColors, gradientLocations} = + React.useMemo(() => { + const colors: string[] = [] + const hoverColors: string[] = [] + const locations: number[] = [] + const gradient = { + primary: tokens.gradients.sky, + secondary: tokens.gradients.sky, + negative: tokens.gradients.sky, + gradient_sky: tokens.gradients.sky, + gradient_midnight: tokens.gradients.midnight, + gradient_sunrise: tokens.gradients.sunrise, + gradient_sunset: tokens.gradients.sunset, + gradient_nordic: tokens.gradients.nordic, + gradient_bonfire: tokens.gradients.bonfire, + }[color || 'primary'] + + if (variant === 'gradient') { + colors.push(...gradient.values.map(([_, color]) => color)) + hoverColors.push(...gradient.values.map(_ => gradient.hover_value)) + locations.push(...gradient.values.map(([location, _]) => location)) + } + + return { + gradientColors: colors, + gradientHoverColors: hoverColors, + gradientLocations: locations, + } + }, [variant, color]) + + const context = React.useMemo( + () => ({ + ...state, + variant, + color, + size, disabled: disabled || false, - }} - style={[ - a.flex_row, - a.align_center, - a.justify_center, - flattenedBaseStyles, - flatten(style), - ...(state.hovered || state.pressed - ? [hoverStyles, flatten(hoverStyleProp)] - : []), - ]} - onPressIn={onPressIn} - onPressOut={onPressOut} - onHoverIn={onHoverIn} - onHoverOut={onHoverOut} - onFocus={onFocus} - onBlur={onBlur}> - {variant === 'gradient' && ( - - - - )} - - {typeof children === 'function' ? children(context) : children} - - - ) -} + }), + [state, variant, color, size, disabled], + ) + + const flattenedBaseStyles = flatten(baseStyles) + + return ( + + {variant === 'gradient' && ( + + + + )} + + {typeof children === 'function' ? children(context) : children} + + + ) + }, +) +Button.displayName = 'Button' export function useSharedButtonTextStyles() { const t = useTheme() diff --git a/src/components/forms/TextField.tsx b/src/components/forms/TextField.tsx index f543c821e0..d513a6db99 100644 --- a/src/components/forms/TextField.tsx +++ b/src/components/forms/TextField.tsx @@ -197,6 +197,13 @@ export function createInput(Component: typeof TextInput) { textAlignVertical: rest.multiline ? 'top' : undefined, minHeight: rest.multiline ? 80 : undefined, }, + // fix for autofill styles covering border + web({ + paddingTop: 12, + paddingBottom: 12, + marginTop: 2, + marginBottom: 2, + }), android({ paddingBottom: 16, }), diff --git a/src/screens/Onboarding/StepProfile/index.tsx b/src/screens/Onboarding/StepProfile/index.tsx index 3556bba7a0..5304aa5031 100644 --- a/src/screens/Onboarding/StepProfile/index.tsx +++ b/src/screens/Onboarding/StepProfile/index.tsx @@ -181,8 +181,8 @@ export function StepProfile() { image = await openCropper({ mediaType: 'photo', cropperCircleOverlay: true, - height: image.height, - width: image.width, + height: 1000, + width: 1000, path: image.path, }) } diff --git a/src/view/com/util/UserAvatar.tsx b/src/view/com/util/UserAvatar.tsx index c212ea4c02..e9aa625806 100644 --- a/src/view/com/util/UserAvatar.tsx +++ b/src/view/com/util/UserAvatar.tsx @@ -303,8 +303,8 @@ let EditableUserAvatar = ({ const croppedImage = await openCropper({ mediaType: 'photo', cropperCircleOverlay: true, - height: item.height, - width: item.width, + height: 1000, + width: 1000, path: item.path, })