@jsenv/navi 0.29.30 → 0.29.31

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.
@@ -11763,7 +11763,11 @@ const readNumberFromDom = (element, attribute, defaultValue) => {
11763
11763
  * interaction_registry.js) — navi has no private one.
11764
11764
  *
11765
11765
  * `contextmenu` is the only one that takes something away: the browser's own menu
11766
- * would cover the answer to the request it is.
11766
+ * would cover the answer to the request it is. It takes it away AFTER, though —
11767
+ * a native interaction IS its own event, the very one the gate reads, and a gate
11768
+ * refuses what is already `defaultPrevented`. Cancelling first would therefore
11769
+ * make the interaction refuse itself, and no right click could ever get through.
11770
+ * So: ask, and only cover the browser's menu once something answered.
11767
11771
  */
11768
11772
 
11769
11773
 
@@ -11781,10 +11785,13 @@ defineInteractionDetector({
11781
11785
  setup: (element, trigger, { types }) => {
11782
11786
  const listeners = types.map((type) => {
11783
11787
  const listener = (nativeEvent) => {
11784
- if (type === "contextmenu") {
11788
+ const performed = trigger(type, nativeEvent);
11789
+ if (type === "contextmenu" && performed) {
11790
+ // Something answered the request, so the browser's own menu would only
11791
+ // cover it. Nothing answered (the gate refused, a listener said "not
11792
+ // this time"): the right click stays what it was, and opens the menu.
11785
11793
  nativeEvent.preventDefault();
11786
11794
  }
11787
- trigger(type, nativeEvent);
11788
11795
  };
11789
11796
  element.addEventListener(type, listener);
11790
11797
  return [type, listener];
@@ -11827,8 +11834,9 @@ installImportMetaCssBuild(import.meta);/**
11827
11834
  * that — and says where it is up to, for the caller to draw the rest with:
11828
11835
  *
11829
11836
  * - `--swipe-pulled`: how far it has come, signed, in px.
11830
- * - `--swipe-progress`: the same as a fraction of the element, signed. Inherited,
11831
- * so anything inside the element can read it.
11837
+ * - `--swipe-progress`: the same as a fraction of the element, signed.
11838
+ *
11839
+ * Both inherit, so anything inside the element can read them.
11832
11840
  * - `[data-swiping="left|right|up|down"]`: which way, while a finger holds it.
11833
11841
  * - `[data-swipe-past-threshold]`: letting go now would go through with it.
11834
11842
  *
@@ -11910,8 +11918,10 @@ const LONGPRESS_ATTRIBUTE = "data-longpress";
11910
11918
  import.meta.css = [/* css */`
11911
11919
  /* Declared, so the browser sees a NUMBER it can interpolate and calculate with:
11912
11920
  what a swipe reveals behind the element is drawn from this, and an undeclared
11913
- custom property only ever jumps from one value to the next. Inherited, so
11914
- anything inside the element can read it. */
11921
+ custom property only ever jumps from one value to the next. Both inherited,
11922
+ because what is drawn from them is drawn by a CHILD of the swiped element:
11923
+ the trail behind a row is inside the row, and a value that stopped at the
11924
+ element itself would reach 0 exactly where it is read. */
11915
11925
  @property --swipe-progress {
11916
11926
  syntax: "<number>";
11917
11927
  inherits: true;
@@ -11919,7 +11929,7 @@ import.meta.css = [/* css */`
11919
11929
  }
11920
11930
  @property --swipe-pulled {
11921
11931
  syntax: "<length>";
11922
- inherits: false;
11932
+ inherits: true;
11923
11933
  initial-value: 0px;
11924
11934
  }
11925
11935
 
@@ -25725,7 +25735,28 @@ installImportMetaCssBuild(import.meta);const css$W = /* css */`
25725
25735
  color: var(--x-button-color);
25726
25736
  background: none;
25727
25737
  border: none;
25728
- border-radius: var(--button-border-radius);
25738
+ /* Squared from the outside, corner by corner: a Group asks the member it
25739
+ joins for square corners along the seam, and the button it means may
25740
+ arrive wrapped (in a tooltip, in a link), so the ask travels down as
25741
+ inherited custom properties rather than as a selector aimed at the
25742
+ button. Each corner falls back to the button's own radius when nothing
25743
+ asks for anything. */
25744
+ border-top-left-radius: var(
25745
+ --x-corner-top-left-radius,
25746
+ var(--button-border-radius)
25747
+ );
25748
+ border-top-right-radius: var(
25749
+ --x-corner-top-right-radius,
25750
+ var(--button-border-radius)
25751
+ );
25752
+ border-bottom-right-radius: var(
25753
+ --x-corner-bottom-right-radius,
25754
+ var(--button-border-radius)
25755
+ );
25756
+ border-bottom-left-radius: var(
25757
+ --x-corner-bottom-left-radius,
25758
+ var(--button-border-radius)
25759
+ );
25729
25760
  outline: none;
25730
25761
  cursor: var(--x-button-cursor);
25731
25762
  touch-action: manipulation;
@@ -25733,6 +25764,14 @@ installImportMetaCssBuild(import.meta);const css$W = /* css */`
25733
25764
  -webkit-tap-highlight-color: var(--navi-control-tap-highlight-color);
25734
25765
 
25735
25766
  .navi_button_content {
25767
+ /* The ask stops here: this element is the button's frame, so what is
25768
+ inside it (a popover the button opens, a button of its own) is no
25769
+ longer at the seam. */
25770
+ --x-corner-top-left-radius: initial;
25771
+ --x-corner-top-right-radius: initial;
25772
+ --x-corner-bottom-right-radius: initial;
25773
+ --x-corner-bottom-left-radius: initial;
25774
+
25736
25775
  position: relative;
25737
25776
  display: inherit;
25738
25777
  box-sizing: border-box;
@@ -27745,6 +27784,15 @@ const css$V = /* css */`
27745
27784
  }
27746
27785
 
27747
27786
  .navi_dialog {
27787
+ /* A popup renders inside its opener's own subtree, so a corner claimed from
27788
+ the outside (see group.jsx) would otherwise reach the controls in here.
27789
+ It stops at the popup: what a popup holds is never at a seam of the group
27790
+ its opener belongs to. */
27791
+ --x-corner-top-left-radius: initial;
27792
+ --x-corner-top-right-radius: initial;
27793
+ --x-corner-bottom-right-radius: initial;
27794
+ --x-corner-bottom-left-radius: initial;
27795
+
27748
27796
  /* Computed once, reused by both max-width itself and min-width's own
27749
27797
  clamp below (see its comment for why) — avoids repeating the same
27750
27798
  min(..., ...) expression twice. */
@@ -29014,6 +29062,15 @@ const css$U = /* css */`
29014
29062
  }
29015
29063
 
29016
29064
  .navi_popover {
29065
+ /* A popup renders inside its opener's own subtree, so a corner claimed from
29066
+ the outside (see group.jsx) would otherwise reach the controls in here.
29067
+ It stops at the popup: what a popup holds is never at a seam of the group
29068
+ its opener belongs to. */
29069
+ --x-corner-top-left-radius: initial;
29070
+ --x-corner-top-right-radius: initial;
29071
+ --x-corner-bottom-right-radius: initial;
29072
+ --x-corner-bottom-left-radius: initial;
29073
+
29017
29074
  --x-popover-max-width: min(
29018
29075
  var(--popover-max-width, var(--popover-maxmax-width)),
29019
29076
  var(--container-position-remaining-width, var(--popover-maxmax-width)),
@@ -45669,6 +45726,14 @@ const inputCss = /* css */`
45669
45726
  }
45670
45727
 
45671
45728
  .navi_input_slot {
45729
+ /* A corner claimed from the outside (see group.jsx) is the frame's, and
45730
+ what lives in here is not the frame — a button in a slot, the content
45731
+ of a popup — so the ask stops at this boundary. */
45732
+ --x-corner-top-left-radius: initial;
45733
+ --x-corner-top-right-radius: initial;
45734
+ --x-corner-bottom-right-radius: initial;
45735
+ --x-corner-bottom-left-radius: initial;
45736
+
45672
45737
  margin-right: var(--slot-spacing, calc(2px + 0.1em));
45673
45738
  margin-left: var(--slot-spacing, calc(2px + 0.1em));
45674
45739
  color: #5e4e4e;
@@ -47099,11 +47164,19 @@ const css$B = /* css */`
47099
47164
  .navi_group {
47100
47165
  --group-border-width: var(--navi-control-border-width);
47101
47166
 
47102
- /* Squaring the joined corners is said on the direct child alone: a navi
47103
- control declares the radius of its frame on its own root, and whatever
47104
- inner element actually draws the frame inherits it. .navi_button_content
47105
- is the exception a button's frame sits on it and a button can arrive
47106
- wrapped (a tooltip, a link), so it is named on its own. */
47167
+ /* Two ways of asking for a square corner, and no selector ever reaching
47168
+ inside a member:
47169
+ - the property, on the member itself: a navi control declares the radius
47170
+ of its frame on its own root, and the inner element that draws that
47171
+ frame inherits it;
47172
+ - the custom property, which travels: a member can be an enrobage (a
47173
+ tooltip, a link) around the control that carries the frame, so the ask
47174
+ also goes down as --x-corner-*-radius, which a control reads as an
47175
+ override of its own radius. Private (the --x- prefix): navi's own
47176
+ controls answer it, an app never writes it. Whoever answers it also
47177
+ stops it (see .navi_button_content in button_ui.jsx), so a button
47178
+ deeper in — the clear cross in a picker's slot, the Save of a form in
47179
+ a popup the member opens — never mistakes itself for the seam. */
47107
47180
 
47108
47181
  /* Members overlap by the width of one border, so along each seam one of the
47109
47182
  two borders covers the other. Whichever member the user is on has to be
@@ -47121,8 +47194,15 @@ const css$B = /* css */`
47121
47194
  position: relative;
47122
47195
  z-index: var(--navi-z-index-control-hovered);
47123
47196
  }
47197
+ /* Three spellings for one thing — the member showing a focus ring. Some
47198
+ controls take the focus on their own root (a button); others wrap a real
47199
+ input and draw the ring on their frame while the keyboard is held
47200
+ somewhere inside (a picker, a spin). The ring is what must not be sliced,
47201
+ so the member holding it is raised whether it wears the state itself or
47202
+ merely contains it. */
47124
47203
  > *:focus-visible,
47125
- > *[data-focus-visible] {
47204
+ > *[data-focus-visible],
47205
+ > *:has([data-focus-visible]) {
47126
47206
  position: relative;
47127
47207
  z-index: var(--navi-z-index-control-focused);
47128
47208
  }
@@ -47133,31 +47213,28 @@ const css$B = /* css */`
47133
47213
  margin-left: calc(var(--border-width, var(--group-border-width)) * -1);
47134
47214
  }
47135
47215
  > *:first-child:not(:only-child) {
47216
+ --x-corner-top-right-radius: 0;
47217
+ --x-corner-bottom-right-radius: 0;
47218
+
47136
47219
  border-top-right-radius: 0 !important;
47137
47220
  border-bottom-right-radius: 0 !important;
47138
-
47139
- .navi_button_content {
47140
- border-top-right-radius: 0 !important;
47141
- border-bottom-right-radius: 0 !important;
47142
- }
47143
47221
  }
47144
47222
 
47145
47223
  > *:last-child:not(:only-child) {
47224
+ --x-corner-top-left-radius: 0;
47225
+ --x-corner-bottom-left-radius: 0;
47226
+
47146
47227
  border-top-left-radius: 0 !important;
47147
47228
  border-bottom-left-radius: 0 !important;
47148
-
47149
- .navi_button_content {
47150
- border-top-left-radius: 0 !important;
47151
- border-bottom-left-radius: 0 !important;
47152
- }
47153
47229
  }
47154
47230
 
47155
47231
  > *:not(:first-child):not(:last-child) {
47156
- border-radius: 0 !important;
47232
+ --x-corner-top-left-radius: 0;
47233
+ --x-corner-top-right-radius: 0;
47234
+ --x-corner-bottom-right-radius: 0;
47235
+ --x-corner-bottom-left-radius: 0;
47157
47236
 
47158
- .navi_button_content {
47159
- border-radius: 0 !important;
47160
- }
47237
+ border-radius: 0 !important;
47161
47238
  }
47162
47239
  }
47163
47240
 
@@ -47167,31 +47244,28 @@ const css$B = /* css */`
47167
47244
  margin-top: calc(var(--border-width, var(--group-border-width)) * -1);
47168
47245
  }
47169
47246
  > *:first-child:not(:only-child) {
47247
+ --x-corner-bottom-right-radius: 0;
47248
+ --x-corner-bottom-left-radius: 0;
47249
+
47170
47250
  border-bottom-right-radius: 0 !important;
47171
47251
  border-bottom-left-radius: 0 !important;
47172
-
47173
- .navi_button_content {
47174
- border-bottom-right-radius: 0 !important;
47175
- border-bottom-left-radius: 0 !important;
47176
- }
47177
47252
  }
47178
47253
 
47179
47254
  > *:last-child:not(:only-child) {
47255
+ --x-corner-top-left-radius: 0;
47256
+ --x-corner-top-right-radius: 0;
47257
+
47180
47258
  border-top-left-radius: 0 !important;
47181
47259
  border-top-right-radius: 0 !important;
47182
-
47183
- .navi_button_content {
47184
- border-top-left-radius: 0 !important;
47185
- border-top-right-radius: 0 !important;
47186
- }
47187
47260
  }
47188
47261
 
47189
47262
  > *:not(:first-child):not(:last-child) {
47190
- border-radius: 0 !important;
47263
+ --x-corner-top-left-radius: 0;
47264
+ --x-corner-top-right-radius: 0;
47265
+ --x-corner-bottom-right-radius: 0;
47266
+ --x-corner-bottom-left-radius: 0;
47191
47267
 
47192
- .navi_button_content {
47193
- border-radius: 0 !important;
47194
- }
47268
+ border-radius: 0 !important;
47195
47269
  }
47196
47270
  }
47197
47271
  }
@@ -47205,8 +47279,15 @@ const Group = ({
47205
47279
  import.meta.css = [css$B, "@jsenv/navi/src/control/group.jsx"];
47206
47280
  return jsx(Box, {
47207
47281
  baseClassName: "navi_group",
47208
- "data-vertical": vertical ? "" : undefined,
47209
- row: row,
47282
+ "data-vertical": vertical ? "" : undefined
47283
+ /* A group draws one frame around its members, so they must share their
47284
+ top and bottom edges. A block box lays them out inline, where they
47285
+ align on baselines instead: a member whose content carries no text —
47286
+ the swatch of a color picker — has no baseline of its own, the one
47287
+ synthesized from its bottom edge does not land where its neighbours'
47288
+ text does, and the member rides a few pixels off, slicing the frame.
47289
+ Flex aligns the edges, in both directions. */,
47290
+ flex: vertical ? "y" : "x",
47210
47291
  ...props,
47211
47292
  children: children
47212
47293
  });
@@ -57431,6 +57512,14 @@ installImportMetaCssBuild(import.meta);const css$r = /* css */`
57431
57512
  }
57432
57513
  }
57433
57514
  .navi_picker_right_slot {
57515
+ /* A corner claimed from the outside (see group.jsx) is the frame's, and
57516
+ what lives in here is not the frame — a button in a slot, the content
57517
+ of a popup — so the ask stops at this boundary. */
57518
+ --x-corner-top-left-radius: initial;
57519
+ --x-corner-top-right-radius: initial;
57520
+ --x-corner-bottom-right-radius: initial;
57521
+ --x-corner-bottom-left-radius: initial;
57522
+
57434
57523
  display: inline-flex;
57435
57524
  height: 1em;
57436
57525
  height: 1lh;