@astryxdesign/core 0.7.7-canary.550ff21 → 0.7.7-canary.59d7d10

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 (107) hide show
  1. package/dist/DateInput/Wheel.d.ts +17 -1
  2. package/dist/DateInput/Wheel.d.ts.map +1 -1
  3. package/dist/DateInput/Wheel.js +179 -19
  4. package/dist/Drawer/useDrawerDialogPresence.d.ts.map +1 -1
  5. package/dist/Drawer/useDrawerDialogPresence.js +4 -0
  6. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  7. package/dist/DropdownMenu/DropdownMenu.js +20 -4
  8. package/dist/Layer/layerClickBoundary.d.ts +7 -1
  9. package/dist/Layer/layerClickBoundary.d.ts.map +1 -1
  10. package/dist/Layer/layerClickBoundary.js +2 -2
  11. package/dist/Layer/usePressPin.d.ts +95 -0
  12. package/dist/Layer/usePressPin.d.ts.map +1 -0
  13. package/dist/Layer/usePressPin.js +365 -0
  14. package/dist/Layer/useTouchTrigger.d.ts +23 -1
  15. package/dist/Layer/useTouchTrigger.d.ts.map +1 -1
  16. package/dist/Layer/useTouchTrigger.js +45 -7
  17. package/dist/Popover/usePopover.d.ts.map +1 -1
  18. package/dist/Popover/usePopover.js +56 -7
  19. package/dist/ProgressBar/ProgressBar.d.ts +1 -1
  20. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  21. package/dist/ProgressBar/ProgressBar.js +33 -6
  22. package/dist/Switch/Switch.d.ts +1 -1
  23. package/dist/Switch/Switch.d.ts.map +1 -1
  24. package/dist/Switch/Switch.js +200 -46
  25. package/dist/Switch/switchFill.d.ts +31 -0
  26. package/dist/Switch/switchFill.d.ts.map +1 -0
  27. package/dist/Switch/switchFill.js +88 -0
  28. package/dist/Switch/switchTouch.d.ts +81 -0
  29. package/dist/Switch/switchTouch.d.ts.map +1 -0
  30. package/dist/Switch/switchTouch.js +133 -0
  31. package/dist/Switch/useSwitchTouch.d.ts +285 -0
  32. package/dist/Switch/useSwitchTouch.d.ts.map +1 -0
  33. package/dist/Switch/useSwitchTouch.js +997 -0
  34. package/dist/Tooltip/Tooltip.d.ts +30 -6
  35. package/dist/Tooltip/Tooltip.d.ts.map +1 -1
  36. package/dist/Tooltip/Tooltip.js +5 -0
  37. package/dist/Tooltip/index.d.ts +1 -1
  38. package/dist/Tooltip/index.d.ts.map +1 -1
  39. package/dist/Tooltip/useTooltip.d.ts +31 -5
  40. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  41. package/dist/Tooltip/useTooltip.js +59 -18
  42. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  43. package/dist/Typeahead/Typeahead.js +26 -15
  44. package/dist/astryx.css +46 -2
  45. package/dist/gestures/GestureHost.d.ts.map +1 -1
  46. package/dist/gestures/GestureHost.js +4 -3
  47. package/dist/gestures/PressTracker.d.ts +6 -0
  48. package/dist/gestures/PressTracker.d.ts.map +1 -1
  49. package/dist/gestures/PressTracker.js +3 -0
  50. package/dist/gestures/types.d.ts +6 -0
  51. package/dist/gestures/types.d.ts.map +1 -1
  52. package/dist/gestures/usePressTracker.d.ts.map +1 -1
  53. package/dist/gestures/usePressTracker.js +1 -0
  54. package/dist/hooks/useFocusTrap.d.ts +15 -0
  55. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  56. package/dist/hooks/useFocusTrap.js +13 -2
  57. package/dist/motion/uikit/index.d.ts +6 -4
  58. package/dist/motion/uikit/index.d.ts.map +1 -1
  59. package/dist/motion/uikit/index.js +6 -4
  60. package/dist/motion/uikit/progressBar.d.ts +27 -7
  61. package/dist/motion/uikit/progressBar.d.ts.map +1 -1
  62. package/dist/motion/uikit/progressBar.js +31 -11
  63. package/dist/motion/uikit/springs.d.ts +13 -29
  64. package/dist/motion/uikit/springs.d.ts.map +1 -1
  65. package/dist/motion/uikit/springs.js +16 -30
  66. package/dist/motion/uikit/switch.d.ts +166 -0
  67. package/dist/motion/uikit/switch.d.ts.map +1 -0
  68. package/dist/motion/uikit/switch.js +186 -0
  69. package/dist/privateAttributes/pressHoldsDrag.stylex.d.ts +18 -0
  70. package/dist/privateAttributes/pressHoldsDrag.stylex.d.ts.map +1 -0
  71. package/dist/privateAttributes/pressHoldsDrag.stylex.js +28 -0
  72. package/dist/utils/pressFeedback.d.ts.map +1 -1
  73. package/dist/utils/pressFeedback.js +5 -0
  74. package/package.json +4 -4
  75. package/src/DateInput/Wheel.tsx +174 -14
  76. package/src/Drawer/useDrawerDialogPresence.ts +4 -0
  77. package/src/DropdownMenu/DropdownMenu.tsx +28 -6
  78. package/src/Layer/layerClickBoundary.ts +2 -2
  79. package/src/Layer/usePressPin.ts +516 -0
  80. package/src/Layer/useTouchTrigger.ts +56 -6
  81. package/src/Popover/usePopover.tsx +71 -9
  82. package/src/ProgressBar/ProgressBar.doc.mjs +4 -2
  83. package/src/ProgressBar/ProgressBar.tsx +67 -7
  84. package/src/Switch/Switch.doc.mjs +3 -3
  85. package/src/Switch/Switch.tsx +412 -86
  86. package/src/Switch/switchFill.ts +106 -0
  87. package/src/Switch/switchTouch.ts +194 -0
  88. package/src/Switch/useSwitchTouch.ts +1117 -0
  89. package/src/Tooltip/Tooltip.doc.mjs +21 -6
  90. package/src/Tooltip/Tooltip.tsx +42 -5
  91. package/src/Tooltip/index.ts +1 -0
  92. package/src/Tooltip/useTooltip.doc.mjs +4 -2
  93. package/src/Tooltip/useTooltip.tsx +84 -21
  94. package/src/Typeahead/Typeahead.tsx +29 -15
  95. package/src/gestures/GestureHost.ts +7 -3
  96. package/src/gestures/PressTracker.ts +10 -0
  97. package/src/gestures/types.ts +6 -0
  98. package/src/gestures/usePressTracker.ts +2 -0
  99. package/src/hooks/useFocusTrap.ts +26 -2
  100. package/src/motion/MEASUREMENTS.md +29 -27
  101. package/src/motion/README.md +2 -1
  102. package/src/motion/uikit/index.ts +5 -4
  103. package/src/motion/uikit/progressBar.ts +31 -11
  104. package/src/motion/uikit/springs.ts +16 -30
  105. package/src/motion/uikit/switch.ts +174 -0
  106. package/src/privateAttributes/pressHoldsDrag.stylex.ts +28 -0
  107. package/src/utils/pressFeedback.ts +5 -0
