@solibo/solibo-ui 1.0.13 → 1.0.15
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/assets/index.css +1 -1
- package/dist/assets/index12.css +1 -1
- package/dist/assets/index15.css +1 -1
- package/dist/assets/index16.css +1 -1
- package/dist/assets/index17.css +1 -1
- package/dist/assets/index18.css +1 -1
- package/dist/assets/index19.css +0 -1
- package/dist/assets/index20.css +1 -1
- package/dist/assets/index21.css +1 -0
- package/dist/assets/index22.css +1 -1
- package/dist/assets/index23.css +1 -1
- package/dist/assets/index24.css +1 -1
- package/dist/assets/index25.css +1 -1
- package/dist/assets/index26.css +1 -1
- package/dist/assets/index27.css +1 -1
- package/dist/assets/index28.css +1 -1
- package/dist/assets/index29.css +1 -1
- package/dist/assets/index30.css +1 -1
- package/dist/assets/index31.css +1 -1
- package/dist/assets/index32.css +1 -1
- package/dist/assets/index33.css +1 -1
- package/dist/assets/index34.css +1 -1
- package/dist/assets/index35.css +1 -1
- package/dist/assets/index36.css +1 -1
- package/dist/assets/index37.css +1 -1
- package/dist/assets/index38.css +1 -1
- package/dist/assets/index39.css +1 -1
- package/dist/assets/index40.css +1 -1
- package/dist/assets/index41.css +1 -1
- package/dist/assets/index42.css +1 -1
- package/dist/assets/index43.css +1 -1
- package/dist/assets/index44.css +1 -1
- package/dist/assets/index45.css +1 -1
- package/dist/assets/index46.css +1 -1
- package/dist/assets/index47.css +1 -1
- package/dist/assets/index48.css +1 -1
- package/dist/assets/index49.css +1 -1
- package/dist/assets/index50.css +1 -1
- package/dist/assets/index51.css +1 -1
- package/dist/assets/index6.css +1 -1
- package/dist/assets/menu-popover.css +1 -0
- package/dist/components/app-link/index.cjs +1 -1
- package/dist/components/app-link/index.js +1 -1
- package/dist/components/aside/index.cjs +1 -1
- package/dist/components/aside/index.js +1 -1
- package/dist/components/avatar/index.cjs +1 -1
- package/dist/components/avatar/index.js +1 -1
- package/dist/components/badge/index.cjs +1 -1
- package/dist/components/badge/index.js +1 -1
- package/dist/components/banner/index.cjs +1 -1
- package/dist/components/banner/index.js +1 -1
- package/dist/components/branding/index.cjs +1 -1
- package/dist/components/branding/index.js +1 -1
- package/dist/components/button/index.cjs +1 -1
- package/dist/components/button/index.js +1 -1
- package/dist/components/card/index.cjs +1 -1
- package/dist/components/card/index.js +1 -1
- package/dist/components/checkbox/index.cjs +1 -1
- package/dist/components/checkbox/index.js +2 -2
- package/dist/components/chip/index.cjs +1 -1
- package/dist/components/chip/index.cjs.map +1 -1
- package/dist/components/chip/index.js +29 -21
- package/dist/components/chip/index.js.map +1 -1
- package/dist/components/collapsible/index.cjs +1 -1
- package/dist/components/collapsible/index.js +1 -1
- package/dist/components/controls/index.cjs +1 -1
- package/dist/components/controls/index.cjs.map +1 -1
- package/dist/components/controls/index.js +108 -36
- package/dist/components/controls/index.js.map +1 -1
- package/dist/components/croppable/index.cjs +1 -1
- package/dist/components/croppable/index.js +1 -1
- package/dist/components/dialog/index.cjs +1 -1
- package/dist/components/dialog/index.js +1 -1
- package/dist/components/dropdown/index.cjs +1 -1
- package/dist/components/dropdown/index.cjs.map +1 -1
- package/dist/components/dropdown/index.js +92 -89
- package/dist/components/dropdown/index.js.map +1 -1
- package/dist/components/dropzone/index.cjs +1 -1
- package/dist/components/dropzone/index.js +1 -1
- package/dist/components/editor/index.cjs +1 -1
- package/dist/components/editor/index.js +2 -2
- package/dist/components/empty-state/index.cjs +1 -1
- package/dist/components/empty-state/index.js +1 -1
- package/dist/components/fieldset/index.cjs +1 -1
- package/dist/components/fieldset/index.js +1 -1
- package/dist/components/figure/index.cjs +1 -1
- package/dist/components/figure/index.js +1 -1
- package/dist/components/file/index.cjs +1 -1
- package/dist/components/file/index.cjs.map +1 -1
- package/dist/components/file/index.js +38 -34
- package/dist/components/file/index.js.map +1 -1
- package/dist/components/footer/index.cjs +1 -1
- package/dist/components/footer/index.js +1 -1
- package/dist/components/form/index.cjs +1 -1
- package/dist/components/form/index.js +1 -1
- package/dist/components/graph/index.cjs +1 -1
- package/dist/components/graph/index.js +1 -1
- package/dist/components/group/index.cjs +1 -1
- package/dist/components/group/index.js +1 -1
- package/dist/components/header/index.cjs +1 -1
- package/dist/components/header/index.js +12 -12
- package/dist/components/icon/index.cjs +1 -1
- package/dist/components/icon/index.js +2 -2
- package/dist/components/iframe/index.cjs +1 -1
- package/dist/components/iframe/index.js +1 -1
- package/dist/components/image/index.cjs +1 -1
- package/dist/components/image/index.js +1 -1
- package/dist/components/input/index.cjs +1 -1
- package/dist/components/input/index.js +3 -3
- package/dist/components/link/index.cjs +1 -1
- package/dist/components/link/index.js +1 -1
- package/dist/components/list/index.cjs +1 -1
- package/dist/components/list/index.cjs.map +1 -1
- package/dist/components/list/index.js +39 -36
- package/dist/components/list/index.js.map +1 -1
- package/dist/components/loading/index.cjs +1 -1
- package/dist/components/loading/index.js +1 -1
- package/dist/components/menu/index.cjs +1 -1
- package/dist/components/menu/index.cjs.map +1 -1
- package/dist/components/menu/index.js +37 -87
- package/dist/components/menu/index.js.map +1 -1
- package/dist/components/message/index.cjs +1 -1
- package/dist/components/message/index.cjs.map +1 -1
- package/dist/components/message/index.js +25 -25
- package/dist/components/nav/index.cjs +1 -1
- package/dist/components/nav/index.js +21 -21
- package/dist/components/popover/index.cjs +1 -1
- package/dist/components/popover/index.cjs.map +1 -1
- package/dist/components/popover/index.js +46 -50
- package/dist/components/popover/index.js.map +1 -1
- package/dist/components/search/index.cjs +1 -1
- package/dist/components/search/index.cjs.map +1 -1
- package/dist/components/search/index.js +48 -50
- package/dist/components/search/index.js.map +1 -1
- package/dist/components/select/index.cjs +1 -1
- package/dist/components/select/index.js +3 -3
- package/dist/components/textarea/index.cjs +1 -1
- package/dist/components/textarea/index.cjs.map +1 -1
- package/dist/components/textarea/index.js +25 -21
- package/dist/components/textarea/index.js.map +1 -1
- package/dist/components/toolbar/index.cjs +1 -1
- package/dist/components/toolbar/index.js +1 -1
- package/dist/icons-DaZGJzI0.cjs +2 -0
- package/dist/icons-DaZGJzI0.cjs.map +1 -0
- package/dist/{icons-Bq3diTRm.js → icons-Dj0vEOCB.js} +2 -1
- package/dist/icons-Dj0vEOCB.js.map +1 -0
- package/dist/{index-DwzLUapm.js → index-CgA0NUMD.js} +35 -33
- package/dist/index-CgA0NUMD.js.map +1 -0
- package/dist/index-DE2nzqL5.js +76 -0
- package/dist/index-DE2nzqL5.js.map +1 -0
- package/dist/index-DF8JisYI.cjs +2 -0
- package/dist/index-DF8JisYI.cjs.map +1 -0
- package/dist/index-Dn1v0qm6.cjs +2 -0
- package/dist/index-Dn1v0qm6.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +30 -9
- package/dist/index.js +2 -2
- package/dist/menu-popover-SiOOwab-.js +74 -0
- package/dist/menu-popover-SiOOwab-.js.map +1 -0
- package/dist/menu-popover-jTTxzTGZ.cjs +2 -0
- package/dist/menu-popover-jTTxzTGZ.cjs.map +1 -0
- package/dist/tokens.json +1 -1
- package/dist/use-touched-B999bBr8.js +20 -0
- package/dist/use-touched-B999bBr8.js.map +1 -0
- package/dist/use-touched-Bq5Gjbpz.cjs +2 -0
- package/dist/use-touched-Bq5Gjbpz.cjs.map +1 -0
- package/package.json +1 -1
- package/dist/assets/index52.css +0 -1
- package/dist/icons-Bq3diTRm.js.map +0 -1
- package/dist/icons-ovA21Oao.cjs +0 -2
- package/dist/icons-ovA21Oao.cjs.map +0 -1
- package/dist/index-BcY9DZZ8.cjs +0 -2
- package/dist/index-BcY9DZZ8.cjs.map +0 -1
- package/dist/index-CjI8oRpS.cjs +0 -2
- package/dist/index-CjI8oRpS.cjs.map +0 -1
- package/dist/index-ClZkChEh.js +0 -73
- package/dist/index-ClZkChEh.js.map +0 -1
- package/dist/index-DwzLUapm.js.map +0 -1
- package/dist/use-touched-DXIJVVzz.js +0 -14
- package/dist/use-touched-DXIJVVzz.js.map +0 -1
- package/dist/use-touched-D_TJ8wDc.cjs +0 -2
- package/dist/use-touched-D_TJ8wDc.cjs.map +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import { t as
|
|
3
|
-
import { useRef as
|
|
1
|
+
import { jsx as k, jsxs as O } from "react/jsx-runtime";
|
|
2
|
+
import { t as z } from "../../classix-DG18itHa.js";
|
|
3
|
+
import { useRef as g, useId as H, useState as h, useCallback as C, useEffect as W, useLayoutEffect as S } from "react";
|
|
4
4
|
import { createPortal as U } from "react-dom";
|
|
5
5
|
import { Button as X } from "../button/index.js";
|
|
6
|
-
import '../../assets/
|
|
6
|
+
import '../../assets/index49.css';const Y = "_popover_1e3fx_1", q = "_inline_1e3fx_6", G = "_below_1e3fx_42", J = "_above_1e3fx_47", M = "_left_1e3fx_57", Q = "_right_1e3fx_62", V = "_trigger_1e3fx_67", n = {
|
|
7
7
|
popover: Y,
|
|
8
8
|
inline: q,
|
|
9
9
|
"popover-panel": "_popover-panel_1e3fx_21",
|
|
@@ -15,37 +15,33 @@ import '../../assets/index17.css';const Y = "_popover_1e3fx_1", q = "_inline_1e3
|
|
|
15
15
|
trigger: V,
|
|
16
16
|
"inline-trigger": "_inline-trigger_1e3fx_77"
|
|
17
17
|
}, ie = ({
|
|
18
|
-
children:
|
|
19
|
-
inline:
|
|
20
|
-
triggerAccessibleLabel:
|
|
21
|
-
triggerAriaHasPopup:
|
|
22
|
-
triggerButtonContent:
|
|
18
|
+
children: v,
|
|
19
|
+
inline: i = !1,
|
|
20
|
+
triggerAccessibleLabel: L,
|
|
21
|
+
triggerAriaHasPopup: T,
|
|
22
|
+
triggerButtonContent: F
|
|
23
23
|
}) => {
|
|
24
|
-
var
|
|
25
|
-
const
|
|
24
|
+
var E;
|
|
25
|
+
const b = g(null), x = g(void 0), m = g(null), y = H(), f = g(null), [t, P] = h(!1), [p, D] = h(!1), [u, B] = h("right"), w = ({
|
|
26
26
|
initialFocus: e
|
|
27
27
|
} = {}) => {
|
|
28
|
-
|
|
29
|
-
},
|
|
28
|
+
x.current = e, D(!1), B("right"), P(!0);
|
|
29
|
+
}, a = C(({
|
|
30
30
|
restoreFocus: e = !0
|
|
31
31
|
} = {}) => {
|
|
32
|
-
var
|
|
33
|
-
|
|
34
|
-
}, []),
|
|
35
|
-
t && e.key === "Escape" &&
|
|
32
|
+
var r;
|
|
33
|
+
P(!1), e && ((r = f.current) == null || r.focus());
|
|
34
|
+
}, []), A = (e) => {
|
|
35
|
+
t && e.key === "Escape" && a();
|
|
36
36
|
}, K = (e) => {
|
|
37
37
|
if (!t) {
|
|
38
|
-
if (o && (e.key === "Enter" || e.key === " ")) {
|
|
39
|
-
e.preventDefault(), d();
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
38
|
if (e.key === "ArrowDown") {
|
|
43
|
-
e.preventDefault(),
|
|
39
|
+
e.preventDefault(), w({
|
|
44
40
|
initialFocus: "first"
|
|
45
41
|
});
|
|
46
42
|
return;
|
|
47
43
|
}
|
|
48
|
-
e.key === "ArrowUp" && (e.preventDefault(),
|
|
44
|
+
e.key === "ArrowUp" && (e.preventDefault(), w({
|
|
49
45
|
initialFocus: "last"
|
|
50
46
|
}));
|
|
51
47
|
}
|
|
@@ -53,22 +49,22 @@ import '../../assets/index17.css';const Y = "_popover_1e3fx_1", q = "_inline_1e3
|
|
|
53
49
|
W(() => {
|
|
54
50
|
if (!t)
|
|
55
51
|
return;
|
|
56
|
-
const e = (
|
|
57
|
-
var
|
|
58
|
-
const
|
|
59
|
-
(
|
|
52
|
+
const e = (r) => {
|
|
53
|
+
var o, d;
|
|
54
|
+
const c = r.target;
|
|
55
|
+
(o = b.current) != null && o.contains(c) || (d = m.current) != null && d.contains(c) || a({
|
|
60
56
|
restoreFocus: !1
|
|
61
57
|
});
|
|
62
58
|
};
|
|
63
59
|
return document.addEventListener("mousedown", e), () => {
|
|
64
60
|
document.removeEventListener("mousedown", e);
|
|
65
61
|
};
|
|
66
|
-
}, [
|
|
62
|
+
}, [a, t]);
|
|
67
63
|
const s = C(() => {
|
|
68
|
-
const e =
|
|
69
|
-
if (!e || !
|
|
70
|
-
const
|
|
71
|
-
|
|
64
|
+
const e = m.current, r = f.current;
|
|
65
|
+
if (!e || !r) return;
|
|
66
|
+
const c = e.getBoundingClientRect(), o = r.getBoundingClientRect(), d = o.top, R = window.innerHeight - o.bottom;
|
|
67
|
+
D(c.height > R && d > R), B(c.width > window.innerWidth - o.left && o.right > window.innerWidth - o.left ? "left" : "right");
|
|
72
68
|
}, []);
|
|
73
69
|
S(() => {
|
|
74
70
|
if (t)
|
|
@@ -77,32 +73,32 @@ import '../../assets/index17.css';const Y = "_popover_1e3fx_1", q = "_inline_1e3
|
|
|
77
73
|
};
|
|
78
74
|
}, [t, s]);
|
|
79
75
|
const j = (e) => {
|
|
80
|
-
e.preventDefault(), e.stopPropagation(), t ?
|
|
76
|
+
e.preventDefault(), e.stopPropagation(), t ? a({
|
|
81
77
|
restoreFocus: !1
|
|
82
|
-
}) :
|
|
83
|
-
},
|
|
84
|
-
"aria-controls": t ?
|
|
78
|
+
}) : w();
|
|
79
|
+
}, I = {
|
|
80
|
+
"aria-controls": t ? y : void 0,
|
|
85
81
|
"aria-expanded": t,
|
|
86
|
-
"aria-haspopup":
|
|
87
|
-
"aria-label":
|
|
88
|
-
className:
|
|
82
|
+
"aria-haspopup": T,
|
|
83
|
+
"aria-label": L,
|
|
84
|
+
className: i ? n["inline-trigger"] : n.trigger,
|
|
89
85
|
onClick: j,
|
|
90
86
|
onKeyDown: K
|
|
91
|
-
},
|
|
92
|
-
left: u === "left" ?
|
|
87
|
+
}, l = i ? (E = f.current) == null ? void 0 : E.getBoundingClientRect() : void 0, N = [u === "left" ? "translateX(-100%)" : "", p ? "translateY(calc(-100% - var(--shape-spacing-2xs)))" : ""].filter(Boolean).join(" "), _ = t ? /* @__PURE__ */ k("div", { className: z(n["popover-panel"], n[p ? "above" : "below"], i && n["inline-panel"], !i && n[u]), "data-horizontal-placement": u, "data-placement": p ? "above" : "below", id: y, ref: m, style: l ? {
|
|
88
|
+
left: u === "left" ? l.right : l.left,
|
|
93
89
|
position: "fixed",
|
|
94
|
-
top: p ?
|
|
90
|
+
top: p ? l.top : l.bottom,
|
|
95
91
|
transform: N || void 0
|
|
96
|
-
} : void 0, children: typeof
|
|
97
|
-
close:
|
|
98
|
-
initialFocus:
|
|
92
|
+
} : void 0, children: typeof v == "function" ? v({
|
|
93
|
+
close: a,
|
|
94
|
+
initialFocus: x.current,
|
|
99
95
|
isOpen: t
|
|
100
|
-
}) :
|
|
101
|
-
return /* @__PURE__ */ O("div", { className:
|
|
96
|
+
}) : v }) : null;
|
|
97
|
+
return /* @__PURE__ */ O("div", { className: z(n.popover, i && n.inline), "data-open": t, onKeyDown: A, onClick: (e) => {
|
|
102
98
|
e.preventDefault(), e.stopPropagation();
|
|
103
|
-
}, ref:
|
|
104
|
-
|
|
105
|
-
|
|
99
|
+
}, ref: b, "data-component": "popover", children: [
|
|
100
|
+
/* @__PURE__ */ k(X, { ...I, ref: f, variant: "simple", children: F }),
|
|
101
|
+
i && _ && typeof document < "u" ? U(_, document.body) : _
|
|
106
102
|
] });
|
|
107
103
|
};
|
|
108
104
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/components/popover/index.tsx"],"sourcesContent":["import cx from 'classix';\nimport {\n type AriaAttributes,\n type ReactNode,\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\nimport { createPortal } from 'react-dom';\n\nimport { Button } from '@/components/button';\n\nimport styles from './styles.module.css';\n\nexport type PopoverCloseOptions = {\n restoreFocus?: boolean;\n};\n\nexport type PopoverInitialFocus = 'first' | 'last';\n\nexport type PopoverRenderProps = {\n close: (options?: PopoverCloseOptions) => void;\n initialFocus?: PopoverInitialFocus;\n isOpen: boolean;\n};\n\ntype PopoverOpenOptions = {\n initialFocus?: PopoverInitialFocus;\n};\n\nexport type PopoverProps = {\n children: ReactNode | ((props: PopoverRenderProps) => ReactNode);\n inline?: boolean;\n triggerAccessibleLabel?: string;\n triggerAriaHasPopup?: AriaAttributes['aria-haspopup'];\n triggerButtonContent: ReactNode;\n};\n\nexport const Popover = ({\n children,\n inline = false,\n triggerAccessibleLabel,\n triggerAriaHasPopup,\n triggerButtonContent,\n}: PopoverProps) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const initialFocusRef = useRef<PopoverInitialFocus | undefined>(undefined);\n const panelRef = useRef<HTMLDivElement>(null);\n const panelId = useId();\n const triggerRef = useRef<HTMLButtonElement | HTMLSpanElement>(null);\n const [isOpen, setIsOpen] = useState(false);\n const [opensAbove, setOpensAbove] = useState(false);\n const [horizontalPlacement, setHorizontalPlacement] = useState<'left' | 'right'>('right');\n\n const openPopover = ({ initialFocus }: PopoverOpenOptions = {}) => {\n initialFocusRef.current = initialFocus;\n setOpensAbove(false);\n setHorizontalPlacement('right');\n setIsOpen(true);\n };\n\n const closePopover = useCallback(({ restoreFocus = true }: PopoverCloseOptions = {}) => {\n setIsOpen(false);\n\n if (restoreFocus) {\n triggerRef.current?.focus();\n }\n }, []);\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (isOpen && event.key === 'Escape') {\n closePopover();\n }\n };\n\n const handleTriggerKeyDown = (event: React.KeyboardEvent<HTMLElement>) => {\n if (isOpen) {\n return;\n }\n\n if (inline && (event.key === 'Enter' || event.key === ' ')) {\n event.preventDefault();\n openPopover();\n return;\n }\n\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n openPopover({ initialFocus: 'first' });\n return;\n }\n\n if (event.key === 'ArrowUp') {\n event.preventDefault();\n openPopover({ initialFocus: 'last' });\n }\n };\n\n useEffect(() => {\n if (!isOpen) {\n return;\n }\n\n const handlePointerDown = (event: MouseEvent) => {\n const target = event.target as Node;\n if (containerRef.current?.contains(target) || panelRef.current?.contains(target)) return;\n\n closePopover({ restoreFocus: false });\n };\n\n document.addEventListener('mousedown', handlePointerDown);\n\n return () => {\n document.removeEventListener('mousedown', handlePointerDown);\n };\n }, [closePopover, isOpen]);\n\n const updatePosition = useCallback(() => {\n const panel = panelRef.current;\n const trigger = triggerRef.current;\n if (!panel || !trigger) return;\n\n const panelBounds = panel.getBoundingClientRect();\n const triggerBounds = trigger.getBoundingClientRect();\n const spaceAbove = triggerBounds.top;\n const spaceBelow = window.innerHeight - triggerBounds.bottom;\n\n setOpensAbove(panelBounds.height > spaceBelow && spaceAbove > spaceBelow);\n setHorizontalPlacement(\n panelBounds.width > window.innerWidth - triggerBounds.left &&\n triggerBounds.right > window.innerWidth - triggerBounds.left\n ? 'left'\n : 'right'\n );\n }, []);\n\n useLayoutEffect(() => {\n if (!isOpen) return undefined;\n\n updatePosition();\n window.addEventListener('resize', updatePosition);\n window.addEventListener('scroll', updatePosition, true);\n\n return () => {\n window.removeEventListener('resize', updatePosition);\n window.removeEventListener('scroll', updatePosition, true);\n };\n }, [isOpen, updatePosition]);\n\n const handleTriggerClick = (event: React.MouseEvent<HTMLElement>) => {\n event.preventDefault();\n event.stopPropagation();\n if (isOpen) {\n closePopover({ restoreFocus: false });\n } else {\n openPopover();\n }\n };\n\n const triggerProps = {\n 'aria-controls': isOpen ? panelId : undefined,\n 'aria-expanded': isOpen,\n 'aria-haspopup': triggerAriaHasPopup,\n 'aria-label': triggerAccessibleLabel,\n className: inline ? styles['inline-trigger'] : styles.trigger,\n onClick: handleTriggerClick,\n onKeyDown: handleTriggerKeyDown,\n };\n\n const triggerBounds = inline ? triggerRef.current?.getBoundingClientRect() : undefined;\n const horizontalTransform = horizontalPlacement === 'left' ? 'translateX(-100%)' : '';\n const verticalTransform = opensAbove ? 'translateY(calc(-100% - var(--shape-spacing-2xs)))' : '';\n const inlineTransform = [horizontalTransform, verticalTransform].filter(Boolean).join(' ');\n const panel = isOpen ? (\n <div\n className={cx(\n styles['popover-panel'],\n styles[opensAbove ? 'above' : 'below'],\n inline && styles['inline-panel'],\n !inline && styles[horizontalPlacement]\n )}\n data-horizontal-placement={horizontalPlacement}\n data-placement={opensAbove ? 'above' : 'below'}\n id={panelId}\n ref={panelRef}\n style={\n triggerBounds\n ? {\n left: horizontalPlacement === 'left' ? triggerBounds.right : triggerBounds.left,\n position: 'fixed',\n top: opensAbove ? triggerBounds.top : triggerBounds.bottom,\n transform: inlineTransform || undefined,\n }\n : undefined\n }\n >\n {typeof children === 'function'\n ? children({ close: closePopover, initialFocus: initialFocusRef.current, isOpen })\n : children}\n </div>\n ) : null;\n\n return (\n <div\n className={cx(styles.popover, inline && styles.inline)}\n data-open={isOpen}\n onKeyDown={handleKeyDown}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n ref={containerRef}\n >\n {inline ? (\n <span\n {...triggerProps}\n ref={triggerRef}\n role='button'\n tabIndex={0}\n >\n {triggerButtonContent}\n </span>\n ) : (\n <Button\n {...triggerProps}\n ref={triggerRef as React.Ref<HTMLButtonElement>}\n variant='simple'\n >\n {triggerButtonContent}\n </Button>\n )}\n {inline && panel && typeof document !== 'undefined'\n ? createPortal(panel, document.body)\n : panel}\n </div>\n );\n};\n"],"names":["Popover","children","inline","triggerAccessibleLabel","triggerAriaHasPopup","triggerButtonContent","containerRef","useRef","initialFocusRef","undefined","panelRef","panelId","useId","triggerRef","isOpen","setIsOpen","useState","opensAbove","setOpensAbove","horizontalPlacement","setHorizontalPlacement","openPopover","initialFocus","current","closePopover","useCallback","restoreFocus","focus","handleKeyDown","event","key","handleTriggerKeyDown","preventDefault","useEffect","handlePointerDown","target","contains","document","addEventListener","removeEventListener","updatePosition","panel","trigger","panelBounds","getBoundingClientRect","triggerBounds","spaceAbove","top","spaceBelow","window","innerHeight","bottom","height","width","innerWidth","left","right","useLayoutEffect","handleTriggerClick","stopPropagation","triggerProps","className","styles","onClick","onKeyDown","inlineTransform","filter","Boolean","join","jsx","cx","position","transform","close","jsxs","popover","Button","createPortal","body"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/popover/index.tsx"],"sourcesContent":["import cx from 'classix';\nimport {\n type AriaAttributes,\n type ReactNode,\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\nimport { createPortal } from 'react-dom';\n\nimport { Button } from '@/components/button';\n\nimport styles from './styles.module.css';\n\nexport type PopoverCloseOptions = {\n restoreFocus?: boolean;\n};\n\nexport type PopoverInitialFocus = 'first' | 'last';\n\nexport type PopoverRenderProps = {\n close: (options?: PopoverCloseOptions) => void;\n initialFocus?: PopoverInitialFocus;\n isOpen: boolean;\n};\n\ntype PopoverOpenOptions = {\n initialFocus?: PopoverInitialFocus;\n};\n\nexport type PopoverProps = {\n children: ReactNode | ((props: PopoverRenderProps) => ReactNode);\n inline?: boolean;\n triggerAccessibleLabel?: string;\n triggerAriaHasPopup?: AriaAttributes['aria-haspopup'];\n triggerButtonContent: ReactNode;\n};\n\nexport const Popover = ({\n children,\n inline = false,\n triggerAccessibleLabel,\n triggerAriaHasPopup,\n triggerButtonContent,\n}: PopoverProps) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const initialFocusRef = useRef<PopoverInitialFocus | undefined>(undefined);\n const panelRef = useRef<HTMLDivElement>(null);\n const panelId = useId();\n const triggerRef = useRef<HTMLButtonElement>(null);\n const [isOpen, setIsOpen] = useState(false);\n const [opensAbove, setOpensAbove] = useState(false);\n const [horizontalPlacement, setHorizontalPlacement] = useState<'left' | 'right'>('right');\n\n const openPopover = ({ initialFocus }: PopoverOpenOptions = {}) => {\n initialFocusRef.current = initialFocus;\n setOpensAbove(false);\n setHorizontalPlacement('right');\n setIsOpen(true);\n };\n\n const closePopover = useCallback(({ restoreFocus = true }: PopoverCloseOptions = {}) => {\n setIsOpen(false);\n\n if (restoreFocus) {\n triggerRef.current?.focus();\n }\n }, []);\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (isOpen && event.key === 'Escape') {\n closePopover();\n }\n };\n\n const handleTriggerKeyDown = (event: React.KeyboardEvent<HTMLElement>) => {\n if (isOpen) {\n return;\n }\n\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n openPopover({ initialFocus: 'first' });\n return;\n }\n\n if (event.key === 'ArrowUp') {\n event.preventDefault();\n openPopover({ initialFocus: 'last' });\n }\n };\n\n useEffect(() => {\n if (!isOpen) {\n return;\n }\n\n const handlePointerDown = (event: MouseEvent) => {\n const target = event.target as Node;\n if (containerRef.current?.contains(target) || panelRef.current?.contains(target)) return;\n\n closePopover({ restoreFocus: false });\n };\n\n document.addEventListener('mousedown', handlePointerDown);\n\n return () => {\n document.removeEventListener('mousedown', handlePointerDown);\n };\n }, [closePopover, isOpen]);\n\n const updatePosition = useCallback(() => {\n const panel = panelRef.current;\n const trigger = triggerRef.current;\n if (!panel || !trigger) return;\n\n const panelBounds = panel.getBoundingClientRect();\n const triggerBounds = trigger.getBoundingClientRect();\n const spaceAbove = triggerBounds.top;\n const spaceBelow = window.innerHeight - triggerBounds.bottom;\n\n setOpensAbove(panelBounds.height > spaceBelow && spaceAbove > spaceBelow);\n setHorizontalPlacement(\n panelBounds.width > window.innerWidth - triggerBounds.left &&\n triggerBounds.right > window.innerWidth - triggerBounds.left\n ? 'left'\n : 'right'\n );\n }, []);\n\n useLayoutEffect(() => {\n if (!isOpen) return undefined;\n\n updatePosition();\n window.addEventListener('resize', updatePosition);\n window.addEventListener('scroll', updatePosition, true);\n\n return () => {\n window.removeEventListener('resize', updatePosition);\n window.removeEventListener('scroll', updatePosition, true);\n };\n }, [isOpen, updatePosition]);\n\n const handleTriggerClick = (event: React.MouseEvent<HTMLElement>) => {\n event.preventDefault();\n event.stopPropagation();\n if (isOpen) {\n closePopover({ restoreFocus: false });\n } else {\n openPopover();\n }\n };\n\n const triggerProps = {\n 'aria-controls': isOpen ? panelId : undefined,\n 'aria-expanded': isOpen,\n 'aria-haspopup': triggerAriaHasPopup,\n 'aria-label': triggerAccessibleLabel,\n className: inline ? styles['inline-trigger'] : styles.trigger,\n onClick: handleTriggerClick,\n onKeyDown: handleTriggerKeyDown,\n };\n\n const triggerBounds = inline ? triggerRef.current?.getBoundingClientRect() : undefined;\n const horizontalTransform = horizontalPlacement === 'left' ? 'translateX(-100%)' : '';\n const verticalTransform = opensAbove ? 'translateY(calc(-100% - var(--shape-spacing-2xs)))' : '';\n const inlineTransform = [horizontalTransform, verticalTransform].filter(Boolean).join(' ');\n const panel = isOpen ? (\n <div\n className={cx(\n styles['popover-panel'],\n styles[opensAbove ? 'above' : 'below'],\n inline && styles['inline-panel'],\n !inline && styles[horizontalPlacement]\n )}\n data-horizontal-placement={horizontalPlacement}\n data-placement={opensAbove ? 'above' : 'below'}\n id={panelId}\n ref={panelRef}\n style={\n triggerBounds\n ? {\n left: horizontalPlacement === 'left' ? triggerBounds.right : triggerBounds.left,\n position: 'fixed',\n top: opensAbove ? triggerBounds.top : triggerBounds.bottom,\n transform: inlineTransform || undefined,\n }\n : undefined\n }\n >\n {typeof children === 'function'\n ? children({ close: closePopover, initialFocus: initialFocusRef.current, isOpen })\n : children}\n </div>\n ) : null;\n\n return (\n <div\n className={cx(styles.popover, inline && styles.inline)}\n data-open={isOpen}\n onKeyDown={handleKeyDown}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n ref={containerRef}\n >\n <Button\n {...triggerProps}\n ref={triggerRef}\n variant='simple'\n >\n {triggerButtonContent}\n </Button>\n {inline && panel && typeof document !== 'undefined'\n ? createPortal(panel, document.body)\n : panel}\n </div>\n );\n};\n"],"names":["Popover","children","inline","triggerAccessibleLabel","triggerAriaHasPopup","triggerButtonContent","containerRef","useRef","initialFocusRef","undefined","panelRef","panelId","useId","triggerRef","isOpen","setIsOpen","useState","opensAbove","setOpensAbove","horizontalPlacement","setHorizontalPlacement","openPopover","initialFocus","current","closePopover","useCallback","restoreFocus","focus","handleKeyDown","event","key","handleTriggerKeyDown","preventDefault","useEffect","handlePointerDown","target","contains","document","addEventListener","removeEventListener","updatePosition","panel","trigger","panelBounds","getBoundingClientRect","triggerBounds","spaceAbove","top","spaceBelow","window","innerHeight","bottom","height","width","innerWidth","left","right","useLayoutEffect","handleTriggerClick","stopPropagation","triggerProps","className","styles","onClick","onKeyDown","inlineTransform","filter","Boolean","join","jsx","cx","position","transform","close","jsxs","popover","Button","createPortal","body"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require('../../assets/index9.css');const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require('../../assets/index9.css');const a=require("react/jsx-runtime"),_=require("react"),m=require("../button/index.cjs"),w=require("../checkbox/index.cjs"),B=require("../chip/index.cjs"),I=require("../collapsible/index.cjs"),T=require("../controls/index.cjs"),H=require("../dialog/index.cjs"),P=require("../header/index.cjs"),z=require("../../index-DF8JisYI.cjs"),A="_search_bp8f4_3",E="_controls_bp8f4_15",J="_chips_bp8f4_29",K="_radio_bp8f4_84",n={search:A,controls:E,chips:J,"filter-dialog":"_filter-dialog_bp8f4_36","filter-groups":"_filter-groups_bp8f4_41","filter-group":"_filter-group_bp8f4_41","filter-option":"_filter-option_bp8f4_66","option-copy":"_option-copy_bp8f4_72",radio:K,"collapsible-options":"_collapsible-options_bp8f4_111"},L=({closeLabel:N="Close",filterButtonLabel:x="Filters",filterDialogColumns:q=1,filterDialogTitle:k="Filters",filterGroups:d=[],onChange:$,onSelectedFiltersChange:o,removeFilterLabel:M=i=>`Remove ${i.label} filter`,resetLabel:O="Reset",searchLabel:C="Search",searchPlaceholder:D="Search",selectedFilters:t=[],value:R=""})=>{const i=_.useId(),[j,r]=_.useState(!1),S=_.useMemo(()=>new Map(d.flatMap(e=>{var l;return[...e.options,...((l=e.collapsible)==null?void 0:l.options)??[]]}).map(e=>[e.value,e])),[d]),p=t.flatMap(e=>{const l=S.get(e);return l?[l]:[]}),h=(e,l,s)=>{var y;if(!o)return;const b=new Set([...(s==null?void 0:s.options.map(c=>c.value))??[],...((y=s==null?void 0:s.collapsible)==null?void 0:y.options.map(c=>c.value))??[]]),u=t.filter(c=>!b.has(c));if(l&&(s==null?void 0:s.defaultValue)===e){o(u);return}o(l?(s==null?void 0:s.control)==="radio"||(s==null?void 0:s.selectionMode)==="single"?[...u,e]:[...new Set([...t,e])]:t.filter(c=>c!==e))},v=(e,l)=>{var s;return t.includes(e)||l.defaultValue===e&&![...l.options,...((s=l.collapsible)==null?void 0:s.options)??[]].some(b=>t.includes(b.value))},f=(e,l)=>a.jsx("div",{className:n["filter-option"],"data-component":"renderfilter",children:l.control==="radio"?a.jsxs("label",{className:n.radio,children:[a.jsx("input",{checked:v(e.value,l),name:`${i}-filter-${l.label??"group"}`,onChange:s=>h(e.value,s.target.checked,l),type:"radio"}),a.jsxs("span",{className:n["option-copy"],children:[e.label,e.description&&a.jsx("sub",{children:e.description})]})]}):a.jsx(w.Checkbox,{checked:v(e.value,l),label:a.jsxs("span",{className:n["option-copy"],children:[e.label,e.description&&a.jsx("sub",{children:e.description})]}),onChange:s=>h(e.value,s.target.checked,l)})},e.value);return a.jsxs("div",{className:n.search,"data-component":"search",children:[a.jsxs("div",{className:n.controls,children:[a.jsx(z.Input,{"aria-label":C,icon:"search",onChange:e=>$(e.target.value),placeholder:D,type:"search",value:R}),d.length>0&&a.jsx(m.Button,{"aria-expanded":j,"aria-haspopup":"dialog",badge:p.length,icon:"funnel",onClick:()=>r(!0),variant:"tertiary",children:x})]}),p.length>0&&a.jsxs("div",{"aria-label":x,className:n.chips,children:[p.map(e=>a.jsx(B.Chip,{accessibleLabel:M(e),label:e.label,onDelete:()=>h(e.value,!1)},e.value)),a.jsx(m.Button,{onClick:()=>o==null?void 0:o([]),variant:"tertiary",children:O})]}),j&&a.jsx(H.Dialog,{"aria-labelledby":i,className:n["filter-dialog"],controls:a.jsx(T.Controls,{children:a.jsx(m.Button,{onClick:()=>r(!1),children:N})}),header:a.jsx(P.Header,{children:a.jsx("h2",{id:i,children:k})}),open:!0,setOpen:r,children:a.jsx("div",{className:n["filter-groups"],"data-columns":q,children:d.map((e,l)=>a.jsxs("section",{"aria-labelledby":e.label?`${i}-${l}`:void 0,className:n["filter-group"],"data-column-span":e.columnSpan??1,role:e.control==="radio"?"radiogroup":"group",children:[e.label&&a.jsx("h3",{id:`${i}-${l}`,children:e.label}),e.options.map(s=>f(s,e)),e.collapsible&&a.jsx(I.Collapsible,{summary:e.collapsible.label,children:a.jsx("div",{className:n["collapsible-options"],children:e.collapsible.options.map(s=>f(s,e))})})]},e.label??l))})})]})};exports.Search=L;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../src/components/search/index.tsx"],"sourcesContent":["import { useId, useMemo, useState } from 'react';\n\nimport { Button } from '../button';\nimport { Checkbox } from '../checkbox';\nimport { Chip } from '../chip';\nimport { Collapsible } from '../collapsible';\nimport { Controls } from '../controls';\nimport { Dialog } from '../dialog';\nimport { Header } from '../header';\nimport { Input } from '../input';\nimport styles from './styles.module.css';\n\nexport type SearchFilter = {\n description?: string;\n label: string;\n value: string;\n};\n\nexport type SearchFilterGroup = {\n collapsible?: {\n label: string;\n options: readonly SearchFilter[];\n };\n columnSpan?: 1 | 2;\n control?: 'checkbox' | 'radio';\n defaultValue?: string;\n label?: string;\n options: readonly SearchFilter[];\n selectionMode?: 'multiple' | 'single';\n};\n\nexport type SearchProps = {\n closeLabel?: string;\n filterButtonLabel?: string;\n filterDialogColumns?: 1 | 2;\n filterDialogTitle?: string;\n filterGroups?: readonly SearchFilterGroup[];\n onChange: (value: string) => void;\n onSelectedFiltersChange?: (selectedFilters: string[]) => void;\n removeFilterLabel?: (filter: SearchFilter) => string;\n resetLabel?: string;\n searchLabel?: string;\n searchPlaceholder?: string;\n selectedFilters?: readonly string[];\n value?: string;\n};\n\nexport const Search = ({\n closeLabel = 'Close',\n filterButtonLabel = 'Filters',\n filterDialogColumns = 1,\n filterDialogTitle = 'Filters',\n filterGroups = [],\n onChange,\n onSelectedFiltersChange,\n removeFilterLabel = (filter) => `Remove ${filter.label} filter`,\n resetLabel = 'Reset',\n searchLabel = 'Search',\n searchPlaceholder = 'Search',\n selectedFilters = [],\n value = '',\n}: SearchProps) => {\n const dialogTitleId = useId();\n const [isFilterDialogOpen, setIsFilterDialogOpen] = useState(false);\n const filtersByValue = useMemo(\n () =>\n new Map(\n filterGroups\n .flatMap((group) => [...group.options, ...(group.collapsible?.options ?? [])])\n .map((filter) => [filter.value, filter])\n ),\n [filterGroups]\n );\n const activeFilters = selectedFilters.flatMap((selectedFilter) => {\n const filter = filtersByValue.get(selectedFilter);\n\n return filter ? [filter] : [];\n });\n\n const setFilterSelected = (\n filterValue: string,\n isSelected: boolean,\n group?: SearchFilterGroup\n ) => {\n if (!onSelectedFiltersChange) return;\n\n const groupValues = new Set([\n ...(group?.options.map((filter) => filter.value) ?? []),\n ...(group?.collapsible?.options.map((filter) => filter.value) ?? []),\n ]);\n const filtersOutsideGroup = selectedFilters.filter(\n (selectedFilter) => !groupValues.has(selectedFilter)\n );\n\n if (isSelected && group?.defaultValue === filterValue) {\n onSelectedFiltersChange(filtersOutsideGroup);\n return;\n }\n\n onSelectedFiltersChange(\n isSelected\n ? group?.control === 'radio' || group?.selectionMode === 'single'\n ? [...filtersOutsideGroup, filterValue]\n : [...new Set([...selectedFilters, filterValue])]\n : selectedFilters.filter((selectedFilter) => selectedFilter !== filterValue)\n );\n };\n\n const isFilterSelected = (filterValue: string, group: SearchFilterGroup) =>\n selectedFilters.includes(filterValue) ||\n (group.defaultValue === filterValue &&\n ![...group.options, ...(group.collapsible?.options ?? [])].some((filter) =>\n selectedFilters.includes(filter.value)\n ));\n\n const renderFilter = (filter: SearchFilter, group: SearchFilterGroup) => (\n <div\n className={styles['filter-option']}\n key={filter.value}\n >\n {group.control === 'radio' ? (\n <label className={styles.radio}>\n <input\n checked={isFilterSelected(filter.value, group)}\n name={`${dialogTitleId}-filter-${group.label ?? 'group'}`}\n onChange={(event) => setFilterSelected(filter.value, event.target.checked, group)}\n type='radio'\n />\n <span className={styles['option-copy']}>\n {filter.label}\n {filter.description && <sub>{filter.description}</sub>}\n </span>\n </label>\n ) : (\n <Checkbox\n checked={isFilterSelected(filter.value, group)}\n label={\n <span className={styles['option-copy']}>\n {filter.label}\n {filter.description && <sub>{filter.description}</sub>}\n </span>\n }\n onChange={(event) => setFilterSelected(filter.value, event.target.checked, group)}\n />\n )}\n </div>\n );\n\n return (\n <div\n className={styles.search}\n data-component='search'\n >\n <div className={styles.controls}>\n <Input\n aria-label={searchLabel}\n icon='search'\n onChange={(event) => onChange(event.target.value)}\n placeholder={searchPlaceholder}\n type='search'\n value={value}\n />\n {filterGroups.length > 0 && (\n <Button\n aria-expanded={isFilterDialogOpen}\n aria-haspopup='dialog'\n badge={activeFilters.length}\n icon='funnel'\n onClick={() => setIsFilterDialogOpen(true)}\n variant='tertiary'\n >\n {filterButtonLabel}\n </Button>\n )}\n </div>\n {activeFilters.length > 0 && (\n <div\n aria-label={filterButtonLabel}\n className={styles.chips}\n >\n {activeFilters.map((filter) => (\n <Chip\n accessibleLabel={removeFilterLabel(filter)}\n key={filter.value}\n label={filter.label}\n onDelete={() => setFilterSelected(filter.value, false)}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n setFilterSelected(filter.value, false);\n }\n }}\n role='button'\n />\n ))}\n <Button\n onClick={() => onSelectedFiltersChange?.([])}\n variant='tertiary'\n >\n {resetLabel}\n </Button>\n </div>\n )}\n {isFilterDialogOpen && (\n <Dialog\n aria-labelledby={dialogTitleId}\n className={styles['filter-dialog']}\n controls={\n <Controls>\n <Button onClick={() => setIsFilterDialogOpen(false)}>{closeLabel}</Button>\n </Controls>\n }\n header={\n <Header>\n <h2 id={dialogTitleId}>{filterDialogTitle}</h2>\n </Header>\n }\n open\n setOpen={setIsFilterDialogOpen}\n >\n <div\n className={styles['filter-groups']}\n data-columns={filterDialogColumns}\n >\n {filterGroups.map((group, groupIndex) => (\n <section\n aria-labelledby={group.label ? `${dialogTitleId}-${groupIndex}` : undefined}\n className={styles['filter-group']}\n data-column-span={group.columnSpan ?? 1}\n key={group.label ?? groupIndex}\n role={group.control === 'radio' ? 'radiogroup' : 'group'}\n >\n {group.label && <h3 id={`${dialogTitleId}-${groupIndex}`}>{group.label}</h3>}\n {group.options.map((filter) => renderFilter(filter, group))}\n {group.collapsible && (\n <Collapsible summary={group.collapsible.label}>\n <div className={styles['collapsible-options']}>\n {group.collapsible.options.map((filter) => renderFilter(filter, group))}\n </div>\n </Collapsible>\n )}\n </section>\n ))}\n </div>\n </Dialog>\n )}\n </div>\n );\n};\n"],"names":["Search","closeLabel","filterButtonLabel","filterDialogColumns","filterDialogTitle","filterGroups","onChange","onSelectedFiltersChange","removeFilterLabel","filter","label","resetLabel","searchLabel","searchPlaceholder","selectedFilters","value","dialogTitleId","useId","isFilterDialogOpen","setIsFilterDialogOpen","useState","filtersByValue","useMemo","Map","flatMap","group","options","collapsible","map","activeFilters","selectedFilter","get","setFilterSelected","filterValue","isSelected","groupValues","Set","filtersOutsideGroup","has","defaultValue","control","selectionMode","isFilterSelected","includes","some","renderFilter","jsx","styles","radio","event","target","checked","jsxs","description","Checkbox","search","controls","Input","length","Button","chips","Chip","key","preventDefault","Dialog","Controls","Header","groupIndex","undefined","columnSpan","Collapsible"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../src/components/search/index.tsx"],"sourcesContent":["import { useId, useMemo, useState } from 'react';\n\nimport { Button } from '../button';\nimport { Checkbox } from '../checkbox';\nimport { Chip } from '../chip';\nimport { Collapsible } from '../collapsible';\nimport { Controls } from '../controls';\nimport { Dialog } from '../dialog';\nimport { Header } from '../header';\nimport { Input } from '../input';\nimport styles from './styles.module.css';\n\nexport type SearchFilter = {\n description?: string;\n label: string;\n value: string;\n};\n\nexport type SearchFilterGroup = {\n collapsible?: {\n label: string;\n options: readonly SearchFilter[];\n };\n columnSpan?: 1 | 2;\n control?: 'checkbox' | 'radio';\n defaultValue?: string;\n label?: string;\n options: readonly SearchFilter[];\n selectionMode?: 'multiple' | 'single';\n};\n\nexport type SearchProps = {\n closeLabel?: string;\n filterButtonLabel?: string;\n filterDialogColumns?: 1 | 2;\n filterDialogTitle?: string;\n filterGroups?: readonly SearchFilterGroup[];\n onChange: (value: string) => void;\n onSelectedFiltersChange?: (selectedFilters: string[]) => void;\n removeFilterLabel?: (filter: SearchFilter) => string;\n resetLabel?: string;\n searchLabel?: string;\n searchPlaceholder?: string;\n selectedFilters?: readonly string[];\n value?: string;\n};\n\nexport const Search = ({\n closeLabel = 'Close',\n filterButtonLabel = 'Filters',\n filterDialogColumns = 1,\n filterDialogTitle = 'Filters',\n filterGroups = [],\n onChange,\n onSelectedFiltersChange,\n removeFilterLabel = (filter) => `Remove ${filter.label} filter`,\n resetLabel = 'Reset',\n searchLabel = 'Search',\n searchPlaceholder = 'Search',\n selectedFilters = [],\n value = '',\n}: SearchProps) => {\n const dialogTitleId = useId();\n const [isFilterDialogOpen, setIsFilterDialogOpen] = useState(false);\n const filtersByValue = useMemo(\n () =>\n new Map(\n filterGroups\n .flatMap((group) => [...group.options, ...(group.collapsible?.options ?? [])])\n .map((filter) => [filter.value, filter])\n ),\n [filterGroups]\n );\n const activeFilters = selectedFilters.flatMap((selectedFilter) => {\n const filter = filtersByValue.get(selectedFilter);\n\n return filter ? [filter] : [];\n });\n\n const setFilterSelected = (\n filterValue: string,\n isSelected: boolean,\n group?: SearchFilterGroup\n ) => {\n if (!onSelectedFiltersChange) return;\n\n const groupValues = new Set([\n ...(group?.options.map((filter) => filter.value) ?? []),\n ...(group?.collapsible?.options.map((filter) => filter.value) ?? []),\n ]);\n const filtersOutsideGroup = selectedFilters.filter(\n (selectedFilter) => !groupValues.has(selectedFilter)\n );\n\n if (isSelected && group?.defaultValue === filterValue) {\n onSelectedFiltersChange(filtersOutsideGroup);\n return;\n }\n\n onSelectedFiltersChange(\n isSelected\n ? group?.control === 'radio' || group?.selectionMode === 'single'\n ? [...filtersOutsideGroup, filterValue]\n : [...new Set([...selectedFilters, filterValue])]\n : selectedFilters.filter((selectedFilter) => selectedFilter !== filterValue)\n );\n };\n\n const isFilterSelected = (filterValue: string, group: SearchFilterGroup) =>\n selectedFilters.includes(filterValue) ||\n (group.defaultValue === filterValue &&\n ![...group.options, ...(group.collapsible?.options ?? [])].some((filter) =>\n selectedFilters.includes(filter.value)\n ));\n\n const renderFilter = (filter: SearchFilter, group: SearchFilterGroup) => (\n <div\n className={styles['filter-option']}\n key={filter.value}\n >\n {group.control === 'radio' ? (\n <label className={styles.radio}>\n <input\n checked={isFilterSelected(filter.value, group)}\n name={`${dialogTitleId}-filter-${group.label ?? 'group'}`}\n onChange={(event) => setFilterSelected(filter.value, event.target.checked, group)}\n type='radio'\n />\n <span className={styles['option-copy']}>\n {filter.label}\n {filter.description && <sub>{filter.description}</sub>}\n </span>\n </label>\n ) : (\n <Checkbox\n checked={isFilterSelected(filter.value, group)}\n label={\n <span className={styles['option-copy']}>\n {filter.label}\n {filter.description && <sub>{filter.description}</sub>}\n </span>\n }\n onChange={(event) => setFilterSelected(filter.value, event.target.checked, group)}\n />\n )}\n </div>\n );\n\n return (\n <div\n className={styles.search}\n data-component='search'\n >\n <div className={styles.controls}>\n <Input\n aria-label={searchLabel}\n icon='search'\n onChange={(event) => onChange(event.target.value)}\n placeholder={searchPlaceholder}\n type='search'\n value={value}\n />\n {filterGroups.length > 0 && (\n <Button\n aria-expanded={isFilterDialogOpen}\n aria-haspopup='dialog'\n badge={activeFilters.length}\n icon='funnel'\n onClick={() => setIsFilterDialogOpen(true)}\n variant='tertiary'\n >\n {filterButtonLabel}\n </Button>\n )}\n </div>\n {activeFilters.length > 0 && (\n <div\n aria-label={filterButtonLabel}\n className={styles.chips}\n >\n {activeFilters.map((filter) => (\n <Chip\n accessibleLabel={removeFilterLabel(filter)}\n key={filter.value}\n label={filter.label}\n onDelete={() => setFilterSelected(filter.value, false)}\n />\n ))}\n <Button\n onClick={() => onSelectedFiltersChange?.([])}\n variant='tertiary'\n >\n {resetLabel}\n </Button>\n </div>\n )}\n {isFilterDialogOpen && (\n <Dialog\n aria-labelledby={dialogTitleId}\n className={styles['filter-dialog']}\n controls={\n <Controls>\n <Button onClick={() => setIsFilterDialogOpen(false)}>{closeLabel}</Button>\n </Controls>\n }\n header={\n <Header>\n <h2 id={dialogTitleId}>{filterDialogTitle}</h2>\n </Header>\n }\n open\n setOpen={setIsFilterDialogOpen}\n >\n <div\n className={styles['filter-groups']}\n data-columns={filterDialogColumns}\n >\n {filterGroups.map((group, groupIndex) => (\n <section\n aria-labelledby={group.label ? `${dialogTitleId}-${groupIndex}` : undefined}\n className={styles['filter-group']}\n data-column-span={group.columnSpan ?? 1}\n key={group.label ?? groupIndex}\n role={group.control === 'radio' ? 'radiogroup' : 'group'}\n >\n {group.label && <h3 id={`${dialogTitleId}-${groupIndex}`}>{group.label}</h3>}\n {group.options.map((filter) => renderFilter(filter, group))}\n {group.collapsible && (\n <Collapsible summary={group.collapsible.label}>\n <div className={styles['collapsible-options']}>\n {group.collapsible.options.map((filter) => renderFilter(filter, group))}\n </div>\n </Collapsible>\n )}\n </section>\n ))}\n </div>\n </Dialog>\n )}\n </div>\n );\n};\n"],"names":["Search","closeLabel","filterButtonLabel","filterDialogColumns","filterDialogTitle","filterGroups","onChange","onSelectedFiltersChange","removeFilterLabel","filter","label","resetLabel","searchLabel","searchPlaceholder","selectedFilters","value","dialogTitleId","useId","isFilterDialogOpen","setIsFilterDialogOpen","useState","filtersByValue","useMemo","Map","flatMap","group","options","collapsible","map","activeFilters","selectedFilter","get","setFilterSelected","filterValue","isSelected","groupValues","Set","filtersOutsideGroup","has","defaultValue","control","selectionMode","isFilterSelected","includes","some","renderFilter","jsx","styles","radio","event","target","checked","jsxs","description","Checkbox","search","controls","Input","length","Button","chips","Chip","Dialog","Controls","Header","groupIndex","undefined","columnSpan","Collapsible"],"mappings":"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"}
|
|
@@ -1,83 +1,81 @@
|
|
|
1
1
|
import { jsxs as c, jsx as i } from "react/jsx-runtime";
|
|
2
|
-
import { useId as
|
|
3
|
-
import { Button as
|
|
4
|
-
import { Checkbox as
|
|
5
|
-
import { Chip as
|
|
6
|
-
import { Collapsible as
|
|
7
|
-
import { Controls as
|
|
8
|
-
import { Dialog as
|
|
9
|
-
import { Header as
|
|
10
|
-
import { I as
|
|
11
|
-
import '../../assets/index9.css';const
|
|
12
|
-
search:
|
|
13
|
-
controls:
|
|
14
|
-
chips:
|
|
2
|
+
import { useId as H, useState as S, useMemo as T } from "react";
|
|
3
|
+
import { Button as _ } from "../button/index.js";
|
|
4
|
+
import { Checkbox as q } from "../checkbox/index.js";
|
|
5
|
+
import { Chip as z } from "../chip/index.js";
|
|
6
|
+
import { Collapsible as A } from "../collapsible/index.js";
|
|
7
|
+
import { Controls as E } from "../controls/index.js";
|
|
8
|
+
import { Dialog as J } from "../dialog/index.js";
|
|
9
|
+
import { Header as K } from "../header/index.js";
|
|
10
|
+
import { I as L } from "../../index-DE2nzqL5.js";
|
|
11
|
+
import '../../assets/index9.css';const P = "_search_bp8f4_3", Q = "_controls_bp8f4_15", U = "_chips_bp8f4_29", V = "_radio_bp8f4_84", o = {
|
|
12
|
+
search: P,
|
|
13
|
+
controls: Q,
|
|
14
|
+
chips: U,
|
|
15
15
|
"filter-dialog": "_filter-dialog_bp8f4_36",
|
|
16
16
|
"filter-groups": "_filter-groups_bp8f4_41",
|
|
17
17
|
"filter-group": "_filter-group_bp8f4_41",
|
|
18
18
|
"filter-option": "_filter-option_bp8f4_66",
|
|
19
19
|
"option-copy": "_option-copy_bp8f4_72",
|
|
20
|
-
radio:
|
|
20
|
+
radio: V,
|
|
21
21
|
"collapsible-options": "_collapsible-options_bp8f4_111"
|
|
22
22
|
}, ea = ({
|
|
23
|
-
closeLabel:
|
|
24
|
-
filterButtonLabel:
|
|
25
|
-
filterDialogColumns:
|
|
26
|
-
filterDialogTitle:
|
|
23
|
+
closeLabel: M = "Close",
|
|
24
|
+
filterButtonLabel: f = "Filters",
|
|
25
|
+
filterDialogColumns: C = 1,
|
|
26
|
+
filterDialogTitle: D = "Filters",
|
|
27
27
|
filterGroups: d = [],
|
|
28
|
-
onChange:
|
|
28
|
+
onChange: O,
|
|
29
29
|
onSelectedFiltersChange: t,
|
|
30
|
-
removeFilterLabel:
|
|
30
|
+
removeFilterLabel: w = (s) => `Remove ${s.label} filter`,
|
|
31
31
|
resetLabel: x = "Reset",
|
|
32
32
|
searchLabel: I = "Search",
|
|
33
33
|
searchPlaceholder: j = "Search",
|
|
34
34
|
selectedFilters: r = [],
|
|
35
|
-
value:
|
|
35
|
+
value: R = ""
|
|
36
36
|
}) => {
|
|
37
|
-
const
|
|
38
|
-
var
|
|
39
|
-
return [...a.options, ...((
|
|
40
|
-
}).map((a) => [a.value, a])), [d]),
|
|
41
|
-
const
|
|
42
|
-
return
|
|
43
|
-
}),
|
|
37
|
+
const s = H(), [v, p] = S(!1), B = T(() => new Map(d.flatMap((a) => {
|
|
38
|
+
var e;
|
|
39
|
+
return [...a.options, ...((e = a.collapsible) == null ? void 0 : e.options) ?? []];
|
|
40
|
+
}).map((a) => [a.value, a])), [d]), m = r.flatMap((a) => {
|
|
41
|
+
const e = B.get(a);
|
|
42
|
+
return e ? [e] : [];
|
|
43
|
+
}), h = (a, e, l) => {
|
|
44
44
|
var $;
|
|
45
45
|
if (!t) return;
|
|
46
|
-
const b = /* @__PURE__ */ new Set([...(
|
|
47
|
-
if (
|
|
46
|
+
const b = /* @__PURE__ */ new Set([...(l == null ? void 0 : l.options.map((n) => n.value)) ?? [], ...(($ = l == null ? void 0 : l.collapsible) == null ? void 0 : $.options.map((n) => n.value)) ?? []]), k = r.filter((n) => !b.has(n));
|
|
47
|
+
if (e && (l == null ? void 0 : l.defaultValue) === a) {
|
|
48
48
|
t(k);
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
|
-
t(
|
|
52
|
-
}, y = (a,
|
|
53
|
-
var
|
|
54
|
-
return r.includes(a) ||
|
|
55
|
-
}, N = (a,
|
|
56
|
-
/* @__PURE__ */ i("input", { checked: y(a.value,
|
|
51
|
+
t(e ? (l == null ? void 0 : l.control) === "radio" || (l == null ? void 0 : l.selectionMode) === "single" ? [...k, a] : [.../* @__PURE__ */ new Set([...r, a])] : r.filter((n) => n !== a));
|
|
52
|
+
}, y = (a, e) => {
|
|
53
|
+
var l;
|
|
54
|
+
return r.includes(a) || e.defaultValue === a && ![...e.options, ...((l = e.collapsible) == null ? void 0 : l.options) ?? []].some((b) => r.includes(b.value));
|
|
55
|
+
}, N = (a, e) => /* @__PURE__ */ i("div", { className: o["filter-option"], "data-component": "renderfilter", children: e.control === "radio" ? /* @__PURE__ */ c("label", { className: o.radio, children: [
|
|
56
|
+
/* @__PURE__ */ i("input", { checked: y(a.value, e), name: `${s}-filter-${e.label ?? "group"}`, onChange: (l) => h(a.value, l.target.checked, e), type: "radio" }),
|
|
57
57
|
/* @__PURE__ */ c("span", { className: o["option-copy"], children: [
|
|
58
58
|
a.label,
|
|
59
59
|
a.description && /* @__PURE__ */ i("sub", { children: a.description })
|
|
60
60
|
] })
|
|
61
|
-
] }) : /* @__PURE__ */ i(
|
|
61
|
+
] }) : /* @__PURE__ */ i(q, { checked: y(a.value, e), label: /* @__PURE__ */ c("span", { className: o["option-copy"], children: [
|
|
62
62
|
a.label,
|
|
63
63
|
a.description && /* @__PURE__ */ i("sub", { children: a.description })
|
|
64
|
-
] }), onChange: (
|
|
64
|
+
] }), onChange: (l) => h(a.value, l.target.checked, e) }) }, a.value);
|
|
65
65
|
return /* @__PURE__ */ c("div", { className: o.search, "data-component": "search", children: [
|
|
66
66
|
/* @__PURE__ */ c("div", { className: o.controls, children: [
|
|
67
|
-
/* @__PURE__ */ i(
|
|
68
|
-
d.length > 0 && /* @__PURE__ */ i(
|
|
67
|
+
/* @__PURE__ */ i(L, { "aria-label": I, icon: "search", onChange: (a) => O(a.target.value), placeholder: j, type: "search", value: R }),
|
|
68
|
+
d.length > 0 && /* @__PURE__ */ i(_, { "aria-expanded": v, "aria-haspopup": "dialog", badge: m.length, icon: "funnel", onClick: () => p(!0), variant: "tertiary", children: f })
|
|
69
69
|
] }),
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}, role: "button" }, a.value)),
|
|
74
|
-
/* @__PURE__ */ i(f, { onClick: () => t == null ? void 0 : t([]), variant: "tertiary", children: x })
|
|
70
|
+
m.length > 0 && /* @__PURE__ */ c("div", { "aria-label": f, className: o.chips, children: [
|
|
71
|
+
m.map((a) => /* @__PURE__ */ i(z, { accessibleLabel: w(a), label: a.label, onDelete: () => h(a.value, !1) }, a.value)),
|
|
72
|
+
/* @__PURE__ */ i(_, { onClick: () => t == null ? void 0 : t([]), variant: "tertiary", children: x })
|
|
75
73
|
] }),
|
|
76
|
-
v && /* @__PURE__ */ i(
|
|
77
|
-
a.label && /* @__PURE__ */ i("h3", { id: `${
|
|
78
|
-
a.options.map((
|
|
79
|
-
a.collapsible && /* @__PURE__ */ i(
|
|
80
|
-
] }, a.label ??
|
|
74
|
+
v && /* @__PURE__ */ i(J, { "aria-labelledby": s, className: o["filter-dialog"], controls: /* @__PURE__ */ i(E, { children: /* @__PURE__ */ i(_, { onClick: () => p(!1), children: M }) }), header: /* @__PURE__ */ i(K, { children: /* @__PURE__ */ i("h2", { id: s, children: D }) }), open: !0, setOpen: p, children: /* @__PURE__ */ i("div", { className: o["filter-groups"], "data-columns": C, children: d.map((a, e) => /* @__PURE__ */ c("section", { "aria-labelledby": a.label ? `${s}-${e}` : void 0, className: o["filter-group"], "data-column-span": a.columnSpan ?? 1, role: a.control === "radio" ? "radiogroup" : "group", children: [
|
|
75
|
+
a.label && /* @__PURE__ */ i("h3", { id: `${s}-${e}`, children: a.label }),
|
|
76
|
+
a.options.map((l) => N(l, a)),
|
|
77
|
+
a.collapsible && /* @__PURE__ */ i(A, { summary: a.collapsible.label, children: /* @__PURE__ */ i("div", { className: o["collapsible-options"], children: a.collapsible.options.map((l) => N(l, a)) }) })
|
|
78
|
+
] }, a.label ?? e)) }) })
|
|
81
79
|
] });
|
|
82
80
|
};
|
|
83
81
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/components/search/index.tsx"],"sourcesContent":["import { useId, useMemo, useState } from 'react';\n\nimport { Button } from '../button';\nimport { Checkbox } from '../checkbox';\nimport { Chip } from '../chip';\nimport { Collapsible } from '../collapsible';\nimport { Controls } from '../controls';\nimport { Dialog } from '../dialog';\nimport { Header } from '../header';\nimport { Input } from '../input';\nimport styles from './styles.module.css';\n\nexport type SearchFilter = {\n description?: string;\n label: string;\n value: string;\n};\n\nexport type SearchFilterGroup = {\n collapsible?: {\n label: string;\n options: readonly SearchFilter[];\n };\n columnSpan?: 1 | 2;\n control?: 'checkbox' | 'radio';\n defaultValue?: string;\n label?: string;\n options: readonly SearchFilter[];\n selectionMode?: 'multiple' | 'single';\n};\n\nexport type SearchProps = {\n closeLabel?: string;\n filterButtonLabel?: string;\n filterDialogColumns?: 1 | 2;\n filterDialogTitle?: string;\n filterGroups?: readonly SearchFilterGroup[];\n onChange: (value: string) => void;\n onSelectedFiltersChange?: (selectedFilters: string[]) => void;\n removeFilterLabel?: (filter: SearchFilter) => string;\n resetLabel?: string;\n searchLabel?: string;\n searchPlaceholder?: string;\n selectedFilters?: readonly string[];\n value?: string;\n};\n\nexport const Search = ({\n closeLabel = 'Close',\n filterButtonLabel = 'Filters',\n filterDialogColumns = 1,\n filterDialogTitle = 'Filters',\n filterGroups = [],\n onChange,\n onSelectedFiltersChange,\n removeFilterLabel = (filter) => `Remove ${filter.label} filter`,\n resetLabel = 'Reset',\n searchLabel = 'Search',\n searchPlaceholder = 'Search',\n selectedFilters = [],\n value = '',\n}: SearchProps) => {\n const dialogTitleId = useId();\n const [isFilterDialogOpen, setIsFilterDialogOpen] = useState(false);\n const filtersByValue = useMemo(\n () =>\n new Map(\n filterGroups\n .flatMap((group) => [...group.options, ...(group.collapsible?.options ?? [])])\n .map((filter) => [filter.value, filter])\n ),\n [filterGroups]\n );\n const activeFilters = selectedFilters.flatMap((selectedFilter) => {\n const filter = filtersByValue.get(selectedFilter);\n\n return filter ? [filter] : [];\n });\n\n const setFilterSelected = (\n filterValue: string,\n isSelected: boolean,\n group?: SearchFilterGroup\n ) => {\n if (!onSelectedFiltersChange) return;\n\n const groupValues = new Set([\n ...(group?.options.map((filter) => filter.value) ?? []),\n ...(group?.collapsible?.options.map((filter) => filter.value) ?? []),\n ]);\n const filtersOutsideGroup = selectedFilters.filter(\n (selectedFilter) => !groupValues.has(selectedFilter)\n );\n\n if (isSelected && group?.defaultValue === filterValue) {\n onSelectedFiltersChange(filtersOutsideGroup);\n return;\n }\n\n onSelectedFiltersChange(\n isSelected\n ? group?.control === 'radio' || group?.selectionMode === 'single'\n ? [...filtersOutsideGroup, filterValue]\n : [...new Set([...selectedFilters, filterValue])]\n : selectedFilters.filter((selectedFilter) => selectedFilter !== filterValue)\n );\n };\n\n const isFilterSelected = (filterValue: string, group: SearchFilterGroup) =>\n selectedFilters.includes(filterValue) ||\n (group.defaultValue === filterValue &&\n ![...group.options, ...(group.collapsible?.options ?? [])].some((filter) =>\n selectedFilters.includes(filter.value)\n ));\n\n const renderFilter = (filter: SearchFilter, group: SearchFilterGroup) => (\n <div\n className={styles['filter-option']}\n key={filter.value}\n >\n {group.control === 'radio' ? (\n <label className={styles.radio}>\n <input\n checked={isFilterSelected(filter.value, group)}\n name={`${dialogTitleId}-filter-${group.label ?? 'group'}`}\n onChange={(event) => setFilterSelected(filter.value, event.target.checked, group)}\n type='radio'\n />\n <span className={styles['option-copy']}>\n {filter.label}\n {filter.description && <sub>{filter.description}</sub>}\n </span>\n </label>\n ) : (\n <Checkbox\n checked={isFilterSelected(filter.value, group)}\n label={\n <span className={styles['option-copy']}>\n {filter.label}\n {filter.description && <sub>{filter.description}</sub>}\n </span>\n }\n onChange={(event) => setFilterSelected(filter.value, event.target.checked, group)}\n />\n )}\n </div>\n );\n\n return (\n <div\n className={styles.search}\n data-component='search'\n >\n <div className={styles.controls}>\n <Input\n aria-label={searchLabel}\n icon='search'\n onChange={(event) => onChange(event.target.value)}\n placeholder={searchPlaceholder}\n type='search'\n value={value}\n />\n {filterGroups.length > 0 && (\n <Button\n aria-expanded={isFilterDialogOpen}\n aria-haspopup='dialog'\n badge={activeFilters.length}\n icon='funnel'\n onClick={() => setIsFilterDialogOpen(true)}\n variant='tertiary'\n >\n {filterButtonLabel}\n </Button>\n )}\n </div>\n {activeFilters.length > 0 && (\n <div\n aria-label={filterButtonLabel}\n className={styles.chips}\n >\n {activeFilters.map((filter) => (\n <Chip\n accessibleLabel={removeFilterLabel(filter)}\n key={filter.value}\n label={filter.label}\n onDelete={() => setFilterSelected(filter.value, false)}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n setFilterSelected(filter.value, false);\n }\n }}\n role='button'\n />\n ))}\n <Button\n onClick={() => onSelectedFiltersChange?.([])}\n variant='tertiary'\n >\n {resetLabel}\n </Button>\n </div>\n )}\n {isFilterDialogOpen && (\n <Dialog\n aria-labelledby={dialogTitleId}\n className={styles['filter-dialog']}\n controls={\n <Controls>\n <Button onClick={() => setIsFilterDialogOpen(false)}>{closeLabel}</Button>\n </Controls>\n }\n header={\n <Header>\n <h2 id={dialogTitleId}>{filterDialogTitle}</h2>\n </Header>\n }\n open\n setOpen={setIsFilterDialogOpen}\n >\n <div\n className={styles['filter-groups']}\n data-columns={filterDialogColumns}\n >\n {filterGroups.map((group, groupIndex) => (\n <section\n aria-labelledby={group.label ? `${dialogTitleId}-${groupIndex}` : undefined}\n className={styles['filter-group']}\n data-column-span={group.columnSpan ?? 1}\n key={group.label ?? groupIndex}\n role={group.control === 'radio' ? 'radiogroup' : 'group'}\n >\n {group.label && <h3 id={`${dialogTitleId}-${groupIndex}`}>{group.label}</h3>}\n {group.options.map((filter) => renderFilter(filter, group))}\n {group.collapsible && (\n <Collapsible summary={group.collapsible.label}>\n <div className={styles['collapsible-options']}>\n {group.collapsible.options.map((filter) => renderFilter(filter, group))}\n </div>\n </Collapsible>\n )}\n </section>\n ))}\n </div>\n </Dialog>\n )}\n </div>\n );\n};\n"],"names":["Search","closeLabel","filterButtonLabel","filterDialogColumns","filterDialogTitle","filterGroups","onChange","onSelectedFiltersChange","removeFilterLabel","filter","label","resetLabel","searchLabel","searchPlaceholder","selectedFilters","value","dialogTitleId","useId","isFilterDialogOpen","setIsFilterDialogOpen","useState","filtersByValue","useMemo","Map","flatMap","group","options","collapsible","map","activeFilters","selectedFilter","get","setFilterSelected","filterValue","isSelected","groupValues","Set","filtersOutsideGroup","has","defaultValue","control","selectionMode","isFilterSelected","includes","some","renderFilter","jsx","styles","radio","event","target","checked","jsxs","description","Checkbox","search","controls","Input","length","Button","chips","Chip","key","preventDefault","Dialog","Controls","Header","groupIndex","undefined","columnSpan","Collapsible"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/search/index.tsx"],"sourcesContent":["import { useId, useMemo, useState } from 'react';\n\nimport { Button } from '../button';\nimport { Checkbox } from '../checkbox';\nimport { Chip } from '../chip';\nimport { Collapsible } from '../collapsible';\nimport { Controls } from '../controls';\nimport { Dialog } from '../dialog';\nimport { Header } from '../header';\nimport { Input } from '../input';\nimport styles from './styles.module.css';\n\nexport type SearchFilter = {\n description?: string;\n label: string;\n value: string;\n};\n\nexport type SearchFilterGroup = {\n collapsible?: {\n label: string;\n options: readonly SearchFilter[];\n };\n columnSpan?: 1 | 2;\n control?: 'checkbox' | 'radio';\n defaultValue?: string;\n label?: string;\n options: readonly SearchFilter[];\n selectionMode?: 'multiple' | 'single';\n};\n\nexport type SearchProps = {\n closeLabel?: string;\n filterButtonLabel?: string;\n filterDialogColumns?: 1 | 2;\n filterDialogTitle?: string;\n filterGroups?: readonly SearchFilterGroup[];\n onChange: (value: string) => void;\n onSelectedFiltersChange?: (selectedFilters: string[]) => void;\n removeFilterLabel?: (filter: SearchFilter) => string;\n resetLabel?: string;\n searchLabel?: string;\n searchPlaceholder?: string;\n selectedFilters?: readonly string[];\n value?: string;\n};\n\nexport const Search = ({\n closeLabel = 'Close',\n filterButtonLabel = 'Filters',\n filterDialogColumns = 1,\n filterDialogTitle = 'Filters',\n filterGroups = [],\n onChange,\n onSelectedFiltersChange,\n removeFilterLabel = (filter) => `Remove ${filter.label} filter`,\n resetLabel = 'Reset',\n searchLabel = 'Search',\n searchPlaceholder = 'Search',\n selectedFilters = [],\n value = '',\n}: SearchProps) => {\n const dialogTitleId = useId();\n const [isFilterDialogOpen, setIsFilterDialogOpen] = useState(false);\n const filtersByValue = useMemo(\n () =>\n new Map(\n filterGroups\n .flatMap((group) => [...group.options, ...(group.collapsible?.options ?? [])])\n .map((filter) => [filter.value, filter])\n ),\n [filterGroups]\n );\n const activeFilters = selectedFilters.flatMap((selectedFilter) => {\n const filter = filtersByValue.get(selectedFilter);\n\n return filter ? [filter] : [];\n });\n\n const setFilterSelected = (\n filterValue: string,\n isSelected: boolean,\n group?: SearchFilterGroup\n ) => {\n if (!onSelectedFiltersChange) return;\n\n const groupValues = new Set([\n ...(group?.options.map((filter) => filter.value) ?? []),\n ...(group?.collapsible?.options.map((filter) => filter.value) ?? []),\n ]);\n const filtersOutsideGroup = selectedFilters.filter(\n (selectedFilter) => !groupValues.has(selectedFilter)\n );\n\n if (isSelected && group?.defaultValue === filterValue) {\n onSelectedFiltersChange(filtersOutsideGroup);\n return;\n }\n\n onSelectedFiltersChange(\n isSelected\n ? group?.control === 'radio' || group?.selectionMode === 'single'\n ? [...filtersOutsideGroup, filterValue]\n : [...new Set([...selectedFilters, filterValue])]\n : selectedFilters.filter((selectedFilter) => selectedFilter !== filterValue)\n );\n };\n\n const isFilterSelected = (filterValue: string, group: SearchFilterGroup) =>\n selectedFilters.includes(filterValue) ||\n (group.defaultValue === filterValue &&\n ![...group.options, ...(group.collapsible?.options ?? [])].some((filter) =>\n selectedFilters.includes(filter.value)\n ));\n\n const renderFilter = (filter: SearchFilter, group: SearchFilterGroup) => (\n <div\n className={styles['filter-option']}\n key={filter.value}\n >\n {group.control === 'radio' ? (\n <label className={styles.radio}>\n <input\n checked={isFilterSelected(filter.value, group)}\n name={`${dialogTitleId}-filter-${group.label ?? 'group'}`}\n onChange={(event) => setFilterSelected(filter.value, event.target.checked, group)}\n type='radio'\n />\n <span className={styles['option-copy']}>\n {filter.label}\n {filter.description && <sub>{filter.description}</sub>}\n </span>\n </label>\n ) : (\n <Checkbox\n checked={isFilterSelected(filter.value, group)}\n label={\n <span className={styles['option-copy']}>\n {filter.label}\n {filter.description && <sub>{filter.description}</sub>}\n </span>\n }\n onChange={(event) => setFilterSelected(filter.value, event.target.checked, group)}\n />\n )}\n </div>\n );\n\n return (\n <div\n className={styles.search}\n data-component='search'\n >\n <div className={styles.controls}>\n <Input\n aria-label={searchLabel}\n icon='search'\n onChange={(event) => onChange(event.target.value)}\n placeholder={searchPlaceholder}\n type='search'\n value={value}\n />\n {filterGroups.length > 0 && (\n <Button\n aria-expanded={isFilterDialogOpen}\n aria-haspopup='dialog'\n badge={activeFilters.length}\n icon='funnel'\n onClick={() => setIsFilterDialogOpen(true)}\n variant='tertiary'\n >\n {filterButtonLabel}\n </Button>\n )}\n </div>\n {activeFilters.length > 0 && (\n <div\n aria-label={filterButtonLabel}\n className={styles.chips}\n >\n {activeFilters.map((filter) => (\n <Chip\n accessibleLabel={removeFilterLabel(filter)}\n key={filter.value}\n label={filter.label}\n onDelete={() => setFilterSelected(filter.value, false)}\n />\n ))}\n <Button\n onClick={() => onSelectedFiltersChange?.([])}\n variant='tertiary'\n >\n {resetLabel}\n </Button>\n </div>\n )}\n {isFilterDialogOpen && (\n <Dialog\n aria-labelledby={dialogTitleId}\n className={styles['filter-dialog']}\n controls={\n <Controls>\n <Button onClick={() => setIsFilterDialogOpen(false)}>{closeLabel}</Button>\n </Controls>\n }\n header={\n <Header>\n <h2 id={dialogTitleId}>{filterDialogTitle}</h2>\n </Header>\n }\n open\n setOpen={setIsFilterDialogOpen}\n >\n <div\n className={styles['filter-groups']}\n data-columns={filterDialogColumns}\n >\n {filterGroups.map((group, groupIndex) => (\n <section\n aria-labelledby={group.label ? `${dialogTitleId}-${groupIndex}` : undefined}\n className={styles['filter-group']}\n data-column-span={group.columnSpan ?? 1}\n key={group.label ?? groupIndex}\n role={group.control === 'radio' ? 'radiogroup' : 'group'}\n >\n {group.label && <h3 id={`${dialogTitleId}-${groupIndex}`}>{group.label}</h3>}\n {group.options.map((filter) => renderFilter(filter, group))}\n {group.collapsible && (\n <Collapsible summary={group.collapsible.label}>\n <div className={styles['collapsible-options']}>\n {group.collapsible.options.map((filter) => renderFilter(filter, group))}\n </div>\n </Collapsible>\n )}\n </section>\n ))}\n </div>\n </Dialog>\n )}\n </div>\n );\n};\n"],"names":["Search","closeLabel","filterButtonLabel","filterDialogColumns","filterDialogTitle","filterGroups","onChange","onSelectedFiltersChange","removeFilterLabel","filter","label","resetLabel","searchLabel","searchPlaceholder","selectedFilters","value","dialogTitleId","useId","isFilterDialogOpen","setIsFilterDialogOpen","useState","filtersByValue","useMemo","Map","flatMap","group","options","collapsible","map","activeFilters","selectedFilter","get","setFilterSelected","filterValue","isSelected","groupValues","Set","filtersOutsideGroup","has","defaultValue","control","selectionMode","isFilterSelected","includes","some","renderFilter","jsx","styles","radio","event","target","checked","jsxs","description","Checkbox","search","controls","Input","length","Button","chips","Chip","Dialog","Controls","Header","groupIndex","undefined","columnSpan","Collapsible"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require("react/jsx-runtime");require("../../classix-5H4IWnMA.cjs");require("../../icons-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require("react/jsx-runtime");require("../../classix-5H4IWnMA.cjs");require("../../icons-DaZGJzI0.cjs");const e=require("../../index-Dn1v0qm6.cjs");require("../../use-touched-Bq5Gjbpz.cjs");exports.Select=e.Select;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import "react/jsx-runtime";
|
|
2
2
|
import "../../classix-DG18itHa.js";
|
|
3
|
-
import "../../icons-
|
|
4
|
-
import { S as e } from "../../index-
|
|
5
|
-
import "../../use-touched-
|
|
3
|
+
import "../../icons-Dj0vEOCB.js";
|
|
4
|
+
import { S as e } from "../../index-CgA0NUMD.js";
|
|
5
|
+
import "../../use-touched-B999bBr8.js";
|
|
6
6
|
export {
|
|
7
7
|
e as Select
|
|
8
8
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require('../../assets/index6.css');const e=require("react/jsx-runtime"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require('../../assets/index6.css');const e=require("react/jsx-runtime"),_=require("../../classix-5H4IWnMA.cjs"),r=require("../../use-touched-Bq5Gjbpz.cjs"),m="_label_ah8yz_3",y="_textarea_ah8yz_11",b="_touched_ah8yz_30",t={label:m,textarea:y,touched:b},j=({className:c,label:a,maxRows:n=12,minRows:l=3,onBlur:u,required:s,style:d,value:o,...x})=>{const{touched:h,onBlur:i}=r.useTouched(o==="");return e.jsxs("label",{className:t.label,"data-component":"textarea",children:[a&&e.jsx("span",{"data-required":s||void 0,children:a}),e.jsx("textarea",{...x,className:_.t(t.textarea,c,h&&t.touched),onBlur:r.composeEventHandlers(i,u),required:s,style:{...d,"--min-rows":l,"--max-rows":n},value:o})]})};exports.Textarea=j;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../src/components/textarea/index.tsx"],"sourcesContent":["import cx from 'classix';\n\nimport { useTouched } from '@/lib/use-touched';\n\nimport styles from './styles.module.css';\n\nexport type TextareaProps = Omit<React.ComponentPropsWithoutRef<'textarea'>, 'children'> & {\n label?: string;\n maxRows?: number;\n minRows?: number;\n};\n\nexport const Textarea = ({\n label,\n maxRows = 12,\n minRows = 3,\n required,\n value,\n ...props\n}: TextareaProps) => {\n const { touched, onBlur } = useTouched(value === '');\n\n return (\n <label className={styles.label}>\n {label && <span data-required={required || undefined}>{label}</span>}\n <textarea\n className={cx(styles.textarea, touched && styles.touched)}\n onBlur={onBlur}\n
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../src/components/textarea/index.tsx"],"sourcesContent":["import cx from 'classix';\n\nimport { composeEventHandlers } from '@/lib/compose-event-handlers';\nimport { useTouched } from '@/lib/use-touched';\n\nimport styles from './styles.module.css';\n\nexport type TextareaProps = Omit<React.ComponentPropsWithoutRef<'textarea'>, 'children'> & {\n label?: string;\n maxRows?: number;\n minRows?: number;\n};\n\nexport const Textarea = ({\n className,\n label,\n maxRows = 12,\n minRows = 3,\n onBlur: onBlurProp,\n required,\n style,\n value,\n ...props\n}: TextareaProps) => {\n const { touched, onBlur } = useTouched(value === '');\n\n return (\n <label className={styles.label}>\n {label && <span data-required={required || undefined}>{label}</span>}\n <textarea\n {...props}\n className={cx(styles.textarea, className, touched && styles.touched)}\n onBlur={composeEventHandlers(onBlur, onBlurProp)}\n required={required}\n style={\n {\n ...style,\n '--min-rows': minRows,\n '--max-rows': maxRows,\n } as React.CSSProperties\n }\n value={value}\n />\n </label>\n );\n};\n"],"names":["Textarea","className","label","maxRows","minRows","onBlur","onBlurProp","required","style","value","props","touched","useTouched","styles","jsx","undefined","cx","textarea","composeEventHandlers"],"mappings":"0SAaaA,EAAWA,CAAC,CACvBC,UAAAA,EACAC,MAAAA,EACAC,QAAAA,EAAU,GACVC,QAAAA,EAAU,EACVC,OAAQC,EACRC,SAAAA,EACAC,MAAAA,EACAC,MAAAA,EACA,GAAGC,CACU,IAAM,CACnB,KAAM,CAAEC,QAAAA,EAASN,OAAAA,CAAAA,EAAWO,EAAAA,WAAWH,IAAU,EAAE,EAEnD,cACG,QAAA,CAAM,UAAWI,EAAOX,MAAM,iBAAA,WAC5BA,SAAAA,CAAAA,GAASY,EAAAA,IAAC,OAAA,CAAK,gBAAeP,GAAYQ,OAAYb,SAAAA,EAAM,QAC5D,WAAA,CACC,GAAIQ,EACJ,UAAWM,IAAGH,EAAOI,SAAUhB,EAAWU,GAAWE,EAAOF,OAAO,EACnE,OAAQO,EAAAA,qBAAqBb,EAAQC,CAAU,EAC/C,SAAAC,EACA,MACE,CACE,GAAGC,EACH,aAAcJ,EACd,aAAcD,CAAAA,EAGlB,MAAAM,CAAA,CAAa,CAAA,EAEjB,CAEJ"}
|