@jsenv/navi 0.29.43 → 0.29.44

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.
@@ -23758,9 +23758,9 @@ const useUIGroupStateController = (
23758
23758
  const delegatedChildrenRef = useRef(new Map());
23759
23759
 
23760
23760
  const groupIsRenderingRef = useRef(false);
23761
- const pendingChangeRef = useRef(false);
23761
+ const pendingChangeRef = useRef(null);
23762
23762
  groupIsRenderingRef.current = true;
23763
- pendingChangeRef.current = false;
23763
+ pendingChangeRef.current = null;
23764
23764
 
23765
23765
  const isMonitoringChild = (childUIStateController) => {
23766
23766
  if (childUIStateController.isProxy) return false;
@@ -23792,7 +23792,18 @@ const useUIGroupStateController = (
23792
23792
  // signals/pubsub without needing external refs.
23793
23793
  const onChange = (e, { notifyExternal }) => {
23794
23794
  if (groupIsRenderingRef.current) {
23795
- pendingChangeRef.current = true;
23795
+ // Held until the layout effect below, WITH what it asked for: a child
23796
+ // whose bound signal was written from the outside changes during the
23797
+ // render that follows, and replaying that as a mount sync is what
23798
+ // makes a group silently drift — its own state comes up to date while
23799
+ // the form around it is never told anything moved. A real change
23800
+ // deferred alongside a mount sync stays a real change.
23801
+ const pendingChange = pendingChangeRef.current;
23802
+ pendingChangeRef.current = {
23803
+ e,
23804
+ notifyExternal:
23805
+ pendingChange?.notifyExternal === true ? true : notifyExternal,
23806
+ };
23796
23807
  return;
23797
23808
  }
23798
23809
  const aggChildState = resolvedAggregateChildStates(
@@ -24256,12 +24267,16 @@ const useUIGroupStateController = (
24256
24267
 
24257
24268
  useLayoutEffect(() => {
24258
24269
  groupIsRenderingRef.current = false;
24259
- if (pendingChangeRef.current) {
24260
- pendingChangeRef.current = false;
24261
- scope._onChange(
24262
- new CustomEvent(`${controlType}_batched_ui_state_update`),
24263
- { notifyExternal: "silent" },
24270
+ const pendingChange = pendingChangeRef.current;
24271
+ if (pendingChange) {
24272
+ pendingChangeRef.current = null;
24273
+ const batchedEvent = new CustomEvent(
24274
+ `${controlType}_batched_ui_state_update`,
24264
24275
  );
24276
+ chainEvent(batchedEvent, pendingChange.e);
24277
+ scope._onChange(batchedEvent, {
24278
+ notifyExternal: pendingChange.notifyExternal,
24279
+ });
24265
24280
  }
24266
24281
  });
24267
24282
 
@@ -24322,20 +24337,6 @@ const useUIFacadeStateController = (props, realUIStateController) => {
24322
24337
  // not be treated as the picker's synced child.
24323
24338
  return false;
24324
24339
  }
24325
- if (props.type === "form" && childController.controlType !== "form") {
24326
- // Only a form: what a type="form" picker syncs with is the form in
24327
- // its popup, not any control that happens to be in there (an input
24328
- // sitting outside the form, a ControlGroup — which is a way of
24329
- // grouping controls INSIDE a form, not a thing a picker talks to).
24330
- return false;
24331
- }
24332
- if (
24333
- props.type === "array" &&
24334
- childController.controlType !== "checkbox_group"
24335
- ) {
24336
- // only selectable list expose array, ignore others
24337
- return false;
24338
- }
24339
24340
  return true;
24340
24341
  };
24341
24342
 
@@ -24355,7 +24356,7 @@ const useUIFacadeStateController = (props, realUIStateController) => {
24355
24356
  `[navi] a second control ("${childType}"${child.name ? ` name="${child.name}"` : ""}) registered in the ${describePicker(props)} popup. ` +
24356
24357
  `A picker talks to ONE control: the first one receives the picker's whole value and is the only one read back, ` +
24357
24358
  `so this one is neither filled nor collected. ` +
24358
- `A popup holding several values needs one group around them — wrap them in a <ControlGroup>, name each control inside it, and give the picker type="form".`,
24359
+ `A popup holding several values needs one group around them — wrap them in a <ControlGroup>, name each control inside it, and give the picker type="object".`,
24359
24360
  child,
24360
24361
  );
24361
24362
  } else {
@@ -32346,6 +32347,12 @@ const defaultRerunOn = {
32346
32347
  GET: false,
32347
32348
  GET_MANY: ["POST"],
32348
32349
  };
32350
+ // What makes a range reader stale (rerunOn.GET_RANGE overrides it). DELETE is
32351
+ // in there, unlike for GET_MANY: an action holds ids and the store drops the
32352
+ // deleted one out of every list holding it, while a list reading by slices
32353
+ // holds places — the row that left takes the ones after it one rank up, and
32354
+ // only the collection knows who fills the last one.
32355
+ const defaultInvalidateRangeOn = ["POST", "DELETE"];
32349
32356
 
32350
32357
  // This handles ALL resource lifecycle logic (rerun/reset) across all resources
32351
32358
  const createResourceLifecycleManager = () => {
@@ -32366,6 +32373,7 @@ const createResourceLifecycleManager = () => {
32366
32373
  paramScope,
32367
32374
  uniqueKeys,
32368
32375
  restActionSet: new Set(),
32376
+ rangeReaderSet: new Set(),
32369
32377
  });
32370
32378
 
32371
32379
  // Register dependencies
@@ -32378,6 +32386,14 @@ const createResourceLifecycleManager = () => {
32378
32386
  }
32379
32387
  }
32380
32388
  };
32389
+ // Only the reader the resource exposes is registered; the ones `bindParams`
32390
+ // makes share its signal (see resource_range_reader.js).
32391
+ const registerRangeReader = (resourceScope, rangeReader) => {
32392
+ const config = registeredResources.get(resourceScope);
32393
+ if (config) {
32394
+ config.rangeReaderSet.add(rangeReader);
32395
+ }
32396
+ };
32381
32397
  const registerAction = (resourceScope, restAction) => {
32382
32398
  const config = registeredResources.get(resourceScope);
32383
32399
  if (config) {
@@ -32608,7 +32624,39 @@ const createResourceLifecycleManager = () => {
32608
32624
  };
32609
32625
  };
32610
32626
 
32627
+ // Which readers hold slices of a collection the mutation just changed: the
32628
+ // one of the resource itself, and the ones of the resources that said they
32629
+ // depend on it.
32630
+ const invalidateRangeReaders = (
32631
+ triggeringAction,
32632
+ triggeringActionContext,
32633
+ ) => {
32634
+ const triggerVerb = triggeringAction.meta.verb;
32635
+ const triggerResourceScope = triggeringActionContext.resourceScope;
32636
+ for (const [resourceScope, config] of registeredResources) {
32637
+ if (config.rangeReaderSet.size === 0) {
32638
+ continue;
32639
+ }
32640
+ const isSameResource = resourceScope === triggerResourceScope;
32641
+ const isDependent = Boolean(
32642
+ triggerResourceScope &&
32643
+ resourceDependencies.get(triggerResourceScope)?.has(resourceScope),
32644
+ );
32645
+ if (!isSameResource && !isDependent) {
32646
+ continue;
32647
+ }
32648
+ const invalidateOn = config.rerunOn.GET_RANGE ?? defaultInvalidateRangeOn;
32649
+ if (!shouldRerunAfter(invalidateOn, triggerVerb)) {
32650
+ continue;
32651
+ }
32652
+ for (const rangeReader of config.rangeReaderSet) {
32653
+ rangeReader.invalidate();
32654
+ }
32655
+ }
32656
+ };
32657
+
32611
32658
  const onActionComplete = (restActionWhoJustCompleted, restActionContext) => {
32659
+ invalidateRangeReaders(restActionWhoJustCompleted, restActionContext);
32612
32660
  const { actionsToRerun, actionsToReset, reasons } = findEffectOnActions(
32613
32661
  restActionWhoJustCompleted,
32614
32662
  restActionContext,
@@ -32627,6 +32675,7 @@ const createResourceLifecycleManager = () => {
32627
32675
  return {
32628
32676
  registerResource,
32629
32677
  registerAction,
32678
+ registerRangeReader,
32630
32679
  onActionComplete,
32631
32680
  // Registers: when `triggerResource` fires, rerun `dependentResource`'s actions.
32632
32681
  // Used by scopedMany to make the parent GET rerun when a child mutation completes.
@@ -32704,13 +32753,20 @@ const getParamScope = (params) => {
32704
32753
  *
32705
32754
  * The reader is a function, so a list feeds on it the way it feeds on any other
32706
32755
  * source: `itemsAction={GAME.GET_RANGE.bindParams({ radar })}`.
32756
+ *
32757
+ * Keeping nothing does not mean hearing nothing: a mutation that decides who
32758
+ * belongs to the collection (a POST, a DELETE, whatever `rerunOn.GET_RANGE`
32759
+ * says) bumps `invalidationSignal`, and whoever reads slices through it goes
32760
+ * and asks again — the counterpart, for a reader, of what a rerun is for an
32761
+ * action. Every reader made by `bindParams` shares the signal of the one it
32762
+ * comes from: the params say which slices are read, not which collection.
32707
32763
  */
32708
32764
 
32709
32765
 
32710
32766
  const createRangeReader = (
32711
32767
  actionName,
32712
32768
  callback,
32713
- { store, params: boundParams },
32769
+ { store, params: boundParams, invalidationSignal = signal(0) },
32714
32770
  ) => {
32715
32771
  const readRange = async (range = {}) => {
32716
32772
  const { signal, ...rangeParams } = range;
@@ -32739,10 +32795,17 @@ const createRangeReader = (
32739
32795
  };
32740
32796
  Object.defineProperty(readRange, "name", { value: actionName });
32741
32797
  readRange.isRangeReader = true;
32798
+ // Bumped when the collection this reads has moved: the slices anyone holds
32799
+ // stand for a composition that is gone.
32800
+ readRange.invalidationSignal = invalidationSignal;
32801
+ readRange.invalidate = () => {
32802
+ invalidationSignal.value = invalidationSignal.peek() + 1;
32803
+ };
32742
32804
  readRange.bindParams = (paramsToBind) => {
32743
32805
  return createRangeReader(actionName, callback, {
32744
32806
  store,
32745
32807
  params: boundParams ? { ...boundParams, ...paramsToBind } : paramsToBind,
32808
+ invalidationSignal,
32746
32809
  });
32747
32810
  };
32748
32811
  return readRange;
@@ -32809,9 +32872,11 @@ const debug$2 = (args) => {
32809
32872
  * - GET_MANY / POST_MANY / … → an array of item objects
32810
32873
  * - GET_RANGE → `{ items, start, count }`, one slice of the collection
32811
32874
  *
32812
- * `GET_RANGE` is a reader rather than an action: it keeps no value and takes no place in
32813
- * the rerun graph, so a `<List.Items>` can feed on it slice by slice
32814
- * (`itemsAction={USER.GET_RANGE.bindParams({ team })}`).
32875
+ * `GET_RANGE` is a reader rather than an action: it keeps no value and has nothing to
32876
+ * rerun, so a `<List.Items>` can feed on it slice by slice
32877
+ * (`itemsAction={USER.GET_RANGE.bindParams({ team })}`). A mutation listed in
32878
+ * `rerunOn.GET_RANGE` (`["POST", "DELETE"]` by default) tells it the collection moved,
32879
+ * and whoever holds slices reads them again.
32815
32880
  *
32816
32881
  * A sub-resource of the backend (`/games/:id/candidates`) must be modelled with a
32817
32882
  * relationship method, never as an `op`/`type` discriminator dispatched inside one
@@ -33991,13 +34056,18 @@ ${originalActionName} source location: ${locationInfo}`,
33991
34056
  continue;
33992
34057
  }
33993
34058
  if (restCallbackKey === "GET_RANGE") {
33994
- // A range is read, never kept: no action, no place in the rerun graph
34059
+ // A range is read, never kept: no action, nothing to rerun only a
34060
+ // signal saying the slices anyone holds are out of date
33995
34061
  // (see resource_range_reader.js).
33996
34062
  stateFacade.GET_RANGE = createRangeReader(
33997
34063
  `${name}.GET_RANGE`,
33998
34064
  restCallback,
33999
34065
  { store, params },
34000
34066
  );
34067
+ resourceLifecycleManager.registerRangeReader(
34068
+ stateFacade,
34069
+ stateFacade.GET_RANGE,
34070
+ );
34001
34071
  continue;
34002
34072
  }
34003
34073
  const isMany = restCallbackKey.endsWith("_MANY");
@@ -54720,6 +54790,7 @@ const ListUI = props => {
54720
54790
  expand: expand,
54721
54791
  "navi-nothing-to-display": nothingToDisplay ? "" : undefined,
54722
54792
  "navi-loading": loading ? "" : undefined,
54793
+ "navi-refreshing": virtual.refreshingSignal.value ? "" : undefined,
54723
54794
  "navi-error": error ? "" : undefined,
54724
54795
  styleCSSVars: LIST_STYLE_CSS_VARS,
54725
54796
  pseudoClasses: LIST_PSEUDO_CLASSES,
@@ -57044,6 +57115,10 @@ const createListVirtual = () => {
57044
57115
  // registers, nothing is drawn), and yet they are what it may have been
57045
57116
  // waiting for — the row it was told to open on, for one.
57046
57117
  const pagesSignal = signal(0);
57118
+ // How many runs are re-reading rows they already show. The list wears it as
57119
+ // an attribute: what is drawn is from before, and the app may want to say so
57120
+ // without taking anything away.
57121
+ const refreshingSignal = signal(0);
57047
57122
  const placeByOwner = new Map();
57048
57123
  const locatorByOwner = new Map();
57049
57124
  let passId = 0;
@@ -57051,6 +57126,7 @@ const createListVirtual = () => {
57051
57126
  const virtual = {
57052
57127
  totalSignal,
57053
57128
  pagesSignal,
57129
+ refreshingSignal,
57054
57130
  // What a run needs to know about the list it lives in: how many rows the
57055
57131
  // list is willing to draw at once, which end it opens on, and how much
57056
57132
  // room one row is given — a row whose content has not arrived must take
@@ -57153,7 +57229,7 @@ const VISIBILITY_HIDDEN_STYLE = {
57153
57229
  * inside `<List.Group>`s; each takes its place in declaration order.
57154
57230
  *
57155
57231
  * @type {import("ignore:preact").FunctionComponent<{
57156
- * renderItem: (item: any, index: number) => import("ignore:preact").ComponentChildren,
57232
+ * renderItem: (item: any, index: number, state: {refreshing: boolean}) => import("ignore:preact").ComponentChildren,
57157
57233
  * itemsAction: (range: {start: number, end: number, limit: number, before?: string, after?: string, around?: string, count?: number, signal: AbortSignal}) => any,
57158
57234
  * count?: number,
57159
57235
  * groupBy?: (item: any, index: number) => any,
@@ -57163,6 +57239,10 @@ const VISIBILITY_HIDDEN_STYLE = {
57163
57239
  * renderSkeleton?: false | ((index: number) => import("ignore:preact").ComponentChildren),
57164
57240
  * renderError?: (failure: {error: any, retry: () => void, start: number, end: number}) => import("ignore:preact").ComponentChildren,
57165
57241
  * }>}
57242
+ * @param {(item: any, index: number, state: {refreshing: boolean}) => any} props.renderItem
57243
+ * What one row is, given the item and where it sits. `state.refreshing` says
57244
+ * the rows drawn are the ones from before while the run reads the collection
57245
+ * again — the list carries `navi-refreshing` for the same reason.
57166
57246
  * @param {(item: any, index: number) => any} [props.groupBy]
57167
57247
  * What tells rows that belong together apart from the others — the day of a
57168
57248
  * message, the month of a game. Consecutive rows sharing it are wrapped in a
@@ -57369,6 +57449,9 @@ const ListItems = ({
57369
57449
  virtualItemSize: virtualItemSize
57370
57450
  }, "navi-list-filler-before"));
57371
57451
  }
57452
+ const renderItemState = {
57453
+ refreshing: store.refreshing
57454
+ };
57372
57455
  let rowIndex = windowFrom;
57373
57456
  while (rowIndex < windowTo) {
57374
57457
  if (rowIndex >= failureFrom && rowIndex <= failureTo) {
@@ -57396,7 +57479,7 @@ const ListItems = ({
57396
57479
  const key = item === undefined ? `${ownerId}_skeleton_${rowIndex}` : idOf(item, rowIndex);
57397
57480
  let rowVnode;
57398
57481
  if (item !== undefined) {
57399
- rowVnode = renderItem(item, rowIndex);
57482
+ rowVnode = renderItem(item, rowIndex, renderItemState);
57400
57483
  } else if (renderRowSkeleton === false) {
57401
57484
  // The row must still take its room: without it the rows below would
57402
57485
  // climb up and slide back down as the answer arrives.
@@ -57497,6 +57580,22 @@ const useItemStore = ({
57497
57580
  }
57498
57581
  const pages = pagesRef.current;
57499
57582
  const [, setPageVersion] = useState(0);
57583
+ // The rows held are out of date and the run has not asked for the new ones
57584
+ // yet. They stay on screen until the answer comes: what is drawn is from
57585
+ // before, which is not the same thing as nothing to draw.
57586
+ const staleRef = useRef(false);
57587
+ const [refreshing, setRefreshing] = useState(false);
57588
+ // A source that says when what it reads has moved (a resource range reader
57589
+ // does: see rerunOn.GET_RANGE) is heard here — a write deciding who belongs
57590
+ // to the collection is exactly what a run cannot deduce from the rows it
57591
+ // holds. A source that says nothing is read once and stays as it is.
57592
+ const invalidationSignal = typeof itemsAction === "function" ? itemsAction.invalidationSignal : null;
57593
+ const invalidation = invalidationSignal ? invalidationSignal.value : 0;
57594
+ const invalidationRef = useRef(invalidation);
57595
+ if (invalidationRef.current !== invalidation) {
57596
+ invalidationRef.current = invalidation;
57597
+ staleRef.current = true;
57598
+ }
57500
57599
  // The one request in flight, with the means to call it off: a page asked for
57501
57600
  // a window the list has left is work the server and the browser are doing for
57502
57601
  // nothing.
@@ -57506,7 +57605,8 @@ const useItemStore = ({
57506
57605
  end: -1,
57507
57606
  held: -1,
57508
57607
  controller: null,
57509
- generation: 0
57608
+ generation: 0,
57609
+ revalidating: false
57510
57610
  });
57511
57611
  // The rows asked for that never came. Kept as a range so the list can say
57512
57612
  // where the hole is, and cleared by a retry — which is what makes the same
@@ -57517,9 +57617,24 @@ const useItemStore = ({
57517
57617
  // It stands for a windowful of them: a list that is about to be filled looks
57518
57618
  // like rows on their way, not like an empty list.
57519
57619
  const rowCount = pages.count ?? count ?? virtual.renderBudget;
57620
+ // A run that never received anything has nothing to keep on screen: asking
57621
+ // again is its first ask, not a refresh.
57622
+ if (staleRef.current && pages.count === undefined) {
57623
+ staleRef.current = false;
57624
+ }
57625
+ useLayoutEffect(() => {
57626
+ if (!refreshing) {
57627
+ return null;
57628
+ }
57629
+ virtual.refreshingSignal.value = virtual.refreshingSignal.peek() + 1;
57630
+ return () => {
57631
+ virtual.refreshingSignal.value = virtual.refreshingSignal.peek() - 1;
57632
+ };
57633
+ }, [refreshing]);
57520
57634
  const store = {
57521
57635
  rowCount,
57522
57636
  failure,
57637
+ refreshing,
57523
57638
  // JS memory is cheap next to the DOM, but a long enough scroll accumulates
57524
57639
  // everything it ever went through. Rows far from what is on screen are
57525
57640
  // dropped and simply asked for again if the user goes back — the same
@@ -57560,7 +57675,25 @@ const useItemStore = ({
57560
57675
  let start = missingStart;
57561
57676
  let end = missingEnd;
57562
57677
  let around;
57563
- if (pages.count === undefined) {
57678
+ // Rows that are all there but out of date: the ask is the window itself,
57679
+ // anchored on the row at its top — a source paginating by cursor gets a
57680
+ // row to count from, and the reading position is what must survive.
57681
+ const revalidating = staleRef.current;
57682
+ if (revalidating) {
57683
+ start = windowFrom;
57684
+ end = windowTo - 1;
57685
+ if (end < start) {
57686
+ // Nothing of this run is on screen (the window frames another one, or
57687
+ // the list is scrolled past it): its own first rows are what it will
57688
+ // draw next.
57689
+ start = 0;
57690
+ end = budget - 1;
57691
+ }
57692
+ const firstHeld = pages.byIndex.get(windowFrom);
57693
+ if (firstHeld && firstHeld.id !== undefined) {
57694
+ around = firstHeld.id;
57695
+ }
57696
+ } else if (pages.count === undefined) {
57564
57697
  const scrolled = virtual.scrolled;
57565
57698
  if (scrolled === "end") {
57566
57699
  // Counting back from the end, the way an HTTP range does: a list
@@ -57591,6 +57724,14 @@ const useItemStore = ({
57591
57724
  return;
57592
57725
  }
57593
57726
  const request = requestRef.current;
57727
+ if (revalidating && request.busy) {
57728
+ if (request.revalidating) {
57729
+ return;
57730
+ }
57731
+ // A page for a window that is about to be replaced wholesale.
57732
+ request.controller?.abort();
57733
+ request.busy = false;
57734
+ }
57594
57735
  if (request.busy) {
57595
57736
  // Still worth waiting for as long as what it went to fetch is still
57596
57737
  // what the list would draw. Once it is not, it is called off — and
@@ -57609,8 +57750,9 @@ const useItemStore = ({
57609
57750
  }
57610
57751
  const held = pages.byIndex.size;
57611
57752
  // Asking again for a range that was already asked for, having received
57612
- // nothing since, can only produce the same answer.
57613
- if (request.start === start && request.end === end && request.held === held) {
57753
+ // nothing since, can only produce the same answer. A revalidation is
57754
+ // exactly the case where it produces another one.
57755
+ if (!revalidating && request.start === start && request.end === end && request.held === held) {
57614
57756
  return;
57615
57757
  }
57616
57758
  request.start = start;
@@ -57625,17 +57767,33 @@ const useItemStore = ({
57625
57767
  end,
57626
57768
  around,
57627
57769
  limit: end - start + 1,
57628
- before: cursor.before,
57629
- after: cursor.after,
57770
+ // A cursor names a row of the collection as it was; a revalidation
57771
+ // is asked precisely because that is what changed.
57772
+ before: revalidating ? undefined : cursor.before,
57773
+ after: revalidating ? undefined : cursor.after,
57630
57774
  count: pages.count,
57631
57775
  signal: controller.signal
57632
57776
  };
57633
57777
  request.busy = true;
57778
+ request.revalidating = revalidating;
57779
+ if (revalidating) {
57780
+ setRefreshing(true);
57781
+ }
57634
57782
  const done = page => {
57635
57783
  const current = generation === request.generation;
57636
57784
  if (current) {
57637
57785
  request.busy = false;
57786
+ request.revalidating = false;
57638
57787
  setFailure(null);
57788
+ if (revalidating) {
57789
+ staleRef.current = false;
57790
+ setRefreshing(false);
57791
+ }
57792
+ }
57793
+ if (revalidating && !current) {
57794
+ // Rows of a composition already superseded by a newer ask: keeping
57795
+ // them would mix two states of the collection.
57796
+ return;
57639
57797
  }
57640
57798
  if (!page) {
57641
57799
  return;
@@ -57646,6 +57804,12 @@ const useItemStore = ({
57646
57804
  // Before the rows land: what is on screen has to stay where it is,
57647
57805
  // and the DOM still shows the state to hold onto.
57648
57806
  virtual.captureAnchor();
57807
+ if (revalidating) {
57808
+ // The rows held stood for a composition that has moved on; the
57809
+ // ones outside the window are forgotten and asked for again if the
57810
+ // user goes back to them.
57811
+ pages.byIndex = new Map();
57812
+ }
57649
57813
  let i = 0;
57650
57814
  while (i < pageItems.length) {
57651
57815
  pages.byIndex.set(pageStart + i, pageItems[i]);
@@ -57661,6 +57825,14 @@ const useItemStore = ({
57661
57825
  return;
57662
57826
  }
57663
57827
  request.busy = false;
57828
+ request.revalidating = false;
57829
+ if (revalidating) {
57830
+ // The rows from before stay: a revalidation that failed has
57831
+ // nothing better to put in their place.
57832
+ staleRef.current = false;
57833
+ setRefreshing(false);
57834
+ return;
57835
+ }
57664
57836
  setFailure({
57665
57837
  start,
57666
57838
  end,
@@ -58265,8 +58437,8 @@ const PickerTypeResolver = props => {
58265
58437
  ...props
58266
58438
  });
58267
58439
  }
58268
- if (props.type === "form") {
58269
- return jsx(PickerForm, {
58440
+ if (props.type === "object") {
58441
+ return jsx(PickerObject, {
58270
58442
  ...props
58271
58443
  });
58272
58444
  }
@@ -58282,19 +58454,19 @@ const PickerText = props => {
58282
58454
  });
58283
58455
  };
58284
58456
 
58285
- // The popup holds a group of named controls — a `<Form>`, or a `<ControlGroup>`
58286
- // when the group is only a shape and has no submit — and this picker's value is
58287
- // whatever that group aggregates. The popup itself holds nothing: it is a
58288
- // surface (see dialog.jsx), so there is nothing to tell it about the shape.
58289
- const PickerForm = props => {
58457
+ // The popup holds a group of named controls — a `<ControlGroup>`, or a `<Form>`
58458
+ // when that group is a question with a send of its own — and this picker's
58459
+ // value is the object that group aggregates. The popup itself holds nothing: it
58460
+ // is a surface (see dialog.jsx), so there is nothing to tell it about the shape.
58461
+ const PickerObject = props => {
58290
58462
  const Next = useNextResolver();
58291
58463
  return jsx(Next, {
58292
- ui: jsx(PickerFormUI, {}),
58464
+ ui: jsx(PickerObjectUI, {}),
58293
58465
  ...props,
58294
58466
  type: "navi_js"
58295
58467
  });
58296
58468
  };
58297
- const PickerFormUI = () => {
58469
+ const PickerObjectUI = () => {
58298
58470
  const {
58299
58471
  value,
58300
58472
  placeholder
@@ -59304,7 +59476,7 @@ Picker.UI.Week = PickerWeekUI;
59304
59476
  Picker.UI.Datetime = PickerDatetimeUI;
59305
59477
  Picker.UI.File = PickerFileUI;
59306
59478
  Picker.UI.Color = PickerColorUI;
59307
- Picker.UI.Form = PickerFormUI;
59479
+ Picker.UI.Object = PickerObjectUI;
59308
59480
  Picker.UI.Multiple = PickerArrayUI;
59309
59481
  Picker.UI.PencilSvg = PencilSvg;
59310
59482
  Picker.UI.ChevronDownSvg = ChevronDownSvg$1;