@jsenv/navi 0.29.445 → 0.29.447

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.
@@ -84749,7 +84749,10 @@ const css$n = /* css */`.navi_split_button {
84749
84749
  * `pressOutside`, `escapeEffect`, `closeOnFocusOut`,
84750
84750
  * `scrollCapture`, `focusCapture`, `popupBackgroundColor`,
84751
84751
  * `popupBorderRadius`, `animation`. See picker.jsx for what each one says.
84752
- * Anything else lands on the split button's own box.
84752
+ * An `aria-*` attribute describes the button and reaches the main half —
84753
+ * `aria-pressed` for a split button whose main half toggles a mode;
84754
+ * `aria-hidden` excepted, which hides the whole control. Anything else lands
84755
+ * on the split button's own box.
84753
84756
  */
84754
84757
  const SplitButton = props => {
84755
84758
  import.meta.css = [css$n, "@jsenv/navi/src/control/input/split_button.jsx"];
@@ -84786,11 +84789,12 @@ const SplitButton = props => {
84786
84789
  id,
84787
84790
  ...rest
84788
84791
  } = props;
84789
- // Everything the popup answers to travels to the Picker; everything else is
84790
- // the split button's own box (margins, width, data-*). Sorted by name rather
84791
- // than named one by one so a Picker popup prop is forwarded by adding it to
84792
- // that list, not by threading it through here.
84793
- const [popupProps, boxProps] = splitPopupProps(rest);
84792
+ // Everything the popup answers to travels to the Picker; an aria-* describes
84793
+ // the button a screen reader meets, which is the main half; everything else
84794
+ // is the split button's own box (margins, width, data-*). Sorted by name
84795
+ // rather than named one by one so a Picker popup prop is forwarded by adding
84796
+ // it to that list, not by threading it through here.
84797
+ const [popupProps, buttonAriaProps, boxProps] = sortRestProps(rest);
84794
84798
  // A split button is a control on the page, not a place one goes: its menu
84795
84799
  // hangs off it even on a phone, where a picker left to itself would decide a
84796
84800
  // small screen means a dialog. Passing mode="dialog" asks for that back.
@@ -84860,6 +84864,7 @@ const SplitButton = props => {
84860
84864
  commandFor: commandFor,
84861
84865
  "command-value": commandValue,
84862
84866
  prefetch: prefetch,
84867
+ ...buttonAriaProps,
84863
84868
  ...halfProps,
84864
84869
  children: label === undefined ? optionShown?.label : label
84865
84870
  }), jsxs("div", {
@@ -84948,17 +84953,22 @@ const SplitButton = props => {
84948
84953
  // a caller reaches all of them through the split button (see picker.jsx's JSDoc
84949
84954
  // for what each one says).
84950
84955
  const POPUP_PROP_SET = new Set(["mode", "popupLayer", "popupTestId", "positionArea", "popoverMode", "popoverSpacing", "popupWidthFitContent", "popoverMaxHeight", "dialogMinWidth", "dialogMinHeight", "dialogMaxWidth", "dialogMaxHeight", "dialogExpand", "dialogExpandX", "dialogExpandY", "dockedOnSmallTouchScreen", "marginWithContainer", "backdrop", "backdropVariant", "backdropColor", "backdropFilter", "pressOutside", "escapeEffect", "closeOnFocusOut", "scrollCapture", "focusCapture", "popupBackgroundColor", "popupBorderRadius", "animation"]);
84951
- const splitPopupProps = props => {
84956
+ const sortRestProps = props => {
84952
84957
  const popupProps = {};
84958
+ const buttonAriaProps = {};
84953
84959
  const boxProps = {};
84954
84960
  for (const key of Object.keys(props)) {
84955
84961
  if (POPUP_PROP_SET.has(key)) {
84956
84962
  popupProps[key] = props[key];
84963
+ } else if (key.startsWith("aria-") && key !== "aria-hidden") {
84964
+ // aria-hidden hides a subtree rather than describing a button: on the
84965
+ // main half alone it would leave the chevron half exposed.
84966
+ buttonAriaProps[key] = props[key];
84957
84967
  } else {
84958
84968
  boxProps[key] = props[key];
84959
84969
  }
84960
84970
  }
84961
- return [popupProps, boxProps];
84971
+ return [popupProps, buttonAriaProps, boxProps];
84962
84972
  };
84963
84973
 
84964
84974
  /**
@@ -93467,6 +93477,12 @@ const DEFAULT_PLACEHOLDER_LIGHT = "#d4d8dd";
93467
93477
  const DEFAULT_PLACEHOLDER_DARK = "#374151";
93468
93478
 
93469
93479
  /**
93480
+ * The props may come in any order: `src` and `srcset` reach the element after
93481
+ * `loading` and the other hints. A plain `<img>` (or `<Box as="img">`) written
93482
+ * in JSX must put `loading` before `src`: WebKit, so every browser on iOS,
93483
+ * decides whether to load when `src` is set, and an image whose `src` came
93484
+ * first loads, lazy or not.
93485
+ *
93470
93486
  * @param {string|false} [props.placeholderColor] - Background color shown while the image loads.
93471
93487
  * Defaults to a light gray. Pass `false` to disable.
93472
93488
  * @param {boolean} [props.placeholderDark] - Use a dark default placeholder color,
@@ -93476,6 +93492,9 @@ const DEFAULT_PLACEHOLDER_DARK = "#374151";
93476
93492
  const Image = ({
93477
93493
  placeholderColor,
93478
93494
  placeholderDark = false,
93495
+ srcset,
93496
+ srcSet,
93497
+ src,
93479
93498
  ...rest
93480
93499
  }) => {
93481
93500
  import.meta.css = [css$5, "@jsenv/navi/src/graphic/image.jsx"];
@@ -93500,6 +93519,13 @@ const Image = ({
93500
93519
  imageEl.setAttribute("navi-loaded", "");
93501
93520
  rest.onLoad?.(e);
93502
93521
  }
93522
+ // Last, srcset before src: an <img> decides its request when they are
93523
+ // set, with the attributes it has at that moment. WebKit loads an image
93524
+ // whose src arrives before loading="lazy", and does not take it back.
93525
+ ,
93526
+ srcset: srcset,
93527
+ srcSet: srcSet,
93528
+ src: src
93503
93529
  });
93504
93530
  };
93505
93531