@pearpages/pulp-react 0.0.0
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/LICENSE +21 -0
- package/README.md +65 -0
- package/dist/ListboxOptions-DLsT-dkV.d.ts +11 -0
- package/dist/ToggleField-C-qKSgHh.d.ts +3 -0
- package/dist/accordion.css +90 -0
- package/dist/accordion.css.map +1 -0
- package/dist/accordion.d.ts +71 -0
- package/dist/accordion.js +6 -0
- package/dist/accordion.js.map +1 -0
- package/dist/alert.css +246 -0
- package/dist/alert.css.map +1 -0
- package/dist/alert.d.ts +46 -0
- package/dist/alert.js +10 -0
- package/dist/alert.js.map +1 -0
- package/dist/badge.css +89 -0
- package/dist/badge.css.map +1 -0
- package/dist/badge.d.ts +38 -0
- package/dist/badge.js +5 -0
- package/dist/badge.js.map +1 -0
- package/dist/button.css +162 -0
- package/dist/button.css.map +1 -0
- package/dist/button.d.ts +61 -0
- package/dist/button.js +8 -0
- package/dist/button.js.map +1 -0
- package/dist/calendar.css +128 -0
- package/dist/calendar.css.map +1 -0
- package/dist/calendar.d.ts +48 -0
- package/dist/calendar.js +6 -0
- package/dist/calendar.js.map +1 -0
- package/dist/card.css +66 -0
- package/dist/card.css.map +1 -0
- package/dist/card.d.ts +69 -0
- package/dist/card.js +5 -0
- package/dist/card.js.map +1 -0
- package/dist/checkbox.css +106 -0
- package/dist/checkbox.css.map +1 -0
- package/dist/checkbox.d.ts +41 -0
- package/dist/checkbox.js +7 -0
- package/dist/checkbox.js.map +1 -0
- package/dist/chunk-2PXTVZ7H.js +95 -0
- package/dist/chunk-2PXTVZ7H.js.map +1 -0
- package/dist/chunk-2ZP4ZBI5.js +43 -0
- package/dist/chunk-2ZP4ZBI5.js.map +1 -0
- package/dist/chunk-3GWESUGD.js +28 -0
- package/dist/chunk-3GWESUGD.js.map +1 -0
- package/dist/chunk-4HRNRTXI.js +25 -0
- package/dist/chunk-4HRNRTXI.js.map +1 -0
- package/dist/chunk-5SBKZS56.js +56 -0
- package/dist/chunk-5SBKZS56.js.map +1 -0
- package/dist/chunk-6I26MMQF.js +19 -0
- package/dist/chunk-6I26MMQF.js.map +1 -0
- package/dist/chunk-75GTNRBH.js +45 -0
- package/dist/chunk-75GTNRBH.js.map +1 -0
- package/dist/chunk-7DS4I7OJ.js +30 -0
- package/dist/chunk-7DS4I7OJ.js.map +1 -0
- package/dist/chunk-ASNTNTJW.js +27 -0
- package/dist/chunk-ASNTNTJW.js.map +1 -0
- package/dist/chunk-ASOQ2MVR.js +19 -0
- package/dist/chunk-ASOQ2MVR.js.map +1 -0
- package/dist/chunk-AWQHULJC.js +31 -0
- package/dist/chunk-AWQHULJC.js.map +1 -0
- package/dist/chunk-BBV4L5WO.js +43 -0
- package/dist/chunk-BBV4L5WO.js.map +1 -0
- package/dist/chunk-CZBCGLEM.js +9 -0
- package/dist/chunk-CZBCGLEM.js.map +1 -0
- package/dist/chunk-DWE374JX.js +65 -0
- package/dist/chunk-DWE374JX.js.map +1 -0
- package/dist/chunk-DXOOW6Q6.js +159 -0
- package/dist/chunk-DXOOW6Q6.js.map +1 -0
- package/dist/chunk-F3OFZGGE.js +116 -0
- package/dist/chunk-F3OFZGGE.js.map +1 -0
- package/dist/chunk-FH54XQ35.js +125 -0
- package/dist/chunk-FH54XQ35.js.map +1 -0
- package/dist/chunk-FXRSZUDH.js +38 -0
- package/dist/chunk-FXRSZUDH.js.map +1 -0
- package/dist/chunk-GTTXRDXV.js +181 -0
- package/dist/chunk-GTTXRDXV.js.map +1 -0
- package/dist/chunk-I4KC4V6A.js +31 -0
- package/dist/chunk-I4KC4V6A.js.map +1 -0
- package/dist/chunk-I5OZ63W7.js +50 -0
- package/dist/chunk-I5OZ63W7.js.map +1 -0
- package/dist/chunk-IDNGNQNV.js +41 -0
- package/dist/chunk-IDNGNQNV.js.map +1 -0
- package/dist/chunk-J5S2HVHO.js +67 -0
- package/dist/chunk-J5S2HVHO.js.map +1 -0
- package/dist/chunk-K5QGGQOV.js +84 -0
- package/dist/chunk-K5QGGQOV.js.map +1 -0
- package/dist/chunk-KPQGS4PG.js +77 -0
- package/dist/chunk-KPQGS4PG.js.map +1 -0
- package/dist/chunk-MI4QUKQS.js +8 -0
- package/dist/chunk-MI4QUKQS.js.map +1 -0
- package/dist/chunk-MRQWUCBA.js +57 -0
- package/dist/chunk-MRQWUCBA.js.map +1 -0
- package/dist/chunk-MXWXJZFS.js +48 -0
- package/dist/chunk-MXWXJZFS.js.map +1 -0
- package/dist/chunk-N7L66GMG.js +129 -0
- package/dist/chunk-N7L66GMG.js.map +1 -0
- package/dist/chunk-NAYFLTK6.js +32 -0
- package/dist/chunk-NAYFLTK6.js.map +1 -0
- package/dist/chunk-O6OBFL3Q.js +155 -0
- package/dist/chunk-O6OBFL3Q.js.map +1 -0
- package/dist/chunk-OGIQRHNF.js +52 -0
- package/dist/chunk-OGIQRHNF.js.map +1 -0
- package/dist/chunk-OUFAFINB.js +45 -0
- package/dist/chunk-OUFAFINB.js.map +1 -0
- package/dist/chunk-OXYP34CG.js +43 -0
- package/dist/chunk-OXYP34CG.js.map +1 -0
- package/dist/chunk-P5C2U5ZF.js +73 -0
- package/dist/chunk-P5C2U5ZF.js.map +1 -0
- package/dist/chunk-PM4YO67Q.js +53 -0
- package/dist/chunk-PM4YO67Q.js.map +1 -0
- package/dist/chunk-Q6J6BMSB.js +86 -0
- package/dist/chunk-Q6J6BMSB.js.map +1 -0
- package/dist/chunk-T76YSNTZ.js +33 -0
- package/dist/chunk-T76YSNTZ.js.map +1 -0
- package/dist/chunk-TGMDOQCL.js +53 -0
- package/dist/chunk-TGMDOQCL.js.map +1 -0
- package/dist/chunk-TVI5AXLE.js +41 -0
- package/dist/chunk-TVI5AXLE.js.map +1 -0
- package/dist/chunk-U6QRAD73.js +22 -0
- package/dist/chunk-U6QRAD73.js.map +1 -0
- package/dist/chunk-UX42PQLT.js +76 -0
- package/dist/chunk-UX42PQLT.js.map +1 -0
- package/dist/chunk-XDVS7HX7.js +100 -0
- package/dist/chunk-XDVS7HX7.js.map +1 -0
- package/dist/chunk-Y4TZA77G.js +57 -0
- package/dist/chunk-Y4TZA77G.js.map +1 -0
- package/dist/chunk-YUHS5S5Y.js +12 -0
- package/dist/chunk-YUHS5S5Y.js.map +1 -0
- package/dist/chunk-Z4PN6B2C.js +17 -0
- package/dist/chunk-Z4PN6B2C.js.map +1 -0
- package/dist/chunk-ZVDN3GRI.js +49 -0
- package/dist/chunk-ZVDN3GRI.js.map +1 -0
- package/dist/combobox.css +280 -0
- package/dist/combobox.css.map +1 -0
- package/dist/combobox.d.ts +75 -0
- package/dist/combobox.js +10 -0
- package/dist/combobox.js.map +1 -0
- package/dist/component-manifest.json +3370 -0
- package/dist/date-picker.css +267 -0
- package/dist/date-picker.css.map +1 -0
- package/dist/date-picker.d.ts +59 -0
- package/dist/date-picker.js +8 -0
- package/dist/date-picker.js.map +1 -0
- package/dist/dialog.css +62 -0
- package/dist/dialog.css.map +1 -0
- package/dist/dialog.d.ts +56 -0
- package/dist/dialog.js +3 -0
- package/dist/dialog.js.map +1 -0
- package/dist/field.css +28 -0
- package/dist/field.css.map +1 -0
- package/dist/field.d.ts +98 -0
- package/dist/field.js +5 -0
- package/dist/field.js.map +1 -0
- package/dist/floating-Bw-LN_QT.d.ts +5 -0
- package/dist/heading.css +30 -0
- package/dist/heading.css.map +1 -0
- package/dist/heading.d.ts +316 -0
- package/dist/heading.js +4 -0
- package/dist/heading.js.map +1 -0
- package/dist/icon-button.css +177 -0
- package/dist/icon-button.css.map +1 -0
- package/dist/icon-button.d.ts +29 -0
- package/dist/icon-button.js +9 -0
- package/dist/icon-button.js.map +1 -0
- package/dist/icon.css +25 -0
- package/dist/icon.css.map +1 -0
- package/dist/icon.d.ts +33 -0
- package/dist/icon.js +4 -0
- package/dist/icon.js.map +1 -0
- package/dist/index.css +2345 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.js +49 -0
- package/dist/index.js.map +1 -0
- package/dist/inline.css +63 -0
- package/dist/inline.css.map +1 -0
- package/dist/inline.d.ts +322 -0
- package/dist/inline.js +4 -0
- package/dist/inline.js.map +1 -0
- package/dist/listbox.css +95 -0
- package/dist/listbox.css.map +1 -0
- package/dist/listbox.d.ts +47 -0
- package/dist/listbox.js +7 -0
- package/dist/listbox.js.map +1 -0
- package/dist/menu.css +102 -0
- package/dist/menu.css.map +1 -0
- package/dist/menu.d.ts +76 -0
- package/dist/menu.js +9 -0
- package/dist/menu.js.map +1 -0
- package/dist/pagination.css +212 -0
- package/dist/pagination.css.map +1 -0
- package/dist/pagination.d.ts +52 -0
- package/dist/pagination.js +10 -0
- package/dist/pagination.js.map +1 -0
- package/dist/picker.css +209 -0
- package/dist/picker.css.map +1 -0
- package/dist/picker.d.ts +57 -0
- package/dist/picker.js +8 -0
- package/dist/picker.js.map +1 -0
- package/dist/popover.css +48 -0
- package/dist/popover.css.map +1 -0
- package/dist/popover.d.ts +68 -0
- package/dist/popover.js +7 -0
- package/dist/popover.js.map +1 -0
- package/dist/progress.css +83 -0
- package/dist/progress.css.map +1 -0
- package/dist/progress.d.ts +40 -0
- package/dist/progress.js +5 -0
- package/dist/progress.js.map +1 -0
- package/dist/radio.css +107 -0
- package/dist/radio.css.map +1 -0
- package/dist/radio.d.ts +68 -0
- package/dist/radio.js +6 -0
- package/dist/radio.js.map +1 -0
- package/dist/select.css +98 -0
- package/dist/select.css.map +1 -0
- package/dist/select.d.ts +39 -0
- package/dist/select.js +6 -0
- package/dist/select.js.map +1 -0
- package/dist/skeleton.css +59 -0
- package/dist/skeleton.css.map +1 -0
- package/dist/skeleton.d.ts +34 -0
- package/dist/skeleton.js +4 -0
- package/dist/skeleton.js.map +1 -0
- package/dist/slider.css +126 -0
- package/dist/slider.css.map +1 -0
- package/dist/slider.d.ts +61 -0
- package/dist/slider.js +5 -0
- package/dist/slider.js.map +1 -0
- package/dist/spinner.css +60 -0
- package/dist/spinner.css.map +1 -0
- package/dist/spinner.d.ts +34 -0
- package/dist/spinner.js +5 -0
- package/dist/spinner.js.map +1 -0
- package/dist/stack.css +60 -0
- package/dist/stack.css.map +1 -0
- package/dist/stack.d.ts +319 -0
- package/dist/stack.js +4 -0
- package/dist/stack.js.map +1 -0
- package/dist/switch.css +97 -0
- package/dist/switch.css.map +1 -0
- package/dist/switch.d.ts +35 -0
- package/dist/switch.js +7 -0
- package/dist/switch.js.map +1 -0
- package/dist/table.css +188 -0
- package/dist/table.css.map +1 -0
- package/dist/table.d.ts +137 -0
- package/dist/table.js +6 -0
- package/dist/table.js.map +1 -0
- package/dist/tabs.css +75 -0
- package/dist/tabs.css.map +1 -0
- package/dist/tabs.d.ts +73 -0
- package/dist/tabs.js +5 -0
- package/dist/tabs.js.map +1 -0
- package/dist/text-field.css +75 -0
- package/dist/text-field.css.map +1 -0
- package/dist/text-field.d.ts +43 -0
- package/dist/text-field.js +6 -0
- package/dist/text-field.js.map +1 -0
- package/dist/text.css +53 -0
- package/dist/text.css.map +1 -0
- package/dist/text.d.ts +331 -0
- package/dist/text.js +4 -0
- package/dist/text.js.map +1 -0
- package/dist/textarea.css +84 -0
- package/dist/textarea.css.map +1 -0
- package/dist/textarea.d.ts +40 -0
- package/dist/textarea.js +6 -0
- package/dist/textarea.js.map +1 -0
- package/dist/toast.css +300 -0
- package/dist/toast.css.map +1 -0
- package/dist/toast.d.ts +60 -0
- package/dist/toast.js +11 -0
- package/dist/toast.js.map +1 -0
- package/dist/tooltip.css +36 -0
- package/dist/tooltip.css.map +1 -0
- package/dist/tooltip.d.ts +34 -0
- package/dist/tooltip.js +5 -0
- package/dist/tooltip.js.map +1 -0
- package/dist/visually-hidden.css +15 -0
- package/dist/visually-hidden.css.map +1 -0
- package/dist/visually-hidden.d.ts +308 -0
- package/dist/visually-hidden.js +4 -0
- package/dist/visually-hidden.js.map +1 -0
- package/package.json +261 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { useDismiss } from './chunk-NAYFLTK6.js';
|
|
2
|
+
import { useFloatingPosition } from './chunk-U6QRAD73.js';
|
|
3
|
+
import { renderAsChild } from './chunk-ZVDN3GRI.js';
|
|
4
|
+
import { classes } from './chunk-MI4QUKQS.js';
|
|
5
|
+
import { createContext, useState, useCallback, useId, useRef, useEffect, useContext } from 'react';
|
|
6
|
+
import { createPortal } from 'react-dom';
|
|
7
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
8
|
+
|
|
9
|
+
// src/popover/Popover.module.css
|
|
10
|
+
var Popover_default = {
|
|
11
|
+
content: "Popover_content",
|
|
12
|
+
title: "Popover_title"
|
|
13
|
+
};
|
|
14
|
+
var PopoverContext = createContext(null);
|
|
15
|
+
function usePopover(part) {
|
|
16
|
+
const context = useContext(PopoverContext);
|
|
17
|
+
if (!context) throw new Error(`${part} must be rendered inside <Popover>`);
|
|
18
|
+
return context;
|
|
19
|
+
}
|
|
20
|
+
function Popover({ open, defaultOpen = false, onOpenChange, placement = "bottom-start", children }) {
|
|
21
|
+
const [uncontrolled, setUncontrolled] = useState(defaultOpen);
|
|
22
|
+
const controlled = open !== void 0;
|
|
23
|
+
const isOpen = controlled ? open : uncontrolled;
|
|
24
|
+
const setOpen = useCallback(
|
|
25
|
+
(next) => {
|
|
26
|
+
if (!controlled) setUncontrolled(next);
|
|
27
|
+
onOpenChange?.(next);
|
|
28
|
+
},
|
|
29
|
+
[controlled, onOpenChange]
|
|
30
|
+
);
|
|
31
|
+
const id = useId();
|
|
32
|
+
const floating = useFloatingPosition({ open: isOpen, placement });
|
|
33
|
+
return /* @__PURE__ */ jsx(PopoverContext.Provider, { value: { open: isOpen, setOpen, contentId: `${id}-content`, titleId: `${id}-title`, placement, floating }, children });
|
|
34
|
+
}
|
|
35
|
+
function PopoverTrigger({ asChild = false, onClick, ref, children, ...rest }) {
|
|
36
|
+
const popover = usePopover("Popover.Trigger");
|
|
37
|
+
const props = {
|
|
38
|
+
...rest,
|
|
39
|
+
ref: popover.floating.refs.setReference,
|
|
40
|
+
"aria-haspopup": "dialog",
|
|
41
|
+
"aria-expanded": popover.open,
|
|
42
|
+
"aria-controls": popover.open ? popover.contentId : void 0,
|
|
43
|
+
onClick: (event) => {
|
|
44
|
+
onClick?.(event);
|
|
45
|
+
if (!event.defaultPrevented) popover.setOpen(!popover.open);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
if (asChild) {
|
|
49
|
+
return renderAsChild("Popover.Trigger", children, { ...props, ref: mergeRefs(ref, popover.floating.refs.setReference) });
|
|
50
|
+
}
|
|
51
|
+
return /* @__PURE__ */ jsx("button", { type: "button", ...props, ref: mergeRefs(ref, popover.floating.refs.setReference), children });
|
|
52
|
+
}
|
|
53
|
+
function mergeRefs(a, b) {
|
|
54
|
+
return (node) => {
|
|
55
|
+
b(node);
|
|
56
|
+
if (typeof a === "function") a(node);
|
|
57
|
+
else if (a) a.current = node;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function PopoverContent({ title, className, ref, children, ...rest }) {
|
|
61
|
+
const popover = usePopover("Popover.Content");
|
|
62
|
+
const { refs, positionStyle, placement } = popover.floating;
|
|
63
|
+
const contentRef = useRef(null);
|
|
64
|
+
useDismiss({
|
|
65
|
+
open: popover.open,
|
|
66
|
+
onDismiss: () => popover.setOpen(false),
|
|
67
|
+
inside: () => [refs.reference.current, refs.floating.current]
|
|
68
|
+
});
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
if (popover.open) {
|
|
71
|
+
const content = contentRef.current;
|
|
72
|
+
if (!content) return;
|
|
73
|
+
const first = content.querySelector('input, select, textarea, button, a[href], [tabindex]:not([tabindex="-1"])');
|
|
74
|
+
(first ?? content).focus();
|
|
75
|
+
return () => {
|
|
76
|
+
const reference = refs.reference.current;
|
|
77
|
+
if (content.contains(document.activeElement) || document.activeElement === document.body) reference?.focus();
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}, [popover.open, refs.reference]);
|
|
81
|
+
if (!popover.open) return null;
|
|
82
|
+
return createPortal(
|
|
83
|
+
/* @__PURE__ */ jsxs(
|
|
84
|
+
"div",
|
|
85
|
+
{
|
|
86
|
+
...rest,
|
|
87
|
+
ref: mergeRefs(ref, (node) => {
|
|
88
|
+
contentRef.current = node;
|
|
89
|
+
refs.setFloating(node);
|
|
90
|
+
}),
|
|
91
|
+
id: popover.contentId,
|
|
92
|
+
role: "dialog",
|
|
93
|
+
"aria-labelledby": title ? popover.titleId : void 0,
|
|
94
|
+
tabIndex: -1,
|
|
95
|
+
className: classes(Popover_default.content, className),
|
|
96
|
+
"data-placement": placement,
|
|
97
|
+
style: positionStyle,
|
|
98
|
+
children: [
|
|
99
|
+
title && /* @__PURE__ */ jsx("h2", { id: popover.titleId, className: Popover_default.title, children: title }),
|
|
100
|
+
children
|
|
101
|
+
]
|
|
102
|
+
}
|
|
103
|
+
),
|
|
104
|
+
document.body
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
function PopoverClose({ asChild = false, onClick, children, ...rest }) {
|
|
108
|
+
const popover = usePopover("Popover.Close");
|
|
109
|
+
const props = {
|
|
110
|
+
...rest,
|
|
111
|
+
onClick: (event) => {
|
|
112
|
+
onClick?.(event);
|
|
113
|
+
if (!event.defaultPrevented) popover.setOpen(false);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
if (asChild) return renderAsChild("Popover.Close", children, props);
|
|
117
|
+
return /* @__PURE__ */ jsx("button", { type: "button", ...props, children });
|
|
118
|
+
}
|
|
119
|
+
Popover.displayName = "Popover";
|
|
120
|
+
PopoverTrigger.displayName = "Popover.Trigger";
|
|
121
|
+
PopoverContent.displayName = "Popover.Content";
|
|
122
|
+
PopoverClose.displayName = "Popover.Close";
|
|
123
|
+
Popover.Trigger = PopoverTrigger;
|
|
124
|
+
Popover.Content = PopoverContent;
|
|
125
|
+
Popover.Close = PopoverClose;
|
|
126
|
+
|
|
127
|
+
export { Popover };
|
|
128
|
+
//# sourceMappingURL=chunk-N7L66GMG.js.map
|
|
129
|
+
//# sourceMappingURL=chunk-N7L66GMG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/popover/Popover.module.css","../src/popover/Popover.tsx"],"names":["content","title"],"mappings":"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","file":"chunk-N7L66GMG.js","sourcesContent":["/* Every value is a token (--popover-*). Position comes in as --_x/--_y from the floating hook. */\n\n@layer components {\n .content {\n --_gap: var(--popover-gap);\n\n position: fixed;\n z-index: var(--popover-layer);\n inset-block-start: var(--_y);\n inset-inline-start: var(--_x);\n display: flex;\n flex-direction: column;\n gap: var(--popover-gap);\n inline-size: var(--popover-width);\n max-inline-size: calc(100vw - 2 * var(--space-4));\n padding: var(--popover-padding);\n border: var(--size-hairline) solid var(--popover-border);\n border-radius: var(--popover-radius);\n background-color: var(--popover-bg);\n color: var(--popover-fg);\n font-family: var(--font-family-body);\n box-shadow: var(--popover-shadow);\n animation: fade var(--popover-duration) var(--motion-easing-standard);\n\n &:focus-visible {\n outline: var(--popover-focus-ring-width) solid var(--popover-focus-ring);\n outline-offset: var(--popover-focus-ring-offset);\n }\n }\n\n .title {\n margin: 0;\n font-family: var(--font-family-display);\n font-size: var(--font-size-md);\n font-weight: var(--font-weight-semibold);\n line-height: var(--font-line-height-tight);\n }\n\n @keyframes fade {\n from {\n opacity: 0;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .content {\n animation: none;\n }\n }\n}\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useId,\n useRef,\n useState,\n type ButtonHTMLAttributes,\n type HTMLAttributes,\n type ReactNode,\n type Ref,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { renderAsChild } from '../internal/asChild';\nimport { classes } from '../internal/classes';\nimport { useFloatingPosition, type FloatingPlacement } from '../internal/floating';\nimport { useDismiss } from '../internal/useDismiss';\nimport styles from './Popover.module.css';\n\nexport type PopoverPlacement = FloatingPlacement;\n\ninterface PopoverContextValue {\n open: boolean;\n setOpen: (open: boolean) => void;\n contentId: string;\n titleId: string;\n placement: PopoverPlacement;\n floating: ReturnType<typeof useFloatingPosition>;\n}\n\nconst PopoverContext = createContext<PopoverContextValue | null>(null);\n\nfunction usePopover(part: string): PopoverContextValue {\n const context = useContext(PopoverContext);\n if (!context) throw new Error(`${part} must be rendered inside <Popover>`);\n return context;\n}\n\nexport interface PopoverProps {\n /** Controlled open state. */\n open?: boolean;\n /** @default false */\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n /** Preferred side; flips when there is no room. @default 'bottom-start' */\n placement?: PopoverPlacement;\n children: ReactNode;\n}\n\n/**\n * A non-modal layer anchored to its trigger: a small form, a filter, a\n * detail panel. The page stays interactive; Escape, a click outside or\n * `Popover.Close` dismiss it and focus returns to the trigger. Compose with\n * `Popover.Trigger`, `Popover.Content` and `Popover.Close`. For anything that\n * must block the page, use Dialog.\n *\n * @status stable\n * @category Overlays\n * @accessibility A non-modal `role=\"dialog\"` named by `title` (or `aria-label`); the trigger has `aria-haspopup=\"dialog\"` and `aria-expanded`. Focus moves to the first focusable element on open and back to the trigger on close; Escape and a click outside dismiss it.\n * @do Give it a `title` or `aria-label`.\n * Use `Popover.Close` inside forms so a keyboard user has a clear exit.\n * @dont Put a long form or a destructive confirmation in it; use Dialog.\n * Open it on hover; that is Tooltip.\n */\nexport function Popover({ open, defaultOpen = false, onOpenChange, placement = 'bottom-start', children }: PopoverProps) {\n const [uncontrolled, setUncontrolled] = useState(defaultOpen);\n const controlled = open !== undefined;\n const isOpen = controlled ? open : uncontrolled;\n const setOpen = useCallback(\n (next: boolean) => {\n if (!controlled) setUncontrolled(next);\n onOpenChange?.(next);\n },\n [controlled, onOpenChange],\n );\n const id = useId();\n const floating = useFloatingPosition({ open: isOpen, placement });\n\n return (\n <PopoverContext.Provider value={{ open: isOpen, setOpen, contentId: `${id}-content`, titleId: `${id}-title`, placement, floating }}>\n {children}\n </PopoverContext.Provider>\n );\n}\n\ninterface PopoverTriggerProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n /** Render the child element as the trigger instead of a plain button. @default false */\n asChild?: boolean;\n ref?: Ref<HTMLButtonElement>;\n children: ReactNode;\n}\n\nfunction PopoverTrigger({ asChild = false, onClick, ref, children, ...rest }: PopoverTriggerProps) {\n const popover = usePopover('Popover.Trigger');\n const props = {\n ...rest,\n ref: popover.floating.refs.setReference,\n 'aria-haspopup': 'dialog' as const,\n 'aria-expanded': popover.open,\n 'aria-controls': popover.open ? popover.contentId : undefined,\n onClick: (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n if (!event.defaultPrevented) popover.setOpen(!popover.open);\n },\n };\n if (asChild) {\n // eslint-disable-next-line react-hooks/refs -- forwarded to the reference element, not read\n return renderAsChild('Popover.Trigger', children, { ...props, ref: mergeRefs(ref, popover.floating.refs.setReference) });\n }\n return (\n <button type=\"button\" {...props} ref={mergeRefs(ref, popover.floating.refs.setReference)}>\n {children}\n </button>\n );\n}\n\nfunction mergeRefs<T>(a: Ref<T> | undefined, b: (node: T | null) => void) {\n return (node: T | null) => {\n b(node);\n if (typeof a === 'function') a(node);\n else if (a) a.current = node;\n };\n}\n\ninterface PopoverContentProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n /** Rendered as the dialog's heading and used as its accessible name. Otherwise pass `aria-label`. */\n title?: ReactNode;\n ref?: Ref<HTMLDivElement>;\n children: ReactNode;\n}\n\nfunction PopoverContent({ title, className, ref, children, ...rest }: PopoverContentProps) {\n const popover = usePopover('Popover.Content');\n const { refs, positionStyle, placement } = popover.floating;\n const contentRef = useRef<HTMLDivElement | null>(null);\n\n useDismiss({\n open: popover.open,\n onDismiss: () => popover.setOpen(false),\n inside: () => [refs.reference.current as Element | null, refs.floating.current],\n });\n\n // Move focus in on open; give it back to the trigger on close.\n useEffect(() => {\n if (popover.open) {\n const content = contentRef.current;\n if (!content) return;\n const first = content.querySelector<HTMLElement>('input, select, textarea, button, a[href], [tabindex]:not([tabindex=\"-1\"])');\n (first ?? content).focus();\n return () => {\n const reference = refs.reference.current as HTMLElement | null;\n if (content.contains(document.activeElement) || document.activeElement === document.body) reference?.focus();\n };\n }\n }, [popover.open, refs.reference]);\n\n if (!popover.open) return null;\n return createPortal(\n <div\n {...rest}\n ref={mergeRefs(ref, (node) => {\n contentRef.current = node;\n refs.setFloating(node);\n })}\n id={popover.contentId}\n role=\"dialog\"\n aria-labelledby={title ? popover.titleId : undefined}\n tabIndex={-1}\n className={classes(styles.content, className)}\n data-placement={placement}\n // eslint-disable-next-line react/forbid-dom-props -- per-instance position (--_x/--_y), see internal/floating.ts\n style={positionStyle}\n >\n {title && (\n <h2 id={popover.titleId} className={styles.title}>\n {title}\n </h2>\n )}\n {children}\n </div>,\n document.body,\n );\n}\n\ninterface PopoverCloseProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n asChild?: boolean;\n children: ReactNode;\n}\n\nfunction PopoverClose({ asChild = false, onClick, children, ...rest }: PopoverCloseProps) {\n const popover = usePopover('Popover.Close');\n const props = {\n ...rest,\n onClick: (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n if (!event.defaultPrevented) popover.setOpen(false);\n },\n };\n if (asChild) return renderAsChild('Popover.Close', children, props);\n return (\n <button type=\"button\" {...props}>\n {children}\n </button>\n );\n}\n\nPopover.displayName = 'Popover';\nPopoverTrigger.displayName = 'Popover.Trigger';\nPopoverContent.displayName = 'Popover.Content';\nPopoverClose.displayName = 'Popover.Close';\n\nPopover.Trigger = PopoverTrigger;\nPopover.Content = PopoverContent;\nPopover.Close = PopoverClose;\n"]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useRef, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
// src/internal/useDismiss.ts
|
|
4
|
+
function useDismiss({ open, onDismiss, inside }) {
|
|
5
|
+
const latest = useRef({ onDismiss, inside });
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
latest.current = { onDismiss, inside };
|
|
8
|
+
});
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
if (!open) return;
|
|
11
|
+
const onPointerDown = (event) => {
|
|
12
|
+
const target = event.target;
|
|
13
|
+
if (latest.current.inside().some((element) => element?.contains(target))) return;
|
|
14
|
+
latest.current.onDismiss();
|
|
15
|
+
};
|
|
16
|
+
const onKeyDown = (event) => {
|
|
17
|
+
if (event.key !== "Escape") return;
|
|
18
|
+
event.preventDefault();
|
|
19
|
+
latest.current.onDismiss();
|
|
20
|
+
};
|
|
21
|
+
document.addEventListener("pointerdown", onPointerDown, true);
|
|
22
|
+
document.addEventListener("keydown", onKeyDown);
|
|
23
|
+
return () => {
|
|
24
|
+
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
25
|
+
document.removeEventListener("keydown", onKeyDown);
|
|
26
|
+
};
|
|
27
|
+
}, [open]);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { useDismiss };
|
|
31
|
+
//# sourceMappingURL=chunk-NAYFLTK6.js.map
|
|
32
|
+
//# sourceMappingURL=chunk-NAYFLTK6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/internal/useDismiss.ts"],"names":[],"mappings":";;;AAUO,SAAS,UAAA,CAAW,EAAE,IAAA,EAAM,SAAA,EAAW,QAAO,EAAmB;AACtE,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,EAAE,SAAA,EAAW,QAAQ,CAAA;AAC3C,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAA,CAAO,OAAA,GAAU,EAAE,SAAA,EAAW,MAAA,EAAO;AAAA,EACvC,CAAC,CAAA;AAED,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,IAAA,EAAM;AACX,IAAA,MAAM,aAAA,GAAgB,CAAC,KAAA,KAAwB;AAC7C,MAAA,MAAM,SAAS,KAAA,CAAM,MAAA;AACrB,MAAA,IAAI,MAAA,CAAO,OAAA,CAAQ,MAAA,EAAO,CAAE,IAAA,CAAK,CAAC,OAAA,KAAY,OAAA,EAAS,QAAA,CAAS,MAAM,CAAC,CAAA,EAAG;AAC1E,MAAA,MAAA,CAAO,QAAQ,SAAA,EAAU;AAAA,IAC3B,CAAA;AACA,IAAA,MAAM,SAAA,GAAY,CAAC,KAAA,KAAyB;AAC1C,MAAA,IAAI,KAAA,CAAM,QAAQ,QAAA,EAAU;AAC5B,MAAA,KAAA,CAAM,cAAA,EAAe;AACrB,MAAA,MAAA,CAAO,QAAQ,SAAA,EAAU;AAAA,IAC3B,CAAA;AACA,IAAA,QAAA,CAAS,gBAAA,CAAiB,aAAA,EAAe,aAAA,EAAe,IAAI,CAAA;AAC5D,IAAA,QAAA,CAAS,gBAAA,CAAiB,WAAW,SAAS,CAAA;AAC9C,IAAA,OAAO,MAAM;AACX,MAAA,QAAA,CAAS,mBAAA,CAAoB,aAAA,EAAe,aAAA,EAAe,IAAI,CAAA;AAC/D,MAAA,QAAA,CAAS,mBAAA,CAAoB,WAAW,SAAS,CAAA;AAAA,IACnD,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AACX","file":"chunk-NAYFLTK6.js","sourcesContent":["import { useEffect, useRef } from 'react';\n\ninterface DismissOptions {\n open: boolean;\n onDismiss: () => void;\n /** Elements that count as \"inside\": a pointer down within them does not dismiss. */\n inside: () => Array<Element | null | undefined>;\n}\n\n/** Closes an overlay on Escape or on a pointer down outside its elements. */\nexport function useDismiss({ open, onDismiss, inside }: DismissOptions) {\n const latest = useRef({ onDismiss, inside });\n useEffect(() => {\n latest.current = { onDismiss, inside };\n });\n\n useEffect(() => {\n if (!open) return;\n const onPointerDown = (event: PointerEvent) => {\n const target = event.target as Node;\n if (latest.current.inside().some((element) => element?.contains(target))) return;\n latest.current.onDismiss();\n };\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key !== 'Escape') return;\n event.preventDefault();\n latest.current.onDismiss();\n };\n document.addEventListener('pointerdown', onPointerDown, true);\n document.addEventListener('keydown', onKeyDown);\n return () => {\n document.removeEventListener('pointerdown', onPointerDown, true);\n document.removeEventListener('keydown', onKeyDown);\n };\n }, [open]);\n}\n"]}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { useRovingFocus } from './chunk-I5OZ63W7.js';
|
|
2
|
+
import { Icon } from './chunk-ASNTNTJW.js';
|
|
3
|
+
import { classes } from './chunk-MI4QUKQS.js';
|
|
4
|
+
import { createContext, useState, useCallback, useId, createElement, useContext } from 'react';
|
|
5
|
+
import { ChevronDown } from '@pearpages/pulp-icons';
|
|
6
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
7
|
+
|
|
8
|
+
// src/accordion/Accordion.module.css
|
|
9
|
+
var Accordion_default = {
|
|
10
|
+
accordion: "Accordion_accordion",
|
|
11
|
+
item: "Accordion_item",
|
|
12
|
+
heading: "Accordion_heading",
|
|
13
|
+
trigger: "Accordion_trigger",
|
|
14
|
+
label: "Accordion_label",
|
|
15
|
+
chevron: "Accordion_chevron",
|
|
16
|
+
panel: "Accordion_panel"
|
|
17
|
+
};
|
|
18
|
+
var AccordionContext = createContext(null);
|
|
19
|
+
var ItemContext = createContext(null);
|
|
20
|
+
function useAccordion(part) {
|
|
21
|
+
const context = useContext(AccordionContext);
|
|
22
|
+
if (!context) throw new Error(`${part} must be rendered inside <Accordion>`);
|
|
23
|
+
return context;
|
|
24
|
+
}
|
|
25
|
+
function useItem(part) {
|
|
26
|
+
const context = useContext(ItemContext);
|
|
27
|
+
if (!context) throw new Error(`${part} must be rendered inside <Accordion.Item>`);
|
|
28
|
+
return context;
|
|
29
|
+
}
|
|
30
|
+
var toSet = (value) => new Set(value === void 0 ? [] : Array.isArray(value) ? value : [value]);
|
|
31
|
+
function Accordion({
|
|
32
|
+
type = "single",
|
|
33
|
+
value,
|
|
34
|
+
defaultValue,
|
|
35
|
+
onValueChange,
|
|
36
|
+
collapsible = true,
|
|
37
|
+
headingLevel = 3,
|
|
38
|
+
className,
|
|
39
|
+
onKeyDown,
|
|
40
|
+
ref,
|
|
41
|
+
children,
|
|
42
|
+
...rest
|
|
43
|
+
}) {
|
|
44
|
+
const [uncontrolled, setUncontrolled] = useState(() => toSet(defaultValue));
|
|
45
|
+
const controlled = value !== void 0;
|
|
46
|
+
const openValues = controlled ? toSet(value) : uncontrolled;
|
|
47
|
+
const toggle = useCallback(
|
|
48
|
+
(item) => {
|
|
49
|
+
const next = new Set(openValues);
|
|
50
|
+
if (next.has(item)) {
|
|
51
|
+
if (type === "single" && !collapsible) return;
|
|
52
|
+
next.delete(item);
|
|
53
|
+
} else {
|
|
54
|
+
if (type === "single") next.clear();
|
|
55
|
+
next.add(item);
|
|
56
|
+
}
|
|
57
|
+
if (!controlled) setUncontrolled(next);
|
|
58
|
+
onValueChange?.(type === "single" ? next.values().next().value ?? "" : Array.from(next));
|
|
59
|
+
},
|
|
60
|
+
[openValues, type, collapsible, controlled, onValueChange]
|
|
61
|
+
);
|
|
62
|
+
const baseId = useId();
|
|
63
|
+
const rove = useRovingFocus({ orientation: "vertical", selector: "[data-accordion-trigger]" });
|
|
64
|
+
return /* @__PURE__ */ jsx(AccordionContext.Provider, { value: { openValues, toggle, headingLevel, baseId }, children: /* @__PURE__ */ jsx(
|
|
65
|
+
"div",
|
|
66
|
+
{
|
|
67
|
+
...rest,
|
|
68
|
+
ref,
|
|
69
|
+
className: classes(Accordion_default.accordion, className),
|
|
70
|
+
"data-type": type,
|
|
71
|
+
onKeyDown: (event) => {
|
|
72
|
+
onKeyDown?.(event);
|
|
73
|
+
if (!event.defaultPrevented) rove(event);
|
|
74
|
+
},
|
|
75
|
+
children
|
|
76
|
+
}
|
|
77
|
+
) });
|
|
78
|
+
}
|
|
79
|
+
function AccordionItem({ value, disabled = false, className, ref, children, ...rest }) {
|
|
80
|
+
const accordion = useAccordion("Accordion.Item");
|
|
81
|
+
const open = accordion.openValues.has(value);
|
|
82
|
+
return /* @__PURE__ */ jsx(ItemContext.Provider, { value: { value, open, disabled }, children: /* @__PURE__ */ jsx(
|
|
83
|
+
"div",
|
|
84
|
+
{
|
|
85
|
+
...rest,
|
|
86
|
+
ref,
|
|
87
|
+
className: classes(Accordion_default.item, className),
|
|
88
|
+
"data-state": open ? "open" : "closed",
|
|
89
|
+
"data-disabled": disabled ? "" : void 0,
|
|
90
|
+
children
|
|
91
|
+
}
|
|
92
|
+
) });
|
|
93
|
+
}
|
|
94
|
+
function AccordionTrigger({ className, onClick, ref, children, ...rest }) {
|
|
95
|
+
const accordion = useAccordion("Accordion.Trigger");
|
|
96
|
+
const item = useItem("Accordion.Trigger");
|
|
97
|
+
const triggerId = `${accordion.baseId}-${item.value}-trigger`;
|
|
98
|
+
const panelId = `${accordion.baseId}-${item.value}-panel`;
|
|
99
|
+
return createElement(
|
|
100
|
+
`h${accordion.headingLevel}`,
|
|
101
|
+
{ className: Accordion_default.heading },
|
|
102
|
+
/* @__PURE__ */ jsxs(
|
|
103
|
+
"button",
|
|
104
|
+
{
|
|
105
|
+
...rest,
|
|
106
|
+
ref,
|
|
107
|
+
type: "button",
|
|
108
|
+
id: triggerId,
|
|
109
|
+
"aria-expanded": item.open,
|
|
110
|
+
"aria-controls": panelId,
|
|
111
|
+
disabled: item.disabled,
|
|
112
|
+
className: classes(Accordion_default.trigger, className),
|
|
113
|
+
"data-accordion-trigger": "",
|
|
114
|
+
"data-state": item.open ? "open" : "closed",
|
|
115
|
+
onClick: (event) => {
|
|
116
|
+
onClick?.(event);
|
|
117
|
+
if (!event.defaultPrevented) accordion.toggle(item.value);
|
|
118
|
+
},
|
|
119
|
+
children: [
|
|
120
|
+
/* @__PURE__ */ jsx("span", { className: Accordion_default.label, children }),
|
|
121
|
+
/* @__PURE__ */ jsx(Icon, { size: "inherit", className: Accordion_default.chevron, children: /* @__PURE__ */ jsx(ChevronDown, {}) })
|
|
122
|
+
]
|
|
123
|
+
}
|
|
124
|
+
)
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
function AccordionPanel({ className, ref, children, ...rest }) {
|
|
128
|
+
const accordion = useAccordion("Accordion.Panel");
|
|
129
|
+
const item = useItem("Accordion.Panel");
|
|
130
|
+
return /* @__PURE__ */ jsx(
|
|
131
|
+
"div",
|
|
132
|
+
{
|
|
133
|
+
...rest,
|
|
134
|
+
ref,
|
|
135
|
+
id: `${accordion.baseId}-${item.value}-panel`,
|
|
136
|
+
role: "region",
|
|
137
|
+
"aria-labelledby": `${accordion.baseId}-${item.value}-trigger`,
|
|
138
|
+
hidden: !item.open,
|
|
139
|
+
className: classes(Accordion_default.panel, className),
|
|
140
|
+
"data-state": item.open ? "open" : "closed",
|
|
141
|
+
children
|
|
142
|
+
}
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
Accordion.displayName = "Accordion";
|
|
146
|
+
AccordionItem.displayName = "Accordion.Item";
|
|
147
|
+
AccordionTrigger.displayName = "Accordion.Trigger";
|
|
148
|
+
AccordionPanel.displayName = "Accordion.Panel";
|
|
149
|
+
Accordion.Item = AccordionItem;
|
|
150
|
+
Accordion.Trigger = AccordionTrigger;
|
|
151
|
+
Accordion.Panel = AccordionPanel;
|
|
152
|
+
|
|
153
|
+
export { Accordion };
|
|
154
|
+
//# sourceMappingURL=chunk-O6OBFL3Q.js.map
|
|
155
|
+
//# sourceMappingURL=chunk-O6OBFL3Q.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/accordion/Accordion.module.css","../src/accordion/Accordion.tsx"],"names":["accordion","item","heading","trigger","label","chevron","panel"],"mappings":"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","file":"chunk-O6OBFL3Q.js","sourcesContent":["/* Every value is a token (--accordion-*). Open state is a data attribute; the chevron rotates on it. */\n\n@layer components {\n .accordion {\n display: flex;\n flex-direction: column;\n border: var(--size-hairline) solid var(--accordion-border);\n border-radius: var(--accordion-radius);\n font-family: var(--font-family-body);\n }\n\n .item {\n border-block-end: var(--size-hairline) solid var(--accordion-border);\n\n &:last-child {\n border-block-end: none;\n }\n }\n\n .heading {\n margin: 0;\n font-size: inherit;\n font-weight: inherit;\n }\n\n .trigger {\n display: flex;\n gap: var(--accordion-trigger-gap);\n align-items: center;\n inline-size: 100%;\n padding-block: var(--accordion-trigger-padding-block);\n padding-inline: var(--accordion-trigger-padding-inline);\n border: none;\n background-color: transparent;\n color: var(--accordion-trigger-fg);\n font-size: var(--accordion-trigger-font-size);\n font-weight: var(--accordion-trigger-font-weight);\n text-align: start;\n cursor: pointer;\n transition: background-color var(--accordion-duration) var(--motion-easing-standard);\n\n &:focus-visible {\n outline: var(--accordion-focus-ring-width) solid var(--accordion-focus-ring);\n outline-offset: calc(-1 * var(--accordion-focus-ring-offset));\n }\n\n &:disabled {\n cursor: not-allowed;\n opacity: 0.55;\n }\n\n &:hover:not(:disabled) {\n background-color: var(--accordion-trigger-bg-hover);\n }\n }\n\n .label {\n flex: 1;\n }\n\n .chevron {\n color: var(--accordion-trigger-chevron);\n transition: rotate var(--accordion-duration) var(--motion-easing-standard);\n }\n\n .trigger[data-state=\"open\"] .chevron {\n rotate: 180deg;\n }\n\n .panel {\n padding-block: var(--accordion-panel-padding-block);\n padding-inline: var(--accordion-panel-padding-inline);\n color: var(--accordion-panel-fg);\n font-size: var(--accordion-panel-font-size);\n }\n}\n","import {\n createContext,\n createElement,\n useCallback,\n useContext,\n useId,\n useState,\n type ButtonHTMLAttributes,\n type HTMLAttributes,\n type ReactNode,\n type Ref,\n} from 'react';\nimport { ChevronDown } from '@pearpages/pulp-icons';\nimport { Icon } from '../icon';\nimport { classes } from '../internal/classes';\nimport { useRovingFocus } from '../internal/useRovingFocus';\nimport styles from './Accordion.module.css';\n\nexport type AccordionType = 'single' | 'multiple';\nexport type AccordionHeadingLevel = 2 | 3 | 4 | 5 | 6;\n\ninterface AccordionContextValue {\n openValues: ReadonlySet<string>;\n toggle: (value: string) => void;\n headingLevel: AccordionHeadingLevel;\n baseId: string;\n}\n\ninterface ItemContextValue {\n value: string;\n open: boolean;\n disabled: boolean;\n}\n\nconst AccordionContext = createContext<AccordionContextValue | null>(null);\nconst ItemContext = createContext<ItemContextValue | null>(null);\n\nfunction useAccordion(part: string): AccordionContextValue {\n const context = useContext(AccordionContext);\n if (!context) throw new Error(`${part} must be rendered inside <Accordion>`);\n return context;\n}\n\nfunction useItem(part: string): ItemContextValue {\n const context = useContext(ItemContext);\n if (!context) throw new Error(`${part} must be rendered inside <Accordion.Item>`);\n return context;\n}\n\nexport interface AccordionProps extends Omit<HTMLAttributes<HTMLDivElement>, 'defaultValue' | 'onChange'> {\n /** `single` keeps one item open; `multiple` allows any number. @default 'single' */\n type?: AccordionType;\n /** Controlled open item(s): a string for `single`, an array for `multiple`. */\n value?: string | string[];\n defaultValue?: string | string[];\n onValueChange?: (value: string | string[]) => void;\n /** In `single` mode, whether the open item can be closed again. @default true */\n collapsible?: boolean;\n /** The heading level of every trigger, for the document outline. @default 3 */\n headingLevel?: AccordionHeadingLevel;\n ref?: Ref<HTMLDivElement>;\n children: ReactNode;\n}\n\nconst toSet = (value: string | string[] | undefined): Set<string> =>\n new Set(value === undefined ? [] : Array.isArray(value) ? value : [value]);\n\n/**\n * Vertically stacked sections that expand one at a time or independently.\n * Each trigger is a button inside a real heading, each panel a labelled\n * region; arrows, Home and End move between triggers. Controlled or\n * uncontrolled by `value`. Compose with `Accordion.Item`,\n * `Accordion.Trigger` and `Accordion.Panel`.\n *\n * @status stable\n * @category Navigation\n * @accessibility Each trigger is a `button` inside a heading of the given `headingLevel`; each panel is a `region` labelled by its trigger. Arrows, Home and End move between triggers; Enter or Space toggles.\n * @do Set `headingLevel` to fit the page outline.\n * Use `multiple` when sections are independent reference material.\n * @dont Nest interactive content in the trigger; it is one button.\n * Use it for a single show-more; use Popover or plain content instead.\n */\nexport function Accordion({\n type = 'single',\n value,\n defaultValue,\n onValueChange,\n collapsible = true,\n headingLevel = 3,\n className,\n onKeyDown,\n ref,\n children,\n ...rest\n}: AccordionProps) {\n const [uncontrolled, setUncontrolled] = useState<Set<string>>(() => toSet(defaultValue));\n const controlled = value !== undefined;\n const openValues = controlled ? toSet(value) : uncontrolled;\n\n const toggle = useCallback(\n (item: string) => {\n const next = new Set(openValues);\n if (next.has(item)) {\n if (type === 'single' && !collapsible) return;\n next.delete(item);\n } else {\n if (type === 'single') next.clear();\n next.add(item);\n }\n if (!controlled) setUncontrolled(next);\n onValueChange?.(type === 'single' ? (next.values().next().value ?? '') : Array.from(next));\n },\n [openValues, type, collapsible, controlled, onValueChange],\n );\n\n const baseId = useId();\n const rove = useRovingFocus({ orientation: 'vertical', selector: '[data-accordion-trigger]' });\n\n return (\n <AccordionContext.Provider value={{ openValues, toggle, headingLevel, baseId }}>\n <div\n {...rest}\n ref={ref}\n className={classes(styles.accordion, className)}\n data-type={type}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n if (!event.defaultPrevented) rove(event);\n }}\n >\n {children}\n </div>\n </AccordionContext.Provider>\n );\n}\n\ninterface AccordionItemProps extends HTMLAttributes<HTMLDivElement> {\n value: string;\n disabled?: boolean;\n ref?: Ref<HTMLDivElement>;\n children: ReactNode;\n}\n\nfunction AccordionItem({ value, disabled = false, className, ref, children, ...rest }: AccordionItemProps) {\n const accordion = useAccordion('Accordion.Item');\n const open = accordion.openValues.has(value);\n return (\n <ItemContext.Provider value={{ value, open, disabled }}>\n <div\n {...rest}\n ref={ref}\n className={classes(styles.item, className)}\n data-state={open ? 'open' : 'closed'}\n data-disabled={disabled ? '' : undefined}\n >\n {children}\n </div>\n </ItemContext.Provider>\n );\n}\n\ninterface AccordionTriggerProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n ref?: Ref<HTMLButtonElement>;\n children: ReactNode;\n}\n\nfunction AccordionTrigger({ className, onClick, ref, children, ...rest }: AccordionTriggerProps) {\n const accordion = useAccordion('Accordion.Trigger');\n const item = useItem('Accordion.Trigger');\n const triggerId = `${accordion.baseId}-${item.value}-trigger`;\n const panelId = `${accordion.baseId}-${item.value}-panel`;\n return createElement(\n `h${accordion.headingLevel}`,\n { className: styles.heading },\n <button\n {...rest}\n ref={ref}\n type=\"button\"\n id={triggerId}\n aria-expanded={item.open}\n aria-controls={panelId}\n disabled={item.disabled}\n className={classes(styles.trigger, className)}\n data-accordion-trigger=\"\"\n data-state={item.open ? 'open' : 'closed'}\n onClick={(event) => {\n onClick?.(event);\n if (!event.defaultPrevented) accordion.toggle(item.value);\n }}\n >\n <span className={styles.label}>{children}</span>\n <Icon size=\"inherit\" className={styles.chevron}>\n <ChevronDown />\n </Icon>\n </button>,\n );\n}\n\ninterface AccordionPanelProps extends HTMLAttributes<HTMLDivElement> {\n ref?: Ref<HTMLDivElement>;\n children: ReactNode;\n}\n\nfunction AccordionPanel({ className, ref, children, ...rest }: AccordionPanelProps) {\n const accordion = useAccordion('Accordion.Panel');\n const item = useItem('Accordion.Panel');\n return (\n <div\n {...rest}\n ref={ref}\n id={`${accordion.baseId}-${item.value}-panel`}\n role=\"region\"\n aria-labelledby={`${accordion.baseId}-${item.value}-trigger`}\n hidden={!item.open}\n className={classes(styles.panel, className)}\n data-state={item.open ? 'open' : 'closed'}\n >\n {children}\n </div>\n );\n}\n\nAccordion.displayName = 'Accordion';\nAccordionItem.displayName = 'Accordion.Item';\nAccordionTrigger.displayName = 'Accordion.Trigger';\nAccordionPanel.displayName = 'Accordion.Panel';\n\nAccordion.Item = AccordionItem;\nAccordion.Trigger = AccordionTrigger;\nAccordion.Panel = AccordionPanel;\n"]}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Field } from './chunk-2PXTVZ7H.js';
|
|
2
|
+
import { classes } from './chunk-MI4QUKQS.js';
|
|
3
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
// src/select/Select.module.css
|
|
6
|
+
var Select_default = {
|
|
7
|
+
field: "Select_field",
|
|
8
|
+
control: "Select_control",
|
|
9
|
+
select: "Select_select"
|
|
10
|
+
};
|
|
11
|
+
function Select({
|
|
12
|
+
label,
|
|
13
|
+
description,
|
|
14
|
+
error,
|
|
15
|
+
size = "md",
|
|
16
|
+
placeholder,
|
|
17
|
+
required,
|
|
18
|
+
disabled,
|
|
19
|
+
id,
|
|
20
|
+
className,
|
|
21
|
+
ref,
|
|
22
|
+
children,
|
|
23
|
+
"aria-describedby": describedBy,
|
|
24
|
+
...rest
|
|
25
|
+
}) {
|
|
26
|
+
const invalid = error !== void 0 && error !== null && error !== false && error !== "";
|
|
27
|
+
return /* @__PURE__ */ jsxs(
|
|
28
|
+
Field,
|
|
29
|
+
{
|
|
30
|
+
id,
|
|
31
|
+
invalid,
|
|
32
|
+
disabled: Boolean(disabled),
|
|
33
|
+
required: Boolean(required),
|
|
34
|
+
className: classes(Select_default.field, className),
|
|
35
|
+
"data-size": size,
|
|
36
|
+
children: [
|
|
37
|
+
/* @__PURE__ */ jsx(Field.Label, { children: label }),
|
|
38
|
+
/* @__PURE__ */ jsx("span", { className: Select_default.control, children: /* @__PURE__ */ jsx(Field.Control, { "aria-describedby": describedBy, children: /* @__PURE__ */ jsxs("select", { ...rest, ref, className: Select_default.select, children: [
|
|
39
|
+
placeholder !== void 0 && /* @__PURE__ */ jsx("option", { value: "", disabled: required, children: placeholder }),
|
|
40
|
+
children
|
|
41
|
+
] }) }) }),
|
|
42
|
+
description && /* @__PURE__ */ jsx(Field.Description, { children: description }),
|
|
43
|
+
invalid && /* @__PURE__ */ jsx(Field.Error, { children: error })
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
Select.displayName = "Select";
|
|
49
|
+
|
|
50
|
+
export { Select };
|
|
51
|
+
//# sourceMappingURL=chunk-OGIQRHNF.js.map
|
|
52
|
+
//# sourceMappingURL=chunk-OGIQRHNF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/select/Select.module.css","../src/select/Select.tsx"],"names":["field","control","select"],"mappings":";;;;;AAAA,IAAA,cAAA,GAAA;AAAA,EAOG,KAAA,EAAAA,cAAAA;AAAA,EAoBA,OAAA,EAAAC,gBAAAA;AAAA,EAuBA,MAAA,EAAAC;AAAA,CAAA;ACbI,SAAS,MAAA,CAAO;AAAA,EACrB,KAAA;AAAA,EACA,WAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA,GAAO,IAAA;AAAA,EACP,WAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,EAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAA;AAAA,EACA,QAAA;AAAA,EACA,kBAAA,EAAoB,WAAA;AAAA,EACpB,GAAG;AACL,CAAA,EAAgB;AACd,EAAA,MAAM,UAAU,KAAA,KAAU,MAAA,IAAa,UAAU,IAAA,IAAQ,KAAA,KAAU,SAAS,KAAA,KAAU,EAAA;AACtF,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,EAAA;AAAA,MACA,OAAA;AAAA,MACA,QAAA,EAAU,QAAQ,QAAQ,CAAA;AAAA,MAC1B,QAAA,EAAU,QAAQ,QAAQ,CAAA;AAAA,MAC1B,SAAA,EAAW,OAAA,CAAQ,cAAA,CAAO,KAAA,EAAO,SAAS,CAAA;AAAA,MAC1C,WAAA,EAAW,IAAA;AAAA,MAEX,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,KAAA,CAAM,KAAA,EAAN,EAAa,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,4BACnB,MAAA,EAAA,EAAK,SAAA,EAAW,eAAO,OAAA,EACtB,QAAA,kBAAA,GAAA,CAAC,MAAM,OAAA,EAAN,EAAc,kBAAA,EAAkB,WAAA,EAC/B,+BAAC,QAAA,EAAA,EAAQ,GAAG,MAAM,GAAA,EAAU,SAAA,EAAW,eAAO,MAAA,EAC3C,QAAA,EAAA;AAAA,UAAA,WAAA,KAAgB,0BACf,GAAA,CAAC,QAAA,EAAA,EAAO,OAAM,EAAA,EAAG,QAAA,EAAU,UACxB,QAAA,EAAA,WAAA,EACH,CAAA;AAAA,UAED;AAAA,SAAA,EACH,GACF,CAAA,EACF,CAAA;AAAA,QACC,WAAA,oBAAe,GAAA,CAAC,KAAA,CAAM,WAAA,EAAN,EAAmB,QAAA,EAAA,WAAA,EAAY,CAAA;AAAA,QAC/C,OAAA,oBAAW,GAAA,CAAC,KAAA,CAAM,KAAA,EAAN,EAAa,QAAA,EAAA,KAAA,EAAM;AAAA;AAAA;AAAA,GAClC;AAEJ;AAEA,MAAA,CAAO,WAAA,GAAc,QAAA","file":"chunk-OGIQRHNF.js","sourcesContent":["/*\n * Every value is a token (--select-*). The chevron is the wrapper's ::after,\n * sharing the select's grid cell. Size and invalid state resolve into private\n * custom properties on the root.\n */\n\n@layer components {\n .field {\n --_height: var(--select-height-md);\n --_font-size: var(--select-font-size-md);\n --_border: var(--select-border-default);\n\n font-family: var(--select-font-family);\n\n &[data-size=\"sm\"] {\n --_height: var(--select-height-sm);\n --_font-size: var(--select-font-size-sm);\n }\n\n &[data-size=\"lg\"] {\n --_height: var(--select-height-lg);\n --_font-size: var(--select-font-size-lg);\n }\n\n &[data-invalid] { --_border: var(--select-border-invalid); }\n }\n\n .control {\n display: grid;\n align-items: center;\n\n & > * {\n grid-area: 1 / 1;\n }\n\n &::after {\n content: \"\";\n inline-size: var(--space-2);\n block-size: var(--space-2);\n margin-inline-end: var(--select-chevron-inset);\n border-inline-end: var(--select-chevron-width) solid var(--select-chevron);\n border-block-end: var(--select-chevron-width) solid var(--select-chevron);\n justify-self: end;\n rotate: 45deg;\n translate: 0 -25%;\n pointer-events: none;\n grid-area: 1 / 1;\n }\n }\n\n .select {\n inline-size: 100%;\n min-block-size: var(--_height);\n padding-block: 0;\n padding-inline: var(--select-padding-inline) var(--select-chevron-gap);\n border: var(--size-hairline) solid var(--_border);\n border-radius: var(--select-radius);\n background-color: var(--select-bg);\n color: var(--select-fg);\n font-size: var(--_font-size);\n appearance: none;\n cursor: pointer;\n transition: border-color var(--select-motion-duration) var(--motion-easing-standard);\n\n &:focus-visible {\n border-color: var(--select-border-focus);\n outline: var(--select-focus-ring-width) solid var(--select-focus-ring);\n outline-offset: var(--select-focus-ring-offset);\n }\n\n &:disabled {\n cursor: not-allowed;\n opacity: 0.55;\n }\n\n &:hover:not(:disabled, :focus-visible) {\n border-color: var(--select-border-hover);\n }\n\n &:has(option[value=\"\"]:checked) {\n color: var(--select-placeholder);\n }\n }\n}\n","import type { ReactNode, Ref, SelectHTMLAttributes } from 'react';\nimport { Field } from '../field';\nimport { classes } from '../internal/classes';\nimport styles from './Select.module.css';\n\nexport type SelectSize = 'sm' | 'md' | 'lg';\n\nexport interface SelectProps extends Omit<SelectHTMLAttributes<HTMLSelectElement>, 'size'> {\n /** Visible label. Always rendered. */\n label: ReactNode;\n description?: ReactNode;\n /** Presence marks the control invalid and announces the message. */\n error?: ReactNode;\n /** @default 'md' */\n size?: SelectSize;\n /** An empty first option shown until a value is chosen. */\n placeholder?: string;\n /** The `<select>` element. */\n ref?: Ref<HTMLSelectElement>;\n /** Applied to the wrapper, not the select. */\n className?: string;\n /** `<option>` and `<optgroup>` elements. */\n children: ReactNode;\n}\n\n/**\n * A native `<select>` on top of Field: the browser's own popup, keyboard and\n * assistive-technology support, with the closed control drawn from\n * `--select-*` tokens. For rich options or multi-select, a listbox component\n * comes later on a headless layer; this one stays native on purpose.\n *\n * @status stable\n * @category Forms\n * @accessibility A native `select` on top of Field: the browser's own popup, keyboard and screen-reader behaviour; the placeholder is a disabled empty option when `required`.\n * @do Use it for a plain list of words; it is the most robust choice on every platform.\n * @dont Use it for options that need a description or an icon; use Picker.\n */\nexport function Select({\n label,\n description,\n error,\n size = 'md',\n placeholder,\n required,\n disabled,\n id,\n className,\n ref,\n children,\n 'aria-describedby': describedBy,\n ...rest\n}: SelectProps) {\n const invalid = error !== undefined && error !== null && error !== false && error !== '';\n return (\n <Field\n id={id}\n invalid={invalid}\n disabled={Boolean(disabled)}\n required={Boolean(required)}\n className={classes(styles.field, className)}\n data-size={size}\n >\n <Field.Label>{label}</Field.Label>\n <span className={styles.control}>\n <Field.Control aria-describedby={describedBy}>\n <select {...rest} ref={ref} className={styles.select}>\n {placeholder !== undefined && (\n <option value=\"\" disabled={required}>\n {placeholder}\n </option>\n )}\n {children}\n </select>\n </Field.Control>\n </span>\n {description && <Field.Description>{description}</Field.Description>}\n {invalid && <Field.Error>{error}</Field.Error>}\n </Field>\n );\n}\n\nSelect.displayName = 'Select';\n"]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { ToggleField } from './chunk-BBV4L5WO.js';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
// src/switch/Switch.module.css
|
|
5
|
+
var Switch_default = {
|
|
6
|
+
switch: "Switch_switch",
|
|
7
|
+
row: "Switch_row",
|
|
8
|
+
input: "Switch_input"
|
|
9
|
+
};
|
|
10
|
+
function Switch({
|
|
11
|
+
label,
|
|
12
|
+
description,
|
|
13
|
+
error,
|
|
14
|
+
size = "md",
|
|
15
|
+
required,
|
|
16
|
+
disabled,
|
|
17
|
+
id,
|
|
18
|
+
className,
|
|
19
|
+
ref,
|
|
20
|
+
"aria-describedby": describedBy,
|
|
21
|
+
...rest
|
|
22
|
+
}) {
|
|
23
|
+
return /* @__PURE__ */ jsx(
|
|
24
|
+
ToggleField,
|
|
25
|
+
{
|
|
26
|
+
label,
|
|
27
|
+
description,
|
|
28
|
+
error,
|
|
29
|
+
size,
|
|
30
|
+
required,
|
|
31
|
+
disabled,
|
|
32
|
+
id,
|
|
33
|
+
className,
|
|
34
|
+
rootClassName: Switch_default.switch,
|
|
35
|
+
rowClassName: Switch_default.row,
|
|
36
|
+
"aria-describedby": describedBy,
|
|
37
|
+
control: /* @__PURE__ */ jsx("input", { ...rest, ref, type: "checkbox", role: "switch", className: Switch_default.input })
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
Switch.displayName = "Switch";
|
|
42
|
+
|
|
43
|
+
export { Switch };
|
|
44
|
+
//# sourceMappingURL=chunk-OUFAFINB.js.map
|
|
45
|
+
//# sourceMappingURL=chunk-OUFAFINB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/switch/Switch.module.css","../src/switch/Switch.tsx"],"names":["switch","row","input"],"mappings":";;;;AAAA,IAAA,cAAA,GAAA;AAAA,EAOG,MAAA,EAAAA,eAAAA;AAAA,EAWA,GAAA,EAAAC,YAAAA;AAAA,EAMA,KAAA,EAAAC;AAAA,CAAA;ACOI,SAAS,MAAA,CAAO;AAAA,EACrB,KAAA;AAAA,EACA,WAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA,GAAO,IAAA;AAAA,EACP,QAAA;AAAA,EACA,QAAA;AAAA,EACA,EAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAA;AAAA,EACA,kBAAA,EAAoB,WAAA;AAAA,EACpB,GAAG;AACL,CAAA,EAAgB;AACd,EAAA,uBACE,GAAA;AAAA,IAAC,WAAA;AAAA,IAAA;AAAA,MACC,KAAA;AAAA,MACA,WAAA;AAAA,MACA,KAAA;AAAA,MACA,IAAA;AAAA,MACA,QAAA;AAAA,MACA,QAAA;AAAA,MACA,EAAA;AAAA,MACA,SAAA;AAAA,MACA,eAAe,cAAA,CAAO,MAAA;AAAA,MACtB,cAAc,cAAA,CAAO,GAAA;AAAA,MACrB,kBAAA,EAAkB,WAAA;AAAA,MAClB,OAAA,kBAAS,GAAA,CAAC,OAAA,EAAA,EAAO,GAAG,IAAA,EAAM,GAAA,EAAU,IAAA,EAAK,UAAA,EAAW,IAAA,EAAK,QAAA,EAAS,SAAA,EAAW,cAAA,CAAO,KAAA,EAAO;AAAA;AAAA,GAC7F;AAEJ;AAEA,MAAA,CAAO,WAAA,GAAc,QAAA","file":"chunk-OUFAFINB.js","sourcesContent":["/*\n * Every value is a token (--switch-*). The input is the track; its ::before\n * is the thumb. Size and invalid state resolve into private custom\n * properties on the root.\n */\n\n@layer components {\n .switch {\n --_size: var(--switch-size-md);\n --_track: var(--switch-track-bg);\n\n font-family: var(--font-family-body);\n\n &[data-size=\"sm\"] { --_size: var(--switch-size-sm); }\n &[data-size=\"lg\"] { --_size: var(--switch-size-lg); }\n &[data-invalid] { --_track: var(--switch-track-invalid); }\n }\n\n .row {\n display: flex;\n align-items: center;\n gap: var(--switch-gap);\n }\n\n .input {\n --_inset: calc(2 * var(--switch-thumb-inset));\n\n position: relative;\n flex: none;\n inline-size: calc(2 * var(--_size));\n block-size: var(--_size);\n margin: 0;\n border: none;\n border-radius: var(--switch-radius);\n background-color: var(--_track);\n appearance: none;\n cursor: pointer;\n transition: background-color var(--switch-motion-duration) var(--motion-easing-standard);\n\n &::before {\n content: \"\";\n position: absolute;\n inset-block-start: var(--_inset);\n inset-inline-start: var(--_inset);\n inline-size: calc(var(--_size) - 2 * var(--_inset));\n block-size: calc(var(--_size) - 2 * var(--_inset));\n border-radius: var(--switch-radius);\n background-color: var(--switch-thumb);\n transition: translate var(--switch-motion-duration) var(--motion-easing-standard);\n }\n\n &:checked {\n background-color: var(--switch-track-bg-checked);\n\n &::before {\n translate: var(--_size) 0;\n background-color: var(--switch-thumb-checked);\n }\n }\n\n &:focus-visible {\n outline: var(--switch-focus-ring-width) solid var(--switch-focus-ring);\n outline-offset: var(--switch-focus-ring-offset);\n }\n\n &:disabled {\n cursor: not-allowed;\n opacity: 0.55;\n }\n\n &:hover:not(:disabled, :checked) {\n background-color: var(--switch-track-bg-hover);\n }\n\n &:hover:not(:disabled):checked {\n background-color: var(--switch-track-bg-checked-hover);\n }\n }\n}\n","import type { InputHTMLAttributes, ReactNode, Ref } from 'react';\nimport { ToggleField, type ToggleSize } from '../internal/ToggleField';\nimport styles from './Switch.module.css';\n\nexport type SwitchSize = ToggleSize;\n\nexport interface SwitchProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type'> {\n /** Visible label beside the switch. */\n label: ReactNode;\n description?: ReactNode;\n error?: ReactNode;\n /** @default 'md' */\n size?: SwitchSize;\n /** The `<input>` element. */\n ref?: Ref<HTMLInputElement>;\n /** Applied to the wrapper, not the input. */\n className?: string;\n}\n\n/**\n * An on/off control: a native checkbox with `role=\"switch\"`, so assistive\n * technology announces on and off, and the browser handles keyboard, forms\n * and state. Use it for settings that take effect immediately; use Checkbox\n * for choices submitted with a form. Drawn with `--switch-*` tokens.\n *\n * @status stable\n * @category Forms\n * @accessibility A native checkbox with `role=\"switch\"`, so on and off are announced; Space toggles; label, description and error wire through Field.\n * @do Use it for settings that apply immediately.\n * @dont Use it inside a form that needs a submit; use Checkbox.\n */\nexport function Switch({\n label,\n description,\n error,\n size = 'md',\n required,\n disabled,\n id,\n className,\n ref,\n 'aria-describedby': describedBy,\n ...rest\n}: SwitchProps) {\n return (\n <ToggleField\n label={label}\n description={description}\n error={error}\n size={size}\n required={required}\n disabled={disabled}\n id={id}\n className={className}\n rootClassName={styles.switch}\n rowClassName={styles.row}\n aria-describedby={describedBy}\n control={<input {...rest} ref={ref} type=\"checkbox\" role=\"switch\" className={styles.input} />}\n />\n );\n}\n\nSwitch.displayName = 'Switch';\n"]}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Icon } from './chunk-ASNTNTJW.js';
|
|
2
|
+
import { parseDate } from '@internationalized/date';
|
|
3
|
+
import { Button, Heading, CalendarGrid as CalendarGrid$1, CalendarGridHeader, CalendarHeaderCell, CalendarGridBody, CalendarCell } from 'react-aria-components';
|
|
4
|
+
import { ChevronLeft, ChevronRight } from '@pearpages/pulp-icons';
|
|
5
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
function toDate(iso) {
|
|
8
|
+
if (iso === void 0) return void 0;
|
|
9
|
+
if (iso === null || iso === "") return null;
|
|
10
|
+
return parseDate(iso);
|
|
11
|
+
}
|
|
12
|
+
function fromDate(date) {
|
|
13
|
+
return date ? date.toString().slice(0, 10) : null;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// src/calendar/Calendar.module.css
|
|
17
|
+
var Calendar_default = {
|
|
18
|
+
root: "Calendar_root",
|
|
19
|
+
header: "Calendar_header",
|
|
20
|
+
heading: "Calendar_heading",
|
|
21
|
+
nav: "Calendar_nav",
|
|
22
|
+
grid: "Calendar_grid",
|
|
23
|
+
weekday: "Calendar_weekday",
|
|
24
|
+
cell: "Calendar_cell"
|
|
25
|
+
};
|
|
26
|
+
function CalendarGrid() {
|
|
27
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
28
|
+
/* @__PURE__ */ jsxs("div", { className: Calendar_default.header, children: [
|
|
29
|
+
/* @__PURE__ */ jsx(Button, { slot: "previous", className: Calendar_default.nav, children: /* @__PURE__ */ jsx(Icon, { size: "inherit", children: /* @__PURE__ */ jsx(ChevronLeft, {}) }) }),
|
|
30
|
+
/* @__PURE__ */ jsx(Heading, { className: Calendar_default.heading }),
|
|
31
|
+
/* @__PURE__ */ jsx(Button, { slot: "next", className: Calendar_default.nav, children: /* @__PURE__ */ jsx(Icon, { size: "inherit", children: /* @__PURE__ */ jsx(ChevronRight, {}) }) })
|
|
32
|
+
] }),
|
|
33
|
+
/* @__PURE__ */ jsxs(CalendarGrid$1, { className: Calendar_default.grid, weekdayStyle: "short", children: [
|
|
34
|
+
/* @__PURE__ */ jsx(CalendarGridHeader, { children: (day) => /* @__PURE__ */ jsx(CalendarHeaderCell, { className: Calendar_default.weekday, children: day }) }),
|
|
35
|
+
/* @__PURE__ */ jsx(CalendarGridBody, { children: (date) => /* @__PURE__ */ jsx(CalendarCell, { date, className: Calendar_default.cell }) })
|
|
36
|
+
] })
|
|
37
|
+
] });
|
|
38
|
+
}
|
|
39
|
+
var calendarRootClass = Calendar_default.root;
|
|
40
|
+
|
|
41
|
+
export { CalendarGrid, calendarRootClass, fromDate, toDate };
|
|
42
|
+
//# sourceMappingURL=chunk-OXYP34CG.js.map
|
|
43
|
+
//# sourceMappingURL=chunk-OXYP34CG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/internal/dates.ts","../src/calendar/Calendar.module.css","../src/calendar/CalendarGrid.tsx"],"names":["root","header","heading","nav","grid","weekday","cell","AriaButton","AriaHeading","AriaCalendarGrid","AriaCalendarGridHeader","AriaCalendarHeaderCell","AriaCalendarGridBody","AriaCalendarCell"],"mappings":";;;;;;AAOO,SAAS,OAAO,GAAA,EAAiE;AACtF,EAAA,IAAI,GAAA,KAAQ,QAAW,OAAO,MAAA;AAC9B,EAAA,IAAI,GAAA,KAAQ,IAAA,IAAQ,GAAA,KAAQ,EAAA,EAAI,OAAO,IAAA;AACvC,EAAA,OAAO,UAAU,GAAG,CAAA;AACtB;AAEO,SAAS,SAAS,IAAA,EAAuC;AAC9D,EAAA,OAAO,OAAO,IAAA,CAAK,QAAA,GAAW,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,GAAI,IAAA;AAC/C;;;ACfA,IAAA,gBAAA,GAAA;AAAA,EAOG,IAAA,EAAAA,eAAAA;AAAA,EAWA,MAAA,EAAAC,iBAAAA;AAAA,EAOA,OAAA,EAAAC,kBAAAA;AAAA,EAMA,GAAA,EAAAC,cAAAA;AAAA,EA6BA,IAAA,EAAAC,eAAAA;AAAA,EAKA,OAAA,EAAAC,kBAAAA;AAAA,EASA,IAAA,EAAAC;AAAA,CAAA;ACrDI,SAAS,YAAA,GAAe;AAC7B,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,gBAAA,CAAO,MAAA,EACrB,QAAA,EAAA;AAAA,sBAAA,GAAA,CAACC,MAAA,EAAA,EAAW,IAAA,EAAK,UAAA,EAAW,SAAA,EAAW,gBAAA,CAAO,GAAA,EAC5C,QAAA,kBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAK,SAAA,EACT,QAAA,kBAAA,GAAA,CAAC,WAAA,EAAA,EAAY,GACf,CAAA,EACF,CAAA;AAAA,sBACA,GAAA,CAACC,OAAA,EAAA,EAAY,SAAA,EAAW,gBAAA,CAAO,OAAA,EAAS,CAAA;AAAA,sBACxC,GAAA,CAACD,MAAA,EAAA,EAAW,IAAA,EAAK,MAAA,EAAO,WAAW,gBAAA,CAAO,GAAA,EACxC,QAAA,kBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAK,SAAA,EACT,QAAA,kBAAA,GAAA,CAAC,YAAA,EAAA,EAAa,GAChB,CAAA,EACF;AAAA,KAAA,EACF,CAAA;AAAA,yBACCE,cAAA,EAAA,EAAiB,SAAA,EAAW,gBAAA,CAAO,IAAA,EAAM,cAAa,OAAA,EACrD,QAAA,EAAA;AAAA,sBAAA,GAAA,CAACC,kBAAA,EAAA,EAAwB,WAAC,GAAA,qBAAQ,GAAA,CAACC,sBAAuB,SAAA,EAAW,gBAAA,CAAO,OAAA,EAAU,QAAA,EAAA,GAAA,EAAI,CAAA,EAA0B,CAAA;AAAA,sBACpH,GAAA,CAACC,gBAAA,EAAA,EAAsB,QAAA,EAAA,CAAC,IAAA,qBAAS,GAAA,CAACC,gBAAiB,IAAA,EAAY,SAAA,EAAW,gBAAA,CAAO,IAAA,EAAM,CAAA,EAAG;AAAA,KAAA,EAC5F;AAAA,GAAA,EACF,CAAA;AAEJ;AAGO,IAAM,oBAAoB,gBAAA,CAAO","file":"chunk-OXYP34CG.js","sourcesContent":["import { parseDate, type CalendarDate, type DateValue } from '@internationalized/date';\n\n/**\n * pulp's date contract is an ISO calendar date string (`YYYY-MM-DD`); the\n * vendor's date objects stay behind this boundary (decision record 001).\n * `undefined` stays `undefined` so uncontrolled props remain uncontrolled.\n */\nexport function toDate(iso: string | null | undefined): CalendarDate | null | undefined {\n if (iso === undefined) return undefined;\n if (iso === null || iso === '') return null;\n return parseDate(iso);\n}\n\nexport function fromDate(date: DateValue | null): string | null {\n return date ? date.toString().slice(0, 10) : null;\n}\n","/*\n * Every value is a token (--calendar-*). React Aria writes the cell state:\n * data-selected, data-focused, data-focus-visible, data-hovered,\n * data-disabled, data-unavailable, data-today, data-outside-month.\n */\n\n@layer components {\n .root {\n display: inline-flex;\n flex-direction: column;\n gap: var(--calendar-gap);\n padding: var(--calendar-padding);\n background-color: var(--calendar-bg);\n color: var(--calendar-fg);\n font-family: var(--calendar-font-family);\n font-size: var(--calendar-font-size);\n }\n\n .header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--calendar-gap);\n }\n\n .heading {\n margin: 0;\n font-size: var(--calendar-heading-font-size);\n font-weight: var(--calendar-heading-font-weight);\n }\n\n .nav {\n display: grid;\n place-items: center;\n inline-size: var(--calendar-nav-size);\n block-size: var(--calendar-nav-size);\n padding: 0;\n border: none;\n border-radius: var(--calendar-nav-radius);\n background-color: transparent;\n color: var(--calendar-nav-fg);\n cursor: pointer;\n transition: background-color var(--calendar-motion-duration) var(--motion-easing-standard);\n\n &[data-hovered] {\n background-color: var(--calendar-nav-bg-hover);\n color: var(--calendar-nav-fg-hover);\n }\n\n &[data-focus-visible] {\n outline: var(--calendar-focus-ring-width) solid var(--calendar-focus-ring);\n outline-offset: var(--calendar-focus-ring-offset);\n }\n\n &[data-disabled] {\n cursor: not-allowed;\n opacity: 0.55;\n }\n }\n\n .grid {\n border-collapse: collapse;\n border-spacing: 0;\n }\n\n .weekday {\n inline-size: var(--calendar-cell-size);\n padding: 0;\n color: var(--calendar-weekday-fg);\n font-size: var(--calendar-weekday-font-size);\n font-weight: var(--calendar-weekday-font-weight);\n text-align: center;\n }\n\n .cell {\n display: grid;\n place-items: center;\n inline-size: var(--calendar-cell-size);\n block-size: var(--calendar-cell-size);\n border-radius: var(--calendar-cell-radius);\n color: var(--calendar-cell-fg);\n cursor: pointer;\n outline: none;\n transition: background-color var(--calendar-motion-duration) var(--motion-easing-standard);\n\n &[data-outside-month] {\n display: none;\n }\n\n &[data-today] {\n color: var(--calendar-cell-fg-today);\n font-weight: var(--calendar-heading-font-weight);\n }\n\n &[data-hovered] {\n background-color: var(--calendar-cell-bg-hover);\n }\n\n &[data-selected] {\n background-color: var(--calendar-cell-bg-selected);\n color: var(--calendar-cell-fg-selected);\n\n &[data-hovered] {\n background-color: var(--calendar-cell-bg-selected-hover);\n }\n }\n\n &[data-focus-visible] {\n outline: var(--calendar-focus-ring-width) solid var(--calendar-focus-ring);\n outline-offset: var(--calendar-focus-ring-offset);\n }\n\n &[data-unavailable] {\n color: var(--calendar-cell-fg-unavailable);\n text-decoration: line-through;\n cursor: not-allowed;\n }\n\n /* Disabled dims the days, not the month name, so the visible text keeps its contrast. */\n &[data-disabled] {\n color: var(--calendar-cell-fg-unavailable);\n cursor: not-allowed;\n }\n }\n}\n","import {\n Button as AriaButton,\n CalendarCell as AriaCalendarCell,\n CalendarGrid as AriaCalendarGrid,\n CalendarGridBody as AriaCalendarGridBody,\n CalendarGridHeader as AriaCalendarGridHeader,\n CalendarHeaderCell as AriaCalendarHeaderCell,\n Heading as AriaHeading,\n} from 'react-aria-components';\nimport { ChevronLeft, ChevronRight } from '@pearpages/pulp-icons';\nimport { Icon } from '../icon';\nimport styles from './Calendar.module.css';\n\n/**\n * The month view shared by Calendar and DatePicker: navigation, the visible\n * month name, weekday header and the day grid. It reads its state from the\n * vendor's calendar context, so it works inside either root. The vendor\n * names the grid for assistive technology through a visually hidden `h2`;\n * the visible month name is decorative (`aria-hidden`), which is why it is\n * a plain div and not a heading level of pulp's choosing.\n */\nexport function CalendarGrid() {\n return (\n <>\n <div className={styles.header}>\n <AriaButton slot=\"previous\" className={styles.nav}>\n <Icon size=\"inherit\">\n <ChevronLeft />\n </Icon>\n </AriaButton>\n <AriaHeading className={styles.heading} />\n <AriaButton slot=\"next\" className={styles.nav}>\n <Icon size=\"inherit\">\n <ChevronRight />\n </Icon>\n </AriaButton>\n </div>\n <AriaCalendarGrid className={styles.grid} weekdayStyle=\"short\">\n <AriaCalendarGridHeader>{(day) => <AriaCalendarHeaderCell className={styles.weekday}>{day}</AriaCalendarHeaderCell>}</AriaCalendarGridHeader>\n <AriaCalendarGridBody>{(date) => <AriaCalendarCell date={date} className={styles.cell} />}</AriaCalendarGridBody>\n </AriaCalendarGrid>\n </>\n );\n}\n\n/** The root class, for DatePicker to style the vendor calendar inside its popover. */\nexport const calendarRootClass = styles.root;\n"]}
|