@adecore/ui 0.31.12 → 0.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/dist/AccentSwatches.js +290 -13
  2. package/dist/Banner.js +90 -9
  3. package/dist/Button.js +114 -22
  4. package/dist/ButtonGroup.js +62 -8
  5. package/dist/Checkbox.js +73 -4
  6. package/dist/ChoiceCards.js +205 -11
  7. package/dist/CloseButton.js +87 -7
  8. package/dist/ColorSwatch.js +132 -15
  9. package/dist/ColorWheelPicker.js +305 -71
  10. package/dist/ColumnResizeHandle.js +43 -8
  11. package/dist/DisabledReason.js +27 -8
  12. package/dist/DockShell.js +144 -37
  13. package/dist/EmptyState.js +95 -6
  14. package/dist/ErrorBoundary.js +254 -31
  15. package/dist/Field.js +349 -31
  16. package/dist/FileIcon.js +67 -6
  17. package/dist/Icon.js +38 -6
  18. package/dist/IconButton.js +176 -20
  19. package/dist/IconPicker.js +344 -73
  20. package/dist/Input.js +233 -14
  21. package/dist/Kbd.js +150 -10
  22. package/dist/LazyBoundary.js +14 -5
  23. package/dist/ListRow.js +75 -15
  24. package/dist/Meter.js +108 -5
  25. package/dist/MiddleTruncate.js +126 -45
  26. package/dist/PanelEmpty.js +64 -5
  27. package/dist/PanelHeader.js +95 -13
  28. package/dist/Pill.js +114 -19
  29. package/dist/ProjectSwitcher.js +225 -12
  30. package/dist/PromptDialog.js +352 -37
  31. package/dist/SectionLabel.js +62 -8
  32. package/dist/SegmentBar.js +197 -36
  33. package/dist/Segmented.js +130 -23
  34. package/dist/Select.js +310 -19
  35. package/dist/SelectSearch.js +344 -29
  36. package/dist/Separator.js +35 -4
  37. package/dist/ShortcutHints.js +146 -76
  38. package/dist/Skeleton.js +31 -4
  39. package/dist/Slider.js +172 -10
  40. package/dist/SlidingColumn.js +194 -34
  41. package/dist/Spinner.js +100 -3
  42. package/dist/Stepper.js +232 -11
  43. package/dist/Surface.js +62 -8
  44. package/dist/Switch.js +60 -6
  45. package/dist/TextMenu.js +212 -17
  46. package/dist/Tile.js +149 -5
  47. package/dist/Toasts.js +391 -33
  48. package/dist/Tooltip.js +153 -16
  49. package/dist/UIProvider.js +62 -15
  50. package/dist/Waveform.js +362 -93
  51. package/dist/Wipe.js +259 -34
  52. package/dist/ZoomControls.js +356 -14
  53. package/dist/class-name.js +1 -1
  54. package/dist/clipboard.js +15 -17
  55. package/dist/context-menu/index.parts.js +1 -1
  56. package/dist/dialog/index.parts.js +1 -1
  57. package/dist/dialog/parts.js +378 -29
  58. package/dist/dialog-layer.js +51 -18
  59. package/dist/error-boundary.js +19 -19
  60. package/dist/error-message.js +1 -1
  61. package/dist/field-context.js +7 -5
  62. package/dist/file-icon.js +23 -21
  63. package/dist/file-tree/helpers.js +133 -119
  64. package/dist/file-tree/index.parts.js +3 -3
  65. package/dist/file-tree/parts.js +418 -127
  66. package/dist/file-tree/style.js +1 -1
  67. package/dist/file-tree/use-file-tree-shift.js +43 -30
  68. package/dist/file-tree/use-file-tree.js +60 -18
  69. package/dist/file-tree/use-slots.js +220 -192
  70. package/dist/floating.js +2 -2
  71. package/dist/format/datetime.js +88 -38
  72. package/dist/format/duration.js +59 -53
  73. package/dist/format/index.js +1 -1
  74. package/dist/format/locale.js +76 -56
  75. package/dist/format/number.js +77 -61
  76. package/dist/format/regions.js +4 -2
  77. package/dist/format/time-zone.js +1 -1
  78. package/dist/icon-button-size.js +12 -2
  79. package/dist/icon-picker.js +70 -61
  80. package/dist/index.js +57 -57
  81. package/dist/key-value-list/index.parts.js +1 -1
  82. package/dist/key-value-list/parts.js +256 -22
  83. package/dist/lazy-landings.js +10 -10
  84. package/dist/lazy.js +84 -71
  85. package/dist/locales/en.js +80 -80
  86. package/dist/locales/nl.js +80 -80
  87. package/dist/locales.js +10 -7
  88. package/dist/menu/index.parts.js +1 -1
  89. package/dist/menu/parts.js +882 -44
  90. package/dist/merge-refs.js +8 -9
  91. package/dist/middle-truncate.js +24 -25
  92. package/dist/modality.js +27 -19
  93. package/dist/placement.js +11 -20
  94. package/dist/platform.js +6 -6
  95. package/dist/popover/index.parts.js +1 -1
  96. package/dist/popover/parts.js +173 -11
  97. package/dist/popup-layer.js +38 -17
  98. package/dist/prefetch.js +78 -79
  99. package/dist/preview-card/index.parts.js +1 -1
  100. package/dist/project-switcher-row.js +153 -12
  101. package/dist/select-row.js +69 -5
  102. package/dist/select-shared.js +6 -6
  103. package/dist/selection.js +16 -16
  104. package/dist/seti-icons.js +413 -413
  105. package/dist/settings/ConfirmDialog.js +55 -8
  106. package/dist/settings/DetailHeader.js +72 -4
  107. package/dist/settings/MasterDetail.js +119 -7
  108. package/dist/settings/SettingsDialog.js +820 -80
  109. package/dist/settings/SettingsRow.js +205 -18
  110. package/dist/settings/SettingsSection.js +96 -6
  111. package/dist/settings/index.js +7 -7
  112. package/dist/settings/target.js +7 -2
  113. package/dist/shortcut-hints.js +73 -55
  114. package/dist/shortcut.js +140 -104
  115. package/dist/step-places.js +1 -1
  116. package/dist/tabs/index.parts.js +1 -1
  117. package/dist/tabs/overflow.js +18 -18
  118. package/dist/tabs/parts.js +780 -166
  119. package/dist/testing/dedupe.js +82 -75
  120. package/dist/testing/fake-source.js +12 -12
  121. package/dist/testing/index.js +1 -1
  122. package/dist/toast-store.js +65 -46
  123. package/dist/tree/index.parts.js +1 -1
  124. package/dist/tree/parts.js +721 -94
  125. package/dist/tree/shift.js +28 -22
  126. package/dist/tree/style.js +2 -2
  127. package/dist/tree/use-tree-shift.js +178 -117
  128. package/dist/useAsyncAction.js +23 -19
  129. package/dist/useColumnResize.js +36 -34
  130. package/dist/useContentSize.js +62 -18
  131. package/dist/useMeasuredWidth.js +14 -3
  132. package/dist/useNow.js +73 -30
  133. package/dist/wipe-split.js +14 -14
  134. package/dist/workspace/DropPreview.js +60 -7
  135. package/dist/workspace/SplitView.js +1025 -441
  136. package/dist/workspace/TabStrip.js +810 -191
  137. package/dist/workspace/Workspace.js +276 -26
  138. package/dist/workspace/context.js +8 -3
  139. package/dist/workspace/geometry.js +173 -150
  140. package/dist/workspace/model.js +313 -250
  141. package/dist/workspace/preview.js +61 -61
  142. package/dist/zoom.js +2 -2
  143. package/package.json +1 -1
  144. package/src/ErrorBoundary.tsx +1 -1
  145. package/src/Field.tsx +4 -3
  146. package/src/IconPicker.tsx +3 -3
  147. package/src/LazyBoundary.tsx +2 -0
  148. package/src/MiddleTruncate.tsx +2 -2
  149. package/src/SegmentBar.tsx +2 -2
  150. package/src/Toasts.tsx +3 -1
  151. package/src/Tooltip.tsx +7 -10
  152. package/src/Waveform.tsx +3 -3
  153. package/src/file-tree/parts.tsx +6 -9
  154. package/src/file-tree/use-file-tree-shift.tsx +6 -9
  155. package/src/lazy.tsx +4 -0
  156. package/src/locales/en.ts +4 -4
  157. package/src/locales/nl.ts +5 -5
  158. package/src/settings/SettingsDialog.tsx +1 -1
  159. package/src/tree/parts.tsx +5 -8
  160. package/src/useContentSize.ts +3 -3
  161. package/src/workspace/SplitView.tsx +2 -2
  162. package/src/workspace/TabStrip.tsx +2 -3
  163. package/src/workspace/Workspace.tsx +2 -5
