diff options
Diffstat (limited to 'packages/web-util/src/forms/InputAbsoluteTime.tsx')
-rw-r--r-- | packages/web-util/src/forms/InputAbsoluteTime.tsx | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/packages/web-util/src/forms/InputAbsoluteTime.tsx b/packages/web-util/src/forms/InputAbsoluteTime.tsx new file mode 100644 index 000000000..f5fd4fc50 --- /dev/null +++ b/packages/web-util/src/forms/InputAbsoluteTime.tsx @@ -0,0 +1,94 @@ +import { AbsoluteTime } from "@gnu-taler/taler-util"; +import { format, parse } from "date-fns"; +import { Fragment, VNode, h } from "preact"; +import { useState } from "preact/hooks"; +import { Calendar } from "./Calendar.js"; +import { Dialog } from "./Dialog.js"; +import { UIFormProps } from "./FormProvider.js"; +import { InputLine } from "./InputLine.js"; +import { useField } from "./useField.js"; +import { noHandlerPropsAndNoContextForField } from "./InputArray.js"; + +export function InputAbsoluteTime<T extends object, K extends keyof T>( + properties: { pattern?: string } & UIFormProps<T, K>, +): VNode { + const pattern = properties.pattern ?? "dd/MM/yyyy"; + const [open, setOpen] = useState(false); + + //FIXME: remove deprecated + const fieldCtx = useField<T, K>(properties.name); + const { value, onChange } = + properties.handler ?? fieldCtx ?? noHandlerPropsAndNoContextForField(properties.name); + return ( + <Fragment> + <InputLine<T, K> + type="text" + after={{ + type: "button", + onClick: () => { + setOpen(true); + }, + // icon: <CalendarIcon class="h-6 w-6" />, + children: ( + <svg + xmlns="http://www.w3.org/2000/svg" + fill="none" + viewBox="0 0 24 24" + stroke-width="1.5" + stroke="currentColor" + class="w-6 h-6" + > + <path + stroke-linecap="round" + stroke-linejoin="round" + d="M6.75 3v2.25M17.25 3v2.25M3 18.75V7.5a2.25 2.25 0 012.25-2.25h13.5A2.25 2.25 0 0121 7.5v11.25m-18 0A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75m-18 0v-7.5A2.25 2.25 0 015.25 9h13.5A2.25 2.25 0 0121 11.25v7.5" + /> + </svg> + ), + }} + converter={{ + //@ts-ignore + fromStringUI: (v): AbsoluteTime | undefined => { + if (!v) return undefined; + try { + const t_ms = parse(v, pattern, Date.now()).getTime(); + return AbsoluteTime.fromMilliseconds(t_ms); + } catch (e) { + return undefined; + } + }, + //@ts-ignore + toStringUI: (v: AbsoluteTime | undefined) => { + return !v || !v.t_ms + ? undefined + : v.t_ms === "never" + ? "never" + : format(v.t_ms, pattern); + }, + }} + {...properties} + /> + {open && ( + <Dialog onClose={() => setOpen(false)}> + <Calendar + value={(value as AbsoluteTime) ?? AbsoluteTime.now()} + onChange={(v) => { + onChange(v as any); + setOpen(false); + }} + /> + </Dialog> + )} + {/* {open && + <Dialog onClose={() => setOpen(false)} > + <TimePicker value={value as AbsoluteTime ?? AbsoluteTime.now()} + onChange={(v) => { + onChange(v as any) + }} + onConfirm={() => { + setOpen(false) + }} /> + </Dialog>} */} + </Fragment> + ); +} |