[APP-1310] Button cleanup (#8754)

* Rm gradient buttons from Storybook

* TEMP move storybook button section

* Remove gradient_sky

* Remove actual defs for gradient_sky and gradient_primary

* Remove other gradient defs

* Remove gradient support entirely

* Deprecate 'variant' in favor of 'color'

* Fork base styles codepath to make variant deprecation more obvious

* Remove text styles for when no color is set, never been used

* Fork text styles codepath to make variant deprecation more obvious

* Revert temp storybook commit, remove deprecated values

* Replace remaining gradient button usage
This commit is contained in:
Eric Bailey
2025-07-31 10:32:16 -05:00
committed by GitHub
parent 3bcfcba6d8
commit e87555c481
8 changed files with 315 additions and 483 deletions
+160 -198
View File
@@ -14,9 +14,8 @@ import {
View, View,
type ViewStyle, type ViewStyle,
} from 'react-native' } from 'react-native'
import {LinearGradient} from 'expo-linear-gradient'
import {atoms as a, flatten, select, tokens, useTheme} from '#/alf' import {atoms as a, flatten, select, useTheme} from '#/alf'
import {type Props as SVGIconProps} from '#/components/icons/common' import {type Props as SVGIconProps} from '#/components/icons/common'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
@@ -32,25 +31,19 @@ import {Text} from '#/components/Typography'
*/ */
export type UninheritableButtonProps = 'variant' | 'color' | 'size' | 'shape' export type UninheritableButtonProps = 'variant' | 'color' | 'size' | 'shape'
export type ButtonVariant = 'solid' | 'outline' | 'ghost' | 'gradient' export type ButtonVariant = 'solid' | 'outline' | 'ghost'
export type ButtonColor = export type ButtonColor =
| 'primary' | 'primary'
| 'secondary' | 'secondary'
| 'secondary_inverted' | 'secondary_inverted'
| 'negative' | 'negative'
| 'negative_secondary' | 'negative_secondary'
| 'gradient_primary'
| 'gradient_sky'
| 'gradient_midnight'
| 'gradient_sunrise'
| 'gradient_sunset'
| 'gradient_nordic'
| 'gradient_bonfire'
export type ButtonSize = 'tiny' | 'small' | 'large' export type ButtonSize = 'tiny' | 'small' | 'large'
export type ButtonShape = 'round' | 'square' | 'default' export type ButtonShape = 'round' | 'square' | 'default'
export type VariantProps = { export type VariantProps = {
/** /**
* The style variation of the button * The style variation of the button
* @deprecated Use `color` instead.
*/ */
variant?: ButtonVariant variant?: ButtonVariant
/** /**
@@ -143,6 +136,15 @@ export const Button = React.forwardRef<View, ButtonProps>(
}, },
ref, ref,
) => { ) => {
/**
* The `variant` prop is deprecated in favor of simply specifying `color`.
* If a `color` is set, then we want to use the existing codepaths for
* "solid" buttons. This is to maintain backwards compatibility.
*/
if (!variant && color) {
variant = 'solid'
}
const t = useTheme() const t = useTheme()
const [state, setState] = React.useState({ const [state, setState] = React.useState({
pressed: false, pressed: false,
@@ -215,8 +217,13 @@ export const Button = React.forwardRef<View, ButtonProps>(
const baseStyles: ViewStyle[] = [] const baseStyles: ViewStyle[] = []
const hoverStyles: ViewStyle[] = [] const hoverStyles: ViewStyle[] = []
if (color === 'primary') { /*
* This is the happy path for new button styles, following the
* deprecation of `variant` prop. This redundant `variant` check is here
* just to make this handling easier to understand.
*/
if (variant === 'solid') { if (variant === 'solid') {
if (color === 'primary') {
if (!disabled) { if (!disabled) {
baseStyles.push({ baseStyles.push({
backgroundColor: t.palette.primary_500, backgroundColor: t.palette.primary_500,
@@ -233,7 +240,75 @@ export const Button = React.forwardRef<View, ButtonProps>(
}), }),
}) })
} }
} else if (variant === 'outline') { } else if (color === 'secondary') {
if (!disabled) {
baseStyles.push(t.atoms.bg_contrast_25)
hoverStyles.push(t.atoms.bg_contrast_50)
} else {
baseStyles.push(t.atoms.bg_contrast_100)
}
} else if (color === 'secondary_inverted') {
if (!disabled) {
baseStyles.push({
backgroundColor: t.palette.contrast_900,
})
hoverStyles.push({
backgroundColor: t.palette.contrast_950,
})
} else {
baseStyles.push({
backgroundColor: t.palette.contrast_600,
})
}
} else if (color === 'negative') {
if (!disabled) {
baseStyles.push({
backgroundColor: t.palette.negative_500,
})
hoverStyles.push({
backgroundColor: t.palette.negative_600,
})
} else {
baseStyles.push({
backgroundColor: select(t.name, {
light: t.palette.negative_700,
dim: t.palette.negative_300,
dark: t.palette.negative_300,
}),
})
}
} else if (color === 'negative_secondary') {
if (!disabled) {
baseStyles.push({
backgroundColor: select(t.name, {
light: t.palette.negative_50,
dim: t.palette.negative_100,
dark: t.palette.negative_100,
}),
})
hoverStyles.push({
backgroundColor: select(t.name, {
light: t.palette.negative_100,
dim: t.palette.negative_200,
dark: t.palette.negative_200,
}),
})
} else {
baseStyles.push({
backgroundColor: select(t.name, {
light: t.palette.negative_100,
dim: t.palette.negative_50,
dark: t.palette.negative_50,
}),
})
}
}
} else {
/*
* BEGIN DEPRECATED STYLES
*/
if (color === 'primary') {
if (variant === 'outline') {
baseStyles.push(a.border, t.atoms.bg, { baseStyles.push(a.border, t.atoms.bg, {
borderWidth: 1, borderWidth: 1,
}) })
@@ -259,14 +334,7 @@ export const Button = React.forwardRef<View, ButtonProps>(
} }
} }
} else if (color === 'secondary') { } else if (color === 'secondary') {
if (variant === 'solid') { if (variant === 'outline') {
if (!disabled) {
baseStyles.push(t.atoms.bg_contrast_25)
hoverStyles.push(t.atoms.bg_contrast_50)
} else {
baseStyles.push(t.atoms.bg_contrast_100)
}
} else if (variant === 'outline') {
baseStyles.push(a.border, t.atoms.bg, { baseStyles.push(a.border, t.atoms.bg, {
borderWidth: 1, borderWidth: 1,
}) })
@@ -290,20 +358,7 @@ export const Button = React.forwardRef<View, ButtonProps>(
} }
} }
} else if (color === 'secondary_inverted') { } else if (color === 'secondary_inverted') {
if (variant === 'solid') { if (variant === 'outline') {
if (!disabled) {
baseStyles.push({
backgroundColor: t.palette.contrast_900,
})
hoverStyles.push({
backgroundColor: t.palette.contrast_950,
})
} else {
baseStyles.push({
backgroundColor: t.palette.contrast_600,
})
}
} else if (variant === 'outline') {
baseStyles.push(a.border, t.atoms.bg, { baseStyles.push(a.border, t.atoms.bg, {
borderWidth: 1, borderWidth: 1,
}) })
@@ -327,24 +382,7 @@ export const Button = React.forwardRef<View, ButtonProps>(
} }
} }
} else if (color === 'negative') { } else if (color === 'negative') {
if (variant === 'solid') { if (variant === 'outline') {
if (!disabled) {
baseStyles.push({
backgroundColor: t.palette.negative_500,
})
hoverStyles.push({
backgroundColor: t.palette.negative_600,
})
} else {
baseStyles.push({
backgroundColor: select(t.name, {
light: t.palette.negative_700,
dim: t.palette.negative_300,
dark: t.palette.negative_300,
}),
})
}
} else if (variant === 'outline') {
baseStyles.push(a.border, t.atoms.bg, { baseStyles.push(a.border, t.atoms.bg, {
borderWidth: 1, borderWidth: 1,
}) })
@@ -370,32 +408,7 @@ export const Button = React.forwardRef<View, ButtonProps>(
} }
} }
} else if (color === 'negative_secondary') { } else if (color === 'negative_secondary') {
if (variant === 'solid') { if (variant === 'outline') {
if (!disabled) {
baseStyles.push({
backgroundColor: select(t.name, {
light: t.palette.negative_50,
dim: t.palette.negative_100,
dark: t.palette.negative_100,
}),
})
hoverStyles.push({
backgroundColor: select(t.name, {
light: t.palette.negative_100,
dim: t.palette.negative_200,
dark: t.palette.negative_200,
}),
})
} else {
baseStyles.push({
backgroundColor: select(t.name, {
light: t.palette.negative_100,
dim: t.palette.negative_50,
dark: t.palette.negative_50,
}),
})
}
} else if (variant === 'outline') {
baseStyles.push(a.border, t.atoms.bg, { baseStyles.push(a.border, t.atoms.bg, {
borderWidth: 1, borderWidth: 1,
}) })
@@ -421,6 +434,10 @@ export const Button = React.forwardRef<View, ButtonProps>(
} }
} }
} }
/*
* END DEPRECATED STYLES
*/
}
if (shape === 'default') { if (shape === 'default') {
if (size === 'large') { if (size === 'large') {
@@ -483,49 +500,6 @@ export const Button = React.forwardRef<View, ButtonProps>(
} }
}, [t, variant, color, size, shape, disabled]) }, [t, variant, color, size, shape, disabled])
const gradientValues = React.useMemo(() => {
const gradient = {
primary: tokens.gradients.sky,
secondary: tokens.gradients.sky,
secondary_inverted: tokens.gradients.sky,
negative: tokens.gradients.sky,
negative_secondary: tokens.gradients.sky,
gradient_primary: tokens.gradients.primary,
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') {
if (gradient.values.length < 2) {
throw new Error(
'Gradient buttons must have at least two colors in the gradient',
)
}
return {
colors: gradient.values.map(([_, color]) => color) as [
string,
string,
...string[],
],
hoverColors: gradient.values.map(_ => gradient.hover_value) as [
string,
string,
...string[],
],
locations: gradient.values.map(([location, _]) => location) as [
number,
number,
...number[],
],
}
}
}, [variant, color])
const context = React.useMemo<ButtonContext>( const context = React.useMemo<ButtonContext>(
() => ({ () => ({
...state, ...state,
@@ -568,27 +542,6 @@ export const Button = React.forwardRef<View, ButtonProps>(
onHoverOut={onHoverOut} onHoverOut={onHoverOut}
onFocus={onFocus} onFocus={onFocus}
onBlur={onBlur}> onBlur={onBlur}>
{variant === 'gradient' && gradientValues && (
<View
style={[
a.absolute,
a.inset_0,
a.overflow_hidden,
{borderRadius: flattenedBaseStyles.borderRadius},
]}>
<LinearGradient
colors={
state.hovered || state.pressed
? gradientValues.hoverColors
: gradientValues.colors
}
locations={gradientValues.locations}
start={{x: 0, y: 0}}
end={{x: 1, y: 1}}
style={[a.absolute, a.inset_0]}
/>
</View>
)}
<Context.Provider value={context}> <Context.Provider value={context}>
{typeof children === 'function' ? children(context) : children} {typeof children === 'function' ? children(context) : children}
</Context.Provider> </Context.Provider>
@@ -604,14 +557,70 @@ export function useSharedButtonTextStyles() {
return React.useMemo(() => { return React.useMemo(() => {
const baseStyles: TextStyle[] = [] const baseStyles: TextStyle[] = []
if (color === 'primary') { /*
* This is the happy path for new button styles, following the
* deprecation of `variant` prop. This redundant `variant` check is here
* just to make this handling easier to understand.
*/
if (variant === 'solid') { if (variant === 'solid') {
if (color === 'primary') {
if (!disabled) { if (!disabled) {
baseStyles.push({color: t.palette.white}) baseStyles.push({color: t.palette.white})
} else { } else {
baseStyles.push({color: t.palette.white, opacity: 0.5}) baseStyles.push({color: t.palette.white, opacity: 0.5})
} }
} else if (variant === 'outline') { } else if (color === 'secondary') {
if (!disabled) {
baseStyles.push({
color: t.palette.contrast_700,
})
} else {
baseStyles.push({
color: t.palette.contrast_400,
})
}
} else if (color === 'secondary_inverted') {
if (!disabled) {
baseStyles.push({
color: t.palette.contrast_50,
})
} else {
baseStyles.push({
color: t.palette.contrast_400,
})
}
} else if (color === 'negative') {
if (!disabled) {
baseStyles.push({color: t.palette.white})
} else {
baseStyles.push({color: t.palette.white, opacity: 0.5})
}
} else if (color === 'negative_secondary') {
if (!disabled) {
baseStyles.push({
color: select(t.name, {
light: t.palette.negative_500,
dim: t.palette.negative_950,
dark: t.palette.negative_900,
}),
})
} else {
baseStyles.push({
color: select(t.name, {
light: t.palette.negative_500,
dim: t.palette.negative_700,
dark: t.palette.negative_700,
}),
opacity: 0.5,
})
}
}
} else {
/*
* BEGIN DEPRECATED STYLES
*/
if (color === 'primary') {
if (variant === 'outline') {
if (!disabled) { if (!disabled) {
baseStyles.push({ baseStyles.push({
color: t.palette.primary_600, color: t.palette.primary_600,
@@ -627,17 +636,7 @@ export function useSharedButtonTextStyles() {
} }
} }
} else if (color === 'secondary') { } else if (color === 'secondary') {
if (variant === 'solid' || variant === 'gradient') { if (variant === 'outline') {
if (!disabled) {
baseStyles.push({
color: t.palette.contrast_700,
})
} else {
baseStyles.push({
color: t.palette.contrast_400,
})
}
} else if (variant === 'outline') {
if (!disabled) { if (!disabled) {
baseStyles.push({ baseStyles.push({
color: t.palette.contrast_600, color: t.palette.contrast_600,
@@ -659,17 +658,7 @@ export function useSharedButtonTextStyles() {
} }
} }
} else if (color === 'secondary_inverted') { } else if (color === 'secondary_inverted') {
if (variant === 'solid' || variant === 'gradient') { if (variant === 'outline') {
if (!disabled) {
baseStyles.push({
color: t.palette.contrast_50,
})
} else {
baseStyles.push({
color: t.palette.contrast_400,
})
}
} else if (variant === 'outline') {
if (!disabled) { if (!disabled) {
baseStyles.push({ baseStyles.push({
color: t.palette.contrast_600, color: t.palette.contrast_600,
@@ -691,13 +680,7 @@ export function useSharedButtonTextStyles() {
} }
} }
} else if (color === 'negative') { } else if (color === 'negative') {
if (variant === 'solid' || variant === 'gradient') { if (variant === 'outline') {
if (!disabled) {
baseStyles.push({color: t.palette.white})
} else {
baseStyles.push({color: t.palette.white, opacity: 0.5})
}
} else if (variant === 'outline') {
if (!disabled) { if (!disabled) {
baseStyles.push({color: t.palette.negative_400}) baseStyles.push({color: t.palette.negative_400})
} else { } else {
@@ -711,26 +694,7 @@ export function useSharedButtonTextStyles() {
} }
} }
} else if (color === 'negative_secondary') { } else if (color === 'negative_secondary') {
if (variant === 'solid' || variant === 'gradient') { if (variant === 'outline') {
if (!disabled) {
baseStyles.push({
color: select(t.name, {
light: t.palette.negative_500,
dim: t.palette.negative_950,
dark: t.palette.negative_900,
}),
})
} else {
baseStyles.push({
color: select(t.name, {
light: t.palette.negative_500,
dim: t.palette.negative_700,
dark: t.palette.negative_700,
}),
opacity: 0.5,
})
}
} else if (variant === 'outline') {
if (!disabled) { if (!disabled) {
baseStyles.push({color: t.palette.negative_400}) baseStyles.push({color: t.palette.negative_400})
} else { } else {
@@ -743,12 +707,10 @@ export function useSharedButtonTextStyles() {
baseStyles.push({color: t.palette.negative_400, opacity: 0.5}) baseStyles.push({color: t.palette.negative_400, opacity: 0.5})
} }
} }
} else {
if (!disabled) {
baseStyles.push({color: t.palette.white})
} else {
baseStyles.push({color: t.palette.white, opacity: 0.5})
} }
/*
* END DEPRECATED STYLES
*/
} }
if (size === 'large') { if (size === 'large') {
+4 -3
View File
@@ -1,7 +1,8 @@
import React, {memo} from 'react' import {memo} from 'react'
import {StyleProp, View, ViewStyle} from 'react-native' import {type StyleProp, View, type ViewStyle} from 'react-native'
import {msg, Trans} from '@lingui/macro' import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import type React from 'react'
import {cleanError} from '#/lib/strings/errors' import {cleanError} from '#/lib/strings/errors'
import {CenteredView} from '#/view/com/util/Views' import {CenteredView} from '#/view/com/util/Views'
@@ -95,7 +96,7 @@ function ListFooterMaybeError({
)} )}
</Text> </Text>
<Button <Button
variant="gradient" variant="solid"
label={_(msg`Press to retry`)} label={_(msg`Press to retry`)}
style={[ style={[
a.align_center, a.align_center,
+2 -2
View File
@@ -305,8 +305,8 @@ export function StepFinished() {
<Button <Button
disabled={saving} disabled={saving}
key={state.activeStep} // remove focus state on nav key={state.activeStep} // remove focus state on nav
variant="gradient" variant="solid"
color="gradient_sky" color="primary"
size="large" size="large"
label={_(msg`Complete onboarding and start using your account`)} label={_(msg`Complete onboarding and start using your account`)}
onPress={finishOnboarding}> onPress={finishOnboarding}>
@@ -15,7 +15,7 @@ import {
TitleText, TitleText,
} from '#/screens/Onboarding/Layout' } from '#/screens/Onboarding/Layout'
import { import {
ApiResponseMap, type ApiResponseMap,
Context, Context,
useInterestsDisplayNames, useInterestsDisplayNames,
} from '#/screens/Onboarding/state' } from '#/screens/Onboarding/state'
@@ -235,8 +235,8 @@ export function StepInterests() {
) : ( ) : (
<Button <Button
disabled={saving || !data} disabled={saving || !data}
variant="gradient" variant="solid"
color="gradient_sky" color="primary"
size="large" size="large"
label={_(msg`Continue to next step`)} label={_(msg`Continue to next step`)}
onPress={saveInterests}> onPress={saveInterests}>
+2 -2
View File
@@ -267,8 +267,8 @@ export function StepProfile() {
<OnboardingControls.Portal> <OnboardingControls.Portal>
<View style={[a.gap_md, gtMobile && {flexDirection: 'row-reverse'}]}> <View style={[a.gap_md, gtMobile && {flexDirection: 'row-reverse'}]}>
<Button <Button
variant="gradient" variant="solid"
color="gradient_sky" color="primary"
size="large" size="large"
label={_(msg`Continue to next step`)} label={_(msg`Continue to next step`)}
onPress={onContinue}> onPress={onContinue}>
+30 -154
View File
@@ -1,4 +1,3 @@
import React from 'react'
import {View} from 'react-native' import {View} from 'react-native'
import {atoms as a} from '#/alf' import {atoms as a} from '#/alf'
@@ -7,7 +6,6 @@ import {
type ButtonColor, type ButtonColor,
ButtonIcon, ButtonIcon,
ButtonText, ButtonText,
type ButtonVariant,
} from '#/components/Button' } from '#/components/Button'
import {ChevronLeft_Stroke2_Corner0_Rounded as ChevronLeft} from '#/components/icons/Chevron' import {ChevronLeft_Stroke2_Corner0_Rounded as ChevronLeft} from '#/components/icons/Chevron'
import {Globe_Stroke2_Corner0_Rounded as Globe} from '#/components/icons/Globe' import {Globe_Stroke2_Corner0_Rounded as Globe} from '#/components/icons/Globe'
@@ -27,10 +25,7 @@ export function Buttons() {
'negative_secondary', 'negative_secondary',
].map(color => ( ].map(color => (
<View key={color} style={[a.gap_md, a.align_start]}> <View key={color} style={[a.gap_md, a.align_start]}>
{['solid', 'outline', 'ghost'].map(variant => (
<React.Fragment key={variant}>
<Button <Button
variant={variant as ButtonVariant}
color={color as ButtonColor} color={color as ButtonColor}
size="large" size="large"
label="Click here"> label="Click here">
@@ -38,247 +33,128 @@ export function Buttons() {
</Button> </Button>
<Button <Button
disabled disabled
variant={variant as ButtonVariant}
color={color as ButtonColor} color={color as ButtonColor}
size="large" size="large"
label="Click here"> label="Click here">
<ButtonText>Button</ButtonText> <ButtonText>Button</ButtonText>
</Button> </Button>
</React.Fragment>
))}
</View> </View>
))} ))}
<View style={[a.flex_row, a.gap_md, a.align_start]}>
<View style={[a.gap_md, a.align_start]}>
{['gradient_sky', 'gradient_midnight', 'gradient_sunrise'].map(
name => (
<React.Fragment key={name}>
<Button
variant="gradient"
color={name as ButtonColor}
size="large"
label="Click here">
<ButtonText>Button</ButtonText>
</Button>
<Button
disabled
variant="gradient"
color={name as ButtonColor}
size="large"
label="Click here">
<ButtonText>Button</ButtonText>
</Button>
</React.Fragment>
),
)}
</View>
</View>
</View> </View>
<View style={[a.flex_wrap, a.gap_md, a.align_start]}> <View style={[a.flex_wrap, a.gap_md, a.align_start]}>
<Button variant="solid" color="primary" size="large" label="Link out"> <Button color="primary" size="large" label="Link out">
<ButtonText>Button</ButtonText> <ButtonText>Button</ButtonText>
</Button> </Button>
<Button variant="solid" color="primary" size="large" label="Link out"> <Button color="primary" size="large" label="Link out">
<ButtonText>Button</ButtonText> <ButtonText>Button</ButtonText>
<ButtonIcon icon={Globe} position="right" /> <ButtonIcon icon={Globe} position="right" />
</Button> </Button>
<Button variant="solid" color="primary" size="small" label="Link out"> <Button color="primary" size="small" label="Link out">
<ButtonText>Button</ButtonText> <ButtonText>Button</ButtonText>
</Button> </Button>
<Button variant="solid" color="primary" size="small" label="Link out"> <Button color="primary" size="small" label="Link out">
<ButtonText>Button</ButtonText> <ButtonText>Button</ButtonText>
<ButtonIcon icon={Globe} position="right" /> <ButtonIcon icon={Globe} position="right" />
</Button> </Button>
<Button variant="solid" color="primary" size="tiny" label="Link out"> <Button color="primary" size="tiny" label="Link out">
<ButtonIcon icon={Globe} position="left" /> <ButtonIcon icon={Globe} position="left" />
<ButtonText>Button</ButtonText> <ButtonText>Button</ButtonText>
</Button> </Button>
</View> </View>
<View style={[a.flex_row, a.gap_md, a.align_center]}> <View style={[a.flex_row, a.gap_md, a.align_center]}>
<Button variant="solid" color="primary" size="large" label="Link out"> <Button color="primary" size="large" label="Link out">
<ButtonText>Button</ButtonText> <ButtonText>Button</ButtonText>
</Button> </Button>
<Button variant="solid" color="primary" size="large" label="Link out"> <Button color="primary" size="large" label="Link out">
<ButtonText>Button</ButtonText> <ButtonText>Button</ButtonText>
<ButtonIcon icon={Globe} position="right" /> <ButtonIcon icon={Globe} position="right" />
</Button> </Button>
<Button variant="solid" color="primary" size="large" label="Link out"> <Button color="primary" size="large" label="Link out">
<ButtonText>Button</ButtonText> <ButtonText>Button</ButtonText>
<ButtonIcon icon={Globe} position="right" size="lg" /> <ButtonIcon icon={Globe} position="right" size="lg" />
</Button> </Button>
<Button <Button color="primary" size="large" shape="round" label="Link out">
variant="solid"
color="primary"
size="large"
shape="round"
label="Link out">
<ButtonIcon icon={ChevronLeft} /> <ButtonIcon icon={ChevronLeft} />
</Button> </Button>
<Button <Button color="primary" size="large" shape="round" label="Link out">
variant="solid"
color="primary"
size="large"
shape="round"
label="Link out">
<ButtonIcon icon={ChevronLeft} size="lg" /> <ButtonIcon icon={ChevronLeft} size="lg" />
</Button> </Button>
</View> </View>
<View style={[a.flex_row, a.gap_md, a.align_center]}> <View style={[a.flex_row, a.gap_md, a.align_center]}>
<Button variant="solid" color="primary" size="small" label="Link out"> <Button color="primary" size="small" label="Link out">
<ButtonText>Button</ButtonText> <ButtonText>Button</ButtonText>
</Button> </Button>
<Button variant="solid" color="primary" size="small" label="Link out"> <Button color="primary" size="small" label="Link out">
<ButtonText>Button</ButtonText> <ButtonText>Button</ButtonText>
<ButtonIcon icon={Globe} position="right" /> <ButtonIcon icon={Globe} position="right" />
</Button> </Button>
<Button <Button color="primary" size="small" shape="round" label="Link out">
variant="solid"
color="primary"
size="small"
shape="round"
label="Link out">
<ButtonIcon icon={ChevronLeft} /> <ButtonIcon icon={ChevronLeft} />
</Button> </Button>
<Button <Button color="primary" size="small" shape="round" label="Link out">
variant="solid"
color="primary"
size="small"
shape="round"
label="Link out">
<ButtonIcon icon={ChevronLeft} size="lg" /> <ButtonIcon icon={ChevronLeft} size="lg" />
</Button> </Button>
</View> </View>
<View style={[a.flex_row, a.gap_md, a.align_center]}> <View style={[a.flex_row, a.gap_md, a.align_center]}>
<Button variant="solid" color="primary" size="tiny" label="Link out"> <Button color="primary" size="tiny" label="Link out">
<ButtonText>Button</ButtonText> <ButtonText>Button</ButtonText>
</Button> </Button>
<Button variant="solid" color="primary" size="tiny" label="Link out"> <Button color="primary" size="tiny" label="Link out">
<ButtonText>Button</ButtonText> <ButtonText>Button</ButtonText>
<ButtonIcon icon={Globe} position="right" /> <ButtonIcon icon={Globe} position="right" />
</Button> </Button>
<Button <Button color="primary" size="tiny" shape="round" label="Link out">
variant="solid"
color="primary"
size="tiny"
shape="round"
label="Link out">
<ButtonIcon icon={ChevronLeft} /> <ButtonIcon icon={ChevronLeft} />
</Button> </Button>
<Button <Button color="primary" size="tiny" shape="round" label="Link out">
variant="solid"
color="primary"
size="tiny"
shape="round"
label="Link out">
<ButtonIcon icon={ChevronLeft} size="md" /> <ButtonIcon icon={ChevronLeft} size="md" />
</Button> </Button>
</View> </View>
<View style={[a.flex_row, a.gap_md, a.align_center]}> <View style={[a.flex_row, a.gap_md, a.align_center]}>
<Button <Button color="primary" size="large" shape="round" label="Link out">
variant="solid"
color="primary"
size="large"
shape="round"
label="Link out">
<ButtonIcon icon={ChevronLeft} /> <ButtonIcon icon={ChevronLeft} />
</Button> </Button>
<Button <Button color="primary" size="small" shape="round" label="Link out">
variant="gradient"
color="gradient_sunset"
size="small"
shape="round"
label="Link out">
<ButtonIcon icon={ChevronLeft} /> <ButtonIcon icon={ChevronLeft} />
</Button> </Button>
<Button <Button color="primary" size="tiny" shape="round" label="Link out">
variant="gradient"
color="gradient_sunset"
size="tiny"
shape="round"
label="Link out">
<ButtonIcon icon={ChevronLeft} /> <ButtonIcon icon={ChevronLeft} />
</Button> </Button>
<Button <Button color="primary" size="large" shape="round" label="Link out">
variant="outline"
color="primary"
size="large"
shape="round"
label="Link out">
<ButtonIcon icon={ChevronLeft} /> <ButtonIcon icon={ChevronLeft} />
</Button> </Button>
<Button <Button color="primary" size="small" shape="round" label="Link out">
variant="ghost"
color="primary"
size="small"
shape="round"
label="Link out">
<ButtonIcon icon={ChevronLeft} /> <ButtonIcon icon={ChevronLeft} />
</Button> </Button>
<Button <Button color="primary" size="tiny" shape="round" label="Link out">
variant="ghost"
color="primary"
size="tiny"
shape="round"
label="Link out">
<ButtonIcon icon={ChevronLeft} /> <ButtonIcon icon={ChevronLeft} />
</Button> </Button>
</View> </View>
<View style={[a.flex_row, a.gap_md, a.align_start]}> <View style={[a.flex_row, a.gap_md, a.align_start]}>
<Button <Button color="primary" size="large" shape="square" label="Link out">
variant="solid"
color="primary"
size="large"
shape="square"
label="Link out">
<ButtonIcon icon={ChevronLeft} /> <ButtonIcon icon={ChevronLeft} />
</Button> </Button>
<Button <Button color="primary" size="small" shape="square" label="Link out">
variant="gradient"
color="gradient_sunset"
size="small"
shape="square"
label="Link out">
<ButtonIcon icon={ChevronLeft} /> <ButtonIcon icon={ChevronLeft} />
</Button> </Button>
<Button <Button color="primary" size="tiny" shape="square" label="Link out">
variant="gradient"
color="gradient_sunset"
size="tiny"
shape="square"
label="Link out">
<ButtonIcon icon={ChevronLeft} /> <ButtonIcon icon={ChevronLeft} />
</Button> </Button>
<Button <Button color="primary" size="large" shape="square" label="Link out">
variant="outline"
color="primary"
size="large"
shape="square"
label="Link out">
<ButtonIcon icon={ChevronLeft} /> <ButtonIcon icon={ChevronLeft} />
</Button> </Button>
<Button <Button color="primary" size="small" shape="square" label="Link out">
variant="ghost"
color="primary"
size="small"
shape="square"
label="Link out">
<ButtonIcon icon={ChevronLeft} /> <ButtonIcon icon={ChevronLeft} />
</Button> </Button>
<Button <Button color="primary" size="tiny" shape="square" label="Link out">
variant="ghost"
color="primary"
size="tiny"
shape="square"
label="Link out">
<ButtonIcon icon={ChevronLeft} /> <ButtonIcon icon={ChevronLeft} />
</Button> </Button>
</View> </View>
+3 -3
View File
@@ -1,5 +1,5 @@
import React from 'react' import React from 'react'
import {TextInput, View} from 'react-native' import {type TextInput, View} from 'react-native'
import {atoms as a} from '#/alf' import {atoms as a} from '#/alf'
import {Button, ButtonText} from '#/components/Button' import {Button, ButtonText} from '#/components/Button'
@@ -216,8 +216,8 @@ export function Forms() {
</View> </View>
<Button <Button
variant="gradient" variant="solid"
color="gradient_nordic" color="primary"
size="small" size="small"
label="Reset all toggles" label="Reset all toggles"
onPress={() => { onPress={() => {
-7
View File
@@ -52,7 +52,6 @@ function StorybookInner() {
<> <>
<View style={[a.flex_row, a.align_start, a.gap_md]}> <View style={[a.flex_row, a.align_start, a.gap_md]}>
<Button <Button
variant="outline"
color="primary" color="primary"
size="small" size="small"
label='Set theme to "system"' label='Set theme to "system"'
@@ -60,7 +59,6 @@ function StorybookInner() {
<ButtonText>System</ButtonText> <ButtonText>System</ButtonText>
</Button> </Button>
<Button <Button
variant="solid"
color="secondary" color="secondary"
size="small" size="small"
label='Set theme to "light"' label='Set theme to "light"'
@@ -68,7 +66,6 @@ function StorybookInner() {
<ButtonText>Light</ButtonText> <ButtonText>Light</ButtonText>
</Button> </Button>
<Button <Button
variant="solid"
color="secondary" color="secondary"
size="small" size="small"
label='Set theme to "dim"' label='Set theme to "dim"'
@@ -79,7 +76,6 @@ function StorybookInner() {
<ButtonText>Dim</ButtonText> <ButtonText>Dim</ButtonText>
</Button> </Button>
<Button <Button
variant="solid"
color="secondary" color="secondary"
size="small" size="small"
label='Set theme to "dark"' label='Set theme to "dark"'
@@ -94,7 +90,6 @@ function StorybookInner() {
<Toasts /> <Toasts />
<Button <Button
variant="solid"
color="primary" color="primary"
size="small" size="small"
onPress={() => navigation.navigate('SharedPreferencesTester')} onPress={() => navigation.navigate('SharedPreferencesTester')}
@@ -128,7 +123,6 @@ function StorybookInner() {
<Settings /> <Settings />
<Button <Button
variant="solid"
color="primary" color="primary"
size="large" size="large"
label="Switch to Contained List" label="Switch to Contained List"
@@ -139,7 +133,6 @@ function StorybookInner() {
) : ( ) : (
<> <>
<Button <Button
variant="solid"
color="primary" color="primary"
size="large" size="large"
label="Switch to Storybook" label="Switch to Storybook"