@servicetitan/anvil2 3.0.8 → 3.0.9

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 (71) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/Combobox.js +1 -1
  3. package/dist/{DataTable-Dwhwvm6R.js → DataTable-FG0Kjx0d.js} +1163 -402
  4. package/dist/DataTable-FG0Kjx0d.js.map +1 -0
  5. package/dist/DataTable.css +301 -233
  6. package/dist/{Divider-CxtTyw8_.js → Divider-Dz27DFuE.js} +17 -17
  7. package/dist/{Divider-CxtTyw8_.js.map → Divider-Dz27DFuE.js.map} +1 -1
  8. package/dist/Divider.css +21 -24
  9. package/dist/Divider.js +1 -1
  10. package/dist/Dnd.js +2 -2
  11. package/dist/{DndHandleButton-CHTOYRlq.js → DndHandleButton-BW9xLWQm.js} +2 -4
  12. package/dist/DndHandleButton-BW9xLWQm.js.map +1 -0
  13. package/dist/DndSort.js +2 -2
  14. package/dist/{FilterBar-CXGsoWw5.js → FilterBar-B3c_VGDk.js} +2 -2
  15. package/dist/{FilterBar-CXGsoWw5.js.map → FilterBar-B3c_VGDk.js.map} +1 -1
  16. package/dist/FilterBar.js +1 -1
  17. package/dist/MultiSelectField.js +1 -1
  18. package/dist/{MultiSelectFieldSync-CIuy3aRD.js → MultiSelectFieldSync-CzHj9Qvy.js} +3 -3
  19. package/dist/{MultiSelectFieldSync-CIuy3aRD.js.map → MultiSelectFieldSync-CzHj9Qvy.js.map} +1 -1
  20. package/dist/MultiSelectMenu.js +1 -1
  21. package/dist/{MultiSelectMenuSync-Drz8SEk9.js → MultiSelectMenuSync-BGcrYjby.js} +3 -3
  22. package/dist/{MultiSelectMenuSync-Drz8SEk9.js.map → MultiSelectMenuSync-BGcrYjby.js.map} +1 -1
  23. package/dist/{RichTextEditor-CoPXdaWI.js → RichTextEditor-FSWAVmTe.js} +4 -4
  24. package/dist/{RichTextEditor-CoPXdaWI.js.map → RichTextEditor-FSWAVmTe.js.map} +1 -1
  25. package/dist/RichTextEditor.js +1 -1
  26. package/dist/{SavedFiltersButton-DzJijqHz.js → SavedFiltersButton-Cr829guv.js} +4 -4
  27. package/dist/{SavedFiltersButton-DzJijqHz.js.map → SavedFiltersButton-Cr829guv.js.map} +1 -1
  28. package/dist/SavedFiltersButton.js +1 -1
  29. package/dist/SelectField.js +1 -1
  30. package/dist/{SelectFieldSync-DlGiJ-Iy.js → SelectFieldSync-C65VFWGm.js} +3 -3
  31. package/dist/{SelectFieldSync-DlGiJ-Iy.js.map → SelectFieldSync-C65VFWGm.js.map} +1 -1
  32. package/dist/SelectMenu.js +1 -1
  33. package/dist/{SelectMenuSync-CAweNjRL.js → SelectMenuSync-CF49L12-.js} +3 -3
  34. package/dist/{SelectMenuSync-CAweNjRL.js.map → SelectMenuSync-CF49L12-.js.map} +1 -1
  35. package/dist/{SelectOptions-BGCap9fZ.js → SelectOptions-C7skDFj2.js} +2 -2
  36. package/dist/{SelectOptions-BGCap9fZ.js.map → SelectOptions-C7skDFj2.js.map} +1 -1
  37. package/dist/Table.js +1 -1
  38. package/dist/beta.js +8 -8
  39. package/dist/drag_indicator-BRHAPLSJ.js +6 -0
  40. package/dist/drag_indicator-BRHAPLSJ.js.map +1 -0
  41. package/dist/{filter-state-DyMDjdRS.js → filter-state-CE8t3-Q7.js} +7 -7
  42. package/dist/filter-state-CE8t3-Q7.js.map +1 -0
  43. package/dist/{index-CukEaIHB.js → index-CKdC7x1S.js} +2 -2
  44. package/dist/{index-CukEaIHB.js.map → index-CKdC7x1S.js.map} +1 -1
  45. package/dist/{index-fSKD4ey4.js → index-DN_iqxhF.js} +2 -2
  46. package/dist/{index-fSKD4ey4.js.map → index-DN_iqxhF.js.map} +1 -1
  47. package/dist/index.js +3 -3
  48. package/dist/src/beta/components/Table/DataTable/DataTable.d.ts +4 -25
  49. package/dist/src/beta/components/Table/DataTable/internal/DataTableBody.d.ts +2 -19
  50. package/dist/src/beta/components/Table/DataTable/internal/DataTableBodyRow.d.ts +12 -13
  51. package/dist/src/beta/components/Table/DataTable/internal/context/surface/DataTableSurfaceCoordinatorContext.d.ts +13 -0
  52. package/dist/src/beta/components/Table/DataTable/internal/context/surface/DataTableSurfaceCoordinatorProvider.d.ts +7 -0
  53. package/dist/src/beta/components/Table/DataTable/internal/context/surface/useDataTableSurfaceCoordinator.d.ts +1 -0
  54. package/dist/src/beta/components/Table/DataTable/internal/editable-cells/useCustomEditHelpers.d.ts +8 -6
  55. package/dist/src/beta/components/Table/createColumnHelper.d.ts +4 -2
  56. package/dist/src/beta/components/Table/formatters/htmlFormatter.d.ts +4 -2
  57. package/dist/src/beta/components/Table/formatters/htmlToMarkdown.d.ts +5 -2
  58. package/dist/src/beta/components/Table/formatters/markdownFormatter.d.ts +3 -2
  59. package/dist/src/beta/components/Table/types.d.ts +47 -30
  60. package/dist/src/internal/components/Surface/Surface.d.ts +4 -0
  61. package/dist/src/internal/components/Surface/surfaceGeometry.d.ts +31 -0
  62. package/dist/{syncFilterUtils-DZqeVWTS.js → syncFilterUtils-CgHB-l6A.js} +2 -2
  63. package/dist/{syncFilterUtils-DZqeVWTS.js.map → syncFilterUtils-CgHB-l6A.js.map} +1 -1
  64. package/dist/{useInfiniteCombobox-C6TDFfds.js → useInfiniteCombobox-BqJm-CdN.js} +2 -2
  65. package/dist/{useInfiniteCombobox-C6TDFfds.js.map → useInfiniteCombobox-BqJm-CdN.js.map} +1 -1
  66. package/dist/{useToggleSelection-Bn7h-gGD.js → useToggleSelection-BGc5OiZF.js} +2 -2
  67. package/dist/{useToggleSelection-Bn7h-gGD.js.map → useToggleSelection-BGc5OiZF.js.map} +1 -1
  68. package/package.json +1 -1
  69. package/dist/DataTable-Dwhwvm6R.js.map +0 -1
  70. package/dist/DndHandleButton-CHTOYRlq.js.map +0 -1
  71. package/dist/filter-state-DyMDjdRS.js.map +0 -1
@@ -2,7 +2,7 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { C as Chip } from './Chip-CyMNyEPR.js';
3
3
  import { F as Flex } from './Flex-_orhvoxS.js';
4
4
  import * as React from 'react';
5
- import { useId, useRef, useCallback, useMemo, createContext, forwardRef, useEffect, useContext, useState, useLayoutEffect, useImperativeHandle, memo as memo$1, Fragment as Fragment$1, isValidElement } from 'react';
5
+ import { useId, useRef, useCallback, useMemo, createContext, forwardRef, useState, useEffect, useContext, useLayoutEffect, useImperativeHandle, memo as memo$1, Fragment as Fragment$1, isValidElement } from 'react';
6
6
  import { c as cx } from './index-De1g9FRV.js';
7
7
  import { D as DateTime } from './luxon-wpz4A-OQ.js';
8
8
  import { C as Checkbox } from './Checkbox-BYWhkYoK.js';
@@ -13,11 +13,13 @@ import { I as Icon } from './Icon-feeG7gXA.js';
13
13
  import { S as SrOnly } from './SrOnly-pnf8ajnh.js';
14
14
  import { u as useNumberField } from './useNumberField-D_ic9i2q.js';
15
15
  import { u as useMergeRefs, m as mergeRefs } from './useMergeRefs-Dfmtq9cI.js';
16
- import { a as SelectMenuSync, S as SelectMenu } from './SelectMenuSync-CAweNjRL.js';
17
- import { a as MultiSelectMenuSync, M as MultiSelectMenu } from './MultiSelectMenuSync-Drz8SEk9.js';
16
+ import { a as SelectMenuSync, S as SelectMenu } from './SelectMenuSync-CF49L12-.js';
17
+ import { a as MultiSelectMenuSync, M as MultiSelectMenu } from './MultiSelectMenuSync-BGcrYjby.js';
18
18
  import { S as SvgClose } from './close-DZj38AEh.js';
19
+ import { S as SvgDragIndicator } from './drag_indicator-BRHAPLSJ.js';
19
20
  import { p as portalScopeClassNames } from './portalScopeClassNames-jlZkdug_.js';
20
21
  import { a as useOnClickOutside, r as registerLayer, u as unregisterLayer } from './useOnClickOutside-Zw5vzxSq.js';
22
+ import { u as useBreakpoint } from './useBreakpoint-CeaUyHxh.js';
21
23
  import { c as computePosition, o as offset, h as autoPlacement, d as shift, g as size, a as autoUpdate, s as safeShowPopover, b as safeHidePopover } from './floating-ui.react-dom-BIKT960u.js';
22
24
  import { F as FieldLabel } from './FieldLabel-VVn8GR64.js';
23
25
  import { S as SvgError } from './error-DR_wWdYY.js';
@@ -35,20 +37,214 @@ import { u as useOptionallyControlledState } from './useOptionallyControlledStat
35
37
  import { u as usePrefersColorScheme } from './usePrefersColorScheme-_hT7dK7_.js';
36
38
  import { S as Spinner } from './Spinner-B7tTWcP6.js';
37
39
 
