@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 +1 @@
1
- {"version":3,"file":"timePicker.js","sources":["../../../../src/components/inputs/timePicker/timePicker.tsx"],"sourcesContent":["import React, { useCallback, useMemo, useRef, useState } from \"react\";\nimport { autoUpdate, useFloating } from \"@floating-ui/react\";\nimport Transition, { TransitionStatus } from \"react-transition-group/Transition\";\nimport { buildFloatingMiddleware, Placement, resolvePlacement } from \"../../../utils/floating\";\nimport { useSafeLayoutEffect } from \"../../../hooks/useSafeLayoutEffect\";\nimport { useForkRef } from \"../../../hooks/useForkRef\";\nimport { TextFieldProps } from \"../textField\";\nimport { ClickAwayListener } from \"../../clickAwayListener\";\nimport { TimePickerInput } from \"./timePickerInput\";\nimport { TimePickerColumns } from \"./timePickerColumns\";\nimport { isValidTimeDate } from \"./timeUtils\";\nimport { createPortal } from \"react-dom\";\n\nconst defaultStyle = (duration: number) => ({\n transition: `opacity ${duration}ms ease-in-out`,\n opacity: 0,\n});\n\nconst transitionStyles = {\n entering: { opacity: 1 },\n entered: { opacity: 1 },\n exiting: { opacity: 0 },\n} as Record<TransitionStatus, { opacity: number }>;\n\nexport interface TimePickerProps extends Omit<TextFieldProps, \"onBlur\" | \"onChange\" | \"value\" | \"defaultValue\"> {\n /** Time format pattern with tokens HH, mm, ss, e.g. \"HH:mm\" or \"HH:mm:ss\". */\n format?: string;\n placement?: Placement;\n disableClock?: boolean;\n label?: string;\n clockAriaLabel?: string;\n autoComplete?: string;\n value?: Date | string;\n clockIcon?: React.ReactNode;\n onChange?: (event?: React.ChangeEvent<HTMLInputElement>, value?: Date, data?: TimePickerProps) => void;\n onBlur?: (event?: React.FocusEvent<HTMLInputElement>, value?: Date, data?: TimePickerProps) => void;\n}\n\nexport const TimePicker = React.forwardRef(function TimePicker(props: TimePickerProps, ref) {\n const {\n value: valueProp,\n onChange: onChangeProp,\n placement = \"bottom-start\",\n disabled,\n disableClock,\n clockAriaLabel = \"Choose time\",\n format,\n onBlur: onBlurProp,\n ...rest\n } = props;\n const value = useMemo(() => (valueProp === undefined ? undefined : new Date(valueProp)), [valueProp]);\n const [viewValue, setViewValue] = useState<Date>(() => (isValidTimeDate(value) ? value : new Date()));\n const [isOpen, setIsOpen] = useState(false);\n\n const anchorRef = useRef<HTMLDivElement | null>(null);\n const clockRef = useRef<HTMLDivElement | null>(null);\n\n const resolved = resolvePlacement(placement);\n const { refs, floatingStyles } = useFloating({\n open: isOpen,\n placement: resolved.placement,\n whileElementsMounted: autoUpdate,\n middleware: buildFloatingMiddleware(resolved),\n });\n\n const anchorForkRef = useForkRef(anchorRef, refs.setReference, ref);\n const clockForkRef = useForkRef(clockRef, refs.setFloating);\n\n useSafeLayoutEffect(() => {\n if (disabled) {\n return;\n }\n\n setViewValue(isValidTimeDate(value) ? value : new Date());\n }, [value, disabled]);\n\n const onToggle = useCallback(() => {\n if (!disabled) {\n setIsOpen((prevState) => !prevState);\n }\n }, [disabled]);\n\n const onClickAway = useCallback((event: Event | React.SyntheticEvent) => {\n const target = event.target as HTMLElement;\n\n if (clockRef.current?.contains(target) || anchorRef.current?.contains(target)) {\n return;\n }\n\n setIsOpen(false);\n }, []);\n\n const onTimeChange = useCallback(\n (next: Date) => {\n setViewValue(next);\n onChangeProp?.(undefined, next, props);\n },\n [onChangeProp, props]\n );\n\n const onComplete = useCallback(() => {\n setIsOpen(false);\n }, []);\n\n return (\n <>\n <TimePickerInput\n ref={anchorForkRef}\n value={value}\n onChange={onChangeProp}\n onBlur={onBlurProp}\n onToggle={onToggle}\n disabled={disabled}\n disableClock={disableClock}\n format={format}\n {...rest}\n />\n {createPortal(\n <Transition\n nodeRef={clockRef}\n in={isOpen && !disabled && !disableClock}\n timeout={150}\n mountOnEnter\n unmountOnExit\n >\n {(state) => (\n <ClickAwayListener onClickAway={onClickAway}>\n <div\n ref={clockForkRef}\n className=\"smwb-date-picker smwb-time-picker\"\n style={{\n ...floatingStyles,\n ...defaultStyle(150),\n ...transitionStyles[state],\n }}\n data-testid=\"time-picker\"\n role=\"dialog\"\n aria-modal=\"false\"\n aria-label={clockAriaLabel}\n >\n <div className=\"smwb-date-picker__inner\">\n <TimePickerColumns\n value={viewValue}\n format={format}\n onChange={onTimeChange}\n onComplete={onComplete}\n />\n </div>\n </div>\n </ClickAwayListener>\n )}\n </Transition>,\n document.body\n )}\n </>\n );\n});\n\nexport default TimePicker;\n"],"names":["defaultStyle","duration","transitionStyles","TimePicker","React","props","ref","valueProp","onChangeProp","placement","disabled","disableClock","clockAriaLabel","format","onBlurProp","rest","value","useMemo","viewValue","setViewValue","useState","isValidTimeDate","isOpen","setIsOpen","anchorRef","useRef","clockRef","resolved","resolvePlacement","refs","floatingStyles","useFloating","autoUpdate","buildFloatingMiddleware","anchorForkRef","useForkRef","clockForkRef","useSafeLayoutEffect","onToggle","useCallback","prevState","onClickAway","event","target","_a","_b","onTimeChange","next","onComplete","jsxs","Fragment","jsx","TimePickerInput","createPortal","Transition","state","ClickAwayListener","TimePickerColumns"],"mappings":"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"}
1
+ {"version":3,"file":"timePicker.js","sources":["../../../../src/components/inputs/timePicker/timePicker.tsx"],"sourcesContent":["import React, { useCallback, useMemo, useRef, useState } from \"react\";\nimport { autoUpdate, useFloating } from \"@floating-ui/react\";\nimport Transition, { TransitionStatus } from \"react-transition-group/Transition\";\nimport { buildFloatingMiddleware, Placement, resolvePlacement } from \"../../../utils/floating\";\nimport { useSafeLayoutEffect } from \"../../../hooks/useSafeLayoutEffect\";\nimport { useForkRef } from \"../../../hooks/useForkRef\";\nimport { TextFieldProps } from \"../textField\";\nimport { ClickAwayListener } from \"../../clickAwayListener\";\nimport { TimePickerInput } from \"./timePickerInput\";\nimport { TimePickerColumns } from \"./timePickerColumns\";\nimport { isValidTimeDate } from \"./timeUtils\";\nimport { createPortal } from \"react-dom\";\n\nconst defaultStyle = (duration: number) => ({\n transition: `opacity ${duration}ms ease-in-out`,\n opacity: 0,\n});\n\nconst transitionStyles = {\n entering: { opacity: 1 },\n entered: { opacity: 1 },\n exiting: { opacity: 0 },\n} as Record<TransitionStatus, { opacity: number }>;\n\nexport interface TimePickerProps extends Omit<TextFieldProps, \"onBlur\" | \"onChange\" | \"value\" | \"defaultValue\"> {\n /** Time format pattern with tokens HH, mm, ss, e.g. \"HH:mm\" or \"HH:mm:ss\". */\n format?: string;\n placement?: Placement;\n disableClock?: boolean;\n label?: string;\n clockAriaLabel?: string;\n autoComplete?: string;\n value?: Date | string;\n clockIcon?: React.ReactNode;\n onChange?: (event?: React.ChangeEvent<HTMLInputElement>, value?: Date, data?: TimePickerProps) => void;\n onBlur?: (event?: React.FocusEvent<HTMLInputElement>, value?: Date, data?: TimePickerProps) => void;\n}\n\nexport const TimePicker = React.forwardRef(function TimePicker(props: TimePickerProps, ref) {\n const {\n value: valueProp,\n onChange: onChangeProp,\n placement = \"bottom-start\",\n disabled,\n disableClock,\n clockAriaLabel = \"Choose time\",\n format,\n onBlur: onBlurProp,\n ...rest\n } = props;\n const value = useMemo(() => (valueProp === undefined ? undefined : new Date(valueProp)), [valueProp]);\n const [viewValue, setViewValue] = useState<Date>(() => (isValidTimeDate(value) ? value : new Date()));\n const [isOpen, setIsOpen] = useState(false);\n\n const anchorRef = useRef<HTMLDivElement | null>(null);\n const clockRef = useRef<HTMLDivElement | null>(null);\n\n const resolved = resolvePlacement(placement);\n const { refs, floatingStyles } = useFloating({\n open: isOpen,\n placement: resolved.placement,\n whileElementsMounted: autoUpdate,\n middleware: buildFloatingMiddleware(resolved),\n });\n\n const anchorForkRef = useForkRef(anchorRef, refs.setReference, ref);\n const clockForkRef = useForkRef(clockRef, refs.setFloating);\n\n useSafeLayoutEffect(() => {\n if (disabled) {\n return;\n }\n\n setViewValue(isValidTimeDate(value) ? value : new Date());\n }, [value, disabled]);\n\n const onToggle = useCallback(() => {\n if (!disabled) {\n setIsOpen((prevState) => !prevState);\n }\n }, [disabled]);\n\n const onClickAway = useCallback((event: Event | React.SyntheticEvent) => {\n const target = event.target as HTMLElement;\n\n if (clockRef.current?.contains(target) || anchorRef.current?.contains(target)) {\n return;\n }\n\n setIsOpen(false);\n }, []);\n\n const onTimeChange = useCallback(\n (next: Date) => {\n setViewValue(next);\n onChangeProp?.(undefined, next, props);\n },\n [onChangeProp, props]\n );\n\n const onComplete = useCallback(() => {\n setIsOpen(false);\n }, []);\n\n return (\n <>\n <TimePickerInput\n ref={anchorForkRef}\n value={value}\n onChange={onChangeProp}\n onBlur={onBlurProp}\n onToggle={onToggle}\n disabled={disabled}\n disableClock={disableClock}\n format={format}\n {...rest}\n />\n {createPortal(\n <Transition\n nodeRef={clockRef}\n in={isOpen && !disabled && !disableClock}\n timeout={150}\n mountOnEnter\n unmountOnExit\n >\n {(state) => (\n <ClickAwayListener onClickAway={onClickAway}>\n <div\n ref={clockForkRef}\n className=\"smwb-date-picker smwb-time-picker\"\n style={{\n ...floatingStyles,\n ...defaultStyle(150),\n ...transitionStyles[state],\n }}\n data-testid=\"time-picker\"\n data-smwb-overlay-layer=\"\"\n role=\"dialog\"\n aria-modal=\"false\"\n aria-label={clockAriaLabel}\n >\n <div className=\"smwb-date-picker__inner\">\n <TimePickerColumns\n value={viewValue}\n format={format}\n onChange={onTimeChange}\n onComplete={onComplete}\n />\n </div>\n </div>\n </ClickAwayListener>\n )}\n </Transition>,\n document.body\n )}\n </>\n );\n});\n\nexport default TimePicker;\n"],"names":["defaultStyle","duration","transitionStyles","TimePicker","React","props","ref","valueProp","onChangeProp","placement","disabled","disableClock","clockAriaLabel","format","onBlurProp","rest","value","useMemo","viewValue","setViewValue","useState","isValidTimeDate","isOpen","setIsOpen","anchorRef","useRef","clockRef","resolved","resolvePlacement","refs","floatingStyles","useFloating","autoUpdate","buildFloatingMiddleware","anchorForkRef","useForkRef","clockForkRef","useSafeLayoutEffect","onToggle","useCallback","prevState","onClickAway","event","target","_a","_b","onTimeChange","next","onComplete","jsxs","Fragment","jsx","TimePickerInput","createPortal","Transition","state","ClickAwayListener","TimePickerColumns"],"mappings":"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"}
@@ -1,79 +1,89 @@
1
1
  import { jsx as n, jsxs as re } from "react/jsx-runtime";
