Files
gui/apps/kitchen-sink/tests/BuildAButton.test.tsx
zeekayandHanzo Dev bfe539744a Type the tab wrappers and variant spreads as the packages declare them
React passes ref as a prop, and a forwardRef over props with an index
signature drops every named prop through Omit; the font extras are
optional in a spread function's config.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-04 21:34:25 -07:00

88 lines
1.9 KiB
TypeScript

import { getSize, getSpace } from '@hanzogui/get-token'
import type { SizeTokens } from '@hanzogui/web'
import {
GetProps,
View,
Text,
createStyledContext,
styled,
useTheme,
withStaticProperties,
} from '@hanzogui/web'
import { cloneElement, useContext } from 'react'
export const ButtonContext = createStyledContext({
size: '$md' as SizeTokens,
})
export const ButtonFrame = styled(View, {
name: 'Button',
context: ButtonContext,
backgroundColor: '$background',
alignItems: 'center',
flexDirection: 'row',
hoverStyle: {
backgroundColor: '$backgroundHover',
},
pressStyle: {
backgroundColor: '$backgroundPress',
},
variants: {
size: {
'...size': (name, { tokens }) => {
return {
height: tokens.size[name],
borderRadius: tokens.radius[name],
// note the getSpace and getSize helpers will let you shift down/up token sizes
// whereas with gap we just multiply by 0.2
// this is a stylistic choice, and depends on your design system values
gap: tokens.space[name].val * 0.2,
paddingHorizontal: getSpace(name, {
shift: -1,
}),
}
},
},
} as const,
defaultVariants: {
size: '$true',
},
})
export const ButtonText = styled(Text, {
name: 'ButtonText',
context: ButtonContext,
color: '$color',
userSelect: 'none',
variants: {
size: {
'...fontSize': (name, extras) => ({
fontSize: extras.font?.size[name],
}),
},
} as const,
})
const ButtonIcon = (props: { children: any }) => {
const { size } = useContext(ButtonContext.context)
const smaller = getSize(size, {
shift: -2,
})
const theme = useTheme()
return cloneElement(props.children, {
size: smaller.val * 0.5,
color: theme.color?.get(),
})
}
export const Button = withStaticProperties(ButtonFrame, {
Props: ButtonContext.Provider,
Text: ButtonText,
Icon: ButtonIcon,
})