@jsenv/navi 0.30.28 → 0.30.29

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.
@@ -13490,7 +13490,7 @@ const CLICK_TO_EXPAND_SELECTOR = "summary, [aria-expanded]";
13490
13490
  // A popup is written inside whatever opened it, but it is not part of it on
13491
13491
  // screen: a control inside a popup must not be read as a click on the region
13492
13492
  // the popup happens to be nested in.
13493
- const POPUP_SELECTOR = "[navi-control='popover'], [navi-control='dialog']";
13493
+ const POPUP_SELECTOR$1 = "[navi-control='popover'], [navi-control='dialog']";
13494
13494
 
13495
13495
  /**
13496
13496
  * Cancels `event` when the control consumed a click that a surrounding
@@ -13528,7 +13528,7 @@ const findClickToExpandRegion = (element) => {
13528
13528
  while (ancestor) {
13529
13529
  // Tested first: a popup carries `aria-expanded` of its own, so it would
13530
13530
  // otherwise pass for the region containing its own content.
13531
- if (ancestor.matches(POPUP_SELECTOR)) {
13531
+ if (ancestor.matches(POPUP_SELECTOR$1)) {
13532
13532
  return null;
13533
13533
  }
13534
13534
  if (ancestor.matches(CLICK_TO_EXPAND_SELECTOR)) {
@@ -43713,6 +43713,17 @@ const resolveClosestExpandable = (el) => {
43713
43713
  }
43714
43714
  return expandableRepeatedBy(expandable) || expandable;
43715
43715
  };
43716
+ // The popup a decision taken inside it answers (a clear, a send). A section
43717
+ // revealed in the page flow (<Expandable>, data-in-flow) is not one: it belongs
43718
+ // to whatever holds it, a page or a popup, so the walk goes through it.
43719
+ const POPUP_SELECTOR = "[aria-expanded]:not([data-in-flow])";
43720
+ const resolveClosestPopup = (el) => {
43721
+ const popup = el.closest(POPUP_SELECTOR);
43722
+ if (!popup) {
43723
+ return null;
43724
+ }
43725
+ return expandableRepeatedBy(popup) || popup;
43726
+ };
43716
43727
  // A control's host repeats the aria-expanded of its root, beside its role, for
43717
43728
  // assistive tech to read (a picker's <input>, a combobox or a button). The root
43718
43729
  // is the expandable: the host is a leaf the walk lands on only when it is the
@@ -43729,16 +43740,16 @@ const expandableRepeatedBy = (el) => {
43729
43740
  }
43730
43741
  return null;
43731
43742
  };
43732
- // The surface a send is decided on: the expandable holding the CONTROL that
43733
- // sends, never one that control is itself. A picker's own root carries
43734
- // aria-expanded for its popup, and a confirm picker pressed as a whole (see
43743
+ // The surface a send is decided on: the popup holding the CONTROL that sends,
43744
+ // never one that control is itself. A picker's own root carries aria-expanded
43745
+ // for its popup, and a confirm picker pressed as a whole (see
43735
43746
  // picker_confirm.jsx) sends from its input: what it answers is the surface
43736
43747
  // around the picker, not the picker. Same for a popup told to send upward
43737
43748
  // once it has closed (data-after-send="--navi-send"): the surface above it.
43738
- const resolveExpandableAround = (source) => {
43749
+ const resolvePopupAround = (source) => {
43739
43750
  const sender = findControlRoot(source) || source;
43740
43751
  const parent = sender.parentElement;
43741
- return parent ? resolveClosestExpandable(parent) : null;
43752
+ return parent ? resolveClosestPopup(parent) : null;
43742
43753
  };
43743
43754
  // An element carrying navi-command-proxy-for="anchorId" stands in for that
43744
43755
  // other element as the command's source when the source is forwarded to
@@ -43764,16 +43775,14 @@ const resolveClosestControlWithAction = (el) => {
43764
43775
  return findClosestControlWithAction(el);
43765
43776
  };
43766
43777
  // Both can enclose the send's source: a form inside a dialog is a control with
43767
- // an action, inside an expandable. The nearer one owns the send — a button
43768
- // inside that form means "submit this form", not "confirm the dialog around
43769
- // it", and the same button placed directly in the dialog means the opposite.
43770
- const resolveClosestSendTarget = (expandable, controlWithAction) => {
43771
- if (!expandable || !controlWithAction) {
43772
- return expandable || controlWithAction;
43778
+ // an action, inside a popup. The nearer one owns the send — a button inside
43779
+ // that form means "submit this form", not "confirm the dialog around it", and
43780
+ // the same button placed directly in the dialog means the opposite.
43781
+ const resolveClosestSendTarget = (popup, controlWithAction) => {
43782
+ if (!popup || !controlWithAction) {
43783
+ return popup || controlWithAction;
43773
43784
  }
43774
- return expandable.contains(controlWithAction)
43775
- ? controlWithAction
43776
- : expandable;
43785
+ return popup.contains(controlWithAction) ? controlWithAction : popup;
43777
43786
  };
43778
43787
 
43779
43788
  const resolveCommandValue = (source, event) => {
@@ -43959,9 +43968,10 @@ const clearCommand = (source, event) => {
43959
43968
  }
43960
43969
  // Only what is open: the clear cross of a picker sits on the closed
43961
43970
  // trigger, with nothing to close. A clear pressed INSIDE an open popup is
43962
- // the one this is for: it answers the popup, so the popup goes away.
43963
- const expandable = resolveClosestExpandable(source);
43964
- if (expandable?.getAttribute("aria-expanded") !== "true") {
43971
+ // the one this is for: it answers the popup, so the popup goes away. An
43972
+ // open section of the page is answered by nothing pressed in it.
43973
+ const popup = resolveClosestPopup(source);
43974
+ if (popup?.getAttribute("aria-expanded") !== "true") {
43965
43975
  return;
43966
43976
  }
43967
43977
  // Asked of the popup itself, not resolved again from the source: a
@@ -43969,7 +43979,7 @@ const clearCommand = (source, event) => {
43969
43979
  // picker names the input it empties), and a close resolved from it would
43970
43980
  // aim at that input's picker — busy with the send it was just handed —
43971
43981
  // rather than at the popup the cross is in.
43972
- triggerNaviCommand(expandable, "--navi-close", clearEvent, {
43982
+ triggerNaviCommand(popup, "--navi-close", clearEvent, {
43973
43983
  optional: true,
43974
43984
  });
43975
43985
  };
@@ -44013,7 +44023,8 @@ const resetCommand = (source, event) => {
44013
44023
  * same act, a level down. A popup opened from another popup answers for
44014
44024
  * itself only — say `data-after-send="--navi-send"` on the sending control
44015
44025
  * to make the decision travel up to the surface holding it;
44016
- * - the document: nothing. A form on a page stays where it is.
44026
+ * - the document: nothing. A form on a page stays where it is, open
44027
+ * <Expandable> sections around it included (see resolveClosestPopup).
44017
44028
  */