2
2
  import '../../../assets/styles/less/components/sheet/sheet.entry.css';/* empty css */
3
- import T, { forwardRef as ne, useState as W, useRef as H, useEffect as oe, useCallback as w } from "react";
4
- import B from "clsx";
3
+ import K, { forwardRef as ne, useState as W, useRef as H, useEffect as oe, useCallback as w } from "react";
4
+ import L from "clsx";
5
5
  import { CSSTransition as j } from "react-transition-group";
6
6
  import { createPortal as se } from "react-dom";
7
7
  import { Button as C } from "../../inputs/button/button.js";
8
8
  import { Icon as $ } from "../../base/icon/icon.js";
9
- import { useForkRef as ie } from "../../../hooks/useForkRef.js";
10
- import { ClickAwayListener as ae } from "../../clickAwayListener/clickAwayListener.js";
11
- const ge = ne(function({
12
- isOpen: u,
13
- onClose: a,
9
+ import { useForkRef as ae } from "../../../hooks/useForkRef.js";
10
+ import { isTopOverlayLayer as ie } from "../../../utils/overlayLayer.js";
11
+ import { ClickAwayListener as le } from "../../clickAwayListener/clickAwayListener.js";
12
+ const ke = ne(function({
13
+ isOpen: m,
14
+ onClose: i,
14
15
  variant: d = "default",
15
16
  children: r,
16
- placement: _ = "bottom",
17
+ placement: k = "bottom",
17
18
  disableOutsideClick: p,
18
- closeOnEsc: v = !0,
19
- ...k
20
- }, A) {
21
- const [m, b] = W(null), D = H(null);
19
+ closeOnEsc: z = !0,
20
+ ...A
21
+ }, D) {
22
+ const [u, b] = W(null), y = H(null);
22
23
  oe(() => {
23
- if (!u || !v || !a)
24
+ if (!m || !z || !i)
24
25
  return;
25
- const o = (R) => {
26
- R.key === "Escape" && a();
26
+ const o = (v) => {
27
+ v.key === "Escape" && ie(y.current) && i();
27
28
  };
28
29
  return document.addEventListener("keydown", o), () => document.removeEventListener("keydown", o);
29
- }, [u, v, a]);
30
- const y = () => {
31
- b(m === "expanded" ? "small" : m ? null : "expanded");
32
- }, i = () => {
33
- a == null || a(), b(null);
30
+ }, [m, z, i]);
31
+ const g = () => {
32
+ b(u === "expanded" ? "small" : u ? null : "expanded");
33
+ }, a = () => {
34
+ i == null || i(), b(null);
34
35
  };
35
36
  return se(
36
37
  /* @__PURE__ */ n(
37
38
  j,
38
39
  {
39
- in: u,
40
+ in: m,
40
41
  timeout: 70,
41
42
  mountOnEnter: !0,
42
43
  unmountOnExit: !0,
43
44
  classNames: { enterDone: "smwb-entered" },
44
45
  appear: !0,
45
- nodeRef: D,
46
- children: d === "default" ? /* @__PURE__ */ n("div", { className: B(p ? "smwb-sheet__overlay" : "smwb-sheet__default"), ref: D, children: /* @__PURE__ */ n(
47
- U,
46
+ nodeRef: y,
47
+ children: d === "default" ? /* @__PURE__ */ n(
48
+ "div",
48
49
  {
49
- ref: A,
50
- onClose: a,
51
- handleSizeButton: y,
52
- handleClose: i,
53
- isOpen: u,
54
- mode: m,
55
- placement: _,
56
- variant: d,
57
- ...k,
58
- children: r
50
+ className: L(p ? "smwb-sheet__overlay" : "smwb-sheet__default"),
51
+ ref: y,
52
+ "data-smwb-overlay-layer": "",
53
+ children: /* @__PURE__ */ n(
54
+ U,
55
+ {
56
+ ref: D,
57
+ onClose: i,
58
+ handleSizeButton: g,
59
+ handleClose: a,
60
+ isOpen: m,
61
+ mode: u,
62
+ placement: k,
63
+ variant: d,
64
+ ...A,
65
+ children: r
66
+ }
67
+ )
59
68
  }
60
- ) }) : /* @__PURE__ */ n(
69
+ ) : /* @__PURE__ */ n(
61
70
  "div",
62
71
  {
63
- className: B("smwb-sheet__overlay", "smwb-dark", `smwb-${_}`, `smwb-sheet_${d}`),
64
- ref: D,
65
- children: /* @__PURE__ */ n(ae, { onClickAway: () => !p && i(), children: /* @__PURE__ */ n(
72
+ className: L("smwb-sheet__overlay", "smwb-dark", `smwb-${k}`, `smwb-sheet_${d}`),
73
+ ref: y,
74
+ "data-smwb-overlay-layer": "",
75
+ children: /* @__PURE__ */ n(le, { onClickAway: () => !p && a(), children: /* @__PURE__ */ n(
66
76
  U,
67
77
  {
68
- ref: A,
69
- onClose: a,
70
- handleSizeButton: y,
71
- handleClose: i,
72
- isOpen: u,
73
- mode: m,
74
- placement: _,
78
+ ref: D,
79
+ onClose: i,
80
+ handleSizeButton: g,
81
+ handleClose: a,
82
+ isOpen: m,
83
+ mode: u,
84
+ placement: k,
75
85
  variant: d,
76
- ...k,
86
+ ...A,
77
87
  children: r
78
88
  }
79
89
  ) })
@@ -83,22 +93,22 @@ const ge = ne(function({
83
93
  ),
84
94
  document.body
85
95
  );
86
- }), le = (z) => z === "bottom" || z === "top", U = T.forwardRef(function(u, a) {
96
+ }), ce = (x) => x === "bottom" || x === "top", U = K.forwardRef(function(m, i) {
87
97
  const {
88
98
  isOpen: d,
89
99
  placement: r,
90
- className: _,
100
+ className: k,
91
101
  mode: p,
92
- size: v = "60%",
93
- variant: k,
94
- onClose: A,
95
- withSizeToggle: m = !0,
102
+ size: z = "60%",
103
+ variant: A,
104
+ onClose: D,
105
+ withSizeToggle: u = !0,
96
106
  hideHeaderActions: b = !1,
97
- reverseHeaderActions: D = !1,
98
- resizable: y = !1,
99
- minSize: i = 80,
107
+ reverseHeaderActions: y = !1,
108
+ resizable: g = !1,
109
+ minSize: a = 80,
100
110
  maxSize: o,
101
- resizeStep: R = 24,
111
+ resizeStep: v = 24,
102
112
  resizeHandleAriaLabel: X = "Resize sheet",
103
113
  onResize: N,
104
114
  style: Y,
@@ -106,26 +116,26 @@ const ge = ne(function({
106
116
  handleSizeButton: V,
107
117
  children: q,
108
118
  ...G
109
- } = u, J = !b && (!!A || m), P = [];
110
- m && P.push(
119
+ } = m, J = !b && (!!D || u), P = [];
120
+ u && P.push(
111
121
  /* @__PURE__ */ n(C, { variant: "outlined", size: "small", onClick: V, children: /* @__PURE__ */ n($, { name: "open_in_full" }) }, "size")
112
- ), A && P.push(
122
+ ), D && P.push(
113
123
  /* @__PURE__ */ n(C, { variant: "outlined", size: "small", onClick: F, children: /* @__PURE__ */ n($, { name: "close" }) }, "close")
114
- ), D && P.reverse();
115
- const I = H(null), S = H(null), Q = ie(a, I, S), [l, L] = W(null), s = le(r), M = w(
124
+ ), y && P.reverse();
125
+ const B = H(null), S = H(null), Q = ae(i, B, S), [l, I] = W(null), s = ce(r), M = w(
116
126
  (e) => {
117
127
  const t = s ? window.innerHeight : window.innerWidth, c = o != null ? o : t;
118
- return Math.max(i, Math.min(c, e));
128
+ return Math.max(a, Math.min(c, e));
119
129
  },
120
- [s, o, i]
121
- ), x = w(() => {
130
+ [s, o, a]
131
+ ), R = w(() => {
122
132
  var t;
123
133
  const e = (t = S.current) == null ? void 0 : t.getBoundingClientRect();
124
- return e ? s ? e.height : e.width : i;
125
- }, [s, i]), h = w(
134
+ return e ? s ? e.height : e.width : a;
135
+ }, [s, a]), h = w(
126
136
  (e) => {
127
137
  const t = M(e);
128
- L(t), N == null || N(t);
138
+ I(t), N == null || N(t);
129
139
  },
130
140
  [M, N]
131
141
  ), E = H(null), Z = w(
@@ -133,59 +143,59 @@ const ge = ne(function({
133
143
  var t, c;
134
144
  e.preventDefault(), E.current = {
135
145
  start: s ? e.clientY : e.clientX,
136
- size: x()
146
+ size: R()
137
147
  };
138
148
  try {
139
149
  (c = (t = e.currentTarget).setPointerCapture) == null || c.call(t, e.pointerId);
140
150
  } catch {
141
151
  }
142
152
  },
143
- [s, x]
153
+ [s, R]
144
154
  ), O = w(
145
155
  (e) => {
146
156
  const t = E.current;
147
157
  if (!t)
148
158
  return;
149
- const f = (s ? e.clientY : e.clientX) - t.start, g = r === "bottom" || r === "right" ? -f : f;
150
- h(t.size + g);
159
+ const f = (s ? e.clientY : e.clientX) - t.start, _ = r === "bottom" || r === "right" ? -f : f;
160
+ h(t.size + _);
151
161
  },
152
162
  [s, r, h]
153
- ), K = w((e) => {
154
- var t, c, f, g;
155
- 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));
163
+ ), T = w((e) => {
164
+ var t, c, f, _;
165
+ E.current = null, (c = (t = e.currentTarget).hasPointerCapture) != null && c.call(t, e.pointerId) && ((_ = (f = e.currentTarget).releasePointerCapture) == null || _.call(f, e.pointerId));
156
166
  }, []), ee = w(
157
167
  (e) => {
158
- 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";
159
- 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));
168
+ 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";
169
+ 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));
160
170
  },
161
- [l, x, s, r, h, R, i, o]
171
+ [l, R, s, r, h, v, a, o]
162
172
  );
163
- T.useEffect(() => {
173
+ K.useEffect(() => {
164
174
  var e;
165
175
  if (!d) {
166
- L(null);
176
+ I(null);
167
177
  return;
168
178
  }
169
179
  (e = S.current) == null || e.focus();
170
180
  }, [d]);
171
- const te = y && l !== null ? { ...s ? { height: l } : { width: l }, transition: "none" } : {};
172
- return /* @__PURE__ */ n(j, { in: d, timeout: 120, appear: !0, classNames: { enterDone: "smwb-sheet_entered" }, nodeRef: I, children: /* @__PURE__ */ re(
181
+ const te = g && l !== null ? { ...s ? { height: l } : { width: l }, transition: "none" } : {};
182
+ return /* @__PURE__ */ n(j, { in: d, timeout: 120, appear: !0, classNames: { enterDone: "smwb-sheet_entered" }, nodeRef: B, children: /* @__PURE__ */ re(
173
183
  "div",
174
184
  {
175
185
  ref: Q,
176
186
  "data-testid": "sheet",
177
187
  tabIndex: -1,
178
188
  role: "dialog",
179
- "aria-modal": k === "modal" || void 0,
189
+ "aria-modal": A === "modal" || void 0,
180
190
  ...G,
181
- className: B("smwb-sheet", _, `smwb-sheet_${k}`, `smwb-${r}`, {
191
+ className: L("smwb-sheet", k, `smwb-sheet_${A}`, `smwb-${r}`, {
182
192
  "smwb-expanded": p === "expanded",
183
193
  "smwb-small": p === "small",
184
- "smwb-sheet_resizable": y
194
+ "smwb-sheet_resizable": g
185
195
  }),
186
- style: { "--sizeProp": v, ...te, ...Y },
196
+ style: { "--sizeProp": z, ...te, ...Y },
187
197
  children: [
188
- y && /* @__PURE__ */ n(
198
+ g && /* @__PURE__ */ n(
189
199
  "div",
190
200
  {
191
201
  className: "smwb-sheet__drag-handle",
@@ -194,13 +204,13 @@ const ge = ne(function({
194
204
  tabIndex: 0,
195
205
  "aria-orientation": s ? "horizontal" : "vertical",
196
206
  "aria-label": X,
197
- "aria-valuemin": i,
207
+ "aria-valuemin": a,
198
208
  "aria-valuemax": Math.round(o != null ? o : s ? window.innerHeight : window.innerWidth),
199
- "aria-valuenow": Math.round(l != null ? l : x()),
209
+ "aria-valuenow": Math.round(l != null ? l : R()),
200
210
  onPointerDown: Z,
201
211
  onPointerMove: O,
202
- onPointerUp: K,
203
- onPointerCancel: K,
212
+ onPointerUp: T,
213
+ onPointerCancel: T,
204
214
  onKeyDown: ee,
205
215
  children: /* @__PURE__ */ n("span", { className: "smwb-sheet__drag-handle-bar" })
206
216
  }
@@ -212,7 +222,7 @@ const ge = ne(function({
212
222
  ) });
213
223
  });
214
224
  export {
215
- ge as Sheet,
216
- ge as default
225
+ ke as Sheet,
226
+ ke as default
217
227
  };
218
228
  //# 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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"}
@@ -7,7 +7,7 @@ export type MenuSubmenuProps = Pick<MenuFloatingProps, "placement" | "onClose">
7
7
  /** Open the submenu on pointer hover in addition to click. */
8
8
  openOnHover?: boolean;
9
9
  };
10
- export declare const MenuSubmenu: React.ForwardRefExoticComponent<Pick<MenuFloatingProps, "onClose" | "placement"> & React.HTMLAttributes<HTMLDivElement> & {
10
+ export declare const MenuSubmenu: React.ForwardRefExoticComponent<Pick<MenuFloatingProps, "placement" | "onClose"> & React.HTMLAttributes<HTMLDivElement> & {
11
11
  toggleElement?: React.ReactElement;
12
12
  /** Items and/or nested `MenuSubmenu` elements (multi-level supported). */
13
13
  children: React.ReactNode;
@@ -1,30 +1,31 @@
1
- import { jsx as g, Fragment as k } from "react/jsx-runtime";
2
- import P, { useRef as a, useEffect as p } from "react";
3
- import { useForkRef as y } from "../../hooks/useForkRef.js";
1
+ import { jsx as T, Fragment as k } from "react/jsx-runtime";
2
+ import y, { useRef as a, useEffect as p } from "react";
3
+ import { useForkRef as P } from "../../hooks/useForkRef.js";
4
4
  import { useEventCallback as C } from "../../hooks/useEventCallback.js";
5
+ import { isEventInForeignOverlay as M } from "../../utils/overlayLayer.js";
5
6
  function E(t) {
6
7
  return t.substring(2).toLowerCase();
7
8
  }
8
- function M(t, s) {
9
- return s.documentElement.clientWidth < t.clientX || s.documentElement.clientHeight < t.clientY;
9
+ function b(t, u) {
10
+ return u.documentElement.clientWidth < t.clientX || u.documentElement.clientHeight < t.clientY;
10
11
  }
11
12
  function A({
12
13
  children: t,
13
- disableReactTree: s = !1,
14
+ disableReactTree: u = !1,
14
15
  mouseEvent: n = "onMouseUp",
15
16
  onClickAway: L,
16
17
  touchEvent: r = "onTouchEnd",
17
18
  enabled: v = !0
18
19
  }) {
19
- const f = a(!1), u = a(null), l = a(!1), d = a(!1);
20
+ const f = a(!1), s = a(null), l = a(!1), d = a(!1);
20
21
  p(() => (setTimeout(() => {
21
22
  l.current = !0;
22
23
  }, 0), () => {
23
24
  l.current = !1;
24
25
  }), []);
25
- const T = y(t.ref, u), o = C((e) => {
26
+ const g = P(t.ref, s), o = C((e) => {
26
27
  const c = d.current;
27
- if (d.current = !1, !v || !l.current || !u.current || "clientX" in e && M(e, document))
28
+ if (d.current = !1, !v || !l.current || !s.current || "clientX" in e && b(e, document))
28
29
  return;
29
30
  if (f.current) {
30
31
  f.current = !1;
@@ -32,17 +33,21 @@ function A({
32
33
  }
33
34
  let i;
34
35
  if (e.composedPath)
35
- i = e.composedPath().indexOf(u.current) > -1;
36
+ i = e.composedPath().indexOf(s.current) > -1;
36
37
  else {
37
38
  const R = e.target;
38
- i = !document.documentElement.contains(R) || u.current.contains(R);
39
+ i = !document.documentElement.contains(R) || s.current.contains(R);
40
+ }
41
+ if (!i && (u || !c)) {
42
+ if (M(e, s.current))
43
+ return;
44
+ L(e);
39
45
  }
40
- !i && (s || !c) && L(e);
41
46
  }), h = (e) => (c) => {
42
47
  d.current = !0;
43
48
  const i = t.props[e];
44
49
  i && i(c);
45
- }, m = { ref: T };
50
+ }, m = { ref: g };
46
51
  return r !== !1 && (m[r] = h(r)), p(() => {
47
52
  if (r !== !1) {
48
53
  const e = E(r), c = () => {
@@ -59,7 +64,7 @@ function A({
59
64
  document.removeEventListener(e, o);
60
65
  };
61
66
  }
62
- }, [o, n]), /* @__PURE__ */ g(k, { children: P.cloneElement(t, m) });
67
+ }, [o, n]), /* @__PURE__ */ T(k, { children: y.cloneElement(t, m) });
63
68
  }
64
69
  export {
65
70
  A as ClickAwayListener
@@ -1 +1 @@
1
- {"version":3,"file":"clickAwayListener.js","sources":["../../../../src/components/clickAwayListener/clickAwayListener.tsx"],"sourcesContent":["import React, { useEffect, useRef } from \"react\";\nimport { useForkRef } from \"../../hooks/useForkRef\";\nimport { useEventCallback } from \"../../hooks/useEventCallback\";\n\ntype ClickAwayMouseEventHandler = \"onClick\" | \"onMouseDown\" | \"onMouseUp\" | \"onPointerDown\" | \"onPointerUp\";\ntype ClickAwayTouchEventHandler = \"onTouchStart\" | \"onTouchEnd\";\n\nfunction mapEventPropToEvent(eventProp: ClickAwayMouseEventHandler | ClickAwayTouchEventHandler) {\n return eventProp.substring(2).toLowerCase() as\n | \"click\"\n | \"mousedown\"\n | \"mouseup\"\n | \"touchstart\"\n | \"touchend\"\n | \"pointerdown\"\n | \"pointerup\";\n}\n\nfunction clickedRootScrollbar(event: MouseEvent, doc: Document) {\n return doc.documentElement.clientWidth < event.clientX || doc.documentElement.clientHeight < event.clientY;\n}\n\nexport interface ClickAwayListenerProps {\n children: React.ReactElement;\n disableReactTree?: boolean;\n mouseEvent?: ClickAwayMouseEventHandler | false;\n onClickAway: (event: MouseEvent | TouchEvent) => void;\n touchEvent?: ClickAwayTouchEventHandler | false;\n /** When false, the listener is inert without unmounting the child. */\n enabled?: boolean;\n}\n\nexport function ClickAwayListener({\n children,\n disableReactTree = false,\n mouseEvent = \"onMouseUp\",\n onClickAway,\n touchEvent = \"onTouchEnd\",\n enabled = true,\n}: ClickAwayListenerProps) {\n const movedRef = useRef(false);\n const nodeRef = useRef<Element>(null);\n const activatedRef = useRef(false);\n const syntheticEventRef = useRef(false);\n\n useEffect(() => {\n // https://github.com/facebook/react/issues/20074\n setTimeout(() => {\n activatedRef.current = true;\n }, 0);\n return () => {\n activatedRef.current = false;\n };\n }, []);\n\n const handleRef = useForkRef((children as React.ReactElement & { ref: React.Ref<Element> }).ref, nodeRef);\n\n const handleClickAway = useEventCallback((event: MouseEvent | TouchEvent) => {\n const insideReactTree = syntheticEventRef.current;\n syntheticEventRef.current = false;\n\n if (\n !enabled ||\n !activatedRef.current ||\n !nodeRef.current ||\n (\"clientX\" in event && clickedRootScrollbar(event, document))\n ) {\n return;\n }\n\n if (movedRef.current) {\n movedRef.current = false;\n return;\n }\n\n let insideDOM;\n\n if (event.composedPath) {\n insideDOM = event.composedPath().indexOf(nodeRef.current) > -1;\n } else {\n const target = event.target as HTMLElement;\n\n insideDOM = !document.documentElement.contains(target) || nodeRef.current.contains(target);\n }\n\n if (!insideDOM && (disableReactTree || !insideReactTree)) {\n onClickAway(event);\n }\n });\n\n const createHandleSynthetic = (handlerName: string) => (event: React.SyntheticEvent) => {\n syntheticEventRef.current = true;\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const childrenPropsHandler = children.props[handlerName];\n\n if (childrenPropsHandler) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n childrenPropsHandler(event);\n }\n };\n\n const childrenProps: { ref: React.Ref<Element> } & Pick<\n React.DOMAttributes<Element>,\n ClickAwayMouseEventHandler | ClickAwayTouchEventHandler\n > = { ref: handleRef };\n\n if (touchEvent !== false) {\n childrenProps[touchEvent] = createHandleSynthetic(touchEvent);\n }\n\n useEffect(() => {\n if (touchEvent !== false) {\n const mappedTouchEvent = mapEventPropToEvent(touchEvent);\n\n const handleTouchMove = () => {\n movedRef.current = true;\n };\n\n document.addEventListener(mappedTouchEvent, handleClickAway);\n document.addEventListener(\"touchmove\", handleTouchMove);\n\n return () => {\n document.removeEventListener(mappedTouchEvent, handleClickAway);\n document.removeEventListener(\"touchmove\", handleTouchMove);\n };\n }\n\n return undefined;\n }, [handleClickAway, touchEvent]);\n\n if (mouseEvent !== false) {\n childrenProps[mouseEvent] = createHandleSynthetic(mouseEvent);\n }\n\n useEffect(() => {\n if (mouseEvent !== false) {\n const mappedMouseEvent = mapEventPropToEvent(mouseEvent);\n\n document.addEventListener(mappedMouseEvent, handleClickAway);\n\n return () => {\n document.removeEventListener(mappedMouseEvent, handleClickAway);\n };\n }\n\n return undefined;\n }, [handleClickAway, mouseEvent]);\n\n return <>{React.cloneElement(children, childrenProps)}</>;\n}\n"],"names":["mapEventPropToEvent","eventProp","clickedRootScrollbar","event","doc","ClickAwayListener","children","disableReactTree","mouseEvent","onClickAway","touchEvent","enabled","movedRef","useRef","nodeRef","activatedRef","syntheticEventRef","useEffect","handleRef","useForkRef","handleClickAway","useEventCallback","insideReactTree","insideDOM","target","createHandleSynthetic","handlerName","childrenPropsHandler","childrenProps","mappedTouchEvent","handleTouchMove","mappedMouseEvent","jsx","Fragment","React"],"mappings":";;;;AAOA,SAASA,EAAoBC,GAAoE;AAC/F,SAAOA,EAAU,UAAU,CAAC,EAAE,YAAA;AAQhC;AAEA,SAASC,EAAqBC,GAAmBC,GAAe;AAC9D,SAAOA,EAAI,gBAAgB,cAAcD,EAAM,WAAWC,EAAI,gBAAgB,eAAeD,EAAM;AACrG;AAYO,SAASE,EAAkB;AAAA,EAChC,UAAAC;AAAA,EACA,kBAAAC,IAAmB;AAAA,EACnB,YAAAC,IAAa;AAAA,EACb,aAAAC;AAAA,EACA,YAAAC,IAAa;AAAA,EACb,SAAAC,IAAU;AACZ,GAA2B;AACzB,QAAMC,IAAWC,EAAO,EAAK,GACvBC,IAAUD,EAAgB,IAAI,GAC9BE,IAAeF,EAAO,EAAK,GAC3BG,IAAoBH,EAAO,EAAK;AAEtC,EAAAI,EAAU,OAER,WAAW,MAAM;AACf,IAAAF,EAAa,UAAU;AAAA,EACzB,GAAG,CAAC,GACG,MAAM;AACX,IAAAA,EAAa,UAAU;AAAA,EACzB,IACC,CAAA,CAAE;AAEL,QAAMG,IAAYC,EAAYb,EAA8D,KAAKQ,CAAO,GAElGM,IAAkBC,EAAiB,CAAClB,MAAmC;AAC3E,UAAMmB,IAAkBN,EAAkB;AAG1C,QAFAA,EAAkB,UAAU,IAG1B,CAACL,KACD,CAACI,EAAa,WACd,CAACD,EAAQ,WACR,aAAaX,KAASD,EAAqBC,GAAO,QAAQ;AAE3D;AAGF,QAAIS,EAAS,SAAS;AACpB,MAAAA,EAAS,UAAU;AACnB;AAAA,IACF;AAEA,QAAIW;AAEJ,QAAIpB,EAAM;AACR,MAAAoB,IAAYpB,EAAM,aAAA,EAAe,QAAQW,EAAQ,OAAO,IAAI;AAAA,SACvD;AACL,YAAMU,IAASrB,EAAM;AAErB,MAAAoB,IAAY,CAAC,SAAS,gBAAgB,SAASC,CAAM,KAAKV,EAAQ,QAAQ,SAASU,CAAM;AAAA,IAC3F;AAEA,IAAI,CAACD,MAAchB,KAAoB,CAACe,MACtCb,EAAYN,CAAK;AAAA,EAErB,CAAC,GAEKsB,IAAwB,CAACC,MAAwB,CAACvB,MAAgC;AACtF,IAAAa,EAAkB,UAAU;AAG5B,UAAMW,IAAuBrB,EAAS,MAAMoB,CAAW;AAEvD,IAAIC,KAEFA,EAAqBxB,CAAK;AAAA,EAE9B,GAEMyB,IAGF,EAAE,KAAKV,EAAA;AAEX,SAAIR,MAAe,OACjBkB,EAAclB,CAAU,IAAIe,EAAsBf,CAAU,IAG9DO,EAAU,MAAM;AACd,QAAIP,MAAe,IAAO;AACxB,YAAMmB,IAAmB7B,EAAoBU,CAAU,GAEjDoB,IAAkB,MAAM;AAC5B,QAAAlB,EAAS,UAAU;AAAA,MACrB;AAEA,sBAAS,iBAAiBiB,GAAkBT,CAAe,GAC3D,SAAS,iBAAiB,aAAaU,CAAe,GAE/C,MAAM;AACX,iBAAS,oBAAoBD,GAAkBT,CAAe,GAC9D,SAAS,oBAAoB,aAAaU,CAAe;AAAA,MAC3D;AAAA,IACF;AAAA,EAGF,GAAG,CAACV,GAAiBV,CAAU,CAAC,GAE5BF,MAAe,OACjBoB,EAAcpB,CAAU,IAAIiB,EAAsBjB,CAAU,IAG9DS,EAAU,MAAM;AACd,QAAIT,MAAe,IAAO;AACxB,YAAMuB,IAAmB/B,EAAoBQ,CAAU;AAEvD,sBAAS,iBAAiBuB,GAAkBX,CAAe,GAEpD,MAAM;AACX,iBAAS,oBAAoBW,GAAkBX,CAAe;AAAA,MAChE;AAAA,IACF;AAAA,EAGF,GAAG,CAACA,GAAiBZ,CAAU,CAAC,GAEzB,gBAAAwB,EAAAC,GAAA,EAAG,UAAAC,EAAM,aAAa5B,GAAUsB,CAAa,GAAE;AACxD;"}
1
+ {"version":3,"file":"clickAwayListener.js","sources":["../../../../src/components/clickAwayListener/clickAwayListener.tsx"],"sourcesContent":["import React, { useEffect, useRef } from \"react\";\nimport { useForkRef } from \"../../hooks/useForkRef\";\nimport { useEventCallback } from \"../../hooks/useEventCallback\";\nimport { isEventInForeignOverlay } from \"../../utils/overlayLayer\";\n\ntype ClickAwayMouseEventHandler = \"onClick\" | \"onMouseDown\" | \"onMouseUp\" | \"onPointerDown\" | \"onPointerUp\";\ntype ClickAwayTouchEventHandler = \"onTouchStart\" | \"onTouchEnd\";\n\nfunction mapEventPropToEvent(eventProp: ClickAwayMouseEventHandler | ClickAwayTouchEventHandler) {\n return eventProp.substring(2).toLowerCase() as\n | \"click\"\n | \"mousedown\"\n | \"mouseup\"\n | \"touchstart\"\n | \"touchend\"\n | \"pointerdown\"\n | \"pointerup\";\n}\n\nfunction clickedRootScrollbar(event: MouseEvent, doc: Document) {\n return doc.documentElement.clientWidth < event.clientX || doc.documentElement.clientHeight < event.clientY;\n}\n\nexport interface ClickAwayListenerProps {\n children: React.ReactElement;\n disableReactTree?: boolean;\n mouseEvent?: ClickAwayMouseEventHandler | false;\n onClickAway: (event: MouseEvent | TouchEvent) => void;\n touchEvent?: ClickAwayTouchEventHandler | false;\n /** When false, the listener is inert without unmounting the child. */\n enabled?: boolean;\n}\n\nexport function ClickAwayListener({\n children,\n disableReactTree = false,\n mouseEvent = \"onMouseUp\",\n onClickAway,\n touchEvent = \"onTouchEnd\",\n enabled = true,\n}: ClickAwayListenerProps) {\n const movedRef = useRef(false);\n const nodeRef = useRef<Element>(null);\n const activatedRef = useRef(false);\n const syntheticEventRef = useRef(false);\n\n useEffect(() => {\n // https://github.com/facebook/react/issues/20074\n setTimeout(() => {\n activatedRef.current = true;\n }, 0);\n return () => {\n activatedRef.current = false;\n };\n }, []);\n\n const handleRef = useForkRef((children as React.ReactElement & { ref: React.Ref<Element> }).ref, nodeRef);\n\n const handleClickAway = useEventCallback((event: MouseEvent | TouchEvent) => {\n const insideReactTree = syntheticEventRef.current;\n syntheticEventRef.current = false;\n\n if (\n !enabled ||\n !activatedRef.current ||\n !nodeRef.current ||\n (\"clientX\" in event && clickedRootScrollbar(event, document))\n ) {\n return;\n }\n\n if (movedRef.current) {\n movedRef.current = false;\n return;\n }\n\n let insideDOM;\n\n if (event.composedPath) {\n insideDOM = event.composedPath().indexOf(nodeRef.current) > -1;\n } else {\n const target = event.target as HTMLElement;\n\n insideDOM = !document.documentElement.contains(target) || nodeRef.current.contains(target);\n }\n\n if (!insideDOM && (disableReactTree || !insideReactTree)) {\n // Interactions inside a portaled overlay layer above the child (modal,\n // dropdown, picker…) are not \"away\" from the child.\n if (isEventInForeignOverlay(event, nodeRef.current)) {\n return;\n }\n onClickAway(event);\n }\n });\n\n const createHandleSynthetic = (handlerName: string) => (event: React.SyntheticEvent) => {\n syntheticEventRef.current = true;\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n const childrenPropsHandler = children.props[handlerName];\n\n if (childrenPropsHandler) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n childrenPropsHandler(event);\n }\n };\n\n const childrenProps: { ref: React.Ref<Element> } & Pick<\n React.DOMAttributes<Element>,\n ClickAwayMouseEventHandler | ClickAwayTouchEventHandler\n > = { ref: handleRef };\n\n if (touchEvent !== false) {\n childrenProps[touchEvent] = createHandleSynthetic(touchEvent);\n }\n\n useEffect(() => {\n if (touchEvent !== false) {\n const mappedTouchEvent = mapEventPropToEvent(touchEvent);\n\n const handleTouchMove = () => {\n movedRef.current = true;\n };\n\n document.addEventListener(mappedTouchEvent, handleClickAway);\n document.addEventListener(\"touchmove\", handleTouchMove);\n\n return () => {\n document.removeEventListener(mappedTouchEvent, handleClickAway);\n document.removeEventListener(\"touchmove\", handleTouchMove);\n };\n }\n\n return undefined;\n }, [handleClickAway, touchEvent]);\n\n if (mouseEvent !== false) {\n childrenProps[mouseEvent] = createHandleSynthetic(mouseEvent);\n }\n\n useEffect(() => {\n if (mouseEvent !== false) {\n const mappedMouseEvent = mapEventPropToEvent(mouseEvent);\n\n document.addEventListener(mappedMouseEvent, handleClickAway);\n\n return () => {\n document.removeEventListener(mappedMouseEvent, handleClickAway);\n };\n }\n\n return undefined;\n }, [handleClickAway, mouseEvent]);\n\n return <>{React.cloneElement(children, childrenProps)}</>;\n}\n"],"names":["mapEventPropToEvent","eventProp","clickedRootScrollbar","event","doc","ClickAwayListener","children","disableReactTree","mouseEvent","onClickAway","touchEvent","enabled","movedRef","useRef","nodeRef","activatedRef","syntheticEventRef","useEffect","handleRef","useForkRef","handleClickAway","useEventCallback","insideReactTree","insideDOM","target","isEventInForeignOverlay","createHandleSynthetic","handlerName","childrenPropsHandler","childrenProps","mappedTouchEvent","handleTouchMove","mappedMouseEvent","jsx","Fragment","React"],"mappings":"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"}