@@ -3,7 +3,10 @@ export interface WheelOption {
3
3
  value: number;
4
4
  /** Row text. */
5
5
  label: string;
6
- /** Rows outside min/max stay visible but cannot be committed. */
6
+ /**
7
+ * Rows outside min/max stay visible but cannot be committed: a wheel that
8
+ * stops on one travels on to the nearest enabled row.
9
+ */
7
10
  isDisabled?: boolean;
8
11
  }
9
12
  export interface WheelProps {
@@ -21,6 +24,19 @@ export interface WheelProps {
21
24
  */
22
25
  isActive?: boolean;
23
26
  }
27
+ /**
28
+ * The enabled row nearest `index`: `index` itself when it is enabled,
29
+ * otherwise the closest enabled row on either side. A tie goes to the side of
30
+ * `towardIndex` (the committed row), and a wheel with no enabled row stays on
31
+ * `towardIndex`.
32
+ *
33
+ * @example
34
+ * ```
35
+ * // Hours 0-23 with 09:00-17:00 bounds: stopping on 7 rests on 9.
36
+ * nearestEnabledIndex(hourOptions, 7, 10); // 9
37
+ * ```
38
+ */
39
+ export declare function nearestEnabledIndex(options: ReadonlyArray<WheelOption>, index: number, towardIndex: number): number;
24
40
  /**
25
41
  * One snap-scrolling picker column.
26
42
  *
@@ -1 +1 @@
1
- {"version":3,"file":"Wheel.d.ts","sourceRoot":"","sources":["../../src/DateInput/Wheel.tsx"],"names":[],"mappings":"AA8MA,MAAM,WAAW,WAAW;IAC1B,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,2BAA2B;IAC3B,OAAO,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IACpC,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,KAAK,CAAC,EACpB,KAAK,EACL,OAAO,EACP,KAAK,EACL,QAAQ,EACR,QAAe,GAChB,EAAE,UAAU,+BAmOZ;yBAzOe,KAAK"}
1
+ {"version":3,"file":"Wheel.d.ts","sourceRoot":"","sources":["../../src/DateInput/Wheel.tsx"],"names":[],"mappings":"AAoNA,MAAM,WAAW,WAAW;IAC1B,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB;IAChB,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,2BAA2B;IAC3B,OAAO,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IACpC,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,aAAa,CAAC,WAAW,CAAC,EACnC,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,GAClB,MAAM,CAsBR;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,KAAK,CAAC,EACpB,KAAK,EACL,OAAO,EACP,KAAK,EACL,QAAQ,EACR,QAAe,GAChB,EAAE,UAAU,+BAkVZ;yBAxVe,KAAK"}
@@ -21,6 +21,11 @@
21
21
  * browser that does not understand `animation-timeline` would otherwise run
22
22
  * the same keyframes on the document timeline and simply play them once.
23
23
  *
24
+ * Under Reduce Motion, the wheel's own scrolls (a step from a key or a click,
25
+ * the travel to the nearest enabled row) land without travel. They cross-fade
26
+ * on a touch screen and land at once otherwise. A finger's scroll and its
27
+ * momentum stay the platform's.
28
+ *
24
29
  * Accessibility: this is a listbox, not a novel widget. It is one tab stop
25
30
  * with arrow/Home/End/PageUp/PageDown keys, `aria-activedescendant` tracking
26
31
  * the active row, and every row reachable by tap — none of which depends on
@@ -37,6 +42,7 @@ import * as stylex from '@stylexjs/stylex';
37
42
  import "../theme/tokens.stylex.js";
38
43
  import { colorVars, radiusVars, fontWeightVars, typeScaleVars, spacingVars, durationVars } from "../theme/tokens.stylex.js";
39
44
  import { focusOutlineStyles } from "../utils/index.js";
45
+ import { reducedMotionFade } from "../motion/reducedMotion.js";
40
46
  import "./tokens.stylex.js";
41
47
  import { dateInputTouchSizes, dateInputTouchGeometry } from "./tokens.stylex.js";
42
48
  import { useOwnScrollGesture } from "./useOwnScrollGesture.js";
@@ -72,6 +78,41 @@ const styles = {
72
78
  $$css: true
73
79
  }
74
80
  };
81
+ /**
82
+ * The enabled row nearest `index`: `index` itself when it is enabled,
83
+ * otherwise the closest enabled row on either side. A tie goes to the side of
84
+ * `towardIndex` (the committed row), and a wheel with no enabled row stays on
85
+ * `towardIndex`.
86
+ *
87
+ * @example
88
+ * ```
89
+ * // Hours 0-23 with 09:00-17:00 bounds: stopping on 7 rests on 9.
90
+ * nearestEnabledIndex(hourOptions, 7, 10); // 9
91
+ * ```
92
+ */
93
+ export function nearestEnabledIndex(options, index, towardIndex) {
94
+ const isEnabled = i => i >= 0 && i < options.length && !options[i].isDisabled;
95
+ if (isEnabled(index)) {
96
+ return index;
97
+ }
98
+ for (let distance = 1; distance < options.length; distance++) {
99
+ const below = index - distance;
100
+ const above = index + distance;
101
+ const isBelowEnabled = isEnabled(below);
102
+ const isAboveEnabled = isEnabled(above);
103
+ if (isBelowEnabled && isAboveEnabled) {
104
+ return towardIndex < index ? below : above;
105
+ }
106
+ if (isBelowEnabled) {
107
+ return below;
108
+ }
109
+ if (isAboveEnabled) {
110
+ return above;
111
+ }
112
+ }
113
+ return towardIndex;
114
+ }
115
+
75
116
  /**
76
117
  * One snap-scrolling picker column.
77
118
  *
@@ -114,20 +155,110 @@ export function Wheel({
114
155
  const first = scrollerRef.current?.firstElementChild;
115
156
  return first instanceof HTMLElement && first.offsetHeight > 0 ? first.offsetHeight : 0;
116
157
  }, []);
117
- const scrollToIndex = useCallback((index, behavior) => {
158
+
159
+ // What last started a scroll of the wheel: a pointer's type, or 'wheel'
160
+ // for a mouse wheel or trackpad. Under Reduce Motion the release of a touch
161
+ // drag cross-fades on any primary pointer. A key step, a row tap or a
162
+ // trackpad's scroll cross-fades on a coarse primary pointer and lands at
163
+ // once on a fine one.
164
+ const lastPointerRef = useRef(null);
165
+
166
+ // A reduced-motion dip whose rows have not landed yet: its timer and the
167
+ // row it lands on. While one is pending the rows stay put for it, so they
168
+ // never move at full opacity, and a further step retargets it.
169
+ const pendingFadeRef = useRef(null);
170
+ // The running dip, so a step during its fade-in starts the next one where
171
+ // the column is.
172
+ const dipRef = useRef(null);
173
+ useEffect(() => () => {
174
+ if (pendingFadeRef.current != null) {
175
+ window.clearTimeout(pendingFadeRef.current.timer);
176
+ pendingFadeRef.current = null;
177
+ }
178
+ }, []);
179
+ const scrollToIndex = useCallback((index, behavior, {
180
+ touchRelease = false
181
+ } = {}) => {
118
182
  const scroller = scrollerRef.current;
119
183
  const size = itemBlockSize();
120
184
  if (scroller == null || size === 0) {
121
185
  return;
122
186
  }
123
- scroller.scrollTo({
124
- top: index * size,
125
- behavior
187
+ const top = index * size;
188
+ // Under Reduce Motion the wheel's own scroll lands without travel. It
189
+ // dips on a touch screen or for a touch drag's release. Otherwise it
190
+ // lands at once.
191
+ const fadeTiming = behavior === 'smooth' ? reducedMotionFade(scroller, {
192
+ touchRelease
193
+ }) : null;
194
+ const pending = pendingFadeRef.current;
195
+ if (fadeTiming == null) {
196
+ if (pending != null) {
197
+ window.clearTimeout(pending.timer);
198
+ pendingFadeRef.current = null;
199
+ }
200
+ scroller.scrollTo({
201
+ top,
202
+ behavior
203
+ });
204
+ return;
205
+ }
206
+ if (fadeTiming.duration === 0 || typeof scroller.animate !== 'function') {
207
+ if (pending != null) {
208
+ window.clearTimeout(pending.timer);
209
+ pendingFadeRef.current = null;
210
+ }
211
+ scroller.scrollTo({
212
+ top,
213
+ behavior: 'auto'
214
+ });
215
+ return;
216
+ }
217
+ if (pending != null) {
218
+ // The dip is still fading out: its rows land here instead.
219
+ pending.top = top;
220
+ return;
221
+ }
222
+ const {
223
+ duration,
224
+ easing
225
+ } = fadeTiming;
226
+ // A step during the last dip's fade-in starts the new dip at the
227
+ // column's current opacity, not at full opacity. A leaving element fades
228
+ // out from where it is.
229
+ const shown = Number.parseFloat(getComputedStyle(scroller).opacity);
230
+ dipRef.current?.cancel();
231
+ dipRef.current = scroller.animate([{
232
+ opacity: Number.isFinite(shown) ? shown : 1,
233
+ easing
234
+ }, {
235
+ opacity: 0,
236
+ easing
237
+ }, {
238
+ opacity: 1
239
+ }], {
240
+ duration,
241
+ easing: 'linear'
126
242
  });
243
+ const landing = {
244
+ top,
245
+ timer: 0
246
+ };
247
+ landing.timer = window.setTimeout(() => {
248
+ pendingFadeRef.current = null;
249
+ scroller.scrollTo({
250
+ top: landing.top,
251
+ behavior: 'auto'
252
+ });
253
+ }, duration / 2);
254
+ pendingFadeRef.current = landing;
127
255
  }, [itemBlockSize]);
128
256
 
129
- // Commit on rest. A disabled row is bounced back to the committed one
130
- // rather than silently keeping a value the wheel is not showing.
257
+ // Commit on rest. A wheel that stops on a disabled row travels on to the
258
+ // nearest enabled row, as UIDatePicker does. That second rest commits it.
259
+ // A rest on the committed row is not a stop to correct. The park after the
260
+ // sheet opens rests there with no touch. A committed value outside the
261
+ // bounds stays until a person moves the wheel.
131
262
  //
132
263
  // Declared here, above the park effect, because that effect consults the
133
264
  // `isAtRestRef` this returns before it repositions anything.
@@ -139,18 +270,24 @@ export function Wheel({
139
270
  return;
140
271
  }
141
272
  const index = Math.min(options.length - 1, Math.max(0, Math.round(scroller.scrollTop / size)));
142
- const option = options[index];
143
- if (option == null || option.isDisabled) {
144
- scrollToIndex(selectedIndex, 'smooth');
273
+ const restIndex = index === selectedIndex ? index : nearestEnabledIndex(options, index, selectedIndex);
274
+ if (restIndex !== index) {
275
+ scrollToIndex(restIndex, 'smooth', {
276
+ touchRelease: lastPointerRef.current === 'touch'
277
+ });
145
278
  return;
146
279
  }
147
- if (option.value !== value) {
280
+ const option = options[index];
281
+ if (option != null && !option.isDisabled && option.value !== value) {
148
282
  onChange(option.value);
149
283
  }
150
284
  }, isActive, isDraggingRef);
151
285
 
152
- // Park the committed row under the band whenever the wheel is shown, or the
153
- // value is changed from outside (the calendar scrolled to another month).
286
+ // Park the committed row under the band at once whenever the wheel is
287
+ // shown. A value that changes from outside while the wheel is shown turns
288
+ // the wheel onto its row instead. UIDatePicker turns onto its maximum the
289
+ // same way, and never jumps there. For example, a bound clamps the time
290
+ // after another wheel turned, or the calendar moved to another month.
154
291
  //
155
292
  // NEVER while the wheel is still moving. A scroller that is mid-gesture or
156
293
  // still carrying momentum is the user's, and repositioning it does not stop
@@ -158,8 +295,15 @@ export function Wheel({
158
295
  // as a new settle, commits the next row along, and parks again. See
159
296
  // useScrollSettle. The settle handler re-checks the position afterwards, so
160
297
  // a correction that is genuinely needed still happens, just at rest.
298
+ const parkedRef = useRef(false);
161
299
  useEffect(() => {
162
- if (!isActive || !isAtRestRef.current) {
300
+ if (!isActive) {
301
+ parkedRef.current = false;
302
+ return;
303
+ }
304
+ // Nor while a reduced-motion dip is still to land its rows: they land
305
+ // under it, on this row.
306
+ if (!isAtRestRef.current || pendingFadeRef.current != null) {
163
307
  return;
164
308
  }
165
309
  const size = itemBlockSize();
@@ -168,14 +312,19 @@ export function Wheel({
168
312
  return;
169
313
  }
170
314
  if (Math.round(scroller.scrollTop / size) !== selectedIndex) {
171
- scroller.scrollTo({
172
- top: selectedIndex * size,
173
- behavior: 'auto'
174
- });
315
+ if (parkedRef.current) {
316
+ scrollToIndex(selectedIndex, 'smooth');
317
+ } else {
318
+ scroller.scrollTo({
319
+ top: selectedIndex * size,
320
+ behavior: 'auto'
321
+ });
322
+ }
175
323
  }
324
+ parkedRef.current = true;
176
325
  // eslint-disable-next-line @eslint-react/set-state-in-effect -- the highlight follows a scroll position, which only exists after layout
177
326
  setActiveIndex(selectedIndex);
178
- }, [isActive, selectedIndex, itemBlockSize, isAtRestRef]);
327
+ }, [isActive, selectedIndex, itemBlockSize, isAtRestRef, scrollToIndex]);
179
328
 
180
329
  // Highlight follows the finger. rAF-throttled: a scroll can fire far more
181
330
  // often than the display refreshes, and this only feeds a repaint.
@@ -276,7 +425,18 @@ export function Wheel({
276
425
  "aria-label": label,
277
426
  "aria-activedescendant": `${id}-${options[activeIndex]?.value}`,
278
427
  tabIndex: 0,
279
- onKeyDown: handleKeyDown,
428
+ onKeyDown: handleKeyDown
429
+ // Read in the capture phase. usePointerDragScroll stops a primary
430
+ // mouse press from bubbling, so that it does not reach BottomSheet's
431
+ // drag. A bubbling handler would never see a mouse, and would keep the
432
+ // last touch.
433
+ ,
434
+ onPointerDownCapture: event => {
435
+ lastPointerRef.current = event.pointerType;
436
+ },
437
+ onWheel: () => {
438
+ lastPointerRef.current = 'wheel';
439
+ },
280
440
  ...stylex.props(styles.scroller, focusOutlineStyles.focusVisible),
281
441
  children: options.map((option, index) => /*#__PURE__*/_jsx("div", {
282
442
  id: `${id}-${option.value}`,
@@ -1 +1 @@
1
- {"version":3,"file":"useDrawerDialogPresence.d.ts","sourceRoot":"","sources":["../../src/Drawer/useDrawerDialogPresence.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAGL,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,cAAc,EACpB,MAAM,OAAO,CAAC;AAaf,KAAK,8BAA8B,GAAG;IACpC,SAAS,EAAE,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IAC/C,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;CAClD,CAAC;AAuDF;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,SAAS,EACT,MAAM,EACN,OAAO,EACP,aAAa,GACd,EAAE,8BAA8B,GAAG,IAAI,CAoEvC"}
1
+ {"version":3,"file":"useDrawerDialogPresence.d.ts","sourceRoot":"","sources":["../../src/Drawer/useDrawerDialogPresence.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAGL,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,cAAc,EACpB,MAAM,OAAO,CAAC;AAcf,KAAK,8BAA8B,GAAG;IACpC,SAAS,EAAE,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IAC/C,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;CAClD,CAAC;AA0DF;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,SAAS,EACT,MAAM,EACN,OAAO,EACP,aAAa,GACd,EAAE,8BAA8B,GAAG,IAAI,CAoEvC"}
@@ -25,6 +25,7 @@
25
25
  */
26
26
  import { useEffect, useRef } from 'react';
27
27
  import { flushSync } from 'react-dom';
28
+ import { notifyTopLayerEntry } from "../Layer/modalOutlet.js";
28
29
 
29
30
  /** Slack past the computed transition before the backstop gives up waiting. */
30
31
  const EXIT_BACKSTOP_BUFFER_MS = 50;
@@ -51,6 +52,9 @@ function showDrawerHost(dialog, isModal) {
51
52
  dialog.showModal();
52
53
  } else if (typeof dialog.showPopover === 'function') {
53
54
  dialog.showPopover();
55
+ // The drawer is now the newest top-layer entry: global hosts shown before
56
+ // it (the toast viewport) re-enter above it, as they do above a modal.
57
+ notifyTopLayerEntry();
54
58
  } else {
55
59
  // Reduced fallback for browsers below the Popover API support floor.
56
60
  dialog.show();
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownMenu.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/DropdownMenu.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DropdownMenu.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/DropdownMenu.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EAAE,EAOZ,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAIf,OAAO,EAAS,KAAK,WAAW,EAAC,MAAM,WAAW,CAAC;AAKnD,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,oBAAoB,CAAC;AA+B9D,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,kCAAkC,CAAC;AAS1C,OAAO,KAAK,EAAC,cAAc,EAAE,cAAc,EAAC,MAAM,mBAAmB,CAAC;AAStE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AA2L5C;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAChD,qBAAqB,EACnB,MAAM,GACN,SAAS,GACT,YAAY,GACZ,SAAS,GACT,aAAa,GACb,YAAY,GACZ,kBAAkB,GAClB,MAAM,GACN,QAAQ,GACR,KAAK,CACR;IACC;;;;;;OAMG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,6BAA6B;IAC7B,KAAK,EAAE,SAAS,CAAC;IACjB;;;;OAIG;IACH,KAAK,CAAC,EAAE,kBAAkB,EAAE,CAAC;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,SAAS,CAAC;IAChB,0EAA0E;IAC1E,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,oBAAoB,EAAE,CAAC;CAC/B;AAED,MAAM,MAAM,kBAAkB,GAC5B,oBAAoB,GAAG,uBAAuB,GAAG,mBAAmB,CAAC;AAMvE,MAAM,MAAM,uBAAuB,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;AAEnE,MAAM,MAAM,wBAAwB,GAAG,oBAAoB,CAAC;AAE5D;;;;;;GAMG;AACH,MAAM,WAAW,wBAAwB;IACvC,yEAAyE;IACzE,GAAG,EAAE,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC;IAC3C,yDAAyD;IACzD,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IACxD,cAAc,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAC/D,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,YAAY,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAChE,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAC9D,SAAS,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAC7D,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IACxD,eAAe,EAAE,MAAM,GAAG,QAAQ,CAAC;IACnC,eAAe,EAAE,OAAO,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,qBAAsB,SAAQ,SAAS;IAC/C;;;OAGG;IACH,MAAM,CAAC,EAAE,uBAAuB,CAAC;IACjC;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,wBAAwB,KAAK,SAAS,CAAC;IAC/D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;IAE3B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,qBAAsB,SAAQ,qBAAqB;IAC3D;;;;;OAKG;IACH,YAAY,CAAC,EAAE,wBAAwB,CAAC;IACxC,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,UAAU,yBAA0B,SAAQ,qBAAqB;IAC/D,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,MAAM,iBAAiB,GAC3B,qBAAqB,GAAG,yBAAyB,CAAC;AAqvCpD,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,qBA4CpD;yBA5Ce,YAAY"}
@@ -279,6 +279,15 @@ function holdInvokerThroughPress(control, popoverId) {
279
279
  doc.addEventListener('pointerup', onPressEnd, true);
280
280
  doc.addEventListener('pointercancel', onPressEnd, true);
281
281
  }
282
+
283
+ /**
284
+ * The name of a menu opened from a custom trigger: the caller's `aria-label`
285
+ * when it is a non-empty string, else the trigger's own accessible name. The
286
+ * popover and the bottom sheet both name the menu through this.
287
+ */
288
+ function resolveCustomTriggerMenuName(callerLabel, triggerName) {
289
+ return typeof callerLabel === 'string' && callerLabel.trim() !== '' ? callerLabel : triggerName;
290
+ }
282
291
  function DropdownMenuBottomSheet({
283
292
  button: buttonFromProps,
284
293
  renderTrigger,
@@ -340,10 +349,18 @@ function DropdownMenuBottomSheet({
340
349
  useEffect(() => {
341
350
  void preloadMenuBottomSheetActionList();
342
351
  }, []);
352
+ // The control's name is only readable from the DOM once it is rendered.
353
+ const [triggerName, setTriggerName] = useState(undefined);
354
+ useIsomorphicLayoutEffect(() => {
355
+ if (renderTrigger != null && isOpen) {
356
+ setTriggerName(readAccessibleName(buttonRef.current));
357
+ }
358
+ }, [renderTrigger, isOpen]);
359
+ const rootTitle = (renderTrigger != null ? resolveCustomTriggerMenuName(rest['aria-label'], triggerName) : undefined) ?? button.label;
343
360
  const currentSubmenu = submenuPath.at(-1);
344
361
  const currentItems = currentSubmenu?.items ?? items;
345
- const currentTitle = currentSubmenu?.label ?? button.label;
346
- const sheetLabel = typeof currentTitle === 'string' ? currentTitle : button.label;
362
+ const currentTitle = currentSubmenu?.label ?? rootTitle;
363
+ const sheetLabel = typeof currentTitle === 'string' ? currentTitle : rootTitle;
347
364
  const setOpen = useCallback(nextIsOpen => {
348
365
  if (!nextIsOpen) {
349
366
  setSubmenuPath([]);
@@ -734,8 +751,7 @@ function DropdownMenuPopover({
734
751
  // The design system's button names the menu by its label. A custom trigger
735
752
  // names it by reference (or the caller's `aria-label` does), so that name
736
753
  // is read off the control as the menu opens.
737
- const callerMenuLabel = rest['aria-label'];
738
- const menuLabel = renderTrigger != null ? typeof callerMenuLabel === 'string' && callerMenuLabel.trim() !== '' ? callerMenuLabel : triggerName : typeof button.label === 'string' ? button.label : undefined;
754
+ const menuLabel = renderTrigger != null ? resolveCustomTriggerMenuName(rest['aria-label'], triggerName) : typeof button.label === 'string' ? button.label : undefined;
739
755
  const popover = usePopover({
740
756
  onHide: handleLayerHide,
741
757
  onShow: handleLayerShow,
@@ -2,7 +2,7 @@
2
2
  * @file layerClickBoundary.ts
3
3
  * @input React pointer, mouse, touch and click events on a layer root
4
4
  * @output Exports layerClickBoundary, the props every layer content root
5
- * spreads, including the layer-root mark
5
+ * spreads, including the layer-root mark; also stopInReactTree
6
6
  * @position Internal to Layer; used by useLayer's renderers and the Dialog,
7
7
  * Drawer, Lightbox, MobileNav, BottomSheetPanel and ToastViewport roots.
8
8
  * Not exported from the package.
@@ -21,6 +21,12 @@ declare const BOUNDARY_EVENTS: readonly ["onClick", "onAuxClick", "onDoubleClick
21
21
  type BoundaryEvent = (typeof BOUNDARY_EVENTS)[number];
22
22
  type Handler = (event: SyntheticEvent) => void;
23
23
  export type LayerClickBoundaryProps = Record<BoundaryEvent, Handler> & Readonly<Record<`data-${string}`, string>>;
24
+ /**
25
+ * Stop a synthetic event at this element for the rest of the React tree only.
26
+ * React's dispatch asks `isPropagationStopped()` before each further
27
+ * listener; the native event is left alone.
28
+ */
29
+ export declare function stopInReactTree(event: SyntheticEvent): void;
24
30
  /**
25
31
  * The boundary props for a layer content root. Pass the root's own props
26
32
  * (its caller's rest props and its own handlers): for each boundary event, a
@@ -1 +1 @@
1
- {"version":3,"file":"layerClickBoundary.d.ts","sourceRoot":"","sources":["../../src/Layer/layerClickBoundary.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,OAAO,CAAC;AAG1C,uDAAuD;AACvD,QAAA,MAAM,eAAe,gWAsBX,CAAC;AAEX,KAAK,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AACtD,KAAK,OAAO,GAAG,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;AAE/C,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAC,aAAa,EAAE,OAAO,CAAC,GAClE,QAAQ,CAAC,MAAM,CAAC,QAAQ,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;AAa7C;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAM,GAC1C,uBAAuB,CAkBzB"}
1
+ {"version":3,"file":"layerClickBoundary.d.ts","sourceRoot":"","sources":["../../src/Layer/layerClickBoundary.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,OAAO,CAAC;AAG1C,uDAAuD;AACvD,QAAA,MAAM,eAAe,gWAsBX,CAAC;AAEX,KAAK,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AACtD,KAAK,OAAO,GAAG,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;AAE/C,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAC,aAAa,EAAE,OAAO,CAAC,GAClE,QAAQ,CAAC,MAAM,CAAC,QAAQ,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;AAI7C;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAE3D;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAM,GAC1C,uBAAuB,CAkBzB"}
@@ -6,7 +6,7 @@
6
6
  * @file layerClickBoundary.ts
7
7
  * @input React pointer, mouse, touch and click events on a layer root
8
8
  * @output Exports layerClickBoundary, the props every layer content root
9
- * spreads, including the layer-root mark
9
+ * spreads, including the layer-root mark; also stopInReactTree
10
10
  * @position Internal to Layer; used by useLayer's renderers and the Dialog,
11
11
  * Drawer, Lightbox, MobileNav, BottomSheetPanel and ToastViewport roots.
12
12
  * Not exported from the package.
@@ -30,7 +30,7 @@ const returnTrue = () => true;
30
30
  * React's dispatch asks `isPropagationStopped()` before each further
31
31
  * listener; the native event is left alone.
32
32
  */
33
- function stopInReactTree(event) {
33
+ export function stopInReactTree(event) {
34
34
  event.isPropagationStopped = returnTrue;
35
35
  }
36
36
 
@@ -0,0 +1,95 @@
1
+ /**
2
+ * @file usePressPin.ts
3
+ * @input A hover layer's trigger, open state, show and hide, and its
4
+ * `triggerBehavior` and `touchTrigger` options
5
+ * @output usePressPin, the press toggle that pins a hover layer open;
6
+ * isPressPinTrigger; stopPressPinClick; the LayerTriggerBehavior type
7
+ * @position Core-internal: one call per hover layer, useTooltip's. It owns
8
+ * the layer's touch trigger, so the host makes no second touch-trigger call.
9
+ *
10
+ * SYNC: When modified, update:
11
+ * - /packages/core/src/Tooltip/useTooltip.tsx
12
+ * - /packages/core/src/Layer/usePressPin.test.tsx
13
+ */
14
+ import { type MouseEvent as ReactMouseEvent, type RefObject } from 'react';
15
+ import { type LayerTouchTrigger, type UseTouchTriggerReturn } from './useTouchTrigger.js';
16
+ /**
17
+ * How the trigger opens the layer. `adaptive`, the default, previews it on
18
+ * hover and focus, and a tap opens it unless the trigger acts. While
19
+ * `touchTrigger` remains, it decides those taps. `hover` previews it on hover
20
+ * and focus, and no touch or pen tap opens it. `toggle` pins it on every
21
+ * press of a button trigger.
22
+ */
23
+ export type LayerTriggerBehavior = 'adaptive' | 'hover' | 'toggle';
24
+ /**
25
+ * The layer component's wrapper handler. It stops a press that pinned or
26
+ * closed the layer in the React tree only, after the trigger's own handlers.
27
+ * No clickable row, card, or container around the trigger then receives it,
28
+ * and document and window listeners still do. An anchored trigger has no
29
+ * wrapper, so a plain `onClick` element around it still receives the press.
30
+ */
31
+ export declare function stopPressPinClick(event: ReactMouseEvent): void;
32
+ /** Whether presses on this element can pin a layer: a button, by role. */
33
+ export declare function isPressPinTrigger(element: Element): boolean;
34
+ export interface UsePressPinOptions {
35
+ /** The layer's `triggerBehavior`. */
36
+ triggerBehavior: LayerTriggerBehavior;
37
+ /** Whether the layer's triggers are live at all. */
38
+ isEnabled: boolean;
39
+ /** The controlled open value, or `undefined` when uncontrolled. */
40
+ isOpen: boolean | undefined;
41
+ /** Whether the layer shows now. */
42
+ isLayerOpen: boolean;
43
+ /** The layer surface's element id. */
44
+ layerId: string;
45
+ /** The component its development warning names. */
46
+ component: string;
47
+ /** Shows the layer now, with no delay. */
48
+ show: () => void;
49
+ /** Hides the layer now. */
50
+ hide: () => void;
51
+ /** Reports a controlled layer's toggled value without changing it. */
52
+ report: (isOpen: boolean) => void;
53
+ /** The layer's `label`: a press that pins the layer says it once, in place of its text. */
54
+ label?: string;
55
+ /** The layer's `touchTrigger`, which decides taps only under `adaptive`. */
56
+ touchTrigger: LayerTouchTrigger;
57
+ /** The host's trigger element, which the touch trigger reads. */
58
+ triggerRef: RefObject<HTMLElement | null>;
59
+ }
60
+ export interface UsePressPinReturn {
61
+ /** Whether presses on this trigger pin the layer: toggle mode and a button. */
62
+ isToggleTrigger: (element: HTMLElement | null) => boolean;
63
+ /**
64
+ * Whether a press holds the layer open now: a pin on a wired trigger while
65
+ * the layer shows, or a controlled layer's open value. The host's hover and
66
+ * focus hides ask it.
67
+ */
68
+ isHeldOpen: () => boolean;
69
+ /** Wires the trigger element, or unwires it with `null`. */
70
+ attach: (element: HTMLElement | null) => void;
71
+ /** Drops the pin: Escape, or a hide that came from elsewhere. */
72
+ unpin: () => void;
73
+ /**
74
+ * While pinned, focus moving onto an element outside the trigger and the
75
+ * layer closes it. Returns whether the pin decided. The pin calls it for its
76
+ * trigger, and a host calls it for the layer's own content.
77
+ */
78
+ handleFocusLeave: (event: FocusEvent) => boolean;
79
+ /**
80
+ * Whether the layer shows pinned on a wired trigger. The host then announces
81
+ * its rendered text, unless the layer has a `label`.
82
+ */
83
+ isPinShown: boolean;
84
+ /** The layer's touch trigger (useTouchTriggerInternal), wired to the pin. */
85
+ touch: Pick<UseTouchTriggerReturn, 'isTouchPointerRef' | 'isTouchInteraction' | 'handlePointerEnter' | 'handlePointerDown' | 'clearTapOpen'>;
86
+ }
87
+ /**
88
+ * Pins a hover layer open on a press of a button trigger, under
89
+ * `triggerBehavior="toggle"`. The same press closes it, and so do Escape, a
90
+ * press or scroll outside, and focus that leaves the trigger and the layer.
91
+ * The press stops at the trigger. A trigger that is not a button gets a
92
+ * development warning and keeps tap-only opening.
93
+ */
94
+ export declare function usePressPin(options: UsePressPinOptions): UsePressPinReturn;
95
+ //# sourceMappingURL=usePressPin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePressPin.d.ts","sourceRoot":"","sources":["../../src/Layer/usePressPin.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAKL,KAAK,UAAU,IAAI,eAAe,EAClC,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAIf,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC3B,MAAM,mBAAmB,CAAC;AAE3B;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAC;AAKnE;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAI9D;AAED,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAM3D;AAED,MAAM,WAAW,kBAAkB;IACjC,qCAAqC;IACrC,eAAe,EAAE,oBAAoB,CAAC;IACtC,oDAAoD;IACpD,SAAS,EAAE,OAAO,CAAC;IACnB,mEAAmE;IACnE,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,mCAAmC;IACnC,WAAW,EAAE,OAAO,CAAC;IACrB,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,2BAA2B;IAC3B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,sEAAsE;IACtE,MAAM,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAClC,2FAA2F;IAC3F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,YAAY,EAAE,iBAAiB,CAAC;IAChC,iEAAiE;IACjE,UAAU,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,iBAAiB;IAChC,+EAA+E;IAC/E,eAAe,EAAE,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,KAAK,OAAO,CAAC;IAC1D;;;;OAIG;IACH,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,4DAA4D;IAC5D,MAAM,EAAE,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9C,iEAAiE;IACjE,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB;;;;OAIG;IACH,gBAAgB,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC;IACjD;;;OAGG;IACH,UAAU,EAAE,OAAO,CAAC;IACpB,6EAA6E;IAC7E,KAAK,EAAE,IAAI,CACT,qBAAqB,EACnB,mBAAmB,GACnB,oBAAoB,GACpB,oBAAoB,GACpB,mBAAmB,GACnB,cAAc,CACjB,CAAC;CACH;AAwBD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,iBAAiB,CAmW1E"}