38
- import './DataTable.css';const surface = "_surface_1f9bx_2";
39
- const header = "_header_1f9bx_36";
40
- const title = "_title_1f9bx_55";
41
- const content = "_content_1f9bx_71";
40
+ import './DataTable.css';const SvgResizeWindowAlt = (props) => /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: 24, height: 24, viewBox: "0 0 24 24", ...props }, /* @__PURE__ */ React.createElement("path", { d: "M4.4 21 21 4.425 19.575 3 3 19.575zm10.025 0L21 14.425 19.575 13 13 19.575z" }));
41
+
42
+ const SURFACE_VIEWPORT_PADDING = 8;
43
+ const SURFACE_MIN_WIDTH = 240;
44
+ const SURFACE_MIN_HEIGHT = 120;
45
+ function clampValue(value, min, max) {
46
+ return Math.min(Math.max(value, min), Math.max(min, max));
47
+ }
48
+ function getMaxSurfaceWidth(viewport, x) {
49
+ return Math.max(
50
+ SURFACE_MIN_WIDTH,
51
+ viewport.width - x - SURFACE_VIEWPORT_PADDING
52
+ );
53
+ }
54
+ function getMaxSurfaceHeight(viewport, y) {
55
+ return Math.max(
56
+ SURFACE_MIN_HEIGHT,
57
+ viewport.height - y - SURFACE_VIEWPORT_PADDING
58
+ );
59
+ }
60
+ function isFiniteRect(rect) {
61
+ return Number.isFinite(rect.x) && Number.isFinite(rect.y) && Number.isFinite(rect.width) && Number.isFinite(rect.height) && rect.width > 0 && rect.height > 0;
62
+ }
63
+ function getEffectiveSurfaceHeight(geometry, options) {
64
+ if (geometry.height !== null) return geometry.height;
65
+ return options.measuredHeight ?? SURFACE_MIN_HEIGHT;
66
+ }
67
+ function toSurfaceRect(geometry, options) {
68
+ return {
69
+ x: geometry.x,
70
+ y: geometry.y,
71
+ width: geometry.width,
72
+ height: getEffectiveSurfaceHeight(geometry, options)
73
+ };
74
+ }
75
+ function hasStrictRectIntersection(rect, boundary) {
76
+ return rect.x + rect.width > boundary.x && boundary.x + boundary.width > rect.x && rect.y + rect.height > boundary.y && boundary.y + boundary.height > rect.y;
77
+ }
78
+ function getAxisCorrection({
79
+ boundarySize,
80
+ boundaryStart,
81
+ max,
82
+ min,
83
+ size,
84
+ start
85
+ }) {
86
+ const boundaryEnd = boundaryStart + boundarySize;
87
+ const end = start + size;
88
+ if (end > boundaryStart && start < boundaryEnd) {
89
+ return { value: start, delta: 0 };
90
+ }
91
+ const target = end <= boundaryStart ? boundaryStart - size + 1 : boundaryEnd - 1;
92
+ const value = clampValue(target, min, max);
93
+ if (value + size <= boundaryStart || value >= boundaryEnd) {
94
+ return null;
95
+ }
96
+ return { value, delta: Math.abs(value - start) };
97
+ }
98
+ function restoreBoundaryIntersection(geometry, viewport, options) {
99
+ const boundary = options.intersectionBoundary;
100
+ if (!boundary || !isFiniteRect(boundary)) return geometry;
101
+ const rect = toSurfaceRect(geometry, options);
102
+ if (hasStrictRectIntersection(rect, boundary)) return geometry;
103
+ const xCorrection = getAxisCorrection({
104
+ boundarySize: boundary.width,
105
+ boundaryStart: boundary.x,
106
+ max: viewport.width - SURFACE_VIEWPORT_PADDING - rect.width,
107
+ min: SURFACE_VIEWPORT_PADDING,
108
+ size: rect.width,
109
+ start: geometry.x
110
+ });
111
+ const yCorrection = getAxisCorrection({
112
+ boundarySize: boundary.height,
113
+ boundaryStart: boundary.y,
114
+ max: viewport.height - SURFACE_VIEWPORT_PADDING - rect.height,
115
+ min: SURFACE_VIEWPORT_PADDING,
116
+ size: rect.height,
117
+ start: geometry.y
118
+ });
119
+ if (!xCorrection || !yCorrection) return geometry;
120
+ const xCorrected = {
121
+ ...geometry,
122
+ x: xCorrection.value
123
+ };
124
+ const yCorrected = {
125
+ ...geometry,
126
+ y: yCorrection.value
127
+ };
128
+ const xCorrectionIntersects = hasStrictRectIntersection(
129
+ toSurfaceRect(xCorrected, options),
130
+ boundary
131
+ );
132
+ const yCorrectionIntersects = hasStrictRectIntersection(
133
+ toSurfaceRect(yCorrected, options),
134
+ boundary
135
+ );
136
+ if (xCorrectionIntersects && yCorrectionIntersects) {
137
+ return xCorrection.delta <= yCorrection.delta ? xCorrected : yCorrected;
138
+ }
139
+ if (xCorrectionIntersects) return xCorrected;
140
+ if (yCorrectionIntersects) return yCorrected;
141
+ const corrected = {
142
+ ...geometry,
143
+ x: xCorrection.value,
144
+ y: yCorrection.value
145
+ };
146
+ if (!hasStrictRectIntersection(toSurfaceRect(corrected, options), boundary)) {
147
+ return geometry;
148
+ }
149
+ return corrected;
150
+ }
151
+ function clampSurfaceGeometry(geometry, viewport, options = {}) {
152
+ const width = clampValue(
153
+ geometry.width,
154
+ SURFACE_MIN_WIDTH,
155
+ Math.max(SURFACE_MIN_WIDTH, viewport.width - SURFACE_VIEWPORT_PADDING * 2)
156
+ );
157
+ const effectiveHeight = clampValue(
158
+ getEffectiveSurfaceHeight(geometry, options),
159
+ SURFACE_MIN_HEIGHT,
160
+ Math.max(
161
+ SURFACE_MIN_HEIGHT,
162
+ viewport.height - SURFACE_VIEWPORT_PADDING * 2
163
+ )
164
+ );
165
+ const x = clampValue(
166
+ geometry.x,
167
+ SURFACE_VIEWPORT_PADDING,
168
+ viewport.width - SURFACE_VIEWPORT_PADDING - width
169
+ );
170
+ const y = clampValue(
171
+ geometry.y,
172
+ SURFACE_VIEWPORT_PADDING,
173
+ viewport.height - SURFACE_VIEWPORT_PADDING - effectiveHeight
174
+ );
175
+ const height = geometry.height === null ? null : clampValue(
176
+ geometry.height,
177
+ SURFACE_MIN_HEIGHT,
178
+ getMaxSurfaceHeight(viewport, y)
179
+ );
180
+ return restoreBoundaryIntersection(
181
+ {
182
+ ...geometry,
183
+ x,
184
+ y,
185
+ width: clampValue(
186
+ width,
187
+ SURFACE_MIN_WIDTH,
188
+ getMaxSurfaceWidth(viewport, x)
189
+ ),
190
+ height
191
+ },
192
+ viewport,
193
+ options
194
+ );
195
+ }
196
+ function clampActiveResizeSurfaceGeometry(geometry, viewport) {
197
+ return {
198
+ ...geometry,
199
+ width: clampValue(
200
+ geometry.width,
201
+ SURFACE_MIN_WIDTH,
202
+ getMaxSurfaceWidth(viewport, geometry.x)
203
+ ),
204
+ height: geometry.height === null ? null : clampValue(
205
+ geometry.height,
206
+ SURFACE_MIN_HEIGHT,
207
+ getMaxSurfaceHeight(viewport, geometry.y)
208
+ )
209
+ };
210
+ }
211
+ function restoreSurfaceGeometryIntersection(geometry, viewport, options = {}) {
212
+ const effectiveHeight = getEffectiveSurfaceHeight(geometry, options);
213
+ return restoreBoundaryIntersection(
214
+ {
215
+ ...geometry,
216
+ x: clampValue(
217
+ geometry.x,
218
+ SURFACE_VIEWPORT_PADDING,
219
+ viewport.width - SURFACE_VIEWPORT_PADDING - geometry.width
220
+ ),
221
+ y: clampValue(
222
+ geometry.y,
223
+ SURFACE_VIEWPORT_PADDING,
224
+ viewport.height - SURFACE_VIEWPORT_PADDING - effectiveHeight
225
+ )
226
+ },
227
+ viewport,
228
+ options
229
+ );
230
+ }
231
+
232
+ const surface = "_surface_9apry_1";
233
+ const header = "_header_9apry_55";
234
+ const title = "_title_9apry_83";
235
+ const content = "_content_9apry_110";
42
236
  const styles$i = {
43
237
  surface: surface,
44
238
  header: header,
45
- "header-bottom-border": "_header-bottom-border_1f9bx_45",
46
- "header-copy": "_header-copy_1f9bx_48",
239
+ "header-bottom-border": "_header-bottom-border_9apry_71",
240
+ "header-copy": "_header-copy_9apry_75",
47
241
  title: title,
48
- "header-actions": "_header-actions_1f9bx_62",
49
- "close-button": "_close-button_1f9bx_68",
242
+ "header-actions": "_header-actions_9apry_91",
243
+ "close-button": "_close-button_9apry_98",
244
+ "drag-handle": "_drag-handle_9apry_102",
50
245
  content: content,
51
- "content-title-spacing": "_content-title-spacing_1f9bx_81"
246
+ "content-title-spacing": "_content-title-spacing_9apry_122",
247
+ "resize-handle": "_resize-handle_9apry_127"
52
248
  };
53
249
 
54
250
  const SurfaceContext = createContext(null);
@@ -77,6 +273,63 @@ function resolveCssDimension(value, fallback) {
77
273
  if (typeof value === "string") return value;
78
274
  return fallback;
79
275
  }
