omnivore/packages/web/components/elements/FormElements.tsx

118 lines
2.9 KiB
TypeScript
Raw Normal View History

2022-02-11 17:24:33 +00:00
import { styled } from '../tokens/stitches.config'
2022-06-03 08:23:05 +00:00
import { useState } from 'react'
import Checkbox from './Checkbox'
2022-06-14 16:59:58 +00:00
import { HStack, VStack } from './LayoutPrimitives'
import { Label } from '@radix-ui/react-dropdown-menu'
2022-06-03 08:23:05 +00:00
export interface FormInputProps {
name: string
label: string
value?: any
onChange?: (value: any) => void
type?: string
placeholder?: string
disabled?: boolean
hidden?: boolean
required?: boolean
css?: any
2022-06-03 08:51:16 +00:00
options?: string[]
2022-06-06 05:10:46 +00:00
min?: any
2022-06-03 08:23:05 +00:00
}
2022-02-11 17:24:33 +00:00
export const FormInput = styled('input', {
border: 'none',
width: '100%',
bg: 'transparent',
fontSize: '16px',
fontFamily: 'inter',
fontWeight: 'normal',
lineHeight: '1.35',
color: '$grayTextContrast',
'&:focus': {
outline: 'none',
},
})
export const BorderedFormInput = styled(FormInput, {
borderRadius: '6px',
border: `1px solid $grayBorder`,
p: '$3',
})
2022-06-03 08:23:05 +00:00
export function GeneralFormInput(props: FormInputProps): JSX.Element {
const [input, setInput] = useState<FormInputProps>(props)
if (props.type === 'checkbox') {
2022-06-14 16:59:58 +00:00
const StyledLabel = styled(Label, {
color: '$grayTextContrast',
fontSize: 13,
padding: '5px 10px',
cursor: 'default',
})
2022-06-03 08:23:05 +00:00
return (
2022-06-03 08:41:26 +00:00
<VStack>
2022-06-03 08:51:16 +00:00
{input.options?.map((label, index) => (
2022-06-14 16:59:58 +00:00
<HStack key={index} alignment='center'>
<Checkbox
key={index}
checked={input.value[index]}
setChecked={(arg) => {
input.value[index] = arg
setInput(input)
props.onChange &&
props.onChange(
input.options?.filter((_, i) => input.value[i])
)
}}
></Checkbox>
<StyledLabel>{label}</StyledLabel>
2022-06-03 08:41:26 +00:00
</HStack>
2022-06-03 08:23:05 +00:00
))}
2022-06-03 08:41:26 +00:00
</VStack>
2022-06-03 08:23:05 +00:00
)
} else if (props.type === 'select') {
return (
<select onChange={input.onChange}>
{input.options?.map((label, index) => (
<option key={index} value={label}>{label}</option>
))}
</select>
)
2022-06-03 08:23:05 +00:00
} else {
return (
<FormInput
key={input.name}
type={input.type || 'text'}
value={input.value}
placeholder={input.placeholder}
onChange={(event) => {
if (input.onChange) {
2022-06-03 08:51:16 +00:00
setInput({ ...input, value: event.target.value })
2022-06-03 08:23:05 +00:00
input.onChange(event.target.value)
}
}}
disabled={input.disabled}
hidden={input.hidden}
required={input.required}
css={{
border: '1px solid $grayBorder',
borderRadius: '8px',
width: '100%',
bg: 'transparent',
fontSize: '16px',
textIndent: '8px',
marginBottom: '2px',
color: '$grayTextContrast',
'&:focus': {
outline: 'none',
boxShadow: '0px 0px 2px 2px rgba(255, 234, 159, 0.56)',
},
}}
name={input.name}
2022-06-06 05:10:46 +00:00
min={input.min}
2022-06-03 08:23:05 +00:00
/>
)
}
}