mantine-entity
Version:
A library combining Mantine, TanStack Query, and Mantine React Table for efficient entity management
133 lines (132 loc) • 9.58 kB
JavaScript
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 };