UNPKG

libmodulor

Version:

A TypeScript library to create platform-agnostic applications

74 lines (73 loc) 3.55 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { TBoolean } from '../../dt/index.js'; import { ucifRepeatability } from '../../uc/index.js'; import { styleDef, useStyleContext, } from '../lib/react/StyleContextProvider.js'; import { htmlInputDef } from '../lib/web/input.js'; const CHECKED_FIELD_TYPES = ['checkbox', 'radio']; const FILE_FIELD_TYPES = ['file']; const MULTIPLE_VALUES_SEPARATOR = ','; // TODO : Split this into smaller components export function UCFormFieldControl({ disabled, errMsg = null, execState, f, onChange: onChangeBase, }) { const { formFieldControl, renderFormFieldControl } = useStyleContext(); const component = renderFormFieldControl?.({ disabled, errMsg, execState, f, onChange: onChangeBase, }); if (component) { return component; } const attrs = htmlInputDef(f, disabled, errMsg); const onChange = (e) => { const target = e.currentTarget; const type = target.type; let value = target.value; if (target.localName === 'select' && !value) { // Prevent the value from being '' when we set/unset the select // Otherwise it sets '' as value and prevents the form for being valid f.clear(); onChangeBase(); return; } if (CHECKED_FIELD_TYPES.includes(type) && 'checked' in target) { value = target.checked; } else if (FILE_FIELD_TYPES.includes(type) && 'files' in target) { value = target.files?.item(0); } const [isRepeatable] = ucifRepeatability(f.def); if (isRepeatable && typeof value === 'string') { const valueArr = value .split(MULTIPLE_VALUES_SEPARATOR) .map((v) => v.trim()); f.setVal(valueArr); onChangeBase(); } else { f.setVal(value); onChangeBase(); } }; const defaultChecked = attrs.internal?.checked; const defaultValue = attrs.internal?.value; if (attrs.internal?.multiline) { const { className, style } = styleDef(formFieldControl, 'textarea', 'default'); return (_jsx("textarea", { ...attrs.spec, className: className, defaultValue: defaultValue, onChange: onChange, style: style })); } const { type } = f.def; if (type instanceof TBoolean) { const { className, style } = styleDef(formFieldControl, 'checkbox'); return (_jsx("input", { ...attrs.spec, className: className, defaultChecked: defaultChecked, defaultValue: defaultValue, onChange: onChange, style: style })); } const options = type.getOptions(); if (options) { // TODO : Handle type.hasStrictOptions() => display an input text alongside the select // TODO : Consider using a radio and/or checkbox and/or selectable buttons when the options count < X const { className, style } = styleDef(formFieldControl, 'select', 'default'); return (_jsxs("select", { ...attrs.spec, className: className, defaultValue: defaultValue, onChange: onChange, style: style, children: [_jsx("option", {}), options.map((o) => (_jsx("option", { value: o.value.toString(), children: o.label }, o.value.toString())))] })); } const { className, style } = styleDef(formFieldControl, 'input', 'default'); return (_jsx("input", { ...attrs.spec, className: className, defaultChecked: defaultChecked, defaultValue: defaultValue, onChange: onChange, style: style })); }