@jsenv/navi 0.29.494 → 0.29.495
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/dev/jsenv_navi.js +69 -25
- package/dist/dev/jsenv_navi.js.map +4 -4
- package/dist/jsenv_navi.js +69 -25
- package/dist/jsenv_navi.js.map +4 -4
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -45384,17 +45384,22 @@ document.body.addEventListener(
|
|
|
45384
45384
|
* on screen. A registry keyed by id then holds the newcomer, and loses the
|
|
45385
45385
|
* first control when the newcomer leaves. navi renders on the client only, so
|
|
45386
45386
|
* a counter is all the uniqueness needs.
|
|
45387
|
+
*
|
|
45388
|
+
* Held in a ref, not in useState: @preact/signals' shouldComponentUpdate
|
|
45389
|
+
* skips the render of a component holding hook state whose props did not
|
|
45390
|
+
* change, so an id kept as state would change when its caller renders.
|
|
45387
45391
|
*/
|
|
45388
45392
|
|
|
45389
45393
|
|
|
45390
45394
|
let generatedIdCount = 0;
|
|
45391
45395
|
|
|
45392
45396
|
const useGeneratedId = () => {
|
|
45393
|
-
const
|
|
45397
|
+
const idRef = useRef(null);
|
|
45398
|
+
if (idRef.current === null) {
|
|
45394
45399
|
generatedIdCount++;
|
|
45395
|
-
|
|
45396
|
-
}
|
|
45397
|
-
return
|
|
45400
|
+
idRef.current = `navi_${generatedIdCount}`;
|
|
45401
|
+
}
|
|
45402
|
+
return idRef.current;
|
|
45398
45403
|
};
|
|
45399
45404
|
|
|
45400
45405
|
/**
|
|
@@ -96709,12 +96714,18 @@ const buildMatchInfo = (searchText, items, matchFn) => {
|
|
|
96709
96714
|
* needed. `data.role === "presentation"` keeps it out entirely.
|
|
96710
96715
|
* Returns the visible rank (position among visible items), or -1 when hidden
|
|
96711
96716
|
* or filtered.
|
|
96717
|
+
* An item rendered without an index keeps the position it has, and a new one
|
|
96718
|
+
* goes last: for a host that cannot know the order at render and gives it
|
|
96719
|
+
* afterwards with setOrder.
|
|
96712
96720
|
* Signals and onChange are deferred to a microtask so multiple items updating
|
|
96713
96721
|
* in one commit cause only one notification.
|
|
96714
96722
|
*
|
|
96715
96723
|
* getTrackedItemByIndex(index): synchronous O(1) lookup of a visible item by
|
|
96716
96724
|
* its visible rank. Returns undefined when index is out of range.
|
|
96717
96725
|
*
|
|
96726
|
+
* setOrder(ids): gives each tracked item its position from its rank in
|
|
96727
|
+
* `ids`.
|
|
96728
|
+
*
|
|
96718
96729
|
* peekItems(): the items as they stand right now, without waiting for the
|
|
96719
96730
|
* deferred notification — what a sibling rendering after the items must read
|
|
96720
96731
|
* to paint them in the same commit.
|
|
@@ -96995,8 +97006,14 @@ const createItemTracker = (onChange) => {
|
|
|
96995
97006
|
// that determines this item's position among siblings.
|
|
96996
97007
|
// Returns the item's visible rank among non-hidden items, or -1 when hidden.
|
|
96997
97008
|
const useTrackItem = (data) => {
|
|
96998
|
-
const { id
|
|
97009
|
+
const { id } = data;
|
|
96999
97010
|
const key = keyForId(id);
|
|
97011
|
+
let { index } = data;
|
|
97012
|
+
if (index === undefined) {
|
|
97013
|
+
index = keyToExplicitOrder.has(key)
|
|
97014
|
+
? keyToExplicitOrder.get(key)
|
|
97015
|
+
: Infinity;
|
|
97016
|
+
}
|
|
97000
97017
|
|
|
97001
97018
|
syncItem(key, index, data);
|
|
97002
97019
|
notify();
|
|
@@ -97014,6 +97031,24 @@ const createItemTracker = (onChange) => {
|
|
|
97014
97031
|
return keyToOrderedIndex.get(key) ?? -1;
|
|
97015
97032
|
};
|
|
97016
97033
|
|
|
97034
|
+
const setOrder = (ids) => {
|
|
97035
|
+
let changed = false;
|
|
97036
|
+
for (let i = 0; i < ids.length; i++) {
|
|
97037
|
+
const key = idToKey.get(ids[i]);
|
|
97038
|
+
if (key === undefined || !allRegistrations.has(key)) {
|
|
97039
|
+
continue;
|
|
97040
|
+
}
|
|
97041
|
+
if (keyToExplicitOrder.get(key) === i) {
|
|
97042
|
+
continue;
|
|
97043
|
+
}
|
|
97044
|
+
syncItem(key, i, allRegistrations.get(key));
|
|
97045
|
+
changed = true;
|
|
97046
|
+
}
|
|
97047
|
+
if (changed) {
|
|
97048
|
+
notify();
|
|
97049
|
+
}
|
|
97050
|
+
};
|
|
97051
|
+
|
|
97017
97052
|
const getTrackedItemByIndex = (index) => {
|
|
97018
97053
|
const key = orderedKeys[index];
|
|
97019
97054
|
if (key === undefined) {
|
|
@@ -97047,6 +97082,7 @@ const createItemTracker = (onChange) => {
|
|
|
97047
97082
|
return {
|
|
97048
97083
|
useTrackItem,
|
|
97049
97084
|
getTrackedItemByIndex,
|
|
97085
|
+
setOrder,
|
|
97050
97086
|
peekItems,
|
|
97051
97087
|
itemsSignal,
|
|
97052
97088
|
visibleItemsSignal,
|
|
@@ -97444,8 +97480,8 @@ const getNumericRange = items => {
|
|
|
97444
97480
|
|
|
97445
97481
|
// Wheel.Item registers its {value, label} here so WheelUI knows the full ordered
|
|
97446
97482
|
// list of items regardless of how children are wrapped (providers, fragments…).
|
|
97447
|
-
//
|
|
97448
|
-
//
|
|
97483
|
+
// The position comes after the commit, from the marker each item leaves where it
|
|
97484
|
+
// stands (see WheelUI).
|
|
97449
97485
|
const WheelItemTrackerContext = createContext(null);
|
|
97450
97486
|
|
|
97451
97487
|
// Lets a WheelGroup push shared presentation (glass, orientation) down to every
|
|
@@ -98067,15 +98103,21 @@ function WheelUI(props) {
|
|
|
98067
98103
|
// (children may be wrapped). This ordered list is the source of truth for the
|
|
98068
98104
|
// whole wheel — the rendered rows are a small recycled window over it.
|
|
98069
98105
|
const tracker = useItemTracker();
|
|
98070
|
-
|
|
98071
|
-
|
|
98072
|
-
|
|
98073
|
-
|
|
98074
|
-
|
|
98075
|
-
|
|
98076
|
-
|
|
98077
|
-
|
|
98078
|
-
|
|
98106
|
+
// The order is read from the markers the items leave in the DOM, not from the
|
|
98107
|
+
// order they render in: an item whose props did not change may skip a render
|
|
98108
|
+
// (signals' shouldComponentUpdate), and a render count would then rank the
|
|
98109
|
+
// ones that did render first.
|
|
98110
|
+
useLayoutEffect(() => {
|
|
98111
|
+
const el = ref.current;
|
|
98112
|
+
if (!el) {
|
|
98113
|
+
return;
|
|
98114
|
+
}
|
|
98115
|
+
const ids = [];
|
|
98116
|
+
for (const marker of el.querySelectorAll("[data-navi-wheel-item]")) {
|
|
98117
|
+
ids.push(marker.getAttribute("data-navi-wheel-item"));
|
|
98118
|
+
}
|
|
98119
|
+
tracker.setOrder(ids);
|
|
98120
|
+
});
|
|
98079
98121
|
const trackedItems = tracker.itemsSignal.value;
|
|
98080
98122
|
const trackedItemsRef = useRef(trackedItems);
|
|
98081
98123
|
trackedItemsRef.current = trackedItems;
|
|
@@ -98875,7 +98917,7 @@ function WheelUI(props) {
|
|
|
98875
98917
|
className: "navi_wheel_pane",
|
|
98876
98918
|
"data-side": "start"
|
|
98877
98919
|
}), jsx(WheelItemTrackerContext.Provider, {
|
|
98878
|
-
value:
|
|
98920
|
+
value: tracker,
|
|
98879
98921
|
children: jsx(ControlFacadeChildrenWrapper, {
|
|
98880
98922
|
facadeController: facadeController,
|
|
98881
98923
|
children: children
|
|
@@ -98988,9 +99030,10 @@ const WheelWindow = ({
|
|
|
98988
99030
|
* Wheel.Item — a value in a Wheel. Must be used inside <Wheel>.
|
|
98989
99031
|
*
|
|
98990
99032
|
* Registration only: it records its {value, label, itemProps} with the wheel and
|
|
98991
|
-
* renders
|
|
98992
|
-
*
|
|
98993
|
-
*
|
|
99033
|
+
* renders no row, only a hidden marker the wheel reads its position from. The
|
|
99034
|
+
* wheel is virtualized — it renders a small recycled window of rows and fills
|
|
99035
|
+
* each from this tracked data — so the value list is the source of truth, not a
|
|
99036
|
+
* per-item DOM node. Selection lives on the wheel's value.
|
|
98994
99037
|
*
|
|
98995
99038
|
* @type {import("preact").FunctionComponent<{
|
|
98996
99039
|
* value: any,
|
|
@@ -99007,16 +99050,17 @@ const WheelItem = ({
|
|
|
99007
99050
|
const idDefault = useGeneratedId();
|
|
99008
99051
|
const resolvedId = id || idDefault;
|
|
99009
99052
|
// Wheel.Item must live inside a Wheel, so the context is always present.
|
|
99010
|
-
const
|
|
99011
|
-
|
|
99012
|
-
trackerContext.tracker.useTrackItem({
|
|
99053
|
+
const tracker = useContext(WheelItemTrackerContext);
|
|
99054
|
+
tracker.useTrackItem({
|
|
99013
99055
|
id: resolvedId,
|
|
99014
|
-
index,
|
|
99015
99056
|
value,
|
|
99016
99057
|
label: children,
|
|
99017
99058
|
itemProps: rest
|
|
99018
99059
|
});
|
|
99019
|
-
return
|
|
99060
|
+
return jsx("span", {
|
|
99061
|
+
hidden: true,
|
|
99062
|
+
"data-navi-wheel-item": resolvedId
|
|
99063
|
+
});
|
|
99020
99064
|
};
|
|
99021
99065
|
Wheel.Item = WheelItem;
|
|
99022
99066
|
|