diff --git a/dist/form.js b/dist/form.js index 125bcac..cd6e64c 100644 --- a/dist/form.js +++ b/dist/form.js @@ -1,8 +1,8 @@ -import { jsx as n, jsxs as M } from "react/jsx-runtime"; -import { Input as I, Checkbox as ee, Textarea as re, RadioGroup as te, HStack as ne, Radio as oe, Select as le, Modal as ie, ModalOverlay as ce, ModalContent as ue, ModalHeader as se, ModalCloseButton as ae, ModalBody as de, VStack as fe, SimpleGrid as pe, ModalFooter as be, Button as A, FormControl as ve, FormLabel as me, FormErrorMessage as xe, useDisclosure as Fe } from "@chakra-ui/react"; -import { useContext as he, useMemo as x, useRef as ge, useEffect as G, createContext as ke, useState as Re, useCallback as B } from "react"; -import { Controller as P, useForm as Se, useWatch as Ce } from "react-hook-form"; -const Me = {}, C = { +import { jsx as l, jsxs as R } from "react/jsx-runtime"; +import { Input as I, Checkbox as ee, Textarea as re, RadioGroup as te, HStack as le, Radio as ne, Select as oe, Modal as ie, ModalOverlay as ce, ModalContent as ue, ModalHeader as se, ModalCloseButton as ae, ModalBody as de, VStack as fe, SimpleGrid as be, ModalFooter as pe, Button as A, FormControl as ve, FormLabel as me, FormErrorMessage as xe, useDisclosure as Fe } from "@chakra-ui/react"; +import { useContext as he, useMemo as m, useRef as ge, useEffect as G, createContext as ke, useState as Se, useCallback as E } from "react"; +import { Controller as P, useForm as ye, useWatch as Re } from "react-hook-form"; +const Me = {}, y = { create: { titlePrefix: "افزودن", submitText: "ثبت" @@ -12,12 +12,12 @@ const Me = {}, C = { submitText: "ویرایش" } }, H = ke(null); -function ye({ item: e, mode: r }) { +function Ce({ item: e, mode: r }) { return e ? [r, e.rowId, e.entityId, e.id].filter(Boolean).join("-") : r; } -function F({ required: e, validate: r, rules: t }) { - const o = { ...t ?? {} }; - return e && (o.required = typeof e == "string" ? e : "این فیلد الزامی است."), r && (o.validate = r), o; +function x({ required: e, validate: r, rules: t }) { + const n = { ...t ?? {} }; + return e && (n.required = typeof e == "string" ? e : "این فیلد الزامی است."), r && (n.validate = r), n; } function v() { const e = he(H); @@ -26,43 +26,68 @@ function v() { return e; } function U(e = []) { - return e.map((r) => ({ - label: r.label ?? r.name, - value: String(r.value ?? r.id) - })); + return e.map((r, t) => { + if (typeof r != "object" || r === null) { + const o = String(r); + return { + key: o, + label: o, + value: o, + disabled: !1 + }; + } + const n = r.value ?? r.id; + return { + key: String(r.key ?? n ?? t), + label: r.label ?? r.name ?? n, + value: String(n), + disabled: !!r.disabled + }; + }); } -function h({ name: e, label: r, showWhen: t, children: o }) { +function Ve({ options: e = [] }) { + return e.map((r, t) => /* @__PURE__ */ l( + "option", + { + value: r.value, + disabled: r.disabled, + children: r.label + }, + `${r.key}-${t}` + )); +} +function F({ name: e, label: r, showWhen: t, children: n }) { var s; - const { errors: i, control: u } = v(), c = Ce({ + const { errors: o, control: u } = v(), c = Re({ control: u, name: t == null ? void 0 : t.name }); - return x(() => t ? typeof t == "function" ? t({ + return m(() => t ? typeof t == "function" ? t({ value: c - }) : c === t.value : !0, [t, c]) ? /* @__PURE__ */ M(ve, { isInvalid: !!i[e], children: [ - r && /* @__PURE__ */ n(me, { fontSize: "sm", fontWeight: "bold", children: r }), - o, - /* @__PURE__ */ n(xe, { children: (s = i[e]) == null ? void 0 : s.message }) + }) : c === t.value : !0, [t, c]) ? /* @__PURE__ */ R(ve, { isInvalid: !!o[e], children: [ + r && /* @__PURE__ */ l(me, { fontSize: "sm", fontWeight: "bold", children: r }), + n, + /* @__PURE__ */ l(xe, { children: (s = o[e]) == null ? void 0 : s.message }) ] }) : null; } -function Ve({ +function Be({ name: e, label: r, required: t, - validate: o, - rules: i, + validate: n, + rules: o, showWhen: u, placeholder: c, - ...l + ...i }) { const { register: s } = v(); - return /* @__PURE__ */ n(h, { name: e, label: r, showWhen: u, children: /* @__PURE__ */ n( + return /* @__PURE__ */ l(F, { name: e, label: r, showWhen: u, children: /* @__PURE__ */ l( I, { borderRadius: "xl", placeholder: c, - ...s(e, F({ required: t, validate: o, rules: i })), - ...l + ...s(e, x({ required: t, validate: n, rules: o })), + ...i } ) }); } @@ -70,60 +95,20 @@ function Ee({ name: e, label: r, required: t, - validate: o, - rules: i, + validate: n, + rules: o, showWhen: u, placeholder: c, - ...l + ...i }) { const { register: s } = v(); - return /* @__PURE__ */ n(h, { name: e, label: r, showWhen: u, children: /* @__PURE__ */ n( + return /* @__PURE__ */ l(F, { name: e, label: r, showWhen: u, children: /* @__PURE__ */ l( re, { borderRadius: "xl", placeholder: c, - ...s(e, F({ required: t, validate: o, rules: i })), - ...l - } - ) }); -} -function Be({ - name: e, - label: r, - required: t, - validate: o, - rules: i, - showWhen: u, - placeholder: c = "انتخاب کنید", - options: l = [], - onChange: s, - isClearable: f = !0, - ...p -}) { - const { control: d, setValue: a } = v(), y = U(l); - return /* @__PURE__ */ n(h, { name: e, label: r, showWhen: u, children: /* @__PURE__ */ n( - P, - { - name: e, - control: d, - rules: F({ required: t, validate: o, rules: i }), - render: ({ field: k }) => /* @__PURE__ */ n( - le, - { - borderRadius: "xl", - placeholder: c, - value: k.value ?? "", - onChange: (m) => { - const R = m.target.value; - k.onChange(R), s == null || s({ - value: R, - setValue: a - }); - }, - ...p, - children: y.map((m) => /* @__PURE__ */ n("option", { value: m.value, children: m.label }, m.value)) - } - ) + ...s(e, x({ required: t, validate: n, rules: o })), + ...i } ) }); } @@ -131,30 +116,37 @@ function Ie({ name: e, label: r, required: t, - validate: o, - rules: i, + validate: n, + rules: o, showWhen: u, - options: c = [], - onChange: l + placeholder: c = "انتخاب کنید", + options: i = [], + onChange: s, + isClearable: d = !0, + ...b }) { - const { control: s, setValue: f } = v(), p = U(c); - return /* @__PURE__ */ n(h, { name: e, label: r, showWhen: u, children: /* @__PURE__ */ n( + const { control: f, setValue: a } = v(), M = m(() => U(i), [i]); + return /* @__PURE__ */ l(F, { name: e, label: r, showWhen: u, children: /* @__PURE__ */ l( P, { name: e, - control: s, - rules: F({ required: t, validate: o, rules: i }), - render: ({ field: d }) => /* @__PURE__ */ n( - te, + control: f, + rules: x({ required: t, validate: n, rules: o }), + render: ({ field: g }) => /* @__PURE__ */ l( + oe, { - value: d.value, - onChange: (a) => { - d.onChange(a), l == null || l({ - value: a, - setValue: f + borderRadius: "xl", + placeholder: d ? c : void 0, + value: g.value ?? "", + onChange: (C) => { + const k = C.target.value; + g.onChange(k), s == null || s({ + value: k, + setValue: a }); }, - children: /* @__PURE__ */ n(ne, { pt: "8px", spacing: 3, children: p.map((a) => /* @__PURE__ */ n(oe, { value: a.value, children: a.label }, a.value)) }) + ...b, + children: /* @__PURE__ */ l(Ve, { options: M }) } ) } @@ -164,28 +156,61 @@ function Pe({ name: e, label: r, required: t, - validate: o, - rules: i, + validate: n, + rules: o, showWhen: u, - children: c, - onChange: l + options: c = [], + onChange: i }) { - const { control: s, setValue: f } = v(); - return /* @__PURE__ */ n(h, { name: e, label: r, showWhen: u, children: /* @__PURE__ */ n( + const { control: s, setValue: d } = v(), b = U(c); + return /* @__PURE__ */ l(F, { name: e, label: r, showWhen: u, children: /* @__PURE__ */ l( P, { name: e, control: s, - rules: F({ required: t, validate: o, rules: i }), - render: ({ field: p }) => /* @__PURE__ */ n( + rules: x({ required: t, validate: n, rules: o }), + render: ({ field: f }) => /* @__PURE__ */ l( + te, + { + value: f.value, + onChange: (a) => { + f.onChange(a), i == null || i({ + value: a, + setValue: d + }); + }, + children: /* @__PURE__ */ l(le, { pt: "8px", spacing: 3, children: b.map((a) => /* @__PURE__ */ l(ne, { value: a.value, children: a.label }, a.value)) }) + } + ) + } + ) }); +} +function $e({ + name: e, + label: r, + required: t, + validate: n, + rules: o, + showWhen: u, + children: c, + onChange: i +}) { + const { control: s, setValue: d } = v(); + return /* @__PURE__ */ l(F, { name: e, label: r, showWhen: u, children: /* @__PURE__ */ l( + P, + { + name: e, + control: s, + rules: x({ required: t, validate: n, rules: o }), + render: ({ field: b }) => /* @__PURE__ */ l( ee, { - isChecked: !!p.value, - onChange: (d) => { - const a = d.target.checked; - p.onChange(a), l == null || l({ + isChecked: !!b.value, + onChange: (f) => { + const a = f.target.checked; + b.onChange(a), i == null || i({ value: a, - setValue: f + setValue: d }); }, children: c ?? r @@ -198,18 +223,18 @@ function ze({ name: e, label: r, required: t, - validate: o, - rules: i, + validate: n, + rules: o, showWhen: u, ...c }) { - const { register: l } = v(); - return /* @__PURE__ */ n(h, { name: e, label: r, showWhen: u, children: /* @__PURE__ */ n( + const { register: i } = v(); + return /* @__PURE__ */ l(F, { name: e, label: r, showWhen: u, children: /* @__PURE__ */ l( I, { type: "file", borderRadius: "xl", - ...l(e, F({ required: t, validate: o, rules: i })), + ...i(e, x({ required: t, validate: n, rules: o })), ...c } ) }); @@ -218,106 +243,106 @@ function De({ name: e, label: r, required: t, - validate: o, - rules: i, + validate: n, + rules: o, showWhen: u, ...c }) { - const { register: l } = v(); - return /* @__PURE__ */ n(h, { name: e, label: r, showWhen: u, children: /* @__PURE__ */ n( + const { register: i } = v(); + return /* @__PURE__ */ l(F, { name: e, label: r, showWhen: u, children: /* @__PURE__ */ l( I, { type: "date", borderRadius: "xl", - ...l(e, F({ required: t, validate: o, rules: i })), + ...i(e, x({ required: t, validate: n, rules: o })), ...c } ) }); } -const je = { - Input: Ve, - Select: Be, - Radio: Ie, +const Ae = { + Input: Be, + Select: Ie, + Radio: Pe, Textarea: Ee, - Check: Pe, + Check: $e, Filepicker: ze, Datepicker: De, useForm: v }; -function Ae({ +function Ge({ isOpen: e, close: r, item: t = null, - entityName: o = "آیتم", - title: i, + entityName: n = "آیتم", + title: o, createTitle: u, editTitle: c, - submitText: l, + submitText: i, createSubmitText: s, - editSubmitText: f, - defaultValues: p = Me, - getDefaultValues: d, + editSubmitText: d, + defaultValues: b = Me, + getDefaultValues: f, resetKey: a, - onSubmit: y, - transformValues: k, - children: m, - isLoading: R = !1, + onSubmit: M, + transformValues: g, + children: C, + isLoading: k = !1, size: _ = "lg", columns: Y = { base: 1, md: 2 } }) { - const b = !!t, g = b ? "edit" : "create", w = x(() => i || (b ? c ?? `${C.edit.titlePrefix} ${o}` : u ?? `${C.create.titlePrefix} ${o}`), [i, c, u, o, b]), J = x(() => l || (b ? f ?? C.edit.submitText : s ?? C.create.submitText), [l, f, s, b]), S = x(() => typeof d == "function" ? d({ + const p = !!t, h = p ? "edit" : "create", w = m(() => o || (p ? c ?? `${y.edit.titlePrefix} ${n}` : u ?? `${y.create.titlePrefix} ${n}`), [o, c, u, n, p]), J = m(() => i || (p ? d ?? y.edit.submitText : s ?? y.create.submitText), [i, d, s, p]), S = m(() => typeof f == "function" ? f({ item: t, - mode: g, - isEdit: b - }) : p, [d, p, t, g, b]), V = ge(S); + mode: h, + isEdit: p + }) : b, [f, b, t, h, p]), V = ge(S); G(() => { V.current = S; }, [S]); - const K = x(() => a || ye({ + const K = m(() => a || Ce({ item: t, - mode: g - }), [a, t, g]), Q = Se({ + mode: h + }), [a, t, h]), Q = ye({ defaultValues: S }), { handleSubmit: X, - reset: E, - register: z, - control: D, - setValue: L, - watch: T, + reset: B, + register: $, + control: z, + setValue: D, + watch: L, formState: { isSubmitting: Z, errors: O } } = Q; G(() => { - e && E(V.current); - }, [e, K, E]); - const $ = () => { - E(V.current), r(); + e && B(V.current); + }, [e, K, B]); + const T = () => { + B(V.current), r(); }, q = X(async (j) => { - const W = typeof k == "function" ? k({ + const W = typeof g == "function" ? g({ values: j, item: t, - mode: g, - isEdit: b + mode: h, + isEdit: p }) : j; - await y({ + await M({ values: W, item: t, - mode: g, - isEdit: b + mode: h, + isEdit: p }); - }), N = x( + }), N = m( () => ({ - register: z, - control: D, - setValue: L, - watch: T, + register: $, + control: z, + setValue: D, + watch: L, errors: O }), - [z, D, L, T, O] + [$, z, D, L, O] ); - return /* @__PURE__ */ M(ie, { isOpen: e, onClose: $, isCentered: !0, size: _, children: [ - /* @__PURE__ */ n(ce, { backdropFilter: "blur(6px)" }), - /* @__PURE__ */ M( + return /* @__PURE__ */ R(ie, { isOpen: e, onClose: T, isCentered: !0, size: _, children: [ + /* @__PURE__ */ l(ce, { backdropFilter: "blur(6px)" }), + /* @__PURE__ */ R( ue, { as: "form", @@ -325,7 +350,7 @@ function Ae({ borderRadius: "2xl", overflow: "visible", children: [ - /* @__PURE__ */ n( + /* @__PURE__ */ l( se, { bgGradient: "linear(to-l, blue.600, facebook.500)", @@ -335,17 +360,17 @@ function Ae({ children: w } ), - /* @__PURE__ */ n(ae, { color: "white" }), - /* @__PURE__ */ n(de, { py: 5, children: /* @__PURE__ */ n(H.Provider, { value: N, children: /* @__PURE__ */ n(fe, { spacing: 4, alignItems: "stretch", children: /* @__PURE__ */ n(pe, { columns: Y, spacing: 4, children: m }) }) }) }), - /* @__PURE__ */ M(be, { gap: 2, bg: "gray.50", children: [ - /* @__PURE__ */ n(A, { type: "button", variant: "ghost", onClick: $, children: "انصراف" }), - /* @__PURE__ */ n( + /* @__PURE__ */ l(ae, { color: "white" }), + /* @__PURE__ */ l(de, { py: 5, children: /* @__PURE__ */ l(H.Provider, { value: N, children: /* @__PURE__ */ l(fe, { spacing: 4, alignItems: "stretch", children: /* @__PURE__ */ l(be, { columns: Y, spacing: 4, children: C }) }) }) }), + /* @__PURE__ */ R(pe, { gap: 2, bg: "gray.50", children: [ + /* @__PURE__ */ l(A, { type: "button", variant: "ghost", onClick: T, children: "انصراف" }), + /* @__PURE__ */ l( A, { type: "submit", colorScheme: "blue", borderRadius: "xl", - isLoading: Z || R, + isLoading: Z || k, children: J } ) @@ -355,32 +380,32 @@ function Ae({ ) ] }); } -function Ge() { - const { isOpen: e, onOpen: r, onClose: t } = Fe(), [o, i] = Re(null), u = B(() => { - i(null), r(); - }, [r]), c = B( - (f) => { - i(f), r(); +function He() { + const { isOpen: e, onOpen: r, onClose: t } = Fe(), [n, o] = Se(null), u = E(() => { + o(null), r(); + }, [r]), c = E( + (d) => { + o(d), r(); }, [r] - ), l = B(() => { - i(null), t(); - }, [t]), s = !!o; - return x( + ), i = E(() => { + o(null), t(); + }, [t]), s = !!n; + return m( () => ({ isOpen: e, - item: o, + item: n, isEdit: s, isCreate: !s, openCreate: u, openEdit: c, - close: l + close: i }), - [e, o, s, u, c, l] + [e, n, s, u, c, i] ); } export { - je as Field, - Ae as FormModal, - Ge as useFormModal + Ae as Field, + Ge as FormModal, + He as useFormModal }; diff --git a/src/form/FormModal.jsx b/src/form/FormModal.jsx index ca2bd85..20559de 100644 --- a/src/form/FormModal.jsx +++ b/src/form/FormModal.jsx @@ -72,10 +72,39 @@ function useFormModalContext() { } function normalizeOptions(options = []) { - return options.map((option) => ({ - label: option.label ?? option.name, - value: String(option.value ?? option.id), - })); + return options.map((option, index) => { + if (typeof option !== "object" || option === null) { + const value = String(option); + + return { + key: value, + label: value, + value, + disabled: false, + }; + } + + const value = option.value ?? option.id; + + return { + key: String(option.key ?? value ?? index), + label: option.label ?? option.name ?? value, + value: String(value), + disabled: Boolean(option.disabled), + }; + }); +} + +function NativeSelectOptions({ options = [] }) { + return options.map((option, index) => ( + + )); } // ----- field wrapper ----- @@ -181,7 +210,8 @@ function SelectField({ ...props }) { const { control, setValue } = useFormModalContext(); - const normalizedOptions = normalizeOptions(options); + + const normalizedOptions = useMemo(() => normalizeOptions(options), [options]); return ( @@ -192,7 +222,7 @@ function SelectField({ render={({ field }) => ( )} />