@@ -1,3 +1,4 @@
1
+ import { c as _c } from "react/compiler-runtime";
1
2
  import { useFileTree as usePierreFileTree } from '@pierre/trees/react';
2
3
  import { useLayoutEffect, useRef } from 'react';
3
4
  import { FILE_TREE_ICONS } from '../file-icon.js';
@@ -6,21 +7,62 @@ import { compareRows } from './helpers.js';
6
7
  import { FILE_TREE_CSS } from './style.js';
7
8
  // Model options are initial; paths and status can subsequently change through the model's mutation methods.
8
9
  export function useFileTree(options) {
9
- const latest = useRef(options.onSelectionChange);
10
- useLayoutEffect(() => {
11
- latest.current = options.onSelectionChange;
12
- }, [options.onSelectionChange]);
13
- return usePierreFileTree({
14
- composition: { contextMenu: { enabled: false } },
15
- icons: FILE_TREE_ICONS,
16
- initialExpansion: 'closed',
17
- search: false,
18
- stickyFolders: false,
19
- sort: compareRows,
20
- ...options,
21
- density: 'compact',
22
- itemHeight: TREE_ROW_HEIGHT,
23
- onSelectionChange: (paths) => latest.current?.(paths),
24
- unsafeCSS: `${FILE_TREE_CSS}\n${options.unsafeCSS ?? ''}`
25
- });
26
- }
10
+ const $ = _c(8);
11
+ const latest = useRef(options.onSelectionChange);
12
+ let t0;
13
+ let t1;
14
+ if ($[0] !== options.onSelectionChange) {
15
+ t0 = () => {
16
+ latest.current = options.onSelectionChange;
17
+ };
18
+ t1 = [options.onSelectionChange];
19
+ $[0] = options.onSelectionChange;
20
+ $[1] = t0;
21
+ $[2] = t1;
22
+ } else {
23
+ t0 = $[1];
24
+ t1 = $[2];
25
+ }
26
+ useLayoutEffect(t0, t1);
27
+ let t2;
28
+ if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
29
+ t2 = {
30
+ contextMenu: {
31
+ enabled: false
32
+ }
33
+ };
34
+ $[3] = t2;
35
+ } else {
36
+ t2 = $[3];
37
+ }
38
+ let t3;
39
+ if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
40
+ t3 = paths => latest.current?.(paths);
41
+ $[4] = t3;
42
+ } else {
43
+ t3 = $[4];
44
+ }
45
+ const t4 = `${FILE_TREE_CSS}\n${options.unsafeCSS ?? ""}`;
46
+ let t5;
47
+ if ($[5] !== options || $[6] !== t4) {
48
+ t5 = {
49
+ composition: t2,
50
+ icons: FILE_TREE_ICONS,
51
+ initialExpansion: "closed",
52
+ search: false,
53
+ stickyFolders: false,
54
+ sort: compareRows,
55
+ ...options,
56
+ density: "compact",
57
+ itemHeight: TREE_ROW_HEIGHT,
58
+ onSelectionChange: t3,
59
+ unsafeCSS: t4
60
+ };
61
+ $[5] = options;
62
+ $[6] = t4;
63
+ $[7] = t5;
64
+ } else {
65
+ t5 = $[7];
66
+ }
67
+ return usePierreFileTree(t5);
68
+ }
@@ -8,208 +8,236 @@ import { FILE_TREE_CSS } from './style.js';
8
8
  * the spacer is missing or the model already moved past what is mounted.
