about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/components/Button.tsx160
-rw-r--r--src/components/live/EditLiveDialog.tsx2
-rw-r--r--src/view/screens/Storybook/Buttons.tsx212
-rw-r--r--src/view/screens/Storybook/index.tsx2
4 files changed, 170 insertions, 206 deletions
diff --git a/src/components/Button.tsx b/src/components/Button.tsx
index 57a8530b5..4759b2a88 100644
--- a/src/components/Button.tsx
+++ b/src/components/Button.tsx
@@ -37,7 +37,8 @@ export type ButtonColor =
   | 'secondary'
   | 'secondary_inverted'
   | 'negative'
-  | 'negative_secondary'
+  | 'primary_subtle'
+  | 'negative_subtle'
 export type ButtonSize = 'tiny' | 'small' | 'large'
 export type ButtonShape = 'round' | 'square' | 'default'
 export type VariantProps = {
@@ -214,7 +215,11 @@ export const Button = React.forwardRef<View, ButtonProps>(
     )
 
     const {baseStyles, hoverStyles} = React.useMemo(() => {
-      const baseStyles: ViewStyle[] = []
+      const baseStyles: ViewStyle[] = [
+        {
+          borderCurve: 'continuous',
+        },
+      ]
       const hoverStyles: ViewStyle[] = []
 
       /*
@@ -233,19 +238,15 @@ export const Button = React.forwardRef<View, ButtonProps>(
             })
           } else {
             baseStyles.push({
-              backgroundColor: select(t.name, {
-                light: t.palette.primary_700,
-                dim: t.palette.primary_300,
-                dark: t.palette.primary_300,
-              }),
+              backgroundColor: t.palette.primary_200,
             })
           }
         } else if (color === 'secondary') {
           if (!disabled) {
             baseStyles.push(t.atoms.bg_contrast_25)
-            hoverStyles.push(t.atoms.bg_contrast_50)
+            hoverStyles.push(t.atoms.bg_contrast_100)
           } else {
-            baseStyles.push(t.atoms.bg_contrast_100)
+            baseStyles.push(t.atoms.bg_contrast_50)
           }
         } else if (color === 'secondary_inverted') {
           if (!disabled) {
@@ -253,7 +254,7 @@ export const Button = React.forwardRef<View, ButtonProps>(
               backgroundColor: t.palette.contrast_900,
             })
             hoverStyles.push({
-              backgroundColor: t.palette.contrast_950,
+              backgroundColor: t.palette.contrast_975,
             })
           } else {
             baseStyles.push({
@@ -270,14 +271,35 @@ export const Button = React.forwardRef<View, ButtonProps>(
             })
           } else {
             baseStyles.push({
+              backgroundColor: t.palette.negative_700,
+            })
+          }
+        } else if (color === 'primary_subtle') {
+          if (!disabled) {
+            baseStyles.push({
+              backgroundColor: select(t.name, {
+                light: t.palette.primary_50,
+                dim: t.palette.primary_100,
+                dark: t.palette.primary_100,
+              }),
+            })
+            hoverStyles.push({
+              backgroundColor: select(t.name, {
+                light: t.palette.primary_100,
+                dim: t.palette.primary_200,
+                dark: t.palette.primary_200,
+              }),
+            })
+          } else {
+            baseStyles.push({
               backgroundColor: select(t.name, {
-                light: t.palette.negative_700,
-                dim: t.palette.negative_300,
-                dark: t.palette.negative_300,
+                light: t.palette.primary_25,
+                dim: t.palette.primary_50,
+                dark: t.palette.primary_50,
               }),
             })
           }
-        } else if (color === 'negative_secondary') {
+        } else if (color === 'negative_subtle') {
           if (!disabled) {
             baseStyles.push({
               backgroundColor: select(t.name, {
@@ -296,7 +318,7 @@ export const Button = React.forwardRef<View, ButtonProps>(
           } else {
             baseStyles.push({
               backgroundColor: select(t.name, {
-                light: t.palette.negative_100,
+                light: t.palette.negative_25,
                 dim: t.palette.negative_50,
                 dark: t.palette.negative_50,
               }),
@@ -407,7 +429,7 @@ export const Button = React.forwardRef<View, ButtonProps>(
               })
             }
           }
-        } else if (color === 'negative_secondary') {
+        } else if (color === 'negative_subtle') {
           if (variant === 'outline') {
             baseStyles.push(a.border, t.atoms.bg, {
               borderWidth: 1,
@@ -442,44 +464,48 @@ export const Button = React.forwardRef<View, ButtonProps>(
       if (shape === 'default') {
         if (size === 'large') {
           baseStyles.push({
-            paddingVertical: 13,
-            paddingHorizontal: 20,
-            borderRadius: 8,
-            gap: 8,
+            paddingVertical: 14,
+            paddingHorizontal: 24,
+            borderRadius: 10,
+            gap: 4,
           })
         } else if (size === 'small') {
           baseStyles.push({
-            paddingVertical: 9,
+            paddingVertical: 8,
             paddingHorizontal: 12,
-            borderRadius: 6,
-            gap: 6,
+            borderRadius: 8,
+            gap: 3,
           })
         } else if (size === 'tiny') {
           baseStyles.push({
-            paddingVertical: 4,
+            paddingVertical: 6,
             paddingHorizontal: 8,
-            borderRadius: 4,
-            gap: 4,
+            borderRadius: 6,
+            gap: 2,
           })
         }
       } else if (shape === 'round' || shape === 'square') {
+        /*
+         * These sizes match the actual rendered size on screen, based on
+         * Chrome's web inspector
+         */
         if (size === 'large') {
           if (shape === 'round') {
-            baseStyles.push({height: 46, width: 46})
+            baseStyles.push({height: 45, width: 45})
           } else {
-            baseStyles.push({height: 44, width: 44})
+            baseStyles.push({height: 45, width: 45})
           }
         } else if (size === 'small') {
           if (shape === 'round') {
-            baseStyles.push({height: 34, width: 34})
+            baseStyles.push({height: 33, width: 33})
           } else {
-            baseStyles.push({height: 34, width: 34})
+            baseStyles.push({height: 33, width: 33})
           }
         } else if (size === 'tiny') {
           if (shape === 'round') {
-            baseStyles.push({height: 22, width: 22})
+            baseStyles.push({height: 25, width: 25})
           } else {
-            baseStyles.push({height: 21, width: 21})
+            baseStyles.push({height: 25, width: 25})
           }
         }
 
@@ -487,7 +513,9 @@ export const Button = React.forwardRef<View, ButtonProps>(
           baseStyles.push(a.rounded_full)
         } else if (shape === 'square') {
           if (size === 'tiny') {
-            baseStyles.push(a.rounded_xs)
+            baseStyles.push({
+              borderRadius: 6,
+            })
           } else {
             baseStyles.push(a.rounded_sm)
           }
@@ -567,51 +595,64 @@ export function useSharedButtonTextStyles() {
         if (!disabled) {
           baseStyles.push({color: t.palette.white})
         } else {
-          baseStyles.push({color: t.palette.white, opacity: 0.5})
+          baseStyles.push({color: t.palette.white})
         }
       } else if (color === 'secondary') {
         if (!disabled) {
-          baseStyles.push({
-            color: t.palette.contrast_700,
-          })
+          baseStyles.push(t.atoms.text_contrast_medium)
         } else {
           baseStyles.push({
-            color: t.palette.contrast_400,
+            color: t.palette.contrast_300,
           })
         }
       } else if (color === 'secondary_inverted') {
         if (!disabled) {
-          baseStyles.push({
-            color: t.palette.contrast_50,
-          })
+          baseStyles.push(t.atoms.text_inverted)
         } else {
           baseStyles.push({
-            color: t.palette.contrast_400,
+            color: t.palette.contrast_300,
           })
         }
       } else if (color === 'negative') {
         if (!disabled) {
           baseStyles.push({color: t.palette.white})
         } else {
-          baseStyles.push({color: t.palette.white, opacity: 0.5})
+          baseStyles.push({color: t.palette.negative_300})
         }
-      } else if (color === 'negative_secondary') {
+      } else if (color === 'primary_subtle') {
         if (!disabled) {
           baseStyles.push({
             color: select(t.name, {
-              light: t.palette.negative_500,
-              dim: t.palette.negative_950,
-              dark: t.palette.negative_900,
+              light: t.palette.primary_600,
+              dim: t.palette.primary_800,
+              dark: t.palette.primary_800,
             }),
           })
         } else {
           baseStyles.push({
             color: select(t.name, {
-              light: t.palette.negative_500,
-              dim: t.palette.negative_700,
-              dark: t.palette.negative_700,
+              light: t.palette.primary_200,
+              dim: t.palette.primary_200,
+              dark: t.palette.primary_200,
+            }),
+          })
+        }
+      } else if (color === 'negative_subtle') {
+        if (!disabled) {
+          baseStyles.push({
+            color: select(t.name, {
+              light: t.palette.negative_600,
+              dim: t.palette.negative_800,
+              dark: t.palette.negative_800,
+            }),
+          })
+        } else {
+          baseStyles.push({
+            color: select(t.name, {
+              light: t.palette.negative_200,
+              dim: t.palette.negative_200,
+              dark: t.palette.negative_200,
             }),
-            opacity: 0.5,
           })
         }
       }
@@ -693,7 +734,7 @@ export function useSharedButtonTextStyles() {
             baseStyles.push({color: t.palette.negative_400, opacity: 0.5})
           }
         }
-      } else if (color === 'negative_secondary') {
+      } else if (color === 'negative_subtle') {
         if (variant === 'outline') {
           if (!disabled) {
             baseStyles.push({color: t.palette.negative_400})
@@ -716,7 +757,7 @@ export function useSharedButtonTextStyles() {
     if (size === 'large') {
       baseStyles.push(a.text_md, a.leading_tight)
     } else if (size === 'small') {
-      baseStyles.push(a.text_sm, a.leading_tight)
+      baseStyles.push(a.text_md, a.leading_tight)
     } else if (size === 'tiny') {
       baseStyles.push(a.text_xs, a.leading_tight)
     }
@@ -737,14 +778,16 @@ export function ButtonText({children, style, ...rest}: ButtonTextProps) {
 
 export function ButtonIcon({
   icon: Comp,
-  position,
   size,
 }: {
   icon: React.ComponentType<SVGIconProps>
+  /**
+   * @deprecated no longer needed
+   */
   position?: 'left' | 'right'
   size?: SVGIconProps['size']
 }) {
-  const {size: buttonSize, disabled} = useButtonContext()
+  const {size: buttonSize} = useButtonContext()
   const textStyles = useSharedButtonTextStyles()
   const {iconSize, iconContainerSize} = React.useMemo(() => {
     /**
@@ -779,8 +822,8 @@ export function ButtonIcon({
      * don't increase button size
      */
     const iconContainerSize = {
-      large: 18,
-      small: 16,
+      large: 17,
+      small: 17,
       tiny: 13,
     }[buttonSize || 'small']
 
@@ -797,9 +840,6 @@ export function ButtonIcon({
         {
           width: iconContainerSize,
           height: iconContainerSize,
-          opacity: disabled ? 0.7 : 1,
-          marginLeft: position === 'left' ? -2 : 0,
-          marginRight: position === 'right' ? -2 : 0,
         },
       ]}>
       <View
diff --git a/src/components/live/EditLiveDialog.tsx b/src/components/live/EditLiveDialog.tsx
index cdffb3286..63fe664e5 100644
--- a/src/components/live/EditLiveDialog.tsx
+++ b/src/components/live/EditLiveDialog.tsx
@@ -240,7 +240,7 @@ function DialogInner({
             label={_(msg`Remove live status`)}
             onPress={() => removeLiveStatus()}
             size={platform({native: 'large', web: 'small'})}
-            color="negative_secondary"
+            color="negative_subtle"
             variant="solid"
             disabled={isRemovingLiveStatus || isGoingLive}>
             <ButtonText>
diff --git a/src/view/screens/Storybook/Buttons.tsx b/src/view/screens/Storybook/Buttons.tsx
index eaf8bba7e..0db062913 100644
--- a/src/view/screens/Storybook/Buttons.tsx
+++ b/src/view/screens/Storybook/Buttons.tsx
@@ -1,3 +1,4 @@
+import {Fragment} from 'react'
 import {View} from 'react-native'
 
 import {atoms as a} from '#/alf'
@@ -5,159 +6,82 @@ import {
   Button,
   type ButtonColor,
   ButtonIcon,
+  type ButtonSize,
   ButtonText,
 } from '#/components/Button'
 import {ChevronLeft_Stroke2_Corner0_Rounded as ChevronLeft} from '#/components/icons/Chevron'
 import {Globe_Stroke2_Corner0_Rounded as Globe} from '#/components/icons/Globe'
-import {H1} from '#/components/Typography'
+import {Text} from '#/components/Typography'
 
 export function Buttons() {
   return (
     <View style={[a.gap_md]}>
-      <H1>Buttons</H1>
+      <Text style={[a.font_heavy, a.text_5xl]}>Buttons</Text>
 
-      <View style={[a.flex_row, a.flex_wrap, a.gap_md, a.align_start]}>
-        {[
-          'primary',
-          'secondary',
-          'secondary_inverted',
-          'negative',
-          'negative_secondary',
-        ].map(color => (
-          <View key={color} style={[a.gap_md, a.align_start]}>
-            <Button
-              color={color as ButtonColor}
-              size="large"
-              label="Click here">
-              <ButtonText>Button</ButtonText>
-            </Button>
-            <Button
-              disabled
-              color={color as ButtonColor}
-              size="large"
-              label="Click here">
-              <ButtonText>Button</ButtonText>
-            </Button>
-          </View>
-        ))}
-      </View>
-
-      <View style={[a.flex_wrap, a.gap_md, a.align_start]}>
-        <Button color="primary" size="large" label="Link out">
-          <ButtonText>Button</ButtonText>
-        </Button>
-        <Button color="primary" size="large" label="Link out">
-          <ButtonText>Button</ButtonText>
-          <ButtonIcon icon={Globe} position="right" />
-        </Button>
-
-        <Button color="primary" size="small" label="Link out">
-          <ButtonText>Button</ButtonText>
-        </Button>
-        <Button color="primary" size="small" label="Link out">
-          <ButtonText>Button</ButtonText>
-          <ButtonIcon icon={Globe} position="right" />
-        </Button>
-
-        <Button color="primary" size="tiny" label="Link out">
-          <ButtonIcon icon={Globe} position="left" />
-          <ButtonText>Button</ButtonText>
-        </Button>
-      </View>
-
-      <View style={[a.flex_row, a.gap_md, a.align_center]}>
-        <Button color="primary" size="large" label="Link out">
-          <ButtonText>Button</ButtonText>
-        </Button>
-        <Button color="primary" size="large" label="Link out">
-          <ButtonText>Button</ButtonText>
-          <ButtonIcon icon={Globe} position="right" />
-        </Button>
-        <Button color="primary" size="large" label="Link out">
-          <ButtonText>Button</ButtonText>
-          <ButtonIcon icon={Globe} position="right" size="lg" />
-        </Button>
-        <Button color="primary" size="large" shape="round" label="Link out">
-          <ButtonIcon icon={ChevronLeft} />
-        </Button>
-        <Button color="primary" size="large" shape="round" label="Link out">
-          <ButtonIcon icon={ChevronLeft} size="lg" />
-        </Button>
-      </View>
-
-      <View style={[a.flex_row, a.gap_md, a.align_center]}>
-        <Button color="primary" size="small" label="Link out">
-          <ButtonText>Button</ButtonText>
-        </Button>
-        <Button color="primary" size="small" label="Link out">
-          <ButtonText>Button</ButtonText>
-          <ButtonIcon icon={Globe} position="right" />
-        </Button>
-        <Button color="primary" size="small" shape="round" label="Link out">
-          <ButtonIcon icon={ChevronLeft} />
-        </Button>
-        <Button color="primary" size="small" shape="round" label="Link out">
-          <ButtonIcon icon={ChevronLeft} size="lg" />
-        </Button>
-      </View>
-
-      <View style={[a.flex_row, a.gap_md, a.align_center]}>
-        <Button color="primary" size="tiny" label="Link out">
-          <ButtonText>Button</ButtonText>
-        </Button>
-        <Button color="primary" size="tiny" label="Link out">
-          <ButtonText>Button</ButtonText>
-          <ButtonIcon icon={Globe} position="right" />
-        </Button>
-        <Button color="primary" size="tiny" shape="round" label="Link out">
-          <ButtonIcon icon={ChevronLeft} />
-        </Button>
-        <Button color="primary" size="tiny" shape="round" label="Link out">
-          <ButtonIcon icon={ChevronLeft} size="md" />
-        </Button>
-      </View>
-
-      <View style={[a.flex_row, a.gap_md, a.align_center]}>
-        <Button color="primary" size="large" shape="round" label="Link out">
-          <ButtonIcon icon={ChevronLeft} />
-        </Button>
-        <Button color="primary" size="small" shape="round" label="Link out">
-          <ButtonIcon icon={ChevronLeft} />
-        </Button>
-        <Button color="primary" size="tiny" shape="round" label="Link out">
-          <ButtonIcon icon={ChevronLeft} />
-        </Button>
-        <Button color="primary" size="large" shape="round" label="Link out">
-          <ButtonIcon icon={ChevronLeft} />
-        </Button>
-        <Button color="primary" size="small" shape="round" label="Link out">
-          <ButtonIcon icon={ChevronLeft} />
-        </Button>
-        <Button color="primary" size="tiny" shape="round" label="Link out">
-          <ButtonIcon icon={ChevronLeft} />
-        </Button>
-      </View>
-
-      <View style={[a.flex_row, a.gap_md, a.align_start]}>
-        <Button color="primary" size="large" shape="square" label="Link out">
-          <ButtonIcon icon={ChevronLeft} />
-        </Button>
-        <Button color="primary" size="small" shape="square" label="Link out">
-          <ButtonIcon icon={ChevronLeft} />
-        </Button>
-        <Button color="primary" size="tiny" shape="square" label="Link out">
-          <ButtonIcon icon={ChevronLeft} />
-        </Button>
-        <Button color="primary" size="large" shape="square" label="Link out">
-          <ButtonIcon icon={ChevronLeft} />
-        </Button>
-        <Button color="primary" size="small" shape="square" label="Link out">
-          <ButtonIcon icon={ChevronLeft} />
-        </Button>
-        <Button color="primary" size="tiny" shape="square" label="Link out">
-          <ButtonIcon icon={ChevronLeft} />
-        </Button>
-      </View>
+      {[
+        'primary',
+        'secondary',
+        'secondary_inverted',
+        'negative',
+        'primary_subtle',
+        'negative_subtle',
+      ].map(color => (
+        <Fragment key={color}>
+          {['tiny', 'small', 'large'].map(size => (
+            <Fragment key={size}>
+              <Text style={[a.font_heavy, a.text_2xl]}>
+                color={color} size={size}
+              </Text>
+              <View style={[a.flex_row, a.align_start, a.gap_md]}>
+                <Button
+                  color={color as ButtonColor}
+                  size={size as ButtonSize}
+                  label="Click here">
+                  <ButtonText>Button</ButtonText>
+                </Button>
+                <Button
+                  disabled
+                  color={color as ButtonColor}
+                  size={size as ButtonSize}
+                  label="Click here">
+                  <ButtonText>Button</ButtonText>
+                </Button>
+                <Button
+                  color={color as ButtonColor}
+                  size={size as ButtonSize}
+                  shape="round"
+                  label="Click here">
+                  <ButtonIcon icon={ChevronLeft} />
+                </Button>
+                <Button
+                  color={color as ButtonColor}
+                  size={size as ButtonSize}
+                  shape="square"
+                  label="Click here">
+                  <ButtonIcon icon={ChevronLeft} />
+                </Button>
+              </View>
+              <View style={[a.flex_row, a.gap_md]}>
+                <Button
+                  color={color as ButtonColor}
+                  size={size as ButtonSize}
+                  label="Click here">
+                  <ButtonIcon icon={Globe} position="left" />
+                  <ButtonText>Button</ButtonText>
+                </Button>
+                <Button
+                  disabled
+                  color={color as ButtonColor}
+                  size={size as ButtonSize}
+                  label="Click here">
+                  <ButtonText>Button</ButtonText>
+                  <ButtonIcon icon={Globe} position="right" />
+                </Button>
+              </View>
+            </Fragment>
+          ))}
+        </Fragment>
+      ))}
     </View>
   )
 }
diff --git a/src/view/screens/Storybook/index.tsx b/src/view/screens/Storybook/index.tsx
index 1151d5a3c..8285b0d73 100644
--- a/src/view/screens/Storybook/index.tsx
+++ b/src/view/screens/Storybook/index.tsx
@@ -87,6 +87,7 @@ function StorybookInner() {
               </Button>
             </View>
 
+            <Buttons />
             <Toasts />
 
             <Button
@@ -109,7 +110,6 @@ function StorybookInner() {
             </ThemeProvider>
 
             <Forms />
-            <Buttons />
             <Typography />
             <Spacing />
             <Shadows />