@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.
@@ -86980,7 +86980,10 @@ const css$n = /* css */`.navi_split_button {
86980
86980
  * `pressOutside`, `escapeEffect`, `closeOnFocusOut`,
86981
86981
  * `scrollCapture`, `focusCapture`, `popupBackgroundColor`,
86982
86982
  * `popupBorderRadius`, `animation`. See picker.jsx for what each one says.
86983
- * Anything else lands on the split button's own box.
86983
+ * An `aria-*` attribute describes the button and reaches the main half —
86984
+ * `aria-pressed` for a split button whose main half toggles a mode;
86985
+ * `aria-hidden` excepted, which hides the whole control. Anything else lands
86986
+ * on the split button's own box.
86984
86987
  */
86985
86988
  const SplitButton = props => {
86986
86989
  import.meta.css = [css$n, "@jsenv/navi/src/control/input/split_button.jsx"];
@@ -87017,11 +87020,12 @@ const SplitButton = props => {
87017
87020
  id,
87018
87021
  ...rest
87019
87022
  } = props;
87020
- // Everything the popup answers to travels to the Picker; everything else is
87021
- // the split button's own box (margins, width, data-*). Sorted by name rather
87022
- // than named one by one so a Picker popup prop is forwarded by adding it to
87023
- // that list, not by threading it through here.
87024
- const [popupProps, boxProps] = splitPopupProps(rest);
87023
+ // Everything the popup answers to travels to the Picker; an aria-* describes
87024
+ // the button a screen reader meets, which is the main half; everything else
87025
+ // is the split button's own box (margins, width, data-*). Sorted by name
87026
+ // rather than named one by one so a Picker popup prop is forwarded by adding
87027
+ // it to that list, not by threading it through here.
87028
+ const [popupProps, buttonAriaProps, boxProps] = sortRestProps(rest);
87025
87029
  // A split button is a control on the page, not a place one goes: its menu
87026
87030
  // hangs off it even on a phone, where a picker left to itself would decide a
87027
87031
  // small screen means a dialog. Passing mode="dialog" asks for that back.
@@ -87091,6 +87095,7 @@ const SplitButton = props => {
87091
87095
  commandFor: commandFor,
87092
87096
  "command-value": commandValue,
87093
87097
  prefetch: prefetch,
87098
+ ...buttonAriaProps,
87094
87099
  ...halfProps,
87095
87100
  children: label === undefined ? optionShown?.label : label
87096
87101
  }), jsxs("div", {
@@ -87179,17 +87184,22 @@ const SplitButton = props => {
87179
87184
  // a caller reaches all of them through the split button (see picker.jsx's JSDoc
87180
87185
  // for what each one says).
87181
87186
  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"]);
87182
- const splitPopupProps = props => {
87187
+ const sortRestProps = props => {
87183
87188
  const popupProps = {};
87189
+ const buttonAriaProps = {};
87184
87190
  const boxProps = {};
87185
87191
  for (const key of Object.keys(props)) {
87186
87192
  if (POPUP_PROP_SET.has(key)) {
87187
87193
  popupProps[key] = props[key];
87194
+ } else if (key.startsWith("aria-") && key !== "aria-hidden") {
87195
+ // aria-hidden hides a subtree rather than describing a button: on the
87196
+ // main half alone it would leave the chevron half exposed.
87197
+ buttonAriaProps[key] = props[key];
87188
87198
  } else {
87189
87199
  boxProps[key] = props[key];
87190
87200
  }
87191
87201
  }
87192
- return [popupProps, boxProps];
87202
+ return [popupProps, buttonAriaProps, boxProps];
87193
87203
  };
87194
87204
 
87195
87205
  /**
@@ -95706,6 +95716,12 @@ const DEFAULT_PLACEHOLDER_LIGHT = "#d4d8dd";
95706
95716
  const DEFAULT_PLACEHOLDER_DARK = "#374151";
95707
95717
 
95708
95718
  /**
95719
+ * The props may come in any order: `src` and `srcset` reach the element after
95720
+ * `loading` and the other hints. A plain `<img>` (or `<Box as="img">`) written
95721
+ * in JSX must put `loading` before `src`: WebKit, so every browser on iOS,
95722
+ * decides whether to load when `src` is set, and an image whose `src` came
95723
+ * first loads, lazy or not.
95724
+ *
95709
95725
  * @param {string|false} [props.placeholderColor] - Background color shown while the image loads.
95710
95726
  * Defaults to a light gray. Pass `false` to disable.
95711
95727
  * @param {boolean} [props.placeholderDark] - Use a dark default placeholder color,
@@ -95715,6 +95731,9 @@ const DEFAULT_PLACEHOLDER_DARK = "#374151";
95715
95731
  const Image = ({
95716
95732
  placeholderColor,
95717
95733
  placeholderDark = false,
95734
+ srcset,
95735
+ srcSet,
95736
+ src,
95718
95737
  ...rest
95719
95738
  }) => {
95720
95739
  import.meta.css = [css$5, "@jsenv/navi/src/graphic/image.jsx"];
@@ -95739,6 +95758,13 @@ const Image = ({
95739
95758
  imageEl.setAttribute("navi-loaded", "");
95740
95759
  rest.onLoad?.(e);
95741
95760
  }
95761
+ // Last, srcset before src: an <img> decides its request when they are
95762
+ // set, with the attributes it has at that moment. WebKit loads an image
95763
+ // whose src arrives before loading="lazy", and does not take it back.
95764
+ ,
95765
+ srcset: srcset,
95766
+ srcSet: srcSet,
95767
+ src: src
95742
95768
  });
95743
95769
  };
95744
95770