@smwb/ui-react 2.3.0 → 2.4.1

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.
Files changed (52) hide show
  1. package/dist/components/clickAwayListener/clickAwayListener.js +19 -14
  2. package/dist/components/clickAwayListener/clickAwayListener.js.map +1 -1
  3. package/dist/components/dataDisplay/treeView/treeView.d.ts +5 -2
  4. package/dist/components/dataDisplay/treeView/treeView.js +78 -75
  5. package/dist/components/dataDisplay/treeView/treeView.js.map +1 -1
  6. package/dist/components/feedBack/modal/modal.js +40 -38
  7. package/dist/components/feedBack/modal/modal.js.map +1 -1
  8. package/dist/components/inputs/datePicker/datePicker.js +13 -12
  9. package/dist/components/inputs/datePicker/datePicker.js.map +1 -1
  10. package/dist/components/inputs/dateTimePicker/dateTimePicker.js +28 -27
  11. package/dist/components/inputs/dateTimePicker/dateTimePicker.js.map +1 -1
  12. package/dist/components/inputs/selectField/dropdownMenu.js +7 -6
  13. package/dist/components/inputs/selectField/dropdownMenu.js.map +1 -1
  14. package/dist/components/inputs/timePicker/timePicker.js +16 -15
  15. package/dist/components/inputs/timePicker/timePicker.js.map +1 -1
  16. package/dist/components/layout/sheet/sheet.js +102 -92
  17. package/dist/components/layout/sheet/sheet.js.map +1 -1
  18. package/dist/components/navigation/menu/menuSubmenu.d.ts +1 -1
  19. package/dist/headless/components/clickAwayListener/clickAwayListener.js +19 -14
  20. package/dist/headless/components/clickAwayListener/clickAwayListener.js.map +1 -1
  21. package/dist/headless/components/dataDisplay/treeView/treeView.js +78 -75
  22. package/dist/headless/components/dataDisplay/treeView/treeView.js.map +1 -1
  23. package/dist/headless/components/feedBack/modal/modal.js +42 -40
  24. package/dist/headless/components/feedBack/modal/modal.js.map +1 -1
  25. package/dist/headless/components/inputs/datePicker/datePicker.js +13 -12
  26. package/dist/headless/components/inputs/datePicker/datePicker.js.map +1 -1
  27. package/dist/headless/components/inputs/dateTimePicker/dateTimePicker.js +28 -27
  28. package/dist/headless/components/inputs/dateTimePicker/dateTimePicker.js.map +1 -1
  29. package/dist/headless/components/inputs/selectField/dropdownMenu.js +7 -6
  30. package/dist/headless/components/inputs/selectField/dropdownMenu.js.map +1 -1
  31. package/dist/headless/components/inputs/timePicker/timePicker.js +16 -15
  32. package/dist/headless/components/inputs/timePicker/timePicker.js.map +1 -1
  33. package/dist/headless/components/layout/sheet/sheet.js +95 -85
  34. package/dist/headless/components/layout/sheet/sheet.js.map +1 -1
  35. package/dist/headless/hooks/useHoverPopover.js +117 -0
  36. package/dist/headless/hooks/useHoverPopover.js.map +1 -0
  37. package/dist/headless/index.js +242 -240
  38. package/dist/headless/index.js.map +1 -1
  39. package/dist/headless/utils/overlayLayer.js +11 -0
  40. package/dist/headless/utils/overlayLayer.js.map +1 -0
  41. package/dist/hooks/useHoverPopover.d.ts +73 -0
  42. package/dist/hooks/useHoverPopover.js +117 -0
  43. package/dist/hooks/useHoverPopover.js.map +1 -0
  44. package/dist/index.cjs +2 -2
  45. package/dist/index.cjs.map +1 -1
  46. package/dist/index.d.ts +2 -0
  47. package/dist/index.js +242 -240
  48. package/dist/index.js.map +1 -1
  49. package/dist/utils/overlayLayer.d.ts +13 -0
  50. package/dist/utils/overlayLayer.js +11 -0
  51. package/dist/utils/overlayLayer.js.map +1 -0
  52. package/package.json +1 -1
@@ -1,35 +1,36 @@
1
1
  import { jsx as n, jsxs as re } from "react/jsx-runtime";
2
- import T, { forwardRef as ne, useState as W, useRef as H, useEffect as oe, useCallback as w } from "react";
3
- import B from "clsx";
2
+ import K, { forwardRef as ne, useState as W, useRef as H, useEffect as oe, useCallback as w } from "react";
3
+ import L from "clsx";
4
4
  import { CSSTransition as j } from "react-transition-group";
5
5
  import { createPortal as se } from "react-dom";
6
6
  import { Button as C } from "../../inputs/button/button.js";
7
7
  import { Icon as $ } from "../../base/icon/icon.js";
