import { h as create, Fragment, VNode } from "preact"; import { Caption } from "./Caption.js"; import { FormProvider } from "./FormProvider.js"; import { Group } from "./Group.js"; import { InputAbsoluteTime } from "./InputAbsoluteTime.js"; import { InputAmount } from "./InputAmount.js"; import { InputArray } from "./InputArray.js"; import { InputChoiceHorizontal } from "./InputChoiceHorizontal.js"; import { InputChoiceStacked } from "./InputChoiceStacked.js"; import { InputFile } from "./InputFile.js"; import { InputInteger } from "./InputInteger.js"; import { InputLine } from "./InputLine.js"; import { InputSelectMultiple } from "./InputSelectMultiple.js"; import { InputSelectOne } from "./InputSelectOne.js"; import { InputText } from "./InputText.js"; import { InputTextArea } from "./InputTextArea.js"; import { InputToggle } from "./InputToggle.js"; /** * Constrain the type with the ui props */ type FieldType = { group: Parameters[0]; caption: Parameters[0]; array: Parameters>[0]; file: Parameters>[0]; selectOne: Parameters>[0]; selectMultiple: Parameters>[0]; text: Parameters>[0]; textArea: Parameters>[0]; choiceStacked: Parameters>[0]; choiceHorizontal: Parameters>[0]; absoluteTime: Parameters>[0]; integer: Parameters>[0]; toggle: Parameters>[0]; amount: Parameters>[0]; }; /** * List all the form fields so typescript can type-check the form instance */ export type UIFormField = | { type: "group"; props: FieldType["group"] } | { type: "caption"; props: FieldType["caption"] } | { type: "array"; props: FieldType["array"] } | { type: "file"; props: FieldType["file"] } | { type: "amount"; props: FieldType["amount"] } | { type: "selectOne"; props: FieldType["selectOne"] } | { type: "selectMultiple"; props: FieldType["selectMultiple"] } | { type: "text"; props: FieldType["text"] } | { type: "textArea"; props: FieldType["textArea"] } | { type: "choiceStacked"; props: FieldType["choiceStacked"] } | { type: "choiceHorizontal"; props: FieldType["choiceHorizontal"] } | { type: "integer"; props: FieldType["integer"] } | { type: "toggle"; props: FieldType["toggle"] } | { type: "absoluteTime"; props: FieldType["absoluteTime"] }; type FieldComponentFunction = ( props: FieldType[key], ) => VNode; type UIFormFieldMap = { [key in keyof FieldType]: FieldComponentFunction; }; /** * Maps input type with component implementation */ const UIFormConfiguration: UIFormFieldMap = { group: Group, caption: Caption, //@ts-ignore array: InputArray, text: InputText, //@ts-ignore file: InputFile, textArea: InputTextArea, //@ts-ignore absoluteTime: InputAbsoluteTime, //@ts-ignore choiceStacked: InputChoiceStacked, //@ts-ignore choiceHorizontal: InputChoiceHorizontal, integer: InputInteger, //@ts-ignore selectOne: InputSelectOne, //@ts-ignore selectMultiple: InputSelectMultiple, //@ts-ignore toggle: InputToggle, //@ts-ignore amount: InputAmount, }; export function RenderAllFieldsByUiConfig({ fields, }: { fields: UIFormField[]; }): VNode { return create( Fragment, {}, fields.map((field, i) => { const Component = UIFormConfiguration[ field.type ] as FieldComponentFunction; return Component(field.props); }), ); } type FormSet = { Provider: typeof FormProvider; InputLine: () => typeof InputLine; InputChoiceHorizontal: () => typeof InputChoiceHorizontal; }; /** * Helper function that created a typed object. * * @returns */ export function createNewForm() { const res: FormSet = { Provider: FormProvider, InputLine: () => InputLine, InputChoiceHorizontal: () => InputChoiceHorizontal, }; return { Provider: res.Provider, InputLine: res.InputLine(), InputChoiceHorizontal: res.InputChoiceHorizontal(), }; }