@jsenv/navi 0.29.153 → 0.29.155

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.
@@ -7073,12 +7073,19 @@ const ARROW_SPACING = 8;
7073
7073
  // (closest "[aria-expanded]", see commands.js): a button inside the callout
7074
7074
  // closes the callout, not the picker or dialog around it. Never "false" — a
7075
7075
  // closed callout is removed, not kept.
7076
+ //
7077
+ // role="status" is the floor, not the final value: a message appearing without
7078
+ // the user asking for it is a live region, and a callout carrying no status at
7079
+ // all still owes one. A status raises it (the addStatusEffect swapping in
7080
+ // "alert" for warning/error), and it is also the name a test reaches the
7081
+ // callout by — navi's classes and ids are not a contract (docs/testid.md).
7076
7082
  const calloutTemplate = /* html */`
7077
7083
  <div
7078
7084
  class="navi_callout"
7079
7085
  popover="manual"
7080
7086
  navi-out-of-flow=""
7081
7087
  aria-expanded="true"
7088
+ role="status"
7082
7089
  >
7083
7090
  <div class="navi_callout_box">
7084
7091
  <div class="navi_callout_frame"></div>
@@ -61160,12 +61167,14 @@ const SKELETON_LIST_ITEM_CLASS = "navi_list_item_skeleton";
61160
61167
  // inside it (see ListItems): a run draws the rows it frames and holds the room
61161
61168
  // of the others.
61162
61169
  const RenderWindowContext = createContext(null);
61163
- // Carries List's own `columns` prop (a grid-template-columns value, e.g.
61170
+ // Carries List's own `itemColumns` prop (a grid-template-columns value, e.g.
61164
61171
  // "1fr auto auto") down to each ListItem/filler/fallback so they can render
61165
61172
  // as a subgrid row instead of a flex row — see ListItem's own use of this
61166
- // context, and List's own `columns` doc, for the full rationale (table-like
61173
+ // context, and List's own `itemColumns` doc, for the full rationale (table-like
61167
61174
  // column sizing that stays correct across a virtualized, windowed item set).
61168
- const ListColumnsContext = createContext(null);
61175
+ // List's own `columns` never reaches here: it lays the items themselves into
61176
+ // the track's columns, and an item then occupies a cell like anything else.
61177
+ const ListItemColumnsContext = createContext(null);
61169
61178
  // Carries the separator element/function down to each ListItem so separators
61170
61179
  // are only rendered between items that actually mount (post-filter, post-window).
61171
61180
  const SeparatorContext = createContext(null);
@@ -61251,6 +61260,8 @@ const css$x = /* css */`@layer navi {
61251
61260
  --x-list-scroll-spacing-bottom: calc(var(--list-footer-height, 0px) + var(--list-scroll-padding-bottom, 0px));
61252
61261
  --x-list-scroll-spacing-left: calc(var(--list-header-width, 0px) + var(--list-scroll-padding-left, 0px));
61253
61262
  --x-list-scroll-spacing-right: calc(var(--list-footer-width, 0px) + var(--list-scroll-padding-right, 0px));
61263
+ min-width: 0;
61264
+ max-width: var(--list-max-width, 100%);
61254
61265
  background-color: var(--x-list-background-color);
61255
61266
  border: var(--x-list-border-width) solid var(--x-list-border-color);
61256
61267
  border-top-left-radius: var(--x-corner-top-left-radius, var(--x-list-border-radius));
@@ -61258,8 +61269,6 @@ const css$x = /* css */`@layer navi {
61258
61269
  border-bottom-right-radius: var(--x-corner-bottom-right-radius, var(--x-list-border-radius));
61259
61270
  border-bottom-left-radius: var(--x-corner-bottom-left-radius, var(--x-list-border-radius));
61260
61271
  flex-direction: column;
61261
- min-width: 0;
61262
- max-width: 100%;
61263
61272
  transition: opacity .2s;
61264
61273
  display: flex;
61265
61274
  overflow: hidden;
@@ -61285,7 +61294,6 @@ const css$x = /* css */`@layer navi {
61285
61294
  min-width: inherit;
61286
61295
  max-width: var(--list-max-width, inherit);
61287
61296
  max-height: var(--list-max-height, inherit);
61288
- flex-wrap: inherit;
61289
61297
  overflow-anchor: none;
61290
61298
  overscroll-behavior: inherit;
61291
61299
  scrollbar-width: inherit;
@@ -61347,7 +61355,6 @@ const css$x = /* css */`@layer navi {
61347
61355
 
61348
61356
  .navi_list {
61349
61357
  box-sizing: border-box;
61350
- flex-wrap: inherit;
61351
61358
  outline: none;
61352
61359
  margin: 0;
61353
61360
  padding: 0;
@@ -61630,6 +61637,7 @@ const ListUI = props => {
61630
61637
  hoverWhileScrolling = false,
61631
61638
  lockSize,
61632
61639
  columns,
61640
+ itemColumns,
61633
61641
  searchText,
61634
61642
  searchNoMatchMode = "remove",
61635
61643
  loading,
@@ -61864,6 +61872,7 @@ const ListUI = props => {
61864
61872
  styleCSSVars: LIST_STYLE_CSS_VARS,
61865
61873
  pseudoClasses: LIST_PSEUDO_CLASSES,
61866
61874
  hasChildUsingForwardedProps: true,
61875
+ childPropSet: LIST_TRACK_PROP_SET,
61867
61876
  onnavi_request_scroll: e => {
61868
61877
  if (!Object.hasOwn(e.detail, "id")) {
61869
61878
  console.warn(`navi_request_scroll event is missing the "id" property in its detail.`, e);
@@ -61893,6 +61902,7 @@ const ListUI = props => {
61893
61902
  horizontal: horizontal,
61894
61903
  spacing: spacing,
61895
61904
  columns: columns,
61905
+ itemColumns: itemColumns,
61896
61906
  tracker: tracker,
61897
61907
  renderWindow: renderWindow,
61898
61908
  virtual: virtual,
@@ -61958,12 +61968,47 @@ const ListFirstResolver = props => {
61958
61968
  * horizontal?: boolean,
61959
61969
  * spacing?: string,
61960
61970
  * columns?: string,
61971
+ * itemColumns?: string,
61972
+ * alignX?: string,
61973
+ * alignY?: string,
61974
+ * flexWrap?: boolean,
61961
61975
  * expandX?: boolean,
61962
61976
  * expandY?: boolean,
61963
61977
  * expand?: boolean,
61964
61978
  * children?: import("ignore:preact").ComponentChildren,
61965
61979
  * [key: string]: any,
61966
61980
  * }>}
61981
+ * @param {string} [props.columns]
61982
+ * The list's own columns: a `grid-template-columns` value the ITEMS are laid
61983
+ * into — a sheet of icons (`repeat(auto-fill, minmax(2.5rem, 1fr))`), a row of
61984
+ * choices (`repeat(3, minmax(0, 1fr))`). Each item takes one cell, and an item
61985
+ * meant to take a whole line says so for itself
61986
+ * (`style={{ gridColumn: "1 / -1" }}`). Several items to a line is a shape the
61987
+ * list cannot virtualize — its render window and the room it holds for the
61988
+ * rows it does not draw both count one item per line — so it is for a set of
61989
+ * items the caller renders whole, not for a `<List.Items>` collection.
61990
+ * @param {string} [props.itemColumns]
61991
+ * The columns inside an ITEM: a `grid-template-columns` value each item fills
61992
+ * with its own children, a table whose cells line up down the list. Every item
61993
+ * becomes a subgrid row spanning all the columns, so a column is as wide as
61994
+ * the widest cell in it among the rows actually in the DOM — real column
61995
+ * sizing that stays right as the window moves. Rows of a table, then, where
61996
+ * `columns` above is a grid of items; the two cannot both be set.
61997
+ * @param {string} [props.alignX]
61998
+ * Where the items sit across the track — `alignX="center"` centres a
61999
+ * horizontal list's row of items inside a list wider than they are. Together
62000
+ * with `alignY`, `align` and `flexWrap`, this reaches the `<ul>` holding the
62001
+ * items rather than the frame drawn around it: the frame's only child is the
62002
+ * scroll box, which fills it and has nothing to arrange.
62003
+ * @param {boolean} [props.flexWrap]
62004
+ * Lets a horizontal list's items fall to the next line instead of running
62005
+ * past the edge — a row of choices under a `maxWidth`, say. Same caveat as
62006
+ * `columns` above: a line holding several items is not virtualizable.
62007
+ * @param {string} [props.overflow]
62008
+ * `"visible"` lets the items paint outside the list — a check in a row's
62009
+ * corner, a badge crossing the edge. A list clips by default, which is what
62010
+ * its rounded corners and its scroll box need, and the two cannot both be
62011
+ * true: asking for visible gives up the clipping, corners included.
61967
62012
  * @param {boolean} [props.itemTransition]
61968
62013
  * Names each row, so a change the application wraps in
61969
62014
  * `document.startViewTransition` is seen row by row — rows moving to their new
@@ -62087,6 +62132,7 @@ const ListContent = ({
62087
62132
  horizontal,
62088
62133
  spacing,
62089
62134
  columns,
62135
+ itemColumns,
62090
62136
  tracker,
62091
62137
  renderWindow,
62092
62138
  virtual,
@@ -62132,6 +62178,7 @@ const ListContent = ({
62132
62178
  horizontal: horizontal,
62133
62179
  spacing: spacing,
62134
62180
  columns: columns,
62181
+ itemColumns: itemColumns,
62135
62182
  ...listProps,
62136
62183
  tracker: tracker,
62137
62184
  renderWindow: renderWindow,
@@ -62143,6 +62190,12 @@ const ListContent = ({
62143
62190
  })
62144
62191
  });
62145
62192
  };
62193
+ // Where the items sit is a question about the track (the <ul>), not about the
62194
+ // frame around it: the frame's only child is the scroll box, which fills it and
62195
+ // has nothing to arrange. Box moves these out of the container's own props and
62196
+ // into BoxForwardedPropsContext, which ListContent reads and hands to the <ul>
62197
+ // — the same route `horizontal`, `spacing` and the column props take by hand.
62198
+ const LIST_TRACK_PROP_SET = new Set(["align", "alignX", "alignY", "flexWrap"]);
62146
62199
  const LIST_STYLE_CSS_VARS = {
62147
62200
  maxHeight: "--list-max-height",
62148
62201
  maxWidth: "--list-max-width",
@@ -63614,6 +63667,7 @@ const UnorderedList = ({
63614
63667
  horizontal,
63615
63668
  spacing,
63616
63669
  columns,
63670
+ itemColumns,
63617
63671
  children,
63618
63672
  ...rest
63619
63673
  }) => {
@@ -63622,11 +63676,19 @@ const UnorderedList = ({
63622
63676
  // A loading state drawing nothing keeps the message: an announced count of 0
63623
63677
  // already tells us the list is empty (see ListUI's loadingPlaceholderShown).
63624
63678
  const suppressFallback = loadingPlaceholderShown || Boolean(error);
63679
+
63680
+ // One track, one template: the two column props are the same
63681
+ // grid-template-columns seen from either end, and only differ in what an
63682
+ // item does with it (see useItemColumnsOverrideProps).
63683
+ if (columns && itemColumns) {
63684
+ console.warn(`List: "columns" and "itemColumns" cannot both be set — they define the same track. "columns" lays the items into the columns; "itemColumns" gives each item the columns its own children fill.`);
63685
+ }
63686
+ const trackColumns = columns || itemColumns;
63625
63687
  return jsxs(Box, {
63626
63688
  as: "ul",
63627
- flex: columns ? undefined : horizontal ? "x" : "y",
63628
- grid: columns ? true : undefined,
63629
- gridTemplateColumns: columns,
63689
+ flex: trackColumns ? undefined : horizontal ? "x" : "y",
63690
+ grid: trackColumns ? true : undefined,
63691
+ gridTemplateColumns: trackColumns,
63630
63692
  ...rest,
63631
63693
  spacing: spacing,
63632
63694
  baseClassName: "navi_list",
@@ -63648,8 +63710,8 @@ const UnorderedList = ({
63648
63710
  value: virtual,
63649
63711
  children: jsx(ListRowContext.Provider, {
63650
63712
  value: null,
63651
- children: jsx(ListColumnsContext.Provider, {
63652
- value: columns || null,
63713
+ children: jsx(ListItemColumnsContext.Provider, {
63714
+ value: columns ? null : itemColumns || null,
63653
63715
  children: jsx(ListDeclaredChildren, {
63654
63716
  children: children
63655
63717
  })
@@ -63718,8 +63780,8 @@ const VirtualFiller = ({
63718
63780
  });
63719
63781
  };
63720
63782
 
63721
- // List's own `columns` prop (see ListColumnsContext) turns a list item into
63722
- // a subgrid row instead of a flex row: its own children become direct grid
63783
+ // List's own `itemColumns` prop (see ListItemColumnsContext) turns a list item
63784
+ // into a subgrid row instead of a flex row: its own children become direct grid
63723
63785
  // items of List's own <ul>, so column widths are computed from whichever
63724
63786
  // rows are actually in the DOM (the currently-windowed items plus the
63725
63787
  // always-mounted header/footer) — real grid/table column sizing, not a
@@ -63729,11 +63791,10 @@ const VirtualFiller = ({
63729
63791
  // this they'd silently stay flex rows and break column alignment against
63730
63792
  // the rest of the grid). `flex` is force-cleared here because Box picks
63731
63793
  // flex over grid when both are set (see box.jsx's own boxFlow resolution),
63732
- // so a caller-provided `flex` prop (leftover from a non-columns usage)
63733
- // would otherwise silently win over this.
63734
- const useListItemColumnsOverrideProps = callerStyle => {
63735
- const columns = useContext(ListColumnsContext);
63736
- if (!columns) {
63794
+ // so a caller-provided `flex` prop would otherwise silently win over this.
63795
+ const useItemColumnsOverrideProps = callerStyle => {
63796
+ const itemColumns = useContext(ListItemColumnsContext);
63797
+ if (!itemColumns) {
63737
63798
  return undefined;
63738
63799
  }
63739
63800
  return {
@@ -63797,11 +63858,11 @@ const ListItemPresentationResolver = props => {
63797
63858
  });
63798
63859
  };
63799
63860
  const ListItemPresentation = props => {
63800
- const columnsOverrideProps = useListItemColumnsOverrideProps(props.style);
63861
+ const itemColumnsOverrideProps = useItemColumnsOverrideProps(props.style);
63801
63862
  return jsx(Box, {
63802
63863
  as: "li",
63803
63864
  ...props,
63804
- ...columnsOverrideProps
63865
+ ...itemColumnsOverrideProps
63805
63866
  });
63806
63867
  };
63807
63868
  // A <List.Item skeleton> — a non-interactive placeholder row shown while a list
@@ -63831,14 +63892,14 @@ const ListItemSkeleton = props => {
63831
63892
  paddingY = "s",
63832
63893
  ...rest
63833
63894
  } = props;
63834
- const columnsOverrideProps = useListItemColumnsOverrideProps(rest.style);
63895
+ const itemColumnsOverrideProps = useItemColumnsOverrideProps(rest.style);
63835
63896
  return jsx(Box, {
63836
63897
  as: "li",
63837
63898
  role: "presentation",
63838
63899
  "aria-hidden": "true",
63839
63900
  paddingY: paddingY,
63840
63901
  ...rest,
63841
- ...columnsOverrideProps,
63902
+ ...itemColumnsOverrideProps,
63842
63903
  baseClassName: `navi_list_item ${SKELETON_LIST_ITEM_CLASS}`,
63843
63904
  children: children ?? jsx(Text, {
63844
63905
  loading: true
@@ -63999,7 +64060,7 @@ const ListItemReal = props => {
63999
64060
  // CSS Highlight API: mark matching text ranges from matchInfo.matchRanges,
64000
64061
  // if any (there is no standalone highlight prop — see ListItem's own doc).
64001
64062
  useSearchHighlight(ref, matchInfo?.matchRanges, [children, hidden]);
64002
- const columnsOverrideProps = useListItemColumnsOverrideProps(rest.style);
64063
+ const itemColumnsOverrideProps = useItemColumnsOverrideProps(rest.style);
64003
64064
  // <List itemTransition>: the row carries the name it is to be paired by, and
64004
64065
  // the stylesheet turns it into a view-transition-name where a browser can
64005
64066
  // draw it inside the list (see the @supports block in the css above).
@@ -64068,7 +64129,7 @@ const ListItemReal = props => {
64068
64129
  id: id,
64069
64130
  "navi-list-item-real": "",
64070
64131
  ...rest,
64071
- ...columnsOverrideProps,
64132
+ ...itemColumnsOverrideProps,
64072
64133
  index: undefined,
64073
64134
  selected: undefined
64074
64135
  // We use aria-hidden and not hidden because hidden would be forced to
@@ -66891,6 +66952,10 @@ installImportMetaCssBuild(import.meta);const css$t = /* css */`@layer navi {
66891
66952
  --x-picker-padding-right: var(--picker-padding-right, var(--picker-padding-x, var(--picker-padding, var(--picker-padding-x-default))));
66892
66953
  --x-picker-padding-left: var(--picker-padding-left, var(--picker-padding-x, var(--picker-padding, var(--picker-padding-x-default))));
66893
66954
  --x-picker-padding-bottom: var(--picker-padding-bottom, var(--picker-padding-y, var(--picker-padding, var(--picker-padding-y-default))));
66955
+ --x-picker-press-padding-top: var(--picker-press-padding-top, var(--picker-press-padding-y, var(--picker-press-padding, 0px)));
66956
+ --x-picker-press-padding-right: var(--picker-press-padding-right, var(--picker-press-padding-x, var(--picker-press-padding, 0px)));
66957
+ --x-picker-press-padding-bottom: var(--picker-press-padding-bottom, var(--picker-press-padding-y, var(--picker-press-padding, 0px)));
66958
+ --x-picker-press-padding-left: var(--picker-press-padding-left, var(--picker-press-padding-x, var(--picker-press-padding, 0px)));
66894
66959
  --x-picker-color: var(--picker-color);
66895
66960
  --x-picker-icon-color: var(--picker-icon-color);
66896
66961
  --x-picker-align-x: var(--picker-align-x, var(--picker-align-x-default));
@@ -67037,14 +67102,17 @@ installImportMetaCssBuild(import.meta);const css$t = /* css */`@layer navi {
67037
67102
 
67038
67103
  &[navi-ui-custom] {
67039
67104
  & .navi_picker_input {
67040
- top: calc(-1 * var(--picker-border-width));
67041
- right: calc(-1 * var(--picker-border-width));
67042
- bottom: calc(-1 * var(--picker-border-width));
67043
- left: calc(-1 * var(--picker-border-width));
67044
- opacity: 0;
67045
- appearance: none;
67105
+ top: calc(-1 * (var(--picker-border-width) + var(--x-picker-press-padding-top)));
67106
+ right: calc(-1 *
67107
+ (var(--picker-border-width) + var(--x-picker-press-padding-right)));
67108
+ bottom: calc(-1 *
67109
+ (var(--picker-border-width) + var(--x-picker-press-padding-bottom)));
67110
+ left: calc(-1 * (var(--picker-border-width) + var(--x-picker-press-padding-left)));
67046
67111
  width: auto;
67047
67112
  height: auto;
67113
+ font: inherit;
67114
+ opacity: 0;
67115
+ appearance: none;
67048
67116
  position: absolute;
67049
67117
  }
67050
67118
  }
@@ -67224,6 +67292,12 @@ const PickerButton = props => {
67224
67292
  // keywords have to become lengths here — "s" reaching CSS untouched makes
67225
67293
  // the declaration invalid, silently, and the gap just goes away.
67226
67294
  props.slotSpacing = resolveSpacingSize(props.slotSpacing);
67295
+ for (const pressPaddingPropName of PRESS_PADDING_PROP_NAMES) {
67296
+ const pressPadding = props[pressPaddingPropName];
67297
+ if (pressPadding !== undefined) {
67298
+ props[pressPaddingPropName] = stringifySpacingStyle(pressPadding);
67299
+ }
67300
+ }
67227
67301
  const {
67228
67302
  ref,
67229
67303
  variant,
@@ -67782,6 +67856,13 @@ const isOpeningKeyboardOnMobile = type => {
67782
67856
  const NON_MOBILE_KEYBOARD_TYPES = new Set(["date", "month", "week", "time", "datetime-local", "color"]);
67783
67857
  const PICKER_BUTTON_PSEUDO_CLASSES = [":hover", ":focus", ":focus-visible", ":focus-within", ":read-only", ":disabled", ":-navi-loading", ":-navi-expanded", ":-navi-has-value"];
67784
67858
  const PickerInputPseudoClasses = [":focus", ":focus-visible", ":read-only", ":disabled", ":-navi-loading", ":-navi-has-value", ":-navi-expanded"];
67859
+
67860
+ // Spacing props that are not the names of real CSS styles, so Box hands them to
67861
+ // the custom property untouched: a size keyword would reach CSS as the word "s"
67862
+ // and a number as a unitless one, either of which makes the calc() using it
67863
+ // invalid and drops the press area back to the box. Hence the pass in
67864
+ // PickerButton, which turns them into lengths.
67865
+ const PRESS_PADDING_PROP_NAMES = ["pressPadding", "pressPaddingX", "pressPaddingY", "pressPaddingTop", "pressPaddingRight", "pressPaddingBottom", "pressPaddingLeft"];
67785
67866
  const PickerStyleCSSVars = {
67786
67867
  "outlineWidth": "--picker-outline-width",
67787
67868
  "borderWidth": "--picker-border-width",
@@ -67795,6 +67876,13 @@ const PickerStyleCSSVars = {
67795
67876
  "popupBorderRadius": "--picker-popup-border-radius",
67796
67877
  "dialogBorderWidth": "--picker-dialog-border-width",
67797
67878
  "slotSpacing": "--picker-slot-spacing",
67879
+ "pressPadding": "--picker-press-padding",
67880
+ "pressPaddingX": "--picker-press-padding-x",
67881
+ "pressPaddingY": "--picker-press-padding-y",
67882
+ "pressPaddingTop": "--picker-press-padding-top",
67883
+ "pressPaddingRight": "--picker-press-padding-right",
67884
+ "pressPaddingBottom": "--picker-press-padding-bottom",
67885
+ "pressPaddingLeft": "--picker-press-padding-left",
67798
67886
  // alignX/alignY resolve to these two on a flex-x box; naming the CSS style
67799
67887
  // (not the prop) is what styleCSSVars matches, so justifyContent/alignItems
67800
67888
  // passed directly land in the same variables.