9
9
  */
10
10
  function mountedRows(model, shadow, elements) {
11
- const spacer = shadow.querySelector('[data-file-tree-virtualized-sticky-offset]');
12
- const offset = spacer === null ? Number.NaN : Number.parseFloat(spacer.style.height);
13
- const itemHeight = model.getItemHeight();
14
- if (!Number.isFinite(offset) || itemHeight <= 0) {
15
- return visibleRows(model);
16
- }
17
- // A folder pinned to the top leaves the flow, but still takes its index in the window.
18
- const pinned = shadow.querySelectorAll('[data-file-tree-sticky-row="true"]').length;
19
- const rows = visibleRowsAround(model, Math.round(offset / itemHeight), elements.length + pinned);
20
- const paths = new Set(rows.map((row) => row.path));
21
- return elements.every((element) => element.dataset.itemPath === undefined || paths.has(element.dataset.itemPath)) ? rows : visibleRows(model);
11
+ const spacer = shadow.querySelector('[data-file-tree-virtualized-sticky-offset]');
12
+ const offset = spacer === null ? Number.NaN : Number.parseFloat(spacer.style.height);
13
+ const itemHeight = model.getItemHeight();
14
+ if (!Number.isFinite(offset) || itemHeight <= 0) {
15
+ return visibleRows(model);
16
+ }
17
+ // A folder pinned to the top leaves the flow, but still takes its index in the window.
18
+ const pinned = shadow.querySelectorAll('[data-file-tree-sticky-row="true"]').length;
19
+ const rows = visibleRowsAround(model, Math.round(offset / itemHeight), elements.length + pinned);
20
+ const paths = new Set(rows.map(row => row.path));
21
+ return elements.every(element => element.dataset.itemPath === undefined || paths.has(element.dataset.itemPath)) ? rows : visibleRows(model);
22
22
  }