276
+ const SURFACE_KEYBOARD_STEP = 8;
277
+ const SURFACE_KEYBOARD_SHIFT_STEP = 32;
278
+ const SURFACE_KEYBOARD_STEP_INTERVAL_MS = 33;
279
+ const SURFACE_ARROW_KEYS = [
280
+ "ArrowLeft",
281
+ "ArrowRight",
282
+ "ArrowUp",
283
+ "ArrowDown"
284
+ ];
285
+ function createSurfacePressedArrowKeys() {
286
+ return {
287
+ ArrowLeft: false,
288
+ ArrowRight: false,
289
+ ArrowUp: false,
290
+ ArrowDown: false
291
+ };
292
+ }
293
+ function isSurfaceArrowKey(key) {
294
+ return SURFACE_ARROW_KEYS.some((arrowKey) => arrowKey === key);
295
+ }
296
+ function getKeyboardAxisDelta(pressedKeys) {
297
+ return {
298
+ x: Number(pressedKeys.ArrowRight) - Number(pressedKeys.ArrowLeft),
299
+ y: Number(pressedKeys.ArrowDown) - Number(pressedKeys.ArrowUp)
300
+ };
301
+ }
302
+ function hasPressedSurfaceArrowKey(pressedKeys) {
303
+ return SURFACE_ARROW_KEYS.some((arrowKey) => pressedKeys[arrowKey]);
304
+ }
305
+ function hasKeyboardAxisDelta(axis) {
306
+ return axis.x !== 0 || axis.y !== 0;
307
+ }
308
+ function parsePixelDimension(value) {
309
+ const numericValue = Number.parseFloat(value);
310
+ if (!Number.isFinite(numericValue)) return null;
311
+ if (value.trim().endsWith("px")) return numericValue;
312
+ return null;
313
+ }
314
+ function getViewportSize() {
315
+ return {
316
+ width: window.innerWidth,
317
+ height: window.innerHeight
318
+ };
319
+ }
320
+ function getMeasuredSurfaceHeight(element) {
321
+ return element.getBoundingClientRect().height;
322
+ }
323
+ function getInteractionStep(shiftKey) {
324
+ return shiftKey ? SURFACE_KEYBOARD_SHIFT_STEP : SURFACE_KEYBOARD_STEP;
325
+ }
326
+ function getElementDimension(element, authoredValue, fallback, dimension) {
327
+ const parsedValue = parsePixelDimension(authoredValue);
328
+ if (parsedValue !== null) return parsedValue;
329
+ const rect = element.getBoundingClientRect();
330
+ const measuredValue = rect.width ;
331
+ return measuredValue > 0 ? measuredValue : fallback;
332
+ }
80
333
  const SurfaceContent = forwardRef(
81
334
  function SurfaceContent2(props, ref) {
82
335
  const {
@@ -86,6 +339,7 @@ const SurfaceContent = forwardRef(
86
339
  title,
87
340
  headerContent,
88
341
  initialFocusRef,
342
+ intersectionBoundaryRef,
89
343
  width,
90
344
  maxHeight,
91
345
  closeButtonLabel = "Close surface",
@@ -95,16 +349,149 @@ const SurfaceContent = forwardRef(
95
349
  ...rest
96
350
  } = props;
97
351
  const { open, referenceElement, surfaceId } = useSurfaceContext();
352
+ const breakpoint = useBreakpoint();
353
+ const isDrawerMode = breakpoint ? !breakpoint.md : false;
354
+ const [localElement, setLocalElement] = useState(
355
+ null
356
+ );
98
357
  const localRef = useRef(null);
99
- const surfaceRef = useMergeRefs([localRef, ref]);
358
+ const setLocalRef = useCallback((node) => {
359
+ localRef.current = node;
360
+ setLocalElement(node);
361
+ }, []);
362
+ const surfaceRef = useMergeRefs([setLocalRef, ref]);
100
363
  const layerId = `${surfaceId}-layer`;
101
364
  const titleId = `${surfaceId}-title`;
102
365
  const resolvedWidth = resolveCssDimension(width, "325px");
103
366
  const resolvedMaxHeight = resolveCssDimension(maxHeight, "450px");
104
367
  const handleCancel = onCancel ?? onClose;
368
+ const [geometry, setGeometry] = useState(null);
369
+ const interactionRef = useRef({ type: "idle" });
370
+ const keyboardInteractionModeRef = useRef(null);
371
+ const pressedArrowKeysRef = useRef(
372
+ createSurfacePressedArrowKeys()
373
+ );
374
+ const keyboardShiftKeyRef = useRef(false);
375
+ const keyboardAnimationFrameRef = useRef(null);
376
+ const keyboardLastStepTimestampRef = useRef(null);
377
+ const getClampOptions = useCallback(
378
+ (measuredHeight) => {
379
+ const boundaryRect = intersectionBoundaryRef?.current?.getBoundingClientRect();
380
+ const intersectionBoundary = boundaryRect ? {
381
+ x: boundaryRect.x,
382
+ y: boundaryRect.y,
383
+ width: boundaryRect.width,
384
+ height: boundaryRect.height
385
+ } : null;
386
+ return {
387
+ measuredHeight,
388
+ intersectionBoundary
389
+ };
390
+ },
391
+ [intersectionBoundaryRef]
392
+ );
393
+ const restoreResizeIntersection = useCallback(() => {
394
+ const viewport = getViewportSize();
395
+ const measuredHeight = localRef.current ? getMeasuredSurfaceHeight(localRef.current) : void 0;
396
+ const clampOptions = getClampOptions(measuredHeight);
397
+ setGeometry(
398
+ (currentGeometry) => currentGeometry ? restoreSurfaceGeometryIntersection(
399
+ currentGeometry,
400
+ viewport,
401
+ clampOptions
402
+ ) : currentGeometry
403
+ );
404
+ }, [getClampOptions]);
405
+ const cancelKeyboardAnimationFrame = useCallback(() => {
406
+ if (keyboardAnimationFrameRef.current !== null) {
407
+ window.cancelAnimationFrame(keyboardAnimationFrameRef.current);
408
+ keyboardAnimationFrameRef.current = null;
409
+ }
410
+ keyboardLastStepTimestampRef.current = null;
411
+ }, []);
412
+ const clearKeyboardInteraction = useCallback(() => {
413
+ cancelKeyboardAnimationFrame();
414
+ keyboardInteractionModeRef.current = null;
415
+ pressedArrowKeysRef.current = createSurfacePressedArrowKeys();
416
+ keyboardShiftKeyRef.current = false;
417
+ }, [cancelKeyboardAnimationFrame]);
418
+ const applyKeyboardInteractionStep = useCallback(() => {
419
+ const mode = keyboardInteractionModeRef.current;
420
+ if (!mode) return;
421
+ const axis = getKeyboardAxisDelta(pressedArrowKeysRef.current);
422
+ if (!hasKeyboardAxisDelta(axis)) return;
423
+ const step = getInteractionStep(keyboardShiftKeyRef.current);
424
+ const viewport = getViewportSize();
425
+ if (mode === "drag") {
426
+ const measuredHeight = localRef.current ? getMeasuredSurfaceHeight(localRef.current) : void 0;
427
+ const clampOptions = getClampOptions(measuredHeight);
428
+ setGeometry(
429
+ (currentGeometry) => currentGeometry ? clampSurfaceGeometry(
430
+ {
431
+ ...currentGeometry,
432
+ x: currentGeometry.x + axis.x * step,
433
+ y: currentGeometry.y + axis.y * step,
434
+ isUserModified: true
435
+ },
436
+ viewport,
437
+ clampOptions
438
+ ) : currentGeometry
439
+ );
440
+ return;
441
+ }
442
+ setGeometry((currentGeometry) => {
443
+ if (!currentGeometry || !localRef.current) return currentGeometry;
444
+ const rect = localRef.current.getBoundingClientRect();
445
+ return clampActiveResizeSurfaceGeometry(
446
+ {
447
+ ...currentGeometry,
448
+ width: currentGeometry.width + axis.x * step,
449
+ height: (currentGeometry.height ?? rect.height) + axis.y * step,
450
+ isUserModified: true,
451
+ hasUserResized: true
452
+ },
453
+ viewport
454
+ );
455
+ });
456
+ }, [getClampOptions]);
457
+ const runKeyboardInteractionFrame = useCallback(
458
+ (timestamp) => {
459
+ const mode = keyboardInteractionModeRef.current;
460
+ const pressedKeys = pressedArrowKeysRef.current;
461
+ if (!mode || !hasPressedSurfaceArrowKey(pressedKeys)) {
462
+ clearKeyboardInteraction();
463
+ return;
464
+ }
465
+ const axis = getKeyboardAxisDelta(pressedKeys);
466
+ if (!hasKeyboardAxisDelta(axis)) {
467
+ cancelKeyboardAnimationFrame();
468
+ return;
469
+ }
470
+ const lastStepTimestamp = keyboardLastStepTimestampRef.current;
471
+ if (lastStepTimestamp === null || timestamp - lastStepTimestamp >= SURFACE_KEYBOARD_STEP_INTERVAL_MS) {
472
+ keyboardLastStepTimestampRef.current = timestamp;
473
+ applyKeyboardInteractionStep();
474
+ }
475
+ keyboardAnimationFrameRef.current = window.requestAnimationFrame(
476
+ runKeyboardInteractionFrame
477
+ );
478
+ },
479
+ [
480
+ applyKeyboardInteractionStep,
481
+ cancelKeyboardAnimationFrame,
482
+ clearKeyboardInteraction
483
+ ]
484
+ );
485
+ const startKeyboardInteractionLoop = useCallback(() => {
486
+ if (keyboardAnimationFrameRef.current !== null) return;
487
+ keyboardLastStepTimestampRef.current = null;
488
+ keyboardAnimationFrameRef.current = window.requestAnimationFrame(
489
+ runKeyboardInteractionFrame
490
+ );
491
+ }, [runKeyboardInteractionFrame]);
105
492
  useOnClickOutside({
106
493
  targets: [
107
- localRef.current ?? void 0,
494
+ localElement ?? void 0,
108
495
  referenceElement.current ?? void 0
109
496
  ],
110
497
  onClickOutside: () => {
@@ -114,10 +501,12 @@ const SurfaceContent = forwardRef(
114
501
  layerId
115
502
  });
116
503
  const updatePosition = useCallback(async () => {
117
- if (!localRef.current || !referenceElement.current) return;
504
+ if (isDrawerMode || !localRef.current || !referenceElement.current)
505
+ return;
506
+ const surfaceElement = localRef.current;
118
507
  const position = await computePosition(
119
508
  referenceElement.current,
120
- localRef.current,
509
+ surfaceElement,
121
510
  {
122
511
  placement: "bottom-start",
123
512
  middleware: [
@@ -129,14 +518,15 @@ const SurfaceContent = forwardRef(
129
518
  "top-start",
130
519
  "top-end"
131
520
  ],
132
- padding: 8
521
+ padding: SURFACE_VIEWPORT_PADDING
133
522
  }),
134
- shift({ padding: 8 }),
523
+ shift({ padding: SURFACE_VIEWPORT_PADDING }),
135
524
  size({
136
- padding: 8,
525
+ padding: SURFACE_VIEWPORT_PADDING,
137
526
  apply({ availableHeight, availableWidth, elements }) {
527
+ const isUserModified = elements.floating.getAttribute("data-user-modified") === "true";
138
528
  Object.assign(elements.floating.style, {
139
- width: resolvedWidth,
529
+ width: isUserModified ? elements.floating.style.width : resolvedWidth,
140
530
  maxWidth: `${Math.max(0, availableWidth)}px`,
141
531
  maxHeight: `min(${resolvedMaxHeight}, ${Math.max(0, availableHeight)}px)`
142
532
  });
@@ -145,24 +535,65 @@ const SurfaceContent = forwardRef(
145
535
  ]
146
536
  }
147
537
  );
148
- localRef.current.style.left = `${position.x}px`;
149
- localRef.current.style.top = `${position.y}px`;
150
- }, [referenceElement, resolvedMaxHeight, resolvedWidth]);
538
+ const viewport = getViewportSize();
539
+ const measuredWidth = getElementDimension(
540
+ surfaceElement,
541
+ resolvedWidth,
542
+ 325);
543
+ const measuredHeight = getMeasuredSurfaceHeight(surfaceElement);
544
+ const clampOptions = getClampOptions(measuredHeight);
545
+ setGeometry((currentGeometry) => {
546
+ if (currentGeometry?.isUserModified) {
547
+ return clampSurfaceGeometry(currentGeometry, viewport, clampOptions);
548
+ }
549
+ return clampSurfaceGeometry(
550
+ {
551
+ x: position.x,
552
+ y: position.y,
553
+ width: measuredWidth,
554
+ height: null,
555
+ isUserModified: false,
556
+ hasUserResized: false
557
+ },
558
+ viewport,
559
+ clampOptions
560
+ );
561
+ });
562
+ }, [
563
+ getClampOptions,
564
+ isDrawerMode,
565
+ referenceElement,
566
+ resolvedMaxHeight,
567
+ resolvedWidth
568
+ ]);
151
569
  useEffect(() => {
152
- if (!open || !localRef.current || !referenceElement.current) return;
570
+ if (isDrawerMode || !open || !localRef.current || !referenceElement.current) {
571
+ return;
572
+ }
153
573
  return autoUpdate(referenceElement.current, localRef.current, () => {
154
574
  void updatePosition();
155
575
  });
156
- }, [open, referenceElement, updatePosition]);
576
+ }, [isDrawerMode, open, referenceElement, updatePosition]);
157
577
  useEffect(() => {
158
578
  if (!localRef.current) return;
159
579
  if (open) {
160
580
  safeShowPopover(localRef.current);
161
- void updatePosition();
581
+ if (!isDrawerMode) {
582
+ void updatePosition();
583
+ }
162
584
  return;
163
585
  }
586
+ interactionRef.current = { type: "idle" };
587
+ clearKeyboardInteraction();
588
+ setGeometry(null);
164
589
  safeHidePopover(localRef.current);
165
- }, [open, updatePosition]);
590
+ }, [clearKeyboardInteraction, isDrawerMode, open, updatePosition]);
591
+ useEffect(() => {
592
+ if (!isDrawerMode) return;
593
+ interactionRef.current = { type: "idle" };
594
+ clearKeyboardInteraction();
595
+ setGeometry(null);
596
+ }, [clearKeyboardInteraction, isDrawerMode]);
166
597
  useEffect(() => {
167
598
  if (!open) return;
168
599
  registerLayer(layerId);
@@ -170,6 +601,11 @@ const SurfaceContent = forwardRef(
170
601
  unregisterLayer(layerId);
171
602
  };
172
603
  }, [layerId, open]);
604
+ useEffect(() => {
605
+ return () => {
606
+ clearKeyboardInteraction();
607
+ };
608
+ }, [clearKeyboardInteraction]);
173
609
  useEffect(() => {
174
610
  if (!open || !initialFocusRef?.current) return;
175
611
  const focusHandle = window.requestAnimationFrame(() => {
@@ -179,10 +615,8 @@ const SurfaceContent = forwardRef(
179
615
  window.cancelAnimationFrame(focusHandle);
180
616
  };
181
617
  }, [initialFocusRef, open]);
182
- useEffect(() => {
183
- const surfaceElement = localRef.current;
184
- if (!surfaceElement) return;
185
- const handleSurfaceKeyDown = (event) => {
618
+ const handleSurfaceKeyDown = useCallback(
619
+ (event) => {
186
620
  onKeyDown?.(event);
187
621
  if (event.defaultPrevented) return;
188
622
  if (event.key === "Escape") {
@@ -190,73 +624,286 @@ const SurfaceContent = forwardRef(
190
624
  event.stopPropagation();
191
625
  handleCancel();
192
626
  }
193
- };
194
- surfaceElement.addEventListener("keydown", handleSurfaceKeyDown);
195
- return () => {
196
- surfaceElement.removeEventListener("keydown", handleSurfaceKeyDown);
197
- };
198
- }, [handleCancel, onKeyDown]);
627
+ },
628
+ [handleCancel, onKeyDown]
629
+ );
630
+ const handleDragPointerDown = useCallback(
631
+ (event) => {
632
+ if (event.button !== 0 || isDrawerMode || !geometry) return;
633
+ event.preventDefault();
634
+ event.currentTarget.setPointerCapture(event.pointerId);
635
+ interactionRef.current = {
636
+ type: "dragging",
637
+ pointerId: event.pointerId,
638
+ startClientX: event.clientX,
639
+ startClientY: event.clientY,
640
+ startX: geometry.x,
641
+ startY: geometry.y
642
+ };
643
+ },
644
+ [geometry, isDrawerMode]
645
+ );
646
+ const handleResizePointerDown = useCallback(
647
+ (event) => {
648
+ if (event.button !== 0 || isDrawerMode || !geometry || !localRef.current) {
649
+ return;
650
+ }
651
+ const rect = localRef.current.getBoundingClientRect();
652
+ event.preventDefault();
653
+ event.currentTarget.setPointerCapture(event.pointerId);
654
+ interactionRef.current = {
655
+ type: "resizing",
656
+ pointerId: event.pointerId,
657
+ startClientX: event.clientX,
658
+ startClientY: event.clientY,
659
+ startWidth: rect.width > 0 ? rect.width : geometry.width,
660
+ startHeight: geometry.height ?? rect.height
661
+ };
662
+ },
663
+ [geometry, isDrawerMode]
664
+ );
665
+ const handleInteractionPointerMove = useCallback(
666
+ (event) => {
667
+ const interaction = interactionRef.current;
668
+ if (interaction.type === "idle" || interaction.pointerId !== event.pointerId) {
669
+ return;
670
+ }
671
+ event.preventDefault();
672
+ const deltaX = event.clientX - interaction.startClientX;
673
+ const deltaY = event.clientY - interaction.startClientY;
674
+ const viewport = getViewportSize();
675
+ const measuredHeight = localRef.current ? getMeasuredSurfaceHeight(localRef.current) : void 0;
676
+ const clampOptions = getClampOptions(measuredHeight);
677
+ setGeometry((currentGeometry) => {
678
+ if (!currentGeometry) return currentGeometry;
679
+ if (interaction.type === "dragging") {
680
+ return clampSurfaceGeometry(
681
+ {
682
+ ...currentGeometry,
683
+ x: interaction.startX + deltaX,
684
+ y: interaction.startY + deltaY,
685
+ isUserModified: true
686
+ },
687
+ viewport,
688
+ clampOptions
689
+ );
690
+ }
691
+ return clampActiveResizeSurfaceGeometry(
692
+ {
693
+ ...currentGeometry,
694
+ width: interaction.startWidth + deltaX,
695
+ height: interaction.startHeight + deltaY,
696
+ isUserModified: true,
697
+ hasUserResized: true
698
+ },
699
+ viewport
700
+ );
701
+ });
702
+ },
703
+ [getClampOptions]
704
+ );
705
+ const handleInteractionPointerEnd = useCallback(
706
+ (event) => {
707
+ const interaction = interactionRef.current;
708
+ if (interaction.type === "idle" || interaction.pointerId !== event.pointerId) {
709
+ return;
710
+ }
711
+ const shouldRestoreIntersection = interaction.type === "resizing";
712
+ if (event.currentTarget.hasPointerCapture(event.pointerId)) {
713
+ event.currentTarget.releasePointerCapture(event.pointerId);
714
+ }
715
+ interactionRef.current = { type: "idle" };
716
+ if (shouldRestoreIntersection) {
717
+ restoreResizeIntersection();
718
+ }
719
+ },
720
+ [restoreResizeIntersection]
721
+ );
722
+ const handleDragKeyboardInteractionBlur = useCallback(() => {
723
+ clearKeyboardInteraction();
724
+ }, [clearKeyboardInteraction]);
725
+ const handleResizeKeyboardInteractionBlur = useCallback(() => {
726
+ restoreResizeIntersection();
727
+ clearKeyboardInteraction();
728
+ }, [clearKeyboardInteraction, restoreResizeIntersection]);
729
+ const handleDragKeyDown = useCallback(
730
+ (event) => {
731
+ if (isDrawerMode || !isSurfaceArrowKey(event.key)) return;
732
+ event.preventDefault();
733
+ event.stopPropagation();
734
+ pressedArrowKeysRef.current[event.key] = true;
735
+ keyboardShiftKeyRef.current = event.shiftKey;
736
+ keyboardInteractionModeRef.current = "drag";
737
+ startKeyboardInteractionLoop();
738
+ },
739
+ [isDrawerMode, startKeyboardInteractionLoop]
740
+ );
741
+ const handleDragKeyUp = useCallback(
742
+ (event) => {
743
+ if (isDrawerMode || !isSurfaceArrowKey(event.key)) return;
744
+ event.preventDefault();
745
+ event.stopPropagation();
746
+ pressedArrowKeysRef.current[event.key] = false;
747
+ keyboardShiftKeyRef.current = event.shiftKey;
748
+ if (!hasPressedSurfaceArrowKey(pressedArrowKeysRef.current)) {
749
+ clearKeyboardInteraction();
750
+ return;
751
+ }
752
+ keyboardInteractionModeRef.current = "drag";
753
+ if (hasKeyboardAxisDelta(
754
+ getKeyboardAxisDelta(pressedArrowKeysRef.current)
755
+ )) {
756
+ startKeyboardInteractionLoop();
757
+ }
758
+ },
759
+ [clearKeyboardInteraction, isDrawerMode, startKeyboardInteractionLoop]
760
+ );
761
+ const handleResizeKeyDown = useCallback(
762
+ (event) => {
763
+ if (isDrawerMode || !isSurfaceArrowKey(event.key)) return;
764
+ event.preventDefault();
765
+ event.stopPropagation();
766
+ pressedArrowKeysRef.current[event.key] = true;
767
+ keyboardShiftKeyRef.current = event.shiftKey;
768
+ keyboardInteractionModeRef.current = "resize";
769
+ startKeyboardInteractionLoop();
770
+ },
771
+ [isDrawerMode, startKeyboardInteractionLoop]
772
+ );
773
+ const handleResizeKeyUp = useCallback(
774
+ (event) => {
775
+ if (isDrawerMode || !isSurfaceArrowKey(event.key)) return;
776
+ event.preventDefault();
777
+ event.stopPropagation();
778
+ pressedArrowKeysRef.current[event.key] = false;
779
+ keyboardShiftKeyRef.current = event.shiftKey;
780
+ if (!hasPressedSurfaceArrowKey(pressedArrowKeysRef.current)) {
781
+ restoreResizeIntersection();
782
+ clearKeyboardInteraction();
783
+ return;
784
+ }
785
+ keyboardInteractionModeRef.current = "resize";
786
+ if (hasKeyboardAxisDelta(
787
+ getKeyboardAxisDelta(pressedArrowKeysRef.current)
788
+ )) {
789
+ startKeyboardInteractionLoop();
790
+ }
791
+ },
792
+ [
793
+ clearKeyboardInteraction,
794
+ isDrawerMode,
795
+ restoreResizeIntersection,
796
+ startKeyboardInteractionLoop
797
+ ]
798
+ );
199
799
  const defaultLabelProps = !("aria-label" in rest) && !("aria-labelledby" in rest) && title ? { "aria-labelledby": titleId } : {};
200
800
  const dialogProps = {
201
- role: "dialog",
801
+ role: open ? "dialog" : void 0,
202
802
  "aria-modal": false
203
803
  };
204
- return /* @__PURE__ */ jsxs(
205
- "div",
206
- {
207
- ...rest,
208
- ...defaultLabelProps,
209
- id: surfaceId,
210
- ref: surfaceRef,
211
- popover: "manual",
212
- ...dialogProps,
213
- tabIndex: -1,
214
- className: cx(className, styles$i["surface"], portalScopeClassNames),
215
- style: {
216
- ...style,
217
- width: resolvedWidth,
218
- maxHeight: resolvedMaxHeight
219
- },
220
- "data-anv": "surface-content",
221
- children: [
222
- /* @__PURE__ */ jsxs(
223
- "div",
224
- {
225
- className: cx(styles$i["header"], {
226
- [styles$i["header-bottom-border"]]: title
227
- }),
228
- children: [
229
- /* @__PURE__ */ jsx("div", { className: styles$i["header-copy"], children: title ? /* @__PURE__ */ jsx("div", { id: titleId, className: styles$i["title"], children: title }) : null }),
230
- /* @__PURE__ */ jsxs("div", { className: styles$i["header-actions"], children: [
231
- headerContent,
232
- /* @__PURE__ */ jsx(
233
- Button,
234
- {
235
- appearance: "ghost",
236
- "aria-label": closeButtonLabel,
237
- className: styles$i["close-button"],
238
- "data-anv": "surface-close-button",
239
- icon: SvgClose,
240
- onClick: onClose,
241
- size: "small",
242
- type: "button"
243
- }
244
- )
245
- ] })
246
- ]
247
- }
248
- ),
249
- /* @__PURE__ */ jsx(
250
- "div",
251
- {
252
- className: cx(styles$i["content"], {
253
- [styles$i["content-title-spacing"]]: title
254
- }),
255
- children
256
- }
257
- )
258
- ]
259
- }
804
+ const surfaceStyle = isDrawerMode ? { ...style } : {
805
+ ...style,
806
+ left: geometry ? `${geometry.x}px` : void 0,
807
+ top: geometry ? `${geometry.y}px` : void 0,
808
+ width: geometry ? `${geometry.width}px` : resolvedWidth,
809
+ maxWidth: geometry ? `${getMaxSurfaceWidth(getViewportSize(), geometry.x)}px` : void 0,
810
+ height: geometry?.hasUserResized && geometry.height !== null ? `${geometry.height}px` : void 0,
811
+ maxHeight: geometry?.hasUserResized && geometry.height !== null ? void 0 : resolvedMaxHeight
812
+ };
813
+ return (
814
+ // eslint-disable-next-line jsx-a11y/no-static-element-interactions -- Surface dialog handles keyboard shortcuts for moving and resizing its nested controls.
815
+ /* @__PURE__ */ jsxs(
816
+ "div",
817
+ {
818
+ ...rest,
819
+ ...defaultLabelProps,
820
+ id: surfaceId,
821
+ ref: surfaceRef,
822
+ popover: "manual",
823
+ ...dialogProps,
824
+ tabIndex: -1,
825
+ className: cx(className, styles$i["surface"], portalScopeClassNames),
826
+ style: surfaceStyle,
827
+ onKeyDown: handleSurfaceKeyDown,
828
+ "data-anv": "surface-content",
829
+ "data-surface-variant": isDrawerMode ? "drawer" : "popover",
830
+ "data-user-modified": geometry?.isUserModified ? "true" : void 0,
831
+ children: [
832
+ /* @__PURE__ */ jsxs(
833
+ "div",
834
+ {
835
+ className: cx(styles$i["header"], {
836
+ [styles$i["header-bottom-border"]]: title
837
+ }),
838
+ children: [
839
+ /* @__PURE__ */ jsx("div", { className: styles$i["header-copy"], children: title ? /* @__PURE__ */ jsx("div", { id: titleId, className: styles$i["title"], children: title }) : null }),
840
+ /* @__PURE__ */ jsxs("div", { className: styles$i["header-actions"], children: [
841
+ headerContent,
842
+ !isDrawerMode ? /* @__PURE__ */ jsx(
843
+ Button,
844
+ {
845
+ appearance: "ghost",
846
+ "aria-label": "Move surface",
847
+ className: styles$i["drag-handle"],
848
+ "data-anv": "surface-drag-handle",
849
+ icon: SvgDragIndicator,
850
+ onBlur: handleDragKeyboardInteractionBlur,
851
+ onKeyDown: handleDragKeyDown,
852
+ onKeyUp: handleDragKeyUp,
853
+ onPointerCancel: handleInteractionPointerEnd,
854
+ onPointerDown: handleDragPointerDown,
855
+ onPointerMove: handleInteractionPointerMove,
856
+ onPointerUp: handleInteractionPointerEnd,
857
+ size: "small",
858
+ type: "button"
859
+ }
860
+ ) : null,
861
+ /* @__PURE__ */ jsx(
862
+ Button,
863
+ {
864
+ appearance: "ghost",
865
+ "aria-label": closeButtonLabel,
866
+ className: styles$i["close-button"],
867
+ "data-anv": "surface-close-button",
868
+ icon: SvgClose,
869
+ onClick: onClose,
870
+ size: "small",
871
+ type: "button"
872
+ }
873
+ )
874
+ ] })
875
+ ]
876
+ }
877
+ ),
878
+ /* @__PURE__ */ jsx(
879
+ "div",
880
+ {
881
+ className: cx(styles$i["content"], {
882
+ [styles$i["content-title-spacing"]]: title
883
+ }),
884
+ children
885
+ }
886
+ ),
887
+ !isDrawerMode ? /* @__PURE__ */ jsx(
888
+ "button",
889
+ {
890
+ "aria-label": "Resize surface",
891
+ className: styles$i["resize-handle"],
892
+ "data-anv": "surface-resize-handle",
893
+ onBlur: handleResizeKeyboardInteractionBlur,
894
+ onKeyDown: handleResizeKeyDown,
895
+ onKeyUp: handleResizeKeyUp,
896
+ onPointerDown: handleResizePointerDown,
897
+ onPointerMove: handleInteractionPointerMove,
898
+ onPointerUp: handleInteractionPointerEnd,
899
+ onPointerCancel: handleInteractionPointerEnd,
900
+ type: "button",
901
+ children: /* @__PURE__ */ jsx(SvgResizeWindowAlt, { "aria-hidden": "true", "data-anv": "icon" })
902
+ }
903
+ ) : null
904
+ ]
905
+ }
906
+ )
260
907
  );
261
908
  }
262
909
  );
@@ -311,19 +958,19 @@ const booleanFormatter = (value, { trueLabel = "True", falseLabel = "False" } =
311
958
  };
312
959
 
313
960
  const styles$h = {
314
- "table-header-cell": "_table-header-cell_14omv_4",
315
- "table-body-cell": "_table-body-cell_14omv_5",
316
- "table-footer-cell": "_table-footer-cell_14omv_6",
317
- "last-pinned-left-column": "_last-pinned-left-column_14omv_30",
318
- "first-pinned-right-column": "_first-pinned-right-column_14omv_30",
319
- "first-pinned-left-column": "_first-pinned-left-column_14omv_51",
320
- "last-pinned-right-column": "_last-pinned-right-column_14omv_56",
321
- "empty-cell": "_empty-cell_14omv_65",
322
- "table-cell-internal-select": "_table-cell-internal-select_14omv_82",
323
- "table-cell-internal-expand": "_table-cell-internal-expand_14omv_86",
324
- "table-header-cell-sortable": "_table-header-cell-sortable_14omv_91",
325
- "table-header-cell-interactive": "_table-header-cell-interactive_14omv_92",
326
- "table-header-cell-group": "_table-header-cell-group_14omv_96"
961
+ "table-header-cell": "_table-header-cell_11yr3_4",
962
+ "table-body-cell": "_table-body-cell_11yr3_5",
963
+ "table-footer-cell": "_table-footer-cell_11yr3_6",
964
+ "last-pinned-left-column": "_last-pinned-left-column_11yr3_30",
965
+ "first-pinned-right-column": "_first-pinned-right-column_11yr3_30",
966
+ "first-pinned-left-column": "_first-pinned-left-column_11yr3_51",
967
+ "last-pinned-right-column": "_last-pinned-right-column_11yr3_56",
968
+ "empty-cell": "_empty-cell_11yr3_73",
969
+ "table-cell-internal-select": "_table-cell-internal-select_11yr3_90",
970
+ "table-cell-internal-expand": "_table-cell-internal-expand_11yr3_94",
971
+ "table-header-cell-sortable": "_table-header-cell-sortable_11yr3_99",
972
+ "table-header-cell-interactive": "_table-header-cell-interactive_11yr3_100",
973
+ "table-header-cell-group": "_table-header-cell-group_11yr3_104"
327
974
  };
328
975
 
329
976
  const TableEmptyCellContent = () => {
@@ -587,7 +1234,17 @@ const dateTimeFormatter = (value, {
587
1234
  return localizedDateTime.toLocaleString(formatOptions);
588
1235
  };
589
1236
 
590
- const SUPPORTED_INLINE_TAGS = ["strong", "b", "em", "i", "code", "mark"];
1237
+ const SUPPORTED_INLINE_TAGS = [
1238
+ "strong",
1239
+ "b",
1240
+ "em",
1241
+ "i",
1242
+ "code",
1243
+ "mark",
1244
+ "s",
1245
+ "strike",
1246
+ "del"
1247
+ ];
591
1248
  const INLINE_TAG_REGEX = new RegExp(
592
1249
  `<(${SUPPORTED_INLINE_TAGS.join("|")})(\\s[^>]*)?>([\\s\\S]*?)</\\1>`,
593
1250
  "gi"
@@ -598,7 +1255,10 @@ const INLINE_WRAPPERS = {
598
1255
  em: ["*", "*"],
599
1256
  i: ["*", "*"],
600
1257
  code: ["`", "`"],
601
- mark: ["==", "=="]
1258
+ mark: ["==", "=="],
1259
+ s: ["~~", "~~"],
1260
+ strike: ["~~", "~~"],
1261
+ del: ["~~", "~~"]
602
1262
  };
603
1263
  function convertInlineTags(html) {
604
1264
  let result = html;
@@ -614,9 +1274,25 @@ function convertInlineTags(html) {
614
1274
  }
615
1275
  return result;
616
1276
  }
1277
+ const UNWRAP_TAGS = ["u", "span"];
1278
+ const UNWRAP_TAG_REGEX = new RegExp(
1279
+ `</?(?:${UNWRAP_TAGS.join("|")})(\\s[^>]*)?>`,
1280
+ "gi"
1281
+ );
1282
+ function unwrapTags(html) {
1283
+ return html.replace(UNWRAP_TAG_REGEX, "");
1284
+ }
617
1285
  const BR_REGEX = /<br\s*\/?>/gi;
618
1286
  const P_OPEN_REGEX = /<p(\s[^>]*)?>/gi;
619
1287
  const P_CLOSE_REGEX = /<\/p>/gi;
1288
+ const HEADING_REGEX$1 = /<h([1-3])(\s[^>]*)?>([\s\S]*?)<\/h\1>/gi;
1289
+ function convertHeadings(html) {
1290
+ return html.replace(HEADING_REGEX$1, (_, level, _attrs, content) => {
1291
+ const hashes = "#".repeat(Number(level));
1292
+ return `${hashes} ${content.trim()}
1293
+ `;
1294
+ });
1295
+ }
620
1296
  const NAMED_ENTITIES = {
621
1297
  amp: "&",
622
1298
  lt: "<",
@@ -644,6 +1320,12 @@ const SUPPORTED_TAGS = [
644
1320
  "i",
645
1321
  "code",
646
1322
  "mark",
1323
+ "s",
1324
+ "strike",
1325
+ "del",
1326
+ "h1",
1327
+ "h2",
1328
+ "h3",
647
1329
  "ul",
648
1330
  "ol",
649
1331
  "li",
@@ -693,7 +1375,9 @@ function htmlToMarkdown(value) {
693
1375
  return "";
694
1376
  }
695
1377
  let result = value;
1378
+ result = unwrapTags(result);
696
1379
  result = removeUnsupportedTags(result);
1380
+ result = convertHeadings(result);
697
1381
  result = result.replace(P_OPEN_REGEX, "");
698
1382
  result = result.replace(P_CLOSE_REGEX, "\n");
699
1383
  result = convertLists(result);
@@ -704,20 +1388,27 @@ function htmlToMarkdown(value) {
704
1388
  return result;
705
1389
  }
706
1390
 
707
- const highlight = "_highlight_1t8gj_1";
708
- const code = "_code_1t8gj_7";
709
- const list = "_list_1t8gj_15";
710
- const container = "_container_1t8gj_23";
1391
+ const highlight = "_highlight_16fej_1";
1392
+ const code = "_code_16fej_7";
1393
+ const list = "_list_16fej_15";
1394
+ const container = "_container_16fej_23";
1395
+ const heading1 = "_heading1_16fej_29";
1396
+ const heading2 = "_heading2_16fej_30";
1397
+ const heading3 = "_heading3_16fej_31";
711
1398
  const styles$f = {
712
1399
  highlight: highlight,
713
1400
  code: code,
714
1401
  list: list,
715
- container: container
1402
+ container: container,
1403
+ heading1: heading1,
1404
+ heading2: heading2,
1405
+ heading3: heading3
716
1406
  };
717
1407
 
718
- const INLINE_REGEX = /\*\*\*(.+?)\*\*\*|\*\*(.+?)\*\*|\*(.+?)\*|==(.+?)==|`(.+?)`/g;
1408
+ const INLINE_REGEX = /\*\*\*(.+?)\*\*\*|\*\*(.+?)\*\*|\*(.+?)\*|==(.+?)==|`(.+?)`|~~(.+?)~~/g;
719
1409
  const UNORDERED_LIST_REGEX = /^- (.+)$/;
720
1410
  const ORDERED_LIST_REGEX = /^\d+\. (.+)$/;
1411
+ const HEADING_REGEX = /^(#{1,3}) +(\S.*)$/;
721
1412
  function parseInline(text) {
722
1413
  const parts = [];
723
1414
  let lastIndex = 0;
@@ -745,6 +1436,8 @@ function parseInline(text) {
745
1436
  parts.push(
746
1437
  /* @__PURE__ */ jsx("code", { className: styles$f.code, children: match[5] }, key)
747
1438
  );
1439
+ } else if (match[6]) {
1440
+ parts.push(/* @__PURE__ */ jsx("s", { children: parseInline(match[6]) }, key));
748
1441
  }
749
1442
  INLINE_REGEX.lastIndex = savedIndex;
750
1443
  lastIndex = savedIndex;
@@ -760,9 +1453,17 @@ function parseBlocks(text) {
760
1453
  let i = 0;
761
1454
  while (i < lines.length) {
762
1455
  const line = lines[i];
1456
+ const headingMatch = line.match(HEADING_REGEX);
763
1457
  const ulMatch = line.match(UNORDERED_LIST_REGEX);
764
1458
  const olMatch = line.match(ORDERED_LIST_REGEX);
765
- if (ulMatch) {
1459
+ if (headingMatch) {
1460
+ blocks.push({
1461
+ type: "heading",
1462
+ level: headingMatch[1].length,
1463
+ content: headingMatch[2]
1464
+ });
1465
+ i++;
1466
+ } else if (ulMatch) {
766
1467
  const items = [ulMatch[1]];
767
1468
  i++;
768
1469
  while (i < lines.length) {
@@ -796,6 +1497,8 @@ function renderBlocks(blocks) {
796
1497
  switch (block.type) {
797
1498
  case "text":
798
1499
  return /* @__PURE__ */ jsx("span", { children: parseInline(block.content) }, index);
1500
+ case "heading":
1501
+ return /* @__PURE__ */ jsx("span", { className: styles$f[`heading${block.level}`], children: parseInline(block.content) }, index);
799
1502
  case "ul":
800
1503
  return /* @__PURE__ */ jsx("ul", { className: styles$f.list, children: block.items.map((item, i) => /* @__PURE__ */ jsx("li", { children: parseInline(item) }, i)) }, index);
801
1504
  case "ol":
@@ -4364,9 +5067,9 @@ const getCommonPinningClasses = (column) => {
4364
5067
  };
4365
5068
 
4366
5069
  const styles$c = {
4367
- "data-table-body-cell-affordance-container": "_data-table-body-cell-affordance-container_1e9zz_1",
4368
- "data-table-body-cell-affordance-host": "_data-table-body-cell-affordance-host_1e9zz_6",
4369
- "data-table-body-cell-affordance-container-interactive": "_data-table-body-cell-affordance-container-interactive_1e9zz_21"
5070
+ "data-table-body-cell-affordance-container": "_data-table-body-cell-affordance-container_1eir6_1",
5071
+ "data-table-body-cell-affordance-host": "_data-table-body-cell-affordance-host_1eir6_6",
5072
+ "data-table-body-cell-affordance-container-interactive": "_data-table-body-cell-affordance-container-interactive_1eir6_21"
4370
5073
  };
4371
5074
 
4372
5075
  const dataTableCellAffordanceHostClassName = styles$c["data-table-body-cell-affordance-host"];
@@ -4415,20 +5118,20 @@ const styles$b = {
4415
5118
  "data-table-body-cell-input": "_data-table-body-cell-input_1t30b_4"};
4416
5119
 
4417
5120
  const styles$a = {
4418
- "data-table-body-cell": "_data-table-body-cell_bmoq4_4",
4419
- "data-table-body-cell-input": "_data-table-body-cell-input_bmoq4_5",
4420
- "table-body-cell": "_table-body-cell_bmoq4_10",
4421
- "table-header-cell": "_table-header-cell_bmoq4_11",
4422
- "table-footer-cell": "_table-footer-cell_bmoq4_12",
4423
- "data-table-cell-content": "_data-table-cell-content_bmoq4_24",
4424
- "data-table-cell-overflow-content": "_data-table-cell-overflow-content_bmoq4_46",
4425
- "data-table-body-cell-editing": "_data-table-body-cell-editing_bmoq4_53",
4426
- "data-table-header-cell": "_data-table-header-cell_bmoq4_54",
4427
- "data-table-footer-cell": "_data-table-footer-cell_bmoq4_57",
4428
- "data-table-body-cell-error": "_data-table-body-cell-error_bmoq4_107",
4429
- "data-table-body-cell-warning": "_data-table-body-cell-warning_bmoq4_122",
4430
- "cell-error-icon": "_cell-error-icon_bmoq4_132",
4431
- "cell-warning-icon": "_cell-warning-icon_bmoq4_137"
5121
+ "data-table-body-cell": "_data-table-body-cell_105ir_4",
5122
+ "data-table-body-cell-input": "_data-table-body-cell-input_105ir_5",
5123
+ "table-body-cell": "_table-body-cell_105ir_10",
5124
+ "table-header-cell": "_table-header-cell_105ir_11",
5125
+ "table-footer-cell": "_table-footer-cell_105ir_12",
5126
+ "data-table-cell-content": "_data-table-cell-content_105ir_24",
5127
+ "data-table-cell-overflow-content": "_data-table-cell-overflow-content_105ir_45",
5128
+ "data-table-body-cell-editing": "_data-table-body-cell-editing_105ir_52",
5129
+ "data-table-header-cell": "_data-table-header-cell_105ir_53",
5130
+ "data-table-footer-cell": "_data-table-footer-cell_105ir_56",
5131
+ "data-table-body-cell-error": "_data-table-body-cell-error_105ir_109",
5132
+ "data-table-body-cell-warning": "_data-table-body-cell-warning_105ir_124",
5133
+ "cell-error-icon": "_cell-error-icon_105ir_134",
5134
+ "cell-warning-icon": "_cell-warning-icon_105ir_139"
4432
5135
  };
4433
5136
 
4434
5137
  function formatCellPositionString(cellPosition) {
@@ -5786,30 +6489,49 @@ const DataTableEditableBooleanCell = Object.assign(
5786
6489
  { displayName: "DataTableEditableBooleanCell" }
5787
6490
  );
5788
6491
 
6492
+ const DataTableSurfaceCoordinatorContext = createContext(null);
6493
+
6494
+ function useDataTableSurfaceCoordinator() {
6495
+ return useContext(DataTableSurfaceCoordinatorContext);
6496
+ }
6497
+
5789
6498
  function isCustomDraftValueUpdater(nextValue) {
5790
6499
  return typeof nextValue === "function";
5791
6500
  }
5792
6501
  function isCustomFieldValueUpdater(nextValue) {
5793
6502
  return typeof nextValue === "function";
5794
6503
  }
6504
+ function isObjectDraftValue(value) {
6505
+ return value !== null && typeof value === "object" && !Array.isArray(value);
6506
+ }
6507
+ function getDraftObject(draftValue) {
6508
+ return isObjectDraftValue(draftValue) ? draftValue : {};
6509
+ }
5795
6510
  function deriveChangedFields(initialValue, draftValue) {
6511
+ const initialObject = getDraftObject(initialValue);
6512
+ const draftObject = getDraftObject(draftValue);
5796
6513
  const orderedKeys = Array.from(
5797
- /* @__PURE__ */ new Set([...Object.keys(initialValue), ...Object.keys(draftValue)])
6514
+ /* @__PURE__ */ new Set([...Object.keys(initialObject), ...Object.keys(draftObject)])
5798
6515
  );
5799
6516
  return orderedKeys.filter(
5800
- (field) => !Object.is(initialValue[field], draftValue[field])
6517
+ (field) => !Object.is(initialObject[field], draftObject[field])
5801
6518
  );
5802
6519
  }
6520
+ function deriveIsDirty(initialValue, draftValue, changedFields) {
6521
+ const initialValueIsNullish = initialValue == null;
6522
+ const draftValueIsNullish = draftValue == null;
6523
+ if (initialValueIsNullish || draftValueIsNullish) {
6524
+ return initialValueIsNullish && draftValueIsNullish ? !Object.is(initialValue, draftValue) : true;
6525
+ }
6526
+ return changedFields.length > 0;
6527
+ }
5803
6528
  function deriveValidation(validateDraft, draftValue, rowId) {
5804
6529
  return validateDraft?.(draftValue, rowId) ?? {};
5805
6530
  }
5806
6531
  function hasValidationErrors(validation) {
5807
- if (validation.formError) {
5808
- return true;
5809
- }
5810
- return Object.values(validation.fieldErrors ?? {}).some(
5811
- (fieldError) => fieldError != null
5812
- );
6532
+ const formError = validation.formError;
6533
+ const fieldErrors = Object.values(validation.fieldErrors ?? {});
6534
+ return formError != null && formError !== false || fieldErrors.some((fieldError) => fieldError != null && fieldError !== false);
5813
6535
  }
5814
6536
  function useCustomEditControllerState({
5815
6537
  row,
@@ -5818,7 +6540,9 @@ function useCustomEditControllerState({
5818
6540
  onCloseEditor
5819
6541
  }) {
5820
6542
  const rowId = String(row.id);
5821
- const initialValueRef = useRef(row[columnId]);
6543
+ const initialValueRef = useRef(
6544
+ row[columnId]
6545
+ );
5822
6546
  const initialValue = initialValueRef.current;
5823
6547
  const [draftValue, setDraftValueState] = useState(initialValue);
5824
6548
  const draftValueRef = useRef(draftValue);
@@ -5829,12 +6553,10 @@ function useCustomEditControllerState({
5829
6553
  );
5830
6554
  const setDraftValue = useCallback(
5831
6555
  (nextValue) => {
5832
- let resolvedValue = draftValueRef.current;
5833
- setDraftValueState((previousValue) => {
5834
- resolvedValue = isCustomDraftValueUpdater(nextValue) ? nextValue(previousValue) : nextValue;
5835
- draftValueRef.current = resolvedValue;
5836
- return resolvedValue;
5837
- });
6556
+ const previousValue = draftValueRef.current;
6557
+ const resolvedValue = isCustomDraftValueUpdater(nextValue) ? nextValue(previousValue) : nextValue;
6558
+ draftValueRef.current = resolvedValue;
6559
+ setDraftValueState(resolvedValue);
5838
6560
  editConfig.onDraftUpdate?.(resolvedValue, rowId);
5839
6561
  return resolvedValue;
5840
6562
  },
@@ -5842,26 +6564,26 @@ function useCustomEditControllerState({
5842
6564
  );
5843
6565
  const setDraftField = useCallback(
5844
6566
  (field, nextValue) => {
5845
- return setDraftValue((previousValue) => ({
5846
- ...previousValue,
5847
- [field]: isCustomFieldValueUpdater(nextValue) ? nextValue(previousValue[field], previousValue) : nextValue
5848
- }));
6567
+ return setDraftValue((previousValue) => {
6568
+ const previousObject = getDraftObject(previousValue);
6569
+ return {
6570
+ ...previousObject,
6571
+ [field]: isCustomFieldValueUpdater(nextValue) ? nextValue(previousObject[field], previousObject) : nextValue
6572
+ };
6573
+ });
5849
6574
  },
5850
6575
  [setDraftValue]
5851
6576
  );
5852
6577
  const performClose = useCallback(
5853
6578
  (reason, action) => {
5854
6579
  const currentDraftValue = draftValueRef.current;
6580
+ const changedFields2 = deriveChangedFields(initialValue, currentDraftValue);
5855
6581
  const validation2 = getValidation(currentDraftValue);
5856
- const changedFields2 = deriveChangedFields(
5857
- initialValue,
5858
- currentDraftValue
5859
- );
5860
6582
  const request = {
5861
6583
  reason,
5862
6584
  draftValue: currentDraftValue,
5863
6585
  initialValue,
5864
- isDirty: changedFields2.length > 0,
6586
+ isDirty: deriveIsDirty(initialValue, currentDraftValue, changedFields2),
5865
6587
  validation: validation2
5866
6588
  };
5867
6589
  if (action === "submit" && editConfig.blockOnValidationError === true && hasValidationErrors(validation2)) {
@@ -5875,24 +6597,26 @@ function useCustomEditControllerState({
5875
6597
  } else {
5876
6598
  draftValueRef.current = initialValue;
5877
6599
  setDraftValueState(initialValue);
5878
- editConfig.onDraftUpdate?.(initialValue, rowId);
6600
+ editConfig.onDraftUpdate?.(
6601
+ initialValue,
6602
+ rowId
6603
+ );
5879
6604
  }
5880
6605
  onCloseEditor?.();
5881
- return true;
5882
6606
  },
5883
6607
  [editConfig, getValidation, initialValue, onCloseEditor, rowId]
5884
6608
  );
5885
6609
  const requestClose = useCallback(
5886
6610
  (reason) => {
5887
- void performClose(reason, reason === "escape" ? "discard" : "submit");
6611
+ performClose(reason, reason === "escape" ? "discard" : "submit");
5888
6612
  },
5889
6613
  [performClose]
5890
6614
  );
5891
6615
  const submit = useCallback(() => {
5892
- void performClose("programmatic", "submit");
6616
+ performClose("programmatic", "submit");
5893
6617
  }, [performClose]);
5894
6618
  const discard = useCallback(() => {
5895
- void performClose("programmatic", "discard");
6619
+ performClose("programmatic", "discard");
5896
6620
  }, [performClose]);
5897
6621
  const setInitialFocus = useCallback((focus) => {
5898
6622
  initialFocusRef.current = focus;
@@ -5905,9 +6629,16 @@ function useCustomEditControllerState({
5905
6629
  [requestClose]
5906
6630
  );
5907
6631
  const changedFields = useMemo(
5908
- () => deriveChangedFields(initialValue, draftValue),
6632
+ () => deriveChangedFields(
6633
+ initialValue,
6634
+ draftValue
6635
+ ),
5909
6636
  [draftValue, initialValue]
5910
6637
  );
6638
+ const isDirty = useMemo(
6639
+ () => deriveIsDirty(initialValue, draftValue, changedFields),
6640
+ [changedFields, draftValue, initialValue]
6641
+ );
5911
6642
  const validation = useMemo(
5912
6643
  () => getValidation(draftValue),
5913
6644
  [draftValue, getValidation]
@@ -5916,7 +6647,7 @@ function useCustomEditControllerState({
5916
6647
  () => ({
5917
6648
  draftValue,
5918
6649
  initialValue,
5919
- isDirty: changedFields.length > 0,
6650
+ isDirty,
5920
6651
  changedFields,
5921
6652
  validation,
5922
6653
  setDraftValue,
@@ -5933,6 +6664,7 @@ function useCustomEditControllerState({
5933
6664
  draftValue,
5934
6665
  handleSubmit,
5935
6666
  initialValue,
6667
+ isDirty,
5936
6668
  requestClose,
5937
6669
  setDraftValue,
5938
6670
  setInitialFocus,
@@ -6059,23 +6791,25 @@ function DataTableEditableCustomCellInner(props, ref) {
6059
6791
  const closeReasonRef = useRef(
6060
6792
  "outside-click"
6061
6793
  );
6794
+ const shouldRestoreFocusRef = useRef(true);
6062
6795
  const [isOpen, setIsOpen] = useState(false);
6063
6796
  const [tabIndex, setTabIndex] = useState(-1);
6064
6797
  const { moveFocusToCell } = useDTFocusDispatchContext();
6798
+ const surfaceCoordinator = useDataTableSurfaceCoordinator();
6065
6799
  const columnId = getColumnId(cell);
6066
6800
  const cellValue = getCellValue(cell);
6067
6801
  const meta = cell.column.columnDef.meta;
6068
6802
  const editConfig = meta?.editConfig;
6069
6803
  const customEditConfig = editConfig?.mode === "custom" ? editConfig : void 0;
6070
6804
  const isValidValueType = useMemo(() => {
6071
- if (cellValue !== null && typeof cellValue === "object" && !Array.isArray(cellValue)) {
6805
+ if (cellValue == null || typeof cellValue === "object" && !Array.isArray(cellValue)) {
6072
6806
  return true;
6073
6807
  }
6074
6808
  logWarningForInvalidCellValueType({
6075
6809
  columnId: String(columnId),
6076
6810
  editMode: "custom",
6077
- expectedType: "non-null object",
6078
- receivedType: cellValue === null ? "null" : Array.isArray(cellValue) ? "array" : typeof cellValue
6811
+ expectedType: "non-array object, null, or undefined",
6812
+ receivedType: Array.isArray(cellValue) ? "array" : typeof cellValue
6079
6813
  });
6080
6814
  return false;
6081
6815
  }, [cellValue, columnId]);
@@ -6091,11 +6825,6 @@ function DataTableEditableCustomCellInner(props, ref) {
6091
6825
  const surfaceTitle = customEditConfig?.surface?.title ?? null;
6092
6826
  const accessibleSurfaceLabel = `Edit ${defaultSurfaceTitle}`;
6093
6827
  const closeButtonLabel = customEditConfig?.surface?.closeButtonLabel ?? `Commit changes and close ${defaultSurfaceTitle} custom editable cell`;
6094
- const beginEditing = useCallback(() => {
6095
- setIsOpen(true);
6096
- setTabIndex(0);
6097
- moveFocusToCell(cellPosition);
6098
- }, [cellPosition, moveFocusToCell]);
6099
6828
  const restoreFocusToOriginCell = useCallback(() => {
6100
6829
  window.requestAnimationFrame(() => {
6101
6830
  moveFocusToCell(cellPosition);
@@ -6103,11 +6832,47 @@ function DataTableEditableCustomCellInner(props, ref) {
6103
6832
  setTabIndex(0);
6104
6833
  });
6105
6834
  }, [cellPosition, moveFocusToCell]);
6106
- const closeSurface = useCallback(() => {
6107
- customEditControllerRef.current = null;
6108
- setIsOpen(false);
6109
- restoreFocusToOriginCell();
6110
- }, [restoreFocusToOriginCell]);
6835
+ const closeSurface = useCallback(
6836
+ (options = {}) => {
6837
+ customEditControllerRef.current = null;
6838
+ shouldRestoreFocusRef.current = options.restoreFocus ?? shouldRestoreFocusRef.current;
6839
+ setIsOpen(false);
6840
+ surfaceCoordinator?.clear(surfaceId);
6841
+ if (shouldRestoreFocusRef.current) {
6842
+ restoreFocusToOriginCell();
6843
+ }
6844
+ shouldRestoreFocusRef.current = true;
6845
+ },
6846
+ [restoreFocusToOriginCell, surfaceCoordinator, surfaceId]
6847
+ );
6848
+ const beginEditing = useCallback(() => {
6849
+ surfaceCoordinator?.requestOpen({
6850
+ id: surfaceId,
6851
+ close: (options) => {
6852
+ shouldRestoreFocusRef.current = options?.restoreFocus ?? true;
6853
+ if (customEditControllerRef.current) {
6854
+ customEditControllerRef.current.requestClose("programmatic");
6855
+ return;
6856
+ }
6857
+ closeSurface(options);
6858
+ }
6859
+ });
6860
+ shouldRestoreFocusRef.current = true;
6861
+ setIsOpen(true);
6862
+ setTabIndex(0);
6863
+ moveFocusToCell(cellPosition);
6864
+ }, [
6865
+ cellPosition,
6866
+ closeSurface,
6867
+ moveFocusToCell,
6868
+ surfaceCoordinator,
6869
+ surfaceId
6870
+ ]);
6871
+ useEffect(() => {
6872
+ return () => {
6873
+ surfaceCoordinator?.clear(surfaceId);
6874
+ };
6875
+ }, [surfaceCoordinator, surfaceId]);
6111
6876
  const handleSurfaceClose = useCallback(() => {
6112
6877
  const controller = customEditControllerRef.current;
6113
6878
  const reason = closeReasonRef.current;
@@ -6243,6 +7008,7 @@ function DataTableEditableCustomCellInner(props, ref) {
6243
7008
  /* @__PURE__ */ jsxs(
6244
7009
  Surface.Content,
6245
7010
  {
7011
+ intersectionBoundaryRef: surfaceCoordinator?.intersectionBoundaryRef,
6246
7012
  onClose: handleSurfaceClose,
6247
7013
  onCancel: handleSurfaceCancel,
6248
7014
  onClickCapture: handleSurfaceClickCapture,
@@ -6432,6 +7198,7 @@ function DataTableOverflowCell(props) {
6432
7198
  const [isCellHovered, setIsCellHovered] = useState(false);
6433
7199
  const [tabIndex, setTabIndex] = useState(-1);
6434
7200
  const { moveFocus, jumpFocus, moveFocusToCell } = useDTFocusDispatchContext();
7201
+ const surfaceCoordinator = useDataTableSurfaceCoordinator();
6435
7202
  const surfaceTitle = getSurfaceTitle(props);
6436
7203
  const rowCanExpand = cell.row.getCanExpand();
6437
7204
  const rowIsExpanded = cell.row.getIsExpanded();
@@ -6447,6 +7214,7 @@ function DataTableOverflowCell(props) {
6447
7214
  const surfaceInstructionsId = `${surfaceId}-surface-instructions`;
6448
7215
  const isClipped = hasOverflow(overflow);
6449
7216
  const isResizeObserverEnabled = isOpen || isCellFocused || isCellHovered;
7217
+ const shouldRestoreFocusRef = useRef(true);
6450
7218
  const commonPinningStyles = useCommonPinningStyles(cell.column);
6451
7219
  const updateOverflow = useCallback(() => {
6452
7220
  const viewport = viewportRef.current;
@@ -6485,20 +7253,46 @@ function DataTableOverflowCell(props) {
6485
7253
  setTabIndex(0);
6486
7254
  });
6487
7255
  }, [cellPosition, moveFocusToCell]);
7256
+ const closeSurface = useCallback(
7257
+ (options = {}) => {
7258
+ shouldRestoreFocusRef.current = options.restoreFocus ?? shouldRestoreFocusRef.current;
7259
+ setIsOpen(false);
7260
+ surfaceCoordinator?.clear(surfaceId);
7261
+ if (shouldRestoreFocusRef.current) {
7262
+ restoreFocusToOriginCell();
7263
+ }
7264
+ shouldRestoreFocusRef.current = true;
7265
+ },
7266
+ [restoreFocusToOriginCell, surfaceCoordinator, surfaceId]
7267
+ );
6488
7268
  const openSurface = useCallback(() => {
6489
7269
  const nextOverflow = updateOverflow();
6490
7270
  if (!hasOverflow(nextOverflow ?? overflow)) {
6491
7271
  return false;
6492
7272
  }
7273
+ surfaceCoordinator?.requestOpen({
7274
+ id: surfaceId,
7275
+ close: closeSurface
7276
+ });
7277
+ shouldRestoreFocusRef.current = true;
6493
7278
  setIsOpen(true);
6494
7279
  setTabIndex(0);
6495
7280
  moveFocusToCell(cellPosition);
6496
7281
  return true;
6497
- }, [cellPosition, moveFocusToCell, overflow, updateOverflow]);
6498
- const closeSurface = useCallback(() => {
6499
- setIsOpen(false);
6500
- restoreFocusToOriginCell();
6501
- }, [restoreFocusToOriginCell]);
7282
+ }, [
7283
+ cellPosition,
7284
+ closeSurface,
7285
+ moveFocusToCell,
7286
+ overflow,
7287
+ surfaceCoordinator,
7288
+ surfaceId,
7289
+ updateOverflow
7290
+ ]);
7291
+ useEffect(() => {
7292
+ return () => {
7293
+ surfaceCoordinator?.clear(surfaceId);
7294
+ };
7295
+ }, [surfaceCoordinator, surfaceId]);
6502
7296
  const handleCellFocus = useCallback(
6503
7297
  (event) => {
6504
7298
  if (event.target !== cellRef.current) {
@@ -6614,7 +7408,7 @@ function DataTableOverflowCell(props) {
6614
7408
  {
6615
7409
  ref: viewportRef,
6616
7410
  className: styles$9["data-table-body-cell-overflow-viewport"],
6617
- children: /* @__PURE__ */ jsx("div", { className: cx(styles$9["data-table-body-cell-overflow-content"]), children })
7411
+ children: /* @__PURE__ */ jsx("div", { className: styles$9["data-table-body-cell-overflow-content"], children })
6618
7412
  }
6619
7413
  );
6620
7414
  return /* @__PURE__ */ jsxs(Surface, { id: surfaceId, open: isOpen, children: [
@@ -6653,6 +7447,7 @@ function DataTableOverflowCell(props) {
6653
7447
  /* @__PURE__ */ jsx(
6654
7448
  Surface.Content,
6655
7449
  {
7450
+ intersectionBoundaryRef: surfaceCoordinator?.intersectionBoundaryRef,
6656
7451
  initialFocusRef: surfaceContentRef,
6657
7452
  onClose: closeSurface,
6658
7453
  onCancel: closeSurface,
@@ -6695,49 +7490,34 @@ function DataTableBodyCell(props) {
6695
7490
  }
6696
7491
 
6697
7492
  const styles$8 = {
6698
- "data-table-body-row": "_data-table-body-row_hfxpb_4",
6699
- "data-table-body-sub-component-row": "_data-table-body-sub-component-row_hfxpb_23",
6700
- "data-table-body-virtualized": "_data-table-body-virtualized_hfxpb_31",
6701
- "data-table-body-row-virtualized": "_data-table-body-row-virtualized_hfxpb_37",
6702
- "data-table-body-sub-component-container": "_data-table-body-sub-component-container_hfxpb_46",
6703
- "data-table-body-sub-component-content": "_data-table-body-sub-component-content_hfxpb_52",
6704
- "data-table-body-cell-group": "_data-table-body-cell-group_hfxpb_60",
6705
- "data-table-body-cell-depth-indent": "_data-table-body-cell-depth-indent_hfxpb_70",
6706
- "data-table-body-cell-action-depth-indent": "_data-table-body-cell-action-depth-indent_hfxpb_76",
6707
- "data-table-body-row-activatable": "_data-table-body-row-activatable_hfxpb_89",
6708
- "data-table-body-row-active": "_data-table-body-row-active_hfxpb_96",
6709
- "data-table-body-row-ancestor-hovered": "_data-table-body-row-ancestor-hovered_hfxpb_107",
6710
- "data-table-body-sub-component-row-active": "_data-table-body-sub-component-row-active_hfxpb_111",
6711
- "data-table-body-row-read-only": "_data-table-body-row-read-only_hfxpb_115",
6712
- "data-table-body-row-top-active": "_data-table-body-row-top-active_hfxpb_131"
7493
+ "data-table-body-row": "_data-table-body-row_1qb05_4",
7494
+ "data-table-body-sub-component-row": "_data-table-body-sub-component-row_1qb05_32",
7495
+ "data-table-body-virtualized": "_data-table-body-virtualized_1qb05_66",
7496
+ "data-table-body-row-virtualized": "_data-table-body-row-virtualized_1qb05_72",
7497
+ "data-table-body-sub-component-container": "_data-table-body-sub-component-container_1qb05_81",
7498
+ "data-table-body-sub-component-content": "_data-table-body-sub-component-content_1qb05_87",
7499
+ "data-table-body-cell-group": "_data-table-body-cell-group_1qb05_95",
7500
+ "data-table-body-cell-depth-indent": "_data-table-body-cell-depth-indent_1qb05_105",
7501
+ "data-table-body-cell-action-depth-indent": "_data-table-body-cell-action-depth-indent_1qb05_111",
7502
+ "data-table-body-row-read-only": "_data-table-body-row-read-only_1qb05_117"
6713
7503
  };
6714
7504
 
6715
- const ACTIVATE_IGNORE_SELECTOR = 'button, a, input, select, textarea, label, [role="button"], [role="checkbox"], [role="menuitem"], [data-anv="checkbox"], [class*="data-table-body-cell-editable"]';
6716
- function escapeRowIdSelectorValue(value) {
6717
- if (typeof CSS !== "undefined" && typeof CSS.escape === "function") {
6718
- return CSS.escape(value);
7505
+ const HOVER_ATTR = "data-anv-is-hovered-row";
7506
+ const SELECTED_ATTR = "data-anv-is-selected-row";
7507
+ const HAS_SUB_COMPONENT_ATTR = "data-anv-has-sub-component";
7508
+ function hasRowSubComponent(value) {
7509
+ if (typeof value !== "object" || value === null || !("subComponent" in value)) {
7510
+ return false;
6719
7511
  }
6720
- return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\a ").replace(/\r/g, "\\d ").replace(/\f/g, "\\c ");
7512
+ return typeof value.subComponent !== "boolean" && value.subComponent != null;
6721
7513
  }
6722
- function getRowElementById(doc, rowId) {
6723
- const rowIdText = String(rowId);
6724
- const rowElement = doc.querySelector(
6725
- `[data-row-id="${escapeRowIdSelectorValue(rowIdText)}"]`
6726
- );
6727
- return rowElement?.dataset.rowId === rowIdText ? rowElement : void 0;
6728
- }
6729
- function collectDescendantIds(row) {
6730
- const out = [];
6731
- const stack = [...row.subRows ?? []];
6732
- while (stack.length) {
6733
- const current = stack.pop();
6734
- if (!current) continue;
6735
- out.push(current.id);
6736
- if (current.subRows?.length) {
6737
- stack.push(...current.subRows);
7514
+ function collectDescendantRowIds(row, out) {
7515
+ for (const child of row.subRows) {
7516
+ out.push(child.id);
7517
+ if (child.subRows.length > 0) {
7518
+ collectDescendantRowIds(child, out);
6738
7519
  }
6739
7520
  }
6740
- return out;
6741
7521
  }
6742
7522
  function DataTableBodyRowInner({
6743
7523
  // columnOrder is no longer read directly; the row only needs the
@@ -6753,70 +7533,84 @@ function DataTableBodyRowInner({
6753
7533
  canExpand,
6754
7534
  depth,
6755
7535
  parentRowCanExpand,
6756
- isActivatable,
6757
- isActive,
6758
- isTopMostActive,
6759
- isReadOnly,
6760
- onToggleActive
7536
+ isSelected,
7537
+ isSomeSelected,
7538
+ isAncestorSelected,
7539
+ isReadOnly
6761
7540
  }) {
6762
7541
  const visibleCells = row.getVisibleCells();
6763
7542
  const id = row.id;
6764
7543
  const original = row.original;
6765
- const descendantIds = useMemo(() => collectDescendantIds(row), [row]);
6766
- const handleRowClick = useCallback(
6767
- (event) => {
6768
- if (!isActivatable) return;
6769
- if (isReadOnly) return;
6770
- const target = event.target;
6771
- if (target?.closest(ACTIVATE_IGNORE_SELECTOR)) return;
6772
- onToggleActive(
6773
- row.id,
6774
- descendantIds
6775
- );
7544
+ const hasSubComponent = hasRowSubComponent(original);
7545
+ const rowRef = useRef(null);
7546
+ const isSelectedRow = isSelected || isSomeSelected || isAncestorSelected;
7547
+ const setRowHover = useCallback(
7548
+ (rowEl, on) => {
7549
+ const apply = (el) => {
7550
+ if (!el) return;
7551
+ if (on) {
7552
+ el.setAttribute(HOVER_ATTR, "true");
7553
+ } else {
7554
+ el.removeAttribute(HOVER_ATTR);
7555
+ }
7556
+ };
7557
+ apply(rowEl);
7558
+ const base = rowEl.closest('[data-anv="data-table-base"]');
7559
+ const scope = base ?? rowEl.ownerDocument;
7560
+ apply(scope.querySelector(`#${CSS.escape(`${row.id}-sub-component`)}`));
7561
+ const descendantIds = [];
7562
+ collectDescendantRowIds(row, descendantIds);
7563
+ for (const childId of descendantIds) {
7564
+ apply(scope.querySelector(`[data-row-id="${CSS.escape(childId)}"]`));
7565
+ }
6776
7566
  },
6777
- [isActivatable, isReadOnly, onToggleActive, row.id, descendantIds]
7567
+ [row]
6778
7568
  );
6779
- const shouldCascadeHover = isActivatable && canExpand;
6780
7569
  const handleMouseEnter = useCallback(
6781
7570
  (event) => {
6782
- if (!shouldCascadeHover) return;
6783
- const doc = event.currentTarget.ownerDocument ?? document;
6784
- const className = styles$8["data-table-body-row-ancestor-hovered"];
6785
- for (const descendantId of descendantIds) {
6786
- const el = getRowElementById(doc, descendantId);
6787
- el?.classList.add(className);
6788
- }
7571
+ setRowHover(event.currentTarget, true);
6789
7572
  },
6790
- [shouldCascadeHover, descendantIds]
7573
+ [setRowHover]
6791
7574
  );
6792
7575
  const handleMouseLeave = useCallback(
6793
7576
  (event) => {
6794
- if (!shouldCascadeHover) return;
6795
- const doc = event.currentTarget.ownerDocument ?? document;
6796
- const className = styles$8["data-table-body-row-ancestor-hovered"];
6797
- for (const descendantId of descendantIds) {
6798
- const el = getRowElementById(doc, descendantId);
6799
- el?.classList.remove(className);
6800
- }
7577
+ setRowHover(event.currentTarget, false);
6801
7578
  },
6802
- [shouldCascadeHover, descendantIds]
7579
+ [setRowHover]
7580
+ );
7581
+ const handleSubComponentMouseEnter = useCallback(
7582
+ (event) => {
7583
+ event.currentTarget.setAttribute(HOVER_ATTR, "true");
7584
+ },
7585
+ []
7586
+ );
7587
+ const handleSubComponentMouseLeave = useCallback(
7588
+ (event) => {
7589
+ event.currentTarget.removeAttribute(HOVER_ATTR);
7590
+ },
7591
+ []
6803
7592
  );
6804
- const rowRef = useRef(null);
6805
7593
  useLayoutEffect(() => {
6806
- const el = rowRef.current;
6807
- if (!el) return;
6808
- const ownerDoc = el.ownerDocument ?? document;
6809
- const className = styles$8["data-table-body-row-ancestor-hovered"];
6810
- let ancestor = row.getParentRow();
6811
- while (ancestor) {
6812
- const ancestorEl = getRowElementById(ownerDoc, ancestor.id);
6813
- if (ancestorEl?.matches(":hover")) {
6814
- el.classList.add(className);
6815
- return;
6816
- }
6817
- ancestor = ancestor.getParentRow();
7594
+ const rowEl = rowRef.current;
7595
+ if (!rowEl) return;
7596
+ const base = rowEl.closest('[data-anv="data-table-base"]');
7597
+ const scope = base ?? rowEl.ownerDocument;
7598
+ const anyAncestorHovered = row.getParentRows().some((parent) => {
7599
+ const el = scope.querySelector(
7600
+ `[data-row-id="${CSS.escape(parent.id)}"]`
7601
+ );
7602
+ return el?.getAttribute(HOVER_ATTR) === "true";
7603
+ });
7604
+ if (anyAncestorHovered) {
7605
+ rowEl.setAttribute(HOVER_ATTR, "true");
7606
+ }
7607
+ if (rowEl.getAttribute(HOVER_ATTR) === "true") {
7608
+ const subComp = scope.querySelector(
7609
+ `#${CSS.escape(`${row.id}-sub-component`)}`
7610
+ );
7611
+ if (subComp) subComp.setAttribute(HOVER_ATTR, "true");
6818
7612
  }
6819
- }, [row]);
7613
+ });
6820
7614
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [
6821
7615
  /* @__PURE__ */ jsx(
6822
7616
  "div",
@@ -6827,16 +7621,14 @@ function DataTableBodyRowInner({
6827
7621
  "aria-expanded": tableHasSubRows && canExpand ? isExpanded : void 0,
6828
7622
  "aria-level": tableHasSubRows && (canExpand || parentRowCanExpand) ? depth + 1 : void 0,
6829
7623
  "data-row-id": row.id,
7624
+ ...hasSubComponent ? { [HAS_SUB_COMPONENT_ATTR]: "true" } : {},
7625
+ ...isSelectedRow ? { [SELECTED_ATTR]: "true" } : {},
7626
+ onMouseEnter: handleMouseEnter,
7627
+ onMouseLeave: handleMouseLeave,
6830
7628
  className: cx(styles$8["data-table-body-row"], {
6831
- [styles$8["data-table-body-row-activatable"]]: isActivatable,
6832
- [styles$8["data-table-body-row-active"]]: isActive,
6833
- [styles$8["data-table-body-row-top-active"]]: isTopMostActive,
6834
7629
  [styles$8["data-table-body-row-read-only"]]: isReadOnly
6835
7630
  }),
6836
7631
  style: depth > 0 ? { "--a2-row-depth": depth } : void 0,
6837
- onClick: isActivatable ? handleRowClick : void 0,
6838
- onMouseEnter: shouldCascadeHover ? handleMouseEnter : void 0,
6839
- onMouseLeave: shouldCascadeHover ? handleMouseLeave : void 0,
6840
7632
  children: (() => {
6841
7633
  let firstDataCellClaimed = false;
6842
7634
  return visibleCells.map((cell) => {
@@ -6870,14 +7662,16 @@ function DataTableBodyRowInner({
6870
7662
  })()
6871
7663
  }
6872
7664
  ),
6873
- isExpanded && "subComponent" in original && /* @__PURE__ */ jsx(
7665
+ isExpanded && hasSubComponent && /* @__PURE__ */ jsx(
6874
7666
  "div",
6875
7667
  {
6876
7668
  id: `${id}-sub-component`,
6877
7669
  "aria-hidden": !isExpanded,
6878
- className: cx(styles$8["data-table-body-sub-component-row"], {
6879
- [styles$8["data-table-body-sub-component-row-active"]]: isActive
6880
- }),
7670
+ ...{ [HAS_SUB_COMPONENT_ATTR]: "true" },
7671
+ ...isSelectedRow ? { [SELECTED_ATTR]: "true" } : {},
7672
+ className: styles$8["data-table-body-sub-component-row"],
7673
+ onMouseEnter: handleSubComponentMouseEnter,
7674
+ onMouseLeave: handleSubComponentMouseLeave,
6881
7675
  children: /* @__PURE__ */ jsx("div", { className: styles$8["data-table-body-sub-component-container"], children: /* @__PURE__ */ jsx(Flex, { className: styles$8["data-table-body-sub-component-content"], children: original.subComponent }) })
6882
7676
  }
6883
7677
  )
@@ -6888,7 +7682,7 @@ function areRowPropsEqual(prev, next) {
6888
7682
  if (!getRowVersion) {
6889
7683
  return false;
6890
7684
  }
6891
- return prev.row.id === next.row.id && getRowVersion(prev.row.original) === getRowVersion(next.row.original) && prev.rowIndex === next.rowIndex && prev.isExpanded === next.isExpanded && prev.canExpand === next.canExpand && prev.depth === next.depth && prev.parentRowCanExpand === next.parentRowCanExpand && prev.tableHasSubRows === next.tableHasSubRows && prev.columnOrder === next.columnOrder && prev.isSelected === next.isSelected && prev.isSomeSelected === next.isSomeSelected && prev.isActivatable === next.isActivatable && prev.isActive === next.isActive && prev.isTopMostActive === next.isTopMostActive && prev.isReadOnly === next.isReadOnly && prev.onToggleActive === next.onToggleActive;
7685
+ return prev.row.id === next.row.id && getRowVersion(prev.row.original) === getRowVersion(next.row.original) && prev.rowIndex === next.rowIndex && prev.isExpanded === next.isExpanded && prev.canExpand === next.canExpand && prev.depth === next.depth && prev.parentRowCanExpand === next.parentRowCanExpand && prev.tableHasSubRows === next.tableHasSubRows && prev.columnOrder === next.columnOrder && prev.isSelected === next.isSelected && prev.isSomeSelected === next.isSomeSelected && prev.isAncestorSelected === next.isAncestorSelected && prev.isReadOnly === next.isReadOnly;
6892
7686
  }
6893
7687
  const DataTableBodyRow = memo$1(
6894
7688
  DataTableBodyRowInner,
@@ -6930,67 +7724,44 @@ const useColumnOrder = ({ table }) => {
6930
7724
  };
6931
7725
  };
6932
7726
 
6933
- function getIsRowActivatable(row, isActivatable) {
6934
- if (!isActivatable) return false;
6935
- if (typeof isActivatable === "function") {
6936
- return isActivatable(row.original);
6937
- }
6938
- return true;
6939
- }
6940
- function getIsRowTopMostActive(row, activeRowMap) {
6941
- if (!activeRowMap[row.id]) return false;
6942
- if (!row.getCanExpand()) return false;
6943
- let ancestor = row.getParentRow();
6944
- while (ancestor) {
6945
- if (activeRowMap[ancestor.id]) return false;
6946
- ancestor = ancestor.getParentRow();
6947
- }
6948
- return true;
6949
- }
6950
7727
  function NonVirtualizedContent({
6951
7728
  table,
6952
7729
  hasSubRows,
6953
7730
  getRowVersion,
6954
- isActivatable,
6955
- activeRowMap,
6956
- readOnlyRowMap,
6957
- onToggleActive
7731
+ readOnlyRowMap
6958
7732
  }) {
6959
7733
  const { columnOrder, columnIndexMap } = useColumnOrder({ table });
6960
7734
  const headerCount = table.getHeaderGroups().length;
6961
- return /* @__PURE__ */ jsx(Fragment, { children: table.getRowModel().rows.map((row, rowIndex) => /* @__PURE__ */ jsx(
6962
- DataTableBodyRow,
6963
- {
6964
- columnOrder,
6965
- columnIndexMap,
6966
- row,
6967
- rowIndex: rowIndex + headerCount,
6968
- tableHasSubRows: hasSubRows,
6969
- isExpanded: row.getIsExpanded(),
6970
- canExpand: row.getCanExpand(),
6971
- depth: row.depth,
6972
- parentRowCanExpand: row.getParentRow()?.getCanExpand() ?? false,
6973
- isSelected: row.getIsSelected(),
6974
- isSomeSelected: row.getIsSomeSelected(),
6975
- isActivatable: getIsRowActivatable(row, isActivatable),
6976
- isActive: !!activeRowMap[row.id],
6977
- isTopMostActive: getIsRowTopMostActive(row, activeRowMap),
6978
- isReadOnly: !!readOnlyRowMap[row.id],
6979
- onToggleActive,
6980
- getRowVersion
6981
- },
6982
- row.id
6983
- )) });
7735
+ return /* @__PURE__ */ jsx(Fragment, { children: table.getRowModel().rows.map((row, rowIndex) => {
7736
+ const isAncestorSelected = row.getParentRows().some((parent) => parent.getIsSelected());
7737
+ return /* @__PURE__ */ jsx(
7738
+ DataTableBodyRow,
7739
+ {
7740
+ columnOrder,
7741
+ columnIndexMap,
7742
+ row,
7743
+ rowIndex: rowIndex + headerCount,
7744
+ tableHasSubRows: hasSubRows,
7745
+ isExpanded: row.getIsExpanded(),
7746
+ canExpand: row.getCanExpand(),
7747
+ depth: row.depth,
7748
+ parentRowCanExpand: row.getParentRow()?.getCanExpand() ?? false,
7749
+ isSelected: row.getIsSelected(),
7750
+ isSomeSelected: row.getIsSomeSelected(),
7751
+ isAncestorSelected,
7752
+ isReadOnly: !!readOnlyRowMap[row.id],
7753
+ getRowVersion
7754
+ },
7755
+ row.id
7756
+ );
7757
+ }) });
6984
7758
  }
6985
7759
  function VirtualizedContent({
6986
7760
  table,
6987
7761
  hasSubRows,
6988
7762
  virtualizer,
6989
7763
  getRowVersion,
6990
- isActivatable,
6991
- activeRowMap,
6992
- readOnlyRowMap,
6993
- onToggleActive
7764
+ readOnlyRowMap
6994
7765
  }) {
6995
7766
  const { columnOrder, columnIndexMap } = useColumnOrder({ table });
6996
7767
  const headerCount = table.getHeaderGroups().length;
@@ -7011,6 +7782,7 @@ function VirtualizedContent({
7011
7782
  style: { height: `${totalSize}px` },
7012
7783
  children: virtualItems.map((virtualRow) => {
7013
7784
  const row = rows[virtualRow.index];
7785
+ const isAncestorSelected = row.getParentRows().some((parent) => parent.getIsSelected());
7014
7786
  return /* @__PURE__ */ jsx(
7015
7787
  "div",
7016
7788
  {
@@ -7032,11 +7804,8 @@ function VirtualizedContent({
7032
7804
  parentRowCanExpand: row.getParentRow()?.getCanExpand() ?? false,
7033
7805
  isSelected: row.getIsSelected(),
7034
7806
  isSomeSelected: row.getIsSomeSelected(),
7035
- isActivatable: getIsRowActivatable(row, isActivatable),
7036
- isActive: !!activeRowMap[row.id],
7037
- isTopMostActive: getIsRowTopMostActive(row, activeRowMap),
7807
+ isAncestorSelected,
7038
7808
  isReadOnly: !!readOnlyRowMap[row.id],
7039
- onToggleActive,
7040
7809
  getRowVersion
7041
7810
  }
7042
7811
  )
@@ -7053,10 +7822,7 @@ function DataTableBody(props) {
7053
7822
  hasSubRows,
7054
7823
  virtualizer,
7055
7824
  getRowVersion,
7056
- isActivatable,
7057
- activeRowMap,
7058
7825
  readOnlyRowMap,
7059
- onToggleActive,
7060
7826
  ...rest
7061
7827
  } = props;
7062
7828
  return /* @__PURE__ */ jsx(TableBody, { type: "data-table", ...rest, children: virtualizer ? /* @__PURE__ */ jsx(
@@ -7066,10 +7832,7 @@ function DataTableBody(props) {
7066
7832
  hasSubRows,
7067
7833
  virtualizer,
7068
7834
  getRowVersion,
7069
- isActivatable,
7070
- activeRowMap,
7071
- readOnlyRowMap,
7072
- onToggleActive
7835
+ readOnlyRowMap
7073
7836
  }
7074
7837
  ) : /* @__PURE__ */ jsx(
7075
7838
  NonVirtualizedContent,
@@ -7077,10 +7840,7 @@ function DataTableBody(props) {
7077
7840
  table,
7078
7841
  hasSubRows,
7079
7842
  getRowVersion,
7080
- isActivatable,
7081
- activeRowMap,
7082
- readOnlyRowMap,
7083
- onToggleActive
7843
+ readOnlyRowMap
7084
7844
  }
7085
7845
  ) });
7086
7846
  }
@@ -8577,6 +9337,37 @@ function DTFocusProvider({
8577
9337
  return /* @__PURE__ */ jsx(DTFocusStateContext.Provider, { value: state, children: /* @__PURE__ */ jsx(DTFocusDispatchContext.Provider, { value: dispatch, children }) });
8578
9338
  }
8579
9339
 
9340
+ function DataTableSurfaceCoordinatorProvider({
9341
+ children,
9342
+ intersectionBoundaryRef
9343
+ }) {
9344
+ const activeSurfaceRef = useRef(null);
9345
+ const requestOpen = useCallback(
9346
+ (registration) => {
9347
+ const activeSurface = activeSurfaceRef.current;
9348
+ if (activeSurface && activeSurface.id !== registration.id) {
9349
+ activeSurface.close({ restoreFocus: false });
9350
+ }
9351
+ activeSurfaceRef.current = registration;
9352
+ },
9353
+ []
9354
+ );
9355
+ const clear = useCallback((id) => {
9356
+ if (activeSurfaceRef.current?.id === id) {
9357
+ activeSurfaceRef.current = null;
9358
+ }
9359
+ }, []);
9360
+ const value = useMemo(
9361
+ () => ({
9362
+ requestOpen,
9363
+ clear,
9364
+ intersectionBoundaryRef
9365
+ }),
9366
+ [clear, intersectionBoundaryRef, requestOpen]
9367
+ );
9368
+ return /* @__PURE__ */ jsx(DataTableSurfaceCoordinatorContext.Provider, { value, children });
9369
+ }
9370
+
8580
9371
  const VIRTUALIZATION_THRESHOLD = 50;
8581
9372
  const DEFAULT_ESTIMATED_ROW_HEIGHT = 35;
8582
9373
  function useDataTableVirtualizer({
@@ -8617,17 +9408,13 @@ function DataTableInner(props, ref) {
8617
9408
  data: dataProp,
8618
9409
  columns: columnsProp,
8619
9410
  customFooter,
8620
- defaultActiveRowIds,
8621
9411
  defaultExpandedRowIds,
8622
9412
  defaultSelectedRowIds,
8623
9413
  defaultSortedColumn,
8624
9414
  disableExpandAll,
8625
9415
  disableSelectAll,
8626
9416
  expandedRowIds,
8627
- activeRowIds,
8628
- isActivatable,
8629
9417
  isSelectable,
8630
- onActivateRow,
8631
9418
  onSelectRow,
8632
9419
  readOnlyRowIds,
8633
9420
  onSort,
@@ -8657,41 +9444,10 @@ function DataTableInner(props, ref) {
8657
9444
  onSelectRow?.(Object.keys(newRowSelection));
8658
9445
  }
8659
9446
  });
8660
- const [rowActivation, setRowActivation] = useOptionallyControlledState({
8661
- controlledValue: isActivatable && activeRowIds ? Object.fromEntries(activeRowIds.map((id) => [id, true])) : void 0,
8662
- defaultValue: isActivatable ? defaultActiveRowIds ? Object.fromEntries(defaultActiveRowIds.map((id) => [id, true])) : {} : {},
8663
- onChange: (newRowActivation) => {
8664
- onActivateRow?.(Object.keys(newRowActivation));
8665
- }
8666
- });
8667
- const activeRowMap = rowActivation ?? {};
8668
9447
  const readOnlyRowMap = useMemo(
8669
9448
  () => readOnlyRowIds ? Object.fromEntries(readOnlyRowIds.map((id) => [String(id), true])) : {},
8670
9449
  [readOnlyRowIds]
8671
9450
  );
8672
- const setRowActivationRef = useRef(setRowActivation);
8673
- setRowActivationRef.current = setRowActivation;
8674
- const toggleRowActivation = useCallback(
8675
- (rowId, descendantIds = []) => {
8676
- setRowActivationRef.current((prev) => {
8677
- const prevMap = prev ?? {};
8678
- const rowKey = String(rowId);
8679
- const descendantKeys = descendantIds.map(String);
8680
- const next = { ...prevMap };
8681
- if (prevMap[rowKey]) {
8682
- delete next[rowKey];
8683
- descendantKeys.forEach((key) => delete next[key]);
8684
- } else {
8685
- next[rowKey] = true;
8686
- descendantKeys.forEach((key) => {
8687
- next[key] = true;
8688
- });
8689
- }
8690
- return next;
8691
- });
8692
- },
8693
- []
8694
- );
8695
9451
  const [sorting, setSorting] = useOptionallyControlledState({
8696
9452
  controlledValue: sortedColumn ? [sortedColumn] : void 0,
8697
9453
  defaultValue: defaultSortedColumn ? [defaultSortedColumn] : void 0,
@@ -8923,18 +9679,23 @@ function DataTableInner(props, ref) {
8923
9679
  }
8924
9680
  ) });
8925
9681
  },
8926
- cell: ({ row }) => /* @__PURE__ */ jsx(
8927
- Checkbox,
8928
- {
8929
- tabIndex: -1,
8930
- "aria-label": row.getIsSelected() ? "Deselect row" : "Select row",
8931
- checked: row.getIsSelected(),
8932
- disabled: !row.getCanSelect(),
8933
- indeterminate: row.getIsSomeSelected(),
8934
- onChange: row.getToggleSelectedHandler(),
8935
- "data-cell-action": "select"
8936
- }
8937
- )
9682
+ cell: ({ row }) => {
9683
+ const original = row.original;
9684
+ const isReadOnlyRow = Boolean(readOnlyRowMap[String(original.id)]);
9685
+ return /* @__PURE__ */ jsx(
9686
+ Checkbox,
9687
+ {
9688
+ tabIndex: -1,
9689
+ "aria-label": row.getIsSelected() ? "Deselect row" : "Select row",
9690
+ checked: row.getIsSelected(),
9691
+ disabled: !row.getCanSelect(),
9692
+ readOnly: isReadOnlyRow,
9693
+ indeterminate: row.getIsSomeSelected(),
9694
+ onChange: row.getToggleSelectedHandler(),
9695
+ "data-cell-action": "select"
9696
+ }
9697
+ );
9698
+ }
8938
9699
  });
8939
9700
  }
8940
9701
  return tableColumns;
@@ -8946,7 +9707,8 @@ function DataTableInner(props, ref) {
8946
9707
  hasRowStatus,
8947
9708
  hasSubComponent,
8948
9709
  isExpandable,
8949
- isSelectable
9710
+ isSelectable,
9711
+ readOnlyRowMap
8950
9712
  ]);
8951
9713
  const table = useReactTable({
8952
9714
  data: tableData ?? [],
@@ -9041,6 +9803,7 @@ function DataTableInner(props, ref) {
9041
9803
  [bodyRowCount, headerRowCount, footerLength]
9042
9804
  );
9043
9805
  const isEmpty = !isLoading && (!tableData || tableData.length === 0);
9806
+ const isTrulyEmpty = isEmpty && (isCursorPagination ? !paginationObject?.hasPrevPage && !paginationObject?.hasNextPage : !totalItemCount);
9044
9807
  const { mode: themeMode } = useContext(ThemeProviderContext);
9045
9808
  const { mode: sysMode } = usePrefersColorScheme();
9046
9809
  const colorSchemeMode = themeMode ?? sysMode;
@@ -9086,6 +9849,9 @@ function DataTableInner(props, ref) {
9086
9849
  const columnCount = useMemo(() => {
9087
9850
  return headers.filter((header) => header.subHeaders?.length === 0).length;
9088
9851
  }, [headers]);
9852
+ const containerClassName = cx(className, {
9853
+ [styles["container-with-pagination"]]: pagination && !isTrulyEmpty
9854
+ });
9089
9855
  return /* @__PURE__ */ jsx(
9090
9856
  DTFocusProvider,
9091
9857
  {
@@ -9096,7 +9862,7 @@ function DataTableInner(props, ref) {
9096
9862
  rightPinnedWidth: table.getRightTotalSize(),
9097
9863
  virtualizer: rowVirtualizer,
9098
9864
  headerRowCount,
9099
- children: /* @__PURE__ */ jsxs(
9865
+ children: /* @__PURE__ */ jsx(DataTableSurfaceCoordinatorProvider, { intersectionBoundaryRef: tableRef, children: /* @__PURE__ */ jsxs(
9100
9866
  TableContainer,
9101
9867
  {
9102
9868
  ...rest,
@@ -9105,9 +9871,7 @@ function DataTableInner(props, ref) {
9105
9871
  ...styleCombined,
9106
9872
  width: cssVars["--a2-table-width"]
9107
9873
  },
9108
- className: cx(className, {
9109
- [styles["container-with-pagination"]]: pagination
9110
- }),
9874
+ className: containerClassName,
9111
9875
  children: [
9112
9876
  /* @__PURE__ */ jsxs(
9113
9877
  TableBase,
@@ -9126,10 +9890,7 @@ function DataTableInner(props, ref) {
9126
9890
  hasSubRows,
9127
9891
  virtualizer: rowVirtualizer,
9128
9892
  getRowVersion,
9129
- isActivatable,
9130
- activeRowMap,
9131
- readOnlyRowMap,
9132
- onToggleActive: toggleRowActivation
9893
+ readOnlyRowMap
9133
9894
  }
9134
9895
  ),
9135
9896
  isEmpty && emptyState && /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -9178,7 +9939,7 @@ function DataTableInner(props, ref) {
9178
9939
  }
9179
9940
  )
9180
9941
  ] }),
9181
- hasFooters && /* @__PURE__ */ jsx(
9942
+ hasFooters && !isTrulyEmpty && /* @__PURE__ */ jsx(
9182
9943
  DataTableFooter,
9183
9944
  {
9184
9945
  className: pagination ? styles["footer-with-pagination"] : void 0,
@@ -9190,7 +9951,7 @@ function DataTableInner(props, ref) {
9190
9951
  ]
9191
9952
  }
9192
9953
  ),
9193
- pagination && (isCursorPagination ? /* @__PURE__ */ jsx(
9954
+ pagination && !isTrulyEmpty && (isCursorPagination ? /* @__PURE__ */ jsx(
9194
9955
  DataTableCursorPagination,
9195
9956
  {
9196
9957
  itemsPerPage: rowsPerPage,
@@ -9223,11 +9984,11 @@ function DataTableInner(props, ref) {
9223
9984
  ))
9224
9985
  ]
9225
9986
  }
9226
- )
9987
+ ) })
9227
9988
  }
9228
9989
  );
9229
9990
  }
9230
9991
  const DataTable = forwardRef(DataTableInner);
9231
9992
 
9232
9993
  export { COLUMN_TYPE_DEFAULTS as C, DataTable as D, chipsFormatter as a, booleanFormatter as b, createColumnHelper$1 as c, currencyFormatter as d, dateFormatter as e, dateTimeFormatter as f, getColumnTypeDefaults as g, htmlFormatter as h, dateFormatPresets as i, timeFormatter as j, markdownFormatter as m, numberFormatter as n, percentFormatter as p, resolveColumnTypeConfig as r, timeFormatPresets as t, yearlessDateFormatter as y };
9233
- //# sourceMappingURL=DataTable-Dwhwvm6R.js.map
9994
+ //# sourceMappingURL=DataTable-FG0Kjx0d.js.map