shelving
Version:
Toolkit for using data in JavaScript.
103 lines (102 loc) • 5.57 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import { UnexpectedError } from "../../error/UnexpectedError.js";
import { ArraySchema } from "../../schema/ArraySchema.js";
import { BooleanSchema } from "../../schema/BooleanSchema.js";
import { ChoiceSchema } from "../../schema/ChoiceSchema.js";
import { DataSchema } from "../../schema/DataSchema.js";
import { DateSchema } from "../../schema/DateSchema.js";
import { DictionarySchema } from "../../schema/DictionarySchema.js";
import { NullableSchema } from "../../schema/NullableSchema.js";
import { NumberSchema } from "../../schema/NumberSchema.js";
import { OptionalSchema } from "../../schema/OptionalSchema.js";
import { StringSchema } from "../../schema/StringSchema.js";
import { isArray } from "../../util/array.js";
import { isData } from "../../util/data.js";
import { isDictionary } from "../../util/dictionary.js";
import { getNumber } from "../../util/number.js";
import { getKeys } from "../../util/object.js";
import { getSource, requireSource } from "../../util/source.js";
import { getString } from "../../util/string.js";
import { ArrayInput } from "./ArrayInput.js";
import { CheckboxInput } from "./CheckboxInput.js";
import { ChoiceRadioInputs } from "./ChoiceRadioInputs.js";
import { DataInput } from "./DataInput.js";
import { DateInput } from "./DateInput.js";
import { DictionaryInput } from "./DictionaryInput.js";
import { Field } from "./Field.js";
import { NumberInput } from "./NumberInput.js";
import { SelectInput } from "./SelectInput.js";
import { TextInput } from "./TextInput.js";
/** A schema is required if it's not wrapped in an `OptionalSchema` or `NullableSchema` */
export function isSchemaRequired(schema) {
return !(schema instanceof OptionalSchema || schema instanceof NullableSchema);
}
export function SchemaInput({ name, schema,
/**
* Required defaults to whether the schema is required
* - A schema is required if it's not wrapped in an `OptionalSchema` or `NullableSchema`
* - Can be overridden by explicitly settings `<SchemaInput required>`
*/
required = isSchemaRequired(schema), ...props }) {
const date = getSource(DateSchema, schema);
if (date)
return _jsx(DateSchemaInput, { name: name, schema: date, required: required, ...props });
const number = getSource(NumberSchema, schema);
if (number)
return _jsx(NumberSchemaInput, { name: name, schema: number, required: required, ...props });
const choice = getSource(ChoiceSchema, schema);
if (choice)
return _jsx(ChoiceSchemaInput, { name: name, schema: choice, required: required, ...props });
const boolean = getSource(BooleanSchema, schema);
if (boolean)
return _jsx(BooleanSchemaInput, { name: name, schema: boolean, required: required, ...props });
const string = getSource(StringSchema, schema);
if (string)
return _jsx(StringSchemaInput, { name: name, schema: string, required: required, ...props });
const array = getSource(ArraySchema, schema);
if (array)
return _jsx(ArraySchemaInput, { name: name, schema: array, required: required, ...props });
const dict = getSource(DictionarySchema, schema);
if (dict)
return _jsx(DictionarySchemaInput, { name: name, schema: dict, required: required, ...props });
const data = getSource(DataSchema, schema);
if (data)
return _jsx(DataSchemaInput, { name: name, schema: data, required: required, ...props });
throw new UnexpectedError(`Schema "${name}" has no corresponding form field`, { name, schema });
}
export function DateSchemaInput({ schema, value, ...props }) {
return _jsx(DateInput, { ...schema, value: getString(value), ...props });
}
export function NumberSchemaInput({ schema, value, ...props }) {
return _jsx(NumberInput, { ...schema, value: getNumber(value), formatter: num => schema.format(num), ...props });
}
export function ChoiceSchemaInput({ schema, value, ...props }) {
const { options } = requireSource(ChoiceSchema, schema);
if (getKeys(options).length <= 8)
return _jsx(ChoiceRadioInputs, { ...schema, value: getString(value), ...props });
return _jsx(SelectInput, { ...schema, value: getString(value), ...props });
}
export function BooleanSchemaInput({ schema, value, ...props }) {
return _jsx(CheckboxInput, { ...schema, value: !!value, ...props });
}
export function StringSchemaInput({ schema, value, ...props }) {
return _jsx(TextInput, { ...schema, value: getString(value), formatter: str => schema.format(schema.sanitize(str)), ...props });
}
export function ArraySchemaInput({ schema, value, ...props }) {
return _jsx(ArrayInput, { ...schema, value: isArray(value) ? value : undefined, ...props });
}
export function DictionarySchemaInput({ schema, value, ...props }) {
return _jsx(DictionaryInput, { ...schema, value: isDictionary(value) ? value : undefined, ...props });
}
export function DataSchemaInput({ schema, value, ...props }) {
return _jsx(DataInput, { ...schema, value: isData(value) ? value : undefined, ...props });
}
/**
* Show the right control/input for a named property of a form, wrapped in a `<Field>`
*
* @example <FormControl name="email" /> // Outputs a `<Field><StringInput></Field>` for the "email" property.
* @example <FormControl name="age" /> // Outputs a `<Field><NumberInput></Field>` for the "age" property.
*/
export function SchemaField({ schema, children, ...props }) {
return (_jsx(Field, { ...props, ...schema, children: children ?? _jsx(SchemaInput, { schema: schema, ...props }) }));
}