@sentropic/design-system-react 0.9.0 → 0.11.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.
@@ -0,0 +1,77 @@
1
+ import React from "react";
2
+ export type PopperStrategy = "absolute" | "fixed";
3
+ export type PopperPlacement = "top" | "bottom" | "left" | "right" | "top-start" | "top-end" | "bottom-start" | "bottom-end" | "left-start" | "left-end" | "right-start" | "right-end";
4
+ export type PopperSide = "top" | "bottom" | "left" | "right";
5
+ export type PopperAlign = "start" | "center" | "end";
6
+ export type PopperProps = {
7
+ /** Reference element the panel is positioned against. */
8
+ anchor: HTMLElement | null;
9
+ /** Controlled open state. When false (or no anchor) nothing renders. */
10
+ open?: boolean;
11
+ /** Wanted placement of the panel relative to the anchor. */
12
+ placement?: PopperPlacement;
13
+ /** Main-axis distance (px) between the anchor and the panel. */
14
+ offset?: number;
15
+ /** Flip to the opposite side when the panel would overflow the viewport. */
16
+ flip?: boolean;
17
+ /** Shift along the cross axis to keep the panel within the viewport. */
18
+ shift?: boolean;
19
+ /** Expose a positioned arrow element. */
20
+ arrow?: boolean;
21
+ /** CSS positioning strategy. */
22
+ strategy?: PopperStrategy;
23
+ /** Render the panel into `document.body` via a Portal. */
24
+ portal?: boolean;
25
+ /** Optional class applied to the floating panel. */
26
+ className?: string;
27
+ /** Notified whenever the resolved placement changes (after flip). */
28
+ onPlacementChange?: (placement: PopperPlacement) => void;
29
+ children?: React.ReactNode;
30
+ };
31
+ /** Split a placement into its side and (optional) alignment. */
32
+ export declare function splitPlacement(placement: PopperPlacement): {
33
+ side: PopperSide;
34
+ align: PopperAlign;
35
+ };
36
+ /** Recompose a side + alignment into a placement string. */
37
+ export declare function joinPlacement(side: PopperSide, align: PopperAlign): PopperPlacement;
38
+ export type Rect = {
39
+ top: number;
40
+ left: number;
41
+ right: number;
42
+ bottom: number;
43
+ width: number;
44
+ height: number;
45
+ };
46
+ /**
47
+ * Pure geometry: compute the panel coordinates (in the chosen strategy's
48
+ * coordinate space) given the anchor rect, the panel size, and options.
49
+ * Returns the resolved placement (after flip) and the top/left coordinates,
50
+ * plus the arrow offset along the main edge.
51
+ *
52
+ * Coordinates are viewport-relative; callers add scroll offsets for the
53
+ * `absolute` strategy. No DOM access here — safe to unit test.
54
+ */
55
+ export declare function computePosition(anchorRect: Rect, panelWidth: number, panelHeight: number, options: {
56
+ placement: PopperPlacement;
57
+ offset: number;
58
+ flip: boolean;
59
+ shift: boolean;
60
+ viewportWidth: number;
61
+ viewportHeight: number;
62
+ }): {
63
+ placement: PopperPlacement;
64
+ top: number;
65
+ left: number;
66
+ };
67
+ /**
68
+ * Float a panel next to an anchor element. Positioning is recomputed on open,
69
+ * scroll, and resize via `computePosition` (pure geometry shared across
70
+ * frameworks). Renders nothing unless `open` and an `anchor` are provided.
71
+ * SSR-safe: all DOM access happens inside effects.
72
+ */
73
+ export declare function Popper({ anchor, open, placement, offset, flip, shift, arrow, strategy, portal, className, onPlacementChange, children, }: PopperProps): React.ReactElement | null;
74
+ export declare namespace Popper {
75
+ var displayName: string;
76
+ }
77
+ //# sourceMappingURL=Popper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Popper.d.ts","sourceRoot":"","sources":["../src/Popper.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,OAAO,CAAC;AAElD,MAAM,MAAM,eAAe,GACvB,KAAK,GACL,QAAQ,GACR,MAAM,GACN,OAAO,GACP,WAAW,GACX,SAAS,GACT,cAAc,GACd,YAAY,GACZ,YAAY,GACZ,UAAU,GACV,aAAa,GACb,WAAW,CAAC;AAEhB,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAC7D,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;AAErD,MAAM,MAAM,WAAW,GAAG;IACxB,yDAAyD;IACzD,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,wEAAwE;IACxE,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,4DAA4D;IAC5D,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,wEAAwE;IACxE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,yCAAyC;IACzC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,0DAA0D;IAC1D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACzD,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B,CAAC;AAEF,gEAAgE;AAChE,wBAAgB,cAAc,CAAC,SAAS,EAAE,eAAe,GAAG;IAC1D,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC;CACpB,CAGA;AAED,4DAA4D;AAC5D,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,GAAG,eAAe,CAEnF;AASD,MAAM,MAAM,IAAI,GAAG;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,IAAI,EAChB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE;IACP,SAAS,EAAE,eAAe,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;CACxB,GACA;IAAE,SAAS,EAAE,eAAe,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAwD3D;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,EACrB,MAAM,EACN,IAAY,EACZ,SAAoB,EACpB,MAAU,EACV,IAAW,EACX,KAAY,EACZ,KAAa,EACb,QAAqB,EACrB,MAAa,EACb,SAAS,EACT,iBAAiB,EACjB,QAAQ,GACT,EAAE,WAAW,GAAG,KAAK,CAAC,YAAY,GAAG,IAAI,CAwGzC;yBArHe,MAAM"}
package/dist/Popper.js ADDED
@@ -0,0 +1,172 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React from "react";
3
+ import { classNames } from "./classNames.js";
4
+ import { Portal } from "./Portal.js";
5
+ /** Split a placement into its side and (optional) alignment. */
6
+ export function splitPlacement(placement) {
7
+ const [side, align] = placement.split("-");
8
+ return { side, align: align ?? "center" };
9
+ }
10
+ /** Recompose a side + alignment into a placement string. */
11
+ export function joinPlacement(side, align) {
12
+ return (align === "center" ? side : `${side}-${align}`);
13
+ }
14
+ const OPPOSITE = {
15
+ top: "bottom",
16
+ bottom: "top",
17
+ left: "right",
18
+ right: "left",
19
+ };
20
+ /**
21
+ * Pure geometry: compute the panel coordinates (in the chosen strategy's
22
+ * coordinate space) given the anchor rect, the panel size, and options.
23
+ * Returns the resolved placement (after flip) and the top/left coordinates,
24
+ * plus the arrow offset along the main edge.
25
+ *
26
+ * Coordinates are viewport-relative; callers add scroll offsets for the
27
+ * `absolute` strategy. No DOM access here — safe to unit test.
28
+ */
29
+ export function computePosition(anchorRect, panelWidth, panelHeight, options) {
30
+ const { offset, flip, shift, viewportWidth, viewportHeight } = options;
31
+ let { side, align } = splitPlacement(options.placement);
32
+ const place = (s, a) => {
33
+ let top = 0;
34
+ let left = 0;
35
+ if (s === "top" || s === "bottom") {
36
+ top = s === "top" ? anchorRect.top - panelHeight - offset : anchorRect.bottom + offset;
37
+ if (a === "start")
38
+ left = anchorRect.left;
39
+ else if (a === "end")
40
+ left = anchorRect.right - panelWidth;
41
+ else
42
+ left = anchorRect.left + anchorRect.width / 2 - panelWidth / 2;
43
+ }
44
+ else {
45
+ left = s === "left" ? anchorRect.left - panelWidth - offset : anchorRect.right + offset;
46
+ if (a === "start")
47
+ top = anchorRect.top;
48
+ else if (a === "end")
49
+ top = anchorRect.bottom - panelHeight;
50
+ else
51
+ top = anchorRect.top + anchorRect.height / 2 - panelHeight / 2;
52
+ }
53
+ return { top, left };
54
+ };
55
+ // Flip: if the panel overflows on the chosen side, try the opposite side.
56
+ if (flip) {
57
+ const candidate = place(side, align);
58
+ const overflows = (side === "top" && candidate.top < 0) ||
59
+ (side === "bottom" && candidate.top + panelHeight > viewportHeight) ||
60
+ (side === "left" && candidate.left < 0) ||
61
+ (side === "right" && candidate.left + panelWidth > viewportWidth);
62
+ if (overflows) {
63
+ const flipped = OPPOSITE[side];
64
+ const flippedPos = place(flipped, align);
65
+ const flippedOverflows = (flipped === "top" && flippedPos.top < 0) ||
66
+ (flipped === "bottom" && flippedPos.top + panelHeight > viewportHeight) ||
67
+ (flipped === "left" && flippedPos.left < 0) ||
68
+ (flipped === "right" && flippedPos.left + panelWidth > viewportWidth);
69
+ // Only flip if the opposite side fits better.
70
+ if (!flippedOverflows)
71
+ side = flipped;
72
+ }
73
+ }
74
+ let { top, left } = place(side, align);
75
+ // Shift: clamp along the cross axis so the panel stays in the viewport.
76
+ if (shift) {
77
+ if (side === "top" || side === "bottom") {
78
+ const max = Math.max(0, viewportWidth - panelWidth);
79
+ left = Math.min(Math.max(0, left), max);
80
+ }
81
+ else {
82
+ const max = Math.max(0, viewportHeight - panelHeight);
83
+ top = Math.min(Math.max(0, top), max);
84
+ }
85
+ }
86
+ return { placement: joinPlacement(side, align), top, left };
87
+ }
88
+ /**
89
+ * Float a panel next to an anchor element. Positioning is recomputed on open,
90
+ * scroll, and resize via `computePosition` (pure geometry shared across
91
+ * frameworks). Renders nothing unless `open` and an `anchor` are provided.
92
+ * SSR-safe: all DOM access happens inside effects.
93
+ */
94
+ export function Popper({ anchor, open = false, placement = "bottom", offset = 8, flip = true, shift = true, arrow = false, strategy = "absolute", portal = true, className, onPlacementChange, children, }) {
95
+ const panelRef = React.useRef(null);
96
+ const [coords, setCoords] = React.useState({
97
+ top: 0,
98
+ left: 0,
99
+ });
100
+ // Placement actually applied (may differ from the requested `placement`
101
+ // after a flip). Defaults to the requested placement.
102
+ const [resolvedPlacement, setResolvedPlacement] = React.useState(placement);
103
+ // Keep latest callback without re-registering listeners.
104
+ const onPlacementChangeRef = React.useRef(onPlacementChange);
105
+ onPlacementChangeRef.current = onPlacementChange;
106
+ React.useEffect(() => {
107
+ if (typeof window === "undefined")
108
+ return;
109
+ if (!open || !anchor)
110
+ return;
111
+ const reposition = () => {
112
+ const panel = panelRef.current;
113
+ if (!panel)
114
+ return;
115
+ const anchorRect = anchor.getBoundingClientRect();
116
+ const panelRect = panel.getBoundingClientRect();
117
+ const result = computePosition({
118
+ top: anchorRect.top,
119
+ left: anchorRect.left,
120
+ right: anchorRect.right,
121
+ bottom: anchorRect.bottom,
122
+ width: anchorRect.width,
123
+ height: anchorRect.height,
124
+ }, panelRect.width, panelRect.height, {
125
+ placement,
126
+ offset,
127
+ flip,
128
+ shift,
129
+ viewportWidth: window.innerWidth,
130
+ viewportHeight: window.innerHeight,
131
+ });
132
+ // `absolute` is positioned relative to the document, so add scroll
133
+ // offsets. `fixed` is viewport-relative, so coordinates are used as-is.
134
+ if (strategy === "absolute") {
135
+ setCoords({ top: result.top + window.scrollY, left: result.left + window.scrollX });
136
+ }
137
+ else {
138
+ setCoords({ top: result.top, left: result.left });
139
+ }
140
+ setResolvedPlacement((prev) => {
141
+ if (result.placement !== prev) {
142
+ onPlacementChangeRef.current?.(result.placement);
143
+ }
144
+ return result.placement;
145
+ });
146
+ };
147
+ reposition();
148
+ const onScroll = () => reposition();
149
+ const onResize = () => reposition();
150
+ window.addEventListener("scroll", onScroll, true);
151
+ window.addEventListener("resize", onResize);
152
+ return () => {
153
+ window.removeEventListener("scroll", onScroll, true);
154
+ window.removeEventListener("resize", onResize);
155
+ };
156
+ }, [anchor, open, placement, offset, flip, shift, strategy]);
157
+ if (!open || !anchor)
158
+ return null;
159
+ const side = splitPlacement(resolvedPlacement).side;
160
+ const panelStyle = {
161
+ position: strategy,
162
+ top: `${coords.top}px`,
163
+ left: `${coords.left}px`,
164
+ };
165
+ const floating = (_jsxs("div", { ref: panelRef, className: classNames("st-popper", className), "data-popper-placement": resolvedPlacement, style: panelStyle, children: [children, arrow ? (_jsx("span", { className: "st-popper__arrow", "data-popper-side": side, "aria-hidden": "true" })) : null] }));
166
+ if (portal) {
167
+ return _jsx(Portal, { target: "body", children: floating });
168
+ }
169
+ return floating;
170
+ }
171
+ Popper.displayName = "Popper";
172
+ //# sourceMappingURL=Popper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Popper.js","sourceRoot":"","sources":["../src/Popper.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import React from "react";
2
+ export type PortalProps = {
3
+ /**
4
+ * Where to teleport the children. A CSS selector string or an actual
5
+ * `HTMLElement`. Defaults to the document `<body>`.
6
+ */
7
+ target?: string | HTMLElement;
8
+ /** When `true`, render inline in place (no teleportation). */
9
+ disabled?: boolean;
10
+ /** Optional class applied to the portal container element. */
11
+ className?: string;
12
+ children?: React.ReactNode;
13
+ };
14
+ /**
15
+ * Resolve a target prop to an `HTMLElement`. Returns `null` when it cannot be
16
+ * resolved (SSR, missing selector, etc.).
17
+ */
18
+ export declare function resolvePortalTarget(target: string | HTMLElement | undefined): HTMLElement | null;
19
+ /**
20
+ * Teleport `children` into another part of the DOM via `ReactDOM.createPortal`.
21
+ * SSR-safe: nothing is portalled during the server render or before mount; the
22
+ * portal is created only after the component has mounted on the client. When
23
+ * `disabled` is set the children render inline in place.
24
+ */
25
+ export declare function Portal({ target, disabled, className, children, }: PortalProps): React.ReactElement | null;
26
+ export declare namespace Portal {
27
+ var displayName: string;
28
+ }
29
+ //# sourceMappingURL=Portal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Portal.d.ts","sourceRoot":"","sources":["../src/Portal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,MAAM,WAAW,GAAG;IACxB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IAC9B,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,GACvC,WAAW,GAAG,IAAI,CAOpB;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,EACrB,MAAe,EACf,QAAgB,EAChB,SAAS,EACT,QAAQ,GACT,EAAE,WAAW,GAAG,KAAK,CAAC,YAAY,GAAG,IAAI,CA0CzC;yBA/Ce,MAAM"}
package/dist/Portal.js ADDED
@@ -0,0 +1,46 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React from "react";
3
+ import ReactDOM from "react-dom";
4
+ import { classNames } from "./classNames.js";
5
+ /**
6
+ * Resolve a target prop to an `HTMLElement`. Returns `null` when it cannot be
7
+ * resolved (SSR, missing selector, etc.).
8
+ */
9
+ export function resolvePortalTarget(target) {
10
+ if (typeof document === "undefined")
11
+ return null;
12
+ if (target == null)
13
+ return document.body;
14
+ if (typeof target === "string") {
15
+ return document.querySelector(target) ?? document.body;
16
+ }
17
+ return target;
18
+ }
19
+ /**
20
+ * Teleport `children` into another part of the DOM via `ReactDOM.createPortal`.
21
+ * SSR-safe: nothing is portalled during the server render or before mount; the
22
+ * portal is created only after the component has mounted on the client. When
23
+ * `disabled` is set the children render inline in place.
24
+ */
25
+ export function Portal({ target = "body", disabled = false, className, children, }) {
26
+ // Only create the portal after mount so the server render and the first
27
+ // client render agree (no DOM access during SSR).
28
+ const [mounted, setMounted] = React.useState(false);
29
+ React.useEffect(() => {
30
+ setMounted(true);
31
+ }, []);
32
+ if (disabled) {
33
+ return (_jsx("div", { className: classNames("st-portal", className), "data-st-portal": "inline", children: children }));
34
+ }
35
+ if (!mounted) {
36
+ // SSR / first client render: render inline so markup is produced in place
37
+ // and hydration stays consistent. The effect below re-renders into a portal.
38
+ return (_jsx("div", { className: classNames("st-portal", className), "data-st-portal": "inline", children: children }));
39
+ }
40
+ const destination = resolvePortalTarget(target);
41
+ if (!destination)
42
+ return null;
43
+ return ReactDOM.createPortal(_jsx("div", { className: classNames("st-portal", className), "data-st-portal": "teleported", children: children }), destination);
44
+ }
45
+ Portal.displayName = "Portal";
46
+ //# sourceMappingURL=Portal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Portal.js","sourceRoot":"","sources":["../src/Portal.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,QAAQ,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAe7C;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAAwC;IAExC,IAAI,OAAO,QAAQ,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IACjD,IAAI,MAAM,IAAI,IAAI;QAAE,OAAO,QAAQ,CAAC,IAAI,CAAC;IACzC,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,QAAQ,CAAC,aAAa,CAAc,MAAM,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC;IACtE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,MAAM,CAAC,EACrB,MAAM,GAAG,MAAM,EACf,QAAQ,GAAG,KAAK,EAChB,SAAS,EACT,QAAQ,GACI;IACZ,wEAAwE;IACxE,kDAAkD;IAClD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAEpD,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,UAAU,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,CACL,cACE,SAAS,EAAE,UAAU,CAAC,WAAW,EAAE,SAAS,CAAC,oBAC9B,QAAQ,YAEtB,QAAQ,GACL,CACP,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,0EAA0E;QAC1E,6EAA6E;QAC7E,OAAO,CACL,cACE,SAAS,EAAE,UAAU,CAAC,WAAW,EAAE,SAAS,CAAC,oBAC9B,QAAQ,YAEtB,QAAQ,GACL,CACP,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAChD,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAE9B,OAAO,QAAQ,CAAC,YAAY,CAC1B,cAAK,SAAS,EAAE,UAAU,CAAC,WAAW,EAAE,SAAS,CAAC,oBAAiB,YAAY,YAC5E,QAAQ,GACL,EACN,WAAW,CACZ,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAC"}
@@ -0,0 +1,41 @@
1
+ import React from "react";
2
+ export type SelectableListProps = Omit<React.HTMLAttributes<HTMLDivElement>, "onChange"> & {
3
+ /** Accessible name for the listbox (required for SR users). */
4
+ label?: string;
5
+ /** References the id of an external visible label (alternative to `label`). */
6
+ labelledby?: string;
7
+ /**
8
+ * Allow more than one selected row. Adds aria-multiselectable and toggles
9
+ * each row independently. Defaults to false (single-select).
10
+ */
11
+ multiple?: boolean;
12
+ /**
13
+ * Selected value(s). Controlled when provided. For single-select pass a
14
+ * string (or null); for multiple pass a string[]. When omitted the list is
15
+ * uncontrolled and keeps its own internal selection.
16
+ */
17
+ value?: string | string[] | null;
18
+ /**
19
+ * Fired with the new selection on every change. Receives a string|null for
20
+ * single-select and a string[] for multiple. Required for the controlled
21
+ * pattern; also fires for uncontrolled lists.
22
+ */
23
+ onChange?: (value: string | string[] | null) => void;
24
+ children?: React.ReactNode;
25
+ className?: string;
26
+ };
27
+ /**
28
+ * Accessible listbox that owns selection + a roving tabindex for its
29
+ * {@link SelectableRow} children. Arrow / Home / End move focus (roving),
30
+ * Space / Enter / click toggle the focused row. Single-select by default;
31
+ * `multiple` toggles rows independently. Controlled via `value`/`onChange`,
32
+ * otherwise it keeps its own internal selection. Pilots each child row through
33
+ * a STABLE React context (so a row's registration effect never re-runs in a
34
+ * loop) plus a `version` counter the rows read to recompute role / tabindex /
35
+ * aria-selected on every selection / focus / registry change.
36
+ */
37
+ export declare function SelectableList({ label, labelledby, multiple, value, onChange, children, className, ...rest }: SelectableListProps): import("react/jsx-runtime").JSX.Element;
38
+ export declare namespace SelectableList {
39
+ var displayName: string;
40
+ }
41
+ //# sourceMappingURL=SelectableList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectableList.d.ts","sourceRoot":"","sources":["../src/SelectableList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAQ1B,MAAM,MAAM,mBAAmB,GAAG,IAAI,CACpC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EACpC,UAAU,CACX,GAAG;IACF,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,KAAK,IAAI,CAAC;IACrD,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAkBF;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,UAAU,EACV,QAAgB,EAChB,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,GAAG,IAAI,EACR,EAAE,mBAAmB,2CA4IrB;yBArJe,cAAc"}
@@ -0,0 +1,156 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React from "react";
3
+ import { classNames } from "./classNames.js";
4
+ import { SelectableListContext, SelectableListVersionContext, } from "./SelectableRow.js";
5
+ function toSet(v) {
6
+ if (v == null)
7
+ return new Set();
8
+ return new Set(Array.isArray(v) ? v : [v]);
9
+ }
10
+ function sortByDom(list) {
11
+ return [...list].sort((a, b) => {
12
+ const pos = a.el.compareDocumentPosition(b.el);
13
+ if (pos & Node.DOCUMENT_POSITION_FOLLOWING)
14
+ return -1;
15
+ if (pos & Node.DOCUMENT_POSITION_PRECEDING)
16
+ return 1;
17
+ return 0;
18
+ });
19
+ }
20
+ /**
21
+ * Accessible listbox that owns selection + a roving tabindex for its
22
+ * {@link SelectableRow} children. Arrow / Home / End move focus (roving),
23
+ * Space / Enter / click toggle the focused row. Single-select by default;
24
+ * `multiple` toggles rows independently. Controlled via `value`/`onChange`,
25
+ * otherwise it keeps its own internal selection. Pilots each child row through
26
+ * a STABLE React context (so a row's registration effect never re-runs in a
27
+ * loop) plus a `version` counter the rows read to recompute role / tabindex /
28
+ * aria-selected on every selection / focus / registry change.
29
+ */
30
+ export function SelectableList({ label, labelledby, multiple = false, value, onChange, children, className, ...rest }) {
31
+ // Controlled when the consumer passes `value` (including null).
32
+ const controlled = value !== undefined;
33
+ // --- Mutable state lives in refs (read by the STABLE context methods); a
34
+ // `version` counter drives re-renders so rows recompute their derived
35
+ // attributes. This keeps the context object identity-stable, which is what
36
+ // prevents the rows' registration effect from re-running in a loop. ------
37
+ const entriesRef = React.useRef([]);
38
+ const tabStopRef = React.useRef(null);
39
+ const internalRef = React.useRef(new Set());
40
+ // `version` is provided to rows so they re-render on every selection / focus /
41
+ // registry change (the actions context stays identity-stable).
42
+ const [version, force] = React.useReducer((n) => n + 1, 0);
43
+ const bump = React.useCallback(() => force(), []);
44
+ // Latest controlled inputs, read by stable callbacks without stale closures.
45
+ const controlledRef = React.useRef(controlled);
46
+ controlledRef.current = controlled;
47
+ const valueRef = React.useRef(value);
48
+ valueRef.current = value;
49
+ const multipleRef = React.useRef(multiple);
50
+ multipleRef.current = multiple;
51
+ const onChangeRef = React.useRef(onChange);
52
+ onChangeRef.current = onChange;
53
+ function currentSelection() {
54
+ return controlledRef.current ? toSet(valueRef.current) : internalRef.current;
55
+ }
56
+ // Default roving stop = first registered (DOM-ordered) row when none focused.
57
+ function effectiveTabStop() {
58
+ return tabStopRef.current ?? entriesRef.current[0]?.el ?? null;
59
+ }
60
+ function valueOf(el) {
61
+ return entriesRef.current.find((e) => e.el === el)?.value;
62
+ }
63
+ // Stable context methods — created ONCE so the context object never changes
64
+ // identity. They read mutable state from refs and bump the version to re-render.
65
+ const context = React.useMemo(() => {
66
+ const register = (el, rowValue) => {
67
+ entriesRef.current = sortByDom([
68
+ ...entriesRef.current.filter((e) => e.el !== el),
69
+ { el, value: rowValue },
70
+ ]);
71
+ bump();
72
+ return () => {
73
+ entriesRef.current = entriesRef.current.filter((e) => e.el !== el);
74
+ if (tabStopRef.current === el)
75
+ tabStopRef.current = null;
76
+ bump();
77
+ };
78
+ };
79
+ const isSelected = (el) => {
80
+ const v = valueOf(el);
81
+ return v !== undefined && currentSelection().has(v);
82
+ };
83
+ const isTabStop = (el) => el === effectiveTabStop();
84
+ const emit = (next) => {
85
+ if (!controlledRef.current)
86
+ internalRef.current = next;
87
+ if (multipleRef.current)
88
+ onChangeRef.current?.([...next]);
89
+ else
90
+ onChangeRef.current?.(next.size ? [...next][0] : null);
91
+ bump();
92
+ };
93
+ const activate = (el) => {
94
+ const v = valueOf(el);
95
+ if (v === undefined)
96
+ return;
97
+ const current = currentSelection();
98
+ let next;
99
+ if (multipleRef.current) {
100
+ next = new Set(current);
101
+ if (next.has(v))
102
+ next.delete(v);
103
+ else
104
+ next.add(v);
105
+ }
106
+ else {
107
+ // Single-select toggles off when re-activating the selected row.
108
+ next = current.has(v) && current.size === 1 ? new Set() : new Set([v]);
109
+ }
110
+ emit(next);
111
+ };
112
+ const focusRow = (el) => {
113
+ tabStopRef.current = el;
114
+ bump();
115
+ };
116
+ const navigate = (el, key) => {
117
+ const list = entriesRef.current;
118
+ if (list.length === 0)
119
+ return;
120
+ const idx = list.findIndex((e) => e.el === el);
121
+ if (idx === -1)
122
+ return;
123
+ let targetIdx = idx;
124
+ if (key === "ArrowDown" || key === "ArrowRight")
125
+ targetIdx = idx + 1;
126
+ else if (key === "ArrowUp" || key === "ArrowLeft")
127
+ targetIdx = idx - 1;
128
+ else if (key === "Home")
129
+ targetIdx = 0;
130
+ else if (key === "End")
131
+ targetIdx = list.length - 1;
132
+ // Clamp (no wrap) so Home/End and arrows stay within bounds.
133
+ targetIdx = Math.max(0, Math.min(list.length - 1, targetIdx));
134
+ const target = list[targetIdx]?.el;
135
+ if (target) {
136
+ tabStopRef.current = target;
137
+ target.focus();
138
+ bump();
139
+ }
140
+ };
141
+ return {
142
+ managed: true,
143
+ itemRole: "option",
144
+ register,
145
+ isSelected,
146
+ isTabStop,
147
+ activate,
148
+ focusRow,
149
+ navigate,
150
+ };
151
+ // eslint-disable-next-line react-hooks/exhaustive-deps
152
+ }, [bump]);
153
+ return (_jsx("div", { ...rest, className: classNames("st-selectableList", className), role: "listbox", "aria-label": labelledby ? undefined : label, "aria-labelledby": labelledby, "aria-multiselectable": multiple ? "true" : undefined, children: _jsx(SelectableListContext.Provider, { value: context, children: _jsx(SelectableListVersionContext.Provider, { value: version, children: children }) }) }));
154
+ }
155
+ SelectableList.displayName = "SelectableList";
156
+ //# sourceMappingURL=SelectableList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectableList.js","sourceRoot":"","sources":["../src/SelectableList.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EACL,qBAAqB,EACrB,4BAA4B,GAE7B,MAAM,oBAAoB,CAAC;AAiC5B,SAAS,KAAK,CAAC,CAAuC;IACpD,IAAI,CAAC,IAAI,IAAI;QAAE,OAAO,IAAI,GAAG,EAAE,CAAC;IAChC,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,SAAS,CAAC,IAAa;IAC9B,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC7B,MAAM,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/C,IAAI,GAAG,GAAG,IAAI,CAAC,2BAA2B;YAAE,OAAO,CAAC,CAAC,CAAC;QACtD,IAAI,GAAG,GAAG,IAAI,CAAC,2BAA2B;YAAE,OAAO,CAAC,CAAC;QACrD,OAAO,CAAC,CAAC;IACX,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc,CAAC,EAC7B,KAAK,EACL,UAAU,EACV,QAAQ,GAAG,KAAK,EAChB,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,GAAG,IAAI,EACa;IACpB,gEAAgE;IAChE,MAAM,UAAU,GAAG,KAAK,KAAK,SAAS,CAAC;IAEvC,0EAA0E;IAC1E,0EAA0E;IAC1E,+EAA+E;IAC/E,+EAA+E;IAC/E,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAU,EAAE,CAAC,CAAC;IAC7C,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAqB,IAAI,CAAC,CAAC;IAC1D,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAc,IAAI,GAAG,EAAE,CAAC,CAAC;IAEzD,+EAA+E;IAC/E,+DAA+D;IAC/D,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACnE,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;IAElD,6EAA6E;IAC7E,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAC/C,aAAa,CAAC,OAAO,GAAG,UAAU,CAAC;IACnC,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACrC,QAAQ,CAAC,OAAO,GAAG,KAAK,CAAC;IACzB,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC3C,WAAW,CAAC,OAAO,GAAG,QAAQ,CAAC;IAC/B,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC3C,WAAW,CAAC,OAAO,GAAG,QAAQ,CAAC;IAE/B,SAAS,gBAAgB;QACvB,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC;IAC/E,CAAC;IAED,8EAA8E;IAC9E,SAAS,gBAAgB;QACvB,OAAO,UAAU,CAAC,OAAO,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,IAAI,CAAC;IACjE,CAAC;IAED,SAAS,OAAO,CAAC,EAAe;QAC9B,OAAO,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC;IAC5D,CAAC;IAED,4EAA4E;IAC5E,iFAAiF;IACjF,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAA6B,GAAG,EAAE;QAC7D,MAAM,QAAQ,GAAG,CAAC,EAAe,EAAE,QAA4B,EAAgB,EAAE;YAC/E,UAAU,CAAC,OAAO,GAAG,SAAS,CAAC;gBAC7B,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;gBAChD,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE;aACxB,CAAC,CAAC;YACH,IAAI,EAAE,CAAC;YACP,OAAO,GAAG,EAAE;gBACV,UAAU,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;gBACnE,IAAI,UAAU,CAAC,OAAO,KAAK,EAAE;oBAAE,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC;gBACzD,IAAI,EAAE,CAAC;YACT,CAAC,CAAC;QACJ,CAAC,CAAC;QAEF,MAAM,UAAU,GAAG,CAAC,EAAe,EAAW,EAAE;YAC9C,MAAM,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;YACtB,OAAO,CAAC,KAAK,SAAS,IAAI,gBAAgB,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACtD,CAAC,CAAC;QAEF,MAAM,SAAS,GAAG,CAAC,EAAe,EAAW,EAAE,CAAC,EAAE,KAAK,gBAAgB,EAAE,CAAC;QAE1E,MAAM,IAAI,GAAG,CAAC,IAAiB,EAAE,EAAE;YACjC,IAAI,CAAC,aAAa,CAAC,OAAO;gBAAE,WAAW,CAAC,OAAO,GAAG,IAAI,CAAC;YACvD,IAAI,WAAW,CAAC,OAAO;gBAAE,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;;gBACrD,WAAW,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAC5D,IAAI,EAAE,CAAC;QACT,CAAC,CAAC;QAEF,MAAM,QAAQ,GAAG,CAAC,EAAe,EAAE,EAAE;YACnC,MAAM,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;YACtB,IAAI,CAAC,KAAK,SAAS;gBAAE,OAAO;YAC5B,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;YACnC,IAAI,IAAiB,CAAC;YACtB,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;gBACxB,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;gBACxB,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;oBAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;;oBAC3B,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACnB,CAAC;iBAAM,CAAC;gBACN,iEAAiE;gBACjE,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACzE,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,CAAC,CAAC;QAEF,MAAM,QAAQ,GAAG,CAAC,EAAe,EAAE,EAAE;YACnC,UAAU,CAAC,OAAO,GAAG,EAAE,CAAC;YACxB,IAAI,EAAE,CAAC;QACT,CAAC,CAAC;QAEF,MAAM,QAAQ,GAAG,CAAC,EAAe,EAAE,GAAW,EAAE,EAAE;YAChD,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC;YAChC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO;YAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;YAC/C,IAAI,GAAG,KAAK,CAAC,CAAC;gBAAE,OAAO;YACvB,IAAI,SAAS,GAAG,GAAG,CAAC;YACpB,IAAI,GAAG,KAAK,WAAW,IAAI,GAAG,KAAK,YAAY;gBAAE,SAAS,GAAG,GAAG,GAAG,CAAC,CAAC;iBAChE,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,WAAW;gBAAE,SAAS,GAAG,GAAG,GAAG,CAAC,CAAC;iBAClE,IAAI,GAAG,KAAK,MAAM;gBAAE,SAAS,GAAG,CAAC,CAAC;iBAClC,IAAI,GAAG,KAAK,KAAK;gBAAE,SAAS,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;YACpD,6DAA6D;YAC7D,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;YAC9D,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC;YACnC,IAAI,MAAM,EAAE,CAAC;gBACX,UAAU,CAAC,OAAO,GAAG,MAAM,CAAC;gBAC5B,MAAM,CAAC,KAAK,EAAE,CAAC;gBACf,IAAI,EAAE,CAAC;YACT,CAAC;QACH,CAAC,CAAC;QAEF,OAAO;YACL,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,QAAQ;YAClB,QAAQ;YACR,UAAU;YACV,SAAS;YACT,QAAQ;YACR,QAAQ;YACR,QAAQ;SACT,CAAC;QACF,uDAAuD;IACzD,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,OAAO,CACL,iBACM,IAAI,EACR,SAAS,EAAE,UAAU,CAAC,mBAAmB,EAAE,SAAS,CAAC,EACrD,IAAI,EAAC,SAAS,gBACF,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,qBACzB,UAAU,0BACL,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,YAEnD,KAAC,qBAAqB,CAAC,QAAQ,IAAC,KAAK,EAAE,OAAO,YAC5C,KAAC,4BAA4B,CAAC,QAAQ,IAAC,KAAK,EAAE,OAAO,YAClD,QAAQ,GAC6B,GACT,GAC7B,CACP,CAAC;AACJ,CAAC;AAED,cAAc,CAAC,WAAW,GAAG,gBAAgB,CAAC"}