UNPKG

mantine-entity

Version:

A library combining Mantine, TanStack Query, and Mantine React Table for efficient entity management

133 lines (132 loc) 9.58 kB
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; /* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable @typescript-eslint/no-explicit-any */ import { useCallback, useMemo } from "react"; import { Checkbox, FileInput, InputLabel, MultiSelect, NumberInput, PasswordInput, Radio, RadioGroup, Select, Textarea, TextInput, } from "@mantine/core"; import { DateInput, DateTimePicker } from "@mantine/dates"; import { Controller, FormProvider, get, useFormContext, } from "react-hook-form"; import { TableField } from "../fields/table"; import { PanelField } from "../fields/panel"; import AsyncSelect from "../fields/async-select"; import SegmentedInput from "../fields/segment"; import SwitchInput from "../fields/switch"; import { ErrorMessage } from "../fields/error-message"; import { compareValues, generateValidationRules } from "../utils"; import RadioCardInput from "../fields/radio-card"; import AsyncMultiSelect from "../fields/async-multi-select"; import { RichTextInput } from "../fields/rich-text"; const RenderController = ({ config, control, render, }) => { const methods = useFormContext(); // useRenderCount(`RenderController (${config.label})`); const { rules, isRequired } = useMemo(() => ({ rules: generateValidationRules(config.validationRules), isRequired: config.validationRules?.required, }), [config.validationRules]); const icon = config.icon ? _jsx(config.icon, { size: 16 }) : undefined; return (_jsx(Controller, { name: config.name, control: control, rules: rules, defaultValue: config.defaultValue ?? "", render: (renderProps) => { const defaultProps = { label: config.label, placeholder: config.placeholder ?? "", description: config.description, withAsterisk: isRequired, disabled: config.disabled ?? false, hidden: config.hidden ?? false, leftSection: icon, inputWrapperOrder: ["label", "input", "error", "description"], error: get(renderProps.formState.errors, config.name) && (_jsx(ErrorMessage, { errors: renderProps.formState.errors, name: config.name, render: ({ message }) => message })), rules, }; return render({ ...renderProps, field: { ...renderProps.field, onChange: (event) => renderProps.field.onChange(config?.transformValue ? config.transformValue(event, methods) : event), }, defaultProps, }); } })); }; const RenderElements = ({ element, methods, editing, }) => { const { showWhen, disabledWhen, visibleRules } = element; const { control } = methods; const getFieldElement = (config) => { const commonProps = { config, control }; switch (config.type) { case "text": return (_jsx(RenderController, { ...commonProps, config: { ...commonProps.config }, render: ({ field, defaultProps }) => (_jsx(TextInput, { ...field, ...defaultProps })) })); case "textarea": return (_jsx(RenderController, { ...commonProps, render: ({ field, defaultProps }) => (_jsx(Textarea, { ...field, ...defaultProps })) })); case "number": return (_jsx(RenderController, { ...commonProps, render: ({ field, defaultProps }) => (_jsx(NumberInput, { ...field, value: Number(field.value), ...defaultProps, allowNegative: false, min: 0, defaultValue: "", ...config.numberProps })) })); case "date": return (_jsx(RenderController, { ...commonProps, render: ({ field, defaultProps }) => (_jsx(DateInput, { ...field, ...defaultProps, value: field.value ? new Date(field.value) : undefined, onChange: (v) => field.onChange(v?.toISOString()) })) })); case "datetime": return (_jsx(RenderController, { ...commonProps, render: ({ field, defaultProps }) => (_jsx(DateTimePicker, { ...field, ...defaultProps, value: field.value ? new Date(field.value) : undefined, onChange: (v) => field.onChange(v?.toISOString()) })) })); case "select": return (_jsx(RenderController, { ...commonProps, render: ({ field, defaultProps }) => (_jsx(Select, { ...field, ...defaultProps, data: config.data || [], comboboxProps: { withinPortal: false }, ...config?.selectProps })) })); case "multiselect": return (_jsx(RenderController, { ...commonProps, config: { ...commonProps.config, defaultValue: [] }, render: ({ field, defaultProps }) => (_jsx(MultiSelect, { ...field, ...defaultProps, data: config.data || [], defaultValue: [] })) })); case "async-select": return (_jsx(RenderController, { ...commonProps, render: ({ field, defaultProps }) => (_jsx(AsyncSelect, { ...field, ...defaultProps, dataSource: config.asyncDataSource, data: config.data || [] })) })); case "async-multi-select": return (_jsx(RenderController, { ...commonProps, config: { ...commonProps.config, defaultValue: [] }, render: ({ field, defaultProps }) => (_jsx(AsyncMultiSelect, { ...field, ...defaultProps, value: field.value, dataSource: config.asyncDataSource, data: config.data || [] })) })); case "file": return (_jsx(RenderController, { ...commonProps, render: ({ field, defaultProps }) => (_jsx(FileInput, { ...field, ...defaultProps })) })); case "radio": return (_jsx(RenderController, { ...commonProps, render: ({ field, defaultProps }) => (_jsx(RadioGroup, { ...field, ...defaultProps, children: config.data?.map((option) => (_jsx(Radio, { value: option.value, label: option.label, size: "xs", mt: 6 }, option.value))) })) })); case "checkbox": return (_jsx(RenderController, { ...commonProps, config: { ...commonProps.config, ...(!commonProps.config.defaultValue ? { defaultValue: undefined } : {}), }, render: ({ field, defaultProps: { inputWrapperOrder, ...defaultProps }, }) => (_jsx(Checkbox, { ...field, checked: Boolean(field.value), ...defaultProps, size: "xs" }, String(field.value))) })); case "label": return _jsx(InputLabel, { size: "sm", children: config.label }); case "panel": return (_jsx(RenderController, { ...commonProps, render: ({ field, defaultProps }) => (_jsx(PanelField, { field: { ...config }, ...field, ...defaultProps, methods: methods })) })); case "table": return (_jsx(RenderController, { ...commonProps, config: { ...commonProps.config, defaultValue: [] }, render: ({ field, defaultProps }) => (_jsx(TableField, { field: { ...config }, ...field, ...defaultProps, methods: methods })) })); case "switch": return (_jsx(RenderController, { ...commonProps, render: ({ field, defaultProps }) => (_jsx(SwitchInput, { ...field, ...defaultProps, data: config.data || [] })) })); case "radio-card": return (_jsx(RenderController, { ...commonProps, render: ({ field, defaultProps }) => (_jsx(RadioCardInput, { ...field, ...defaultProps, data: config.data || [] })) })); case "segment": return (_jsx(RenderController, { ...commonProps, render: ({ field, defaultProps }) => (_jsx(SegmentedInput, { ...defaultProps, ...field, data: config.data || [] })) })); case "password": return (_jsx(RenderController, { ...commonProps, render: ({ field, defaultProps }) => (_jsx(PasswordInput, { ...field, ...defaultProps })) })); case "custom": return (_jsx(RenderController, { ...commonProps, render: (controller) => config?.customComponent ? (config?.customComponent({ controller, methods })) : (_jsx(_Fragment, {})) })); case "rich-text": return (_jsx(RenderController, { ...commonProps, render: ({ field, defaultProps }) => (_jsx(RichTextInput, { ...field, ...defaultProps, editable: config.editableRichText })) })); default: return _jsxs("div", { children: ["Field type ", config.type, " not supported"] }); } }; const disabled = useMemo(() => (disabledWhen ? disabledWhen(methods) : element.disabled), [element.disabled, disabledWhen]); const showControl = useCallback((children) => { if (visibleRules && visibleRules.comparison) { if (editing) return children; const comparisonResult = compareValues(methods.watch(visibleRules.fieldName), visibleRules.fieldValue, visibleRules.comparison, visibleRules.caseSensitivity); if (comparisonResult) { return visibleRules.whenVisibleRulesPass === "showField" ? children : null; } else { return visibleRules.whenVisibleRulesPass === "hideField" ? children : null; } } return showWhen && !showWhen(methods) ? null : children; }, [showWhen, visibleRules, methods, editing]); if (element.hidden) { return null; } return (_jsx(FormProvider, { ...methods, children: showControl(getFieldElement({ ...element, disabled })) })); }; export { RenderElements };