import { formatISO9075, fromUnixTime, getUnixTime } from "date-fns"; import { Component, Show, mergeProps, splitProps, FlowComponent, createSignal, createEffect, For, } 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"; import type { JSX } from "solid-js"; import { createNativeInputValue, createOptionalNumberInputHandler, } from "~/util"; export const TextInput: Component< { label: string; placeholder?: string; labelMinWidth?: string; suffix?: string | JSX.Element; 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} /> ); }; export const NumberInput: Component< { value?: number; onInput: (v: number | undefined) => void } & Omit< Parameters[0], "onInput" > > = (p) => { let el: HTMLInputElement = undefined!; const [props, rest] = splitProps(p, ["value", "onInput"]); const value = createNativeInputValue( () => el, () => props.value ); return ( ); }; // TODO: Move input-group into separate component export const Select: Component< { value: string | number; options: [string | number, string][]; label: string; labelMinWidth?: string; onChange: (v: any) => void; } & JSX.InputHTMLAttributes > = (p) => { p = mergeProps( { labelMinWidth: "95px", }, p ); const [props, rest] = splitProps(p, [ "value", "options", "label", "labelMinWidth", "onChange", ]); return (
); };