@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.
- package/dist/jsenv_navi.js +134 -45
- package/dist/jsenv_navi.js.map +9 -9
- package/docs/control_group.md +51 -11
- package/docs/interactions.md +9 -8
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -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
|
-
|
|
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.
|
|
11831
|
-
*
|
|
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.
|
|
11914
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
/*
|
|
47103
|
-
|
|
47104
|
-
|
|
47105
|
-
|
|
47106
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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;
|