23
23
  /*
24
24
  * Lines the ports up with their rows: every size first, then the spaces they reserve, then every offset,
25
25
  * then the ports, so a pass forces two layouts at most however many rows are mounted.
26
26
  */
27
27
  export function positionPorts(ports) {
28
- const spaced = [...ports].map((port) => ({
29
- port,
30
- control: port.lightControl.childNodes.length > 0 ? Math.ceil(port.lightControl.getBoundingClientRect().width) + 6 : 0,
31
- decoration: port.lightDecoration.childNodes.length > 0 ? Math.ceil(port.lightDecoration.getBoundingClientRect().width) + 6 : 0
32
- }));
33
- for (const { port, control, decoration } of spaced) {
34
- setSpace(port.rowElement, '--adecore-tree-control-space', control);
35
- setSpace(port.rowElement, '--adecore-tree-decoration-space', decoration);
36
- }
37
- const placed = spaced.map(({ port, control, decoration }) => {
38
- const row = port.rowElement;
39
- const content = row.querySelector('[data-item-section="content"]');
40
- const icon = row.querySelector('[data-item-section="icon"]');
41
- return {
42
- port,
43
- top: `${row.offsetTop}px`,
44
- controlLeft: `${row.offsetLeft + (icon?.offsetLeft ?? 4) - control}px`,
45
- decorationLeft: `${row.offsetLeft + (content === null ? row.offsetWidth - decoration - 2 : content.offsetLeft + content.offsetWidth + 6)}px`
46
- };
47
- });
48
- for (const { port, top, controlLeft, decorationLeft } of placed) {
49
- port.control.style.top = top;
50
- port.control.style.left = controlLeft;
51
- port.decoration.style.top = top;
52
- port.decoration.style.left = decorationLeft;
53
- }
28
+ const spaced = [...ports].map(port => ({
29
+ port,
30
+ control: port.lightControl.childNodes.length > 0 ? Math.ceil(port.lightControl.getBoundingClientRect().width) + 6 : 0,
31
+ decoration: port.lightDecoration.childNodes.length > 0 ? Math.ceil(port.lightDecoration.getBoundingClientRect().width) + 6 : 0
32
+ }));
33
+ for (const {
34
+ port,
35
+ control,
36
+ decoration
37
+ } of spaced) {
38
+ setSpace(port.rowElement, '--adecore-tree-control-space', control);
39
+ setSpace(port.rowElement, '--adecore-tree-decoration-space', decoration);
40
+ }
41
+ const placed = spaced.map(({
42
+ port,
43
+ control,
44
+ decoration
45
+ }) => {
46
+ const row = port.rowElement;
47
+ const content = row.querySelector('[data-item-section="content"]');
48
+ const icon = row.querySelector('[data-item-section="icon"]');
49
+ return {
50
+ port,
51
+ top: `${row.offsetTop}px`,
52
+ controlLeft: `${row.offsetLeft + (icon?.offsetLeft ?? 4) - control}px`,
53
+ decorationLeft: `${row.offsetLeft + (content === null ? row.offsetWidth - decoration - 2 : content.offsetLeft + content.offsetWidth + 6)}px`
54
+ };
55
+ });
56
+ for (const {
57
+ port,
58
+ top,
59
+ controlLeft,
60
+ decorationLeft
61
+ } of placed) {
62
+ port.control.style.top = top;
63
+ port.control.style.left = controlLeft;
64
+ port.decoration.style.top = top;
65
+ port.decoration.style.left = decorationLeft;
66
+ }
54
67
  }
