@jsenv/navi 0.29.30 → 0.29.32
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 +184 -47
- package/dist/jsenv_navi.js.map +10 -10
- package/docs/control_group.md +51 -11
- package/docs/interactions.md +45 -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
|
|
|
@@ -12294,6 +12304,30 @@ const swipeTypeOf = (axis, pulled) => {
|
|
|
12294
12304
|
* `view-transition-name` must be unique per document, so only the application can
|
|
12295
12305
|
* name what moves.
|
|
12296
12306
|
*
|
|
12307
|
+
* WHEN THE PRESS BECOMES A HOLD: `grab`.
|
|
12308
|
+
*
|
|
12309
|
+
* interactions={{ toss: remove, grab: () => navigator.vibrate?.(10) }}
|
|
12310
|
+
*
|
|
12311
|
+
* The three above all answer the RELEASE, and between the press and the release
|
|
12312
|
+
* there is one instant that counts for the hand making the gesture: the one where
|
|
12313
|
+
* the object stops being pressed and starts being held. `grab` is that instant,
|
|
12314
|
+
* and it is the same one whichever way the drag was entered — a finger held still,
|
|
12315
|
+
* a mouse travelled a few pixels.
|
|
12316
|
+
*
|
|
12317
|
+
* It matters most where it is least visible. On a screen the held object is under
|
|
12318
|
+
* the thumb that hides it, so the only feedback available is the one that is felt;
|
|
12319
|
+
* without it the hand waits, doubts the press was heard, and lets go too early. A
|
|
12320
|
+
* vibration is the usual answer, but nothing here is about vibration — a sound, a
|
|
12321
|
+
* class, a measure are the same moment.
|
|
12322
|
+
*
|
|
12323
|
+
* It is told, not asked: `grab` reports, so what it returns is not waited on and
|
|
12324
|
+
* preventing its event does not call the gesture off. And it is not an interaction
|
|
12325
|
+
* on its own — declared without one of the three above there is no gesture for it
|
|
12326
|
+
* to be the beginning of.
|
|
12327
|
+
*
|
|
12328
|
+
* A `longpress` needs nothing of this: it already happens at the moment the hold
|
|
12329
|
+
* is acquired rather than at the release (see interaction_press.js).
|
|
12330
|
+
*
|
|
12297
12331
|
* What the copy LOOKS like is the application's too. A copy of a transparent
|
|
12298
12332
|
* element is invisible — a row usually gets its background from the list around it,
|
|
12299
12333
|
* which the copy has left — so it is dressed through the attributes the gesture
|
|
@@ -12304,6 +12338,8 @@ const swipeTypeOf = (axis, pulled) => {
|
|
|
12304
12338
|
const MOVE = "move";
|
|
12305
12339
|
const REORDER = "reorder";
|
|
12306
12340
|
const TOSS = "toss";
|
|
12341
|
+
// The moment the press stops being a press and becomes a hold on the object.
|
|
12342
|
+
const GRAB = "grab";
|
|
12307
12343
|
|
|
12308
12344
|
// What makes an element a place something can land, written by the detector itself.
|
|
12309
12345
|
const REORDERABLE_ATTRIBUTE = "data-reorderable";
|
|
@@ -12319,11 +12355,16 @@ const TOSS_SPEED_ATTRIBUTE = "data-toss-speed";
|
|
|
12319
12355
|
|
|
12320
12356
|
defineInteractionDetector({
|
|
12321
12357
|
name: "drag",
|
|
12322
|
-
claims: (type) =>
|
|
12358
|
+
claims: (type) =>
|
|
12359
|
+
type === MOVE || type === REORDER || type === TOSS || type === GRAB,
|
|
12323
12360
|
setup: (element, trigger, { types, readConfig }) => {
|
|
12324
12361
|
const canMove = types.includes(MOVE);
|
|
12325
12362
|
const canReorder = types.includes(REORDER);
|
|
12326
12363
|
const canToss = types.includes(TOSS);
|
|
12364
|
+
if (!canMove && !canReorder && !canToss) {
|
|
12365
|
+
return undefined;
|
|
12366
|
+
}
|
|
12367
|
+
const tellsWhenGrabbed = types.includes(GRAB);
|
|
12327
12368
|
// Read at setup rather than at the press: a container can say it, and it is
|
|
12328
12369
|
// what the gesture is about rather than something it discovers.
|
|
12329
12370
|
const axisHolder = element.closest(`[${AXIS_ATTRIBUTE}]`);
|
|
@@ -12342,11 +12383,15 @@ defineInteractionDetector({
|
|
|
12342
12383
|
// SURROUNDINGS scroll on, which for a list is the axis the list runs on.
|
|
12343
12384
|
element.setAttribute("data-drag-source", axes === "x" ? "x" : "");
|
|
12344
12385
|
|
|
12386
|
+
// What a release can mean, which is not all of what was declared: "grab" is a
|
|
12387
|
+
// moment, not an outcome, and the gesture must not read it as one.
|
|
12388
|
+
const effects = types.filter((type) => type !== GRAB);
|
|
12389
|
+
|
|
12345
12390
|
const onPointerDown = (pointerDownEvent) => {
|
|
12346
12391
|
// What this element says a release can mean. The gesture then runs only what
|
|
12347
12392
|
// those need — no copy for a move, no drop hint for something that can only
|
|
12348
12393
|
// be thrown away.
|
|
12349
|
-
startDragTo(pointerDownEvent,
|
|
12394
|
+
startDragTo(pointerDownEvent, effects, {
|
|
12350
12395
|
draggedElement: element,
|
|
12351
12396
|
// Nothing to land on when nothing reorders.
|
|
12352
12397
|
itemSelector: canReorder ? `[${REORDERABLE_ATTRIBUTE}]` : undefined,
|
|
@@ -12367,6 +12412,19 @@ defineInteractionDetector({
|
|
|
12367
12412
|
longPressSlop: readConfig(SLOP_ATTRIBUTE, undefined),
|
|
12368
12413
|
tossDistance: readConfig(TOSS_DISTANCE_ATTRIBUTE, undefined),
|
|
12369
12414
|
tossSpeed: readConfig(TOSS_SPEED_ATTRIBUTE, undefined),
|
|
12415
|
+
// The one moment the gesture has that is not a release. Said here rather
|
|
12416
|
+
// than from the press that led to it, because the press is only one of the
|
|
12417
|
+
// two ways in: a finger holds still, a mouse travels a few pixels, and it
|
|
12418
|
+
// is the same instant — the object is now held. Nothing is done with what
|
|
12419
|
+
// comes back: this says something happened, it does not ask for work.
|
|
12420
|
+
onDragStart: tellsWhenGrabbed
|
|
12421
|
+
? (gestureInfo) => {
|
|
12422
|
+
trigger(GRAB, pointerDownEvent, {
|
|
12423
|
+
pointerType: pointerDownEvent.pointerType,
|
|
12424
|
+
gestureInfo,
|
|
12425
|
+
});
|
|
12426
|
+
}
|
|
12427
|
+
: undefined,
|
|
12370
12428
|
// Handed straight back in all three cases: what `trigger` returns is a
|
|
12371
12429
|
// promise while the answer is still going, which is what the gesture waits
|
|
12372
12430
|
// on before it lets go of what it carries.
|
|
@@ -25725,7 +25783,28 @@ installImportMetaCssBuild(import.meta);const css$W = /* css */`
|
|
|
25725
25783
|
color: var(--x-button-color);
|
|
25726
25784
|
background: none;
|
|
25727
25785
|
border: none;
|
|
25728
|
-
|
|
25786
|
+
/* Squared from the outside, corner by corner: a Group asks the member it
|
|
25787
|
+
joins for square corners along the seam, and the button it means may
|
|
25788
|
+
arrive wrapped (in a tooltip, in a link), so the ask travels down as
|
|
25789
|
+
inherited custom properties rather than as a selector aimed at the
|
|
25790
|
+
button. Each corner falls back to the button's own radius when nothing
|
|
25791
|
+
asks for anything. */
|
|
25792
|
+
border-top-left-radius: var(
|
|
25793
|
+
--x-corner-top-left-radius,
|
|
25794
|
+
var(--button-border-radius)
|
|
25795
|
+
);
|
|
25796
|
+
border-top-right-radius: var(
|
|
25797
|
+
--x-corner-top-right-radius,
|
|
25798
|
+
var(--button-border-radius)
|
|
25799
|
+
);
|
|
25800
|
+
border-bottom-right-radius: var(
|
|
25801
|
+
--x-corner-bottom-right-radius,
|
|
25802
|
+
var(--button-border-radius)
|
|
25803
|
+
);
|
|
25804
|
+
border-bottom-left-radius: var(
|
|
25805
|
+
--x-corner-bottom-left-radius,
|
|
25806
|
+
var(--button-border-radius)
|
|
25807
|
+
);
|
|
25729
25808
|
outline: none;
|
|
25730
25809
|
cursor: var(--x-button-cursor);
|
|
25731
25810
|
touch-action: manipulation;
|
|
@@ -25733,6 +25812,14 @@ installImportMetaCssBuild(import.meta);const css$W = /* css */`
|
|
|
25733
25812
|
-webkit-tap-highlight-color: var(--navi-control-tap-highlight-color);
|
|
25734
25813
|
|
|
25735
25814
|
.navi_button_content {
|
|
25815
|
+
/* The ask stops here: this element is the button's frame, so what is
|
|
25816
|
+
inside it (a popover the button opens, a button of its own) is no
|
|
25817
|
+
longer at the seam. */
|
|
25818
|
+
--x-corner-top-left-radius: initial;
|
|
25819
|
+
--x-corner-top-right-radius: initial;
|
|
25820
|
+
--x-corner-bottom-right-radius: initial;
|
|
25821
|
+
--x-corner-bottom-left-radius: initial;
|
|
25822
|
+
|
|
25736
25823
|
position: relative;
|
|
25737
25824
|
display: inherit;
|
|
25738
25825
|
box-sizing: border-box;
|
|
@@ -27745,6 +27832,15 @@ const css$V = /* css */`
|
|
|
27745
27832
|
}
|
|
27746
27833
|
|
|
27747
27834
|
.navi_dialog {
|
|
27835
|
+
/* A popup renders inside its opener's own subtree, so a corner claimed from
|
|
27836
|
+
the outside (see group.jsx) would otherwise reach the controls in here.
|
|
27837
|
+
It stops at the popup: what a popup holds is never at a seam of the group
|
|
27838
|
+
its opener belongs to. */
|
|
27839
|
+
--x-corner-top-left-radius: initial;
|
|
27840
|
+
--x-corner-top-right-radius: initial;
|
|
27841
|
+
--x-corner-bottom-right-radius: initial;
|
|
27842
|
+
--x-corner-bottom-left-radius: initial;
|
|
27843
|
+
|
|
27748
27844
|
/* Computed once, reused by both max-width itself and min-width's own
|
|
27749
27845
|
clamp below (see its comment for why) — avoids repeating the same
|
|
27750
27846
|
min(..., ...) expression twice. */
|
|
@@ -29014,6 +29110,15 @@ const css$U = /* css */`
|
|
|
29014
29110
|
}
|
|
29015
29111
|
|
|
29016
29112
|
.navi_popover {
|
|
29113
|
+
/* A popup renders inside its opener's own subtree, so a corner claimed from
|
|
29114
|
+
the outside (see group.jsx) would otherwise reach the controls in here.
|
|
29115
|
+
It stops at the popup: what a popup holds is never at a seam of the group
|
|
29116
|
+
its opener belongs to. */
|
|
29117
|
+
--x-corner-top-left-radius: initial;
|
|
29118
|
+
--x-corner-top-right-radius: initial;
|
|
29119
|
+
--x-corner-bottom-right-radius: initial;
|
|
29120
|
+
--x-corner-bottom-left-radius: initial;
|
|
29121
|
+
|
|
29017
29122
|
--x-popover-max-width: min(
|
|
29018
29123
|
var(--popover-max-width, var(--popover-maxmax-width)),
|
|
29019
29124
|
var(--container-position-remaining-width, var(--popover-maxmax-width)),
|
|
@@ -45669,6 +45774,14 @@ const inputCss = /* css */`
|
|
|
45669
45774
|
}
|
|
45670
45775
|
|
|
45671
45776
|
.navi_input_slot {
|
|
45777
|
+
/* A corner claimed from the outside (see group.jsx) is the frame's, and
|
|
45778
|
+
what lives in here is not the frame — a button in a slot, the content
|
|
45779
|
+
of a popup — so the ask stops at this boundary. */
|
|
45780
|
+
--x-corner-top-left-radius: initial;
|
|
45781
|
+
--x-corner-top-right-radius: initial;
|
|
45782
|
+
--x-corner-bottom-right-radius: initial;
|
|
45783
|
+
--x-corner-bottom-left-radius: initial;
|
|
45784
|
+
|
|
45672
45785
|
margin-right: var(--slot-spacing, calc(2px + 0.1em));
|
|
45673
45786
|
margin-left: var(--slot-spacing, calc(2px + 0.1em));
|
|
45674
45787
|
color: #5e4e4e;
|
|
@@ -47099,11 +47212,19 @@ const css$B = /* css */`
|
|
|
47099
47212
|
.navi_group {
|
|
47100
47213
|
--group-border-width: var(--navi-control-border-width);
|
|
47101
47214
|
|
|
47102
|
-
/*
|
|
47103
|
-
|
|
47104
|
-
|
|
47105
|
-
|
|
47106
|
-
|
|
47215
|
+
/* Two ways of asking for a square corner, and no selector ever reaching
|
|
47216
|
+
inside a member:
|
|
47217
|
+
- the property, on the member itself: a navi control declares the radius
|
|
47218
|
+
of its frame on its own root, and the inner element that draws that
|
|
47219
|
+
frame inherits it;
|
|
47220
|
+
- the custom property, which travels: a member can be an enrobage (a
|
|
47221
|
+
tooltip, a link) around the control that carries the frame, so the ask
|
|
47222
|
+
also goes down as --x-corner-*-radius, which a control reads as an
|
|
47223
|
+
override of its own radius. Private (the --x- prefix): navi's own
|
|
47224
|
+
controls answer it, an app never writes it. Whoever answers it also
|
|
47225
|
+
stops it (see .navi_button_content in button_ui.jsx), so a button
|
|
47226
|
+
deeper in — the clear cross in a picker's slot, the Save of a form in
|
|
47227
|
+
a popup the member opens — never mistakes itself for the seam. */
|
|
47107
47228
|
|
|
47108
47229
|
/* Members overlap by the width of one border, so along each seam one of the
|
|
47109
47230
|
two borders covers the other. Whichever member the user is on has to be
|
|
@@ -47121,8 +47242,15 @@ const css$B = /* css */`
|
|
|
47121
47242
|
position: relative;
|
|
47122
47243
|
z-index: var(--navi-z-index-control-hovered);
|
|
47123
47244
|
}
|
|
47245
|
+
/* Three spellings for one thing — the member showing a focus ring. Some
|
|
47246
|
+
controls take the focus on their own root (a button); others wrap a real
|
|
47247
|
+
input and draw the ring on their frame while the keyboard is held
|
|
47248
|
+
somewhere inside (a picker, a spin). The ring is what must not be sliced,
|
|
47249
|
+
so the member holding it is raised whether it wears the state itself or
|
|
47250
|
+
merely contains it. */
|
|
47124
47251
|
> *:focus-visible,
|
|
47125
|
-
> *[data-focus-visible]
|
|
47252
|
+
> *[data-focus-visible],
|
|
47253
|
+
> *:has([data-focus-visible]) {
|
|
47126
47254
|
position: relative;
|
|
47127
47255
|
z-index: var(--navi-z-index-control-focused);
|
|
47128
47256
|
}
|
|
@@ -47133,31 +47261,28 @@ const css$B = /* css */`
|
|
|
47133
47261
|
margin-left: calc(var(--border-width, var(--group-border-width)) * -1);
|
|
47134
47262
|
}
|
|
47135
47263
|
> *:first-child:not(:only-child) {
|
|
47264
|
+
--x-corner-top-right-radius: 0;
|
|
47265
|
+
--x-corner-bottom-right-radius: 0;
|
|
47266
|
+
|
|
47136
47267
|
border-top-right-radius: 0 !important;
|
|
47137
47268
|
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
47269
|
}
|
|
47144
47270
|
|
|
47145
47271
|
> *:last-child:not(:only-child) {
|
|
47272
|
+
--x-corner-top-left-radius: 0;
|
|
47273
|
+
--x-corner-bottom-left-radius: 0;
|
|
47274
|
+
|
|
47146
47275
|
border-top-left-radius: 0 !important;
|
|
47147
47276
|
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
47277
|
}
|
|
47154
47278
|
|
|
47155
47279
|
> *:not(:first-child):not(:last-child) {
|
|
47156
|
-
|
|
47280
|
+
--x-corner-top-left-radius: 0;
|
|
47281
|
+
--x-corner-top-right-radius: 0;
|
|
47282
|
+
--x-corner-bottom-right-radius: 0;
|
|
47283
|
+
--x-corner-bottom-left-radius: 0;
|
|
47157
47284
|
|
|
47158
|
-
|
|
47159
|
-
border-radius: 0 !important;
|
|
47160
|
-
}
|
|
47285
|
+
border-radius: 0 !important;
|
|
47161
47286
|
}
|
|
47162
47287
|
}
|
|
47163
47288
|
|
|
@@ -47167,31 +47292,28 @@ const css$B = /* css */`
|
|
|
47167
47292
|
margin-top: calc(var(--border-width, var(--group-border-width)) * -1);
|
|
47168
47293
|
}
|
|
47169
47294
|
> *:first-child:not(:only-child) {
|
|
47295
|
+
--x-corner-bottom-right-radius: 0;
|
|
47296
|
+
--x-corner-bottom-left-radius: 0;
|
|
47297
|
+
|
|
47170
47298
|
border-bottom-right-radius: 0 !important;
|
|
47171
47299
|
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
47300
|
}
|
|
47178
47301
|
|
|
47179
47302
|
> *:last-child:not(:only-child) {
|
|
47303
|
+
--x-corner-top-left-radius: 0;
|
|
47304
|
+
--x-corner-top-right-radius: 0;
|
|
47305
|
+
|
|
47180
47306
|
border-top-left-radius: 0 !important;
|
|
47181
47307
|
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
47308
|
}
|
|
47188
47309
|
|
|
47189
47310
|
> *:not(:first-child):not(:last-child) {
|
|
47190
|
-
|
|
47311
|
+
--x-corner-top-left-radius: 0;
|
|
47312
|
+
--x-corner-top-right-radius: 0;
|
|
47313
|
+
--x-corner-bottom-right-radius: 0;
|
|
47314
|
+
--x-corner-bottom-left-radius: 0;
|
|
47191
47315
|
|
|
47192
|
-
|
|
47193
|
-
border-radius: 0 !important;
|
|
47194
|
-
}
|
|
47316
|
+
border-radius: 0 !important;
|
|
47195
47317
|
}
|
|
47196
47318
|
}
|
|
47197
47319
|
}
|
|
@@ -47205,8 +47327,15 @@ const Group = ({
|
|
|
47205
47327
|
import.meta.css = [css$B, "@jsenv/navi/src/control/group.jsx"];
|
|
47206
47328
|
return jsx(Box, {
|
|
47207
47329
|
baseClassName: "navi_group",
|
|
47208
|
-
"data-vertical": vertical ? "" : undefined
|
|
47209
|
-
|
|
47330
|
+
"data-vertical": vertical ? "" : undefined
|
|
47331
|
+
/* A group draws one frame around its members, so they must share their
|
|
47332
|
+
top and bottom edges. A block box lays them out inline, where they
|
|
47333
|
+
align on baselines instead: a member whose content carries no text —
|
|
47334
|
+
the swatch of a color picker — has no baseline of its own, the one
|
|
47335
|
+
synthesized from its bottom edge does not land where its neighbours'
|
|
47336
|
+
text does, and the member rides a few pixels off, slicing the frame.
|
|
47337
|
+
Flex aligns the edges, in both directions. */,
|
|
47338
|
+
flex: vertical ? "y" : "x",
|
|
47210
47339
|
...props,
|
|
47211
47340
|
children: children
|
|
47212
47341
|
});
|
|
@@ -57431,6 +57560,14 @@ installImportMetaCssBuild(import.meta);const css$r = /* css */`
|
|
|
57431
57560
|
}
|
|
57432
57561
|
}
|
|
57433
57562
|
.navi_picker_right_slot {
|
|
57563
|
+
/* A corner claimed from the outside (see group.jsx) is the frame's, and
|
|
57564
|
+
what lives in here is not the frame — a button in a slot, the content
|
|
57565
|
+
of a popup — so the ask stops at this boundary. */
|
|
57566
|
+
--x-corner-top-left-radius: initial;
|
|
57567
|
+
--x-corner-top-right-radius: initial;
|
|
57568
|
+
--x-corner-bottom-right-radius: initial;
|
|
57569
|
+
--x-corner-bottom-left-radius: initial;
|
|
57570
|
+
|
|
57434
57571
|
display: inline-flex;
|
|
57435
57572
|
height: 1em;
|
|
57436
57573
|
height: 1lh;
|