251 lines
5.7 KiB
TypeScript
251 lines
5.7 KiB
TypeScript
import { define } from '../src'
|
|
import { ExampleSection, theme } from './ssr/helpers'
|
|
|
|
const Input = define('Input', {
|
|
base: 'input',
|
|
|
|
padding: `${theme.spacing.sm}px ${theme.spacing.md}px`,
|
|
fontSize: 14,
|
|
border: `1px solid ${theme.colors.border}`,
|
|
borderRadius: theme.radius.sm,
|
|
background: theme.colors.bgElevated,
|
|
color: theme.colors.fg,
|
|
transition: 'all 0.2s ease',
|
|
width: '100%',
|
|
boxSizing: 'border-box',
|
|
|
|
states: {
|
|
':focus': {
|
|
outline: 'none',
|
|
borderColor: theme.colors.borderActive,
|
|
},
|
|
':disabled': {
|
|
background: theme.colors.bg,
|
|
color: theme.colors.fgDim,
|
|
cursor: 'not-allowed'
|
|
}
|
|
},
|
|
|
|
variants: {
|
|
status: {
|
|
error: {
|
|
borderColor: '#ff0000',
|
|
states: {
|
|
':focus': {
|
|
borderColor: '#ff0000',
|
|
}
|
|
}
|
|
},
|
|
success: {
|
|
borderColor: theme.colors.accent,
|
|
states: {
|
|
':focus': {
|
|
borderColor: theme.colors.accent,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
const Textarea = define('Textarea', {
|
|
base: 'textarea',
|
|
|
|
padding: `${theme.spacing.sm}px ${theme.spacing.md}px`,
|
|
fontSize: 14,
|
|
border: `1px solid ${theme.colors.border}`,
|
|
borderRadius: theme.radius.sm,
|
|
background: theme.colors.bgElevated,
|
|
color: theme.colors.fg,
|
|
transition: 'all 0.2s ease',
|
|
width: '100%',
|
|
minHeight: 120,
|
|
boxSizing: 'border-box',
|
|
fontFamily: 'inherit',
|
|
resize: 'vertical',
|
|
|
|
states: {
|
|
':focus': {
|
|
outline: 'none',
|
|
borderColor: theme.colors.borderActive,
|
|
}
|
|
}
|
|
})
|
|
|
|
const FormGroup = define('FormGroup', {
|
|
marginBottom: theme.spacing.lg,
|
|
|
|
parts: {
|
|
Label: {
|
|
base: 'label',
|
|
display: 'block',
|
|
fontSize: 14,
|
|
fontWeight: 400,
|
|
color: theme.colors.fg,
|
|
marginBottom: theme.spacing.xs
|
|
},
|
|
Helper: {
|
|
fontSize: 12,
|
|
color: theme.colors.fgMuted,
|
|
marginTop: 6
|
|
},
|
|
Error: {
|
|
fontSize: 12,
|
|
color: '#ff0000',
|
|
marginTop: 6
|
|
}
|
|
},
|
|
|
|
render({ props, parts: { Root, Label, Helper, Error } }) {
|
|
return (
|
|
<Root>
|
|
{props.label && <Label>{props.label}</Label>}
|
|
{props.children}
|
|
{props.helper && <Helper>{props.helper}</Helper>}
|
|
{props.error && <Error>{props.error}</Error>}
|
|
</Root>
|
|
)
|
|
}
|
|
})
|
|
|
|
const Checkbox = define('Checkbox', {
|
|
parts: {
|
|
Input: {
|
|
base: 'input[type=checkbox]',
|
|
width: 18,
|
|
height: 18,
|
|
cursor: 'pointer'
|
|
},
|
|
Label: {
|
|
base: 'label',
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
gap: theme.spacing.sm,
|
|
cursor: 'pointer',
|
|
fontSize: 14,
|
|
color: theme.colors.fgMuted,
|
|
|
|
states: {
|
|
':hover': {
|
|
color: theme.colors.fg
|
|
}
|
|
},
|
|
|
|
selectors: {
|
|
'@Input:disabled + &': {
|
|
cursor: 'not-allowed',
|
|
color: theme.colors.fgDim
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
render({ props, parts: { Root, Input, Label } }) {
|
|
return (
|
|
<Root>
|
|
<Label>
|
|
<Input id={props.id} checked={props.checked} disabled={props.disabled} />
|
|
{props.label}
|
|
</Label>
|
|
</Root>
|
|
)
|
|
}
|
|
})
|
|
|
|
const FormExamples = define('FormExamples', {
|
|
maxWidth: 600,
|
|
margin: '0 auto'
|
|
})
|
|
|
|
const Button = define('FormButton', {
|
|
base: 'button',
|
|
|
|
padding: `${theme.spacing.sm}px ${theme.spacing.lg}px`,
|
|
fontSize: 14,
|
|
fontWeight: 400,
|
|
border: `1px solid ${theme.colors.accent}`,
|
|
borderRadius: theme.radius.sm,
|
|
cursor: 'pointer',
|
|
transition: 'all 0.2s ease',
|
|
background: theme.colors.accent,
|
|
color: theme.colors.bg,
|
|
|
|
states: {
|
|
':hover': {
|
|
background: theme.colors.accentDim,
|
|
borderColor: theme.colors.accentDim,
|
|
},
|
|
':active': {
|
|
transform: 'translateY(1px)'
|
|
}
|
|
},
|
|
|
|
variants: {
|
|
variant: {
|
|
secondary: {
|
|
background: theme.colors.bgElevated,
|
|
color: theme.colors.fg,
|
|
border: `1px solid ${theme.colors.border}`,
|
|
states: {
|
|
':hover': {
|
|
borderColor: theme.colors.borderActive,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
const ButtonGroup = define('FormButtonGroup', {
|
|
display: 'flex',
|
|
gap: theme.spacing.sm,
|
|
marginTop: theme.spacing.lg
|
|
})
|
|
|
|
export const FormExamplesContent = () => (
|
|
<FormExamples>
|
|
<ExampleSection title="Text Inputs">
|
|
<FormGroup label="Email" helper="We'll never share your email">
|
|
<Input type="email" placeholder="you@example.com" />
|
|
</FormGroup>
|
|
|
|
<FormGroup label="Password">
|
|
<Input type="password" placeholder="Enter your password" />
|
|
</FormGroup>
|
|
|
|
<FormGroup label="Disabled Input">
|
|
<Input value="This field is disabled" disabled />
|
|
</FormGroup>
|
|
</ExampleSection>
|
|
|
|
<ExampleSection title="Validation States">
|
|
<FormGroup label="Valid Email" helper="Looks good!">
|
|
<Input status="success" type="email" value="user@example.com" />
|
|
</FormGroup>
|
|
|
|
<FormGroup label="Invalid Email" error="Please enter a valid email address">
|
|
<Input status="error" type="email" value="not-an-email" />
|
|
</FormGroup>
|
|
</ExampleSection>
|
|
|
|
<ExampleSection title="Textarea">
|
|
<FormGroup label="Bio" helper="Tell us about yourself">
|
|
<Textarea placeholder="Write something interesting..." />
|
|
</FormGroup>
|
|
</ExampleSection>
|
|
|
|
<ExampleSection title="Checkboxes">
|
|
<FormGroup>
|
|
<Checkbox id="cb1" label="I agree to the terms and conditions" checked />
|
|
<Checkbox id="cb2" label="Subscribe to newsletter" />
|
|
<Checkbox id="cb3" label="This option is disabled" disabled />
|
|
</FormGroup>
|
|
</ExampleSection>
|
|
|
|
<ButtonGroup>
|
|
<Button type="submit">Submit</Button>
|
|
<Button type="reset" variant="secondary">Reset</Button>
|
|
</ButtonGroup>
|
|
</FormExamples>
|
|
)
|