55
68
  // An unchanged space is left alone, so a pass that only scrolled measures once.
56
69
  function setSpace(row, name, space) {
57
- const value = `${space}px`;
58
- if (row.style.getPropertyValue(name) !== value) {
59
- row.style.setProperty(name, value);
60
- }
70
+ const value = `${space}px`;
71
+ if (row.style.getPropertyValue(name) !== value) {
72
+ row.style.setProperty(name, value);
73
+ }
61
74
  }
62
75
  // beta.6 owns button rows. Sibling slots keep real controls outside those buttons and in the app's stylesheet.
63
76
  export function useFileTreeSlots(model, frame, label) {
64
- const prefix = useId().replaceAll(':', '');
65
- const [slots, setSlots] = useState([]);
66
- useEffect(() => {
67
- if (frame === null) {
68
- return;
77
+ const prefix = useId().replaceAll(':', '');
78
+ const [slots, setSlots] = useState([]);
79
+ useEffect(() => {
80
+ if (frame === null) {
81
+ return;
82
+ }
83
+ const ports = new Map();
84
+ let shadow = null;
85
+ let style = null;
86
+ let serial = 0;
87
+ let disposed = false;
88
+ let pending = false;
89
+ let snapshot = null;
90
+ const position = () => positionPorts(ports.values());
91
+ const resize = new ResizeObserver(position);
92
+ const dropPort = port => {
93
+ port.control.remove();
94
+ port.decoration.remove();
95
+ resize.unobserve(port.lightControl);
96
+ resize.unobserve(port.lightDecoration);
97
+ port.lightControl.remove();
98
+ port.lightDecoration.remove();
99
+ };
100
+ const makePort = (element, host, kind) => {
101
+ const container = document.createElement('span');
102
+ container.dataset.treePort = kind;
103
+ const slot = document.createElement('slot');
104
+ slot.name = `${prefix}-${kind}-${serial}`;
105
+ container.append(slot);
106
+ element.parentElement?.append(container);
107
+ const target = document.createElement('span');
108
+ target.slot = slot.name;
109
+ target.dataset.treeSlot = kind;
110
+ target.className = kind === 'control' ? 'adecore-tree-control' : 'adecore-tree-decoration';
111
+ // React delegates to this portal target before the event reaches the engine's shadow tree.
112
+ for (const type of ['click', 'dblclick', 'keydown', 'keyup', 'pointerdown', 'dragstart']) {
113
+ target.addEventListener(type, event => event.stopPropagation());
114
+ }
115
+ host.append(target);
116
+ resize.observe(target);
117
+ return {
118
+ container,
119
+ target
120
+ };
121
+ };
122
+ const scan = () => {
123
+ pending = false;
124
+ if (disposed) {
125
+ return;
126
+ }
127
+ const current = model.getFileTreeContainer();
128
+ if (!current?.shadowRoot) {
129
+ return;
130
+ }
131
+ if (shadow !== current.shadowRoot) {
132
+ shadow = current.shadowRoot;
133
+ style = document.createElement('style');
134
+ style.dataset.adecoreTreeStyle = 'true';
135
+ style.textContent = FILE_TREE_CSS;
136
+ shadow.append(style);
137
+ changes.observe(shadow, {
138
+ childList: true,
139
+ subtree: true,
140
+ attributes: true,
141
+ attributeFilter: ['data-item-path', 'aria-selected', 'aria-expanded']
142
+ });
143
+ changes.observe(current, {
144
+ childList: true,
145
+ subtree: true
146
+ });
147
+ resize.observe(current);
148
+ }
149
+ shadow.querySelector('[role="tree"]')?.setAttribute('aria-label', label);
150
+ const elements = [...shadow.querySelectorAll('[data-type="item"]:not([data-item-parked="true"]):not([data-file-tree-sticky-row="true"])')];
151
+ const rows = mountedRows(model, shadow, elements);
152
+ const byPath = new Map(rows.map(row => [pathOfRow(row), row]));
153
+ const byIndex = new Map(rows.map(row_0 => [row_0.index, row_0]));
154
+ const live = new Set(elements);
155
+ for (const [element_0, port_0] of ports) {
156
+ if (!live.has(element_0)) {
157
+ dropPort(port_0);
158
+ ports.delete(element_0);
69
159
  }
70
- const ports = new Map();
71
- let shadow = null;
72
- let style = null;
73
- let serial = 0;
74
- let disposed = false;
75
- let pending = false;
76
- let snapshot = null;
77
- const position = () => positionPorts(ports.values());
78
- const resize = new ResizeObserver(position);
79
- const dropPort = (port) => {
80
- port.control.remove();
81
- port.decoration.remove();
82
- resize.unobserve(port.lightControl);
83
- resize.unobserve(port.lightDecoration);
84
- port.lightControl.remove();
85
- port.lightDecoration.remove();
86
- };
87
- const makePort = (element, host, kind) => {
88
- const container = document.createElement('span');
89
- container.dataset.treePort = kind;
90
- const slot = document.createElement('slot');
91
- slot.name = `${prefix}-${kind}-${serial}`;
92
- container.append(slot);
93
- element.parentElement?.append(container);
94
- const target = document.createElement('span');
95
- target.slot = slot.name;
96
- target.dataset.treeSlot = kind;
97
- target.className = kind === 'control' ? 'adecore-tree-control' : 'adecore-tree-decoration';
98
- // React delegates to this portal target before the event reaches the engine's shadow tree.
99
- for (const type of ['click', 'dblclick', 'keydown', 'keyup', 'pointerdown', 'dragstart']) {
100
- target.addEventListener(type, (event) => event.stopPropagation());
101
- }
102
- host.append(target);
103
- resize.observe(target);
104
- return { container, target };
105
- };
106
- const scan = () => {
107
- pending = false;
108
- if (disposed) {
109
- return;
110
- }
111
- const current = model.getFileTreeContainer();
112
- if (!current?.shadowRoot) {
113
- return;
114
- }
115
- if (shadow !== current.shadowRoot) {
116
- shadow = current.shadowRoot;
117
- style = document.createElement('style');
118
- style.dataset.adecoreTreeStyle = 'true';
119
- style.textContent = FILE_TREE_CSS;
120
- shadow.append(style);
121
- changes.observe(shadow, {
122
- childList: true,
123
- subtree: true,
124
- attributes: true,
125
- attributeFilter: ['data-item-path', 'aria-selected', 'aria-expanded']
126
- });
127
- changes.observe(current, { childList: true, subtree: true });
128
- resize.observe(current);
129
- }
130
- shadow.querySelector('[role="tree"]')?.setAttribute('aria-label', label);
131
- const elements = [
132
- ...shadow.querySelectorAll('[data-type="item"]:not([data-item-parked="true"]):not([data-file-tree-sticky-row="true"])')
133
- ];
134
- const rows = mountedRows(model, shadow, elements);
135
- const byPath = new Map(rows.map((row) => [pathOfRow(row), row]));
136
- const byIndex = new Map(rows.map((row) => [row.index, row]));
137
- const live = new Set(elements);
138
- for (const [element, port] of ports) {
139
- if (!live.has(element)) {
140
- dropPort(port);
141
- ports.delete(element);
142
- }
143
- }
144
- const next = [];
145
- for (const element of elements) {
146
- const path = element.dataset.itemPath;
147
- const row = path === undefined ? undefined : byPath.get(path);
148
- if (row === undefined) {
149
- continue;
150
- }
151
- element.dataset.interactive = 'true';
152
- element.dataset.joinedStart = String(row.isSelected && byIndex.get(row.index - 1)?.isSelected === true);
153
- element.dataset.joinedEnd = String(row.isSelected && byIndex.get(row.index + 1)?.isSelected === true);
154
- let port = ports.get(element);
155
- if (port === undefined) {
156
- serial++;
157
- const control = makePort(element, current, 'control');
158
- const decoration = makePort(element, current, 'decoration');
159
- port = {
160
- rowElement: element,
161
- control: control.container,
162
- decoration: decoration.container,
163
- lightControl: control.target,
164
- lightDecoration: decoration.target
165
- };
166
- ports.set(element, port);
167
- }
168
- if (port.control.dataset.itemPath !== row.path) {
169
- port.control.dataset.itemPath = row.path;
170
- }
171
- if (port.decoration.dataset.itemPath !== row.path) {
172
- port.decoration.dataset.itemPath = row.path;
173
- }
174
- port.lightControl.dataset.itemPath = row.path;
175
- port.lightDecoration.dataset.itemPath = row.path;
176
- next.push({ row, control: port.lightControl, decoration: port.lightDecoration });
177
- }
178
- const key = next
179
- .map(({ row, control }) => `${control.slot}:${row.path}:${row.isSelected}:${row.isExpanded}:${row.isFocused}:${row.name}`)
180
- .join('|');
181
- if (snapshot !== key) {
182
- snapshot = key;
183
- // Recycled rows must paint with their new portal contents in the same frame.
184
- flushSync(() => setSlots(next));
185
- }
186
- position();
187
- };
188
- const schedule = () => {
189
- if (!pending && !disposed) {
190
- pending = true;
191
- queueMicrotask(scan);
192
- }
193
- };
194
- const shifts = new MutationObserver(position);
195
- shifts.observe(frame, { attributes: true, attributeFilter: ['style'] });
196
- const changes = new MutationObserver(schedule);
197
- changes.observe(frame, { childList: true, subtree: true });
198
- const unsubscribe = model.subscribe(schedule);
199
- schedule();
200
- return () => {
201
- disposed = true;
202
- unsubscribe();
203
- changes.disconnect();
204
- shifts.disconnect();
205
- resize.disconnect();
206
- style?.remove();
207
- for (const port of ports.values()) {
208
- port.rowElement.style.removeProperty('--adecore-tree-control-space');
209
- port.rowElement.style.removeProperty('--adecore-tree-decoration-space');
210
- dropPort(port);
211
- }
212
- };
213
- }, [frame, model, label, prefix]);
214
- return slots;
215
- }
160
+ }
161
+ const next = [];
162
+ for (const element_1 of elements) {
163
+ const path = element_1.dataset.itemPath;
164
+ const row_1 = path === undefined ? undefined : byPath.get(path);
165
+ if (row_1 === undefined) {
166
+ continue;
167
+ }
168
+ element_1.dataset.interactive = 'true';
169
+ element_1.dataset.joinedStart = String(row_1.isSelected && byIndex.get(row_1.index - 1)?.isSelected === true);
170
+ element_1.dataset.joinedEnd = String(row_1.isSelected && byIndex.get(row_1.index + 1)?.isSelected === true);
171
+ let port_1 = ports.get(element_1);
172
+ if (port_1 === undefined) {
173
+ serial++;
174
+ const control = makePort(element_1, current, 'control');
175
+ const decoration = makePort(element_1, current, 'decoration');
176
+ port_1 = {
177
+ rowElement: element_1,
178
+ control: control.container,
179
+ decoration: decoration.container,
180
+ lightControl: control.target,
181
+ lightDecoration: decoration.target
182
+ };
183
+ ports.set(element_1, port_1);
184
+ }
185
+ if (port_1.control.dataset.itemPath !== row_1.path) {
186
+ port_1.control.dataset.itemPath = row_1.path;
187
+ }
188
+ if (port_1.decoration.dataset.itemPath !== row_1.path) {
189
+ port_1.decoration.dataset.itemPath = row_1.path;
190
+ }
191
+ port_1.lightControl.dataset.itemPath = row_1.path;
192
+ port_1.lightDecoration.dataset.itemPath = row_1.path;
193
+ next.push({
194
+ row: row_1,
195
+ control: port_1.lightControl,
196
+ decoration: port_1.lightDecoration
197
+ });
198
+ }
199
+ const key = next.map(({
200
+ row: row_2,
201
+ control: control_0
202
+ }) => `${control_0.slot}:${row_2.path}:${row_2.isSelected}:${row_2.isExpanded}:${row_2.isFocused}:${row_2.name}`).join('|');
203
+ if (snapshot !== key) {
204
+ snapshot = key;
205
+ // Recycled rows must paint with their new portal contents in the same frame.
206
+ flushSync(() => setSlots(next));
207
+ }
208
+ position();
209
+ };
210
+ const schedule = () => {
211
+ if (!pending && !disposed) {
212
+ pending = true;
213
+ queueMicrotask(scan);
214
+ }
215
+ };
216
+ const shifts = new MutationObserver(position);
217
+ shifts.observe(frame, {
218
+ attributes: true,
219
+ attributeFilter: ['style']
220
+ });
221
+ const changes = new MutationObserver(schedule);
222
+ changes.observe(frame, {
223
+ childList: true,
224
+ subtree: true
225
+ });
226
+ const unsubscribe = model.subscribe(schedule);
227
+ schedule();
228
+ return () => {
229
+ disposed = true;
230
+ unsubscribe();
231
+ changes.disconnect();
232
+ shifts.disconnect();
233
+ resize.disconnect();
234
+ style?.remove();
235
+ for (const port_2 of ports.values()) {
236
+ port_2.rowElement.style.removeProperty('--adecore-tree-control-space');
237
+ port_2.rowElement.style.removeProperty('--adecore-tree-decoration-space');
238
+ dropPort(port_2);
239
+ }
240
+ };
241
+ }, [frame, model, label, prefix]);
242
+ return slots;
243
+ }
package/dist/floating.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // Every popup, menu, tooltip and dialog of the library is portaled; these are the layers it draws them on.
2
2
  const FLOATING_LAYERS = '[data-base-ui-portal], .tooltip-popup, .dialog-popup, .dialog-backdrop';
3
3
  /* Whether an event landed in a popup rather than on the surface under it, which a canvas-like surface must not take as a click of its own. */
4
- export const isInFloatingLayer = (target) => target instanceof Element && target.closest(FLOATING_LAYERS) !== null;
4
+ export const isInFloatingLayer = target => target instanceof Element && target.closest(FLOATING_LAYERS) !== null;
5
5
  /* A popup is portaled out of its trigger's element but not out of React's tree, so its events still bubble to that trigger. */
6
- export const cameThroughPortal = (event) => !(event.target instanceof Node && event.currentTarget.contains(event.target));
6
+ export const cameThroughPortal = event => !(event.target instanceof Node && event.currentTarget.contains(event.target));