@jsenv/navi 0.29.298 → 0.29.300

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.
@@ -48917,7 +48917,7 @@ const COMMAND_DEFAULT_PROPS_FACTORIES = {
48917
48917
  * (it wears it itself) and loses the shrink under the finger, which has
48918
48918
  * nothing left to scale but the interactive area itself.
48919
48919
  */
48920
- const Button = createComponentResolver([ButtonFirstResolver, ButtonRouteResolver, ButtonCommandPropResolver, ButtonConfirmResolver, ButtonUI]);
48920
+ const Button = /*#__PURE__*/createComponentResolver([ButtonFirstResolver, ButtonRouteResolver, ButtonCommandPropResolver, ButtonConfirmResolver, ButtonUI]);
48921
48921
 
48922
48922
  installImportMetaCssBuild(import.meta);
48923
48923
  const css$O = /* css */`.navi_control_swap {
@@ -52288,7 +52288,7 @@ const InputTextualFirstResolver = props => {
52288
52288
  ...props
52289
52289
  });
52290
52290
  };
52291
- const InputTextual = createComponentResolver([InputTextualAsTextResolver, InputTextualFirstResolver, InputWithListResolver, InputWithSuggestionsResolver, InputTypeResolver, InputModeResolver, InputHeadlessResolver, InputTextualUI]);
52291
+ const InputTextual = /*#__PURE__*/createComponentResolver([InputTextualAsTextResolver, InputTextualFirstResolver, InputWithListResolver, InputWithSuggestionsResolver, InputTypeResolver, InputModeResolver, InputHeadlessResolver, InputTextualUI]);
52292
52292
  const RealInput = ({
52293
52293
  maxLength,
52294
52294
  ...domProps
@@ -62349,6 +62349,7 @@ const css$B = /* css */`.navi_picker {
62349
62349
  --popover-background-color: var(--picker-popup-background-color, var(--navi-popup-background-color));
62350
62350
  --popover-outline-width: var(--picker-outline-width);
62351
62351
  --popover-outline-color: var(--picker-outline-color);
62352
+ --popover-box-shadow: var(--picker-popup-box-shadow, var(--navi-popup-box-shadow));
62352
62353
  --popover-max-height: var(--picker-popover-max-height);
62353
62354
  min-width: var(--picker-popover-min-width, var(--anchor-width, 0px));
62354
62355
  cursor: default;
@@ -62385,6 +62386,7 @@ const css$B = /* css */`.navi_picker {
62385
62386
  --dialog-background-color: var(--picker-popup-background-color, var(--navi-popup-background-color));
62386
62387
  --dialog-outline-width: var(--picker-outline-width);
62387
62388
  --dialog-outline-color: var(--picker-outline-color);
62389
+ --dialog-box-shadow: var(--picker-popup-box-shadow, var(--navi-popup-box-shadow));
62388
62390
  --dialog-min-width: var(--picker-dialog-min-width);
62389
62391
  --dialog-min-height: var(--picker-dialog-min-height);
62390
62392
  --dialog-max-width: var(--picker-dialog-max-width);
@@ -62569,7 +62571,10 @@ const PickerCustom = props => {
62569
62571
  // hands the popup that controller, and a controlled Dialog/Popover reads
62570
62572
  // no onOpen/onClose of its own.
62571
62573
  onOpen,
62572
- onClose
62574
+ onClose,
62575
+ // What opens the popup — the press, or an interaction navi detects
62576
+ // ("longpress", "contextmenu"…, or a list of them). See the JSDoc.
62577
+ openOn = "press"
62573
62578
  } = props;
62574
62579
  // Resolve the id the same way useControlProps does (own id > Field's id > generated id)
62575
62580
  // before computing popupId below, so two Pickers without an explicit id never collide.
@@ -62605,6 +62610,7 @@ const PickerCustom = props => {
62605
62610
  delete pickerProps.onConfirm;
62606
62611
  delete pickerProps.onOpen;
62607
62612
  delete pickerProps.onClose;
62613
+ delete pickerProps.openOn;
62608
62614
  // Read below for the popup alone; on the trigger it would land on the DOM as
62609
62615
  // an unknown attribute holding a ref object.
62610
62616
  delete pickerProps.anchor;
@@ -63002,7 +63008,29 @@ const PickerCustom = props => {
63002
63008
  // could then never form. So the picker steps back and opens on the click,
63003
63009
  // which the browser only delivers if the press stayed a press (a gesture
63004
63010
  // swallows the click it leaves behind).
63005
- const interactionsDispute = interactionsDisputeThePress(props.interactions);
63011
+ // Opening on something else than the press: the hold, the right click.
63012
+ // Declared on the picker itself, as the caller would declare their own,
63013
+ // so it is read and arbitrated like any other gesture — a swipe on the
63014
+ // same card takes the press a hold would have taken — and gated like one:
63015
+ // a read-only picker refuses it where the finger is. The press is then
63016
+ // nobody's: a tap on the card opens nothing (see the two reactions
63017
+ // below), and the keyboard keeps its own ways in (the shortcuts above).
63018
+ const openOnList = Array.isArray(openOn) ? openOn : [openOn];
63019
+ const opensOnPress = openOnList.includes("press");
63020
+ let interactions = props.interactions;
63021
+ if (!opensOnPress) {
63022
+ interactions = {
63023
+ ...interactions
63024
+ };
63025
+ for (const type of openOnList) {
63026
+ interactions[type] = e => {
63027
+ requestOpen(e);
63028
+ };
63029
+ }
63030
+ pickerProps.interactions = interactions;
63031
+ pickerProps["data-open-on"] = openOnList.join(" ");
63032
+ }
63033
+ const interactionsDispute = interactionsDisputeThePress(interactions);
63006
63034
  Object.assign(pickerProps, {
63007
63035
  eventReactionDefinitions: {
63008
63036
  mouseDown: e => {
@@ -63028,7 +63056,7 @@ const PickerCustom = props => {
63028
63056
  // because that is where such a box says what it travels by — and
63029
63057
  // asked at every press, since what the picker sits in is not the
63030
63058
  // picker's to know at mount.
63031
- if (interactionsDispute || isPressDisputedByDrag(e.target)) {
63059
+ if (!opensOnPress || interactionsDispute || isPressDisputedByDrag(e.target)) {
63032
63060
  return null;
63033
63061
  }
63034
63062
  return {
@@ -63045,6 +63073,11 @@ const PickerCustom = props => {
63045
63073
  if (isWithinPickerContent(e.target)) {
63046
63074
  return null;
63047
63075
  }
63076
+ if (!opensOnPress) {
63077
+ // Neither the tap, nor the click a hold leaves behind: the press
63078
+ // is not what opens this picker.
63079
+ return null;
63080
+ }
63048
63081
  // When a label is clicked it transfers focus to the select
63049
63082
  // in that case we want to open it (otherwise we have already opened on mousedown interaction)
63050
63083
  // And when a gesture disputes the press (see the two disputes
@@ -63125,7 +63158,12 @@ const PickerContentInsidePopup = props => {
63125
63158
  // itself, and this one does not. Popover ignores it, same as Dialog ignores
63126
63159
  // marginWithAnchor.
63127
63160
  dockedOnSmallTouchScreen,
63161
+ // Same again: the dialog takes the trigger's box as a floor (and, with
63162
+ // dialogMaxWidth="var(--anchor-width)", as a ceiling) — what keeps a card
63163
+ // its own width once lifted. Dialog's own `sizeFromAnchor`.
63164
+ dialogSizeFromAnchor,
63128
63165
  animation,
63166
+ animationDuration,
63129
63167
  // mode="callout": what the callout says about what it holds, and paints
63130
63168
  // in its border and icon — "none" for a plain tooltip (see the callout
63131
63169
  // defaults in PickerCustomResolver). And whether it wears a cross: without
@@ -63186,6 +63224,7 @@ const PickerContentInsidePopup = props => {
63186
63224
  mode: mode,
63187
63225
  layer: popupLayer,
63188
63226
  animation: animation,
63227
+ animationDuration: animationDuration,
63189
63228
  positionArea: isPopover ? positionArea ?? (popoverMode === "nearby" ? "bottom-start" : "inset(top-left)") : positionArea,
63190
63229
  marginWithAnchor: isPopover ? popoverSpacing : undefined,
63191
63230
  marginWithContainer: marginWithContainer === undefined && isPopover ? popoverSpacing : marginWithContainer,
@@ -63200,6 +63239,7 @@ const PickerContentInsidePopup = props => {
63200
63239
  expandX: isPopover ? undefined : dialogExpandX,
63201
63240
  expandY: isPopover ? undefined : dialogExpandY,
63202
63241
  dockedOnSmallTouchScreen: isPopover ? undefined : dockedOnSmallTouchScreen,
63242
+ sizeFromAnchor: isPopover ? undefined : dialogSizeFromAnchor,
63203
63243
  children: jsx(PopupModeContext.Provider, {
63204
63244
  value: mode,
63205
63245
  children: children
@@ -65890,209 +65930,6 @@ const ListFirstResolver = props => {
65890
65930
  })
65891
65931
  });
65892
65932
  };
65893
-
65894
- /**
65895
- * List — generic virtualized scroll container.
65896
- * Items must use <List.Item> to participate in tracking.
65897
- *
65898
- * @type {import("ignore:preact").FunctionComponent<{
65899
- * selectable?: boolean,
65900
- * multiple?: boolean,
65901
- * deselectable?: boolean,
65902
- * maxLength?: number,
65903
- * maxLengthGuard?: number,
65904
- * parallelGuard?: number,
65905
- * standalone?: boolean,
65906
- * action?: (value: any) => void,
65907
- * uiAction?: (value: any) => void,
65908
- * popover?: boolean,
65909
- * role?: string,
65910
- * renderBudget?: number | string,
65911
- * renderBudgetSkipCheck?: boolean,
65912
- * virtualItemSize?: number,
65913
- * onListVisibleItemsChange?: (visibleItems: any[]) => void,
65914
- * scrolled?: "start" | "end" | number | {id: string, offset?: number},
65915
- * defaultScrolled?: "start" | "end" | number | {id: string, offset?: number},
65916
- * onScrolledChange?: (scrolled: {id: string, index: number, offset: number}) => void,
65917
- * scroller?: "self" | "parent" | "document" | Element | {current: Element},
65918
- * hoverWhileScrolling?: boolean,
65919
- * fallback?: import("ignore:preact").ComponentChildren,
65920
- * searchFallback?: import("ignore:preact").ComponentChildren,
65921
- * searchText?: string,
65922
- * searchNoMatchMode?: "remove" | "invisible_and_inert" | "muted",
65923
- * loading?: boolean,
65924
- * loadingFallback?: "skeleton" | "loader" | import("ignore:preact").ComponentChildren,
65925
- * loadingSkeletonCount?: number,
65926
- * renderSkeleton?: false | ((index: number) => import("ignore:preact").ComponentChildren),
65927
- * error?: boolean | import("ignore:preact").ComponentChildren,
65928
- * separator?: boolean | import("ignore:preact").ComponentChildren,
65929
- * itemTransition?: boolean,
65930
- * lockSize?: boolean,
65931
- * horizontal?: boolean,
65932
- * spacing?: string,
65933
- * columns?: string,
65934
- * itemColumns?: string,
65935
- * alignX?: string,
65936
- * alignY?: string,
65937
- * flexWrap?: boolean,
65938
- * expandX?: boolean,
65939
- * expandY?: boolean,
65940
- * expand?: boolean,
65941
- * children?: import("ignore:preact").ComponentChildren,
65942
- * [key: string]: any,
65943
- * }>}
65944
- * @param {string} [props.columns]
65945
- * The list's own columns: a `grid-template-columns` value the ITEMS are laid
65946
- * into — a sheet of icons (`repeat(auto-fill, minmax(2.5rem, 1fr))`), a row of
65947
- * choices (`repeat(3, minmax(0, 1fr))`). Each item takes one cell, and an item
65948
- * meant to take a whole line says so for itself
65949
- * (`style={{ gridColumn: "1 / -1" }}`). Several items to a line is a shape the
65950
- * list cannot virtualize — its render window and the room it holds for the
65951
- * rows it does not draw both count one item per line — so it is for a set of
65952
- * items the caller renders whole, not for a `<List.Items>` collection.
65953
- * @param {string} [props.itemColumns]
65954
- * The columns inside an ITEM: a `grid-template-columns` value each item fills
65955
- * with its own children, a table whose cells line up down the list. Every item
65956
- * becomes a subgrid row spanning all the columns, so a column is as wide as
65957
- * the widest cell in it among the rows actually in the DOM — real column
65958
- * sizing that stays right as the window moves. Rows of a table, then, where
65959
- * `columns` above is a grid of items; the two cannot both be set.
65960
- * @param {string} [props.alignX]
65961
- * Where the items sit across the track — `alignX="center"` centres a
65962
- * horizontal list's row of items inside a list wider than they are. Together
65963
- * with `alignY`, `align` and `flexWrap`, this reaches the `<ul>` holding the
65964
- * items rather than the frame drawn around it: the frame's only child is the
65965
- * scroll box, which fills it and has nothing to arrange.
65966
- * @param {boolean} [props.flexWrap]
65967
- * Lets a horizontal list's items fall to the next line instead of running
65968
- * past the edge — a row of choices under a `maxWidth`, say. Same caveat as
65969
- * `columns` above: a line holding several items is not virtualizable.
65970
- * @param {string} [props.overflow]
65971
- * `"visible"` lets the items paint outside the list — a check in a row's
65972
- * corner, a badge crossing the edge. A list clips by default, which is what
65973
- * its rounded corners and its scroll box need, and the two cannot both be
65974
- * true: asking for visible gives up the clipping, corners included.
65975
- * @param {boolean} [props.itemTransition]
65976
- * Names each row, so a change the application wraps in
65977
- * `document.startViewTransition` is seen row by row — rows moving to their new
65978
- * place, an arriving row appearing where it lands — instead of the list
65979
- * cross-fading as a block. The rows are drawn inside the list's own picture,
65980
- * so one coming from outside the visible part of the list is cut at the list's
65981
- * edge like any other overflow. Requires nested view transition groups
65982
- * (Chrome/Edge 140+): elsewhere the rows are left unnamed and the change
65983
- * simply happens — but the browser still names the document root, so the page
65984
- * cross-fades as a whole unless the application says otherwise, which is its
65985
- * call and not the list's:
65986
- * ```css
65987
- * @supports not (view-transition-group: contain) {
65988
- * :root { view-transition-name: none; }
65989
- * }
65990
- * ```
65991
- * @param {false|((index: number) => any)} [props.renderSkeleton]
65992
- * What a row on its way looks like — a row of the shape the real ones will
65993
- * have, so nothing moves when they arrive. Used for the rows a `<List.Items>`
65994
- * stands for and does not hold yet, and for the placeholder rows drawn while
65995
- * the whole list is `loading`. Defaults to a bare `<List.Item skeleton>`.
65996
- * @param {"skeleton"|"loader"|import("ignore:preact").ComponentChildren} [props.loadingFallback="skeleton"]
65997
- * What to display in place of the items while `loading` — that is, while
65998
- * there is nothing to show at all: `"skeleton"` renders
65999
- * `loadingSkeletonCount` placeholder rows (look:
66000
- * `renderSkeleton`), `"loader"` a single centered spinner, and
66001
- * anything else is rendered as-is in a row of its own. A falsy value
66002
- * displays nothing. A list that knows how many rows it will have has no use
66003
- * for this — see `<List.Items count>`, whose not-yet-loaded rows are drawn
66004
- * as skeletons in place, one per row, virtualized like the rest.
66005
- * @param {number} [props.loadingSkeletonCount=3]
66006
- * How many placeholder rows `loadingFallback="skeleton"` draws. `0` says the
66007
- * list is already known to be empty: the empty `fallback` shows right away
66008
- * rather than an empty frame, so nothing moves when the response arrives.
66009
- * @param {"start"|"end"|number|{id: string, offset?: number}} [props.defaultScrolled="start"]
66010
- * Where the list opens, after which the user owns the scroll. `"end"` is a
66011
- * thread read backwards — the last rows are the ones to show, and the ones
66012
- * asked for first. A number opens on that row of the collection. `{id,
66013
- * offset}` — what `onScrolledChange` hands out — opens on a NAMED row,
66014
- * `offset` pixels below where the row would land on its own: the row is asked
66015
- * for by name (see the range's own `around`), then put back by MEASURING it,
66016
- * so it lands where it was even if rows were inserted before it, and whatever
66017
- * the screen it was saved on. `offset: 0` is where a `scrollIntoView()` puts
66018
- * it — in front of the fixed bar the scroller gives room for, below the
66019
- * sticky header and the group label the row lives under — so nothing of that
66020
- * room has to be restated as a number by whoever asks.
66021
- * @param {"start"|"end"|number|{id: string, offset?: number}} [props.scrolled]
66022
- * The same, but held: the list goes back there every time this changes, even
66023
- * after the user has scrolled — the caller owns where the list is (see
66024
- * `defaultScrolled` for the uncontrolled form, and `open`/`defaultOpen`
66025
- * elsewhere in navi for the same pair). When the named row turns out not to
66026
- * exist — a message deleted since — the list opens at `defaultScrolled`
66027
- * instead.
66028
- *
66029
- * In every form the list holds itself there while it is still finding out
66030
- * how many rows there are and how tall one is, and lets go the moment the
66031
- * user reaches for the list.
66032
- * @param {(scrolled: {id: string, index: number, offset: number}) => void} [props.onScrolledChange]
66033
- * Where the list is, as the user scrolls: the row at the top of the view and
66034
- * how far below the place a row lands on its own (see `defaultScrolled`) it
66035
- * starts. Keep it to come back to it
66036
- * later through `scrolled`/`defaultScrolled` — an index would not do, since
66037
- * rows get inserted while a list is being read.
66038
- * @param {"self"|"parent"|"document"|Element|{current: Element}} [props.scroller="self"]
66039
- * Which box scrolls. `"self"` gives the list a scroll box of its own;
66040
- * `"parent"` makes it virtualize against the scrollable ancestor it lives in
66041
- * (the page, a panel) — no scroll box nested inside another one, no height
66042
- * to compute.
66043
- *
66044
- * `"parent"` finds that ancestor by measuring: the nearest one whose content
66045
- * actually overflows it, the page if none does. Declaring `overflow` is not
66046
- * enough to be picked (a box with `overflow-x: auto` that grows with its
66047
- * content computes `overflow-y: auto` without ever scrolling), and the
66048
- * answer is taken again as the geometry moves, so an ancestor that starts to
66049
- * scroll once it fills up is picked up then. When that is still not the box
66050
- * you mean, say so: `"document"`, or the element itself (a ref works) —
66051
- * nothing is guessed then.
66052
- * @param {boolean} [props.hoverWhileScrolling=false]
66053
- * Whether the rows still answer the pointer while the scroller they live in
66054
- * is moving. They do not by default: a scroll slides the rows under a
66055
- * motionless pointer, so the browser reports a hover on each of them, and
66056
- * the user asked to scroll, not to hover. The cost of taking them at face
66057
- * value is paid by whatever hover triggers — a highlight elsewhere in the
66058
- * tree, a prefetch, a map — at the worst moment, mid-scroll.
66059
- *
66060
- * Pass `true` for a list whose rows must stay live under the pointer while
66061
- * it scrolls. The trade of the default is the mirror one: right after a
66062
- * scroll, the row under the pointer lights up only once the pointer moves.
66063
- * @param {boolean} [props.deselectable]
66064
- * A single-select list allowed to hold nothing: the selected row, pressed
66065
- * again, lets go. Without it the list is a radio group — a choice, once
66066
- * made, moves to another row but never goes away. A `multiple` list toggles
66067
- * its rows already.
66068
- * @param {number} [props.maxLength]
66069
- * How many items a `selectable multiple` list accepts — the same word, and
66070
- * the same behaviour, as `maxLength` on a text field: a rule the list is
66071
- * judged against, not a wall. A longer selection is allowed to exist and is
66072
- * reported as invalid, which is what lets a value coming from elsewhere (an
66073
- * API, a URL) be shown and then corrected.
66074
- * @param {number} [props.maxLengthGuard]
66075
- * The same limit, enforced as the selection is made: while the list holds as
66076
- * many items as it accepts, the ones not selected go read-only — still
66077
- * pointable, focusable and pressable, answering `"[max] max."` instead of
66078
- * taking — and `uiAction` is not called. The selected ones stay takeable
66079
- * back, so a selection that arrived too long can always be brought back
66080
- * under the limit. Implies `maxLength` for validity.
66081
- * @param {number} [props.parallelGuard=4]
66082
- * How many runs the rows may have in flight at once, for a list whose rows
66083
- * carry their own `action` (a button per row). While that many are out, every
66084
- * row that is not running goes read-only and says how many it is waiting on;
66085
- * the next press is possible again as soon as one comes back. `Infinity`
66086
- * lifts it. Counts runs, not values — `maxLengthGuard` above is the one that
66087
- * says how many things the selection may hold.
66088
- * @param {boolean} [props.standalone]
66089
- * This list answers for itself: it does not register with the control group
66090
- * or picker around it, so its selection stays out of that value and nothing
66091
- * coming down — a distributed value, a reset — reaches it. What a popup whose
66092
- * one answer is spread over several lists says, so that none of them is taken
66093
- * for the answer itself.
66094
- */
66095
- const List = createComponentResolver([ListFirstResolver, ListSelectableResolver, ListUI]);
66096
65933
  const ListContent = ({
66097
65934
  role,
66098
65935
  fallback,
@@ -68358,14 +68195,13 @@ const LIST_ITEM_STYLE_CSS_VARS = {
68358
68195
  * search-driven scroll-to-top-match behavior. `matchRanges` are [start, end]
68359
68196
  * ranges highlighted via the CSS Highlight API.
68360
68197
  */
68361
- const ListItem = createComponentResolver([ListItemFirstResolver, ListItemRowResolver, ListItemSkeletonResolver, ListItemSelectableResolver, ListItemHeaderOrFooterResolver, ListItemPresentationResolver, ListItemUI],
68198
+ const ListItem = /*#__PURE__*/createComponentResolver([ListItemFirstResolver, ListItemRowResolver, ListItemSkeletonResolver, ListItemSelectableResolver, ListItemHeaderOrFooterResolver, ListItemPresentationResolver, ListItemUI],
68362
68199
  // Rendered by the hundred, and almost always with the same primitive props:
68363
68200
  // a selection change re-renders the list, and every row but two has nothing
68364
68201
  // to change.
68365
68202
  {
68366
68203
  pure: true
68367
68204
  });
68368
- List.Item = ListItem;
68369
68205
 
68370
68206
  // Everything the list knows about the collection while its children are being
68371
68207
  // rendered: how many rows it has in total, which of them are actually held, and
@@ -69125,7 +68961,6 @@ const ListItems = ({
69125
68961
  }
69126
68962
  return rows;
69127
68963
  };
69128
- List.Items = ListItems;
69129
68964
 
69130
68965
  // What is drawn where rows were asked for and never came: the sentence and the
69131
68966
  // way out, in the row itself — the rest of the list is fine, so replacing all
@@ -69735,6 +69570,219 @@ const resolveSeparatorVnode = (separator, gapIndex) => {
69735
69570
  }
69736
69571
  return separator;
69737
69572
  };
69573
+ const ListResolved = /*#__PURE__*/createComponentResolver([ListFirstResolver, ListSelectableResolver, ListUI]);
69574
+
69575
+ // Declared last because Item and Items are consts defined above, and they are
69576
+ // folded into the declaration rather than written onto List afterwards
69577
+ // (`List.Item = ListItem`): List is what createComponentResolver returns, an
69578
+ // object a bundler cannot see through, so a property assigned to it later is a
69579
+ // side effect it has to keep — and with it List, its rows and everything they
69580
+ // import, in a bundle that never renders a list. See Picker for the same shape.
69581
+ /**
69582
+ * List — generic virtualized scroll container.
69583
+ * Items must use <List.Item> to participate in tracking.
69584
+ *
69585
+ * @type {import("ignore:preact").FunctionComponent<{
69586
+ * selectable?: boolean,
69587
+ * multiple?: boolean,
69588
+ * deselectable?: boolean,
69589
+ * maxLength?: number,
69590
+ * maxLengthGuard?: number,
69591
+ * parallelGuard?: number,
69592
+ * standalone?: boolean,
69593
+ * action?: (value: any) => void,
69594
+ * uiAction?: (value: any) => void,
69595
+ * popover?: boolean,
69596
+ * role?: string,
69597
+ * renderBudget?: number | string,
69598
+ * renderBudgetSkipCheck?: boolean,
69599
+ * virtualItemSize?: number,
69600
+ * onListVisibleItemsChange?: (visibleItems: any[]) => void,
69601
+ * scrolled?: "start" | "end" | number | {id: string, offset?: number},
69602
+ * defaultScrolled?: "start" | "end" | number | {id: string, offset?: number},
69603
+ * onScrolledChange?: (scrolled: {id: string, index: number, offset: number}) => void,
69604
+ * scroller?: "self" | "parent" | "document" | Element | {current: Element},
69605
+ * hoverWhileScrolling?: boolean,
69606
+ * fallback?: import("ignore:preact").ComponentChildren,
69607
+ * searchFallback?: import("ignore:preact").ComponentChildren,
69608
+ * searchText?: string,
69609
+ * searchNoMatchMode?: "remove" | "invisible_and_inert" | "muted",
69610
+ * loading?: boolean,
69611
+ * loadingFallback?: "skeleton" | "loader" | import("ignore:preact").ComponentChildren,
69612
+ * loadingSkeletonCount?: number,
69613
+ * renderSkeleton?: false | ((index: number) => import("ignore:preact").ComponentChildren),
69614
+ * error?: boolean | import("ignore:preact").ComponentChildren,
69615
+ * separator?: boolean | import("ignore:preact").ComponentChildren,
69616
+ * itemTransition?: boolean,
69617
+ * lockSize?: boolean,
69618
+ * horizontal?: boolean,
69619
+ * spacing?: string,
69620
+ * columns?: string,
69621
+ * itemColumns?: string,
69622
+ * alignX?: string,
69623
+ * alignY?: string,
69624
+ * flexWrap?: boolean,
69625
+ * expandX?: boolean,
69626
+ * expandY?: boolean,
69627
+ * expand?: boolean,
69628
+ * children?: import("ignore:preact").ComponentChildren,
69629
+ * [key: string]: any,
69630
+ * }>}
69631
+ * @param {string} [props.columns]
69632
+ * The list's own columns: a `grid-template-columns` value the ITEMS are laid
69633
+ * into — a sheet of icons (`repeat(auto-fill, minmax(2.5rem, 1fr))`), a row of
69634
+ * choices (`repeat(3, minmax(0, 1fr))`). Each item takes one cell, and an item
69635
+ * meant to take a whole line says so for itself
69636
+ * (`style={{ gridColumn: "1 / -1" }}`). Several items to a line is a shape the
69637
+ * list cannot virtualize — its render window and the room it holds for the
69638
+ * rows it does not draw both count one item per line — so it is for a set of
69639
+ * items the caller renders whole, not for a `<List.Items>` collection.
69640
+ * @param {string} [props.itemColumns]
69641
+ * The columns inside an ITEM: a `grid-template-columns` value each item fills
69642
+ * with its own children, a table whose cells line up down the list. Every item
69643
+ * becomes a subgrid row spanning all the columns, so a column is as wide as
69644
+ * the widest cell in it among the rows actually in the DOM — real column
69645
+ * sizing that stays right as the window moves. Rows of a table, then, where
69646
+ * `columns` above is a grid of items; the two cannot both be set.
69647
+ * @param {string} [props.alignX]
69648
+ * Where the items sit across the track — `alignX="center"` centres a
69649
+ * horizontal list's row of items inside a list wider than they are. Together
69650
+ * with `alignY`, `align` and `flexWrap`, this reaches the `<ul>` holding the
69651
+ * items rather than the frame drawn around it: the frame's only child is the
69652
+ * scroll box, which fills it and has nothing to arrange.
69653
+ * @param {boolean} [props.flexWrap]
69654
+ * Lets a horizontal list's items fall to the next line instead of running
69655
+ * past the edge — a row of choices under a `maxWidth`, say. Same caveat as
69656
+ * `columns` above: a line holding several items is not virtualizable.
69657
+ * @param {string} [props.overflow]
69658
+ * `"visible"` lets the items paint outside the list — a check in a row's
69659
+ * corner, a badge crossing the edge. A list clips by default, which is what
69660
+ * its rounded corners and its scroll box need, and the two cannot both be
69661
+ * true: asking for visible gives up the clipping, corners included.
69662
+ * @param {boolean} [props.itemTransition]
69663
+ * Names each row, so a change the application wraps in
69664
+ * `document.startViewTransition` is seen row by row — rows moving to their new
69665
+ * place, an arriving row appearing where it lands — instead of the list
69666
+ * cross-fading as a block. The rows are drawn inside the list's own picture,
69667
+ * so one coming from outside the visible part of the list is cut at the list's
69668
+ * edge like any other overflow. Requires nested view transition groups
69669
+ * (Chrome/Edge 140+): elsewhere the rows are left unnamed and the change
69670
+ * simply happens — but the browser still names the document root, so the page
69671
+ * cross-fades as a whole unless the application says otherwise, which is its
69672
+ * call and not the list's:
69673
+ * ```css
69674
+ * @supports not (view-transition-group: contain) {
69675
+ * :root { view-transition-name: none; }
69676
+ * }
69677
+ * ```
69678
+ * @param {false|((index: number) => any)} [props.renderSkeleton]
69679
+ * What a row on its way looks like — a row of the shape the real ones will
69680
+ * have, so nothing moves when they arrive. Used for the rows a `<List.Items>`
69681
+ * stands for and does not hold yet, and for the placeholder rows drawn while
69682
+ * the whole list is `loading`. Defaults to a bare `<List.Item skeleton>`.
69683
+ * @param {"skeleton"|"loader"|import("ignore:preact").ComponentChildren} [props.loadingFallback="skeleton"]
69684
+ * What to display in place of the items while `loading` — that is, while
69685
+ * there is nothing to show at all: `"skeleton"` renders
69686
+ * `loadingSkeletonCount` placeholder rows (look:
69687
+ * `renderSkeleton`), `"loader"` a single centered spinner, and
69688
+ * anything else is rendered as-is in a row of its own. A falsy value
69689
+ * displays nothing. A list that knows how many rows it will have has no use
69690
+ * for this — see `<List.Items count>`, whose not-yet-loaded rows are drawn
69691
+ * as skeletons in place, one per row, virtualized like the rest.
69692
+ * @param {number} [props.loadingSkeletonCount=3]
69693
+ * How many placeholder rows `loadingFallback="skeleton"` draws. `0` says the
69694
+ * list is already known to be empty: the empty `fallback` shows right away
69695
+ * rather than an empty frame, so nothing moves when the response arrives.
69696
+ * @param {"start"|"end"|number|{id: string, offset?: number}} [props.defaultScrolled="start"]
69697
+ * Where the list opens, after which the user owns the scroll. `"end"` is a
69698
+ * thread read backwards — the last rows are the ones to show, and the ones
69699
+ * asked for first. A number opens on that row of the collection. `{id,
69700
+ * offset}` — what `onScrolledChange` hands out — opens on a NAMED row,
69701
+ * `offset` pixels below where the row would land on its own: the row is asked
69702
+ * for by name (see the range's own `around`), then put back by MEASURING it,
69703
+ * so it lands where it was even if rows were inserted before it, and whatever
69704
+ * the screen it was saved on. `offset: 0` is where a `scrollIntoView()` puts
69705
+ * it — in front of the fixed bar the scroller gives room for, below the
69706
+ * sticky header and the group label the row lives under — so nothing of that
69707
+ * room has to be restated as a number by whoever asks.
69708
+ * @param {"start"|"end"|number|{id: string, offset?: number}} [props.scrolled]
69709
+ * The same, but held: the list goes back there every time this changes, even
69710
+ * after the user has scrolled — the caller owns where the list is (see
69711
+ * `defaultScrolled` for the uncontrolled form, and `open`/`defaultOpen`
69712
+ * elsewhere in navi for the same pair). When the named row turns out not to
69713
+ * exist — a message deleted since — the list opens at `defaultScrolled`
69714
+ * instead.
69715
+ *
69716
+ * In every form the list holds itself there while it is still finding out
69717
+ * how many rows there are and how tall one is, and lets go the moment the
69718
+ * user reaches for the list.
69719
+ * @param {(scrolled: {id: string, index: number, offset: number}) => void} [props.onScrolledChange]
69720
+ * Where the list is, as the user scrolls: the row at the top of the view and
69721
+ * how far below the place a row lands on its own (see `defaultScrolled`) it
69722
+ * starts. Keep it to come back to it
69723
+ * later through `scrolled`/`defaultScrolled` — an index would not do, since
69724
+ * rows get inserted while a list is being read.
69725
+ * @param {"self"|"parent"|"document"|Element|{current: Element}} [props.scroller="self"]
69726
+ * Which box scrolls. `"self"` gives the list a scroll box of its own;
69727
+ * `"parent"` makes it virtualize against the scrollable ancestor it lives in
69728
+ * (the page, a panel) — no scroll box nested inside another one, no height
69729
+ * to compute.
69730
+ *
69731
+ * `"parent"` finds that ancestor by measuring: the nearest one whose content
69732
+ * actually overflows it, the page if none does. Declaring `overflow` is not
69733
+ * enough to be picked (a box with `overflow-x: auto` that grows with its
69734
+ * content computes `overflow-y: auto` without ever scrolling), and the
69735
+ * answer is taken again as the geometry moves, so an ancestor that starts to
69736
+ * scroll once it fills up is picked up then. When that is still not the box
69737
+ * you mean, say so: `"document"`, or the element itself (a ref works) —
69738
+ * nothing is guessed then.
69739
+ * @param {boolean} [props.hoverWhileScrolling=false]
69740
+ * Whether the rows still answer the pointer while the scroller they live in
69741
+ * is moving. They do not by default: a scroll slides the rows under a
69742
+ * motionless pointer, so the browser reports a hover on each of them, and
69743
+ * the user asked to scroll, not to hover. The cost of taking them at face
69744
+ * value is paid by whatever hover triggers — a highlight elsewhere in the
69745
+ * tree, a prefetch, a map — at the worst moment, mid-scroll.
69746
+ *
69747
+ * Pass `true` for a list whose rows must stay live under the pointer while
69748
+ * it scrolls. The trade of the default is the mirror one: right after a
69749
+ * scroll, the row under the pointer lights up only once the pointer moves.
69750
+ * @param {boolean} [props.deselectable]
69751
+ * A single-select list allowed to hold nothing: the selected row, pressed
69752
+ * again, lets go. Without it the list is a radio group — a choice, once
69753
+ * made, moves to another row but never goes away. A `multiple` list toggles
69754
+ * its rows already.
69755
+ * @param {number} [props.maxLength]
69756
+ * How many items a `selectable multiple` list accepts — the same word, and
69757
+ * the same behaviour, as `maxLength` on a text field: a rule the list is
69758
+ * judged against, not a wall. A longer selection is allowed to exist and is
69759
+ * reported as invalid, which is what lets a value coming from elsewhere (an
69760
+ * API, a URL) be shown and then corrected.
69761
+ * @param {number} [props.maxLengthGuard]
69762
+ * The same limit, enforced as the selection is made: while the list holds as
69763
+ * many items as it accepts, the ones not selected go read-only — still
69764
+ * pointable, focusable and pressable, answering `"[max] max."` instead of
69765
+ * taking — and `uiAction` is not called. The selected ones stay takeable
69766
+ * back, so a selection that arrived too long can always be brought back
69767
+ * under the limit. Implies `maxLength` for validity.
69768
+ * @param {number} [props.parallelGuard=4]
69769
+ * How many runs the rows may have in flight at once, for a list whose rows
69770
+ * carry their own `action` (a button per row). While that many are out, every
69771
+ * row that is not running goes read-only and says how many it is waiting on;
69772
+ * the next press is possible again as soon as one comes back. `Infinity`
69773
+ * lifts it. Counts runs, not values — `maxLengthGuard` above is the one that
69774
+ * says how many things the selection may hold.
69775
+ * @param {boolean} [props.standalone]
69776
+ * This list answers for itself: it does not register with the control group
69777
+ * or picker around it, so its selection stays out of that value and nothing
69778
+ * coming down — a distributed value, a reset — reaches it. What a popup whose
69779
+ * one answer is spread over several lists says, so that none of them is taken
69780
+ * for the answer itself.
69781
+ */
69782
+ const List = /*#__PURE__*/Object.assign(ListResolved, {
69783
+ Item: ListItem,
69784
+ Items: ListItems
69785
+ });
69738
69786
 
69739
69787
  const PickerNaviTime = props => {
69740
69788
  const Next = useNextResolver();
@@ -70667,7 +70715,7 @@ const PickerObject = props => {
70667
70715
  "navi-state-shape": "object"
70668
70716
  });
70669
70717
  };
70670
- const PickerObjectUI = asPickerOwnUI(() => {
70718
+ const PickerObjectUI = /*#__PURE__*/asPickerOwnUI(() => {
70671
70719
  const {
70672
70720
  value,
70673
70721
  placeholder
@@ -70702,7 +70750,7 @@ const PickerArray = props => {
70702
70750
  "navi-state-shape": "array"
70703
70751
  });
70704
70752
  };
70705
- const PickerArrayUI = asPickerOwnUI(() => {
70753
+ const PickerArrayUI = /*#__PURE__*/asPickerOwnUI(() => {
70706
70754
  const {
70707
70755
  value,
70708
70756
  placeholder,
@@ -70785,7 +70833,7 @@ const PickerColor = props => {
70785
70833
  ...props
70786
70834
  });
70787
70835
  };
70788
- const PickerColorUI = asPickerOwnUI(() => {
70836
+ const PickerColorUI = /*#__PURE__*/asPickerOwnUI(() => {
70789
70837
  const {
70790
70838
  value,
70791
70839
  placeholder
@@ -70809,7 +70857,7 @@ const PickerDate = props => {
70809
70857
  type: "date"
70810
70858
  });
70811
70859
  };
70812
- const PickerDateUI = asPickerOwnUI(props => {
70860
+ const PickerDateUI = /*#__PURE__*/asPickerOwnUI(props => {
70813
70861
  const {
70814
70862
  value,
70815
70863
  placeholder
@@ -70841,7 +70889,7 @@ const PickerMonth = props => {
70841
70889
  type: "month"
70842
70890
  });
70843
70891
  };
70844
- const PickerMonthUI = asPickerOwnUI(props => {
70892
+ const PickerMonthUI = /*#__PURE__*/asPickerOwnUI(props => {
70845
70893
  const {
70846
70894
  value,
70847
70895
  placeholder
@@ -70872,7 +70920,7 @@ const PickerWeek = props => {
70872
70920
  type: "week"
70873
70921
  });
70874
70922
  };
70875
- const PickerWeekUI = asPickerOwnUI(props => {
70923
+ const PickerWeekUI = /*#__PURE__*/asPickerOwnUI(props => {
70876
70924
  const {
70877
70925
  value,
70878
70926
  placeholder
@@ -70903,7 +70951,7 @@ const PickerTime = props => {
70903
70951
  type: "time"
70904
70952
  });
70905
70953
  };
70906
- const PickerTimeUI = asPickerOwnUI(props => {
70954
+ const PickerTimeUI = /*#__PURE__*/asPickerOwnUI(props => {
70907
70955
  const {
70908
70956
  value,
70909
70957
  placeholder
@@ -70934,7 +70982,7 @@ const PickerDuration = props => {
70934
70982
  "navi-input-type": "duration"
70935
70983
  });
70936
70984
  };
70937
- const PickerDurationUI = asPickerOwnUI(props => {
70985
+ const PickerDurationUI = /*#__PURE__*/asPickerOwnUI(props => {
70938
70986
  const {
70939
70987
  value,
70940
70988
  placeholder
@@ -70964,7 +71012,7 @@ const PickerDatetime = props => {
70964
71012
  type: "datetime-local"
70965
71013
  });
70966
71014
  };
70967
- const PickerDatetimeUI = asPickerOwnUI(props => {
71015
+ const PickerDatetimeUI = /*#__PURE__*/asPickerOwnUI(props => {
70968
71016
  const {
70969
71017
  value,
70970
71018
  placeholder
@@ -70993,7 +71041,7 @@ const PickerFile = props => {
70993
71041
  ...props
70994
71042
  });
70995
71043
  };
70996
- const PickerFileUI = asPickerOwnUI(() => {
71044
+ const PickerFileUI = /*#__PURE__*/asPickerOwnUI(() => {
70997
71045
  const {
70998
71046
  value,
70999
71047
  placeholder
@@ -71209,6 +71257,11 @@ const css$t = /* css */`@layer navi {
71209
71257
  }
71210
71258
  }
71211
71259
 
71260
+ &[data-open-on~="longpress"] {
71261
+ -webkit-touch-callout: none;
71262
+ user-select: none;
71263
+ }
71264
+
71212
71265
  &[navi-ui-custom] {
71213
71266
  & .navi_picker_input {
71214
71267
  top: calc(-1 * (var(--picker-border-width) + var(--x-picker-press-padding-top)));
@@ -72037,6 +72090,7 @@ const PickerStyleCSSVars = {
72037
72090
  "dialogMaxHeight": ["--picker-dialog-max-height", "maxHeight"],
72038
72091
  "popupBackgroundColor": "--picker-popup-background-color",
72039
72092
  "popupBorderRadius": ["--picker-popup-border-radius", "borderRadius"],
72093
+ "popupBoxShadow": ["--picker-popup-box-shadow", "boxShadow"],
72040
72094
  "dialogBorderWidth": ["--picker-dialog-border-width", "borderWidth"],
72041
72095
  "slotSpacing": ["--picker-slot-spacing", "margin"],
72042
72096
  "pressPadding": ["--picker-press-padding", "padding"],
@@ -72134,6 +72188,9 @@ const PickerFirstResolver = props => {
72134
72188
  * action?: (value: any, event: Event) => void,
72135
72189
  * children?: import("ignore:preact").ComponentChildren,
72136
72190
  * mode?: "popover" | "dialog" | "callout",
72191
+ * openOn?: "press" | "longpress" | "contextmenu" | string | string[],
72192
+ * animation?: boolean | "auto" | "fading" | "scaling" | "sliding" | "growing" | `slide-from-${string}`,
72193
+ * animationDuration?: string,
72137
72194
  * calloutStatus?: "info" | "warning" | "error" | "success" | "none",
72138
72195
  * calloutIcon?: boolean,
72139
72196
  * calloutCloseButton?: boolean,
@@ -72164,6 +72221,7 @@ const PickerFirstResolver = props => {
72164
72221
  * dialogMaxHeight?: number | string,
72165
72222
  * popupBackgroundColor?: string,
72166
72223
  * popupBorderRadius?: number | string,
72224
+ * popupBoxShadow?: string,
72167
72225
  * dialogBorderWidth?: number | string,
72168
72226
  * clearable?: boolean,
72169
72227
  * picksNothing?: boolean,
@@ -72176,6 +72234,7 @@ const PickerFirstResolver = props => {
72176
72234
  * dialogExpand?: boolean,
72177
72235
  * dialogExpandX?: boolean,
72178
72236
  * dialogExpandY?: boolean,
72237
+ * dialogSizeFromAnchor?: boolean,
72179
72238
  * marginWithContainer?: number | string,
72180
72239
  * anchor?: import("ignore:preact").RefObject<HTMLElement> | HTMLElement,
72181
72240
  * escapeEffect?: "cancel" | "close",
@@ -72193,6 +72252,23 @@ const PickerFirstResolver = props => {
72193
72252
  * variant that paints the trigger transparent leaves the popup a real sheet.
72194
72253
  * @param {number|string} [popupBorderRadius] The popup's corners. Left out they
72195
72254
  * echo the trigger's `borderRadius`.
72255
+ * @param {string} [popupBoxShadow] The popup's shadow, popover or dialog. Left
72256
+ * out it is the one every navi popup casts. `"none"` for a popup that is
72257
+ * not a sheet — a card lifted out of a page draws its own edges, and the
72258
+ * popup only carries it (see `dialogSizeFromAnchor`).
72259
+ * @param {"press"|"longpress"|"contextmenu"|string|string[]} [openOn="press"]
72260
+ * What opens the popup. The press, by default — the way a native select
72261
+ * opens. Any other name is an interaction navi detects (see
72262
+ * docs/interactions.md: `"longpress"`, `"contextmenu"`, `"dblclick"`…), or
72263
+ * a list of them — `["longpress", "contextmenu"]` is the hold on a phone and
72264
+ * the right click at a desk. The picker declares it on itself, so it is
72265
+ * arbitrated like any other gesture: a swipe on the same card takes the
72266
+ * press a hold would have taken. A tap then opens nothing — the press stays
72267
+ * free for what the `ui` holds, which is what lets a whole card be a picker
72268
+ * without every touch on it opening the sheet — and the keyboard keeps its
72269
+ * ways in (Enter, Space, the arrows). Being a gesture, the open goes through
72270
+ * the interaction gate as one: a `readOnly` picker refuses it and says so
72271
+ * where the finger is, whatever `openWhileReadOnly` says.
72196
72272
  * @param {import("ignore:preact").ComponentChildren | "default"} [ui] What the
72197
72273
  * trigger draws in place of the value's default rendering (a date, a list
72198
72274
  * joined by commas…) — and then all it draws: `placeholder` is not shown
@@ -72304,7 +72380,14 @@ const PickerFirstResolver = props => {
72304
72380
  * @param {boolean} [picksNothing] The popup asks something rather than holding
72305
72381
  * an answer, so the trigger draws a label and never a value: no chevron, no
72306
72382
  * clear cross, in any variant. `type="confirm"` says it for itself; say it
72307
- * for a popup of your own that is a menu of actions rather than a choice.
72383
+ * for a popup of your own that is a menu of actions rather than a choice —
72384
+ * or a DOOR: a drawing that grows to be looked at (a weather scene, a plan),
72385
+ * with no `action` at all. The picker is then a trigger and a popup, and
72386
+ * nothing more: its close does nothing, and what it keeps from being a
72387
+ * control is what a door still needs — the role of a button, the keyboard
72388
+ * opening it, the anchor being itself, and one popup per instance without
72389
+ * an id to wire. See "The trigger wears the wait" in docs/popup_open.md for
72390
+ * when that beats a `Button` opening a shared `Dialog`.
72308
72391
  * @param {string|import("ignore:preact").ComponentChildren} [clearConfirm] The
72309
72392
  * question asked before the clear cross clears anything — the `message` of
72310
72393
  * the `<Picker type="confirm">` the cross then is, plain text or JSX. Asked
@@ -72411,6 +72494,21 @@ const PickerFirstResolver = props => {
72411
72494
  * a dialog docked by `dockedOnSmallTouchScreen` withdraws it and stays
72412
72495
  * container-wide, so both can be stated at once.
72413
72496
  * @param {number|string} [dialogMaxHeight] Same, on the height.
72497
+ * @param {boolean|"auto"|"fading"|"scaling"|"sliding"|"growing"|`slide-from-${string}`} [animation]
72498
+ * The popup's own (see Popover/Dialog). `"growing"` is the one a picker
72499
+ * whose `ui` is a whole piece of the page wants: the popup is the browser
72500
+ * morphing the trigger's box into what carries `data-grow` inside the popup
72501
+ * (the popup itself when nothing does), and back on close. The trigger IS
72502
+ * the anchor, so nothing has to be named for it — see `dialogSizeFromAnchor`
72503
+ * for a card that must keep its width on the way, and leave it out for a
72504
+ * drawing that opens precisely to get bigger.
72505
+ * @param {string} [animationDuration] The popup's own (`--popup-animation-duration`).
72506
+ * @param {boolean} [dialogSizeFromAnchor] Dialog mode: the dialog takes the
72507
+ * trigger's box as a floor (`--anchor-width`/`--anchor-height`, Dialog's
72508
+ * own `sizeFromAnchor`) — and, with `dialogMaxWidth="var(--anchor-width)"`,
72509
+ * as a ceiling too. That pair is what keeps a card its own width once
72510
+ * lifted out of the page (`animation="growing"`, with `data-grow` on the
72511
+ * card inside the popup): it moves, and nothing else about it changes.
72414
72512
  * @param {"cancel"|"close"} [escapeEffect="cancel"] What Escape does to an open
72415
72513
  * picker. "cancel" puts back the value the picker had at open, and a dialog
72416
72514
  * picker also goes back in history — so anything written to the url while it
@@ -72549,26 +72647,37 @@ const warnOnUnknownPickerType = props => {
72549
72647
  pickerTypeWarnedSet.add(type);
72550
72648
  console.warn(`[navi] <Picker type="${type}"> — "${type}" is not a picker type. ` + `The picker holds a single text value instead, so an object given to it is written as "[object Object]". ` + `Types are: date, month, week, time, datetime, duration, color, file, text, array, object, confirm — ` + `"object" being the one for a popup holding several named controls.`);
72551
72649
  };
72552
- const Picker = createComponentResolver([PickerFirstResolver, PickerPresetResolver, PickerConfirmResolver, PickerCustomResolver, PickerTypeResolver, PickerButton]);
72553
- Picker.Chip = PickerChip;
72554
- Picker.Clear = PickerClear;
72555
- Picker.UI = PickerDefaultUI;
72556
- Picker.UI.Date = PickerDateUI;
72557
- Picker.UI.Time = PickerTimeUI;
72558
- Picker.UI.Duration = PickerDurationUI;
72559
- Picker.UI.Week = PickerWeekUI;
72560
- Picker.UI.Datetime = PickerDatetimeUI;
72561
- Picker.UI.File = PickerFileUI;
72562
- Picker.UI.Color = PickerColorUI;
72563
- Picker.UI.Object = PickerObjectUI;
72564
- Picker.UI.Multiple = PickerArrayUI;
72565
- Picker.UI.PencilSvg = PencilSvg;
72566
- Picker.UI.ChevronDownSvg = ChevronDownSvg$1;
72567
- Picker.UI.ClockSvg = ClockSvg;
72568
- Picker.UI.DurationSvg = DurationSvg;
72569
- Picker.UI.CalendarSvg = CalendarSvg;
72570
- Picker.UI.FileSvg = FileSvg;
72571
- Picker.UI.ColorSvg = ColorSvg;
72650
+ const PickerResolved = /*#__PURE__*/createComponentResolver([PickerFirstResolver, PickerPresetResolver, PickerConfirmResolver, PickerCustomResolver, PickerTypeResolver, PickerButton]);
72651
+ const PickerUI = /*#__PURE__*/Object.assign(PickerDefaultUI, {
72652
+ Date: PickerDateUI,
72653
+ Time: PickerTimeUI,
72654
+ Duration: PickerDurationUI,
72655
+ Week: PickerWeekUI,
72656
+ Datetime: PickerDatetimeUI,
72657
+ File: PickerFileUI,
72658
+ Color: PickerColorUI,
72659
+ Object: PickerObjectUI,
72660
+ Multiple: PickerArrayUI,
72661
+ PencilSvg,
72662
+ ChevronDownSvg: ChevronDownSvg$1,
72663
+ ClockSvg,
72664
+ DurationSvg,
72665
+ CalendarSvg,
72666
+ FileSvg,
72667
+ ColorSvg
72668
+ });
72669
+
72670
+ // Assembled in pure expressions rather than written onto Picker afterwards
72671
+ // (`Picker.Chip = PickerChip`): what createComponentResolver returns is an object
72672
+ // a bundler cannot see through, so a property assigned to it later is a side
72673
+ // effect it has to keep — and with it Picker, every UI and everything they
72674
+ // import, in a bundle that never renders a picker. The annotations say these
72675
+ // calls only create and return; an unused Picker then disappears whole.
72676
+ const Picker = /*#__PURE__*/Object.assign(PickerResolved, {
72677
+ Chip: PickerChip,
72678
+ Clear: PickerClear,
72679
+ UI: PickerUI
72680
+ });
72572
72681
 
72573
72682
  installImportMetaCssBuild(import.meta);
72574
72683
  const css$s = /* css */`@layer navi {
@@ -78548,7 +78657,7 @@ const useTableDragContextValue = ({
78548
78657
  };
78549
78658
  }, [grabTarget, canChangeColumnOrder]);
78550
78659
  };
78551
- const TableDragCloneContainer = forwardRef((props, ref) => {
78660
+ const TableDragCloneContainer = /*#__PURE__*/forwardRef((props, ref) => {
78552
78661
  import.meta.css = [css$k, "@jsenv/navi/src/control/table/drag/table_drag.jsx"];
78553
78662
  const {
78554
78663
  tableId
@@ -78559,7 +78668,7 @@ const TableDragCloneContainer = forwardRef((props, ref) => {
78559
78668
  "data-overlay-for": tableId
78560
78669
  });
78561
78670
  });
78562
- const TableColumnDropPreview = forwardRef((props, ref) => {
78671
+ const TableColumnDropPreview = /*#__PURE__*/forwardRef((props, ref) => {
78563
78672
  return jsxs("div", {
78564
78673
  ref: ref,
78565
78674
  className: "navi_table_column_drop_preview",
@@ -80655,7 +80764,7 @@ const css$f = /* css */`.navi_table_ui {
80655
80764
  overflow: hidden;
80656
80765
  }
80657
80766
  `;
80658
- const TableUI = forwardRef((props, ref) => {
80767
+ const TableUI = /*#__PURE__*/forwardRef((props, ref) => {
80659
80768
  import.meta.css = [css$f, "@jsenv/navi/src/control/table/table_ui.jsx"];
80660
80769
  const {
80661
80770
  tableRef,