Skip to content

Instantly share code, notes, and snippets.

@harrisrobin
Last active February 6, 2024 08:03
Show Gist options
  • Save harrisrobin/38dbaa5da2568138ddb2ac2bc2e62ddd to your computer and use it in GitHub Desktop.
Save harrisrobin/38dbaa5da2568138ddb2ac2bc2e62ddd to your computer and use it in GitHub Desktop.
Dripsy vs useColorToken
import React from "react"
import {
PressableStateCallbackType,
Pressable,
StyleProp,
ViewStyle,
} from "react-native"
import { ButtonProps, ButtonVariants } from "./button.props"
import { Text } from "../text"
import { useDripsyTheme, useSx } from "dripsy"
const Button = (props: ButtonProps) => {
const {
variant = "solid",
tx,
text,
txOptions,
pressedStyle: pressedStyleOverride,
children,
RightAccessory,
LeftAccessory,
onPress,
sx: sxOverride = {},
...rest
} = props
const sx = useSx()
const { theme } = useDripsyTheme()
const VIEW_PRESETS: Record<ButtonVariants, StyleProp<ViewStyle>> = {
solid: sx({
backgroundColor: "$green9",
}),
soft: sx({
backgroundColor: "$green3",
}),
surface: sx({
backgroundColor: "$green3",
borderWidth: 1,
borderColor: "$green7",
}),
outline: sx({
backgroundColor: "transparent",
borderWidth: 1,
borderColor: "$green7",
}),
ghost: sx({
backgroundColor: "transparent",
borderWidth: 0,
}),
}
const PRESSED_VIEW_PRESETS: Record<ButtonVariants, StyleProp<ViewStyle>> = {
solid: sx({
backgroundColor: "$green4",
}),
soft: sx({
backgroundColor: "$green4",
}),
surface: sx({
backgroundColor: "$green4",
borderColor: "$green8",
}),
outline: sx({
backgroundColor: "$green4",
borderColor: "$green8",
}),
ghost: {
backgroundColor: "$green4",
borderWidth: 0,
},
}
function baseStyle({ pressed }: PressableStateCallbackType) {
let style: StyleProp<ViewStyle>[] = [
sx({
minHeight: 56,
borderRadius: "$4",
justifyContent: "center",
alignItems: "center",
flexDirection: "row",
paddingVertical: "$4",
paddingHorizontal: "$7",
overflow: "hidden",
}),
VIEW_PRESETS[variant],
sx(sxOverride) as ViewStyle,
]
if (pressed) {
style = [...style, PRESSED_VIEW_PRESETS[variant], pressedStyleOverride]
}
return style
}
const colorTokenForVariant = {
solid: "$slate1",
soft: "$green11",
outline: "$green11",
surface: "$green11",
ghost: "$green11",
}
const textColorToken = colorTokenForVariant[variant]
const RIGHT_ACCESSORY_STYLE = sx({
marginRight: "$2",
zIndex: 1,
color: textColorToken,
})
const LEFT_ACCESSORY_STYLE = sx({
marginEnd: "$2",
zIndex: 1,
color: textColorToken,
})
return (
<Pressable
onPress={onPress}
style={baseStyle}
accessibilityRole="button"
{...rest}>
{(state: PressableStateCallbackType) => (
<>
{!!LeftAccessory && (
<LeftAccessory
pressableState={state}
style={[LEFT_ACCESSORY_STYLE]}
/>
)}
<Text
tx={tx}
text={text}
txOptions={txOptions}
sx={{
color: textColorToken,
fontWeight: "$medium",
}}>
{children}
</Text>
{!!RightAccessory && (
<RightAccessory
pressableState={state}
style={[RIGHT_ACCESSORY_STYLE]}
/>
)}
</>
)}
</Pressable>
)
}
export { Button }
import React from "react"
import {
PressableStateCallbackType,
Pressable,
StyleProp,
ViewStyle,
} from "react-native"
import { ButtonProps, ButtonVariants } from "./button.props"
import { Text } from "../text"
import { useToken } from "../hooks"
const Button = (props: ButtonProps) => {
const {
variant = "solid",
tx,
text,
txOptions,
style: styleOverride,
pressedStyle: pressedStyleOverride,
children,
RightAccessory,
LeftAccessory,
onPress,
...rest
} = props
const baseStyleRadius = useToken("radii", "4")
const baseStylePaddingVertical = useToken("space", "4")
const baseStylePaddingHorizontal = useToken("space", "7")
const BASE_PRESSABLE_STYLE: ViewStyle = {
minHeight: 56,
borderRadius: baseStyleRadius,
justifyContent: "center",
alignItems: "center",
flexDirection: "row",
paddingVertical: baseStylePaddingVertical,
paddingHorizontal: baseStylePaddingHorizontal,
overflow: "hidden",
}
const VIEW_PRESETS: Record<ButtonVariants, StyleProp<ViewStyle>> = {
solid: {
backgroundColor: useToken("colors", "green9"),
},
soft: {
backgroundColor: useToken("colors", "green3"),
},
surface: {
backgroundColor: useToken("colors", "green3"),
borderWidth: 1,
borderColor: useToken("colors", "green7"),
},
outline: {
backgroundColor: "transparent",
borderWidth: 1,
borderColor: useToken("colors", "green7"),
},
ghost: {
backgroundColor: "transparent",
borderWidth: 0,
},
}
const PRESSED_VIEW_PRESETS: Record<ButtonVariants, StyleProp<ViewStyle>> = {
solid: {
backgroundColor: useToken("colors", "green4"),
},
soft: {
backgroundColor: useToken("colors", "green4"),
},
surface: {
backgroundColor: useToken("colors", "green4"),
borderColor: useToken("colors", "green8"),
},
outline: {
backgroundColor: useToken("colors", "green4"),
borderColor: useToken("colors", "green8"),
},
ghost: {
backgroundColor: useToken("colors", "green4"),
borderWidth: 0,
},
}
function baseStyle({ pressed }: PressableStateCallbackType) {
let style: StyleProp<ViewStyle>[] = [
BASE_PRESSABLE_STYLE,
VIEW_PRESETS[variant],
styleOverride as ViewStyle,
]
if (pressed) {
style = [...style, PRESSED_VIEW_PRESETS[variant], pressedStyleOverride]
}
return style
}
const colorTokenForVariant = {
solid: "slate1",
soft: "green11",
outline: "green11",
surface: "green11",
ghost: "green11",
}
const RIGHT_ACCESSORY_STYLE: ViewStyle = {
marginStart: useToken("space", "2"),
zIndex: 1,
}
const LEFT_ACCESSORY_STYLE: ViewStyle = {
marginEnd: useToken("space", "2"),
zIndex: 1,
}
const textColor = useToken("colors", colorTokenForVariant[variant])
return (
<Pressable
onPress={onPress}
style={baseStyle}
accessibilityRole="button"
{...rest}>
{(state: PressableStateCallbackType) => (
<>
{!!LeftAccessory && (
<LeftAccessory
textColor={textColor}
pressableState={state}
style={[LEFT_ACCESSORY_STYLE]}
/>
)}
<Text
tx={tx}
text={text}
txOptions={txOptions}
color={`${textColor}`}
fontWeight="$medium">
{children}
</Text>
{!!RightAccessory && (
<RightAccessory
textColor={textColor}
pressableState={state}
style={[RIGHT_ACCESSORY_STYLE]}
/>
)}
</>
)}
</Pressable>
)
}
export { Button }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment