@jsenv/navi 0.29.493 → 0.29.494

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.
@@ -6,7 +6,7 @@ import { installImportMetaCssBuild, coarsePointerSignal, windowHeightSignal, win
6
6
  import { createPubSub, createIterableWeakSet, elementIsFocusable, getScrollContainer, dispatchInternalCustomEvent, dispatchCustomEvent, createEventGroupLogger, findEvent, mergeOneStyle, findFocusable, getElementSignature, chainEvent, isTouchDrivenEvent, getKeyboardEventDefaultAction, isPressDrivenClick, getVisuallyVisibleInfo, getFirstVisuallyVisibleAncestor, createValueEffect, findFocusDelegateTarget, scrollIntoViewThroughScrollables, allowWheelThrough, dispatchPublicCustomEvent, resolveCSSColor, getScrollContainerSet, ELEMENT_SIZE_CHANGE, findSelfOrAncestorFixedPosition, visibleRectEffect, pickPositionRelativeTo, getBorderSizes, getPaddingSizes, applyNewPosition, measureLongestVisualLineWidth, keepTouchRefusable, waitForTap, waitForPressHeld, suppressClickAfterGesture, startDragToTravel, dragSourceThatStoodDown, markDragSource, refuseDragTo, startDragTo, installPanZoom, createInternalCustomEvent, activeElementSignal, normalizeStyle, getPositionedParent, normalizeStyles, createGroupTransitionController, getBorderRadius, preventIntermediateScrollbar, createOpacityTransition, watchWheelTravel, scrollRoomTowards, trapScrollInside, scrollIntoViewScoped, isPressDisputedByDrag, closestOpenableAncestor, isAncestorOpen, isDisplayedDespiteClosedAncestor, observeAncestorOpenState, getAncestorOpenType, findBefore, findAfter, resolveCSSSize, hasCSSSizeUnit, releaseWheelGesture, getScrollIntoViewScopedOffsets, wheelGestureIsTakenFrom, claimWheelGesture, initFocusGroup, stringifyStyle as stringifyStyle$1, isScrollable, resolveOklchLightness, contrastColor, overflowGoesToViewport, parsePositionArea, snapToPixel, trapFocusInside, getVirtualKeyboardOverlayHeight, onAncestorReopen, canScroll, measureWidestChildRow, performTabNavigation, dragAfterIntent, stickyAsRelativeCoords, createDragToMoveGestureController, getDropTargetInfo, setStyles, useActiveElement, setVirtualKeyboardOverlaysContent, subscribeVirtualKeyboardGeometryChange } from "@jsenv/dom";
7
7
  export { chainEvent, clickIsSuppressed, contrastColor, createDragGestureController, dragAfterIntent, findEvent, markDragSource, startDragTo } from "@jsenv/dom";
8
8
  import { signal, computed, effect, untracked, batch, useComputed, useSignal } from "@preact/signals";
9
- import { useState, useLayoutEffect, useErrorBoundary, useContext, useMemo, useRef, useEffect, useReducer, useCallback, useId } from "preact/hooks";
9
+ import { useState, useLayoutEffect, useErrorBoundary, useContext, useMemo, useRef, useEffect, useReducer, useCallback } from "preact/hooks";
10
10
  import { options, isValidElement, createContext, render as render$1, h, toChildArray, createRef, cloneElement, createElement, Fragment as Fragment$1 } from "preact";
11
11
  import { humanizeI18n, prefixFirstAndIndentRemainingLines, setRuntimeLangSource, formatDuration, formatMonth, formatDay, resolveTimeRangePrecision, formatDatePlaceholder, toDate, getRelativeDay, formatDayRelative, formatMonthPlaceholder, formatWeekPlaceholder, formatDatetimePlaceholder, formatDatetime, toTimeOfDay, formatTimeOfDay, formatMinuteDuration, formatTime, formatSecondDuration, formatHourDuration, formatTimeRelative, pluralCategory, formatNumber, interpolateText, installInterpolateJsx } from "@jsenv/humanize";
12
12
  export { createI18n, formatByteSize, formatDatetime, formatDay, formatDayRelative, formatDuration, formatHourDuration, formatList, formatMinuteDuration, formatMonth, formatNumber, formatSecondDuration, formatTime, formatTimeOfDay, formatTimeRange, formatTimeRelative, interpolateText, pluralCategory } from "@jsenv/humanize";
@@ -14058,13 +14058,13 @@ const writePressWritesHere = (pressWrites) => {
14058
14058
  }
14059
14059
  };
14060
14060
 
14061
- // Preact's own useId() (see preact/hooks) returns "P<mask0>-<mask1>", where the
14062
- // mask is derived from render order within the nearest root/async boundary:
14063
- // stable across re-renders of the same mount, but not across two mounts on the
14064
- // same page, and not across two documents.
14065
- const PREACT_GENERATED_ID_REGEX = /^P\d+-\d+/;
14066
- const isLikelyPreactGeneratedId = (id) => {
14067
- return PREACT_GENERATED_ID_REGEX.test(id);
14061
+ // An id made up at render names one mount: navi's own ("navi_<n>", see
14062
+ // useGeneratedId) counts mounts in the document, and preact's useId(), which
14063
+ // an app may hand a component, gives "P<mask0>-<mask1>" from the render order.
14064
+ // Neither names the same component in two mounts or two documents.
14065
+ const GENERATED_ID_REGEX = /^(?:navi_\d+|P\d+-\d+)/;
14066
+ const isGeneratedId = (id) => {
14067
+ return GENERATED_ID_REGEX.test(id);
14068
14068
  };
14069
14069
 
14070
14070
  /**
@@ -14088,7 +14088,7 @@ const dropGeneratedIdKeys = (state) => {
14088
14088
  }
14089
14089
  let stateWithoutGeneratedIdKeys = state;
14090
14090
  for (const key of Object.keys(state)) {
14091
- if (!isLikelyPreactGeneratedId(key)) {
14091
+ if (!isGeneratedId(key)) {
14092
14092
  continue;
14093
14093
  }
14094
14094
  if (stateWithoutGeneratedIdKeys === state) {
@@ -15393,7 +15393,7 @@ Consider using unique IDs for each component instance.`,
15393
15393
  return useNavStateBasic(id, options);
15394
15394
  };
15395
15395
 
15396
- // A generated id (preact's useId()) names one mount. State written under one
15396
+ // A generated id (see isGeneratedId) names one mount. State written under one
15397
15397
  // outlives that mount in the history entry — a page left with a popup open —
15398
15398
  // and the mount coming back to the entry generates another id: the state is
15399
15399
  // there, and nothing reads it. Reported when a component mounting on the entry
@@ -15419,7 +15419,7 @@ const warnAboutOrphanGeneratedKeys = () => {
15419
15419
  }
15420
15420
  for (const key of Object.keys(state)) {
15421
15421
  if (
15422
- !isLikelyPreactGeneratedId(key) ||
15422
+ !isGeneratedId(key) ||
15423
15423
  idUsageMap.has(key) ||
15424
15424
  orphanKeysReported.has(key)
15425
15425
  ) {
@@ -15427,7 +15427,7 @@ const warnAboutOrphanGeneratedKeys = () => {
15427
15427
  }
15428
15428
  orphanKeysReported.add(key);
15429
15429
  console.warn(
15430
- `useNavState: this history entry holds "${key}", written by a component whose id was generated (preact's useId()) and that is not mounted anymore — a Picker without an id, a popup with navState and no id. A generated id names one mount, so nothing will read that state again: a popup open when this screen was left comes back closed. Give the component a stable id if it was meant to be found as it was.`,
15430
+ `useNavState: this history entry holds "${key}", written by a component whose id was generated and that is not mounted anymore — a Picker without an id, a popup with navState and no id. A generated id names one mount, so nothing will read that state again: a popup open when this screen was left comes back closed. Give the component a stable id if it was meant to be found as it was.`,
15431
15431
  );
15432
15432
  }
15433
15433
  };
@@ -15515,13 +15515,13 @@ const useNavStateBasic = (
15515
15515
 
15516
15516
  let effectiveType = type;
15517
15517
  // A push bakes the key into a history entry of its own, and an id naming a
15518
- // render position (see isLikelyPreactGeneratedId) can be claimed by two
15518
+ // render position (see isGeneratedId) can be claimed by two
15519
15519
  // mounts of this same page. A replace keeps the key on the entry the document
15520
15520
  // is already on, where the id at least names one render.
15521
- if (type === "push" && isLikelyPreactGeneratedId(id)) {
15521
+ if (type === "push" && isGeneratedId(id)) {
15522
15522
  {
15523
15523
  console.warn(
15524
- `useNavState(${id}): this id looks auto-generated (e.g. preact's useId()) and type is "push" — falling back to "replace". A push history entry keyed by an unstable id won't survive a reload correctly, and could even collide with a different component's own auto-generated id. Pass a stable, explicit id to use type: "push".`,
15524
+ `useNavState(${id}): this id looks auto-generated and type is "push" — falling back to "replace". A push history entry keyed by an unstable id won't survive a reload correctly, and could even collide with a different component's own auto-generated id. Pass a stable, explicit id to use type: "push".`,
15525
15525
  );
15526
15526
  }
15527
15527
  effectiveType = "replace";
@@ -15639,7 +15639,7 @@ const useNavStateBasic = (
15639
15639
  * - "push": creates a new history entry — pressing the back button removes it and calls onLeave.
15640
15640
  * - "replace": updates the current history entry — no extra history entry is created.
15641
15641
  * Silently downgraded to "replace" (with a dev-only console.warn) when `id`
15642
- * looks auto-generated (e.g. preact's own useId()) — an unstable id baked
15642
+ * looks auto-generated (navi's own, or preact's useId()) — an unstable id baked
15643
15643
  * into a pushed history entry won't survive a reload correctly, and could
15644
15644
  * even collide with a different component's own auto-generated id. Pass a
15645
15645
  * stable, explicit id to actually get "push" behavior.
@@ -30792,7 +30792,8 @@ ${name}.many("${propertyName}") source location: ${declarationSite}`,
30792
30792
  * - `DELETE: async ({ id }) => [id, null]`
30793
30793
  *
30794
30794
  * `ownerId` may also be `{ [uniqueKey]: value }` when the owner is known by an alternate key.
30795
- * The property is `null` until a callback provides data; setting it to `null` clears it.
30795
+ * The property is `undefined` until an answer speaks for the owner (its row, or a
30796
+ * callback), `null` when that answer holds none; setting it to `null` clears it.
30796
30797
  * Mutations apply directly to the owner's signal, so the parent GET is never rerun; an
30797
30798
  * owner the store does not hold yet is left alone, its child comes with its next read.
30798
30799
  *
@@ -30851,7 +30852,10 @@ ${name}.many("${propertyName}") source location: ${declarationSite}`,
30851
30852
  for (const childSetup of childSetupCallbackSet) {
30852
30853
  childSetup(childItem);
30853
30854
  }
30854
- const childSignal = signal(null);
30855
+ // `undefined` until something answers for this owner, `null` once an
30856
+ // answer says it holds none: a screen tells « not read yet » from
30857
+ // « nothing » as it does with an action's data.
30858
+ const childSignal = signal(undefined);
30855
30859
  // The child keeps its identity while its props change, so the owner's
30856
30860
  // getter also reads this version, bumped by each change in place:
30857
30861
  // whichever way the props came in — the owner's row, a write of this
@@ -30860,7 +30864,10 @@ ${name}.many("${propertyName}") source location: ${declarationSite}`,
30860
30864
  // Returns whether the child changed — what the store asks a relation
30861
30865
  // (see assign in array_signal_store.js).
30862
30866
  const applyProps = (props) => {
30863
- if (!props) {
30867
+ if (props === undefined) {
30868
+ return false;
30869
+ }
30870
+ if (props === null) {
30864
30871
  if (childSignal.peek() === null) {
30865
30872
  return false;
30866
30873
  }
@@ -30882,7 +30889,7 @@ ${name}.many("${propertyName}") source location: ${declarationSite}`,
30882
30889
  }
30883
30890
  }
30884
30891
  if (childSignal.peek() !== childItem) {
30885
- childSignal.value = childItem; // first activation: null → childItem
30892
+ childSignal.value = childItem; // first activation
30886
30893
  return true;
30887
30894
  }
30888
30895
  if (changed) {
@@ -34777,7 +34784,12 @@ const Box = props => {
34777
34784
  mount,
34778
34785
  ...computeProps
34779
34786
  } = props;
34780
- const parentBoxFlow = useContext(BoxFlowContext);
34787
+ // The flow of the nearest Box above in the component tree, which lays this
34788
+ // box out unless a plain element sits between the two in the DOM: the box
34789
+ // then reads that element's flow once mounted (see readDomParentFlow).
34790
+ const contextBoxFlow = useContext(BoxFlowContext);
34791
+ const [domParentFlow, setDomParentFlow] = useState(null);
34792
+ const parentBoxFlow = domParentFlow && domParentFlow.contextBoxFlow === contextBoxFlow ? domParentFlow.flow : contextBoxFlow;
34781
34793
  // Which interactions this box answers, and with what. Read here rather than
34782
34794
  // on the control, so a swipe or a hold can be declared on anything — a row, a
34783
34795
  // card, a block of text — and reach the control it belongs to (which is what
@@ -34824,7 +34836,17 @@ const Box = props => {
34824
34836
  childForwardedProps,
34825
34837
  styleDeps
34826
34838
  } = computed;
34827
- const syncBox = useCallback(computed.syncBox, styleDeps);
34839
+ const verifyParentFlow = parentBoxFlow === contextBoxFlow && FLOW_STYLING_ITS_CHILDREN_SET.has(contextBoxFlow) && readsParentFlow(computeProps);
34840
+ const syncBox = useCallback(verifyParentFlow ? boxEl => {
34841
+ const flow = readDomParentFlow(boxEl);
34842
+ if (flow !== contextBoxFlow) {
34843
+ setDomParentFlow({
34844
+ contextBoxFlow,
34845
+ flow
34846
+ });
34847
+ }
34848
+ return computed.syncBox(boxEl);
34849
+ } : computed.syncBox, styleDeps);
34828
34850
  const finalRef = useComposeElementRef(syncBox, ref);
34829
34851
  useInteractionsEffect(finalRef, interactionsRef);
34830
34852
  let innerChildren = children;
@@ -35137,6 +35159,13 @@ const computeBox = (props, parentBoxFlow) => {
35137
35159
  const mergedValue = prepareStyleValue(stylesTarget[name], value, name, styleContext);
35138
35160
  const cssVar = readCSSVarName(styleContext.styleCSSVars[name]);
35139
35161
  if (cssVar) {
35162
+ if (name === "color" && value === "inherit") {
35163
+ // A token set to `inherit` takes the token of the parent element
35164
+ // (a list's white for its selected items), never the parent's color.
35165
+ // `color: currentColor` IS `color: inherit`, and a token carries it.
35166
+ addCSSVar("currentColor", cssVar, stylesTarget);
35167
+ return true;
35168
+ }
35140
35169
  addCSSVar(mergedValue, cssVar, stylesTarget);
35141
35170
  if (name === "borderRadius" && value === "inherit") {
35142
35171
  // "inherit" cannot be expressed via a CSS variable — a var() reference
@@ -35453,6 +35482,47 @@ const declaresSomething = value => {
35453
35482
  }
35454
35483
  return true;
35455
35484
  };
35485
+ // The flows the styles of a child branch on (see expandX, selfAlignX… in
35486
+ // box_style_util.js): under any other the child writes the same styles
35487
+ // whatever its parent is.
35488
+ const FLOW_STYLING_ITS_CHILDREN_SET = new Set(["flex-x", "flex-y", "inline-flex-x", "inline-flex-y", "grid", "inline-grid"]);
35489
+ const PARENT_FLOW_PROP_NAMES = ["expand", "expandX", "expandY", "selfAlignX", "selfAlignY"];
35490
+ const readsParentFlow = props => {
35491
+ for (const name of PARENT_FLOW_PROP_NAMES) {
35492
+ if (props[name]) {
35493
+ return true;
35494
+ }
35495
+ }
35496
+ return false;
35497
+ };
35498
+ // A Box parent says its flow on its element; a plain element is read from its
35499
+ // computed style, which only a box mounted under one pays for.
35500
+ const readDomParentFlow = boxEl => {
35501
+ let parent = boxEl.parentElement;
35502
+ while (parent) {
35503
+ const flowAttribute = parent.getAttribute("navi-box-flow");
35504
+ if (flowAttribute) {
35505
+ return flowAttribute;
35506
+ }
35507
+ const {
35508
+ display,
35509
+ flexDirection
35510
+ } = window.getComputedStyle(parent);
35511
+ if (display === "contents") {
35512
+ parent = parent.parentElement;
35513
+ continue;
35514
+ }
35515
+ if (display === "flex" || display === "inline-flex") {
35516
+ const axis = flexDirection.startsWith("column") ? "y" : "x";
35517
+ return `${display}-${axis}`;
35518
+ }
35519
+ if (display === "grid" || display === "inline-grid") {
35520
+ return display;
35521
+ }
35522
+ return "block";
35523
+ }
35524
+ return undefined;
35525
+ };
35456
35526
  const isScrollingOverflow = value => value === "auto" || value === "scroll";
35457
35527
  const mayHoldComponent = children => {
35458
35528
  if (children === null || children === undefined) {
@@ -61334,7 +61404,7 @@ const Expandable = props => {
61334
61404
  const rootRef = ref || defaultRef;
61335
61405
  const uiRef = useRef();
61336
61406
  const contentContainerRef = useRef();
61337
- const contentId = useId();
61407
+ const contentId = useGeneratedId();
61338
61408
  const isColumn = layout === "column";
61339
61409
  const closedContentSized = isColumn && mount === "always";
61340
61410
  // Only the two directions the layout has room for: a column layout reveals
@@ -62974,7 +63044,7 @@ const ButtonConfirm = ({
62974
63044
  // it is elsewhere by then, and pulling it back would take it from whatever
62975
63045
  // the person moved to.
62976
63046
  const restoreFocusRef = useRef(false);
62977
- const questionId = `${useId()}_question`;
63047
+ const questionId = `${useGeneratedId()}_question`;
62978
63048
  const cancel = restoreFocus => {
62979
63049
  restoreFocusRef.current = restoreFocus;
62980
63050
  setAsking(false);
@@ -63776,7 +63846,7 @@ const ControlSwap = props => {
63776
63846
  const activeSide = sides[activeIndex];
63777
63847
  const capRefs = [useRef(), useRef()];
63778
63848
  const slotRefs = [useRef(), useRef()];
63779
- const slotIdPrefix = useId();
63849
+ const slotIdPrefix = useGeneratedId();
63780
63850
  const activeNameRef = useRef(floor.name);
63781
63851
  activeNameRef.current = activeSide.name;
63782
63852
  const swapTo = (name, event, pressedCapIndex = null) => {
@@ -64637,7 +64707,7 @@ const InputCheckboxFieldInterface = props => {
64637
64707
  // setting's name — which are its label and its accessible name: a mode one
64638
64708
  // toggles is a checkbox, not a button writing a signal on each press.
64639
64709
  const hasLabel = variant === "button" && children !== undefined && children !== null && children !== false;
64640
- const labelId = useId();
64710
+ const labelId = useGeneratedId();
64641
64711
  const boxRef = useRef();
64642
64712
  useAccentColorAttributes(boxRef, accentColor, {
64643
64713
  elementSelector: ".navi_checkbox_accent_probe"
@@ -75878,7 +75948,7 @@ const PopupTitleContext = createContext(null);
75878
75948
  const PopupTitle = props => {
75879
75949
  import.meta.css = [css$E, "@jsenv/navi/src/layout/popup_title.jsx"];
75880
75950
  const registerTitle = useContext(PopupTitleContext);
75881
- const idDefault = useId();
75951
+ const idDefault = useGeneratedId();
75882
75952
  const id = props.id || `popup_title_${idDefault}`;
75883
75953
  useLayoutEffect(() => {
75884
75954
  if (!registerTitle) {
@@ -79274,7 +79344,7 @@ const usePopoverProps = props => {
79274
79344
  // open, two separate invocations of openEffect that don't otherwise share
79275
79345
  // any scope, hence the ref.
79276
79346
  const disarmBackdropHideRef = useRef(null);
79277
- const defaultId = useId();
79347
+ const defaultId = useGeneratedId();
79278
79348
  const id = rest.id || defaultId;
79279
79349
  const backdropId = `${id}-backdrop`;
79280
79350
  const debugPopup = useDebugPopup();
@@ -80877,10 +80947,10 @@ const PickerCustom = props => {
80877
80947
  // before computing popupId below, so two Pickers without an explicit id never collide.
80878
80948
  // Captured before the fallback chain below overwrites props.id — needed to
80879
80949
  // know whether the id actually came from the caller (stable) or from
80880
- // useId()/ControlIdContext (a generated id names one mount: a reload, or a
80950
+ // useGeneratedId()/ControlIdContext (a generated id names one mount: a reload, or a
80881
80951
  // return to this page, generates another), see pickerNavType below.
80882
80952
  const hasExplicitId = Boolean(props.id);
80883
- const idDefault = useId();
80953
+ const idDefault = useGeneratedId();
80884
80954
  const controlId = useContext(ControlIdContext);
80885
80955
  props.id = props.id || controlId || idDefault;
80886
80956
  // Given no value, the picker holds what the control in its popup holds (see
@@ -80982,7 +81052,7 @@ const PickerCustom = props => {
80982
81052
  const debugPopup = useDebugPopup();
80983
81053
  // In "dialog" mode with a stable, caller-provided id, enterExpanded()
80984
81054
  // pushes a history entry so the back button closes it. Every other case
80985
- // (popover mode, or a dialog whose id was auto-generated via useId()/
81055
+ // (popover mode, or a dialog whose id was auto-generated via useGeneratedId()/
80986
81056
  // ControlIdContext) replaces the current history state instead — a
80987
81057
  // generated id names one mount, so pushing it would either leave an entry
80988
81058
  // nothing reads or, worse, collide with a different component's own
@@ -83875,7 +83945,7 @@ const ListSelectable = props => {
83875
83945
  const Next = useNextResolver();
83876
83946
  import.meta.css = [css$x, "@jsenv/navi/src/control/list/list_selectable.jsx"];
83877
83947
  // we allow ourselves to auto-generate a name
83878
- const defaultName = useId();
83948
+ const defaultName = useGeneratedId();
83879
83949
  props.name = props.name || `listbox_${defaultName}`;
83880
83950
  const {
83881
83951
  ref,
@@ -84224,7 +84294,7 @@ const ListItemSelectableResolver = props => {
84224
84294
  };
84225
84295
  const ListItemSelectable = props => {
84226
84296
  const Next = useNextResolver();
84227
- const defaultId = useId();
84297
+ const defaultId = useGeneratedId();
84228
84298
  // Whether the caller SAYS anything about this row's selection. Passing
84229
84299
  // `checked: undefined` is not the same as not passing it: a control with the
84230
84300
  // key present calls itself controlled, and a controlled row is one the list
@@ -85214,7 +85284,7 @@ const ListUI = props => {
85214
85284
  } = props;
85215
85285
  // Remembered by name, and a name made up at render (see ListFirstResolver)
85216
85286
  // names no list a later mount would recognize.
85217
- const rememberScroll = !scrollResetOnNavigation && !isLikelyPreactGeneratedId(rest.id);
85287
+ const rememberScroll = !scrollResetOnNavigation && !isGeneratedId(rest.id);
85218
85288
  // Where the list was when its screen was left, when this is the way back
85219
85289
  // (see scroll_restoration.js). Read once: `defaultScrolled` is held by
85220
85290
  // reference, and a place read again each render would be a list moved each
@@ -85524,7 +85594,7 @@ const ListFirstResolver = props => {
85524
85594
  const Next = useNextResolver();
85525
85595
  const refDefault = useRef(null);
85526
85596
  props.ref = props.ref || refDefault;
85527
- const idDefault = useId();
85597
+ const idDefault = useGeneratedId();
85528
85598
  props.id = props.id || idDefault;
85529
85599
  const listItemsRef = useRef(null);
85530
85600
  if (!listItemsRef.current) {
@@ -89117,7 +89187,7 @@ const ListItemUI = props => {
89117
89187
  if (identityMatters && props.id === undefined) {
89118
89188
  console.warn("ListItem is missing an explicit id prop. Provide a stable id so pointed/selected state survives search reordering.");
89119
89189
  }
89120
- const idDefault = useId();
89190
+ const idDefault = useGeneratedId();
89121
89191
  props.id = props.id || idDefault;
89122
89192
  const listItems = useContext(ListItemsContext);
89123
89193
  const groupId = useContext(ListGroupContext);
@@ -89933,7 +90003,7 @@ const useRunItems = (store, {
89933
90003
  renderSkeleton,
89934
90004
  renderError
89935
90005
  }) => {
89936
- const ownerId = useId();
90006
+ const ownerId = useGeneratedId();
89937
90007
  // Dev only: the group `groupOfMissing` put an item not held in, by rank,
89938
90008
  // checked against `groupBy` once the item lands.
89939
90009
  const missingGroupCheckRef = useRef(null);
@@ -90502,7 +90572,7 @@ const ListRunSkeletonItem = ({
90502
90572
  }) => {
90503
90573
  const listItems = useContext(ListItemsContext);
90504
90574
  const groupId = useContext(ListGroupContext);
90505
- const entryId = useId();
90575
+ const entryId = useGeneratedId();
90506
90576
  listItems.draw(entryId, {
90507
90577
  ownerId: runItem.ownerId,
90508
90578
  place: runItem.index,
@@ -91243,7 +91313,7 @@ const ListItemGroup = ({
91243
91313
  children,
91244
91314
  ...rest
91245
91315
  }) => {
91246
- const groupId = useId();
91316
+ const groupId = useGeneratedId();
91247
91317
  const listItems = useContext(ListItemsContext);
91248
91318
  const group = listItems.group(groupId);
91249
91319
  useLayoutEffect(() => {
@@ -95587,7 +95657,7 @@ const Spin = ({
95587
95657
  } else {
95588
95658
  compareValues ??= compareValuesDefault;
95589
95659
  }
95590
- const id = useId();
95660
+ const id = useGeneratedId();
95591
95661
  // What the group around it says, when there is one: how big the whole thing
95592
95662
  // is written is said once, on the group, and every spin in it follows.
95593
95663
  const group = useContext(SpinGroupContext);
@@ -96805,7 +96875,7 @@ const TimeRangeSpin = ({
96805
96875
  endTimeProps,
96806
96876
  ...rest
96807
96877
  }) => {
96808
- const startId = useId();
96878
+ const startId = useGeneratedId();
96809
96879
  return jsxs(ControlGroup, {
96810
96880
  flex: true,
96811
96881
  alignY: "center",
@@ -96898,7 +96968,7 @@ const css$q = /* css */`.navi_checkbox_group {
96898
96968
  const CheckboxGroup = props => {
96899
96969
  const refDefault = useRef(null);
96900
96970
  props.ref = props.ref || refDefault;
96901
- const defaultName = useId();
96971
+ const defaultName = useGeneratedId();
96902
96972
  props.name = props.name || `checkbox_group_${defaultName}`;
96903
96973
  const checkboxGroup = jsx(CheckboxGroupInterface, {
96904
96974
  ...props
@@ -97663,7 +97733,7 @@ const css$o = /* css */`.navi_radio_group {
97663
97733
  const RadioGroup = props => {
97664
97734
  const refDefault = useRef(null);
97665
97735
  props.ref = props.ref || refDefault;
97666
- const defaultName = useId();
97736
+ const defaultName = useGeneratedId();
97667
97737
  props.name = props.name || `radio_group_${defaultName}`;
97668
97738
  const radioGroup = jsx(RadioGroupInterface, {
97669
97739
  ...props
@@ -98004,7 +98074,7 @@ const SplitButton = props => {
98004
98074
  if (popupProps.positionArea === undefined && mode === "popover") {
98005
98075
  popupProps.positionArea = "bottom-end";
98006
98076
  }
98007
- const idDefault = useId();
98077
+ const idDefault = useGeneratedId();
98008
98078
  const idResolved = id || idDefault;
98009
98079
  const menuId = `${idResolved}_menu`;
98010
98080
  const rootRef = useRef(null);
@@ -101062,7 +101132,7 @@ const WheelItem = ({
101062
101132
  children,
101063
101133
  ...rest
101064
101134
  }) => {
101065
- const idDefault = useId();
101135
+ const idDefault = useGeneratedId();
101066
101136
  const resolvedId = id || idDefault;
101067
101137
  // Wheel.Item must live inside a Wheel, so the context is always present.
101068
101138
  const trackerContext = useContext(WheelItemTrackerContext);
@@ -101660,7 +101730,7 @@ const TimeRangeWheel = ({
101660
101730
  ...rest
101661
101731
  }) => {
101662
101732
  import.meta.css = [css$j, "@jsenv/navi/src/control/wheel/wheel_time.jsx"];
101663
- const startId = useId();
101733
+ const startId = useGeneratedId();
101664
101734
  const startRef = useRef(null);
101665
101735
  const endRef = useRef(null);
101666
101736
  const endHourList = useMemo(() => resolveHourList(hours), [hours ? hours.min : undefined, hours ? hours.max : undefined, hours]);
@@ -104648,7 +104718,7 @@ const useIsInTableHead = () => useContext(TableSectionContext) === "head";
104648
104718
  const Table = props => {
104649
104719
  installTableCss();
104650
104720
  const tableDefaultRef = useRef();
104651
- const tableDefaultId = `table-${useId()}`;
104721
+ const tableDefaultId = `table-${useGeneratedId()}`;
104652
104722
  const {
104653
104723
  id = tableDefaultId,
104654
104724
  selection = [],