@allxsmith/bestax-bulma 5.46.0 → 5.47.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/esm/components/TreeView.js +5 -2
- package/dist/esm/components/TreeView.js.map +1 -1
- package/dist/esm/helpers/useTreeView.js +64 -9
- package/dist/esm/helpers/useTreeView.js.map +1 -1
- package/dist/index.cjs +68 -10
- package/dist/index.cjs.map +1 -1
- package/dist/types/components/TreeView.d.ts +2 -0
- package/dist/types/helpers/useTreeView.d.ts +19 -3
- package/dist/types-cjs/components/TreeView.d.ts +2 -0
- package/dist/types-cjs/helpers/useTreeView.d.ts +19 -3
- package/package.json +2 -1
package/dist/index.cjs
CHANGED
|
@@ -10138,6 +10138,38 @@ function parentItemOf(element) {
|
|
|
10138
10138
|
const group = element.parentElement;
|
|
10139
10139
|
return group.getAttribute('role') === 'group' ? group.parentElement : null;
|
|
10140
10140
|
}
|
|
10141
|
+
/** No positions: on the server, and until the tree has mounted. */
|
|
10142
|
+
const NO_POSITIONS = new Map();
|
|
10143
|
+
/**
|
|
10144
|
+
* Each item's place among the items beside it, by its key, read off the
|
|
10145
|
+
* items on the page: the ones in the same group, or at the top. A loading or
|
|
10146
|
+
* failed load's row counts, as it does for a browser that works positions
|
|
10147
|
+
* out for itself, so the declared ones say what a browser would.
|
|
10148
|
+
*/
|
|
10149
|
+
function positionsOf(shown, { values }) {
|
|
10150
|
+
const sets = new Map();
|
|
10151
|
+
shown.forEach(element => {
|
|
10152
|
+
const set = sets.get(element.parentElement);
|
|
10153
|
+
if (set)
|
|
10154
|
+
set.push(element);
|
|
10155
|
+
else
|
|
10156
|
+
sets.set(element.parentElement, [element]);
|
|
10157
|
+
});
|
|
10158
|
+
const positions = new Map();
|
|
10159
|
+
sets.forEach(set => set.forEach((element, at) => positions.set(values.get(element), {
|
|
10160
|
+
posinset: at + 1,
|
|
10161
|
+
setsize: set.length,
|
|
10162
|
+
})));
|
|
10163
|
+
return positions;
|
|
10164
|
+
}
|
|
10165
|
+
/** Whether two sets of positions say the same for every item. */
|
|
10166
|
+
function samePositions(a, b) {
|
|
10167
|
+
return (a.size === b.size &&
|
|
10168
|
+
Array.from(a).every(([key, { posinset, setsize }]) => {
|
|
10169
|
+
const other = b.get(key);
|
|
10170
|
+
return other?.posinset === posinset && other.setsize === setsize;
|
|
10171
|
+
}));
|
|
10172
|
+
}
|
|
10141
10173
|
/** The values of the items an item on the page is in, from the top. */
|
|
10142
10174
|
function pathOf(element, { values }) {
|
|
10143
10175
|
const path = [];
|
|
@@ -10232,9 +10264,11 @@ function useControlled(controlled, initial) {
|
|
|
10232
10264
|
return [isControlled ? controlled : own, set];
|
|
10233
10265
|
}
|
|
10234
10266
|
/**
|
|
10235
|
-
* The open state, the selection, the keys, the tab stop
|
|
10236
|
-
* a TreeView (#1096). Focus moves for real, with a roving
|
|
10237
|
-
* than through `aria-activedescendant`.
|
|
10267
|
+
* The open state, the selection, the keys, the tab stop, the positions and
|
|
10268
|
+
* the registry of a TreeView (#1096). Focus moves for real, with a roving
|
|
10269
|
+
* tabindex, rather than through `aria-activedescendant`. Each item's
|
|
10270
|
+
* position among the items beside it is declared rather than left to the
|
|
10271
|
+
* browser (#1171), read off the page once the tree has mounted.
|
|
10238
10272
|
*
|
|
10239
10273
|
* Every item registers its value, its parent and whether it's disabled from
|
|
10240
10274
|
* a layout effect. In a checkbox tree a closed item's children still render
|
|
@@ -10276,6 +10310,8 @@ function useTreeView(options) {
|
|
|
10276
10310
|
const restingPathRef = React.useRef([]);
|
|
10277
10311
|
// The values above an item that left the page with focus in it.
|
|
10278
10312
|
const lostRef = React.useRef(null);
|
|
10313
|
+
// Each item's place among the items beside it, by its key.
|
|
10314
|
+
const [positions, setPositions] = React.useState(NO_POSITIONS);
|
|
10279
10315
|
const { records } = registryRef.current;
|
|
10280
10316
|
const checks = mode === 'checkbox'
|
|
10281
10317
|
? // eslint-disable-next-line react-hooks/refs -- read in render on purpose: items write the registry from their layout effects and then ask for this render with `refresh`
|
|
@@ -10329,11 +10365,12 @@ function useTreeView(options) {
|
|
|
10329
10365
|
else
|
|
10330
10366
|
act(item, list);
|
|
10331
10367
|
};
|
|
10332
|
-
// After every render,
|
|
10333
|
-
//
|
|
10334
|
-
//
|
|
10335
|
-
//
|
|
10336
|
-
// to the first item, and focus goes
|
|
10368
|
+
// After every render, read each item's position off the page, and put the
|
|
10369
|
+
// stop where it belongs. While focus is in the tree it's the focused item.
|
|
10370
|
+
// Otherwise it's the selected item, or the first checked one on the page,
|
|
10371
|
+
// and failing that it stays where it was. An item that goes away hands it
|
|
10372
|
+
// to its nearest ancestor on the page, or to the first item, and focus goes
|
|
10373
|
+
// with it if it had focus.
|
|
10337
10374
|
// eslint-disable-next-line react-hooks/exhaustive-deps -- after every render on purpose: it reads the page, and sets state only when what it reads has changed
|
|
10338
10375
|
useClientLayoutEffect(() => {
|
|
10339
10376
|
const tree = treeRef.current;
|
|
@@ -10343,6 +10380,9 @@ function useTreeView(options) {
|
|
|
10343
10380
|
// sharing a value, which they shouldn't, can leave it without one the
|
|
10344
10381
|
// page still has.
|
|
10345
10382
|
const shown = shownIn(tree, registry);
|
|
10383
|
+
const placed = positionsOf(shown, registry);
|
|
10384
|
+
if (!samePositions(positions, placed))
|
|
10385
|
+
setPositions(placed);
|
|
10346
10386
|
const onPage = shown.map(element => registry.values.get(element));
|
|
10347
10387
|
const elementOf = (value) => shown[onPage.indexOf(value)];
|
|
10348
10388
|
const isShown = (value) => value != null && onPage.includes(value);
|
|
@@ -10364,6 +10404,20 @@ function useTreeView(options) {
|
|
|
10364
10404
|
restingPathRef.current = next ? pathOf(elementOf(next), registry) : [];
|
|
10365
10405
|
}
|
|
10366
10406
|
});
|
|
10407
|
+
// Items can also move without the tree rendering, such as children that a
|
|
10408
|
+
// component of the app sorts with state of its own. That changes no record,
|
|
10409
|
+
// so the page is watched for items coming, going and moving, and the
|
|
10410
|
+
// positions are read again.
|
|
10411
|
+
React.useEffect(() => {
|
|
10412
|
+
const tree = treeRef.current;
|
|
10413
|
+
const observer = new MutationObserver(() => {
|
|
10414
|
+
const registry = registryRef.current;
|
|
10415
|
+
const placed = positionsOf(shownIn(tree, registry), registry);
|
|
10416
|
+
setPositions(current => samePositions(current, placed) ? current : placed);
|
|
10417
|
+
});
|
|
10418
|
+
observer.observe(tree, { childList: true, subtree: true });
|
|
10419
|
+
return () => observer.disconnect();
|
|
10420
|
+
}, []);
|
|
10367
10421
|
const register = React.useCallback((value, record) => {
|
|
10368
10422
|
const { records: known } = registryRef.current;
|
|
10369
10423
|
known.set(value, record);
|
|
@@ -10486,6 +10540,7 @@ function useTreeView(options) {
|
|
|
10486
10540
|
tabStop,
|
|
10487
10541
|
isOpen,
|
|
10488
10542
|
stateOf,
|
|
10543
|
+
positionOf: key => positions.get(key),
|
|
10489
10544
|
register,
|
|
10490
10545
|
setElement,
|
|
10491
10546
|
onFocus,
|
|
@@ -11071,7 +11126,9 @@ const TreeViewItem = React.forwardRef(function TreeViewItem({ value, label, icon
|
|
|
11071
11126
|
if (branch.hidden)
|
|
11072
11127
|
return jsxRuntime.jsx(jsxRuntime.Fragment, { children: items });
|
|
11073
11128
|
const info = { value, parent, disabled, isParent, open };
|
|
11074
|
-
|
|
11129
|
+
// A position the caller gives wins, for a set the page holds only part of.
|
|
11130
|
+
const position = tree.positionOf(value);
|
|
11131
|
+
return (jsxRuntime.jsxs("li", { ...props, ref: setRefs, className: classNames(itemClass, className), role: "treeitem", "aria-labelledby": labelId, "aria-level": branch.path.length + 1, "aria-posinset": props['aria-posinset'] ?? position?.posinset, "aria-setsize": props['aria-setsize'] ?? position?.setsize, "aria-expanded": isParent ? open : undefined, "aria-disabled": disabled || undefined, "aria-selected": selected, "aria-checked": checked, tabIndex: tree.tabStop === value ? 0 : -1, onKeyDown: event => {
|
|
11075
11132
|
onKeyDown?.(event);
|
|
11076
11133
|
tree.onKeyDown(event, info);
|
|
11077
11134
|
}, onFocus: event => {
|
|
@@ -11141,7 +11198,8 @@ function StatusRow({ kind, parent, level, message, onRetry, labelRef, }) {
|
|
|
11141
11198
|
open: false,
|
|
11142
11199
|
retry,
|
|
11143
11200
|
};
|
|
11144
|
-
|
|
11201
|
+
const position = tree.positionOf(labelId);
|
|
11202
|
+
return (jsxRuntime.jsx("li", { ref: setRef, className: itemClass, role: "treeitem", "aria-labelledby": retry ? `${labelId} ${retryId}` : labelId, "aria-level": level, "aria-posinset": position?.posinset, "aria-setsize": position?.setsize, "aria-disabled": !retry || undefined, tabIndex: tree.tabStop === labelId ? 0 : -1, onKeyDown: event => tree.onKeyDown(event, info), onFocus: event => {
|
|
11145
11203
|
// Focus in something the message holds isn't the row's.
|
|
11146
11204
|
if (event.target === event.currentTarget) {
|
|
11147
11205
|
tree.onFocus(labelId, event.currentTarget);
|