44018
44029
  // What follows a send that went through — and it is asked of the button that
44019
44030
  // sent before the form it sent, because a form with two submit buttons has two
@@ -44044,7 +44055,7 @@ const resolveAfterSend = (target, requester, surface) => {
44044
44055
  // the target: a popup that IS the send target is handled on its own (see the
44045
44056
  // aria-expanded branch in sendCommand), and must not answer twice.
44046
44057
  const resolveSendSurface = (target) =>
44047
- target.parentElement?.closest(`[data-slide], [aria-expanded]`);
44058
+ target.parentElement?.closest(`[data-slide], ${POPUP_SELECTOR}`);
44048
44059
  // What follows a send is caused by the send, not by the gesture: the send
44049
44060
  // answered the gesture and may have prevented it (an Enter must not also click
44050
44061
  // the submit button, nor activate the trigger of the popup it closed), and a
@@ -44057,11 +44068,10 @@ const createSentEvent = (event) => {
44057
44068
  };
44058
44069
 
44059
44070
  const sendCommand = (source, event, { requester }) => {
44060
- const expandable = resolveExpandableAround(source);
44061
44071
  const target =
44062
44072
  resolveExplicitTarget(source) ||
44063
44073
  resolveClosestSendTarget(
44064
- expandable,
44074
+ resolvePopupAround(source),
44065
44075
  resolveClosestControlWithAction(source),
44066
44076
  );
44067
44077
  if (!target) {
@@ -44072,7 +44082,7 @@ const sendCommand = (source, event, { requester }) => {
44072
44082
  // looking at, and a decision just taken there is a reason to leave it. The
44073
44083
  // NEAREST surface answers, and only that one — a form inside a slide inside a
44074
44084
  // dialog goes back a slide, it does not also close the dialog.
44075
- // send inside expandable — the control itself when it sends from its host,
44085
+ // send inside popup — the control itself when it sends from its host,
44076
44086
  // whose aria-expanded is its root's (see expandableRepeatedBy)
44077
44087
  if (
44078
44088
  target.getAttribute("aria-expanded") === "true" &&
@@ -61501,7 +61511,11 @@ const Expandable = props => {
61501
61511
  return jsx(Box, {
61502
61512
  ref: rootRef,
61503
61513
  baseClassName: "navi_expandable",
61504
- "aria-expanded": opened ? "true" : "false",
61514
+ "aria-expanded": opened ? "true" : "false"
61515
+ // Read by commands.js: open or not, this is no popup — a clear or a send
61516
+ // pressed inside does not close it (see resolveClosestPopup).
61517
+ ,
61518
+ "data-in-flow": "",
61505
61519
  "data-layout": isColumn ? "column" : undefined,
61506
61520
  "data-open-direction": revealDirection,
61507
61521
  "data-animation": animation ? "" : undefined,
@@ -61596,6 +61610,7 @@ const ExpandableUI = ({
61596
61610
  role: "button",
61597
61611
  tabIndex: 0,
61598
61612
  "aria-expanded": opened,
61613
+ "data-in-flow": "",
61599
61614
  "aria-controls": contentId,
61600
61615
  onClick: onUIClick,
61601
61616
  onPointerDown: onUIPointerDown,