diff --git a/src/components/Form.tsx b/src/components/Form.tsx new file mode 100644 index 0000000..5f481e5 --- /dev/null +++ b/src/components/Form.tsx @@ -0,0 +1,217 @@ +import { formatISO9075, fromUnixTime, getUnixTime } from "date-fns"; +import { + Component, + JSX, + Show, + mergeProps, + splitProps, + FlowComponent, + createSignal, + createEffect, +} from "solid-js"; +import { validateInput } from "~/hooks/validation"; +import AsteriskIcon from "~icons/ph/asterisk-bold"; +import MaximizeIcon from "~icons/carbon/maximize"; +import MinimizeIcon from "~icons/carbon/minimize"; +import autosize from "autosize"; + +export const TextInput: Component< + { + label: string; + placeholder?: string; + labelMinWidth?: string; + suffix?: string; + size?: string; + vertical?: boolean; + } & JSX.InputHTMLAttributes +> = (p) => { + p = mergeProps( + { + placeholder: p.label, + labelMinWidth: "95px", + size: "sm", + vertical: false, + }, + p + ); + const [props, rest] = splitProps(p, [ + "name", + "size", + "class", + "label", + "placeholder", + "suffix", + "vertical", + "labelMinWidth", + ]); + const sizes: Record = { + xs: "input-xs", + sm: "input-sm", + lg: "input-lg", + }; + + const [validate, vState] = validateInput({ value: () => rest.value }); + + return ( +
+ +
+ ); +}; + +export const Checkbox: FlowComponent< + JSX.InputHTMLAttributes +> = (p) => { + const [props, rest] = splitProps(p, ["children"]); + + return ( +
+ +
+ ); +}; + +export const TextArea: Component< + { + label: string; + labelSuffixJsx?: JSX.Element; + value?: string; + placeholder?: string; + } & JSX.TextareaHTMLAttributes +> = (p) => { + p = mergeProps({ rows: 3, placeholder: p.label }, p); + const [props, rest] = splitProps(p, ["label", "labelSuffixJsx", "value"]); + const [autosizeEnabled, setAutosize] = createSignal(false); + let textareaEl: HTMLTextAreaElement = undefined!; + createEffect(function () { + if (autosizeEnabled()) { + autosize(textareaEl); + } else { + autosize.destroy(textareaEl); + } + }); + + return ( +
+ + +
+ ); +}; + +export const UnixDateInput: Component< + { + required?: boolean; + label: string; + value?: number; + onInput: (v: number) => void; + } & Parameters[0] +> = (p) => { + const [props, rest] = splitProps(p, [ + "required", + "label", + "value", + "onInput", + ]); + return ( + { + if (!evt.currentTarget.valueAsDate) { + return; + } + + if (evt.currentTarget.valueAsDate.getFullYear() > 9999) { + return; + } + + props.onInput(getUnixTime(evt.currentTarget.valueAsDate)); + }} + {...rest} + /> + ); +};