import { IconLibraryPlus, IconTrash } from "@tabler/icons-react"; import type { JsonSchema } from "json-schema-library"; import { memo, useMemo } from "react"; import { Button } from "ui/components/buttons/Button"; import { IconButton } from "ui/components/buttons/IconButton"; import { Dropdown } from "ui/components/overlay/Dropdown"; import { useEvent } from "ui/hooks/use-event"; import { FieldComponent } from "./Field"; import { FieldWrapper } from "./FieldWrapper"; import { useDerivedFieldContext, useFormValue } from "./Form"; import { coerce, getMultiSchema, getMultiSchemaMatched, isEqual, suffixPath } from "./utils"; export const ArrayField = ({ path = "" }: { path?: string }) => { const { setValue, pointer, required, schema, ...ctx } = useDerivedFieldContext(path); if (!schema || typeof schema === "undefined") return `ArrayField(${path}): no schema ${pointer}`; // if unique items with enum if (schema.uniqueItems && typeof schema.items === "object" && "enum" in schema.items) { return ( { // @ts-ignore const selected = Array.from(e.target.selectedOptions).map((o) => o.value); setValue(ctx.path, selected); }} /> ); } return ( {({ value }) => value?.map((v, index: number) => ( )) }
); }; const ArrayItem = memo(({ path, index, schema }: any) => { const { value, ...ctx } = useDerivedFieldContext(path, (ctx) => { return ctx.value?.[index]; }); const itemPath = suffixPath(path, index); let subschema = schema.items; const itemsMultiSchema = getMultiSchema(schema.items); if (itemsMultiSchema) { const [, , _subschema] = getMultiSchemaMatched(schema.items, value); subschema = _subschema; } const handleUpdate = useEvent((pointer: string, value: any) => { ctx.setValue(pointer, value); }); const handleDelete = useEvent((pointer: string) => { ctx.deleteValue(pointer); }); const DeleteButton = useMemo( () => handleDelete(itemPath)} size="sm" />, [itemPath], ); return (
{ handleUpdate(itemPath, coerce(e.target.value, subschema!)); }} className="w-full" /> {DeleteButton}
); }, isEqual); const ArrayIterator = memo( ({ name, children }: any) => { return children(useFormValue(name)); }, (prev, next) => prev.value?.length === next.value?.length, ); const ArrayAdd = ({ schema, path }: { schema: JsonSchema; path: string }) => { const { setValue, value: { currentIndex }, ...ctx } = useDerivedFieldContext(path, (ctx) => { return { currentIndex: ctx.value?.length ?? 0 }; }); const itemsMultiSchema = getMultiSchema(schema.items); function handleAdd(template?: any) { const newPath = suffixPath(path, currentIndex); setValue(newPath, template ?? ctx.lib.getTemplate(undefined, schema!.items)); } if (itemsMultiSchema) { return ( ({ label: s!.title ?? `Option ${i + 1}`, onClick: () => handleAdd(ctx.lib.getTemplate(undefined, s!)), }))} onClickItem={console.log} > ); } return ; };