@gunkin/uiify 0.0.8-alpha → 0.0.10-alpha
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/alert-modal/AlertModalParts.js +1 -1
- package/dist/components/alert-modal/AlertModalParts.js.map +1 -1
- package/dist/components/behavior.css +4 -0
- package/dist/components/behavior.css.map +1 -1
- package/dist/components/button/Button.d.ts.map +1 -1
- package/dist/components/button/Button.js +11 -1
- package/dist/components/button/Button.js.map +1 -1
- package/dist/components/button/index.d.ts +1 -1
- package/dist/components/button/index.d.ts.map +1 -1
- package/dist/components/button/index.js.map +1 -1
- package/dist/components/button/types.d.ts +4 -0
- package/dist/components/button/types.d.ts.map +1 -1
- package/dist/components/drawer/Drawer.d.ts.map +1 -1
- package/dist/components/drawer/Drawer.js +0 -2
- package/dist/components/drawer/Drawer.js.map +1 -1
- package/dist/components/enhance/dialog-dismiss.d.ts +22 -0
- package/dist/components/enhance/dialog-dismiss.d.ts.map +1 -0
- package/dist/components/enhance/dialog-dismiss.js +49 -0
- package/dist/components/enhance/dialog-dismiss.js.map +1 -0
- package/dist/components/enhance/internal/read-box.d.ts +3 -0
- package/dist/components/enhance/internal/read-box.d.ts.map +1 -0
- package/dist/components/enhance/internal/read-box.js +7 -0
- package/dist/components/enhance/internal/read-box.js.map +1 -0
- package/dist/components/enhance/invoker-fallback.d.ts +0 -7
- package/dist/components/enhance/invoker-fallback.d.ts.map +1 -1
- package/dist/components/enhance/invoker-fallback.js +3 -6
- package/dist/components/enhance/invoker-fallback.js.map +1 -1
- package/dist/components/enhance/listeners.d.ts +2 -0
- package/dist/components/enhance/listeners.d.ts.map +1 -1
- package/dist/components/enhance/listeners.js +6 -0
- package/dist/components/enhance/listeners.js.map +1 -1
- package/dist/components/enhance/sheet-swipe.d.ts +9 -0
- package/dist/components/enhance/sheet-swipe.d.ts.map +1 -0
- package/dist/components/enhance/sheet-swipe.js +112 -0
- package/dist/components/enhance/sheet-swipe.js.map +1 -0
- package/dist/components/file-upload/FileUpload.js +2 -2
- package/dist/components/file-upload/FileUpload.js.map +1 -1
- package/dist/components/file-upload/types.d.ts +1 -1
- package/dist/components/file-upload/types.d.ts.map +1 -1
- package/dist/components/header/Header.js +3 -3
- package/dist/components/header/Header.js.map +1 -1
- package/dist/components/modal/Modal.d.ts +5 -4
- package/dist/components/modal/Modal.d.ts.map +1 -1
- package/dist/components/modal/Modal.js +48 -7
- package/dist/components/modal/Modal.js.map +1 -1
- package/dist/components/modal/ModalAnatomy.d.ts +33 -0
- package/dist/components/modal/ModalAnatomy.d.ts.map +1 -0
- package/dist/components/modal/ModalAnatomy.js +34 -0
- package/dist/components/modal/ModalAnatomy.js.map +1 -0
- package/dist/components/modal/ModalParts.d.ts +1 -0
- package/dist/components/modal/ModalParts.d.ts.map +1 -1
- package/dist/components/modal/ModalParts.js +26 -2
- package/dist/components/modal/ModalParts.js.map +1 -1
- package/dist/components/modal/attributes.d.ts +13 -0
- package/dist/components/modal/attributes.d.ts.map +1 -0
- package/dist/components/modal/attributes.js +17 -0
- package/dist/components/modal/attributes.js.map +1 -0
- package/dist/components/modal/client/ModalClientContent.d.ts.map +1 -1
- package/dist/components/modal/client/ModalClientContent.js +36 -14
- package/dist/components/modal/client/ModalClientContent.js.map +1 -1
- package/dist/components/modal/index.d.ts +2 -2
- package/dist/components/modal/index.d.ts.map +1 -1
- package/dist/components/modal/index.js +17 -1
- package/dist/components/modal/index.js.map +1 -1
- package/dist/components/modal/types.d.ts +43 -11
- package/dist/components/modal/types.d.ts.map +1 -1
- package/dist/components/number-field/NumberField.js +2 -2
- package/dist/components/number-field/NumberField.js.map +1 -1
- package/dist/components/number-field/types.d.ts +1 -1
- package/dist/components/number-field/types.d.ts.map +1 -1
- package/dist/components/otp-input/OtpInput.js +2 -2
- package/dist/components/otp-input/OtpInput.js.map +1 -1
- package/dist/components/otp-input/types.d.ts +1 -1
- package/dist/components/otp-input/types.d.ts.map +1 -1
- package/dist/components/pagination/Pagination.js +2 -2
- package/dist/components/pagination/Pagination.js.map +1 -1
- package/dist/components/pagination/PaginationShell.js +1 -1
- package/dist/components/pagination/PaginationShell.js.map +1 -1
- package/dist/components/pagination/types.d.ts +1 -1
- package/dist/components/pagination/types.d.ts.map +1 -1
- package/dist/components/pagination/use-pagination.js +2 -2
- package/dist/components/pagination/use-pagination.js.map +1 -1
- package/dist/components/segmented-control/client/SegmentedControlClient.d.ts +1 -1
- package/dist/components/segmented-control/client/SegmentedControlClient.d.ts.map +1 -1
- package/dist/components/segmented-control/client/SegmentedControlClient.js +2 -2
- package/dist/components/segmented-control/client/SegmentedControlClient.js.map +1 -1
- package/dist/components/segmented-control/types.d.ts +1 -1
- package/dist/components/segmented-control/types.d.ts.map +1 -1
- package/dist/components/spinner/Spinner.js +1 -1
- package/dist/components/spinner/Spinner.js.map +1 -1
- package/dist/components/spinner/types.d.ts +1 -1
- package/dist/components/spinner/types.d.ts.map +1 -1
- package/dist/components/tags-input/TagsInput.js +2 -2
- package/dist/components/tags-input/TagsInput.js.map +1 -1
- package/dist/components/tags-input/types.d.ts +1 -1
- package/dist/components/tags-input/types.d.ts.map +1 -1
- package/dist/components/toggle-group/client/ToggleGroupClient.d.ts +1 -1
- package/dist/components/toggle-group/client/ToggleGroupClient.d.ts.map +1 -1
- package/dist/components/toggle-group/client/ToggleGroupClient.js +7 -7
- package/dist/components/toggle-group/client/ToggleGroupClient.js.map +1 -1
- package/dist/components/toggle-group/types.d.ts +1 -1
- package/dist/components/toggle-group/types.d.ts.map +1 -1
- package/dist/core/render-native-invoker.d.ts +1 -1
- package/dist/core/render-native-invoker.d.ts.map +1 -1
- package/dist/core/render-native-invoker.js.map +1 -1
- package/dist/elements/choice/Choice.js +2 -2
- package/dist/elements/choice/Choice.js.map +1 -1
- package/dist/elements/choice/types.d.ts +1 -1
- package/dist/elements/choice/types.d.ts.map +1 -1
- package/dist/hooks/index.d.ts +0 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +0 -2
- package/dist/hooks/index.js.map +1 -1
- package/dist/styles/index.css +1 -1
- package/package.json +2 -1
- package/dist/hooks/use-lock-body-scroll.d.ts +0 -3
- package/dist/hooks/use-lock-body-scroll.d.ts.map +0 -1
- package/dist/hooks/use-lock-body-scroll.js +0 -15
- package/dist/hooks/use-lock-body-scroll.js.map +0 -1
- package/dist/hooks/utils/scroll-lock.d.ts +0 -5
- package/dist/hooks/utils/scroll-lock.d.ts.map +0 -1
- package/dist/hooks/utils/scroll-lock.js +0 -29
- package/dist/hooks/utils/scroll-lock.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/modal/ModalParts.tsx"],"sourcesContent":["import type { ElementType, ReactElement } from \"react\";\nimport { renderNativeInvoker } from \"@gunkin/uiify/core/render\";\nimport type { ModalCloseProps, ModalContentProps, ModalTriggerProps } from \"./types.js\";\n\n/** Native modal invoker with modal identity and trigger anatomy. */\nexport function ModalTrigger<TAs extends ElementType = \"button\">(\n props: ModalTriggerProps<TAs>,\n): ReactElement {\n const { as, target, ...consumerProps } = props as ModalTriggerProps<\"button\">;\n return renderNativeInvoker(\n as,\n \"data-uiify-modal\",\n \"trigger\",\n \"show-modal\",\n target,\n consumerProps as Record<string, unknown>,\n { button: true },\n );\n}\nModalTrigger.displayName = \"ModalTrigger\";\n\n/** Native modal dialog content with modal identity and content anatomy. */\nexport function ModalContent(props: ModalContentProps): ReactElement {\n const { children, ...dialogProps } = props;\n return (\n <dialog
|
|
1
|
+
{"version":3,"sources":["../../../src/components/modal/ModalParts.tsx"],"sourcesContent":["import type { ElementType, ReactElement } from \"react\";\nimport { renderNativeInvoker } from \"@gunkin/uiify/core/render\";\nimport { modalAppearanceAttributes } from \"./attributes.js\";\nimport type { ModalCloseProps, ModalContentProps, ModalTriggerProps } from \"./types.js\";\n\nexport {\n ModalBody,\n ModalDescription,\n ModalFooter,\n ModalGrabber,\n ModalHeader,\n ModalTitle,\n} from \"./ModalAnatomy.js\";\n\n/** Native modal invoker with modal identity and trigger anatomy. */\nexport function ModalTrigger<TAs extends ElementType = \"button\">(\n props: ModalTriggerProps<TAs>,\n): ReactElement {\n const { as, target, ...consumerProps } = props as ModalTriggerProps<\"button\">;\n return renderNativeInvoker(\n as,\n \"data-uiify-modal\",\n \"trigger\",\n \"show-modal\",\n target,\n consumerProps as Record<string, unknown>,\n { button: true },\n );\n}\nModalTrigger.displayName = \"ModalTrigger\";\n\n/** Native modal dialog content with modal identity and content anatomy. */\nexport function ModalContent(props: ModalContentProps): ReactElement {\n const { align, backdrop, children, dismiss, size, ...dialogProps } = props;\n return (\n <dialog\n {...dialogProps}\n {...modalAppearanceAttributes({ align, backdrop, dismiss, size })}\n data-part=\"content\"\n data-uiify-modal=\"\"\n >\n {children}\n </dialog>\n );\n}\nModalContent.displayName = \"ModalContent\";\n\n/** Native modal close invoker. */\nexport function ModalClose<TAs extends ElementType = \"button\">(\n props: ModalCloseProps<TAs>,\n): ReactElement {\n const { as, target, ...consumerProps } = props as ModalCloseProps<\"button\">;\n return renderNativeInvoker(\n as,\n \"data-uiify-modal\",\n \"close\",\n \"request-close\",\n target,\n consumerProps as Record<string, unknown>,\n { button: true, variant: \"ghost\" },\n );\n}\nModalClose.displayName = \"ModalClose\";\n"],"mappings":"AAmCI;AAlCJ,SAAS,2BAA2B;AACpC,SAAS,iCAAiC;AAG1C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGA,SAAS,aACd,OACc;AACd,QAAM,EAAE,IAAI,QAAQ,GAAG,cAAc,IAAI;AACzC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,EAAE,QAAQ,KAAK;AAAA,EACjB;AACF;AACA,aAAa,cAAc;AAGpB,SAAS,aAAa,OAAwC;AACnE,QAAM,EAAE,OAAO,UAAU,UAAU,SAAS,MAAM,GAAG,YAAY,IAAI;AACrE,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACH,GAAG,0BAA0B,EAAE,OAAO,UAAU,SAAS,KAAK,CAAC;AAAA,MAChE,aAAU;AAAA,MACV,oBAAiB;AAAA,MAEhB;AAAA;AAAA,EACH;AAEJ;AACA,aAAa,cAAc;AAGpB,SAAS,WACd,OACc;AACd,QAAM,EAAE,IAAI,QAAQ,GAAG,cAAc,IAAI;AACzC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,EAAE,QAAQ,MAAM,SAAS,QAAQ;AAAA,EACnC;AACF;AACA,WAAW,cAAc;","names":[]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ModalAlign, ModalAppearanceProps, ModalBackdrop, ModalDismiss, ModalSize } from "./types.js";
|
|
2
|
+
export interface ModalAppearanceAttributes {
|
|
3
|
+
readonly closedby: ModalDismiss;
|
|
4
|
+
readonly "data-align": ModalAlign | undefined;
|
|
5
|
+
readonly "data-backdrop": ModalBackdrop | undefined;
|
|
6
|
+
readonly "data-size": ModalSize | undefined;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* DOM attributes for the appearance props. Defaults (`md`, `center`, `opaque`) render nothing;
|
|
10
|
+
* `closedby` is always rendered because `UIEnhance` reads it.
|
|
11
|
+
*/
|
|
12
|
+
export declare function modalAppearanceAttributes({ align, backdrop, dismiss, size, }: ModalAppearanceProps): ModalAppearanceAttributes;
|
|
13
|
+
//# sourceMappingURL=attributes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attributes.d.ts","sourceRoot":"","sources":["../../../src/components/modal/attributes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,oBAAoB,EACpB,aAAa,EACb,YAAY,EACZ,SAAS,EACV,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,YAAY,EAAE,UAAU,GAAG,SAAS,CAAC;IAC9C,QAAQ,CAAC,eAAe,EAAE,aAAa,GAAG,SAAS,CAAC;IACpD,QAAQ,CAAC,WAAW,EAAE,SAAS,GAAG,SAAS,CAAC;CAC7C;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,EACxC,KAAK,EACL,QAAQ,EACR,OAAe,EACf,IAAI,GACL,EAAE,oBAAoB,GAAG,yBAAyB,CAOlD"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
function modalAppearanceAttributes({
|
|
2
|
+
align,
|
|
3
|
+
backdrop,
|
|
4
|
+
dismiss = "any",
|
|
5
|
+
size
|
|
6
|
+
}) {
|
|
7
|
+
return {
|
|
8
|
+
closedby: dismiss,
|
|
9
|
+
"data-align": align === "center" ? void 0 : align,
|
|
10
|
+
"data-backdrop": backdrop === "opaque" ? void 0 : backdrop,
|
|
11
|
+
"data-size": size === "md" ? void 0 : size
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
modalAppearanceAttributes
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=attributes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/modal/attributes.ts"],"sourcesContent":["import type {\n ModalAlign,\n ModalAppearanceProps,\n ModalBackdrop,\n ModalDismiss,\n ModalSize,\n} from \"./types.js\";\n\nexport interface ModalAppearanceAttributes {\n readonly closedby: ModalDismiss;\n readonly \"data-align\": ModalAlign | undefined;\n readonly \"data-backdrop\": ModalBackdrop | undefined;\n readonly \"data-size\": ModalSize | undefined;\n}\n\n/**\n * DOM attributes for the appearance props. Defaults (`md`, `center`, `opaque`) render nothing;\n * `closedby` is always rendered because `UIEnhance` reads it.\n */\nexport function modalAppearanceAttributes({\n align,\n backdrop,\n dismiss = \"any\",\n size,\n}: ModalAppearanceProps): ModalAppearanceAttributes {\n return {\n closedby: dismiss,\n \"data-align\": align === \"center\" ? undefined : align,\n \"data-backdrop\": backdrop === \"opaque\" ? undefined : backdrop,\n \"data-size\": size === \"md\" ? undefined : size,\n };\n}\n"],"mappings":"AAmBO,SAAS,0BAA0B;AAAA,EACxC;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV;AACF,GAAoD;AAClD,SAAO;AAAA,IACL,UAAU;AAAA,IACV,cAAc,UAAU,WAAW,SAAY;AAAA,IAC/C,iBAAiB,aAAa,WAAW,SAAY;AAAA,IACrD,aAAa,SAAS,OAAO,SAAY;AAAA,EAC3C;AACF;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModalClientContent.d.ts","sourceRoot":"","sources":["../../../../src/components/modal/client/ModalClientContent.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"ModalClientContent.d.ts","sourceRoot":"","sources":["../../../../src/components/modal/client/ModalClientContent.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAG1C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AA4B3D;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,GAAG,YAAY,CA4G/E;yBA5Ge,kBAAkB"}
|
|
@@ -2,18 +2,37 @@
|
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
3
|
import { useEffect, useReducer, useRef, useState } from "react";
|
|
4
4
|
import { useMergedRefs } from "@gunkin/uiify/hooks";
|
|
5
|
+
import { modalAppearanceAttributes } from "../attributes.js";
|
|
5
6
|
function increment(count) {
|
|
6
7
|
return count + 1;
|
|
7
8
|
}
|
|
9
|
+
function closeNestedDialogs(dialog) {
|
|
10
|
+
for (const nested of dialog.querySelectorAll("dialog[open]")) {
|
|
11
|
+
nested.close();
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function afterMotion(dialog, done) {
|
|
15
|
+
requestAnimationFrame(() => {
|
|
16
|
+
const running = dialog.getAnimations?.({ subtree: true }) ?? [];
|
|
17
|
+
void Promise.allSettled(
|
|
18
|
+
running.map(
|
|
19
|
+
(animation) => animation.effect?.getComputedTiming().endTime === Infinity ? 0 : animation.finished
|
|
20
|
+
)
|
|
21
|
+
).then(done);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
8
24
|
function ModalClientContent(props) {
|
|
9
25
|
const {
|
|
26
|
+
align,
|
|
27
|
+
backdrop,
|
|
10
28
|
children,
|
|
11
|
-
closeOnBackdropClick = false,
|
|
12
29
|
defaultOpen = false,
|
|
13
|
-
|
|
30
|
+
dismiss,
|
|
14
31
|
onOpenChange,
|
|
32
|
+
onOpenChangeComplete,
|
|
15
33
|
open,
|
|
16
34
|
ref,
|
|
35
|
+
size,
|
|
17
36
|
...dialogProps
|
|
18
37
|
} = props;
|
|
19
38
|
const elementRef = useRef(null);
|
|
@@ -26,6 +45,8 @@ function ModalClientContent(props) {
|
|
|
26
45
|
wantOpenRef.current = wantOpen;
|
|
27
46
|
const onOpenChangeRef = useRef(onOpenChange);
|
|
28
47
|
onOpenChangeRef.current = onOpenChange;
|
|
48
|
+
const onOpenChangeCompleteRef = useRef(onOpenChangeComplete);
|
|
49
|
+
onOpenChangeCompleteRef.current = onOpenChangeComplete;
|
|
29
50
|
const reconciledRef = useRef(false);
|
|
30
51
|
useEffect(() => {
|
|
31
52
|
const dialog = elementRef.current;
|
|
@@ -40,37 +61,38 @@ function ModalClientContent(props) {
|
|
|
40
61
|
}
|
|
41
62
|
}
|
|
42
63
|
if (wantOpen && !dialog.open) dialog.showModal();
|
|
43
|
-
else if (!wantOpen && dialog.open)
|
|
64
|
+
else if (!wantOpen && dialog.open) {
|
|
65
|
+
closeNestedDialogs(dialog);
|
|
66
|
+
dialog.close();
|
|
67
|
+
}
|
|
44
68
|
}, [nativeVersion, wantOpen, controlled]);
|
|
45
69
|
useEffect(() => {
|
|
46
70
|
const dialog = elementRef.current;
|
|
47
71
|
if (!dialog) return;
|
|
72
|
+
let disposed = false;
|
|
48
73
|
const onToggle = (event) => {
|
|
49
74
|
const next = event.newState === "open";
|
|
75
|
+
afterMotion(dialog, () => {
|
|
76
|
+
if (!disposed) onOpenChangeCompleteRef.current?.(next);
|
|
77
|
+
});
|
|
50
78
|
if (next === wantOpenRef.current) return;
|
|
51
79
|
if (!controlled) setUncontrolledOpen(next);
|
|
52
80
|
onOpenChangeRef.current?.(next);
|
|
53
81
|
recordNativeToggle();
|
|
54
82
|
};
|
|
55
83
|
dialog.addEventListener("toggle", onToggle);
|
|
56
|
-
return () =>
|
|
84
|
+
return () => {
|
|
85
|
+
disposed = true;
|
|
86
|
+
dialog.removeEventListener("toggle", onToggle);
|
|
87
|
+
};
|
|
57
88
|
}, [controlled]);
|
|
58
|
-
const handleClick = (event) => {
|
|
59
|
-
onClick?.(event);
|
|
60
|
-
if (event.defaultPrevented || !closeOnBackdropClick) return;
|
|
61
|
-
if (event.target !== event.currentTarget) return;
|
|
62
|
-
const box = event.currentTarget.getBoundingClientRect();
|
|
63
|
-
const onBackdrop = event.clientX < box.left || event.clientX > box.right || event.clientY < box.top || event.clientY > box.bottom;
|
|
64
|
-
if (!onBackdrop) return;
|
|
65
|
-
event.currentTarget.requestClose();
|
|
66
|
-
};
|
|
67
89
|
return /* @__PURE__ */ jsx(
|
|
68
90
|
"dialog",
|
|
69
91
|
{
|
|
70
92
|
...dialogProps,
|
|
93
|
+
...modalAppearanceAttributes({ align, backdrop, dismiss, size }),
|
|
71
94
|
"data-part": "content",
|
|
72
95
|
"data-uiify-modal": "",
|
|
73
|
-
onClick: handleClick,
|
|
74
96
|
ref: mergedRef,
|
|
75
97
|
suppressHydrationWarning: true,
|
|
76
98
|
children
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/modal/client/ModalClientContent.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useReducer, useRef, useState } from \"react\";\nimport type {
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/modal/client/ModalClientContent.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useReducer, useRef, useState } from \"react\";\nimport type { ReactElement } from \"react\";\nimport { useMergedRefs } from \"@gunkin/uiify/hooks\";\nimport { modalAppearanceAttributes } from \"../attributes.js\";\nimport type { ModalClientContentProps } from \"../types.js\";\n\nfunction increment(count: number): number {\n return count + 1;\n}\n\n/** A dialog nested in this one would stay open (and invisible) after its parent closes. */\nfunction closeNestedDialogs(dialog: HTMLDialogElement): void {\n for (const nested of dialog.querySelectorAll<HTMLDialogElement>(\"dialog[open]\")) {\n nested.close();\n }\n}\n\n/**\n * Runs `done` once the dialog's own transitions have finished; at once when there are none.\n * An `infinite` animation inside (a Spinner or Skeleton) never finishes, so it is not waited on.\n */\nfunction afterMotion(dialog: HTMLDialogElement, done: () => void): void {\n requestAnimationFrame(() => {\n const running = dialog.getAnimations?.({ subtree: true }) ?? [];\n void Promise.allSettled(\n running.map((animation) =>\n animation.effect?.getComputedTiming().endTime === Infinity ? 0 : animation.finished,\n ),\n ).then(done);\n });\n}\n\n/**\n * Controlled/initially-open adapter over a native modal `<dialog>`.\n *\n * The browser stays the owner of modality: opening is `showModal()`, closing is\n * `close()`, and every change — invoker command, Escape, `requestClose()`,\n * `form method=\"dialog\"`, programmatic — is observed through the single native\n * `toggle` event (Chrome 132, Firefox 133, Safari 26). SSR never emits `open`;\n * `defaultOpen` and controlled `open` are applied after mount.\n */\nexport function ModalClientContent(props: ModalClientContentProps): ReactElement {\n const {\n align,\n backdrop,\n children,\n defaultOpen = false,\n dismiss,\n onOpenChange,\n onOpenChangeComplete,\n open,\n ref,\n size,\n ...dialogProps\n } = props;\n\n const elementRef = useRef<HTMLDialogElement | null>(null);\n const mergedRef = useMergedRefs<HTMLDialogElement>(elementRef, ref);\n const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);\n // Bumped on every native toggle so the sync effect re-runs after the parent\n // has had its render: a controlling parent that rejected the change is then\n // reconciled by reverting the element.\n const [nativeVersion, recordNativeToggle] = useReducer(increment, 0);\n const controlled = open !== undefined;\n const wantOpen = controlled ? open : uncontrolledOpen;\n\n const wantOpenRef = useRef(wantOpen);\n wantOpenRef.current = wantOpen;\n const onOpenChangeRef = useRef(onOpenChange);\n onOpenChangeRef.current = onOpenChange;\n const onOpenChangeCompleteRef = useRef(onOpenChangeComplete);\n onOpenChangeCompleteRef.current = onOpenChangeComplete;\n // One-shot: has the first-mount reconciliation below already run?\n const reconciledRef = useRef(false);\n\n useEffect(() => {\n const dialog = elementRef.current;\n if (!dialog) return;\n if (!reconciledRef.current) {\n reconciledRef.current = true;\n // SSR markup is always closed. If the dialog is already open at mount,\n // that can only mean a native invoker command opened it in the window\n // between initial paint and this effect running — the `toggle` event\n // fired with no listener attached yet, and that notification is\n // otherwise lost forever. Recover it exactly like a native toggle.\n //\n // The reverse (closed at mount) is never reconciled: it's indistinguishable\n // from \"nothing happened\" versus a pre-hydration open+close cycle that\n // netted back to closed, and it's also the normal starting shape for\n // defaultOpen (open before hydration) is reconciled when the DOM catches up.\n if (dialog.open && !wantOpenRef.current) {\n if (!controlled) setUncontrolledOpen(true);\n onOpenChangeRef.current?.(true);\n // Defer enacting show/close to the next pass, once the controlling\n // parent (if any) has had a chance to react to the report above —\n // the DOM already matches what was just reported, so there is\n // nothing to enact this pass regardless.\n recordNativeToggle();\n return;\n }\n }\n if (wantOpen && !dialog.open) dialog.showModal();\n else if (!wantOpen && dialog.open) {\n closeNestedDialogs(dialog);\n dialog.close();\n }\n // `controlled` is read above (line 66) and must be a dependency; the sibling\n // `toggle`-listener effect below lists it for the same reason.\n }, [nativeVersion, wantOpen, controlled]);\n\n useEffect(() => {\n const dialog = elementRef.current;\n if (!dialog) return;\n let disposed = false;\n const onToggle = (event: Event): void => {\n const next = (event as ToggleEvent).newState === \"open\";\n afterMotion(dialog, () => {\n if (!disposed) onOpenChangeCompleteRef.current?.(next);\n });\n // Programmatic changes already match the desired state; only report\n // changes the browser initiated.\n if (next === wantOpenRef.current) return;\n if (!controlled) setUncontrolledOpen(next);\n onOpenChangeRef.current?.(next);\n recordNativeToggle();\n };\n dialog.addEventListener(\"toggle\", onToggle);\n return () => {\n disposed = true;\n dialog.removeEventListener(\"toggle\", onToggle);\n };\n }, [controlled]);\n\n return (\n <dialog\n {...dialogProps}\n {...modalAppearanceAttributes({ align, backdrop, dismiss, size })}\n data-part=\"content\"\n data-uiify-modal=\"\"\n ref={mergedRef}\n // SSR markup is always closed, but the browser may have already opened this\n // dialog via a native invoker command before hydration (see the effect above,\n // which reconciles exactly that). React's hydration diff otherwise flags the\n // resulting `open` mismatch as an error; it is the documented recovery path.\n suppressHydrationWarning\n >\n {children}\n </dialog>\n );\n}\nModalClientContent.displayName = \"ModalClientContent\";\n"],"mappings":"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","names":[]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { Modal } from "./Modal.js";
|
|
2
|
-
export { ModalClose, ModalContent, ModalTrigger } from "./ModalParts.js";
|
|
3
|
-
export type { ModalCloseOwnProps, ModalCloseProps, ModalContentOwnProps, ModalContentProps, ModalProps, ModalTriggerOwnProps, ModalTriggerProps, } from "./types.js";
|
|
2
|
+
export { ModalBody, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalGrabber, ModalHeader, ModalTitle, ModalTrigger, } from "./ModalParts.js";
|
|
3
|
+
export type { ModalAlign, ModalAppearanceProps, ModalBackdrop, ModalBodyProps, ModalCloseOwnProps, ModalCloseProps, ModalContentOwnProps, ModalContentProps, ModalDescriptionProps, ModalDismiss, ModalFooterProps, ModalGrabberProps, ModalHeaderProps, ModalProps, ModalSize, ModalTitleProps, ModalTriggerOwnProps, ModalTriggerProps, } from "./types.js";
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/modal/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/modal/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EACL,SAAS,EACT,UAAU,EACV,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,WAAW,EACX,UAAU,EACV,YAAY,GACb,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,UAAU,EACV,oBAAoB,EACpB,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,iBAAiB,EACjB,qBAAqB,EACrB,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACV,SAAS,EACT,eAAe,EACf,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
|
|
@@ -1,9 +1,25 @@
|
|
|
1
1
|
import { Modal } from "./Modal.js";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
ModalBody,
|
|
4
|
+
ModalClose,
|
|
5
|
+
ModalContent,
|
|
6
|
+
ModalDescription,
|
|
7
|
+
ModalFooter,
|
|
8
|
+
ModalGrabber,
|
|
9
|
+
ModalHeader,
|
|
10
|
+
ModalTitle,
|
|
11
|
+
ModalTrigger
|
|
12
|
+
} from "./ModalParts.js";
|
|
3
13
|
export {
|
|
4
14
|
Modal,
|
|
15
|
+
ModalBody,
|
|
5
16
|
ModalClose,
|
|
6
17
|
ModalContent,
|
|
18
|
+
ModalDescription,
|
|
19
|
+
ModalFooter,
|
|
20
|
+
ModalGrabber,
|
|
21
|
+
ModalHeader,
|
|
22
|
+
ModalTitle,
|
|
7
23
|
ModalTrigger
|
|
8
24
|
};
|
|
9
25
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/modal/index.ts"],"sourcesContent":["export { Modal } from \"./Modal.js\";\nexport {
|
|
1
|
+
{"version":3,"sources":["../../../src/components/modal/index.ts"],"sourcesContent":["export { Modal } from \"./Modal.js\";\nexport {\n ModalBody,\n ModalClose,\n ModalContent,\n ModalDescription,\n ModalFooter,\n ModalGrabber,\n ModalHeader,\n ModalTitle,\n ModalTrigger,\n} from \"./ModalParts.js\";\nexport type {\n ModalAlign,\n ModalAppearanceProps,\n ModalBackdrop,\n ModalBodyProps,\n ModalCloseOwnProps,\n ModalCloseProps,\n ModalContentOwnProps,\n ModalContentProps,\n ModalDescriptionProps,\n ModalDismiss,\n ModalFooterProps,\n ModalGrabberProps,\n ModalHeaderProps,\n ModalProps,\n ModalSize,\n ModalTitleProps,\n ModalTriggerOwnProps,\n ModalTriggerProps,\n} from \"./types.js\";\n"],"mappings":"AAAA,SAAS,aAAa;AACtB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;","names":[]}
|
|
@@ -1,12 +1,37 @@
|
|
|
1
1
|
import type { ComponentPropsWithRef, ElementType, ReactNode } from "react";
|
|
2
2
|
import type { NativeButtonProps } from "@gunkin/uiify/core/render";
|
|
3
|
-
export
|
|
3
|
+
export type ModalSize = "sm" | "md" | "lg" | "full";
|
|
4
|
+
export type ModalAlign = "center" | "start";
|
|
5
|
+
export type ModalDismiss = "any" | "closerequest" | "none";
|
|
6
|
+
export type ModalBackdrop = "opaque" | "blur" | "none";
|
|
7
|
+
export interface ModalAppearanceProps {
|
|
8
|
+
/** Width step; `full` fills the viewport. Default `md`. */
|
|
9
|
+
readonly size?: ModalSize | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* Vertical position on tablet and desktop; phones get a bottom sheet unless `size` is `full`.
|
|
12
|
+
* Default `center`.
|
|
13
|
+
*/
|
|
14
|
+
readonly align?: ModalAlign | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* Native `closedby`: `any` also closes on a backdrop tap, `closerequest` on Escape only, `none`
|
|
17
|
+
* only through your own controls. Default `any`. Engines without `closedby` (Safari) ignore it:
|
|
18
|
+
* Escape still closes the dialog there, and `UIEnhance` honours it only for its own backdrop
|
|
19
|
+
* tap (`any` only) and sheet swipe (off for `none`).
|
|
20
|
+
*/
|
|
21
|
+
readonly dismiss?: ModalDismiss | undefined;
|
|
22
|
+
/** Backdrop treatment. Default `opaque`. */
|
|
23
|
+
readonly backdrop?: ModalBackdrop | undefined;
|
|
24
|
+
}
|
|
25
|
+
export interface ModalProps extends ModalAppearanceProps {
|
|
4
26
|
readonly id: string;
|
|
5
27
|
readonly trigger: ReactNode;
|
|
6
28
|
readonly title: ReactNode;
|
|
7
29
|
readonly description?: ReactNode;
|
|
8
30
|
readonly children?: ReactNode;
|
|
9
|
-
|
|
31
|
+
/** Accessible name of the header close icon. */
|
|
32
|
+
readonly closeLabel?: string;
|
|
33
|
+
/** Actions row pinned under the body. */
|
|
34
|
+
readonly footer?: ReactNode;
|
|
10
35
|
readonly className?: string;
|
|
11
36
|
}
|
|
12
37
|
/** Own props of the native `show-modal` invoker. */
|
|
@@ -23,20 +48,15 @@ export interface ModalCloseOwnProps {
|
|
|
23
48
|
readonly target: string;
|
|
24
49
|
}
|
|
25
50
|
export type ModalCloseProps<TAs extends ElementType = "button"> = NativeButtonProps<TAs, ModalCloseOwnProps>;
|
|
26
|
-
export interface ModalContentOwnProps {
|
|
51
|
+
export interface ModalContentOwnProps extends ModalAppearanceProps {
|
|
27
52
|
readonly children?: ReactNode;
|
|
28
53
|
/** Unique id supplied by the consumer; referenced by trigger and close `target`. */
|
|
29
54
|
readonly id: string;
|
|
30
55
|
}
|
|
31
56
|
/** A plain, initially closed `<dialog>`: `open` and `popover` are not part of the native contract. */
|
|
32
|
-
export type ModalContentProps = ModalContentOwnProps & Omit<ComponentPropsWithRef<"dialog">, keyof ModalContentOwnProps | "open" | "popover">;
|
|
33
|
-
export interface ModalClientContentOwnProps {
|
|
57
|
+
export type ModalContentProps = ModalContentOwnProps & Omit<ComponentPropsWithRef<"dialog">, keyof ModalContentOwnProps | "open" | "popover" | "closedby">;
|
|
58
|
+
export interface ModalClientContentOwnProps extends ModalAppearanceProps {
|
|
34
59
|
readonly children?: ReactNode;
|
|
35
|
-
/**
|
|
36
|
-
* Close when the backdrop is clicked — a click whose target is the `<dialog>`
|
|
37
|
-
* itself, not one of its children. Default `false` (matches the native parts).
|
|
38
|
-
*/
|
|
39
|
-
readonly closeOnBackdropClick?: boolean;
|
|
40
60
|
/** Uncontrolled initial state, applied with `showModal()` after hydration; SSR markup stays closed. */
|
|
41
61
|
readonly defaultOpen?: boolean;
|
|
42
62
|
readonly id: string;
|
|
@@ -48,9 +68,21 @@ export interface ModalClientContentOwnProps {
|
|
|
48
68
|
* is no evidence left that a transition happened at all.
|
|
49
69
|
*/
|
|
50
70
|
readonly onOpenChange?: (open: boolean) => void;
|
|
71
|
+
/**
|
|
72
|
+
* Fires once per open or close transition, after the dialog's CSS transitions have
|
|
73
|
+
* finished (immediately when there are none). This includes the transition that applies
|
|
74
|
+
* `defaultOpen` after hydration; it does not fire for a dialog that never changes state.
|
|
75
|
+
*/
|
|
76
|
+
readonly onOpenChangeComplete?: (open: boolean) => void;
|
|
51
77
|
/** Controlled state, authoritative after hydration. */
|
|
52
78
|
readonly open?: boolean;
|
|
53
79
|
}
|
|
54
80
|
/** Props of the client adapter; `popover` is excluded because the adapter is always modal. */
|
|
55
|
-
export type ModalClientContentProps = ModalClientContentOwnProps & Omit<ComponentPropsWithRef<"dialog">, keyof ModalClientContentOwnProps | "popover">;
|
|
81
|
+
export type ModalClientContentProps = ModalClientContentOwnProps & Omit<ComponentPropsWithRef<"dialog">, keyof ModalClientContentOwnProps | "popover" | "closedby">;
|
|
82
|
+
export type ModalHeaderProps = ComponentPropsWithRef<"div">;
|
|
83
|
+
export type ModalTitleProps = ComponentPropsWithRef<"h2">;
|
|
84
|
+
export type ModalDescriptionProps = ComponentPropsWithRef<"p">;
|
|
85
|
+
export type ModalBodyProps = ComponentPropsWithRef<"div">;
|
|
86
|
+
export type ModalFooterProps = ComponentPropsWithRef<"div">;
|
|
87
|
+
export type ModalGrabberProps = Omit<ComponentPropsWithRef<"div">, "children">;
|
|
56
88
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/modal/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,MAAM,WAAW,UAAU;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/modal/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,7 +19,7 @@ function NumberFieldRoot(props) {
|
|
|
19
19
|
render,
|
|
20
20
|
value: controlledValue,
|
|
21
21
|
defaultValue,
|
|
22
|
-
|
|
22
|
+
onValueChange,
|
|
23
23
|
min,
|
|
24
24
|
max,
|
|
25
25
|
step = 1,
|
|
@@ -36,7 +36,7 @@ function NumberFieldRoot(props) {
|
|
|
36
36
|
const [value, setValue] = useControllableState({
|
|
37
37
|
value: controlledValue,
|
|
38
38
|
defaultValue,
|
|
39
|
-
onChange
|
|
39
|
+
onChange: onValueChange
|
|
40
40
|
});
|
|
41
41
|
const [editing, setEditing] = useState(false);
|
|
42
42
|
const [displayValue, setDisplayValue] = useState(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/number-field/NumberField.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useCallback,\n useMemo,\n useRef,\n useState,\n type ElementType,\n type FocusEvent,\n type KeyboardEvent,\n type ReactElement,\n type ReactNode,\n type SyntheticEvent,\n} from \"react\";\nimport { useControllableState, useId } from \"@gunkin/uiify/hooks\";\nimport { createPartContext } from \"@gunkin/uiify/core\";\nimport { composeEventHandlers } from \"@gunkin/uiify/core/compose-event-handlers\";\nimport { useRenderElement, type PolymorphicProps } from \"@gunkin/uiify/core/render\";\nimport { clampNumber, createFormatter, formatNumber, parseNumber, stepNumber } from \"./format.js\";\nimport { usePressRepeat } from \"./use-press-repeat.js\";\nimport type {\n NumberFieldContextValue,\n NumberFieldRootProps,\n NumberFieldGroupProps,\n NumberFieldInputProps,\n NumberFieldIncrementProps,\n NumberFieldDecrementProps,\n} from \"./types.js\";\n\nexport type {\n NumberFieldDecrementProps,\n NumberFieldGroupProps,\n NumberFieldIncrementProps,\n NumberFieldInputProps,\n NumberFieldRootOwnProps,\n NumberFieldRootProps,\n} from \"./types.js\";\n\nconst [NumberFieldProvider, useNumberFieldContext] =\n createPartContext<NumberFieldContextValue>(\"NumberField\");\n\nexport function NumberFieldRoot<TAs extends ElementType = \"div\">(\n props: NumberFieldRootProps<TAs>,\n): ReactElement | null {\n const {\n as,\n render,\n value: controlledValue,\n defaultValue,\n onChange,\n min,\n max,\n step = 1,\n formatOptions,\n clampValueOnBlur = true,\n disabled = false,\n readOnly = false,\n required = false,\n ...consumerProps\n } = props as NumberFieldRootProps<ElementType>;\n\n const inputId = useId();\n const inputRef = useRef<HTMLInputElement>(null);\n const formatter = useMemo(() => createFormatter(formatOptions), [formatOptions]);\n const [value, setValue] = useControllableState<number | undefined>({\n value: controlledValue,\n defaultValue,\n onChange,\n });\n const [editing, setEditing] = useState(false);\n const [displayValue, setDisplayValue] = useState(() =>\n value === undefined ? \"\" : formatNumber(value, formatter),\n );\n\n const syncDisplay = useCallback(\n (next: number | undefined) => {\n setDisplayValue(next === undefined ? \"\" : formatNumber(next, formatter));\n },\n [formatter],\n );\n\n const applyValue = useCallback(\n (next: number | undefined) => {\n const clamped =\n next === undefined ? undefined : clampValueOnBlur ? clampNumber(next, min, max) : next;\n setValue(clamped);\n syncDisplay(clamped);\n },\n [clampValueOnBlur, max, min, setValue, syncDisplay],\n );\n\n const increment = useCallback(\n (multiplier = 1) => {\n if (disabled || readOnly) return;\n const base = value ?? min ?? 0;\n applyValue(stepNumber(base, multiplier, step, min, max));\n },\n [applyValue, disabled, max, min, readOnly, step, value],\n );\n\n const decrement = useCallback(\n (multiplier = 1) => {\n increment(-multiplier);\n },\n [increment],\n );\n\n const commitInput = useCallback(\n (raw: string) => {\n const parsed = parseNumber(raw, formatter);\n if (parsed === undefined) {\n syncDisplay(value);\n return;\n }\n applyValue(parsed);\n },\n [applyValue, formatter, syncDisplay, value],\n );\n\n const contextValue = useMemo<NumberFieldContextValue>(\n () => ({\n clampValueOnBlur,\n commitInput,\n decrement,\n disabled,\n displayValue: editing\n ? displayValue\n : value === undefined\n ? \"\"\n : formatNumber(value, formatter),\n formatter,\n increment,\n inputId,\n inputRef,\n max,\n min,\n numericValue: value,\n readOnly,\n required,\n setDisplayValue,\n setEditing,\n step,\n }),\n [\n clampValueOnBlur,\n commitInput,\n decrement,\n disabled,\n displayValue,\n editing,\n formatter,\n increment,\n inputId,\n max,\n min,\n readOnly,\n required,\n step,\n value,\n ],\n );\n\n const element = useRenderElement({\n as,\n defaultTag: \"div\",\n props: {\n ...consumerProps,\n \"data-disabled\": disabled ? \"\" : undefined,\n \"data-uiify-number-field\": \"\",\n },\n render,\n state: { disabled, readOnly, required },\n });\n\n return <NumberFieldProvider value={contextValue}>{element}</NumberFieldProvider>;\n}\nNumberFieldRoot.displayName = \"NumberFieldRoot\";\n\nexport function NumberFieldGroup<TAs extends ElementType = \"div\">(\n props: NumberFieldGroupProps<TAs>,\n): ReactElement | null {\n const { as, render, ...consumerProps } = props as NumberFieldGroupProps<ElementType>;\n const { disabled } = useNumberFieldContext(\"Group\");\n\n return useRenderElement({\n as,\n defaultTag: \"div\",\n props: { ...consumerProps, \"data-disabled\": disabled ? \"\" : undefined },\n render,\n state: { disabled },\n });\n}\n\nexport function NumberFieldInput<TAs extends ElementType = \"input\">(\n props: NumberFieldInputProps<TAs>,\n): ReactElement | null {\n const { as, render, ...consumerProps } = props as NumberFieldInputProps<\"input\">;\n const {\n commitInput,\n decrement,\n disabled,\n displayValue,\n increment,\n inputId,\n inputRef,\n max,\n min,\n numericValue,\n readOnly,\n required,\n setDisplayValue,\n setEditing,\n } = useNumberFieldContext(\"Input\");\n\n const onKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n if (disabled || readOnly) return;\n switch (event.key) {\n case \"ArrowUp\":\n event.preventDefault();\n increment();\n break;\n case \"ArrowDown\":\n event.preventDefault();\n decrement();\n break;\n case \"PageUp\":\n event.preventDefault();\n increment(10);\n break;\n case \"PageDown\":\n event.preventDefault();\n decrement(10);\n break;\n case \"Home\":\n event.preventDefault();\n if (min !== undefined) commitInput(String(min));\n break;\n case \"End\":\n event.preventDefault();\n if (max !== undefined) commitInput(String(max));\n break;\n default:\n break;\n }\n };\n\n return useRenderElement({\n as,\n defaultTag: \"input\",\n props: {\n ...consumerProps,\n id: inputId,\n ref: inputRef,\n role: \"spinbutton\",\n inputMode: \"decimal\",\n \"aria-valuenow\": numericValue,\n \"aria-valuemin\": min,\n \"aria-valuemax\": max,\n \"aria-required\": required || undefined,\n \"data-disabled\": disabled ? \"\" : undefined,\n \"data-readonly\": readOnly ? \"\" : undefined,\n disabled: disabled || undefined,\n readOnly: readOnly || undefined,\n required: required || undefined,\n value: displayValue,\n onFocus: composeEventHandlers(consumerProps.onFocus, () => setEditing(true)),\n onBlur: composeEventHandlers(consumerProps.onBlur, (event: FocusEvent<HTMLInputElement>) => {\n setEditing(false);\n commitInput(event.currentTarget.value);\n }),\n onChange: composeEventHandlers(\n consumerProps.onChange,\n (event: SyntheticEvent<HTMLInputElement>) => {\n setDisplayValue(event.currentTarget.value);\n },\n ),\n onKeyDown: composeEventHandlers(consumerProps.onKeyDown, onKeyDown),\n },\n render,\n state: { disabled, readOnly, required },\n });\n}\n\nexport function NumberFieldIncrement<TAs extends ElementType = \"button\">(\n props: NumberFieldIncrementProps<TAs>,\n): ReactElement | null {\n const { as, render, ...consumerProps } = props as PolymorphicProps<\n \"button\",\n { readonly children?: ReactNode }\n >;\n const { disabled, increment, readOnly } = useNumberFieldContext(\"Increment\");\n const inactive = disabled || readOnly;\n const repeatProps = usePressRepeat(() => increment(), inactive);\n\n return useRenderElement({\n as,\n defaultTag: \"button\",\n props: {\n ...consumerProps,\n type: \"button\",\n tabIndex: -1,\n \"data-disabled\": inactive ? \"\" : undefined,\n disabled: inactive || undefined,\n onClick: composeEventHandlers(consumerProps.onClick, () => increment()),\n onPointerDown: composeEventHandlers(consumerProps.onPointerDown, repeatProps.onPointerDown),\n onPointerUp: composeEventHandlers(consumerProps.onPointerUp, repeatProps.onPointerUp),\n onPointerLeave: composeEventHandlers(\n consumerProps.onPointerLeave,\n repeatProps.onPointerLeave,\n ),\n onPointerCancel: composeEventHandlers(\n consumerProps.onPointerCancel,\n repeatProps.onPointerCancel,\n ),\n },\n render,\n state: { disabled: inactive },\n });\n}\n\nexport function NumberFieldDecrement<TAs extends ElementType = \"button\">(\n props: NumberFieldDecrementProps<TAs>,\n): ReactElement | null {\n const { as, render, ...consumerProps } = props as PolymorphicProps<\n \"button\",\n { readonly children?: ReactNode }\n >;\n const { decrement, disabled, readOnly } = useNumberFieldContext(\"Decrement\");\n const inactive = disabled || readOnly;\n const repeatProps = usePressRepeat(() => decrement(), inactive);\n\n return useRenderElement({\n as,\n defaultTag: \"button\",\n props: {\n ...consumerProps,\n type: \"button\",\n tabIndex: -1,\n \"data-disabled\": inactive ? \"\" : undefined,\n disabled: inactive || undefined,\n onClick: composeEventHandlers(consumerProps.onClick, () => decrement()),\n onPointerDown: composeEventHandlers(consumerProps.onPointerDown, repeatProps.onPointerDown),\n onPointerUp: composeEventHandlers(consumerProps.onPointerUp, repeatProps.onPointerUp),\n onPointerLeave: composeEventHandlers(\n consumerProps.onPointerLeave,\n repeatProps.onPointerLeave,\n ),\n onPointerCancel: composeEventHandlers(\n consumerProps.onPointerCancel,\n repeatProps.onPointerCancel,\n ),\n },\n render,\n state: { disabled: inactive },\n });\n}\n\nexport const NumberField = {\n Root: NumberFieldRoot,\n Group: NumberFieldGroup,\n Input: NumberFieldInput,\n Increment: NumberFieldIncrement,\n Decrement: NumberFieldDecrement,\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/number-field/NumberField.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useCallback,\n useMemo,\n useRef,\n useState,\n type ElementType,\n type FocusEvent,\n type KeyboardEvent,\n type ReactElement,\n type ReactNode,\n type SyntheticEvent,\n} from \"react\";\nimport { useControllableState, useId } from \"@gunkin/uiify/hooks\";\nimport { createPartContext } from \"@gunkin/uiify/core\";\nimport { composeEventHandlers } from \"@gunkin/uiify/core/compose-event-handlers\";\nimport { useRenderElement, type PolymorphicProps } from \"@gunkin/uiify/core/render\";\nimport { clampNumber, createFormatter, formatNumber, parseNumber, stepNumber } from \"./format.js\";\nimport { usePressRepeat } from \"./use-press-repeat.js\";\nimport type {\n NumberFieldContextValue,\n NumberFieldRootProps,\n NumberFieldGroupProps,\n NumberFieldInputProps,\n NumberFieldIncrementProps,\n NumberFieldDecrementProps,\n} from \"./types.js\";\n\nexport type {\n NumberFieldDecrementProps,\n NumberFieldGroupProps,\n NumberFieldIncrementProps,\n NumberFieldInputProps,\n NumberFieldRootOwnProps,\n NumberFieldRootProps,\n} from \"./types.js\";\n\nconst [NumberFieldProvider, useNumberFieldContext] =\n createPartContext<NumberFieldContextValue>(\"NumberField\");\n\nexport function NumberFieldRoot<TAs extends ElementType = \"div\">(\n props: NumberFieldRootProps<TAs>,\n): ReactElement | null {\n const {\n as,\n render,\n value: controlledValue,\n defaultValue,\n onValueChange,\n min,\n max,\n step = 1,\n formatOptions,\n clampValueOnBlur = true,\n disabled = false,\n readOnly = false,\n required = false,\n ...consumerProps\n } = props as NumberFieldRootProps<ElementType>;\n\n const inputId = useId();\n const inputRef = useRef<HTMLInputElement>(null);\n const formatter = useMemo(() => createFormatter(formatOptions), [formatOptions]);\n const [value, setValue] = useControllableState<number | undefined>({\n value: controlledValue,\n defaultValue,\n onChange: onValueChange,\n });\n const [editing, setEditing] = useState(false);\n const [displayValue, setDisplayValue] = useState(() =>\n value === undefined ? \"\" : formatNumber(value, formatter),\n );\n\n const syncDisplay = useCallback(\n (next: number | undefined) => {\n setDisplayValue(next === undefined ? \"\" : formatNumber(next, formatter));\n },\n [formatter],\n );\n\n const applyValue = useCallback(\n (next: number | undefined) => {\n const clamped =\n next === undefined ? undefined : clampValueOnBlur ? clampNumber(next, min, max) : next;\n setValue(clamped);\n syncDisplay(clamped);\n },\n [clampValueOnBlur, max, min, setValue, syncDisplay],\n );\n\n const increment = useCallback(\n (multiplier = 1) => {\n if (disabled || readOnly) return;\n const base = value ?? min ?? 0;\n applyValue(stepNumber(base, multiplier, step, min, max));\n },\n [applyValue, disabled, max, min, readOnly, step, value],\n );\n\n const decrement = useCallback(\n (multiplier = 1) => {\n increment(-multiplier);\n },\n [increment],\n );\n\n const commitInput = useCallback(\n (raw: string) => {\n const parsed = parseNumber(raw, formatter);\n if (parsed === undefined) {\n syncDisplay(value);\n return;\n }\n applyValue(parsed);\n },\n [applyValue, formatter, syncDisplay, value],\n );\n\n const contextValue = useMemo<NumberFieldContextValue>(\n () => ({\n clampValueOnBlur,\n commitInput,\n decrement,\n disabled,\n displayValue: editing\n ? displayValue\n : value === undefined\n ? \"\"\n : formatNumber(value, formatter),\n formatter,\n increment,\n inputId,\n inputRef,\n max,\n min,\n numericValue: value,\n readOnly,\n required,\n setDisplayValue,\n setEditing,\n step,\n }),\n [\n clampValueOnBlur,\n commitInput,\n decrement,\n disabled,\n displayValue,\n editing,\n formatter,\n increment,\n inputId,\n max,\n min,\n readOnly,\n required,\n step,\n value,\n ],\n );\n\n const element = useRenderElement({\n as,\n defaultTag: \"div\",\n props: {\n ...consumerProps,\n \"data-disabled\": disabled ? \"\" : undefined,\n \"data-uiify-number-field\": \"\",\n },\n render,\n state: { disabled, readOnly, required },\n });\n\n return <NumberFieldProvider value={contextValue}>{element}</NumberFieldProvider>;\n}\nNumberFieldRoot.displayName = \"NumberFieldRoot\";\n\nexport function NumberFieldGroup<TAs extends ElementType = \"div\">(\n props: NumberFieldGroupProps<TAs>,\n): ReactElement | null {\n const { as, render, ...consumerProps } = props as NumberFieldGroupProps<ElementType>;\n const { disabled } = useNumberFieldContext(\"Group\");\n\n return useRenderElement({\n as,\n defaultTag: \"div\",\n props: { ...consumerProps, \"data-disabled\": disabled ? \"\" : undefined },\n render,\n state: { disabled },\n });\n}\n\nexport function NumberFieldInput<TAs extends ElementType = \"input\">(\n props: NumberFieldInputProps<TAs>,\n): ReactElement | null {\n const { as, render, ...consumerProps } = props as NumberFieldInputProps<\"input\">;\n const {\n commitInput,\n decrement,\n disabled,\n displayValue,\n increment,\n inputId,\n inputRef,\n max,\n min,\n numericValue,\n readOnly,\n required,\n setDisplayValue,\n setEditing,\n } = useNumberFieldContext(\"Input\");\n\n const onKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n if (disabled || readOnly) return;\n switch (event.key) {\n case \"ArrowUp\":\n event.preventDefault();\n increment();\n break;\n case \"ArrowDown\":\n event.preventDefault();\n decrement();\n break;\n case \"PageUp\":\n event.preventDefault();\n increment(10);\n break;\n case \"PageDown\":\n event.preventDefault();\n decrement(10);\n break;\n case \"Home\":\n event.preventDefault();\n if (min !== undefined) commitInput(String(min));\n break;\n case \"End\":\n event.preventDefault();\n if (max !== undefined) commitInput(String(max));\n break;\n default:\n break;\n }\n };\n\n return useRenderElement({\n as,\n defaultTag: \"input\",\n props: {\n ...consumerProps,\n id: inputId,\n ref: inputRef,\n role: \"spinbutton\",\n inputMode: \"decimal\",\n \"aria-valuenow\": numericValue,\n \"aria-valuemin\": min,\n \"aria-valuemax\": max,\n \"aria-required\": required || undefined,\n \"data-disabled\": disabled ? \"\" : undefined,\n \"data-readonly\": readOnly ? \"\" : undefined,\n disabled: disabled || undefined,\n readOnly: readOnly || undefined,\n required: required || undefined,\n value: displayValue,\n onFocus: composeEventHandlers(consumerProps.onFocus, () => setEditing(true)),\n onBlur: composeEventHandlers(consumerProps.onBlur, (event: FocusEvent<HTMLInputElement>) => {\n setEditing(false);\n commitInput(event.currentTarget.value);\n }),\n onChange: composeEventHandlers(\n consumerProps.onChange,\n (event: SyntheticEvent<HTMLInputElement>) => {\n setDisplayValue(event.currentTarget.value);\n },\n ),\n onKeyDown: composeEventHandlers(consumerProps.onKeyDown, onKeyDown),\n },\n render,\n state: { disabled, readOnly, required },\n });\n}\n\nexport function NumberFieldIncrement<TAs extends ElementType = \"button\">(\n props: NumberFieldIncrementProps<TAs>,\n): ReactElement | null {\n const { as, render, ...consumerProps } = props as PolymorphicProps<\n \"button\",\n { readonly children?: ReactNode }\n >;\n const { disabled, increment, readOnly } = useNumberFieldContext(\"Increment\");\n const inactive = disabled || readOnly;\n const repeatProps = usePressRepeat(() => increment(), inactive);\n\n return useRenderElement({\n as,\n defaultTag: \"button\",\n props: {\n ...consumerProps,\n type: \"button\",\n tabIndex: -1,\n \"data-disabled\": inactive ? \"\" : undefined,\n disabled: inactive || undefined,\n onClick: composeEventHandlers(consumerProps.onClick, () => increment()),\n onPointerDown: composeEventHandlers(consumerProps.onPointerDown, repeatProps.onPointerDown),\n onPointerUp: composeEventHandlers(consumerProps.onPointerUp, repeatProps.onPointerUp),\n onPointerLeave: composeEventHandlers(\n consumerProps.onPointerLeave,\n repeatProps.onPointerLeave,\n ),\n onPointerCancel: composeEventHandlers(\n consumerProps.onPointerCancel,\n repeatProps.onPointerCancel,\n ),\n },\n render,\n state: { disabled: inactive },\n });\n}\n\nexport function NumberFieldDecrement<TAs extends ElementType = \"button\">(\n props: NumberFieldDecrementProps<TAs>,\n): ReactElement | null {\n const { as, render, ...consumerProps } = props as PolymorphicProps<\n \"button\",\n { readonly children?: ReactNode }\n >;\n const { decrement, disabled, readOnly } = useNumberFieldContext(\"Decrement\");\n const inactive = disabled || readOnly;\n const repeatProps = usePressRepeat(() => decrement(), inactive);\n\n return useRenderElement({\n as,\n defaultTag: \"button\",\n props: {\n ...consumerProps,\n type: \"button\",\n tabIndex: -1,\n \"data-disabled\": inactive ? \"\" : undefined,\n disabled: inactive || undefined,\n onClick: composeEventHandlers(consumerProps.onClick, () => decrement()),\n onPointerDown: composeEventHandlers(consumerProps.onPointerDown, repeatProps.onPointerDown),\n onPointerUp: composeEventHandlers(consumerProps.onPointerUp, repeatProps.onPointerUp),\n onPointerLeave: composeEventHandlers(\n consumerProps.onPointerLeave,\n repeatProps.onPointerLeave,\n ),\n onPointerCancel: composeEventHandlers(\n consumerProps.onPointerCancel,\n repeatProps.onPointerCancel,\n ),\n },\n render,\n state: { disabled: inactive },\n });\n}\n\nexport const NumberField = {\n Root: NumberFieldRoot,\n Group: NumberFieldGroup,\n Input: NumberFieldInput,\n Increment: NumberFieldIncrement,\n Decrement: NumberFieldDecrement,\n};\n"],"mappings":"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","names":[]}
|
|
@@ -26,7 +26,7 @@ export interface NumberFieldRootOwnProps {
|
|
|
26
26
|
readonly formatOptions?: Intl.NumberFormatOptions;
|
|
27
27
|
readonly max?: number;
|
|
28
28
|
readonly min?: number;
|
|
29
|
-
readonly
|
|
29
|
+
readonly onValueChange?: (value: number | undefined) => void;
|
|
30
30
|
readonly readOnly?: boolean;
|
|
31
31
|
readonly required?: boolean;
|
|
32
32
|
readonly step?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/number-field/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAEjE,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,QAAQ,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC;IACtC,QAAQ,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IACtD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,QAAQ,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CAC9C;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IACpC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,aAAa,CAAC,EAAE,IAAI,CAAC,mBAAmB,CAAC;IAClD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/number-field/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,7 +22,7 @@ function OtpInputRoot(props) {
|
|
|
22
22
|
length = 6,
|
|
23
23
|
value: controlledValue,
|
|
24
24
|
defaultValue = "",
|
|
25
|
-
|
|
25
|
+
onValueChange,
|
|
26
26
|
onComplete,
|
|
27
27
|
type = "numeric",
|
|
28
28
|
mask = false,
|
|
@@ -35,7 +35,7 @@ function OtpInputRoot(props) {
|
|
|
35
35
|
const [value, setValue] = useControllableState({
|
|
36
36
|
value: controlledValue,
|
|
37
37
|
defaultValue,
|
|
38
|
-
onChange
|
|
38
|
+
onChange: onValueChange
|
|
39
39
|
});
|
|
40
40
|
const updateValue = useCallback(
|
|
41
41
|
(nextRaw) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/otp-input/OtpInput.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useCallback,\n useMemo,\n useRef,\n useState,\n type ClipboardEvent,\n type CSSProperties,\n type ElementType,\n type KeyboardEvent,\n type ReactElement,\n type SyntheticEvent,\n} from \"react\";\nimport { useControllableState, useId } from \"@gunkin/uiify/hooks\";\nimport { createPartContext } from \"@gunkin/uiify/core\";\nimport { composeEventHandlers } from \"@gunkin/uiify/core/compose-event-handlers\";\nimport { useRenderElement } from \"@gunkin/uiify/core/render\";\nimport type { PolymorphicProps } from \"@gunkin/uiify/core/render\";\nimport type {\n OtpInputType,\n OtpInputContextValue,\n OtpInputRootProps,\n OtpInputSlotProps,\n OtpInputHiddenInputProps,\n} from \"./types.js\";\n\nconst [OtpInputProvider, useOtpInputContext] = createPartContext<OtpInputContextValue>(\"OtpInput\");\n\nfunction sanitizeValue(raw: string, type: OtpInputType, maxLength: number): string {\n const pattern = type === \"numeric\" ? /\\d/g : /[a-zA-Z0-9]/g;\n return (raw.match(pattern) ?? []).join(\"\").slice(0, maxLength);\n}\n\nexport function OtpInputRoot<TAs extends ElementType = \"div\">(\n props: OtpInputRootProps<TAs>,\n): ReactElement | null {\n const {\n as,\n render,\n length = 6,\n value: controlledValue,\n defaultValue = \"\",\n onChange,\n onComplete,\n type = \"numeric\",\n mask = false,\n disabled = false,\n autoFocus = false,\n ...consumerProps\n } = props as OtpInputRootProps<ElementType>;\n\n const hiddenInputRef = useRef<HTMLInputElement>(null);\n const [focused, setFocused] = useState(false);\n const [value, setValue] = useControllableState<string>({\n value: controlledValue,\n defaultValue,\n onChange,\n });\n\n const updateValue = useCallback(\n (nextRaw: string) => {\n const next = sanitizeValue(nextRaw, type, length);\n setValue(next);\n if (next.length === length) onComplete?.(next);\n },\n [length, onComplete, setValue, type],\n );\n\n const { onClick: consumerOnClick } = consumerProps as {\n onClick?: (event: SyntheticEvent<HTMLElement>) => void;\n };\n\n const handleClick = () => hiddenInputRef.current?.focus();\n\n const activeIndex = focused ? Math.min(value.length, length - 1) : -1;\n const contextValue = useMemo<OtpInputContextValue>(\n () => ({\n activeIndex,\n autoFocus,\n disabled,\n hiddenInputRef,\n length,\n mask,\n onHiddenBlur: () => setFocused(false),\n onHiddenFocus: () => setFocused(true),\n type,\n updateValue,\n value,\n }),\n [activeIndex, autoFocus, disabled, length, mask, type, updateValue, value],\n );\n\n const element = useRenderElement({\n as,\n defaultTag: \"div\",\n props: {\n ...consumerProps,\n \"data-uiify-otp-input\": \"\",\n \"data-disabled\": disabled ? \"\" : undefined,\n \"data-complete\": value.length === length ? \"\" : undefined,\n onClick: composeEventHandlers(consumerOnClick, handleClick),\n },\n render,\n state: { disabled, mask, type },\n });\n\n return <OtpInputProvider value={contextValue}>{element}</OtpInputProvider>;\n}\nOtpInputRoot.displayName = \"OtpInputRoot\";\n\nexport function OtpInputSlot<TAs extends ElementType = \"div\">(\n props: OtpInputSlotProps<TAs>,\n): ReactElement | null {\n const { as, render, index, ...consumerProps } = props as OtpInputSlotProps<ElementType>;\n const { activeIndex, disabled, length, mask, value } = useOtpInputContext(\"Slot\");\n\n if (index < 0 || index >= length) {\n throw new Error(`OtpInput.Slot index ${index} is out of range for length ${length}`);\n }\n\n const char = value[index] ?? \"\";\n const active = activeIndex === index;\n const filled = char !== \"\";\n\n return useRenderElement({\n as,\n defaultTag: \"div\",\n props: {\n ...consumerProps,\n \"aria-hidden\": true,\n \"data-part\": \"slot\",\n \"data-active\": active ? \"\" : undefined,\n \"data-disabled\": disabled ? \"\" : undefined,\n \"data-filled\": filled ? \"\" : undefined,\n \"data-index\": index,\n children: mask && filled ? \"•\" : char,\n },\n render,\n state: { active, filled },\n });\n}\n\nexport function OtpInputHiddenInput<TAs extends ElementType = \"input\">(\n props: OtpInputHiddenInputProps<TAs>,\n): ReactElement | null {\n const {\n as,\n render,\n autoFocus: autoFocusProp,\n style: consumerStyle,\n ...consumerProps\n } = props as PolymorphicProps<\"input\", { readonly autoFocus?: boolean }>;\n\n const {\n autoFocus: rootAutoFocus,\n disabled,\n hiddenInputRef,\n length,\n mask,\n onHiddenBlur,\n onHiddenFocus,\n type,\n updateValue,\n value,\n } = useOtpInputContext(\"HiddenInput\");\n const inputId = useId();\n const autoFocus = autoFocusProp ?? rootAutoFocus;\n const {\n onBlur: consumerOnBlur,\n onChange: consumerOnChange,\n onFocus: consumerOnFocus,\n onKeyDown: consumerOnKeyDown,\n onPaste: consumerOnPaste,\n } = consumerProps as {\n onBlur?: (event: SyntheticEvent<HTMLInputElement>) => void;\n onChange?: (event: SyntheticEvent<HTMLInputElement>) => void;\n onFocus?: (event: SyntheticEvent<HTMLInputElement>) => void;\n onKeyDown?: (event: KeyboardEvent<HTMLInputElement>) => void;\n onPaste?: (event: ClipboardEvent<HTMLInputElement>) => void;\n };\n\n const handleChange = (event: SyntheticEvent<HTMLInputElement>) => {\n updateValue(event.currentTarget.value);\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n if (event.key === \"Backspace\" && value.length > 0) {\n event.preventDefault();\n updateValue(value.slice(0, -1));\n }\n };\n\n const handlePaste = (event: ClipboardEvent<HTMLInputElement>) => {\n event.preventDefault();\n updateValue(event.clipboardData.getData(\"text\"));\n };\n\n return useRenderElement({\n as,\n defaultTag: \"input\",\n props: {\n ...consumerProps,\n \"data-part\": \"control\",\n id: inputId,\n ref: hiddenInputRef,\n type: mask ? \"password\" : \"text\",\n inputMode: type === \"numeric\" ? \"numeric\" : \"text\",\n autoComplete: \"one-time-code\",\n autoFocus: autoFocus || undefined,\n disabled: disabled || undefined,\n \"aria-label\": \"One-time code\",\n value,\n maxLength: length,\n onChange: composeEventHandlers(consumerOnChange, handleChange),\n onFocus: composeEventHandlers(consumerOnFocus, onHiddenFocus),\n onBlur: composeEventHandlers(consumerOnBlur, onHiddenBlur),\n onKeyDown: composeEventHandlers(consumerOnKeyDown, handleKeyDown),\n onPaste: composeEventHandlers(consumerOnPaste, handlePaste),\n style: {\n ...consumerStyle,\n position: \"absolute\",\n opacity: 0,\n pointerEvents: \"none\",\n width: 1,\n height: 1,\n } as CSSProperties,\n },\n render,\n state: { disabled },\n });\n}\n\nexport const OtpInput = {\n Root: OtpInputRoot,\n Slot: OtpInputSlot,\n HiddenInput: OtpInputHiddenInput,\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/otp-input/OtpInput.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useCallback,\n useMemo,\n useRef,\n useState,\n type ClipboardEvent,\n type CSSProperties,\n type ElementType,\n type KeyboardEvent,\n type ReactElement,\n type SyntheticEvent,\n} from \"react\";\nimport { useControllableState, useId } from \"@gunkin/uiify/hooks\";\nimport { createPartContext } from \"@gunkin/uiify/core\";\nimport { composeEventHandlers } from \"@gunkin/uiify/core/compose-event-handlers\";\nimport { useRenderElement } from \"@gunkin/uiify/core/render\";\nimport type { PolymorphicProps } from \"@gunkin/uiify/core/render\";\nimport type {\n OtpInputType,\n OtpInputContextValue,\n OtpInputRootProps,\n OtpInputSlotProps,\n OtpInputHiddenInputProps,\n} from \"./types.js\";\n\nconst [OtpInputProvider, useOtpInputContext] = createPartContext<OtpInputContextValue>(\"OtpInput\");\n\nfunction sanitizeValue(raw: string, type: OtpInputType, maxLength: number): string {\n const pattern = type === \"numeric\" ? /\\d/g : /[a-zA-Z0-9]/g;\n return (raw.match(pattern) ?? []).join(\"\").slice(0, maxLength);\n}\n\nexport function OtpInputRoot<TAs extends ElementType = \"div\">(\n props: OtpInputRootProps<TAs>,\n): ReactElement | null {\n const {\n as,\n render,\n length = 6,\n value: controlledValue,\n defaultValue = \"\",\n onValueChange,\n onComplete,\n type = \"numeric\",\n mask = false,\n disabled = false,\n autoFocus = false,\n ...consumerProps\n } = props as OtpInputRootProps<ElementType>;\n\n const hiddenInputRef = useRef<HTMLInputElement>(null);\n const [focused, setFocused] = useState(false);\n const [value, setValue] = useControllableState<string>({\n value: controlledValue,\n defaultValue,\n onChange: onValueChange,\n });\n\n const updateValue = useCallback(\n (nextRaw: string) => {\n const next = sanitizeValue(nextRaw, type, length);\n setValue(next);\n if (next.length === length) onComplete?.(next);\n },\n [length, onComplete, setValue, type],\n );\n\n const { onClick: consumerOnClick } = consumerProps as {\n onClick?: (event: SyntheticEvent<HTMLElement>) => void;\n };\n\n const handleClick = () => hiddenInputRef.current?.focus();\n\n const activeIndex = focused ? Math.min(value.length, length - 1) : -1;\n const contextValue = useMemo<OtpInputContextValue>(\n () => ({\n activeIndex,\n autoFocus,\n disabled,\n hiddenInputRef,\n length,\n mask,\n onHiddenBlur: () => setFocused(false),\n onHiddenFocus: () => setFocused(true),\n type,\n updateValue,\n value,\n }),\n [activeIndex, autoFocus, disabled, length, mask, type, updateValue, value],\n );\n\n const element = useRenderElement({\n as,\n defaultTag: \"div\",\n props: {\n ...consumerProps,\n \"data-uiify-otp-input\": \"\",\n \"data-disabled\": disabled ? \"\" : undefined,\n \"data-complete\": value.length === length ? \"\" : undefined,\n onClick: composeEventHandlers(consumerOnClick, handleClick),\n },\n render,\n state: { disabled, mask, type },\n });\n\n return <OtpInputProvider value={contextValue}>{element}</OtpInputProvider>;\n}\nOtpInputRoot.displayName = \"OtpInputRoot\";\n\nexport function OtpInputSlot<TAs extends ElementType = \"div\">(\n props: OtpInputSlotProps<TAs>,\n): ReactElement | null {\n const { as, render, index, ...consumerProps } = props as OtpInputSlotProps<ElementType>;\n const { activeIndex, disabled, length, mask, value } = useOtpInputContext(\"Slot\");\n\n if (index < 0 || index >= length) {\n throw new Error(`OtpInput.Slot index ${index} is out of range for length ${length}`);\n }\n\n const char = value[index] ?? \"\";\n const active = activeIndex === index;\n const filled = char !== \"\";\n\n return useRenderElement({\n as,\n defaultTag: \"div\",\n props: {\n ...consumerProps,\n \"aria-hidden\": true,\n \"data-part\": \"slot\",\n \"data-active\": active ? \"\" : undefined,\n \"data-disabled\": disabled ? \"\" : undefined,\n \"data-filled\": filled ? \"\" : undefined,\n \"data-index\": index,\n children: mask && filled ? \"•\" : char,\n },\n render,\n state: { active, filled },\n });\n}\n\nexport function OtpInputHiddenInput<TAs extends ElementType = \"input\">(\n props: OtpInputHiddenInputProps<TAs>,\n): ReactElement | null {\n const {\n as,\n render,\n autoFocus: autoFocusProp,\n style: consumerStyle,\n ...consumerProps\n } = props as PolymorphicProps<\"input\", { readonly autoFocus?: boolean }>;\n\n const {\n autoFocus: rootAutoFocus,\n disabled,\n hiddenInputRef,\n length,\n mask,\n onHiddenBlur,\n onHiddenFocus,\n type,\n updateValue,\n value,\n } = useOtpInputContext(\"HiddenInput\");\n const inputId = useId();\n const autoFocus = autoFocusProp ?? rootAutoFocus;\n const {\n onBlur: consumerOnBlur,\n onChange: consumerOnChange,\n onFocus: consumerOnFocus,\n onKeyDown: consumerOnKeyDown,\n onPaste: consumerOnPaste,\n } = consumerProps as {\n onBlur?: (event: SyntheticEvent<HTMLInputElement>) => void;\n onChange?: (event: SyntheticEvent<HTMLInputElement>) => void;\n onFocus?: (event: SyntheticEvent<HTMLInputElement>) => void;\n onKeyDown?: (event: KeyboardEvent<HTMLInputElement>) => void;\n onPaste?: (event: ClipboardEvent<HTMLInputElement>) => void;\n };\n\n const handleChange = (event: SyntheticEvent<HTMLInputElement>) => {\n updateValue(event.currentTarget.value);\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n if (event.key === \"Backspace\" && value.length > 0) {\n event.preventDefault();\n updateValue(value.slice(0, -1));\n }\n };\n\n const handlePaste = (event: ClipboardEvent<HTMLInputElement>) => {\n event.preventDefault();\n updateValue(event.clipboardData.getData(\"text\"));\n };\n\n return useRenderElement({\n as,\n defaultTag: \"input\",\n props: {\n ...consumerProps,\n \"data-part\": \"control\",\n id: inputId,\n ref: hiddenInputRef,\n type: mask ? \"password\" : \"text\",\n inputMode: type === \"numeric\" ? \"numeric\" : \"text\",\n autoComplete: \"one-time-code\",\n autoFocus: autoFocus || undefined,\n disabled: disabled || undefined,\n \"aria-label\": \"One-time code\",\n value,\n maxLength: length,\n onChange: composeEventHandlers(consumerOnChange, handleChange),\n onFocus: composeEventHandlers(consumerOnFocus, onHiddenFocus),\n onBlur: composeEventHandlers(consumerOnBlur, onHiddenBlur),\n onKeyDown: composeEventHandlers(consumerOnKeyDown, handleKeyDown),\n onPaste: composeEventHandlers(consumerOnPaste, handlePaste),\n style: {\n ...consumerStyle,\n position: \"absolute\",\n opacity: 0,\n pointerEvents: \"none\",\n width: 1,\n height: 1,\n } as CSSProperties,\n },\n render,\n state: { disabled },\n });\n}\n\nexport const OtpInput = {\n Root: OtpInputRoot,\n Slot: OtpInputSlot,\n HiddenInput: OtpInputHiddenInput,\n};\n"],"mappings":"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","names":[]}
|
|
@@ -25,7 +25,7 @@ export interface OtpInputRootShellOwnProps {
|
|
|
25
25
|
readonly type?: OtpInputType;
|
|
26
26
|
}
|
|
27
27
|
export interface OtpInputRootControlledOwnProps {
|
|
28
|
-
readonly
|
|
28
|
+
readonly onValueChange?: (value: string) => void;
|
|
29
29
|
readonly onComplete?: (value: string) => void;
|
|
30
30
|
readonly value?: string;
|
|
31
31
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/otp-input/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAEjE,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,cAAc,CAAC;AAEtD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAClE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,IAAI,CAAC;IAClC,QAAQ,CAAC,aAAa,EAAE,MAAM,IAAI,CAAC;CACpC;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC;CAC9B;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/otp-input/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAEjE,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,cAAc,CAAC;AAEtD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAClE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,IAAI,CAAC;IAClC,QAAQ,CAAC,aAAa,EAAE,MAAM,IAAI,CAAC;CACpC;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC;CAC9B;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,sBAAsB,CAAC,GAAG,SAAS,WAAW,GAAG,KAAK,IAAI,eAAe,CACnF,GAAG,EACH,yBAAyB,EACzB,yBAAyB,EACzB,WAAW,CACZ,CAAC;AAEF,MAAM,MAAM,iBAAiB,CAAC,GAAG,SAAS,WAAW,GAAG,KAAK,IAAI,eAAe,CAC9E,GAAG,EACH,yBAAyB,GAAG,8BAA8B,EAC1D,yBAAyB,GAAG,8BAA8B,EAC1D,WAAW,CACZ,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,iBAAiB,CAAC,GAAG,SAAS,WAAW,GAAG,KAAK,IAAI,eAAe,CAC9E,GAAG,EACH,oBAAoB,EACpB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,EACpC,WAAW,CACZ,CAAC;AAEF,MAAM,MAAM,wBAAwB,CAAC,GAAG,SAAS,WAAW,GAAG,OAAO,IAAI,eAAe,CACvF,GAAG,EACH;IAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,EAChC;IAAE,QAAQ,EAAE,OAAO,CAAA;CAAE,EACrB,gBAAgB,CACjB,CAAC"}
|
|
@@ -21,7 +21,7 @@ function PaginationRoot(props) {
|
|
|
21
21
|
count,
|
|
22
22
|
defaultPage,
|
|
23
23
|
disabled,
|
|
24
|
-
|
|
24
|
+
onPageChange,
|
|
25
25
|
page,
|
|
26
26
|
showFirstLast,
|
|
27
27
|
siblingCount,
|
|
@@ -37,7 +37,7 @@ function PaginationRoot(props) {
|
|
|
37
37
|
...boundaryCount !== void 0 ? { boundaryCount } : {},
|
|
38
38
|
...defaultPage !== void 0 ? { defaultPage } : {},
|
|
39
39
|
...disabled !== void 0 ? { disabled } : {},
|
|
40
|
-
...
|
|
40
|
+
...onPageChange !== void 0 ? { onPageChange } : {},
|
|
41
41
|
...page !== void 0 ? { page } : {},
|
|
42
42
|
...showFirstLast !== void 0 ? { showFirstLast } : {},
|
|
43
43
|
...siblingCount !== void 0 ? { siblingCount } : {}
|