You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

79 lines
2.0 KiB
TypeScript

import { h } from "preact";
import { FieldKind, Field as FieldModel } from "../../../../common/schema.ts";
import { ValidationErrors } from "../../../../common/validation.ts";
import { Callback, Dispatch } from "../../../utils.ts";
import { Action, deleteField, setFieldOption, setFieldProp } from "../state.ts";
import { Validated } from "../../lib/input/Validated.ts";
import { TextInput } from "../../lib/input/TextInput.ts";
import { Select } from "../../lib/input/Select.ts";
import { Labeled } from "../../lib/Labeled.ts";
import { FieldOptions, SetFieldOption } from "./FieldOptions.ts";
const Field = (p: {
field: FieldModel;
errors?: ValidationErrors<FieldModel>;
setName: Callback<[string]>;
setKind: Callback<[FieldKind]>;
setFieldOption: SetFieldOption;
delete: Callback<[]>;
}) => {
const nameInput = h(
Validated,
{ errors: p.errors?.name },
h(TextInput, {
value: p.field.name,
placeholder: "Field name",
onInput: p.setName,
}),
);
const kindSelect = h(
Labeled,
{ label: "Kind" },
h(Select<FieldKind>, {
options: { string: "string", number: "number" },
value: p.field.kind,
onChange: p.setKind,
}),
);
const options = h(FieldOptions, {
kind: p.field.kind,
options: p.field.options,
errors: p.errors?.options,
setFieldOption: p.setFieldOption,
});
const deleteBtn = h("button", { onClick: p.delete }, "Delete");
return h(
"div",
{ class: "field" },
nameInput,
kindSelect,
options,
deleteBtn,
);
};
export const Fields = (p: {
fields: FieldModel[];
errors?: ValidationErrors<FieldModel[]>;
dispatch: Dispatch<Action>;
}) => {
const fields = p.fields.map((f, i) => {
const errors = p.errors?.[i];
return h(Field, {
field: f,
errors,
setName: (s) => p.dispatch(setFieldProp(i, "name", s)),
setKind: (s) => p.dispatch(setFieldProp(i, "kind", s)),
setFieldOption: (pr, v) => p.dispatch(setFieldOption(i, pr, v)),
delete: () => p.dispatch(deleteField(i)),
});
});
return h("div", { class: "fields" }, ...fields);
};