@jsenv/navi 0.29.494 → 0.29.496
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 +82 -38
- package/dist/dev/jsenv_navi.js.map +7 -7
- package/dist/jsenv_navi.js +82 -38
- package/dist/jsenv_navi.js.map +7 -7
- 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
|
/**
|
|
@@ -78988,12 +78993,14 @@ const PickerCustomResolver = props => {
|
|
|
78988
78993
|
return renderResolver(PickerNative, props);
|
|
78989
78994
|
}
|
|
78990
78995
|
if (props.mode === "callout") {
|
|
78991
|
-
// A tooltip is an icon one presses, unless told otherwise
|
|
78992
|
-
//
|
|
78993
|
-
//
|
|
78994
|
-
//
|
|
78995
|
-
if (
|
|
78996
|
+
// A tooltip is an icon one presses, unless told otherwise; "picker" asks
|
|
78997
|
+
// for the field-like drawing back. "circle" is the icon variant with the
|
|
78998
|
+
// status icon drawn round — a word about the trigger, not a drawing of its
|
|
78999
|
+
// own.
|
|
79000
|
+
if (props.variant === undefined) {
|
|
78996
79001
|
props.variant = "icon";
|
|
79002
|
+
} else if (props.variant === "picker") {
|
|
79003
|
+
props.variant = undefined;
|
|
78997
79004
|
}
|
|
78998
79005
|
const circle = props.variant === "circle";
|
|
78999
79006
|
if (circle) {
|
|
@@ -80484,11 +80491,10 @@ const PickerConfirmResolver = props => {
|
|
|
80484
80491
|
openWhileReadOnly = false
|
|
80485
80492
|
} = props;
|
|
80486
80493
|
// A button, unless told otherwise: nothing is picked here, the popup is a
|
|
80487
|
-
// question, and a question is asked by pressing something. "picker"
|
|
80488
|
-
//
|
|
80489
|
-
//
|
|
80490
|
-
|
|
80491
|
-
const variant = Object.hasOwn(props, "variant") ? props.variant === "picker" ? undefined : props.variant : "button";
|
|
80494
|
+
// question, and a question is asked by pressing something. "picker" is how a
|
|
80495
|
+
// caller asks for the field-like drawing back — a word, not an undefined, so
|
|
80496
|
+
// a wrapper forwarding `variant={variant}` keeps the button.
|
|
80497
|
+
const variant = props.variant === undefined ? "button" : props.variant === "picker" ? undefined : props.variant;
|
|
80492
80498
|
|
|
80493
80499
|
// From the picker's own input, as its press would have been: the input is
|
|
80494
80500
|
// what carries `command`/`commandFor` in the DOM, and what a form sending
|
|
@@ -92879,9 +92885,8 @@ const PickerUI = /*#__PURE__*/Object.assign(PickerDefaultUI, {
|
|
|
92879
92885
|
* not sit in — an object on a map saying
|
|
92880
92886
|
* `triggerNaviCommand(pickerEl, "--navi-open", event, { anchor, value })` —
|
|
92881
92887
|
* therefore wants an element of its own to stretch into rather than the
|
|
92882
|
-
* nearest positioned ancestor it happens to find. `"picker"`
|
|
92883
|
-
*
|
|
92884
|
-
* drawing every other picker has.
|
|
92888
|
+
* nearest positioned ancestor it happens to find. `"picker"` asks a confirm
|
|
92889
|
+
* or callout picker for the field-like drawing every other picker has.
|
|
92885
92890
|
* @param {boolean} [cta] A call to action: filled with the accent, its border
|
|
92886
92891
|
* matching, as `cta` draws a Button — for a confirm picker that is a row's
|
|
92887
92892
|
* main action.
|
|
@@ -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
|
|