@jsenv/navi 0.29.81 → 0.29.83

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.
@@ -22179,7 +22179,14 @@ const getFocusedBeforeTransfer = (e) => {
22179
22179
  * @param {boolean|"last-resort"|"restore"} autoFocus
22180
22180
  * When false the hook is a no-op. The other values say WHEN this element is
22181
22181
  * the right place for the keyboard (the whole ladder lives in
22182
- * findFocusTarget, see focus_transfer.js):
22182
+ * findFocusTarget, see focus_transfer.js, and the decisions behind it in
22183
+ * docs/autofocus.md):
22184
+ * - `true` — "I am what the user came for". On a FIELD it asks for the
22185
+ * keyboard outright, on a touch device included, where a popup otherwise
22186
+ * keeps it down: the comment box of a popup opened to write a comment. On a
22187
+ * CONTAINER it says the opposite, since a surface takes no keyboard by
22188
+ * being focused — the popup that is read before it is filled, arriving at
22189
+ * the top of its own reading order.
22183
22190
  * - `"last-resort"` — "not me, unless you have nothing else". Said by a
22184
22191
  * focusable that is a poor place to arrive (a picker's search box, a
22185
22192
  * panel's close button, a slide's chevron) and by a container about its own
@@ -22649,6 +22656,24 @@ const scrollTo = ({ x, y }) => {
22649
22656
  const [publishBeforeRouting, observeBeforeRouting] = createPubSub();
22650
22657
  const [publishAfterRouting, observeAfterRouting] = createPubSub();
22651
22658
 
22659
+ /*
22660
+ * A press aims at a place; it does not always go one step deeper. A row of tabs
22661
+ * is a lateral move — the neighbour is one finger away — so the whole row should
22662
+ * weigh one history entry: the arrow at the top and the phone's back button then
22663
+ * leave by where the reader came in, and the swipe (which replaces already, see
22664
+ * route_travel.jsx) and the press say the same thing.
22665
+ *
22666
+ * `<Link replace>` is that, and it travels as an attribute because the click
22667
+ * handler sees the anchor, not the component that rendered it — the same mouth
22668
+ * as what a link asks of a route transition.
22669
+ */
22670
+
22671
+ const LINK_REPLACE_ATTRIBUTE = "data-navi-replace";
22672
+
22673
+ const linkAsksForReplace = (linkElement) => {
22674
+ return linkElement.hasAttribute(LINK_REPLACE_ATTRIBUTE);
22675
+ };
22676
+
22652
22677
  const setupBrowserIntegrationViaHistory = ({
22653
22678
  applyActions,
22654
22679
  applyRouting,
@@ -22929,7 +22954,9 @@ const setupBrowserIntegrationViaHistory = ({
22929
22954
  e.preventDefault();
22930
22955
  handleRoutingTask(href, {
22931
22956
  reason: `"click" on a[href="${href}"]`,
22932
- navigationType: "push",
22957
+ // A link that takes the place of the current entry instead of stacking
22958
+ // on it says so on itself (see link_replace.js).
22959
+ navigationType: linkAsksForReplace(linkElement) ? "replace" : "push",
22933
22960
  // Who started it. Announced with the navigation because a press
22934
22961
  // carries things the url does not: what a link asks of a route
22935
22962
  // transition is the first of them (see route_transition.jsx). Read by
@@ -44326,6 +44353,12 @@ Object.assign(PSEUDO_CLASSES, {
44326
44353
  * the pair's movement and only turns it round, which is what the rare way
44327
44354
  * round a pair usually needs. Said nowhere else, the relations answer as
44328
44355
  * they always do.
44356
+ * @param {boolean} [props.replace] - Go to the destination by TAKING THE PLACE
44357
+ * of the current history entry instead of stacking onto it: the link stays a
44358
+ * link (an address, a middle click, the keyboard, `aria-current`), only the
44359
+ * way there changes. What a row of tabs wants — the neighbour is a lateral
44360
+ * move, not a step deeper, so the whole row weighs one entry and the back
44361
+ * button leaves by where the reader came in.
44329
44362
  * @param {boolean} [props.preventDefault] - Call `event.preventDefault()` on
44330
44363
  * click (navigation suppressed; `onClick` still runs).
44331
44364
  * @param {(event: MouseEvent) => void} [props.onClick]
@@ -44390,6 +44423,7 @@ const LinkPlain = props => {
44390
44423
  revealOnInteraction = false,
44391
44424
  hrefFallback = !anchor,
44392
44425
  routeTransition,
44426
+ replace,
44393
44427
  children
44394
44428
  } = props;
44395
44429
  if (anchor && !props.id) {
@@ -44503,6 +44537,13 @@ const LinkPlain = props => {
44503
44537
  // a name; anything more travels as JSON, which is also how a plain <a>
44504
44538
  // writes it by hand.
44505
44539
  const routeTransitionRequest = routeTransition === undefined || routeTransition === null ? undefined : typeof routeTransition === "string" ? routeTransition : JSON.stringify(routeTransition);
44540
+
44541
+ // Which way this link goes to the place it aims at, worn as an attribute so
44542
+ // that whoever answers the press reads it off the anchor (see
44543
+ // link_replace.js, which owns the name and does the reading).
44544
+ const replaceRequest = replace ? {
44545
+ [LINK_REPLACE_ATTRIBUTE]: ""
44546
+ } : null;
44506
44547
  const innerChildren = children || (hrefFallback ? href : children);
44507
44548
  const startIconEl = startIcon;
44508
44549
  const endIconEl = innerEndIcon;
@@ -44554,7 +44595,9 @@ const LinkPlain = props => {
44554
44595
  endIcon: undefined,
44555
44596
  hrefFallback: undefined,
44556
44597
  routeTransition: undefined,
44598
+ replace: undefined,
44557
44599
  "data-navi-route-transition-request": routeTransitionRequest,
44600
+ ...replaceRequest,
44558
44601
  onClick: e => {
44559
44602
  onClick?.(e);
44560
44603
  if (slide) {
@@ -49864,6 +49907,13 @@ const inputCss = /* css */`
49864
49907
 
49865
49908
  .navi_button {
49866
49909
  font-size: inherit;
49910
+ /* A <button> does not inherit the font on its own — same as the
49911
+ <input> above — and what stands in a slot is measured on the line
49912
+ box (Icon fillLine is 1lh): left on the browser's own font, the
49913
+ clear cross would resolve 1lh against a font the field is not
49914
+ written in, and the field would change height the moment the icon
49915
+ is replaced by the button. */
49916
+ font-family: inherit;
49867
49917
 
49868
49918
  /* A button in a slot (e.g. the clear cross) is drawn small but must
49869
49919
  not be small to hit: the spacing around it — the slot margins on the