@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.
- package/dist/AccentSwatches.js +290 -13
- package/dist/Banner.js +90 -9
- package/dist/Button.js +114 -22
- package/dist/ButtonGroup.js +62 -8
- package/dist/Checkbox.js +73 -4
- package/dist/ChoiceCards.js +205 -11
- package/dist/CloseButton.js +87 -7
- package/dist/ColorSwatch.js +132 -15
- package/dist/ColorWheelPicker.js +305 -71
- package/dist/ColumnResizeHandle.js +43 -8
- package/dist/DisabledReason.js +27 -8
- package/dist/DockShell.js +144 -37
- package/dist/EmptyState.js +95 -6
- package/dist/ErrorBoundary.js +254 -31
- package/dist/Field.js +349 -31
- package/dist/FileIcon.js +67 -6
- package/dist/Icon.js +38 -6
- package/dist/IconButton.js +176 -20
- package/dist/IconPicker.js +344 -73
- package/dist/Input.js +233 -14
- package/dist/Kbd.js +150 -10
- package/dist/LazyBoundary.js +14 -5
- package/dist/ListRow.js +75 -15
- package/dist/Meter.js +108 -5
- package/dist/MiddleTruncate.js +126 -45
- package/dist/PanelEmpty.js +64 -5
- package/dist/PanelHeader.js +95 -13
- package/dist/Pill.js +114 -19
- package/dist/ProjectSwitcher.js +225 -12
- package/dist/PromptDialog.js +352 -37
- package/dist/SectionLabel.js +62 -8
- package/dist/SegmentBar.js +197 -36
- package/dist/Segmented.js +130 -23
- package/dist/Select.js +310 -19
- package/dist/SelectSearch.js +344 -29
- package/dist/Separator.js +35 -4
- package/dist/ShortcutHints.js +146 -76
- package/dist/Skeleton.js +31 -4
- package/dist/Slider.js +172 -10
- package/dist/SlidingColumn.js +194 -34
- package/dist/Spinner.js +100 -3
- package/dist/Stepper.js +232 -11
- package/dist/Surface.js +62 -8
- package/dist/Switch.js +60 -6
- package/dist/TextMenu.js +212 -17
- package/dist/Tile.js +149 -5
- package/dist/Toasts.js +391 -33
- package/dist/Tooltip.js +153 -16
- package/dist/UIProvider.js +62 -15
- package/dist/Waveform.js +362 -93
- package/dist/Wipe.js +259 -34
- package/dist/ZoomControls.js +356 -14
- package/dist/class-name.js +1 -1
- package/dist/clipboard.js +15 -17
- package/dist/context-menu/index.parts.js +1 -1
- package/dist/dialog/index.parts.js +1 -1
- package/dist/dialog/parts.js +378 -29
- package/dist/dialog-layer.js +51 -18
- package/dist/error-boundary.js +19 -19
- package/dist/error-message.js +1 -1
- package/dist/field-context.js +7 -5
- package/dist/file-icon.js +23 -21
- package/dist/file-tree/helpers.js +133 -119
- package/dist/file-tree/index.parts.js +3 -3
- package/dist/file-tree/parts.js +418 -127
- package/dist/file-tree/style.js +1 -1
- package/dist/file-tree/use-file-tree-shift.js +43 -30
- package/dist/file-tree/use-file-tree.js +60 -18
- package/dist/file-tree/use-slots.js +220 -192
- package/dist/floating.js +2 -2
- package/dist/format/datetime.js +88 -38
- package/dist/format/duration.js +59 -53
- package/dist/format/index.js +1 -1
- package/dist/format/locale.js +76 -56
- package/dist/format/number.js +77 -61
- package/dist/format/regions.js +4 -2
- package/dist/format/time-zone.js +1 -1
- package/dist/icon-button-size.js +12 -2
- package/dist/icon-picker.js +70 -61
- package/dist/index.js +57 -57
- package/dist/key-value-list/index.parts.js +1 -1
- package/dist/key-value-list/parts.js +256 -22
- package/dist/lazy-landings.js +10 -10
- package/dist/lazy.js +84 -71
- package/dist/locales/en.js +80 -80
- package/dist/locales/nl.js +80 -80
- package/dist/locales.js +10 -7
- package/dist/menu/index.parts.js +1 -1
- package/dist/menu/parts.js +882 -44
- package/dist/merge-refs.js +8 -9
- package/dist/middle-truncate.js +24 -25
- package/dist/modality.js +27 -19
- package/dist/placement.js +11 -20
- package/dist/platform.js +6 -6
- package/dist/popover/index.parts.js +1 -1
- package/dist/popover/parts.js +173 -11
- package/dist/popup-layer.js +38 -17
- package/dist/prefetch.js +78 -79
- package/dist/preview-card/index.parts.js +1 -1
- package/dist/project-switcher-row.js +153 -12
- package/dist/select-row.js +69 -5
- package/dist/select-shared.js +6 -6
- package/dist/selection.js +16 -16
- package/dist/seti-icons.js +413 -413
- package/dist/settings/ConfirmDialog.js +55 -8
- package/dist/settings/DetailHeader.js +72 -4
- package/dist/settings/MasterDetail.js +119 -7
- package/dist/settings/SettingsDialog.js +820 -80
- package/dist/settings/SettingsRow.js +205 -18
- package/dist/settings/SettingsSection.js +96 -6
- package/dist/settings/index.js +7 -7
- package/dist/settings/target.js +7 -2
- package/dist/shortcut-hints.js +73 -55
- package/dist/shortcut.js +140 -104
- package/dist/step-places.js +1 -1
- package/dist/tabs/index.parts.js +1 -1
- package/dist/tabs/overflow.js +18 -18
- package/dist/tabs/parts.js +780 -166
- package/dist/testing/dedupe.js +82 -75
- package/dist/testing/fake-source.js +12 -12
- package/dist/testing/index.js +1 -1
- package/dist/toast-store.js +65 -46
- package/dist/tree/index.parts.js +1 -1
- package/dist/tree/parts.js +721 -94
- package/dist/tree/shift.js +28 -22
- package/dist/tree/style.js +2 -2
- package/dist/tree/use-tree-shift.js +178 -117
- package/dist/useAsyncAction.js +23 -19
- package/dist/useColumnResize.js +36 -34
- package/dist/useContentSize.js +62 -18
- package/dist/useMeasuredWidth.js +14 -3
- package/dist/useNow.js +73 -30
- package/dist/wipe-split.js +14 -14
- package/dist/workspace/DropPreview.js +60 -7
- package/dist/workspace/SplitView.js +1025 -441
- package/dist/workspace/TabStrip.js +810 -191
- package/dist/workspace/Workspace.js +276 -26
- package/dist/workspace/context.js +8 -3
- package/dist/workspace/geometry.js +173 -150
- package/dist/workspace/model.js +313 -250
- package/dist/workspace/preview.js +61 -61
- package/dist/zoom.js +2 -2
- package/package.json +1 -1
- package/src/ErrorBoundary.tsx +1 -1
- package/src/Field.tsx +4 -3
- package/src/IconPicker.tsx +3 -3
- package/src/LazyBoundary.tsx +2 -0
- package/src/MiddleTruncate.tsx +2 -2
- package/src/SegmentBar.tsx +2 -2
- package/src/Toasts.tsx +3 -1
- package/src/Tooltip.tsx +7 -10
- package/src/Waveform.tsx +3 -3
- package/src/file-tree/parts.tsx +6 -9
- package/src/file-tree/use-file-tree-shift.tsx +6 -9
- package/src/lazy.tsx +4 -0
- package/src/locales/en.ts +4 -4
- package/src/locales/nl.ts +5 -5
- package/src/settings/SettingsDialog.tsx +1 -1
- package/src/tree/parts.tsx +5 -8
- package/src/useContentSize.ts +3 -3
- package/src/workspace/SplitView.tsx +2 -2
- package/src/workspace/TabStrip.tsx +2 -3
- 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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
container
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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 =
|
|
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 =
|
|
6
|
+
export const cameThroughPortal = event => !(event.target instanceof Node && event.currentTarget.contains(event.target));
|