/ |/ \ / \ / \ / | $$$$$$$$//$$$$$$ |$$$$$$$ |/$$$$$$ |$$$$$$$$/ $$ |__ $$ | $$ |$$ |__$$ |$$ | _$$/ $$ |__ $$ | $$ | $$ |$$ $$< $$ |/ |$$ | $$$$$/ $$ | $$ |$$$$$$$ |$$ |$$$$ |$$$$$/ $$ | $$ \__$$ |$$ | $$ |$$ \__$$ |$$ |_____ $$ | $$ $$/ $$ | $$ |$$ $$/ $$ | $$/ $$$$$$/ $$/ $$/ $$$$$$/ $$$$$$$$/
167 lines
4.2 KiB
TypeScript
167 lines
4.2 KiB
TypeScript
import { define } from 'forge'
|
|
import { theme } from './theme'
|
|
import { VStack, HStack } from './stack'
|
|
import { Section } from './section'
|
|
import { H2 } from './text'
|
|
|
|
export const Button = define('Button', {
|
|
base: 'button',
|
|
|
|
display: 'inline-flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
fontWeight: 500,
|
|
transition: 'all 0.2s',
|
|
cursor: 'pointer',
|
|
borderRadius: theme('radius-sm'),
|
|
border: '1px solid transparent',
|
|
outline: 'none',
|
|
|
|
// Default: primary + md
|
|
background: theme('colors-primary'),
|
|
color: theme('colors-bg'),
|
|
height: 40,
|
|
padding: `0 ${theme('spacing-4')}`,
|
|
fontSize: theme('fontSize-sm'),
|
|
|
|
states: {
|
|
':not(:disabled):hover': {
|
|
background: theme('colors-primaryHover'),
|
|
},
|
|
':disabled': {
|
|
opacity: 0.5,
|
|
cursor: 'not-allowed',
|
|
},
|
|
},
|
|
|
|
variants: {
|
|
variant: {
|
|
primary: {
|
|
background: theme('colors-primary'),
|
|
color: theme('colors-bg'),
|
|
states: {
|
|
':not(:disabled):hover': {
|
|
background: theme('colors-primaryHover'),
|
|
},
|
|
},
|
|
},
|
|
secondary: {
|
|
background: theme('colors-secondary'),
|
|
color: theme('colors-bg'),
|
|
states: {
|
|
':not(:disabled):hover': {
|
|
background: theme('colors-secondaryHover'),
|
|
},
|
|
},
|
|
},
|
|
outline: {
|
|
background: 'transparent',
|
|
color: theme('colors-fg'),
|
|
borderColor: theme('colors-border'),
|
|
states: {
|
|
':not(:disabled):hover': {
|
|
borderColor: theme('colors-borderActive'),
|
|
},
|
|
},
|
|
},
|
|
ghost: {
|
|
background: 'transparent',
|
|
color: theme('colors-fg'),
|
|
border: 'none',
|
|
states: {
|
|
':not(:disabled):hover': {
|
|
background: theme('colors-bgMuted'),
|
|
},
|
|
},
|
|
},
|
|
destructive: {
|
|
background: theme('colors-destructive'),
|
|
color: theme('colors-bg'),
|
|
states: {
|
|
':not(:disabled):hover': {
|
|
background: theme('colors-destructiveHover'),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
size: {
|
|
sm: {
|
|
height: 32,
|
|
padding: `0 ${theme('spacing-3')}`,
|
|
fontSize: theme('fontSize-sm'),
|
|
},
|
|
md: {
|
|
height: 40,
|
|
padding: `0 ${theme('spacing-4')}`,
|
|
fontSize: theme('fontSize-sm'),
|
|
},
|
|
lg: {
|
|
height: 48,
|
|
padding: `0 ${theme('spacing-6')}`,
|
|
fontSize: theme('fontSize-base'),
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
export type ButtonProps = Parameters<typeof Button>[0]
|
|
|
|
export const Test = () => {
|
|
return (
|
|
<Section>
|
|
{/* Variants */}
|
|
<VStack gap={4}>
|
|
<H2>Button Variants</H2>
|
|
<HStack gap={4}>
|
|
<Button variant="primary">Primary</Button>
|
|
<Button variant="secondary">Secondary</Button>
|
|
<Button variant="outline">Outline</Button>
|
|
<Button variant="ghost">Ghost</Button>
|
|
<Button variant="destructive">Destructive</Button>
|
|
</HStack>
|
|
</VStack>
|
|
|
|
{/* Sizes */}
|
|
<VStack gap={4}>
|
|
<H2>Button Sizes</H2>
|
|
<HStack gap={4} v="end">
|
|
<Button size="sm">Small</Button>
|
|
<Button size="md">Medium</Button>
|
|
<Button size="lg">Large</Button>
|
|
</HStack>
|
|
</VStack>
|
|
|
|
{/* With custom content */}
|
|
<VStack gap={4}>
|
|
<H2>Custom Content</H2>
|
|
<HStack gap={4}>
|
|
<Button variant="primary">
|
|
<span>🚀</span>
|
|
<span style={{ marginLeft: '8px' }}>Launch</span>
|
|
</Button>
|
|
<Button variant="outline" style={{ flexDirection: 'column', height: '80px', width: '96px' }}>
|
|
<span style={{ fontSize: '24px' }}>💳</span>
|
|
<span style={{ fontSize: '12px', marginTop: '4px' }}>Card</span>
|
|
</Button>
|
|
</HStack>
|
|
</VStack>
|
|
|
|
{/* Native attributes work */}
|
|
<VStack gap={4}>
|
|
<H2>Native Attributes</H2>
|
|
<HStack gap={4}>
|
|
<Button onClick={() => alert('Clicked!')} variant="primary">
|
|
Click Me
|
|
</Button>
|
|
<Button disabled variant="secondary">
|
|
Disabled
|
|
</Button>
|
|
<Button type="submit" variant="outline">
|
|
Submit
|
|
</Button>
|
|
</HStack>
|
|
</VStack>
|
|
</Section>
|
|
)
|
|
}
|