8
- import { useForkRef as ie } from "../../../hooks/useForkRef.js";
9
- import { ClickAwayListener as ae } from "../../clickAwayListener/clickAwayListener.js";
10
- const ye = ne(function({
8
+ import { useForkRef as ae } from "../../../hooks/useForkRef.js";
9
+ import { isTopOverlayLayer as ie } from "../../../utils/overlayLayer.js";
10
+ import { ClickAwayListener as le } from "../../clickAwayListener/clickAwayListener.js";
11
+ const _e = ne(function({
11
12
  isOpen: u,
12
- onClose: a,
13
+ onClose: i,
13
14
  variant: d = "default",
14
15
  children: r,
15
- placement: _ = "bottom",
16
+ placement: k = "bottom",
16
17
  disableOutsideClick: p,
17
- closeOnEsc: v = !0,
18
- ...k
19
- }, A) {
20
- const [m, b] = W(null), D = H(null);
18
+ closeOnEsc: z = !0,
19
+ ...A
20
+ }, D) {
21
+ const [m, b] = W(null), y = H(null);
21
22
  oe(() => {
22
- if (!u || !v || !a)
23
+ if (!u || !z || !i)
23
24
  return;
24
- const o = (R) => {
25
- R.key === "Escape" && a();
25
+ const o = (v) => {
26
+ v.key === "Escape" && ie(y.current) && i();
26
27
  };
27
28
  return document.addEventListener("keydown", o), () => document.removeEventListener("keydown", o);
28
- }, [u, v, a]);
29
- const y = () => {
29
+ }, [u, z, i]);
30
+ const g = () => {
30
31
  b(m === "expanded" ? "small" : m ? null : "expanded");
31
- }, i = () => {
32
- a == null || a(), b(null);
32
+ }, a = () => {
33
+ i == null || i(), b(null);
33
34
  };
34
35
  return se(
35
36
  /* @__PURE__ */ n(
@@ -41,38 +42,47 @@ const ye = ne(function({
41
42
  unmountOnExit: !0,
42
43
  classNames: { enterDone: "smwb-entered" },
43
44
  appear: !0,
44
- nodeRef: D,
45
- children: d === "default" ? /* @__PURE__ */ n("div", { className: B(p ? "smwb-sheet__overlay" : "smwb-sheet__default"), ref: D, children: /* @__PURE__ */ n(
46
- U,
45
+ nodeRef: y,
46
+ children: d === "default" ? /* @__PURE__ */ n(
47
+ "div",
47
48
  {
48
- ref: A,
49
- onClose: a,
50
- handleSizeButton: y,
51
- handleClose: i,
52
- isOpen: u,
53
- mode: m,
54
- placement: _,
55
- variant: d,
56
- ...k,
57
- children: r
49
+ className: L(p ? "smwb-sheet__overlay" : "smwb-sheet__default"),
50
+ ref: y,
51
+ "data-smwb-overlay-layer": "",
52
+ children: /* @__PURE__ */ n(
53
+ U,
54
+ {
55
+ ref: D,
56
+ onClose: i,
57
+ handleSizeButton: g,
58
+ handleClose: a,
59
+ isOpen: u,
60
+ mode: m,
61
+ placement: k,
62
+ variant: d,
63
+ ...A,
64
+ children: r
65
+ }
66
+ )
58
67
  }
59
- ) }) : /* @__PURE__ */ n(
68
+ ) : /* @__PURE__ */ n(
60
69
  "div",
61
70
  {
62
- className: B("smwb-sheet__overlay", "smwb-dark", `smwb-${_}`, `smwb-sheet_${d}`),
63
- ref: D,
64
- children: /* @__PURE__ */ n(ae, { onClickAway: () => !p && i(), children: /* @__PURE__ */ n(
71
+ className: L("smwb-sheet__overlay", "smwb-dark", `smwb-${k}`, `smwb-sheet_${d}`),
72
+ ref: y,
73
+ "data-smwb-overlay-layer": "",
74
+ children: /* @__PURE__ */ n(le, { onClickAway: () => !p && a(), children: /* @__PURE__ */ n(
65
75
  U,
66
76
  {
67
- ref: A,
68
- onClose: a,
69
- handleSizeButton: y,
70
- handleClose: i,
77
+ ref: D,
78
+ onClose: i,
79
+ handleSizeButton: g,
80
+ handleClose: a,
71
81
  isOpen: u,
72
82
  mode: m,
73
- placement: _,
83
+ placement: k,
74
84
  variant: d,
75
- ...k,
85
+ ...A,
76
86
  children: r
77
87
  }
78
88
  ) })
@@ -82,22 +92,22 @@ const ye = ne(function({
82
92
  ),
83
93
  document.body
84
94
  );
85
- }), le = (z) => z === "bottom" || z === "top", U = T.forwardRef(function(u, a) {
95
+ }), ce = (x) => x === "bottom" || x === "top", U = K.forwardRef(function(u, i) {
86
96
  const {
87
97
  isOpen: d,
88
98
  placement: r,
89
- className: _,
99
+ className: k,
90
100
  mode: p,
91
- size: v = "60%",
92
- variant: k,
93
- onClose: A,
101
+ size: z = "60%",
102
+ variant: A,
103
+ onClose: D,
94
104
  withSizeToggle: m = !0,
95
105
  hideHeaderActions: b = !1,
96
- reverseHeaderActions: D = !1,
97
- resizable: y = !1,
98
- minSize: i = 80,
106
+ reverseHeaderActions: y = !1,
107
+ resizable: g = !1,
108
+ minSize: a = 80,
99
109
  maxSize: o,
100
- resizeStep: R = 24,
110
+ resizeStep: v = 24,
101
111
  resizeHandleAriaLabel: X = "Resize sheet",
102
112
  onResize: N,
103
113
  style: Y,
@@ -105,26 +115,26 @@ const ye = ne(function({
105
115
  handleSizeButton: V,
106
116
  children: q,
107
117
  ...G
108
- } = u, J = !b && (!!A || m), P = [];
118
+ } = u, J = !b && (!!D || m), P = [];
109
119
  m && P.push(
110
120
  /* @__PURE__ */ n(C, { variant: "outlined", size: "small", onClick: V, children: /* @__PURE__ */ n($, { name: "open_in_full" }) }, "size")
111
- ), A && P.push(
121
+ ), D && P.push(
112
122
  /* @__PURE__ */ n(C, { variant: "outlined", size: "small", onClick: F, children: /* @__PURE__ */ n($, { name: "close" }) }, "close")
113
- ), D && P.reverse();
114
- const I = H(null), S = H(null), Q = ie(a, I, S), [l, L] = W(null), s = le(r), M = w(
123
+ ), y && P.reverse();
124
+ const B = H(null), S = H(null), Q = ae(i, B, S), [l, I] = W(null), s = ce(r), M = w(
115
125
  (e) => {
116
126
  const t = s ? window.innerHeight : window.innerWidth, c = o != null ? o : t;
117
- return Math.max(i, Math.min(c, e));
127
+ return Math.max(a, Math.min(c, e));
118
128
  },
119
- [s, o, i]
120
- ), x = w(() => {
129
+ [s, o, a]
130
+ ), R = w(() => {
121
131
  var t;
122
132
  const e = (t = S.current) == null ? void 0 : t.getBoundingClientRect();
123
- return e ? s ? e.height : e.width : i;
124
- }, [s, i]), h = w(
133
+ return e ? s ? e.height : e.width : a;
134
+ }, [s, a]), h = w(
125
135
  (e) => {
126
136
  const t = M(e);
127
- L(t), N == null || N(t);
137
+ I(t), N == null || N(t);
128
138
  },
129
139
  [M, N]
130
140
  ), E = H(null), Z = w(
@@ -132,59 +142,59 @@ const ye = ne(function({
132
142
  var t, c;
133
143
  e.preventDefault(), E.current = {
134
144
  start: s ? e.clientY : e.clientX,
135
- size: x()
145
+ size: R()
136
146
  };
137
147
  try {
138
148
  (c = (t = e.currentTarget).setPointerCapture) == null || c.call(t, e.pointerId);
139
149
  } catch {
140
150
  }
141
151
  },
142
- [s, x]
152
+ [s, R]
143
153
  ), O = w(
144
154
  (e) => {
145
155
  const t = E.current;
146
156
  if (!t)
147
157
  return;
148
- const f = (s ? e.clientY : e.clientX) - t.start, g = r === "bottom" || r === "right" ? -f : f;
149
- h(t.size + g);
158
+ const f = (s ? e.clientY : e.clientX) - t.start, _ = r === "bottom" || r === "right" ? -f : f;
159
+ h(t.size + _);
150
160
  },
151
161
  [s, r, h]
152
- ), K = w((e) => {
153
- var t, c, f, g;
154
- E.current = null, (c = (t = e.currentTarget).hasPointerCapture) != null && c.call(t, e.pointerId) && ((g = (f = e.currentTarget).releasePointerCapture) == null || g.call(f, e.pointerId));
162
+ ), T = w((e) => {
163
+ var t, c, f, _;
164
+ E.current = null, (c = (t = e.currentTarget).hasPointerCapture) != null && c.call(t, e.pointerId) && ((_ = (f = e.currentTarget).releasePointerCapture) == null || _.call(f, e.pointerId));
155
165
  }, []), ee = w(
156
166
  (e) => {
157
- const t = l != null ? l : x(), c = o != null ? o : s ? window.innerHeight : window.innerWidth, f = r === "bottom" ? "ArrowUp" : r === "top" ? "ArrowDown" : r === "left" ? "ArrowRight" : "ArrowLeft", g = r === "bottom" ? "ArrowDown" : r === "top" ? "ArrowUp" : r === "left" ? "ArrowLeft" : "ArrowRight";
158
- e.key === f ? (e.preventDefault(), h(t + R)) : e.key === g ? (e.preventDefault(), h(t - R)) : e.key === "Home" ? (e.preventDefault(), h(i)) : e.key === "End" && (e.preventDefault(), h(c));
167
+ const t = l != null ? l : R(), c = o != null ? o : s ? window.innerHeight : window.innerWidth, f = r === "bottom" ? "ArrowUp" : r === "top" ? "ArrowDown" : r === "left" ? "ArrowRight" : "ArrowLeft", _ = r === "bottom" ? "ArrowDown" : r === "top" ? "ArrowUp" : r === "left" ? "ArrowLeft" : "ArrowRight";
168
+ e.key === f ? (e.preventDefault(), h(t + v)) : e.key === _ ? (e.preventDefault(), h(t - v)) : e.key === "Home" ? (e.preventDefault(), h(a)) : e.key === "End" && (e.preventDefault(), h(c));
159
169
  },
160
- [l, x, s, r, h, R, i, o]
170
+ [l, R, s, r, h, v, a, o]
161
171
  );
162
- T.useEffect(() => {
172
+ K.useEffect(() => {
163
173
  var e;
164
174
  if (!d) {
165
- L(null);
175
+ I(null);
166
176
  return;
167
177
  }
168
178
  (e = S.current) == null || e.focus();
169
179
  }, [d]);
170
- const te = y && l !== null ? { ...s ? { height: l } : { width: l }, transition: "none" } : {};
171
- return /* @__PURE__ */ n(j, { in: d, timeout: 120, appear: !0, classNames: { enterDone: "smwb-sheet_entered" }, nodeRef: I, children: /* @__PURE__ */ re(
180
+ const te = g && l !== null ? { ...s ? { height: l } : { width: l }, transition: "none" } : {};
181
+ return /* @__PURE__ */ n(j, { in: d, timeout: 120, appear: !0, classNames: { enterDone: "smwb-sheet_entered" }, nodeRef: B, children: /* @__PURE__ */ re(
172
182
  "div",
173
183
  {
174
184
  ref: Q,
175
185
  "data-testid": "sheet",
176
186
  tabIndex: -1,
177
187
  role: "dialog",
178
- "aria-modal": k === "modal" || void 0,
188
+ "aria-modal": A === "modal" || void 0,
179
189
  ...G,
180
- className: B("smwb-sheet", _, `smwb-sheet_${k}`, `smwb-${r}`, {
190
+ className: L("smwb-sheet", k, `smwb-sheet_${A}`, `smwb-${r}`, {
181
191
  "smwb-expanded": p === "expanded",
182
192
  "smwb-small": p === "small",
183
- "smwb-sheet_resizable": y
193
+ "smwb-sheet_resizable": g
184
194
  }),
185
- style: { "--sizeProp": v, ...te, ...Y },
195
+ style: { "--sizeProp": z, ...te, ...Y },
186
196
  children: [
187
- y && /* @__PURE__ */ n(
197
+ g && /* @__PURE__ */ n(
188
198
  "div",
189
199
  {
190
200
  className: "smwb-sheet__drag-handle",
@@ -193,13 +203,13 @@ const ye = ne(function({
193
203
  tabIndex: 0,
194
204
  "aria-orientation": s ? "horizontal" : "vertical",
195
205
  "aria-label": X,
196
- "aria-valuemin": i,
206
+ "aria-valuemin": a,
197
207
  "aria-valuemax": Math.round(o != null ? o : s ? window.innerHeight : window.innerWidth),
198
- "aria-valuenow": Math.round(l != null ? l : x()),
208
+ "aria-valuenow": Math.round(l != null ? l : R()),
199
209
  onPointerDown: Z,
200
210
  onPointerMove: O,
201
- onPointerUp: K,
202
- onPointerCancel: K,
211
+ onPointerUp: T,
212
+ onPointerCancel: T,
203
213
  onKeyDown: ee,
204
214
  children: /* @__PURE__ */ n("span", { className: "smwb-sheet__drag-handle-bar" })
205
215
  }
@@ -211,7 +221,7 @@ const ye = ne(function({
211
221
  ) });
212
222
  });
213
223
  export {
214
- ye as Sheet,
215
- ye as default
224
+ _e as Sheet,
225
+ _e as default
216
226
  };
217
227
  //# sourceMappingURL=sheet.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sheet.js","sources":["../../../../../src/components/layout/sheet/sheet.tsx"],"sourcesContent":["import React, { CSSProperties, forwardRef, PropsWithChildren, useCallback, useEffect, useRef, useState } from \"react\";\nimport cn from \"clsx\";\nimport { CSSTransition } from \"react-transition-group\";\nimport { createPortal } from \"react-dom\";\nimport Button from \"../../inputs/button/button\";\nimport Icon from \"../../base/icon/icon\";\nimport { ClickAwayListener } from \"../../clickAwayListener\";\nimport { useForkRef } from \"../../../hooks/useForkRef\";\n\nexport interface SheetProps extends React.HTMLAttributes<HTMLDivElement> {\n className?: string;\n placement?: \"top\" | \"bottom\" | \"right\" | \"left\";\n isOpen: boolean;\n onClose?: () => void;\n variant?: \"default\" | \"modal\";\n withSizeToggle?: boolean;\n /** Hide built-in header actions; onClose still handles Esc and backdrop. */\n hideHeaderActions?: boolean;\n reverseHeaderActions?: boolean;\n size?: string;\n disableOutsideClick?: boolean;\n /** Close the sheet when Escape is pressed. */\n closeOnEsc?: boolean;\n /**\n * Allow the user to resize the sheet by dragging a grab handle with\n * touch or mouse (mobile bottom-sheet style). Off by default.\n */\n resizable?: boolean;\n /** Minimum size in px while resizing (default 80). */\n minSize?: number;\n /** Maximum size in px while resizing (default: viewport dimension). */\n maxSize?: number;\n /** Step in px for keyboard resizing (default 24). */\n resizeStep?: number;\n /** Accessible label for the resize handle. */\n resizeHandleAriaLabel?: string;\n /** Called with the new size in px while/after resizing. */\n onResize?: (size: number) => void;\n \"aria-label\"?: string;\n}\n\ntype Mode = \"small\" | \"expanded\" | null;\n\nexport const Sheet = forwardRef<HTMLDivElement, PropsWithChildren<SheetProps>>(function Sheet(\n {\n isOpen,\n onClose,\n variant = \"default\",\n children,\n placement = \"bottom\",\n disableOutsideClick,\n closeOnEsc = true,\n ...props\n },\n ref\n) {\n const [mode, setMode] = useState<Mode>(null);\n const nodeRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!isOpen || !closeOnEsc || !onClose) {\n return;\n }\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n onClose();\n }\n };\n document.addEventListener(\"keydown\", onKeyDown);\n\n return () => document.removeEventListener(\"keydown\", onKeyDown);\n }, [isOpen, closeOnEsc, onClose]);\n\n const handleSizeButton = () => {\n if (mode === \"expanded\") {\n setMode(\"small\");\n } else if (!mode) {\n setMode(\"expanded\");\n } else {\n setMode(null);\n }\n };\n\n const handleClose = () => {\n onClose?.();\n setMode(null);\n };\n\n return createPortal(\n <CSSTransition\n in={isOpen}\n timeout={70}\n mountOnEnter\n unmountOnExit\n classNames={{ enterDone: \"smwb-entered\" }}\n appear\n nodeRef={nodeRef}\n >\n {variant === \"default\" ? (\n <div className={cn(disableOutsideClick ? \"smwb-sheet__overlay\" : \"smwb-sheet__default\")} ref={nodeRef}>\n <SheetBlock\n ref={ref}\n onClose={onClose}\n handleSizeButton={handleSizeButton}\n handleClose={handleClose}\n isOpen={isOpen}\n mode={mode}\n placement={placement}\n variant={variant}\n {...props}\n >\n {children}\n </SheetBlock>\n </div>\n ) : (\n <div\n className={cn(\"smwb-sheet__overlay\", \"smwb-dark\", `smwb-${placement}`, `smwb-sheet_${variant}`)}\n ref={nodeRef}\n >\n <ClickAwayListener onClickAway={() => !disableOutsideClick && handleClose()}>\n <SheetBlock\n ref={ref}\n onClose={onClose}\n handleSizeButton={handleSizeButton}\n handleClose={handleClose}\n isOpen={isOpen}\n mode={mode}\n placement={placement}\n variant={variant}\n {...props}\n >\n {children}\n </SheetBlock>\n </ClickAwayListener>\n </div>\n )}\n </CSSTransition>,\n document.body\n );\n});\n\nexport default Sheet;\n\ninterface SheetBlockProps extends SheetProps {\n mode: Mode;\n handleSizeButton: () => void;\n handleClose: () => void;\n}\n\n/** Sheets anchored to a horizontal edge resize on the Y axis, vertical edges on X. */\nconst isVerticalAxis = (placement: SheetProps[\"placement\"]) => placement === \"bottom\" || placement === \"top\";\n\nconst SheetBlock = React.forwardRef(function SheetBlock(props: SheetBlockProps, ref: React.Ref<HTMLDivElement>) {\n const {\n isOpen,\n placement,\n className,\n mode,\n\n size = \"60%\",\n variant,\n onClose,\n withSizeToggle = true,\n hideHeaderActions = false,\n reverseHeaderActions = false,\n resizable = false,\n minSize = 80,\n maxSize,\n resizeStep = 24,\n resizeHandleAriaLabel = \"Resize sheet\",\n onResize,\n style,\n handleClose,\n handleSizeButton,\n children,\n ...rest\n } = props;\n const showActions = !hideHeaderActions && (!!onClose || withSizeToggle);\n const headerActionNodes: React.ReactNode[] = [];\n if (withSizeToggle) {\n headerActionNodes.push(\n <Button variant={\"outlined\"} size=\"small\" onClick={handleSizeButton} key=\"size\">\n <Icon name=\"open_in_full\" />\n </Button>\n );\n }\n if (onClose) {\n headerActionNodes.push(\n <Button variant={\"outlined\"} size=\"small\" onClick={handleClose} key=\"close\">\n <Icon name=\"close\" />\n </Button>\n );\n }\n if (reverseHeaderActions) {\n headerActionNodes.reverse();\n }\n const nodeRef = useRef<HTMLDivElement>(null);\n const rootRef = useRef<HTMLDivElement>(null);\n const forkRef = useForkRef(ref, nodeRef, rootRef);\n\n // Drag-to-resize state. `dragSize` (px) wins over the CSS size when set\n // (inline style beats the .smwb-expanded/.smwb-small rules).\n const [dragSize, setDragSize] = useState<number | null>(null);\n const vertical = isVerticalAxis(placement);\n\n const clamp = useCallback(\n (px: number) => {\n const viewport = vertical ? window.innerHeight : window.innerWidth;\n const max = maxSize ?? viewport;\n return Math.max(minSize, Math.min(max, px));\n },\n [vertical, maxSize, minSize]\n );\n\n const currentSizePx = useCallback(() => {\n const rect = rootRef.current?.getBoundingClientRect();\n if (!rect) {\n return minSize;\n }\n return vertical ? rect.height : rect.width;\n }, [vertical, minSize]);\n\n const applySize = useCallback(\n (px: number) => {\n const next = clamp(px);\n setDragSize(next);\n onResize?.(next);\n },\n [clamp, onResize]\n );\n\n const dragRef = useRef<{ start: number; size: number } | null>(null);\n\n const onPointerDown = useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n event.preventDefault();\n dragRef.current = {\n start: vertical ? event.clientY : event.clientX,\n size: currentSizePx(),\n };\n try {\n event.currentTarget.setPointerCapture?.(event.pointerId);\n } catch {\n /* pointer capture is best-effort (unsupported in some envs) */\n }\n },\n [vertical, currentSizePx]\n );\n\n const onPointerMove = useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n const drag = dragRef.current;\n if (!drag) {\n return;\n }\n const pos = vertical ? event.clientY : event.clientX;\n const delta = pos - drag.start;\n // Sign so dragging *away* from the anchored edge grows the sheet.\n const grow = placement === \"bottom\" || placement === \"right\" ? -delta : delta;\n applySize(drag.size + grow);\n },\n [vertical, placement, applySize]\n );\n\n const endDrag = useCallback((event: React.PointerEvent<HTMLDivElement>) => {\n dragRef.current = null;\n if (event.currentTarget.hasPointerCapture?.(event.pointerId)) {\n event.currentTarget.releasePointerCapture?.(event.pointerId);\n }\n }, []);\n\n const onHandleKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n const base = dragSize ?? currentSizePx();\n const max = maxSize ?? (vertical ? window.innerHeight : window.innerWidth);\n // Key that should make the sheet *bigger*, per anchored edge.\n const incKey =\n placement === \"bottom\"\n ? \"ArrowUp\"\n : placement === \"top\"\n ? \"ArrowDown\"\n : placement === \"left\"\n ? \"ArrowRight\"\n : \"ArrowLeft\";\n const decKey =\n placement === \"bottom\"\n ? \"ArrowDown\"\n : placement === \"top\"\n ? \"ArrowUp\"\n : placement === \"left\"\n ? \"ArrowLeft\"\n : \"ArrowRight\";\n if (event.key === incKey) {\n event.preventDefault();\n applySize(base + resizeStep);\n } else if (event.key === decKey) {\n event.preventDefault();\n applySize(base - resizeStep);\n } else if (event.key === \"Home\") {\n event.preventDefault();\n applySize(minSize);\n } else if (event.key === \"End\") {\n event.preventDefault();\n applySize(max);\n }\n },\n [dragSize, currentSizePx, vertical, placement, applySize, resizeStep, minSize, maxSize]\n );\n\n React.useEffect(() => {\n if (!isOpen) {\n setDragSize(null);\n return;\n }\n\n rootRef.current?.focus();\n }, [isOpen]);\n\n // While a drag size is applied, suppress the sheet's 0.2s size\n // transition so the panel tracks the pointer in real time instead\n // of lagging 200ms behind every move.\n const sizeStyle: CSSProperties =\n resizable && dragSize !== null\n ? { ...(vertical ? { height: dragSize } : { width: dragSize }), transition: \"none\" }\n : {};\n\n return (\n <CSSTransition in={isOpen} timeout={120} appear classNames={{ enterDone: \"smwb-sheet_entered\" }} nodeRef={nodeRef}>\n <div\n ref={forkRef}\n data-testid=\"sheet\"\n tabIndex={-1}\n role=\"dialog\"\n aria-modal={variant === \"modal\" || undefined}\n {...rest}\n className={cn(\"smwb-sheet\", className, `smwb-sheet_${variant}`, `smwb-${placement}`, {\n \"smwb-expanded\": mode === \"expanded\",\n \"smwb-small\": mode === \"small\",\n \"smwb-sheet_resizable\": resizable,\n })}\n style={{ \"--sizeProp\": size, ...sizeStyle, ...style } as CSSProperties}\n >\n {resizable && (\n <div\n className=\"smwb-sheet__drag-handle\"\n data-testid=\"sheet-drag-handle\"\n role=\"separator\"\n tabIndex={0}\n aria-orientation={vertical ? \"horizontal\" : \"vertical\"}\n aria-label={resizeHandleAriaLabel}\n aria-valuemin={minSize}\n aria-valuemax={Math.round(maxSize ?? (vertical ? window.innerHeight : window.innerWidth))}\n aria-valuenow={Math.round(dragSize ?? currentSizePx())}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={endDrag}\n onPointerCancel={endDrag}\n onKeyDown={onHandleKeyDown}\n >\n <span className=\"smwb-sheet__drag-handle-bar\" />\n </div>\n )}\n {showActions && <div className=\"smwb-sheet__header\">{headerActionNodes}</div>}\n {isOpen && mode !== \"small\" && <div className=\"smwb-sheet__inner\">{children}</div>}\n </div>\n </CSSTransition>\n );\n});\n"],"names":["Sheet","forwardRef","isOpen","onClose","variant","children","placement","disableOutsideClick","closeOnEsc","props","ref","mode","setMode","useState","nodeRef","useRef","useEffect","onKeyDown","event","handleSizeButton","handleClose","createPortal","jsx","CSSTransition","cn","SheetBlock","ClickAwayListener","isVerticalAxis","React","className","size","withSizeToggle","hideHeaderActions","reverseHeaderActions","resizable","minSize","maxSize","resizeStep","resizeHandleAriaLabel","onResize","style","rest","showActions","headerActionNodes","Button","Icon","rootRef","forkRef","useForkRef","dragSize","setDragSize","vertical","clamp","useCallback","px","viewport","max","currentSizePx","rect","_a","applySize","next","dragRef","onPointerDown","_b","onPointerMove","drag","delta","grow","endDrag","_d","_c","onHandleKeyDown","base","incKey","decKey","sizeStyle","jsxs"],"mappings":"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"}
1
+ {"version":3,"file":"sheet.js","sources":["../../../../../src/components/layout/sheet/sheet.tsx"],"sourcesContent":["import React, { CSSProperties, forwardRef, PropsWithChildren, useCallback, useEffect, useRef, useState } from \"react\";\nimport cn from \"clsx\";\nimport { CSSTransition } from \"react-transition-group\";\nimport { createPortal } from \"react-dom\";\nimport Button from \"../../inputs/button/button\";\nimport Icon from \"../../base/icon/icon\";\nimport { ClickAwayListener } from \"../../clickAwayListener\";\nimport { useForkRef } from \"../../../hooks/useForkRef\";\nimport { isTopOverlayLayer } from \"../../../utils/overlayLayer\";\n\nexport interface SheetProps extends React.HTMLAttributes<HTMLDivElement> {\n className?: string;\n placement?: \"top\" | \"bottom\" | \"right\" | \"left\";\n isOpen: boolean;\n onClose?: () => void;\n variant?: \"default\" | \"modal\";\n withSizeToggle?: boolean;\n /** Hide built-in header actions; onClose still handles Esc and backdrop. */\n hideHeaderActions?: boolean;\n reverseHeaderActions?: boolean;\n size?: string;\n disableOutsideClick?: boolean;\n /** Close the sheet when Escape is pressed. */\n closeOnEsc?: boolean;\n /**\n * Allow the user to resize the sheet by dragging a grab handle with\n * touch or mouse (mobile bottom-sheet style). Off by default.\n */\n resizable?: boolean;\n /** Minimum size in px while resizing (default 80). */\n minSize?: number;\n /** Maximum size in px while resizing (default: viewport dimension). */\n maxSize?: number;\n /** Step in px for keyboard resizing (default 24). */\n resizeStep?: number;\n /** Accessible label for the resize handle. */\n resizeHandleAriaLabel?: string;\n /** Called with the new size in px while/after resizing. */\n onResize?: (size: number) => void;\n \"aria-label\"?: string;\n}\n\ntype Mode = \"small\" | \"expanded\" | null;\n\nexport const Sheet = forwardRef<HTMLDivElement, PropsWithChildren<SheetProps>>(function Sheet(\n {\n isOpen,\n onClose,\n variant = \"default\",\n children,\n placement = \"bottom\",\n disableOutsideClick,\n closeOnEsc = true,\n ...props\n },\n ref\n) {\n const [mode, setMode] = useState<Mode>(null);\n const nodeRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!isOpen || !closeOnEsc || !onClose) {\n return;\n }\n const onKeyDown = (event: KeyboardEvent) => {\n // Only the topmost overlay layer reacts to Escape.\n if (event.key === \"Escape\" && isTopOverlayLayer(nodeRef.current)) {\n onClose();\n }\n };\n document.addEventListener(\"keydown\", onKeyDown);\n\n return () => document.removeEventListener(\"keydown\", onKeyDown);\n }, [isOpen, closeOnEsc, onClose]);\n\n const handleSizeButton = () => {\n if (mode === \"expanded\") {\n setMode(\"small\");\n } else if (!mode) {\n setMode(\"expanded\");\n } else {\n setMode(null);\n }\n };\n\n const handleClose = () => {\n onClose?.();\n setMode(null);\n };\n\n return createPortal(\n <CSSTransition\n in={isOpen}\n timeout={70}\n mountOnEnter\n unmountOnExit\n classNames={{ enterDone: \"smwb-entered\" }}\n appear\n nodeRef={nodeRef}\n >\n {variant === \"default\" ? (\n <div\n className={cn(disableOutsideClick ? \"smwb-sheet__overlay\" : \"smwb-sheet__default\")}\n ref={nodeRef}\n data-smwb-overlay-layer=\"\"\n >\n <SheetBlock\n ref={ref}\n onClose={onClose}\n handleSizeButton={handleSizeButton}\n handleClose={handleClose}\n isOpen={isOpen}\n mode={mode}\n placement={placement}\n variant={variant}\n {...props}\n >\n {children}\n </SheetBlock>\n </div>\n ) : (\n <div\n className={cn(\"smwb-sheet__overlay\", \"smwb-dark\", `smwb-${placement}`, `smwb-sheet_${variant}`)}\n ref={nodeRef}\n data-smwb-overlay-layer=\"\"\n >\n <ClickAwayListener onClickAway={() => !disableOutsideClick && handleClose()}>\n <SheetBlock\n ref={ref}\n onClose={onClose}\n handleSizeButton={handleSizeButton}\n handleClose={handleClose}\n isOpen={isOpen}\n mode={mode}\n placement={placement}\n variant={variant}\n {...props}\n >\n {children}\n </SheetBlock>\n </ClickAwayListener>\n </div>\n )}\n </CSSTransition>,\n document.body\n );\n});\n\nexport default Sheet;\n\ninterface SheetBlockProps extends SheetProps {\n mode: Mode;\n handleSizeButton: () => void;\n handleClose: () => void;\n}\n\n/** Sheets anchored to a horizontal edge resize on the Y axis, vertical edges on X. */\nconst isVerticalAxis = (placement: SheetProps[\"placement\"]) => placement === \"bottom\" || placement === \"top\";\n\nconst SheetBlock = React.forwardRef(function SheetBlock(props: SheetBlockProps, ref: React.Ref<HTMLDivElement>) {\n const {\n isOpen,\n placement,\n className,\n mode,\n\n size = \"60%\",\n variant,\n onClose,\n withSizeToggle = true,\n hideHeaderActions = false,\n reverseHeaderActions = false,\n resizable = false,\n minSize = 80,\n maxSize,\n resizeStep = 24,\n resizeHandleAriaLabel = \"Resize sheet\",\n onResize,\n style,\n handleClose,\n handleSizeButton,\n children,\n ...rest\n } = props;\n const showActions = !hideHeaderActions && (!!onClose || withSizeToggle);\n const headerActionNodes: React.ReactNode[] = [];\n if (withSizeToggle) {\n headerActionNodes.push(\n <Button variant={\"outlined\"} size=\"small\" onClick={handleSizeButton} key=\"size\">\n <Icon name=\"open_in_full\" />\n </Button>\n );\n }\n if (onClose) {\n headerActionNodes.push(\n <Button variant={\"outlined\"} size=\"small\" onClick={handleClose} key=\"close\">\n <Icon name=\"close\" />\n </Button>\n );\n }\n if (reverseHeaderActions) {\n headerActionNodes.reverse();\n }\n const nodeRef = useRef<HTMLDivElement>(null);\n const rootRef = useRef<HTMLDivElement>(null);\n const forkRef = useForkRef(ref, nodeRef, rootRef);\n\n // Drag-to-resize state. `dragSize` (px) wins over the CSS size when set\n // (inline style beats the .smwb-expanded/.smwb-small rules).\n const [dragSize, setDragSize] = useState<number | null>(null);\n const vertical = isVerticalAxis(placement);\n\n const clamp = useCallback(\n (px: number) => {\n const viewport = vertical ? window.innerHeight : window.innerWidth;\n const max = maxSize ?? viewport;\n return Math.max(minSize, Math.min(max, px));\n },\n [vertical, maxSize, minSize]\n );\n\n const currentSizePx = useCallback(() => {\n const rect = rootRef.current?.getBoundingClientRect();\n if (!rect) {\n return minSize;\n }\n return vertical ? rect.height : rect.width;\n }, [vertical, minSize]);\n\n const applySize = useCallback(\n (px: number) => {\n const next = clamp(px);\n setDragSize(next);\n onResize?.(next);\n },\n [clamp, onResize]\n );\n\n const dragRef = useRef<{ start: number; size: number } | null>(null);\n\n const onPointerDown = useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n event.preventDefault();\n dragRef.current = {\n start: vertical ? event.clientY : event.clientX,\n size: currentSizePx(),\n };\n try {\n event.currentTarget.setPointerCapture?.(event.pointerId);\n } catch {\n /* pointer capture is best-effort (unsupported in some envs) */\n }\n },\n [vertical, currentSizePx]\n );\n\n const onPointerMove = useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n const drag = dragRef.current;\n if (!drag) {\n return;\n }\n const pos = vertical ? event.clientY : event.clientX;\n const delta = pos - drag.start;\n // Sign so dragging *away* from the anchored edge grows the sheet.\n const grow = placement === \"bottom\" || placement === \"right\" ? -delta : delta;\n applySize(drag.size + grow);\n },\n [vertical, placement, applySize]\n );\n\n const endDrag = useCallback((event: React.PointerEvent<HTMLDivElement>) => {\n dragRef.current = null;\n if (event.currentTarget.hasPointerCapture?.(event.pointerId)) {\n event.currentTarget.releasePointerCapture?.(event.pointerId);\n }\n }, []);\n\n const onHandleKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n const base = dragSize ?? currentSizePx();\n const max = maxSize ?? (vertical ? window.innerHeight : window.innerWidth);\n // Key that should make the sheet *bigger*, per anchored edge.\n const incKey =\n placement === \"bottom\"\n ? \"ArrowUp\"\n : placement === \"top\"\n ? \"ArrowDown\"\n : placement === \"left\"\n ? \"ArrowRight\"\n : \"ArrowLeft\";\n const decKey =\n placement === \"bottom\"\n ? \"ArrowDown\"\n : placement === \"top\"\n ? \"ArrowUp\"\n : placement === \"left\"\n ? \"ArrowLeft\"\n : \"ArrowRight\";\n if (event.key === incKey) {\n event.preventDefault();\n applySize(base + resizeStep);\n } else if (event.key === decKey) {\n event.preventDefault();\n applySize(base - resizeStep);\n } else if (event.key === \"Home\") {\n event.preventDefault();\n applySize(minSize);\n } else if (event.key === \"End\") {\n event.preventDefault();\n applySize(max);\n }\n },\n [dragSize, currentSizePx, vertical, placement, applySize, resizeStep, minSize, maxSize]\n );\n\n React.useEffect(() => {\n if (!isOpen) {\n setDragSize(null);\n return;\n }\n\n rootRef.current?.focus();\n }, [isOpen]);\n\n // While a drag size is applied, suppress the sheet's 0.2s size\n // transition so the panel tracks the pointer in real time instead\n // of lagging 200ms behind every move.\n const sizeStyle: CSSProperties =\n resizable && dragSize !== null\n ? { ...(vertical ? { height: dragSize } : { width: dragSize }), transition: \"none\" }\n : {};\n\n return (\n <CSSTransition in={isOpen} timeout={120} appear classNames={{ enterDone: \"smwb-sheet_entered\" }} nodeRef={nodeRef}>\n <div\n ref={forkRef}\n data-testid=\"sheet\"\n tabIndex={-1}\n role=\"dialog\"\n aria-modal={variant === \"modal\" || undefined}\n {...rest}\n className={cn(\"smwb-sheet\", className, `smwb-sheet_${variant}`, `smwb-${placement}`, {\n \"smwb-expanded\": mode === \"expanded\",\n \"smwb-small\": mode === \"small\",\n \"smwb-sheet_resizable\": resizable,\n })}\n style={{ \"--sizeProp\": size, ...sizeStyle, ...style } as CSSProperties}\n >\n {resizable && (\n <div\n className=\"smwb-sheet__drag-handle\"\n data-testid=\"sheet-drag-handle\"\n role=\"separator\"\n tabIndex={0}\n aria-orientation={vertical ? \"horizontal\" : \"vertical\"}\n aria-label={resizeHandleAriaLabel}\n aria-valuemin={minSize}\n aria-valuemax={Math.round(maxSize ?? (vertical ? window.innerHeight : window.innerWidth))}\n aria-valuenow={Math.round(dragSize ?? currentSizePx())}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={endDrag}\n onPointerCancel={endDrag}\n onKeyDown={onHandleKeyDown}\n >\n <span className=\"smwb-sheet__drag-handle-bar\" />\n </div>\n )}\n {showActions && <div className=\"smwb-sheet__header\">{headerActionNodes}</div>}\n {isOpen && mode !== \"small\" && <div className=\"smwb-sheet__inner\">{children}</div>}\n </div>\n </CSSTransition>\n );\n});\n"],"names":["Sheet","forwardRef","isOpen","onClose","variant","children","placement","disableOutsideClick","closeOnEsc","props","ref","mode","setMode","useState","nodeRef","useRef","useEffect","onKeyDown","event","isTopOverlayLayer","handleSizeButton","handleClose","createPortal","jsx","CSSTransition","cn","SheetBlock","ClickAwayListener","isVerticalAxis","React","className","size","withSizeToggle","hideHeaderActions","reverseHeaderActions","resizable","minSize","maxSize","resizeStep","resizeHandleAriaLabel","onResize","style","rest","showActions","headerActionNodes","Button","Icon","rootRef","forkRef","useForkRef","dragSize","setDragSize","vertical","clamp","useCallback","px","viewport","max","currentSizePx","rect","_a","applySize","next","dragRef","onPointerDown","_b","onPointerMove","drag","delta","grow","endDrag","_d","_c","onHandleKeyDown","base","incKey","decKey","sizeStyle","jsxs"],"mappings":"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"}
@@ -0,0 +1,117 @@
1
+ import { useState as k, useRef as m, useMemo as _, useCallback as e, useEffect as S } from "react";
2
+ import { offset as z, flip as B, shift as G, useFloating as V, autoUpdate as j } from "@floating-ui/react";
3
+ import { resolvePlacement as q } from "../utils/floating.js";
4
+ const J = "bottom-start", K = 4, Q = 8, W = ({ x: l, y: r }) => ({
5
+ x: l,
6
+ y: r,
7
+ top: r,
8
+ left: l,
9
+ right: l,
10
+ bottom: r,
11
+ width: 0,
12
+ height: 0
13
+ });
14
+ function H(l = {}) {
15
+ const {
16
+ placement: r = J,
17
+ offsetPx: T = K,
18
+ openDelay: M = 0,
19
+ closeDelay: R = 0,
20
+ middleware: a
21
+ } = l, [p, c] = k(!1), A = m({ x: 0, y: 0 }), F = m({ x: 0, y: 0 }), h = m(null), P = m(null), s = m(null), E = q(r), X = _(
22
+ () => [
23
+ z({ mainAxis: T, crossAxis: T }),
24
+ ...E.autoMiddleware ? [E.autoMiddleware] : [B()],
25
+ G({ padding: Q }),
26
+ ...a != null ? a : []
27
+ ],
28
+ [T, E.autoMiddleware, a]
29
+ ), { refs: g, floatingStyles: w, update: y } = V({
30
+ open: p,
31
+ placement: E.placement,
32
+ whileElementsMounted: j,
33
+ middleware: X
34
+ }), x = _(
35
+ () => ({ getBoundingClientRect: () => W(F.current) }),
36
+ []
37
+ ), o = e(() => {
38
+ P.current !== null && (clearTimeout(P.current), P.current = null), s.current !== null && (clearTimeout(s.current), s.current = null);
39
+ }, []);
40
+ S(() => () => o(), [o]), S(() => {
41
+ var t;
42
+ p && (g.setPositionReference((t = h.current) != null ? t : x), y());
43
+ }, [p, g, y, x]);
44
+ const f = e(() => {
45
+ h.current === null && (F.current = A.current);
46
+ }, []), b = e(() => {
47
+ o(), f(), c(!0);
48
+ }, [o, f]), v = e(() => {
49
+ if (o(), M <= 0) {
50
+ f(), c(!0);
51
+ return;
52
+ }
53
+ P.current = setTimeout(() => {
54
+ f(), c(!0);
55
+ }, M);
56
+ }, [o, f, M]), u = e(() => {
57
+ if (o(), R <= 0) {
58
+ c(!1);
59
+ return;
60
+ }
61
+ s.current = setTimeout(() => c(!1), R);
62
+ }, [o, R]), N = e(() => {
63
+ o(), c(!1);
64
+ }, [o]), O = e((t) => {
65
+ h.current = null, F.current = t;
66
+ }, []), U = e((t) => {
67
+ h.current = t;
68
+ }, []), D = e(
69
+ (t) => {
70
+ A.current = { x: t.clientX, y: t.clientY }, v();
71
+ },
72
+ [v]
73
+ ), L = e((t) => {
74
+ A.current = { x: t.clientX, y: t.clientY };
75
+ }, []), I = e(
76
+ (t) => ({
77
+ onPointerEnter: (i) => {
78
+ var n;
79
+ (n = t == null ? void 0 : t.onPointerEnter) == null || n.call(t, i), D(i);
80
+ },
81
+ onPointerMove: (i) => {
82
+ var n;
83
+ (n = t == null ? void 0 : t.onPointerMove) == null || n.call(t, i), L(i);
84
+ },
85
+ onPointerLeave: (i) => {
86
+ var n;
87
+ (n = t == null ? void 0 : t.onPointerLeave) == null || n.call(t, i), u();
88
+ }
89
+ }),
90
+ [D, L, u]
91
+ ), C = e(() => {
92
+ o(), c(!0);
93
+ }, [o]), Y = e(
94
+ (t) => ({
95
+ ref: g.setFloating,
96
+ style: { ...w, ...t == null ? void 0 : t.style },
97
+ onPointerEnter: C,
98
+ onPointerLeave: u
99
+ }),
100
+ [g, w, C, u]
101
+ );
102
+ return {
103
+ open: p,
104
+ getReferenceProps: I,
105
+ getFloatingProps: Y,
106
+ setAnchorEl: U,
107
+ setVirtualAnchor: O,
108
+ openNow: b,
109
+ scheduleOpen: v,
110
+ scheduleClose: u,
111
+ close: N
112
+ };
113
+ }
114
+ export {
115
+ H as useHoverPopover
116
+ };
117
+ //# sourceMappingURL=useHoverPopover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useHoverPopover.js","sources":["../../../src/hooks/useHoverPopover.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { CSSProperties, PointerEvent as ReactPointerEvent } from \"react\";\nimport { autoUpdate, flip, offset, shift, useFloating } from \"@floating-ui/react\";\nimport type { Middleware, VirtualElement } from \"@floating-ui/react\";\nimport { resolvePlacement } from \"../utils/floating\";\nimport type { Placement } from \"../utils/floating\";\n\nexport interface UseHoverPopoverParams {\n /** Placement of the popover relative to its anchor. Default `\"bottom-start\"`. */\n placement?: Placement;\n /** Offset (px) applied on both axes between the anchor and the popover. Default `4`. */\n offsetPx?: number;\n /** Delay (ms) before opening after pointer enter. Default `0`. */\n openDelay?: number;\n /** Delay (ms) before closing after pointer leave. Default `0`. */\n closeDelay?: number;\n /** Extra floating-ui middleware appended after the smwb defaults. */\n middleware?: Middleware[];\n}\n\n/** A pointer position in viewport (client) coordinates. */\nexport interface HoverPopoverPoint {\n x: number;\n y: number;\n}\n\nexport interface HoverPopoverReferenceProps {\n onPointerEnter: (event: ReactPointerEvent) => void;\n onPointerMove: (event: ReactPointerEvent) => void;\n onPointerLeave: (event: ReactPointerEvent) => void;\n}\n\nexport interface HoverPopoverFloatingProps {\n ref: (node: HTMLElement | null) => void;\n style: CSSProperties;\n onPointerEnter: () => void;\n onPointerLeave: () => void;\n}\n\nexport interface UseHoverPopoverResult {\n /** Whether the popover is currently open. */\n open: boolean;\n /**\n * Pointer handlers for the trigger element(s). Spread on a single anchor, or\n * on EVERY row of a list/table to share one popover across many triggers. By\n * default the popover is anchored to the cursor position frozen when it opens.\n * Pass your own handlers to compose them (e.g. to mark which row is active).\n */\n getReferenceProps: (userHandlers?: Partial<HoverPopoverReferenceProps>) => HoverPopoverReferenceProps;\n /** Props for the single floating element; keeps it open while it is hovered. */\n getFloatingProps: (userProps?: { style?: CSSProperties }) => HoverPopoverFloatingProps;\n /** Anchor the popover to a real element instead of the cursor (`null` clears it). */\n setAnchorEl: (element: Element | null) => void;\n /** Anchor the popover to an explicit point, e.g. an external cursor source. */\n setVirtualAnchor: (point: HoverPopoverPoint) => void;\n /** Open immediately, ignoring `openDelay`. */\n openNow: () => void;\n /** Open after `openDelay`. */\n scheduleOpen: () => void;\n /** Close after `closeDelay`. */\n scheduleClose: () => void;\n /** Close immediately. */\n close: () => void;\n}\n\nconst DEFAULT_PLACEMENT: Placement = \"bottom-start\";\nconst DEFAULT_OFFSET_PX = 4;\nconst SHIFT_PADDING_PX = 8;\n\nconst rectFromPoint = ({ x, y }: HoverPopoverPoint) => ({\n x,\n y,\n top: y,\n left: x,\n right: x,\n bottom: y,\n width: 0,\n height: 0,\n});\n\n/**\n * Headless hover-popover positioning.\n *\n * Wraps floating-ui with the smwb placement / offset / flip / shift conventions\n * but imposes NO DOM structure: spread `getReferenceProps()` on any trigger\n * (including a `<tr>`, which the wrapper-based `<Tooltip>` cannot do) and\n * `getFloatingProps()` on a single floating element you render yourself.\n *\n * The default anchor is the cursor point frozen when the popover opens (a\n * floating-ui virtual element), so ONE instance can serve a whole table/list —\n * call `getReferenceProps()` on every row and render one shared popover instead\n * of mounting one floating engine per row. Use `setAnchorEl` to anchor to a\n * real element instead.\n */\nexport function useHoverPopover(params: UseHoverPopoverParams = {}): UseHoverPopoverResult {\n const {\n placement = DEFAULT_PLACEMENT,\n offsetPx = DEFAULT_OFFSET_PX,\n openDelay = 0,\n closeDelay = 0,\n middleware,\n } = params;\n\n const [open, setOpen] = useState(false);\n\n const cursorRef = useRef<HoverPopoverPoint>({ x: 0, y: 0 });\n const anchorRef = useRef<HoverPopoverPoint>({ x: 0, y: 0 });\n const anchorElRef = useRef<Element | null>(null);\n const openTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const closeTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const resolved = resolvePlacement(placement);\n\n const floatingMiddleware = useMemo<Middleware[]>(\n () => [\n offset({ mainAxis: offsetPx, crossAxis: offsetPx }),\n ...(resolved.autoMiddleware ? [resolved.autoMiddleware] : [flip()]),\n shift({ padding: SHIFT_PADDING_PX }),\n ...(middleware ?? []),\n ],\n [offsetPx, resolved.autoMiddleware, middleware]\n );\n\n const { refs, floatingStyles, update } = useFloating({\n open,\n placement: resolved.placement,\n whileElementsMounted: autoUpdate,\n middleware: floatingMiddleware,\n });\n\n const virtualReference = useMemo<VirtualElement>(\n () => ({ getBoundingClientRect: () => rectFromPoint(anchorRef.current) }),\n []\n );\n\n const clearTimers = useCallback(() => {\n if (openTimerRef.current !== null) {\n clearTimeout(openTimerRef.current);\n openTimerRef.current = null;\n }\n if (closeTimerRef.current !== null) {\n clearTimeout(closeTimerRef.current);\n closeTimerRef.current = null;\n }\n }, []);\n\n useEffect(() => () => clearTimers(), [clearTimers]);\n\n // Apply the active anchor (element or frozen cursor) whenever the popover\n // opens; autoUpdate keeps it positioned while the floating element is mounted.\n useEffect(() => {\n if (!open) return;\n refs.setPositionReference(anchorElRef.current ?? virtualReference);\n void update();\n }, [open, refs, update, virtualReference]);\n\n const freezeAnchor = useCallback(() => {\n if (anchorElRef.current === null) anchorRef.current = cursorRef.current;\n }, []);\n\n const openNow = useCallback(() => {\n clearTimers();\n freezeAnchor();\n setOpen(true);\n }, [clearTimers, freezeAnchor]);\n\n const scheduleOpen = useCallback(() => {\n clearTimers();\n if (openDelay <= 0) {\n freezeAnchor();\n setOpen(true);\n return;\n }\n openTimerRef.current = setTimeout(() => {\n freezeAnchor();\n setOpen(true);\n }, openDelay);\n }, [clearTimers, freezeAnchor, openDelay]);\n\n const scheduleClose = useCallback(() => {\n clearTimers();\n if (closeDelay <= 0) {\n setOpen(false);\n return;\n }\n closeTimerRef.current = setTimeout(() => setOpen(false), closeDelay);\n }, [clearTimers, closeDelay]);\n\n const close = useCallback(() => {\n clearTimers();\n setOpen(false);\n }, [clearTimers]);\n\n const setVirtualAnchor = useCallback((point: HoverPopoverPoint) => {\n anchorElRef.current = null;\n anchorRef.current = point;\n }, []);\n\n const setAnchorEl = useCallback((element: Element | null) => {\n anchorElRef.current = element;\n }, []);\n\n const handleEnter = useCallback(\n (event: ReactPointerEvent) => {\n cursorRef.current = { x: event.clientX, y: event.clientY };\n scheduleOpen();\n },\n [scheduleOpen]\n );\n\n const handleMove = useCallback((event: ReactPointerEvent) => {\n cursorRef.current = { x: event.clientX, y: event.clientY };\n }, []);\n\n const getReferenceProps = useCallback<UseHoverPopoverResult[\"getReferenceProps\"]>(\n (userHandlers) => ({\n onPointerEnter: (event) => {\n userHandlers?.onPointerEnter?.(event);\n handleEnter(event);\n },\n onPointerMove: (event) => {\n userHandlers?.onPointerMove?.(event);\n handleMove(event);\n },\n onPointerLeave: (event) => {\n userHandlers?.onPointerLeave?.(event);\n scheduleClose();\n },\n }),\n [handleEnter, handleMove, scheduleClose]\n );\n\n const cancelClose = useCallback(() => {\n clearTimers();\n setOpen(true);\n }, [clearTimers]);\n\n const getFloatingProps = useCallback<UseHoverPopoverResult[\"getFloatingProps\"]>(\n (userProps) => ({\n ref: refs.setFloating,\n style: { ...floatingStyles, ...userProps?.style },\n onPointerEnter: cancelClose,\n onPointerLeave: scheduleClose,\n }),\n [refs, floatingStyles, cancelClose, scheduleClose]\n );\n\n return {\n open,\n getReferenceProps,\n getFloatingProps,\n setAnchorEl,\n setVirtualAnchor,\n openNow,\n scheduleOpen,\n scheduleClose,\n close,\n };\n}\n"],"names":["DEFAULT_PLACEMENT","DEFAULT_OFFSET_PX","SHIFT_PADDING_PX","rectFromPoint","x","y","useHoverPopover","params","placement","offsetPx","openDelay","closeDelay","middleware","open","setOpen","useState","cursorRef","useRef","anchorRef","anchorElRef","openTimerRef","closeTimerRef","resolved","resolvePlacement","floatingMiddleware","useMemo","offset","flip","shift","refs","floatingStyles","update","useFloating","autoUpdate","virtualReference","clearTimers","useCallback","useEffect","_a","freezeAnchor","openNow","scheduleOpen","scheduleClose","close","setVirtualAnchor","point","setAnchorEl","element","handleEnter","event","handleMove","getReferenceProps","userHandlers","cancelClose","getFloatingProps","userProps"],"mappings":"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"}