@g4rcez/components 0.0.28 → 0.0.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/core/button.js +1 -1
- package/dist/components/core/polymorph.d.ts +1 -1
- package/dist/components/core/polymorph.d.ts.map +1 -1
- package/dist/components/core/resizable.d.ts.map +1 -1
- package/dist/components/core/resizable.js +43 -4
- package/dist/components/display/alert.d.ts +2 -3
- package/dist/components/display/alert.d.ts.map +1 -1
- package/dist/components/display/alert.js +6 -6
- package/dist/components/display/calendar.d.ts +1 -1
- package/dist/components/display/calendar.d.ts.map +1 -1
- package/dist/components/display/calendar.js +6 -5
- package/dist/components/display/card.d.ts +4 -3
- package/dist/components/display/card.d.ts.map +1 -1
- package/dist/components/display/card.js +2 -2
- package/dist/components/display/list.d.ts +16 -0
- package/dist/components/display/list.d.ts.map +1 -0
- package/dist/components/display/list.js +35 -0
- package/dist/components/display/tabs.d.ts.map +1 -1
- package/dist/components/floating/modal.d.ts +4 -3
- package/dist/components/floating/modal.d.ts.map +1 -1
- package/dist/components/floating/modal.js +13 -12
- package/dist/components/form/autocomplete.d.ts.map +1 -1
- package/dist/components/form/autocomplete.js +26 -19
- package/dist/components/form/checkbox.d.ts +3 -1
- package/dist/components/form/checkbox.d.ts.map +1 -1
- package/dist/components/form/checkbox.js +5 -4
- package/dist/components/form/date-picker.d.ts +3 -3
- package/dist/components/form/date-picker.d.ts.map +1 -1
- package/dist/components/form/date-picker.js +12 -7
- package/dist/components/form/input-field.d.ts.map +1 -1
- package/dist/components/form/input-field.js +2 -2
- package/dist/components/form/input.d.ts.map +1 -1
- package/dist/components/form/input.js +4 -5
- package/dist/components/form/select.d.ts.map +1 -1
- package/dist/components/form/select.js +8 -7
- package/dist/components/form/switch.d.ts +4 -3
- package/dist/components/form/switch.d.ts.map +1 -1
- package/dist/components/form/switch.js +28 -7
- package/dist/components/table/index.js +5 -5
- package/dist/components/table/sort.d.ts.map +1 -1
- package/dist/components/table/sort.js +7 -6
- package/dist/hooks/use-click-outside.d.ts +3 -0
- package/dist/hooks/use-click-outside.d.ts.map +1 -0
- package/dist/hooks/use-click-outside.js +17 -0
- package/dist/hooks/use-form.d.ts +18 -5
- package/dist/hooks/use-form.d.ts.map +1 -1
- package/dist/hooks/use-form.js +62 -18
- package/dist/index.css +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +6673 -6644
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +49 -49
- package/dist/index.umd.js.map +1 -1
- package/dist/lib/dom.d.ts +2 -1
- package/dist/lib/dom.d.ts.map +1 -1
- package/dist/lib/dom.js +11 -12
- package/dist/preset/preset.tailwind.d.ts.map +1 -1
- package/dist/preset/preset.tailwind.js +4 -2
- package/dist/preset/src/styles/theme.js +6 -6
- package/dist/styles/theme.js +6 -6
- package/package.json +3 -3
- package/README.md +0 -36
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-picker.d.ts","sourceRoot":"","sources":["../../../src/components/form/date-picker.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"date-picker.d.ts","sourceRoot":"","sources":["../../../src/components/form/date-picker.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAyD,MAAM,OAAO,CAAC;AAI9E,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAY,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAS,UAAU,EAAE,MAAM,SAAS,CAAC;AAE5C,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC,UAAU,EAAE,aAAa,GAAG,EAAE,CAAC,CAAC;AAyBvE,eAAO,MAAM,UAAU,uGAuGtB,CAAC"}
|
|
@@ -2,12 +2,12 @@ import { __rest } from "tslib";
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { format, parse, startOfDay } from "date-fns";
|
|
4
4
|
import { CalendarIcon } from "lucide-react";
|
|
5
|
-
import { Fragment, useId, useMemo, useState } from "react";
|
|
5
|
+
import { forwardRef, Fragment, useId, useMemo, useState } from "react";
|
|
6
6
|
import { Is } from "sidekicker";
|
|
7
|
+
import { useTranslations } from "../../hooks/use-translate-context";
|
|
7
8
|
import { Calendar } from "../display/calendar";
|
|
8
9
|
import { Dropdown } from "../floating/dropdown";
|
|
9
10
|
import { Input } from "./input";
|
|
10
|
-
import { useTranslations } from "../../hooks/use-translate-context";
|
|
11
11
|
const fixedDate = new Date(1970, 11, 31);
|
|
12
12
|
const parts = {
|
|
13
13
|
year: () => [/\d/, /\d/, /\d/, /\d/],
|
|
@@ -27,7 +27,7 @@ const partValues = {
|
|
|
27
27
|
day: (date) => date.getDate().toString().padStart(2, "0"),
|
|
28
28
|
month: (date) => (date.getMonth() + 1).toString().padStart(2, "0"),
|
|
29
29
|
};
|
|
30
|
-
export const DatePicker = (_a) => {
|
|
30
|
+
export const DatePicker = forwardRef((_a, externalRef) => {
|
|
31
31
|
var _b;
|
|
32
32
|
var { date, locale, disabledDate, autoFocusToday, onChange, markToday } = _a, props = __rest(_a, ["date", "locale", "disabledDate", "autoFocusToday", "onChange", "markToday"]);
|
|
33
33
|
const labelId = useId();
|
|
@@ -55,14 +55,19 @@ export const DatePicker = (_a) => {
|
|
|
55
55
|
if (matches) {
|
|
56
56
|
const d = startOfDay(parse(v, placeholder, new Date()));
|
|
57
57
|
setInnerDate(d);
|
|
58
|
-
onChange === null || onChange === void 0 ? void 0 : onChange(d);
|
|
58
|
+
return onChange === null || onChange === void 0 ? void 0 : onChange(d);
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
+
setInnerDate(undefined);
|
|
62
|
+
return onChange === null || onChange === void 0 ? void 0 : onChange(undefined);
|
|
61
63
|
};
|
|
62
64
|
const onChangeDate = (d) => {
|
|
63
65
|
setInnerDate(d);
|
|
64
66
|
onChange === null || onChange === void 0 ? void 0 : onChange(d);
|
|
65
|
-
|
|
67
|
+
if (d)
|
|
68
|
+
return setValue(format(d, placeholder));
|
|
69
|
+
return setValue("");
|
|
66
70
|
};
|
|
67
|
-
|
|
68
|
-
};
|
|
71
|
+
const htmlValue = innerDate === null || innerDate === void 0 ? void 0 : innerDate.toISOString();
|
|
72
|
+
return (_jsx(Input, Object.assign({}, props, { mask: mask, value: value, "data-value": htmlValue, "data-target": props.name, className: "uppercase", formNoValidate: !open, placeholder: placeholder, onChange: onChangeDateInput, required: (_b = props.required) !== null && _b !== void 0 ? _b : true, error: open ? undefined : props.error, name: undefined, id: undefined, right: _jsxs(Fragment, { children: [_jsx("input", { "data-origin": props.name, hidden: true, type: "date", id: props.name, ref: externalRef, name: props.name, defaultValue: htmlValue }), _jsx(Dropdown, { open: open, restoreFocus: true, onChange: setOpen, trigger: _jsxs("span", { "aria-labelledby": labelId, children: [_jsx("span", { id: labelId, className: "sr-only", children: translation.datePickerCalendarButtonLabel }), _jsx(CalendarIcon, {})] }), buttonProps: { "aria-describedby": labelId }, children: _jsx(Calendar, Object.assign({}, props, { locale: locale, date: innerDate, onChange: onChangeDate, markToday: markToday, disabledDate: disabledDate, autoFocusToday: autoFocusToday })) })] }) })));
|
|
73
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-field.d.ts","sourceRoot":"","sources":["../../../src/components/form/input-field.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAY,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAG3D,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGrD,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC,iBAAiB,CAC/C,OAAO,CAAC;IACJ,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;CACzB,CAAC,CACL,CAAC;AAEF,eAAO,MAAM,aAAa,iEAA0E,aAAa,
|
|
1
|
+
{"version":3,"file":"input-field.d.ts","sourceRoot":"","sources":["../../../src/components/form/input-field.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAY,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAG3D,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGrD,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC,iBAAiB,CAC/C,OAAO,CAAC;IACJ,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;CACzB,CAAC,CACL,CAAC;AAEF,eAAO,MAAM,aAAa,iEAA0E,aAAa,4CA2ChH,CAAC;AAEF,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,OAAO,GAAG,QAAQ,IAAI,gBAAgB,CACxE,OAAO,CAAC;IACJ,IAAI,EAAE,KAAK,CAAC;IACZ,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,KAAK,CAAC;IACZ,QAAQ,EAAE,KAAK,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,KAAK,CAAC;IACb,UAAU,EAAE,KAAK,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACvB,CAAC,EACF,CAAC,CACJ,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,CAAC,SAAS,OAAO,GAAG,QAAQ,8LAmBpD,iBAAiB,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,4CAqCvC,CAAC"}
|
|
@@ -5,10 +5,10 @@ import { Fragment } from "react";
|
|
|
5
5
|
import { useTranslations } from "../../hooks/use-translate-context";
|
|
6
6
|
import { css } from "../../lib/dom";
|
|
7
7
|
import { Tooltip } from "../floating/tooltip";
|
|
8
|
-
export const InputFeedback = ({ reportStatus, hideLeft = false, className, info, children, title }) => (_jsxs("div", { className: css("w-full justify-between", hideLeft && children === null ? "hidden" : "flex", className), children: [hideLeft ? null : (_jsxs("span", { className: "flex items-center gap-1 group-
|
|
8
|
+
export const InputFeedback = ({ reportStatus, hideLeft = false, className, info, children, title }) => (_jsxs("div", { className: css("w-full justify-between", hideLeft && children === null ? "hidden" : "flex", className), children: [hideLeft ? null : (_jsxs("span", { className: "flex items-center gap-1 transition-colors group-focus-within:text-primary group-hover:text-primary group-error:text-danger", children: [title, reportStatus || info ? (_jsxs("span", { className: "flex items-center justify-center gap-1", children: [info ? (_jsx(Tooltip, { title: _jsxs("span", { className: "cursor-help", children: [_jsx("span", { className: "sr-only", children: info }), _jsx(InfoIcon, { className: "aspect-square size-3", "aria-hidden": "true", size: 16, strokeWidth: 1, absoluteStrokeWidth: true })] }), children: info })) : null, reportStatus ? (_jsxs(Fragment, { children: [_jsx(CheckCircle, { className: "hidden aspect-square size-3 opacity-0 transition-opacity group-assert:block group-assert:text-success group-assert:opacity-100", "aria-hidden": "true", size: 16, strokeWidth: 1, absoluteStrokeWidth: true }), _jsx(XCircle, { className: "hidden aspect-square size-3 opacity-0 transition-opacity group-error:block group-error:opacity-100", "aria-hidden": "true", size: 16, strokeWidth: 1, absoluteStrokeWidth: true })] })) : null] })) : null] })), children] }));
|
|
9
9
|
export const InputField = ({ optionalText: _optionalText, left, rightLabel, container, feedback, interactive, right, info, children, error, form, id, labelClassName = "", name, title, placeholder, hideLeft, required, }) => {
|
|
10
10
|
const ID = id !== null && id !== void 0 ? id : name;
|
|
11
11
|
const translation = useTranslations();
|
|
12
12
|
const optionalText = _optionalText !== null && _optionalText !== void 0 ? _optionalText : translation.inputOptionalLabel;
|
|
13
|
-
return (_jsxs("fieldset", { form: form, "data-error": !!error, "data-interactive": !!interactive, className: css("group inline-flex gap-1.5
|
|
13
|
+
return (_jsxs("fieldset", { form: form, "data-error": !!error, "data-interactive": !!interactive, className: css("group inline-flex w-full gap-1.5", container), children: [_jsxs("label", { form: form, htmlFor: ID, className: "inline-flex w-full cursor-text flex-row flex-wrap justify-between gap-1 text-sm transition-colors empty:hidden group-hover:border-primary group-error:text-danger", children: [!hideLeft && !rightLabel ? (_jsx(InputFeedback, { info: info, hideLeft: hideLeft, reportStatus: true, title: title, placeholder: placeholder, children: optionalText || rightLabel ? (_jsxs(Fragment, { children: [!required ? _jsx("span", { className: "text-opacity-70", children: optionalText }) : null, rightLabel ? _jsx(Fragment, { children: rightLabel }) : null] })) : null })) : null, _jsxs("div", { className: `group relative flex w-full flex-row flex-nowrap items-center gap-x-2 gap-y-1 rounded-md border border-input-border bg-transparent transition-colors group-focus-within:border-primary group-hover:border-primary group-error:border-danger ${labelClassName} focus:ring-2 focus:ring-inset focus:ring-primary`, children: [left ? _jsx("span", { className: "absolute left-0 flex flex-nowrap gap-1 whitespace-nowrap pl-2", children: left }) : null, children, right ? _jsx("span", { className: "absolute right-0 flex flex-nowrap gap-2 whitespace-nowrap pr-1", children: right }) : null] })] }), _jsx("p", { className: "hidden text-xs empty:hidden group-has-[input:not(:focus):invalid[data-initialized=true]]:block group-error:block group-error:text-danger", children: error }), _jsx("p", { className: "text-xs empty:mt-0 empty:hidden group-has-[input:not(:focus):valid[data-initialized=true]]:block group-assert:block group-error:hidden", children: feedback })] }));
|
|
14
14
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../src/components/form/input.tsx"],"names":[],"mappings":"AACA,OAAO,KAAwC,MAAM,OAAO,CAAC;AAC7D,OAAkB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEzD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,aAAa,EAAc,eAAe,EAAE,MAAM,eAAe,CAAC;AAE3E,MAAM,MAAM,UAAU,GAAG,QAAQ,CAC7B,eAAe,CAAC,OAAO,CAAC,EACxB,YAAY,GACR,aAAa,GAAG;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB,CACR,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,UAAU,
|
|
1
|
+
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../src/components/form/input.tsx"],"names":[],"mappings":"AACA,OAAO,KAAwC,MAAM,OAAO,CAAC;AAC7D,OAAkB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEzD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,aAAa,EAAc,eAAe,EAAE,MAAM,eAAe,CAAC;AAE3E,MAAM,MAAM,UAAU,GAAG,QAAQ,CAC7B,eAAe,CAAC,OAAO,CAAC,EACxB,YAAY,GACR,aAAa,GAAG;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB,CACR,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,UAAU,CAoF/B,CAAC"}
|
|
@@ -3,7 +3,7 @@ import { __rest } from "tslib";
|
|
|
3
3
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
4
4
|
import { forwardRef, useEffect, useRef } from "react";
|
|
5
5
|
import MaskInput from "the-mask-input";
|
|
6
|
-
import { css, mergeRefs } from "../../lib/dom";
|
|
6
|
+
import { css, initializeInputDataset, mergeRefs } from "../../lib/dom";
|
|
7
7
|
import { InputField } from "./input-field";
|
|
8
8
|
export const Input = forwardRef((_a, ref) => {
|
|
9
9
|
var _b;
|
|
@@ -14,7 +14,7 @@ export const Input = forwardRef((_a, ref) => {
|
|
|
14
14
|
if (inputRef.current === null)
|
|
15
15
|
return;
|
|
16
16
|
const input = inputRef.current;
|
|
17
|
-
const focus = (
|
|
17
|
+
const focus = initializeInputDataset(inputRef.current);
|
|
18
18
|
const goNextInputImpl = (e) => {
|
|
19
19
|
const event = e;
|
|
20
20
|
if (event.key === "Enter" && input.enterKeyHint === "next") {
|
|
@@ -29,11 +29,10 @@ export const Input = forwardRef((_a, ref) => {
|
|
|
29
29
|
}
|
|
30
30
|
};
|
|
31
31
|
input.addEventListener("keydown", goNextInputImpl);
|
|
32
|
-
input.addEventListener("focus", focus);
|
|
33
32
|
return () => {
|
|
33
|
+
focus();
|
|
34
34
|
input.removeEventListener("keydown", goNextInputImpl);
|
|
35
|
-
input.removeEventListener("focus", focus);
|
|
36
35
|
};
|
|
37
36
|
}, []);
|
|
38
|
-
return (_jsx(InputField, { info: info, container: css("group inline-block w-full", container), error: error, feedback: feedback, hideLeft: hideLeft, left: left, optionalText: optionalText, right: right, rightLabel: rightLabel, interactive: interactive, form: props.form, id: props.name || props.id, name: props.name, labelClassName: labelClassName, title: props.title, placeholder: props.placeholder, required: props.required, children: _jsx(MaskInput, Object.assign({}, props, { type: type, "data-next": next, ref: mergeRefs(ref, inputRef), id: id, name: id, className: css("input
|
|
37
|
+
return (_jsx(InputField, { info: info, container: css("group inline-block w-full", container), error: error, feedback: feedback, hideLeft: hideLeft, left: left, optionalText: optionalText, right: right, rightLabel: rightLabel, interactive: interactive, form: props.form, id: props.name || props.id, name: props.name, labelClassName: labelClassName, title: props.title, placeholder: props.placeholder, required: props.required, children: _jsx(MaskInput, Object.assign({}, props, { type: type, "data-next": next, ref: mergeRefs(ref, inputRef), id: id, name: id, className: css("input placeholder-input-mask group h-11 w-full flex-1 rounded-md bg-transparent p-2 text-foreground outline-none transition-colors group-error:text-danger group-error:placeholder-input-mask-error", !!right ? "pe-4" : "", !!left ? "ps-4" : "", props.className) })) }));
|
|
39
38
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../src/components/form/select.tsx"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../src/components/form/select.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA6D,MAAM,OAAO,CAAC;AAGlF,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAc,eAAe,EAAE,MAAM,eAAe,CAAC;AAE5D,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE/G,MAAM,MAAM,WAAW,GAAG,QAAQ,CAC9B,eAAe,CAAC,QAAQ,CAAC,EACzB;IACI,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B,CACJ,CAAC;AAEF,eAAO,MAAM,MAAM,oGA4FlB,CAAC"}
|
|
@@ -2,30 +2,31 @@
|
|
|
2
2
|
import { __rest } from "tslib";
|
|
3
3
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
4
4
|
import { ChevronDown } from "lucide-react";
|
|
5
|
-
import { forwardRef, useEffect, useRef } from "react";
|
|
5
|
+
import { forwardRef, useEffect, useImperativeHandle, useRef } from "react";
|
|
6
6
|
import { useTranslations } from "../../hooks/use-translate-context";
|
|
7
|
-
import { css, mergeRefs } from "../../lib/dom";
|
|
7
|
+
import { css, initializeInputDataset, mergeRefs } from "../../lib/dom";
|
|
8
8
|
import { InputField } from "./input-field";
|
|
9
9
|
export const Select = forwardRef((_a, ref) => {
|
|
10
10
|
var _b;
|
|
11
|
-
var { required = true, options, selectContainer = "", feedback = null, labelClassName, interactive, rightLabel, optionalText, container, hideLeft = false, right, left, error } = _a, props = __rest(_a, ["required", "options", "selectContainer", "feedback", "labelClassName", "interactive", "rightLabel", "optionalText", "container", "hideLeft", "right", "left", "error"]);
|
|
11
|
+
var { required = true, options, info, selectContainer = "", feedback = null, labelClassName, interactive, rightLabel, optionalText, container, hideLeft = false, right, left, error } = _a, props = __rest(_a, ["required", "options", "info", "selectContainer", "feedback", "labelClassName", "interactive", "rightLabel", "optionalText", "container", "hideLeft", "right", "left", "error"]);
|
|
12
12
|
const translation = useTranslations();
|
|
13
13
|
const inputRef = useRef(null);
|
|
14
14
|
const id = (_b = props.id) !== null && _b !== void 0 ? _b : props.name;
|
|
15
|
+
useImperativeHandle(ref, () => inputRef.current);
|
|
15
16
|
useEffect(() => {
|
|
16
17
|
if (inputRef.current === null)
|
|
17
18
|
return;
|
|
18
19
|
const input = inputRef.current;
|
|
19
|
-
const focus = (
|
|
20
|
+
const focus = initializeInputDataset(inputRef.current);
|
|
20
21
|
const change = () => input.setAttribute("data-selected", "true");
|
|
21
|
-
input.addEventListener("focus", focus);
|
|
22
22
|
input.addEventListener("change", change);
|
|
23
23
|
return () => {
|
|
24
|
-
|
|
24
|
+
focus();
|
|
25
25
|
input.removeEventListener("change", change);
|
|
26
26
|
};
|
|
27
27
|
}, []);
|
|
28
|
-
|
|
28
|
+
const onClickLabel = () => { var _a; return (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus(); };
|
|
29
|
+
return (_jsx(InputField, { container: css("group inline-block w-full", container), error: error, feedback: feedback, hideLeft: hideLeft, left: left, info: info, optionalText: optionalText, rightLabel: rightLabel, interactive: interactive, form: props.form, id: props.name || props.id, name: props.name, labelClassName: labelClassName, title: props.title, placeholder: props.placeholder, required: required, right: _jsx("label", { htmlFor: id, children: _jsxs("button", { onClick: onClickLabel, type: "button", className: "mt-2 transition-colors hover:text-primary", children: [_jsx(ChevronDown, { size: 20 }), _jsx("span", { className: "sr-only", children: translation.inputCaretDown })] }) }), children: _jsxs("select", Object.assign({}, props, { id: id, name: id, value: props.value, required: required, ref: mergeRefs(ref, inputRef), "data-selected": !!props.value || false, defaultValue: props.value ? undefined : "", className: css("input select group h-11 w-full flex-1 rounded-md bg-transparent p-2 text-foreground placeholder-input-placeholder outline-none transition-colors group-error:text-danger group-error:placeholder-input-mask-error", "data-[selected=false]:text-input-placeholder", props.className), children: [_jsx("option", { value: "", disabled: true, hidden: true, children: props.placeholder }), options.map((option) => {
|
|
29
30
|
var _a;
|
|
30
31
|
return (_jsx("option", Object.assign({}, option, { children: (_a = option.label) !== null && _a !== void 0 ? _a : option.value }), `${id}-select-option-${option.value}`));
|
|
31
32
|
})] })) }));
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
type SwitchProps =
|
|
2
|
+
export type SwitchProps = React.ComponentProps<"input"> & {
|
|
3
3
|
onCheck?: (nextValue: boolean) => void;
|
|
4
|
+
error?: string;
|
|
5
|
+
container?: string;
|
|
4
6
|
};
|
|
5
|
-
export declare const Switch:
|
|
6
|
-
export {};
|
|
7
|
+
export declare const Switch: React.ForwardRefExoticComponent<Omit<SwitchProps, "ref"> & React.RefAttributes<HTMLInputElement>>;
|
|
7
8
|
//# sourceMappingURL=switch.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switch.d.ts","sourceRoot":"","sources":["../../../src/components/form/switch.tsx"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"switch.d.ts","sourceRoot":"","sources":["../../../src/components/form/switch.tsx"],"names":[],"mappings":"AACA,OAAO,KAA8E,MAAM,OAAO,CAAC;AAInG,MAAM,MAAM,WAAW,GAAG,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG;IACtD,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,eAAO,MAAM,MAAM,mGAwDjB,CAAC"}
|
|
@@ -1,19 +1,40 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { __rest } from "tslib";
|
|
3
3
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
4
|
-
import { useId, useState } from "react";
|
|
5
|
-
|
|
4
|
+
import { forwardRef, useEffect, useId, useImperativeHandle, useRef, useState } from "react";
|
|
5
|
+
import { useCallbackRef } from "../../hooks/use-callback-ref";
|
|
6
|
+
import { css, dispatchInput } from "../../lib/dom";
|
|
7
|
+
export const Switch = forwardRef((_a, ref) => {
|
|
6
8
|
var _b;
|
|
7
|
-
var { children } = _a, props = __rest(_a, ["children"]);
|
|
9
|
+
var { children, container, error } = _a, props = __rest(_a, ["children", "container", "error"]);
|
|
8
10
|
const id = useId();
|
|
9
|
-
const [innerChecked, setInnerChecked] = useState(false);
|
|
10
|
-
const checked =
|
|
11
|
+
const [innerChecked, setInnerChecked] = useState((_b = props.checked) !== null && _b !== void 0 ? _b : false);
|
|
12
|
+
const checked = innerChecked;
|
|
13
|
+
const innerRef = useRef(null);
|
|
14
|
+
const stableOnChange = useCallbackRef(props.onChange);
|
|
15
|
+
useImperativeHandle(ref, () => innerRef.current);
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (innerRef.current !== null) {
|
|
18
|
+
if (stableOnChange.current) {
|
|
19
|
+
const onChange = (e) => {
|
|
20
|
+
e.target.checked = !e.target.checked;
|
|
21
|
+
stableOnChange.current && stableOnChange.current(e);
|
|
22
|
+
};
|
|
23
|
+
innerRef.current.addEventListener("change", onChange);
|
|
24
|
+
return () => { var _a; return (_a = innerRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListener("change", onChange); };
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}, []);
|
|
11
28
|
const onCheck = (e) => {
|
|
12
29
|
var _a;
|
|
13
30
|
const button = e.target;
|
|
14
31
|
const checked = !(button.dataset.checked === "true");
|
|
15
32
|
setInnerChecked(checked);
|
|
16
33
|
(_a = props === null || props === void 0 ? void 0 : props.onCheck) === null || _a === void 0 ? void 0 : _a.call(props, checked);
|
|
34
|
+
if (innerRef.current !== null) {
|
|
35
|
+
dispatchInput(innerRef.current, checked.toString());
|
|
36
|
+
innerRef.current.dispatchEvent(new Event("change", { bubbles: true }));
|
|
37
|
+
}
|
|
17
38
|
};
|
|
18
|
-
return (_jsxs("
|
|
19
|
-
};
|
|
39
|
+
return (_jsxs("fieldset", { className: css("flex flex-wrap items-center", container), children: [_jsx("input", Object.assign({}, props, { ref: innerRef, hidden: true, type: "checkbox", checked: checked, onChange: (e) => setInnerChecked(e.target.checked) })), _jsx("button", { type: "button", role: "switch", onClick: onCheck, "aria-checked": checked, "data-checked": checked, "aria-labelledby": `${id}-label`, className: "duration-300 ease-in-out relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 data-[checked=false]:bg-input-switch-bg data-[checked=true]:bg-primary", children: _jsx("span", { "aria-hidden": "true", "data-checked": checked, className: "duration-300 duration-300 ease-in-out inline-block aspect-square size-5 transform rounded-full shadow ring-0 transition data-[checked=false]:translate-x-0 data-[checked=true]:translate-x-5 data-[checked=false]:bg-disabled data-[checked=true]:bg-input-switch" }) }), _jsx("span", { className: "ml-3 text-sm", id: `${id}-label`, children: _jsx("span", { className: "font-medium text-foreground", children: children }) }), _jsx("span", { className: "mt-1 flex-1 whitespace-nowrap text-xs text-danger empty:mt-0 empty:hidden", children: error })] }));
|
|
40
|
+
});
|
|
@@ -5,7 +5,7 @@ import { AnimatePresence, motion } from "framer-motion";
|
|
|
5
5
|
import Linq from "linq-arrays";
|
|
6
6
|
import React, { Fragment, useEffect, useMemo, useRef, useState } from "react";
|
|
7
7
|
import { TableVirtuoso } from "react-virtuoso";
|
|
8
|
-
import {
|
|
8
|
+
import { Is } from "sidekicker";
|
|
9
9
|
import { useReducer } from "use-typed-reducer";
|
|
10
10
|
import { useCallbackRef } from "../../hooks/use-callback-ref";
|
|
11
11
|
import { path } from "../../lib/fns";
|
|
@@ -14,7 +14,7 @@ import { Pagination } from "./pagination";
|
|
|
14
14
|
import { multiSort } from "./sort";
|
|
15
15
|
import { createOptionCols } from "./table-lib";
|
|
16
16
|
import { TableHeader } from "./thead";
|
|
17
|
-
const calculateSkeletonWidth = () =>
|
|
17
|
+
const calculateSkeletonWidth = (index) => Math.min(Math.max(index + index * (index % 2 === 0 ? 2 : 4) + 10, 50), 90);
|
|
18
18
|
const TableBody = React.forwardRef((props, ref) => {
|
|
19
19
|
var _a;
|
|
20
20
|
return (_jsx("tbody", Object.assign({}, props, { role: "rowgroup", className: `divide-y divide-table-border ${(_a = props.className) !== null && _a !== void 0 ? _a : ""}`, ref: ref, children: _jsx(AnimatePresence, { children: props.children }) })));
|
|
@@ -53,12 +53,12 @@ const ItemContent = (index, row, context) => {
|
|
|
53
53
|
const matrix = `${colIndex},${index}`;
|
|
54
54
|
const value = path(row, col.id);
|
|
55
55
|
const Component = col.Element;
|
|
56
|
-
return (_createElement("td", Object.assign({}, col.cellProps, { "data-matrix": matrix, role: "cell", key: `accessor-${index}-${colIndex}`, className: "px-2 h-14 border-none first:table-cell hidden md:table-cell" }), loading ? (_jsx("div", { className: "animate-pulse h-2 bg-table-border rounded", style: { width: `${calculateSkeletonWidth()}%` } })) : Component ? (_jsx(Component, { row: row, matrix: matrix, col: col, rowIndex: index, value: value })) : (_jsx(Fragment, { children: Is.nil(value) ? "" : value }))));
|
|
56
|
+
return (_createElement("td", Object.assign({}, col.cellProps, { "data-matrix": matrix, role: "cell", key: `accessor-${index}-${colIndex}`, className: "px-2 h-14 border-none first:table-cell hidden md:table-cell" }), loading ? (_jsx("div", { className: "animate-pulse h-2 bg-table-border rounded", style: { width: `${calculateSkeletonWidth(index)}%` } })) : Component ? (_jsx(Component, { row: row, matrix: matrix, col: col, rowIndex: index, value: value })) : (_jsx(Fragment, { children: Is.nil(value) ? "" : value }))));
|
|
57
57
|
}) }));
|
|
58
58
|
};
|
|
59
59
|
const Frag = () => _jsx(Fragment, {});
|
|
60
60
|
const InnerTable = (_a) => {
|
|
61
|
-
var { filters, pagination = null, onScrollEnd, useControl = false, setCols, setFilters, sorters, cols, border =
|
|
61
|
+
var { filters, pagination = null, onScrollEnd, useControl = false, setCols, setFilters, sorters, cols, border = false, setSorters } = _a, props = __rest(_a, ["filters", "pagination", "onScrollEnd", "useControl", "setCols", "setFilters", "sorters", "cols", "border", "setSorters"]);
|
|
62
62
|
const ref = useRef(null);
|
|
63
63
|
const [showLoadingFooter, setShowLoadingFooter] = useState(false);
|
|
64
64
|
const onScrollEndRef = useCallbackRef(onScrollEnd);
|
|
@@ -94,7 +94,7 @@ const InnerTable = (_a) => {
|
|
|
94
94
|
observer.observe(div);
|
|
95
95
|
return () => observer.disconnect();
|
|
96
96
|
}, []);
|
|
97
|
-
return (_jsxs("div", { className: "min-w-full", children: [_jsxs("div", { className: `group
|
|
97
|
+
return (_jsxs("div", { className: "min-w-full", children: [_jsxs("div", { className: `group rounded-lg px-1 ${border ? "border border-table-border" : ""}`, children: [_jsx(TableVirtuoso, { data: rows, useWindowScroll: true, components: components, totalCount: rows.length, itemContent: ItemContent, context: { loading: props.loading, loadingMore: props.loadingMore, cols: cols }, fixedFooterContent: showLoadingFooter ? Frag : null, fixedHeaderContent: () => (_jsx(TableHeader, { headers: cols, sorters: sorters, filters: filters, setCols: setCols, setSorters: setSorters, setFilters: setFilters, loading: !!props.loading })) }), _jsx("div", { "aria-hidden": "true", ref: ref, className: "h-0.5 w-full" })] }), pagination !== null ? _jsx(Pagination, Object.assign({}, pagination)) : null] }));
|
|
98
98
|
};
|
|
99
99
|
const dispatcherFun = (prev, setter) => typeof setter === "function" ? setter(prev) : setter;
|
|
100
100
|
export const Table = (props) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sort.d.ts","sourceRoot":"","sources":["../../../src/components/table/sort.tsx"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"sort.d.ts","sourceRoot":"","sources":["../../../src/components/table/sort.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAwC,MAAM,OAAO,CAAC;AAG7D,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAGpC,OAAO,EAAE,GAAG,EAAY,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAErF,KAAK,KAAK,CAAC,CAAC,SAAS,EAAE,IAAI,MAAM,CAAC,SAAS,MAAM,CAAC,SAAS,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC;AAE9E,aAAK,KAAK;IACN,GAAG,QAAQ;IACX,IAAI,SAAS;IACb,SAAS,cAAc;CAC1B;AAED,MAAM,MAAM,MAAM,CAAC,CAAC,SAAS,EAAE,IAAI;IAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAAC,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,KAAK,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAY9F,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,UAAU,MAAM,CAAC,CAAC,CAAC,EAAE,QAA2C,CAAC;AAEnH,KAAK,KAAK,CAAC,CAAC,SAAS,EAAE,IAAI,kBAAkB,CACzC,CAAC,EACD;IACI,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACrB,GAAG,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAC1D,CACJ,CAAC;AASF,eAAO,MAAM,IAAI,GAAI,CAAC,SAAS,EAAE,SAAS,KAAK,CAAC,CAAC,CAAC,4CA0EjD,CAAC;AAEF,KAAK,eAAe,CAAC,CAAC,SAAS,EAAE,IAAI,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,SAAS,GAAG,YAAY,CAAC,GAAG;IAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAA;CAAE,CAAC;AAE9G,eAAO,MAAM,UAAU,GAAI,CAAC,SAAS,EAAE,SAAS,eAAe,CAAC,CAAC,CAAC,4CAkCjE,CAAC"}
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { ArrowDown01Icon, ArrowUp01Icon, ArrowUpDownIcon, PlusIcon, Trash2Icon } from "lucide-react";
|
|
4
4
|
import { Fragment, useEffect, useState } from "react";
|
|
5
|
+
import { useTranslations } from "../../hooks/use-translate-context";
|
|
5
6
|
import { uuid } from "../../lib/fns";
|
|
6
7
|
import { Dropdown } from "../floating/dropdown";
|
|
7
8
|
import { Select } from "../form/select";
|
|
8
9
|
import { getLabel } from "./table-lib";
|
|
9
|
-
import { useTranslations } from "../../hooks/use-translate-context";
|
|
10
10
|
var Order;
|
|
11
11
|
(function (Order) {
|
|
12
12
|
Order["Asc"] = "asc";
|
|
@@ -19,8 +19,8 @@ const createSorterFn = (fields) => (a, b) => fields.reduce((acc, x) => {
|
|
|
19
19
|
const p = a[property] > b[property] ? reverse : a[property] < b[property] ? -reverse : 0;
|
|
20
20
|
return acc !== 0 ? acc : p;
|
|
21
21
|
}, 0);
|
|
22
|
-
export const multiSort = (array, fields) => array.
|
|
23
|
-
const createSorter = (col, label, order
|
|
22
|
+
export const multiSort = (array, fields) => array.toSorted(createSorterFn(fields));
|
|
23
|
+
const createSorter = (col, label, order) => ({
|
|
24
24
|
id: uuid(),
|
|
25
25
|
type: order,
|
|
26
26
|
value: col.id,
|
|
@@ -36,7 +36,7 @@ export const Sort = (props) => {
|
|
|
36
36
|
const onAddSorter = () => {
|
|
37
37
|
const col = props.cols[0];
|
|
38
38
|
if (col)
|
|
39
|
-
props.set((prev) => [...prev, createSorter(col, orders.asc.label)]);
|
|
39
|
+
props.set((prev) => [...prev, createSorter(col, orders.asc.label, orders.asc.value)]);
|
|
40
40
|
};
|
|
41
41
|
const onSetSorter = (id) => (e) => {
|
|
42
42
|
const value = e.target.value;
|
|
@@ -66,9 +66,10 @@ export const SorterHead = (props) => {
|
|
|
66
66
|
if (status === Order.Undefined)
|
|
67
67
|
return prev.filter((x) => x.value !== props.col.id);
|
|
68
68
|
const findIndex = prev.findIndex((p) => p.value === props.col.id);
|
|
69
|
+
const sorter = createSorter(props.col, status, status);
|
|
69
70
|
if (findIndex === -1)
|
|
70
|
-
return [...prev,
|
|
71
|
-
prev[findIndex] =
|
|
71
|
+
return [...prev, sorter];
|
|
72
|
+
prev[findIndex] = sorter;
|
|
72
73
|
return [...prev];
|
|
73
74
|
});
|
|
74
75
|
}, [status, props.col]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-click-outside.d.ts","sourceRoot":"","sources":["../../src/hooks/use-click-outside.ts"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAEzC,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,WAAW,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,KAAK,IAAI,SAclI,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
export const useOnClickOutside = (ref, handler) => {
|
|
3
|
+
useEffect(() => {
|
|
4
|
+
const listener = (event) => {
|
|
5
|
+
if (!ref.current || ref.current.contains(event.target))
|
|
6
|
+
return;
|
|
7
|
+
handler(event);
|
|
8
|
+
};
|
|
9
|
+
const params = { passive: true };
|
|
10
|
+
document.addEventListener("mousedown", listener, params);
|
|
11
|
+
document.addEventListener("touchstart", listener, params);
|
|
12
|
+
return () => {
|
|
13
|
+
document.removeEventListener("mousedown", listener);
|
|
14
|
+
document.removeEventListener("touchstart", listener);
|
|
15
|
+
};
|
|
16
|
+
}, [ref, handler]);
|
|
17
|
+
};
|
package/dist/hooks/use-form.d.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { AllPaths } from "sidekicker";
|
|
3
3
|
import { z } from "zod";
|
|
4
|
+
import { DatePickerProps } from "../components";
|
|
5
|
+
import { AutocompleteProps } from "../components/form/autocomplete";
|
|
6
|
+
import { CheckboxProps } from "../components/form/checkbox";
|
|
4
7
|
import { InputProps } from "../components/form/input";
|
|
5
8
|
import { SelectProps } from "../components/form/select";
|
|
9
|
+
import { SwitchProps } from "../components/form/switch";
|
|
6
10
|
export declare const formToJson: (form: HTMLFormElement) => any;
|
|
7
11
|
export declare const convertPath: (path: string) => string[];
|
|
8
12
|
export declare const getSchemaShape: <T extends z.ZodObject<any>>(name: string, schema: T) => T;
|
|
@@ -10,16 +14,25 @@ type CustomOnInvalid = (args: {
|
|
|
10
14
|
form: HTMLFormElement;
|
|
11
15
|
errors: Record<string, string>;
|
|
12
16
|
}) => any;
|
|
13
|
-
type
|
|
14
|
-
|
|
17
|
+
export type UseFormSubmitParams<T> = {
|
|
18
|
+
success: boolean;
|
|
19
|
+
errors: Array<{
|
|
20
|
+
message: string;
|
|
21
|
+
path: string[];
|
|
22
|
+
}>;
|
|
23
|
+
json: any;
|
|
24
|
+
data: T;
|
|
15
25
|
form: HTMLFormElement;
|
|
16
26
|
reset: () => void;
|
|
17
27
|
event: React.FormEvent<HTMLFormElement>;
|
|
18
|
-
}
|
|
28
|
+
};
|
|
29
|
+
type UseFormSubmit<T> = (args: UseFormSubmitParams<T>) => any;
|
|
19
30
|
export declare const useForm: <T extends z.ZodObject<any>>(schema: T) => {
|
|
20
31
|
input: <Props extends InputProps>(name: AllPaths<z.infer<T>>, props?: Props) => Props;
|
|
21
|
-
|
|
22
|
-
|
|
32
|
+
datepicker: <Props extends DatePickerProps>(name: AllPaths<z.infer<T>>, props?: Props) => Props;
|
|
33
|
+
checkbox: <Props extends CheckboxProps | SwitchProps>(name: AllPaths<z.infer<T>>, props?: Props) => Props;
|
|
34
|
+
select: <Props extends SelectProps | AutocompleteProps>(name: AllPaths<z.infer<T>>, props?: Props) => Props;
|
|
35
|
+
onSubmit: (exec: UseFormSubmit<z.infer<T>>) => (event: React.FormEvent<HTMLFormElement>) => any;
|
|
23
36
|
errors: Record<string, string | undefined> | null;
|
|
24
37
|
onInvalid: (exec?: CustomOnInvalid) => (event: React.FormEvent<HTMLFormElement>) => void;
|
|
25
38
|
disabled: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-form.d.ts","sourceRoot":"","sources":["../../src/hooks/use-form.ts"],"names":[],"mappings":"AACA,OAAO,KAAmD,MAAM,OAAO,CAAC;AACxE,OAAO,EAAE,QAAQ,EAAe,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,CAAC,EAAuB,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"use-form.d.ts","sourceRoot":"","sources":["../../src/hooks/use-form.ts"],"names":[],"mappings":"AACA,OAAO,KAAmD,MAAM,OAAO,CAAC;AACxE,OAAO,EAAE,QAAQ,EAAe,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,CAAC,EAAuB,MAAM,KAAK,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAiBxD,eAAO,MAAM,UAAU,SAAU,eAAe,KAAG,GAIlD,CAAC;AAEF,eAAO,MAAM,WAAW,SAAU,MAAM,aAAuD,CAAC;AAEhG,eAAO,MAAM,cAAc,GAAI,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,MAAM,UAAU,CAAC,MAKpE,CAAC;AAWf,KAAK,eAAe,GAAG,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,KAAK,GAAG,CAAC;AAEhG,MAAM,MAAM,mBAAmB,CAAC,CAAC,IAAI;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACnD,IAAI,EAAE,GAAG,CAAC;IACV,IAAI,EAAE,CAAC,CAAC;IACR,IAAI,EAAE,eAAe,CAAC;IACtB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;CAC3C,CAAC;AAEF,KAAK,aAAa,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC;AAE9D,eAAO,MAAM,OAAO,GAAI,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC;YAiD1C,KAAK,SAAS,UAAU,QAAQ,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,KAAK,KAAG,KAAK;iBA7CtE,KAAK,SAAS,eAAe,QAAQ,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,KAAK,KAAG,KAAK;eA8BlF,KAAK,SAAS,aAAa,GAAG,WAAW,QAAQ,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,KAAK,KAAG,KAAK;aAf9F,KAAK,SAAS,WAAW,GAAG,iBAAiB,QAAQ,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,KAAK,KAAG,KAAK;qBA6GrG,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,KAAK,CAAC,SAAS,CAAC,eAAe,CAAC;;uBApBrE,eAAe,aAAa,KAAK,CAAC,SAAS,CAAC,eAAe,CAAC;;CAoD3E,CAAC"}
|
package/dist/hooks/use-form.js
CHANGED
|
@@ -31,6 +31,8 @@ export const getSchemaShape = (name, schema) => convertPath(name).reduce((acc, e
|
|
|
31
31
|
return shape instanceof ZodArray ? shape.element : shape;
|
|
32
32
|
}, schema);
|
|
33
33
|
const getValueByType = (e) => {
|
|
34
|
+
if (e.dataset.value)
|
|
35
|
+
return e.dataset.value;
|
|
34
36
|
if (e.type === "checkbox")
|
|
35
37
|
return e.checked;
|
|
36
38
|
if (e.type === "number")
|
|
@@ -40,9 +42,25 @@ const getValueByType = (e) => {
|
|
|
40
42
|
export const useForm = (schema) => {
|
|
41
43
|
const [errors, setErrors] = useState(null);
|
|
42
44
|
const ref = useRef({});
|
|
45
|
+
const datepicker = (name, props) => {
|
|
46
|
+
const validator = getSchemaShape(name, schema);
|
|
47
|
+
return Object.assign(Object.assign({}, props), { name, id: name, required: !validator.isOptional(), error: errors === null || errors === void 0 ? void 0 : errors[name], ref: (e) => {
|
|
48
|
+
if (e === null)
|
|
49
|
+
return;
|
|
50
|
+
ref.current[name] = { element: e, schema: validator };
|
|
51
|
+
} });
|
|
52
|
+
};
|
|
43
53
|
const select = (name, props) => {
|
|
44
54
|
const validator = getSchemaShape(name, schema);
|
|
45
|
-
return Object.assign(Object.assign({}, props), { name, id: name, error: errors === null || errors === void 0 ? void 0 : errors[name], ref: (e) => {
|
|
55
|
+
return Object.assign(Object.assign({}, props), { name, id: name, required: !validator.isOptional(), error: errors === null || errors === void 0 ? void 0 : errors[name], ref: (e) => {
|
|
56
|
+
if (e === null)
|
|
57
|
+
return;
|
|
58
|
+
ref.current[name] = { element: e, schema: validator };
|
|
59
|
+
} });
|
|
60
|
+
};
|
|
61
|
+
const checkbox = (name, props) => {
|
|
62
|
+
const validator = getSchemaShape(name, schema);
|
|
63
|
+
return Object.assign(Object.assign({}, props), { name, id: name, required: !validator.isOptional(), error: errors === null || errors === void 0 ? void 0 : errors[name], ref: (e) => {
|
|
46
64
|
if (e === null)
|
|
47
65
|
return;
|
|
48
66
|
ref.current[name] = { element: e, schema: validator };
|
|
@@ -51,7 +69,7 @@ export const useForm = (schema) => {
|
|
|
51
69
|
const input = (name, props) => {
|
|
52
70
|
var _a;
|
|
53
71
|
const validator = getSchemaShape(name, schema);
|
|
54
|
-
return Object.assign(Object.assign({}, props), { name, id: name, type: Is.instance(validator, ZodNumber) ? "number" : ((_a = props === null || props === void 0 ? void 0 : props.type) !== null && _a !== void 0 ? _a : "text"), error: errors === null || errors === void 0 ? void 0 : errors[name], ref: (e) => {
|
|
72
|
+
return Object.assign(Object.assign({}, props), { name, id: name, required: !validator.isOptional(), type: Is.instance(validator, ZodNumber) ? "number" : ((_a = props === null || props === void 0 ? void 0 : props.type) !== null && _a !== void 0 ? _a : "text"), error: errors === null || errors === void 0 ? void 0 : errors[name], ref: (e) => {
|
|
55
73
|
if (e === null)
|
|
56
74
|
return;
|
|
57
75
|
ref.current[name] = { element: e, schema: validator };
|
|
@@ -59,30 +77,42 @@ export const useForm = (schema) => {
|
|
|
59
77
|
};
|
|
60
78
|
useEffect(() => {
|
|
61
79
|
const events = Object.values(ref.current).map((input) => {
|
|
62
|
-
const
|
|
80
|
+
const element = input.element.dataset.origin
|
|
81
|
+
? document.querySelector(`[data-target=${input.element.name}]`)
|
|
82
|
+
: input.element;
|
|
83
|
+
const validation = input.schema.safeParse(getValueByType(element));
|
|
63
84
|
const onBlurField = (e) => {
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
85
|
+
const name = element.dataset.target || element.name;
|
|
86
|
+
if (!name)
|
|
87
|
+
return;
|
|
88
|
+
console.log(e);
|
|
89
|
+
const value = getValueByType(e.target) || (e.relatedTarget ? getValueByType(e.relatedTarget) : "");
|
|
90
|
+
const validation = input.schema.safeParse(value);
|
|
91
|
+
console.log({ name, value, validation });
|
|
67
92
|
if (validation.success) {
|
|
68
|
-
|
|
93
|
+
element.setCustomValidity("");
|
|
69
94
|
return setErrors((prev) => {
|
|
70
95
|
const _a = prev || {}, _b = name, removed = _a[_b], rest = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
|
|
71
96
|
return rest === null || Is.empty(rest) ? null : rest;
|
|
72
97
|
});
|
|
73
98
|
}
|
|
74
|
-
if (
|
|
99
|
+
if (element.required) {
|
|
75
100
|
const errorMessage = validation.error.issues[0].message;
|
|
76
|
-
|
|
101
|
+
element.setCustomValidity(errorMessage);
|
|
77
102
|
setErrors((prev) => (Object.assign(Object.assign({}, prev), { [name]: errorMessage })));
|
|
78
103
|
}
|
|
79
104
|
};
|
|
80
|
-
|
|
81
|
-
|
|
105
|
+
element.addEventListener("blur", onBlurField);
|
|
106
|
+
if (element.tagName === "SELECT")
|
|
107
|
+
element.addEventListener("change", onBlurField);
|
|
82
108
|
return {
|
|
83
109
|
input,
|
|
84
|
-
hasInitialError:
|
|
85
|
-
unsubscribe: () =>
|
|
110
|
+
hasInitialError: element.required ? !validation.success : false,
|
|
111
|
+
unsubscribe: () => {
|
|
112
|
+
element.removeEventListener("blur", onBlurField);
|
|
113
|
+
if (element.tagName === "SELECT")
|
|
114
|
+
element.addEventListener("change", onBlurField);
|
|
115
|
+
},
|
|
86
116
|
};
|
|
87
117
|
});
|
|
88
118
|
const hasErrors = events.some((x) => x.hasInitialError);
|
|
@@ -91,18 +121,20 @@ export const useForm = (schema) => {
|
|
|
91
121
|
return () => events.forEach((item) => item.unsubscribe());
|
|
92
122
|
});
|
|
93
123
|
const onInvalid = useCallback((exec) => (event) => {
|
|
94
|
-
event.preventDefault();
|
|
95
124
|
const form = event.currentTarget;
|
|
96
125
|
const validationErrors = Object.values(ref.current).reduce((acc, input) => {
|
|
97
126
|
const field = input.element;
|
|
98
127
|
const validation = input.schema.safeParse(getValueByType(field));
|
|
128
|
+
if (field.dataset.ignore === "ignore")
|
|
129
|
+
return acc;
|
|
99
130
|
if (validation.success)
|
|
100
131
|
return acc;
|
|
101
132
|
const errorMessage = validation.error.issues[0].message;
|
|
102
133
|
field.setAttribute("data-initialized", "true");
|
|
103
|
-
|
|
134
|
+
const name = field.dataset.name || field.name || "";
|
|
135
|
+
return Object.assign(Object.assign({}, acc), { [name]: errorMessage });
|
|
104
136
|
}, {});
|
|
105
|
-
const e = Is.empty(validationErrors) ? null :
|
|
137
|
+
const e = Is.empty(validationErrors) ? null : validationErrors;
|
|
106
138
|
setErrors(e);
|
|
107
139
|
exec === null || exec === void 0 ? void 0 : exec({ form, errors: e || {} });
|
|
108
140
|
}, []);
|
|
@@ -120,7 +152,19 @@ export const useForm = (schema) => {
|
|
|
120
152
|
json = setPath(json, input.name, getValueByType(input));
|
|
121
153
|
}
|
|
122
154
|
});
|
|
123
|
-
|
|
155
|
+
const result = schema.safeParse(json);
|
|
156
|
+
if (result.success) {
|
|
157
|
+
return exec({ form, json, data: result.data, event, reset: () => formReset(form), success: true, errors: [] });
|
|
158
|
+
}
|
|
159
|
+
return exec({
|
|
160
|
+
form,
|
|
161
|
+
json,
|
|
162
|
+
event,
|
|
163
|
+
data: json,
|
|
164
|
+
success: false,
|
|
165
|
+
reset: () => formReset(form),
|
|
166
|
+
errors: result.error.issues.map((x) => ({ message: x.message, path: x.path.map((x) => String(x)) })),
|
|
167
|
+
});
|
|
124
168
|
}, []);
|
|
125
|
-
return { input, select, onSubmit, errors, onInvalid, disabled: errors !== null };
|
|
169
|
+
return { input, datepicker, checkbox, select, onSubmit, errors, onInvalid, disabled: errors !== null };
|
|
126
170
|
};
|