@jsenv/navi 0.29.149 → 0.29.151
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 +302 -246
- package/dist/jsenv_navi.js.map +31 -29
- package/dist/jsenv_navi_side_effects.js +1 -1
- package/dist/jsenv_navi_side_effects.js.map +1 -1
- package/docs/create_and_edit.md +1 -1
- package/docs/css_architecture.md +3 -2
- package/docs/popup_open.md +16 -11
- package/package.json +1 -2
package/dist/jsenv_navi.js
CHANGED
|
@@ -5596,8 +5596,19 @@ const CLICK_SELECTOR = selfInteractionSelector("click");
|
|
|
5596
5596
|
* The closest element CLAIMING THE PRESS wins, not the closest one claiming
|
|
5597
5597
|
* anything: an affordance that took only the drag is transparent here, exactly
|
|
5598
5598
|
* as it is to the drag readers when it took only the click.
|
|
5599
|
+
*
|
|
5600
|
+
* @param {Event} event The gesture being arbitrated.
|
|
5601
|
+
* @param {Element} controlHost The control asking whether the press is its own.
|
|
5602
|
+
* @param {Element} [requester] Who asked this control to act, when someone did
|
|
5603
|
+
* — the source of a command, typically. The claim answers "was this press
|
|
5604
|
+
* yours or the affordance's"; it says nothing about a request that affordance
|
|
5605
|
+
* is making, and the answer there is always yes.
|
|
5599
5606
|
*/
|
|
5600
|
-
const isAimedAtSelfInteractionsBelow = (
|
|
5607
|
+
const isAimedAtSelfInteractionsBelow = (
|
|
5608
|
+
event,
|
|
5609
|
+
controlHost,
|
|
5610
|
+
requester,
|
|
5611
|
+
) => {
|
|
5601
5612
|
const target = event?.target;
|
|
5602
5613
|
if (!target || typeof target.closest !== "function") {
|
|
5603
5614
|
return false;
|
|
@@ -5611,6 +5622,13 @@ const isAimedAtSelfInteractionsBelow = (event, controlHost) => {
|
|
|
5611
5622
|
if (claimer === controlHost || claimer.contains(controlHost)) {
|
|
5612
5623
|
return false;
|
|
5613
5624
|
}
|
|
5625
|
+
// The claimer is the one asking. Its claim took the press so IT would decide
|
|
5626
|
+
// what the press means, and this is that decision arriving — a clear cross
|
|
5627
|
+
// sending "--navi-clear" to the field it sits in. Stepping back here would be
|
|
5628
|
+
// the control refusing the very request the claim exists to let through.
|
|
5629
|
+
if (requester && (claimer === requester || claimer.contains(requester))) {
|
|
5630
|
+
return false;
|
|
5631
|
+
}
|
|
5614
5632
|
// From the root rather than the host: a layered control (a picker holding an
|
|
5615
5633
|
// input) has its gate on the input, and what the application drew sits beside
|
|
5616
5634
|
// it, not in it.
|
|
@@ -9802,12 +9820,21 @@ const createControlInteraction = (
|
|
|
9802
9820
|
|
|
9803
9821
|
const dispatchRequestInteraction = (
|
|
9804
9822
|
element,
|
|
9805
|
-
{
|
|
9823
|
+
{
|
|
9824
|
+
event,
|
|
9825
|
+
name = "",
|
|
9826
|
+
requester,
|
|
9827
|
+
prevented,
|
|
9828
|
+
allowed,
|
|
9829
|
+
always,
|
|
9830
|
+
...detailRest
|
|
9831
|
+
} = {},
|
|
9806
9832
|
) => {
|
|
9807
9833
|
const controlHost = findControlHost(element) || element;
|
|
9808
9834
|
return dispatchInternalCustomEvent(controlHost, "navi_request_interaction", {
|
|
9809
9835
|
event,
|
|
9810
9836
|
name,
|
|
9837
|
+
requester,
|
|
9811
9838
|
prevented,
|
|
9812
9839
|
allowed,
|
|
9813
9840
|
always,
|
|
@@ -9829,6 +9856,9 @@ const onRequestInteraction = (
|
|
|
9829
9856
|
// through (see READONLY_CONSTRAINT).
|
|
9830
9857
|
intent = "write",
|
|
9831
9858
|
bypassInteractivity = false,
|
|
9859
|
+
// Who asked, when the control is not answering the gesture on its own —
|
|
9860
|
+
// the source of a command (see the self-interactions step-back below).
|
|
9861
|
+
requester,
|
|
9832
9862
|
prevented,
|
|
9833
9863
|
allowed,
|
|
9834
9864
|
always,
|
|
@@ -9862,7 +9892,9 @@ const onRequestInteraction = (
|
|
|
9862
9892
|
// reaction never happened, so its `prevented`/`always` (an
|
|
9863
9893
|
// `e.preventDefault()`, for most of them) have nothing to undo and would take
|
|
9864
9894
|
// the press from the affordance itself.
|
|
9865
|
-
|
|
9895
|
+
// Unless that element is the one asking: what it took the press to decide is
|
|
9896
|
+
// arriving here, and it is this control's to answer.
|
|
9897
|
+
if (isAimedAtSelfInteractionsBelow(event, controlHost, requester)) {
|
|
9866
9898
|
debugInteraction(
|
|
9867
9899
|
event,
|
|
9868
9900
|
`"${name}" is for a self-interactions element below`,
|
|
@@ -9947,6 +9979,11 @@ const dispatchRequestAction = (
|
|
|
9947
9979
|
return dispatchRequestInteraction(element, {
|
|
9948
9980
|
event,
|
|
9949
9981
|
name,
|
|
9982
|
+
// The gate needs it as much as the action does: the requester may be an
|
|
9983
|
+
// affordance that claimed the press to ask for this very action, and the
|
|
9984
|
+
// control must not read that claim as "this press was not for me" — see
|
|
9985
|
+
// isAimedAtSelfInteractionsBelow.
|
|
9986
|
+
requester: actionOptions.requester,
|
|
9950
9987
|
prevented,
|
|
9951
9988
|
allowed: () => {
|
|
9952
9989
|
allowed?.();
|
|
@@ -30404,6 +30441,9 @@ registerNaviCommand("--navi-update", (source, event, { argument }) => {
|
|
|
30404
30441
|
dispatchRequestInteraction(target, {
|
|
30405
30442
|
event,
|
|
30406
30443
|
name: "--navi-update",
|
|
30444
|
+
// The source may have claimed the press to send this very command — see
|
|
30445
|
+
// the requester in onRequestInteraction.
|
|
30446
|
+
requester: source,
|
|
30407
30447
|
prevented: () => event.preventDefault(),
|
|
30408
30448
|
allowed: () => {
|
|
30409
30449
|
const commandValue = resolveCommandValue(source, event);
|
|
@@ -30442,6 +30482,9 @@ registerNaviCommand("--navi-clear", (source, event) => {
|
|
|
30442
30482
|
dispatchRequestInteraction(target, {
|
|
30443
30483
|
event: clearEvent,
|
|
30444
30484
|
name: "--navi-clear",
|
|
30485
|
+
// The source may have claimed the press to send this very command — see
|
|
30486
|
+
// the requester in onRequestInteraction.
|
|
30487
|
+
requester: source,
|
|
30445
30488
|
prevented: () => clearEvent.preventDefault(),
|
|
30446
30489
|
allowed: () => {
|
|
30447
30490
|
// What the control holds, before it holds nothing: the clear is
|
|
@@ -30529,6 +30572,9 @@ registerNaviCommand("--navi-reset", (source, event) => {
|
|
|
30529
30572
|
dispatchRequestInteraction(target, {
|
|
30530
30573
|
event,
|
|
30531
30574
|
name: "--navi-reset",
|
|
30575
|
+
// The source may have claimed the press to send this very command — see
|
|
30576
|
+
// the requester in onRequestInteraction.
|
|
30577
|
+
requester: source,
|
|
30532
30578
|
prevented: () => event.preventDefault(),
|
|
30533
30579
|
allowed: () => dispatchRequestResetUIState(target, event),
|
|
30534
30580
|
});
|
|
@@ -42834,6 +42880,34 @@ const DetailsFieldContent = ({
|
|
|
42834
42880
|
});
|
|
42835
42881
|
};
|
|
42836
42882
|
|
|
42883
|
+
/**
|
|
42884
|
+
* Runs `fn` and commits whatever it re-renders before returning, instead of
|
|
42885
|
+
* letting Preact batch it into the next microtask. Layout effects of what gets
|
|
42886
|
+
* mounted run inside the call too, exactly as they would on any other commit.
|
|
42887
|
+
*
|
|
42888
|
+
* For the caller that has to read the DOM it just asked for — measuring an
|
|
42889
|
+
* element whose content it mounts in the same breath — and cannot wait a tick
|
|
42890
|
+
* to do it, because what comes after is a browser event still in flight
|
|
42891
|
+
* (preventDefault, focus placement) that no longer accepts being answered late.
|
|
42892
|
+
*
|
|
42893
|
+
* `options.debounceRendering` is Preact's own hook for deciding *when* the
|
|
42894
|
+
* render queue drains; swapping it for "right now" for the duration of the call
|
|
42895
|
+
* is exactly how preact/compat implements React's flushSync. Reserve it for the
|
|
42896
|
+
* case above: rendering synchronously in the middle of an event gives up the
|
|
42897
|
+
* batching that makes several state changes one commit.
|
|
42898
|
+
*/
|
|
42899
|
+
const flushSyncRendering = (fn) => {
|
|
42900
|
+
const debounceRenderingPrevious = options.debounceRendering;
|
|
42901
|
+
options.debounceRendering = (drainRenderQueue) => {
|
|
42902
|
+
drainRenderQueue();
|
|
42903
|
+
};
|
|
42904
|
+
try {
|
|
42905
|
+
fn();
|
|
42906
|
+
} finally {
|
|
42907
|
+
options.debounceRendering = debounceRenderingPrevious;
|
|
42908
|
+
}
|
|
42909
|
+
};
|
|
42910
|
+
|
|
42837
42911
|
/**
|
|
42838
42912
|
* Small, renderer-agnostic helpers shared by Popover and Dialog's own custom
|
|
42839
42913
|
* (non-top-layer) renderers — operate on a plain DOM element, no knowledge
|
|
@@ -43047,6 +43121,96 @@ const resolveAutoAnimationKind = (anchor, parsedPositionArea) => {
|
|
|
43047
43121
|
return anchor || (yIsOverlapping && xIsOverlapping) ? "scaling" : "sliding";
|
|
43048
43122
|
};
|
|
43049
43123
|
|
|
43124
|
+
/**
|
|
43125
|
+
* When a popup builds what it holds, and when it throws it away.
|
|
43126
|
+
*
|
|
43127
|
+
* A closed popup shows nothing, focuses nothing, and answers nothing: what it
|
|
43128
|
+
* holds is out of reach until it opens. Building that content at mount time
|
|
43129
|
+
* means a page carrying a handful of closed popups pays, on the very render
|
|
43130
|
+
* that decides how fast it appears, for content nobody has asked for — and
|
|
43131
|
+
* pays again on every subsequent measurement, since each of those nodes makes
|
|
43132
|
+
* the document the rest of the page queries bigger.
|
|
43133
|
+
*
|
|
43134
|
+
* So the content is built when the popup first opens, and stays built from
|
|
43135
|
+
* then on: closing is not throwing away, and a reopened popup finds its scroll
|
|
43136
|
+
* position, its half-typed form and its list state where it left them.
|
|
43137
|
+
*
|
|
43138
|
+
* It is built synchronously, from inside `openController.open()` and before
|
|
43139
|
+
* `openEffect` runs (see open_controller.js), so the popup still measures real
|
|
43140
|
+
* content when it positions and animates itself, and so anything inside it
|
|
43141
|
+
* still observes the opening the way it always did — mounted while the popup
|
|
43142
|
+
* reads as closed, told it opened right after (see
|
|
43143
|
+
* use_displayed_layout_effect.js).
|
|
43144
|
+
*
|
|
43145
|
+
* The `mount` prop moves that line. "closed" is two states, not one — never
|
|
43146
|
+
* opened yet, and closed again after an opening — and the three values answer
|
|
43147
|
+
* both at once:
|
|
43148
|
+
*
|
|
43149
|
+
* | mount | before the first open | after a close |
|
|
43150
|
+
* | ----------------- | --------------------- | ------------- |
|
|
43151
|
+
* | "always" | mounted | mounted |
|
|
43152
|
+
* | "from-first-open" | not mounted | mounted |
|
|
43153
|
+
* | "while-opened" | not mounted | not mounted |
|
|
43154
|
+
*
|
|
43155
|
+
* "always" is for content something else depends on before any opening: a
|
|
43156
|
+
* value the popup's owner reads off its own children, fields a form around it
|
|
43157
|
+
* collects on submit, a size measured from outside.
|
|
43158
|
+
*
|
|
43159
|
+
* "while-opened" is the opposite end: content that must be rebuilt from
|
|
43160
|
+
* scratch every time, because what it shows is read once at build time and can
|
|
43161
|
+
* change while the popup is closed — an uncontrolled field seeded from a
|
|
43162
|
+
* `defaultValue`, a form whose fresh state is its initial state.
|
|
43163
|
+
*/
|
|
43164
|
+
|
|
43165
|
+
|
|
43166
|
+
const MOUNT_DEFAULT = "from-first-open";
|
|
43167
|
+
|
|
43168
|
+
const usePopupContentMount = (
|
|
43169
|
+
openController,
|
|
43170
|
+
ref,
|
|
43171
|
+
{ children, mount = MOUNT_DEFAULT },
|
|
43172
|
+
) => {
|
|
43173
|
+
const mountedAlways = mount === "always";
|
|
43174
|
+
const [contentMounted, setContentMounted] = useState(
|
|
43175
|
+
() => mountedAlways || openController.opened,
|
|
43176
|
+
);
|
|
43177
|
+
openController.mountContent = contentMounted
|
|
43178
|
+
? null
|
|
43179
|
+
: () => {
|
|
43180
|
+
flushSyncRendering(() => {
|
|
43181
|
+
setContentMounted(true);
|
|
43182
|
+
});
|
|
43183
|
+
};
|
|
43184
|
+
openController.unmountContent =
|
|
43185
|
+
mount === "while-opened"
|
|
43186
|
+
? () => {
|
|
43187
|
+
const element = ref?.current;
|
|
43188
|
+
if (!element) {
|
|
43189
|
+
setContentMounted(false);
|
|
43190
|
+
return;
|
|
43191
|
+
}
|
|
43192
|
+
// The popup is still on screen while it plays its exit transition;
|
|
43193
|
+
// emptying it right away would show that transition running on a
|
|
43194
|
+
// blank surface.
|
|
43195
|
+
whenTransitionSettles(element, () => {
|
|
43196
|
+
if (openController.opened) {
|
|
43197
|
+
// reopened while it was leaving — the content it holds is the
|
|
43198
|
+
// one that open just asked for
|
|
43199
|
+
return;
|
|
43200
|
+
}
|
|
43201
|
+
setContentMounted(false);
|
|
43202
|
+
});
|
|
43203
|
+
}
|
|
43204
|
+
: null;
|
|
43205
|
+
useLayoutEffect(() => {
|
|
43206
|
+
if (mountedAlways) {
|
|
43207
|
+
setContentMounted(true);
|
|
43208
|
+
}
|
|
43209
|
+
}, [mountedAlways]);
|
|
43210
|
+
|
|
43211
|
+
return contentMounted ? children : null;
|
|
43212
|
+
};
|
|
43213
|
+
|
|
43050
43214
|
installImportMetaCssBuild(import.meta);/**
|
|
43051
43215
|
* Expandable: an in-flow disclosure — a UI part that reveals a content part.
|
|
43052
43216
|
* It covers the same ground as <Details> with structural differences:
|
|
@@ -43087,10 +43251,9 @@ installImportMetaCssBuild(import.meta);/**
|
|
|
43087
43251
|
* events.
|
|
43088
43252
|
*
|
|
43089
43253
|
* Content is not built until the first expansion and stays built afterwards —
|
|
43090
|
-
* same policy, same prop
|
|
43091
|
-
* `
|
|
43092
|
-
*
|
|
43093
|
-
* content).
|
|
43254
|
+
* same policy, same `mount` prop as popups (see popup_content_mount.js):
|
|
43255
|
+
* `"always"` builds it right away, `"while-opened"` throws it away once the
|
|
43256
|
+
* collapse settles (so a closing animation still plays on real content).
|
|
43094
43257
|
*
|
|
43095
43258
|
* The animation is a REVEAL, not a resize: the expandable's own footprint
|
|
43096
43259
|
* grows/shrinks progressively (the content's grid track interpolates
|
|
@@ -43252,8 +43415,7 @@ const useExpandableContext = partName => {
|
|
|
43252
43415
|
* layout?: "row" | "column",
|
|
43253
43416
|
* autoFocus?: boolean,
|
|
43254
43417
|
* maxContentHeight?: string | number,
|
|
43255
|
-
*
|
|
43256
|
-
* unmountWhenClosed?: boolean,
|
|
43418
|
+
* mount?: "always" | "from-first-open" | "while-opened",
|
|
43257
43419
|
* arrowKeyShortcuts?: boolean,
|
|
43258
43420
|
* openKeyShortcut?: string,
|
|
43259
43421
|
* closeKeyShortcut?: string,
|
|
@@ -43290,13 +43452,15 @@ const useExpandableContext = partName => {
|
|
|
43290
43452
|
* the UI part (it would otherwise be lost to the closed, inert content).
|
|
43291
43453
|
* @param maxContentHeight - Caps the content height; taller content scrolls
|
|
43292
43454
|
* inside the expandable instead of growing it.
|
|
43293
|
-
* @param
|
|
43294
|
-
*
|
|
43295
|
-
*
|
|
43296
|
-
*
|
|
43297
|
-
*
|
|
43298
|
-
*
|
|
43299
|
-
*
|
|
43455
|
+
* @param mount - When the content is built and thrown away, same three values
|
|
43456
|
+
* as a popup's (see popup_content_mount.js). `"from-first-open"` (the
|
|
43457
|
+
* default) builds it on the first expansion and keeps it afterwards.
|
|
43458
|
+
* `"always"` builds it right away; in layout="column" it also gives the
|
|
43459
|
+
* closed expandable its content's height (the content is kept laid out at
|
|
43460
|
+
* its open width), so opening only reveals the width instead of changing the
|
|
43461
|
+
* height too. `"while-opened"` throws the content away once the collapse
|
|
43462
|
+
* settles — after the closing animation, so it still plays on real
|
|
43463
|
+
* content — and rebuilds it from scratch on every expansion.
|
|
43300
43464
|
*/
|
|
43301
43465
|
const Expandable = props => {
|
|
43302
43466
|
import.meta.css = [css$Q, "@jsenv/navi/src/control/expandable/expandable.jsx"];
|
|
@@ -43312,8 +43476,7 @@ const Expandable = props => {
|
|
|
43312
43476
|
layout,
|
|
43313
43477
|
autoFocus,
|
|
43314
43478
|
maxContentHeight,
|
|
43315
|
-
|
|
43316
|
-
unmountWhenClosed,
|
|
43479
|
+
mount = MOUNT_DEFAULT,
|
|
43317
43480
|
arrowKeyShortcuts = true,
|
|
43318
43481
|
openKeyShortcut = "ArrowRight",
|
|
43319
43482
|
closeKeyShortcut = "ArrowLeft",
|
|
@@ -43326,7 +43489,9 @@ const Expandable = props => {
|
|
|
43326
43489
|
const contentContainerRef = useRef();
|
|
43327
43490
|
const contentId = useId();
|
|
43328
43491
|
const isColumn = layout === "column";
|
|
43329
|
-
const
|
|
43492
|
+
const mountedAlways = mount === "always";
|
|
43493
|
+
const mountedWhileOpened = mount === "while-opened";
|
|
43494
|
+
const closedContentSized = isColumn && mountedAlways;
|
|
43330
43495
|
// Reading .value during render is what subscribes the expandable to it.
|
|
43331
43496
|
const openRequested = signal ? signal.value : open;
|
|
43332
43497
|
const [opened, setOpened] = useState(() => Boolean(openRequested === undefined ? defaultOpen : openRequested));
|
|
@@ -43337,13 +43502,10 @@ const Expandable = props => {
|
|
|
43337
43502
|
const {
|
|
43338
43503
|
loading: actionLoading
|
|
43339
43504
|
} = useActionStatus(effectiveAction);
|
|
43340
|
-
const [contentMounted, setContentMounted] = useState(() =>
|
|
43341
|
-
// Same exclusion as popup_content_mount.js: content that must exist while
|
|
43342
|
-
// closed cannot also be thrown away on close.
|
|
43343
|
-
const effectiveUnmountWhenClosed = unmountWhenClosed && !mountWhenClosed;
|
|
43505
|
+
const [contentMounted, setContentMounted] = useState(() => mountedAlways || opened);
|
|
43344
43506
|
|
|
43345
43507
|
// Fully open and no longer moving — what allows overflow to become visible
|
|
43346
|
-
// (see the CSS) and what
|
|
43508
|
+
// (see the CSS) and what mount="while-opened" waits for before emptying.
|
|
43347
43509
|
const [settled, setSettled] = useState(true);
|
|
43348
43510
|
|
|
43349
43511
|
// Read before the close touches the DOM: flipping the content to inert can
|
|
@@ -43410,7 +43572,7 @@ const Expandable = props => {
|
|
|
43410
43572
|
focusedAtPointerDownRef.current = null;
|
|
43411
43573
|
setOpened(nextOpen);
|
|
43412
43574
|
// Flipped here, before the closing/opening commit, so effects of that very
|
|
43413
|
-
// commit already see the movement as started —
|
|
43575
|
+
// commit already see the movement as started — mount="while-opened" must not
|
|
43414
43576
|
// read a stale "settled" and empty the content under a closing animation.
|
|
43415
43577
|
setSettled(!animation);
|
|
43416
43578
|
if (signal) {
|
|
@@ -43532,17 +43694,17 @@ const Expandable = props => {
|
|
|
43532
43694
|
return cancel;
|
|
43533
43695
|
}, [opened]);
|
|
43534
43696
|
useLayoutEffect(() => {
|
|
43535
|
-
if (settled && !opened &&
|
|
43697
|
+
if (settled && !opened && mountedWhileOpened) {
|
|
43536
43698
|
setContentMounted(false);
|
|
43537
43699
|
}
|
|
43538
|
-
}, [settled, opened,
|
|
43700
|
+
}, [settled, opened, mountedWhileOpened]);
|
|
43539
43701
|
useLayoutEffect(() => {
|
|
43540
|
-
if (
|
|
43702
|
+
if (mountedAlways) {
|
|
43541
43703
|
setContentMounted(true);
|
|
43542
43704
|
}
|
|
43543
|
-
}, [
|
|
43705
|
+
}, [mountedAlways]);
|
|
43544
43706
|
|
|
43545
|
-
// closedContentSized (column +
|
|
43707
|
+
// closedContentSized (column + mount="always"): the closed content sizes
|
|
43546
43708
|
// the height (see the CSS), which is only right if it lies at its OPEN
|
|
43547
43709
|
// width — at its natural closed width (a 0-wide track) it would wrap
|
|
43548
43710
|
// against nothing and stack word by word. So while closed, its width is
|
|
@@ -44090,7 +44252,7 @@ installImportMetaCssBuild(import.meta);const css$P = /* css */`@layer navi {
|
|
|
44090
44252
|
--button-color: currentColor;
|
|
44091
44253
|
--button-cursor: pointer;
|
|
44092
44254
|
--button-font-size: var(--navi-control-font-size);
|
|
44093
|
-
--button-font-family: var(--navi-control-font-family);
|
|
44255
|
+
--button-font-family: var(--navi-control-font-family, inherit);
|
|
44094
44256
|
--button-border-color-hover: color-mix(in srgb,
|
|
44095
44257
|
var(--button-border-color) 70%,
|
|
44096
44258
|
black);
|
|
@@ -44337,37 +44499,30 @@ a.navi_button {
|
|
|
44337
44499
|
}
|
|
44338
44500
|
|
|
44339
44501
|
&[data-cta] {
|
|
44340
|
-
--
|
|
44341
|
-
--
|
|
44342
|
-
--
|
|
44343
|
-
|
|
44344
|
-
|
|
44345
|
-
|
|
44346
|
-
|
|
44347
|
-
|
|
44348
|
-
|
|
44349
|
-
|
|
44350
|
-
|
|
44351
|
-
|
|
44352
|
-
|
|
44353
|
-
|
|
44354
|
-
|
|
44355
|
-
|
|
44356
|
-
|
|
44357
|
-
|
|
44358
|
-
|
|
44359
|
-
|
|
44360
|
-
|
|
44361
|
-
|
|
44362
|
-
|
|
44363
|
-
|
|
44364
|
-
var(--button-cta-background-color) 40%,
|
|
44365
|
-
white);
|
|
44366
|
-
--x-button-border-color: color-mix(in srgb,
|
|
44367
|
-
var(--button-cta-background-color) 40%,
|
|
44368
|
-
white);
|
|
44369
|
-
--x-button-color: #fff9;
|
|
44370
|
-
}
|
|
44502
|
+
--button-background-color: var(--button-background, var(--button-cta-background-color));
|
|
44503
|
+
--button-border-color: var(--button-cta-background-color);
|
|
44504
|
+
--button-color: white;
|
|
44505
|
+
--button-background-color-hover: color-mix(in srgb,
|
|
44506
|
+
var(--button-background-color) 85%,
|
|
44507
|
+
white);
|
|
44508
|
+
--button-border-color-hover: color-mix(in srgb,
|
|
44509
|
+
var(--button-border-color) 85%,
|
|
44510
|
+
white);
|
|
44511
|
+
--button-background-color-readonly: color-mix(in srgb,
|
|
44512
|
+
var(--button-background-color) 50%,
|
|
44513
|
+
white);
|
|
44514
|
+
--button-border-color-readonly: color-mix(in srgb,
|
|
44515
|
+
var(--button-border-color) 50%,
|
|
44516
|
+
white);
|
|
44517
|
+
--button-background-color-disabled: color-mix(in srgb,
|
|
44518
|
+
var(--button-background-color) 40%,
|
|
44519
|
+
white);
|
|
44520
|
+
--button-border-color-disabled: color-mix(in srgb,
|
|
44521
|
+
var(--button-border-color) 40%,
|
|
44522
|
+
white);
|
|
44523
|
+
--button-color-disabled: color-mix(in srgb,
|
|
44524
|
+
var(--button-color) 60%,
|
|
44525
|
+
transparent);
|
|
44371
44526
|
}
|
|
44372
44527
|
}
|
|
44373
44528
|
`;
|
|
@@ -45310,7 +45465,7 @@ installImportMetaCssBuild(import.meta);const css$M = /* css */`@layer navi {
|
|
|
45310
45465
|
--outline-color: var(--navi-focus-outline-color);
|
|
45311
45466
|
--margin: 3px 3px 3px 4px;
|
|
45312
45467
|
--font-size: var(--navi-control-font-size);
|
|
45313
|
-
--font-family: var(--navi-control-font-family);
|
|
45468
|
+
--font-family: var(--navi-control-font-family, inherit);
|
|
45314
45469
|
--width: round(1em, 1px);
|
|
45315
45470
|
--height: round(1em, 1px);
|
|
45316
45471
|
--loader-color: var(--navi-loader-color);
|
|
@@ -46016,7 +46171,7 @@ installImportMetaCssBuild(import.meta);const css$K = /* css */`@layer navi {
|
|
|
46016
46171
|
--border-color-checked: var(--accent-color);
|
|
46017
46172
|
--cursor: pointer;
|
|
46018
46173
|
--font-size: var(--navi-control-font-size);
|
|
46019
|
-
--font-family: var(--navi-control-font-family);
|
|
46174
|
+
--font-family: var(--navi-control-font-family, inherit);
|
|
46020
46175
|
--border-color-hover: color-mix(in srgb, var(--border-color) 60%, black);
|
|
46021
46176
|
--border-color-hover-checked: color-mix(in srgb,
|
|
46022
46177
|
var(--border-color-checked) 80%,
|
|
@@ -46463,7 +46618,7 @@ installImportMetaCssBuild(import.meta);const css$J = /* css */`@layer navi {
|
|
|
46463
46618
|
--thumb-border-radius: 100%;
|
|
46464
46619
|
--thumb-cursor: pointer;
|
|
46465
46620
|
--font-size: var(--navi-control-font-size);
|
|
46466
|
-
--font-family: var(--navi-control-font-family);
|
|
46621
|
+
--font-family: var(--navi-control-font-family, inherit);
|
|
46467
46622
|
--loader-color: var(--navi-loader-color);
|
|
46468
46623
|
--accent-color: var(--navi-control-accent-color);
|
|
46469
46624
|
--color-mix-light: black;
|
|
@@ -46811,7 +46966,7 @@ const inputCss = /* css */`@layer navi {
|
|
|
46811
46966
|
--outline-offset: calc(-.5 * var(--outline-width));
|
|
46812
46967
|
--outline-color: var(--navi-focus-outline-color);
|
|
46813
46968
|
--font-size: var(--navi-control-font-size);
|
|
46814
|
-
--font-family: var(--navi-control-font-family);
|
|
46969
|
+
--font-family: var(--navi-control-font-family, inherit);
|
|
46815
46970
|
--loader-color: var(--navi-loader-color);
|
|
46816
46971
|
--border-color: var(--navi-control-border-color);
|
|
46817
46972
|
--background-color: var(--navi-surface-color);
|
|
@@ -47026,13 +47181,24 @@ const inputCss = /* css */`@layer navi {
|
|
|
47026
47181
|
}
|
|
47027
47182
|
|
|
47028
47183
|
&[data-variant="text"] {
|
|
47029
|
-
--
|
|
47030
|
-
--
|
|
47184
|
+
--background-color: transparent;
|
|
47185
|
+
--background-color-hover: var(--background-color);
|
|
47186
|
+
--background-color-focus: var(--background-color);
|
|
47187
|
+
--background-color-readonly: var(--background-color);
|
|
47188
|
+
--background-color-disabled: var(--background-color);
|
|
47189
|
+
--border-color: transparent;
|
|
47190
|
+
--border-color-hover: var(--border-color);
|
|
47191
|
+
--border-color-readonly: var(--border-color);
|
|
47192
|
+
--border-color-disabled: var(--border-color);
|
|
47031
47193
|
cursor: inherit;
|
|
47032
47194
|
}
|
|
47033
47195
|
|
|
47034
47196
|
&[data-variant="underline"] {
|
|
47035
|
-
--
|
|
47197
|
+
--background-color: transparent;
|
|
47198
|
+
--background-color-hover: var(--background-color);
|
|
47199
|
+
--background-color-focus: var(--background-color);
|
|
47200
|
+
--background-color-readonly: var(--background-color);
|
|
47201
|
+
--background-color-disabled: var(--background-color);
|
|
47036
47202
|
border: none;
|
|
47037
47203
|
border-radius: 0;
|
|
47038
47204
|
padding-left: 0;
|
|
@@ -47054,12 +47220,7 @@ const inputCss = /* css */`@layer navi {
|
|
|
47054
47220
|
position: absolute;
|
|
47055
47221
|
}
|
|
47056
47222
|
|
|
47057
|
-
&[data-hover] {
|
|
47058
|
-
--x-background-color: transparent;
|
|
47059
|
-
}
|
|
47060
|
-
|
|
47061
47223
|
&[data-focus-visible] {
|
|
47062
|
-
--x-background-color: transparent;
|
|
47063
47224
|
outline-style: none;
|
|
47064
47225
|
|
|
47065
47226
|
& .navi_input_underline {
|
|
@@ -47067,10 +47228,6 @@ const inputCss = /* css */`@layer navi {
|
|
|
47067
47228
|
height: 2px;
|
|
47068
47229
|
}
|
|
47069
47230
|
}
|
|
47070
|
-
|
|
47071
|
-
&[data-readonly], &[data-disabled] {
|
|
47072
|
-
--x-background-color: transparent;
|
|
47073
|
-
}
|
|
47074
47231
|
}
|
|
47075
47232
|
}
|
|
47076
47233
|
`;
|
|
@@ -53902,7 +54059,7 @@ const createOpenController = (
|
|
|
53902
54059
|
// previous subject first.
|
|
53903
54060
|
onOpen: null,
|
|
53904
54061
|
// The counterpart, set only when the popup was told to throw its content
|
|
53905
|
-
// away on close (`
|
|
54062
|
+
// away on close (`mount="while-opened"`). Called from performClose above.
|
|
53906
54063
|
unmountContent: null,
|
|
53907
54064
|
// Told whenever `opened` actually changes, whatever asked for it — an
|
|
53908
54065
|
// interaction, a command, a prop — with the event that asked. What lets a
|
|
@@ -54374,111 +54531,6 @@ const getAvailableWidth = (layer, element) => {
|
|
|
54374
54531
|
return visualViewportWidthSignal.peek();
|
|
54375
54532
|
};
|
|
54376
54533
|
|
|
54377
|
-
/**
|
|
54378
|
-
* Runs `fn` and commits whatever it re-renders before returning, instead of
|
|
54379
|
-
* letting Preact batch it into the next microtask. Layout effects of what gets
|
|
54380
|
-
* mounted run inside the call too, exactly as they would on any other commit.
|
|
54381
|
-
*
|
|
54382
|
-
* For the caller that has to read the DOM it just asked for — measuring an
|
|
54383
|
-
* element whose content it mounts in the same breath — and cannot wait a tick
|
|
54384
|
-
* to do it, because what comes after is a browser event still in flight
|
|
54385
|
-
* (preventDefault, focus placement) that no longer accepts being answered late.
|
|
54386
|
-
*
|
|
54387
|
-
* `options.debounceRendering` is Preact's own hook for deciding *when* the
|
|
54388
|
-
* render queue drains; swapping it for "right now" for the duration of the call
|
|
54389
|
-
* is exactly how preact/compat implements React's flushSync. Reserve it for the
|
|
54390
|
-
* case above: rendering synchronously in the middle of an event gives up the
|
|
54391
|
-
* batching that makes several state changes one commit.
|
|
54392
|
-
*/
|
|
54393
|
-
const flushSyncRendering = (fn) => {
|
|
54394
|
-
const debounceRenderingPrevious = options.debounceRendering;
|
|
54395
|
-
options.debounceRendering = (drainRenderQueue) => {
|
|
54396
|
-
drainRenderQueue();
|
|
54397
|
-
};
|
|
54398
|
-
try {
|
|
54399
|
-
fn();
|
|
54400
|
-
} finally {
|
|
54401
|
-
options.debounceRendering = debounceRenderingPrevious;
|
|
54402
|
-
}
|
|
54403
|
-
};
|
|
54404
|
-
|
|
54405
|
-
/**
|
|
54406
|
-
* When a popup builds what it holds, and when it throws it away.
|
|
54407
|
-
*
|
|
54408
|
-
* A closed popup shows nothing, focuses nothing, and answers nothing: what it
|
|
54409
|
-
* holds is out of reach until it opens. Building that content at mount time
|
|
54410
|
-
* means a page carrying a handful of closed popups pays, on the very render
|
|
54411
|
-
* that decides how fast it appears, for content nobody has asked for — and
|
|
54412
|
-
* pays again on every subsequent measurement, since each of those nodes makes
|
|
54413
|
-
* the document the rest of the page queries bigger.
|
|
54414
|
-
*
|
|
54415
|
-
* So the content is built when the popup first opens, and stays built from
|
|
54416
|
-
* then on: closing is not throwing away, and a reopened popup finds its scroll
|
|
54417
|
-
* position, its half-typed form and its list state where it left them.
|
|
54418
|
-
*
|
|
54419
|
-
* It is built synchronously, from inside `openController.open()` and before
|
|
54420
|
-
* `openEffect` runs (see open_controller.js), so the popup still measures real
|
|
54421
|
-
* content when it positions and animates itself, and so anything inside it
|
|
54422
|
-
* still observes the opening the way it always did — mounted while the popup
|
|
54423
|
-
* reads as closed, told it opened right after (see
|
|
54424
|
-
* use_displayed_layout_effect.js).
|
|
54425
|
-
*
|
|
54426
|
-
* `mountWhenClosed` is for content something else depends on before any of
|
|
54427
|
-
* this: a value the popup's owner reads off its own children, fields a form
|
|
54428
|
-
* around it collects on submit, a size measured from outside.
|
|
54429
|
-
*
|
|
54430
|
-
* `unmountWhenClosed` is the opposite end: content that must be rebuilt from
|
|
54431
|
-
* scratch every time, because what it shows is read once at build time and can
|
|
54432
|
-
* change while the popup is closed — an uncontrolled field seeded from a
|
|
54433
|
-
* `defaultValue`, a form whose fresh state is its initial state.
|
|
54434
|
-
*/
|
|
54435
|
-
|
|
54436
|
-
|
|
54437
|
-
const usePopupContentMount = (
|
|
54438
|
-
openController,
|
|
54439
|
-
ref,
|
|
54440
|
-
{ children, mountWhenClosed, unmountWhenClosed },
|
|
54441
|
-
) => {
|
|
54442
|
-
const [contentMounted, setContentMounted] = useState(
|
|
54443
|
-
() => Boolean(mountWhenClosed) || openController.opened,
|
|
54444
|
-
);
|
|
54445
|
-
openController.mountContent = contentMounted
|
|
54446
|
-
? null
|
|
54447
|
-
: () => {
|
|
54448
|
-
flushSyncRendering(() => {
|
|
54449
|
-
setContentMounted(true);
|
|
54450
|
-
});
|
|
54451
|
-
};
|
|
54452
|
-
openController.unmountContent =
|
|
54453
|
-
unmountWhenClosed && !mountWhenClosed
|
|
54454
|
-
? () => {
|
|
54455
|
-
const element = ref?.current;
|
|
54456
|
-
if (!element) {
|
|
54457
|
-
setContentMounted(false);
|
|
54458
|
-
return;
|
|
54459
|
-
}
|
|
54460
|
-
// The popup is still on screen while it plays its exit transition;
|
|
54461
|
-
// emptying it right away would show that transition running on a
|
|
54462
|
-
// blank surface.
|
|
54463
|
-
whenTransitionSettles(element, () => {
|
|
54464
|
-
if (openController.opened) {
|
|
54465
|
-
// reopened while it was leaving — the content it holds is the
|
|
54466
|
-
// one that open just asked for
|
|
54467
|
-
return;
|
|
54468
|
-
}
|
|
54469
|
-
setContentMounted(false);
|
|
54470
|
-
});
|
|
54471
|
-
}
|
|
54472
|
-
: null;
|
|
54473
|
-
useLayoutEffect(() => {
|
|
54474
|
-
if (mountWhenClosed) {
|
|
54475
|
-
setContentMounted(true);
|
|
54476
|
-
}
|
|
54477
|
-
}, [mountWhenClosed]);
|
|
54478
|
-
|
|
54479
|
-
return contentMounted ? children : null;
|
|
54480
|
-
};
|
|
54481
|
-
|
|
54482
54534
|
/**
|
|
54483
54535
|
* Entry/exit animation CSS shared by Popover and Dialog.
|
|
54484
54536
|
*
|
|
@@ -55669,16 +55721,15 @@ const css$E = /* css */`
|
|
|
55669
55721
|
* open controller (see `open_controller.js`) for a caller that wants to
|
|
55670
55722
|
* drive open/close itself instead of `open`/`defaultOpen`/`onClose` (used
|
|
55671
55723
|
* by `picker_custom.jsx`).
|
|
55672
|
-
* @param {
|
|
55673
|
-
*
|
|
55674
|
-
*
|
|
55675
|
-
*
|
|
55676
|
-
*
|
|
55677
|
-
*
|
|
55678
|
-
* popup has finished closing
|
|
55679
|
-
* fresh state is its initial state: an uncontrolled field
|
|
55680
|
-
* `defaultValue` that changed while the popup was closed.
|
|
55681
|
-
* `mountWhenClosed` is set.
|
|
55724
|
+
* @param {"always"|"from-first-open"|"while-opened"} [props.mount] - When
|
|
55725
|
+
* `children` are built and thrown away (see popup_content_mount.js).
|
|
55726
|
+
* `"from-first-open"` (the default) builds them on the first open and keeps
|
|
55727
|
+
* them afterwards. `"always"` builds them right away, for content something
|
|
55728
|
+
* depends on while the popup is still closed: a value read off it, fields a
|
|
55729
|
+
* surrounding form collects on submit, a size measured from outside.
|
|
55730
|
+
* `"while-opened"` throws them away once the popup has finished closing, for
|
|
55731
|
+
* content whose fresh state is its initial state: an uncontrolled field
|
|
55732
|
+
* seeded from a `defaultValue` that changed while the popup was closed.
|
|
55682
55733
|
* @param {import("ignore:preact").ComponentChildren} props.children
|
|
55683
55734
|
*/
|
|
55684
55735
|
const Dialog = props => {
|
|
@@ -55915,8 +55966,7 @@ const useDialogProps = props => {
|
|
|
55915
55966
|
// openController.onOpen below).
|
|
55916
55967
|
onOpen,
|
|
55917
55968
|
children: childrenProp,
|
|
55918
|
-
|
|
55919
|
-
unmountWhenClosed,
|
|
55969
|
+
mount,
|
|
55920
55970
|
...rest
|
|
55921
55971
|
} = props;
|
|
55922
55972
|
// Assigned on every render, like openEffect below, so it always closes over
|
|
@@ -55925,8 +55975,7 @@ const useDialogProps = props => {
|
|
|
55925
55975
|
openController.onOpen = onOpen || null;
|
|
55926
55976
|
const children = usePopupContentMount(openController, props.ref, {
|
|
55927
55977
|
children: childrenProp,
|
|
55928
|
-
|
|
55929
|
-
unmountWhenClosed
|
|
55978
|
+
mount
|
|
55930
55979
|
});
|
|
55931
55980
|
const isModal = layer === "top";
|
|
55932
55981
|
const ref = props.ref;
|
|
@@ -57139,16 +57188,15 @@ const css$D = /* css */`
|
|
|
57139
57188
|
* open controller (see `open_controller.js`) for a caller that wants to
|
|
57140
57189
|
* drive open/close itself instead of `open`/`defaultOpen`/`onClose` (used
|
|
57141
57190
|
* by `picker_custom.jsx`/`side_panel.jsx`).
|
|
57142
|
-
* @param {
|
|
57143
|
-
*
|
|
57144
|
-
*
|
|
57145
|
-
*
|
|
57146
|
-
*
|
|
57147
|
-
*
|
|
57148
|
-
* popup has finished closing
|
|
57149
|
-
* fresh state is its initial state: an uncontrolled field
|
|
57150
|
-
* `defaultValue` that changed while the popup was closed.
|
|
57151
|
-
* `mountWhenClosed` is set.
|
|
57191
|
+
* @param {"always"|"from-first-open"|"while-opened"} [props.mount] - When
|
|
57192
|
+
* `children` are built and thrown away (see popup_content_mount.js).
|
|
57193
|
+
* `"from-first-open"` (the default) builds them on the first open and keeps
|
|
57194
|
+
* them afterwards. `"always"` builds them right away, for content something
|
|
57195
|
+
* depends on while the popup is still closed: a value read off it, fields a
|
|
57196
|
+
* surrounding form collects on submit, a size measured from outside.
|
|
57197
|
+
* `"while-opened"` throws them away once the popup has finished closing, for
|
|
57198
|
+
* content whose fresh state is its initial state: an uncontrolled field
|
|
57199
|
+
* seeded from a `defaultValue` that changed while the popup was closed.
|
|
57152
57200
|
* @param {import("ignore:preact").ComponentChildren} props.children
|
|
57153
57201
|
*/
|
|
57154
57202
|
const Popover = props => {
|
|
@@ -57363,8 +57411,7 @@ const usePopoverProps = props => {
|
|
|
57363
57411
|
// openController.onOpen below).
|
|
57364
57412
|
onOpen,
|
|
57365
57413
|
children: childrenProp,
|
|
57366
|
-
|
|
57367
|
-
unmountWhenClosed,
|
|
57414
|
+
mount,
|
|
57368
57415
|
...rest
|
|
57369
57416
|
} = props;
|
|
57370
57417
|
// Assigned on every render, like openEffect below, so it always closes over
|
|
@@ -57373,8 +57420,7 @@ const usePopoverProps = props => {
|
|
|
57373
57420
|
openController.onOpen = onOpen || null;
|
|
57374
57421
|
const children = usePopupContentMount(openController, props.ref, {
|
|
57375
57422
|
children: childrenProp,
|
|
57376
|
-
|
|
57377
|
-
unmountWhenClosed
|
|
57423
|
+
mount
|
|
57378
57424
|
});
|
|
57379
57425
|
const isTopLayer = layer === "top";
|
|
57380
57426
|
const ref = props.ref;
|
|
@@ -58313,16 +58359,15 @@ const css$C = /* css */`@layer navi {
|
|
|
58313
58359
|
* @param {string} [props.className] - Merged with the shared
|
|
58314
58360
|
* `"navi_popup"` class (see this file's own CSS) rather than replacing
|
|
58315
58361
|
* it.
|
|
58316
|
-
* @param {
|
|
58317
|
-
*
|
|
58318
|
-
*
|
|
58319
|
-
*
|
|
58320
|
-
*
|
|
58321
|
-
*
|
|
58322
|
-
* popup has finished closing
|
|
58323
|
-
* fresh state is its initial state: an uncontrolled field
|
|
58324
|
-
* `defaultValue` that changed while the popup was closed.
|
|
58325
|
-
* `mountWhenClosed` is set.
|
|
58362
|
+
* @param {"always"|"from-first-open"|"while-opened"} [props.mount] - When
|
|
58363
|
+
* `children` are built and thrown away (see popup_content_mount.js).
|
|
58364
|
+
* `"from-first-open"` (the default) builds them on the first open and keeps
|
|
58365
|
+
* them afterwards. `"always"` builds them right away, for content something
|
|
58366
|
+
* depends on while the popup is still closed: a value read off it, fields a
|
|
58367
|
+
* surrounding form collects on submit, a size measured from outside.
|
|
58368
|
+
* `"while-opened"` throws them away once the popup has finished closing, for
|
|
58369
|
+
* content whose fresh state is its initial state: an uncontrolled field
|
|
58370
|
+
* seeded from a `defaultValue` that changed while the popup was closed.
|
|
58326
58371
|
* @param {import("ignore:preact").ComponentChildren} props.children
|
|
58327
58372
|
*/
|
|
58328
58373
|
const Popup = props => {
|
|
@@ -58852,8 +58897,7 @@ const PickerCustom = props => {
|
|
|
58852
58897
|
// and pushes it down instead, leaving the popup free to build its
|
|
58853
58898
|
// content only when it is first opened (see popup_content_mount.js).
|
|
58854
58899
|
// A caller who knows better says so with the popup's own props.
|
|
58855
|
-
|
|
58856
|
-
unmountWhenClosed: props.unmountWhenClosed,
|
|
58900
|
+
mount: props.mount ?? (isControlValueGivenByProps(props) ? MOUNT_DEFAULT : "always"),
|
|
58857
58901
|
// Not on pickerProps (the trigger): commands.js's own
|
|
58858
58902
|
// resolveClosestExpandable() does `el.closest("[aria-expanded]")` to
|
|
58859
58903
|
// find where to dispatch navi_request_open/navi_request_close — and
|
|
@@ -59139,8 +59183,7 @@ const PickerContentInsidePopup = props => {
|
|
|
59139
59183
|
...rest,
|
|
59140
59184
|
// On popupProps already (see the picker's popup assembly); they mean
|
|
59141
59185
|
// nothing to the picker element.
|
|
59142
|
-
|
|
59143
|
-
unmountWhenClosed: undefined,
|
|
59186
|
+
mount: undefined,
|
|
59144
59187
|
onFocusOut: e => {
|
|
59145
59188
|
if (!isPopover || !closeOnFocusOut) {
|
|
59146
59189
|
return;
|
|
@@ -59222,7 +59265,7 @@ const PICKER_CALLOUT_CONTENT_TOKEN = createOpenToken();
|
|
|
59222
59265
|
* The content is rendered through a portal into an element this component
|
|
59223
59266
|
* owns, handed to the callout as its message (a Node, appended as-is). It is
|
|
59224
59267
|
* rendered whether the callout is open or not, so what the content holds
|
|
59225
|
-
* survives a close, the way a popup's `
|
|
59268
|
+
* survives a close, the way a popup's `mount="always"` keeps it. The element
|
|
59226
59269
|
* carries data-picker-content: the callout is appended inside the picker root,
|
|
59227
59270
|
* and a press in there must read as inside the popup, not on the trigger.
|
|
59228
59271
|
*/
|
|
@@ -59393,7 +59436,12 @@ const PickerConfirmResolver = props => {
|
|
|
59393
59436
|
return jsx(Next, {
|
|
59394
59437
|
...props,
|
|
59395
59438
|
type: "navi_js",
|
|
59396
|
-
allowNameless: true
|
|
59439
|
+
allowNameless: true
|
|
59440
|
+
// No chevron, no clear cross, whatever variant the trigger is drawn in:
|
|
59441
|
+
// both announce a value, and a question holds none.
|
|
59442
|
+
,
|
|
59443
|
+
|
|
59444
|
+
picksNothing: true,
|
|
59397
59445
|
variant: variant,
|
|
59398
59446
|
mode: mode,
|
|
59399
59447
|
focusCapture: focusCapture,
|
|
@@ -59401,10 +59449,10 @@ const PickerConfirmResolver = props => {
|
|
|
59401
59449
|
onConfirm: onConfirm
|
|
59402
59450
|
// A question holds no value to read before it is asked: the popup is
|
|
59403
59451
|
// built on the first open, like that of a picker told its value (see
|
|
59404
|
-
//
|
|
59452
|
+
// the `mount` resolution in picker_custom.jsx).
|
|
59405
59453
|
,
|
|
59406
59454
|
|
|
59407
|
-
|
|
59455
|
+
mount: MOUNT_DEFAULT,
|
|
59408
59456
|
message: undefined,
|
|
59409
59457
|
confirmLabel: undefined,
|
|
59410
59458
|
cancelLabel: undefined,
|
|
@@ -60262,7 +60310,7 @@ installImportMetaCssBuild(import.meta);const css$y = /* css */`@layer navi {
|
|
|
60262
60310
|
--x-list-item-cursor: default;
|
|
60263
60311
|
--x-list-item-border-color: var(--list-item-border-color);
|
|
60264
60312
|
font-size: var(--navi-control-font-size);
|
|
60265
|
-
font-family: var(--navi-control-font-family);
|
|
60313
|
+
font-family: var(--navi-control-font-family, inherit);
|
|
60266
60314
|
line-height: var(--navi-control-line-height);
|
|
60267
60315
|
position: relative;
|
|
60268
60316
|
}
|
|
@@ -66705,7 +66753,7 @@ installImportMetaCssBuild(import.meta);const css$t = /* css */`@layer navi {
|
|
|
66705
66753
|
--picker-padding-x-default: var(--navi-picker-padding-x-default);
|
|
66706
66754
|
--picker-padding-y-default: var(--navi-picker-padding-y-default);
|
|
66707
66755
|
--picker-font-size: var(--navi-control-font-size);
|
|
66708
|
-
--picker-font-family: var(--navi-control-font-family);
|
|
66756
|
+
--picker-font-family: var(--navi-control-font-family, inherit);
|
|
66709
66757
|
--picker-loader-color: var(--navi-loader-color);
|
|
66710
66758
|
--picker-border-color: var(--navi-control-border-color);
|
|
66711
66759
|
--picker-background-color: white;
|
|
@@ -66805,6 +66853,7 @@ installImportMetaCssBuild(import.meta);const css$t = /* css */`@layer navi {
|
|
|
66805
66853
|
padding-bottom: var(--x-picker-padding-bottom);
|
|
66806
66854
|
padding-left: var(--x-picker-padding-left);
|
|
66807
66855
|
justify-content: inherit;
|
|
66856
|
+
text-align: var(--picker-align-x, var(--picker-text-align-default));
|
|
66808
66857
|
pointer-events: none;
|
|
66809
66858
|
user-select: none;
|
|
66810
66859
|
flex-grow: 1;
|
|
@@ -66963,7 +67012,7 @@ installImportMetaCssBuild(import.meta);const css$t = /* css */`@layer navi {
|
|
|
66963
67012
|
--picker-background-color-hover: var(--picker-background-color);
|
|
66964
67013
|
--picker-background-color-readonly: var(--picker-background-color);
|
|
66965
67014
|
--picker-background-color-disabled: var(--picker-background-color);
|
|
66966
|
-
--
|
|
67015
|
+
--picker-icon-color: currentColor;
|
|
66967
67016
|
|
|
66968
67017
|
& .navi_picker_value {
|
|
66969
67018
|
flex-grow: 0;
|
|
@@ -66996,7 +67045,7 @@ installImportMetaCssBuild(import.meta);const css$t = /* css */`@layer navi {
|
|
|
66996
67045
|
--picker-background-color-hover: var(--picker-background-color);
|
|
66997
67046
|
--picker-background-color-readonly: var(--picker-background-color);
|
|
66998
67047
|
--picker-background-color-disabled: var(--picker-background-color);
|
|
66999
|
-
--
|
|
67048
|
+
--picker-icon-color: currentColor;
|
|
67000
67049
|
|
|
67001
67050
|
& .navi_picker_box {
|
|
67002
67051
|
z-index: -1;
|
|
@@ -67018,7 +67067,7 @@ installImportMetaCssBuild(import.meta);const css$t = /* css */`@layer navi {
|
|
|
67018
67067
|
--picker-background-color-hover: var(--picker-background-color);
|
|
67019
67068
|
--picker-background-color-readonly: var(--picker-background-color);
|
|
67020
67069
|
--picker-background-color-disabled: var(--picker-background-color);
|
|
67021
|
-
--
|
|
67070
|
+
--picker-icon-color: currentColor;
|
|
67022
67071
|
font-size: inherit;
|
|
67023
67072
|
font-family: inherit;
|
|
67024
67073
|
line-height: inherit;
|
|
@@ -67043,7 +67092,7 @@ installImportMetaCssBuild(import.meta);const css$t = /* css */`@layer navi {
|
|
|
67043
67092
|
--picker-border-color-disabled: var(--picker-border-color-readonly);
|
|
67044
67093
|
--picker-background-color-disabled: var(--picker-background-color-readonly);
|
|
67045
67094
|
--picker-color-disabled: var(--picker-color-readonly);
|
|
67046
|
-
text-align: center;
|
|
67095
|
+
--picker-text-align-default: center;
|
|
67047
67096
|
}
|
|
67048
67097
|
|
|
67049
67098
|
&[data-variant="text"] {
|
|
@@ -67109,6 +67158,11 @@ const PickerButton = props => {
|
|
|
67109
67158
|
// not come back. The cross is then a confirm picker (see
|
|
67110
67159
|
// picker_confirm.jsx), and the clear only goes out on yes.
|
|
67111
67160
|
clearConfirm,
|
|
67161
|
+
// Nothing is picked here: the popup asks a question rather than holding an
|
|
67162
|
+
// answer, so the trigger draws a label and never a value. Set by the
|
|
67163
|
+
// confirm resolver (see picker_confirm.jsx), which is the picker that is
|
|
67164
|
+
// one — a caller whose popup is a menu of actions says it for themselves.
|
|
67165
|
+
picksNothing,
|
|
67112
67166
|
readOnly,
|
|
67113
67167
|
error
|
|
67114
67168
|
} = props;
|
|
@@ -67122,17 +67176,19 @@ const PickerButton = props => {
|
|
|
67122
67176
|
const isSingleLine = maxLines === 1;
|
|
67123
67177
|
// Same rule as the root: phrasing content inside a sentence.
|
|
67124
67178
|
const ContentTag = variant === "text" ? "span" : "div";
|
|
67125
|
-
//
|
|
67126
|
-
//
|
|
67127
|
-
//
|
|
67128
|
-
//
|
|
67179
|
+
// Who gets the right slot — the chevron saying "this opens", and the cross
|
|
67180
|
+
// replacing it once there is something to clear. Both are about a value, so
|
|
67181
|
+
// the slot follows the value and not the drawing: `picksNothing` has none to
|
|
67182
|
+
// announce and none to take back, whatever variant it is drawn in.
|
|
67183
|
+
// Then the variants that draw no value beside it: an icon picker IS its icon,
|
|
67184
|
+
// a headless one draws nothing, a button says what it opens with its label, a
|
|
67129
67185
|
// word in a sentence has no room for furniture. Nor a picker rendering the
|
|
67130
67186
|
// browser's own control ("default").
|
|
67131
67187
|
// Nor a bare one: the picker is that drawing's box to the pixel, so anything
|
|
67132
67188
|
// navi adds beside it either grows the box or covers what the caller drew.
|
|
67133
67189
|
// The pieces are the caller's to place there instead — a <Picker.Clear /> in
|
|
67134
67190
|
// their own layout (see warnOnClearableWithoutSlot).
|
|
67135
|
-
const hasRightSlot = variant !== "icon" && variant !== "headless" && variant !== "button" && variant !== "text" && variant !== "bare" && ui !== "default";
|
|
67191
|
+
const hasRightSlot = !picksNothing && variant !== "icon" && variant !== "headless" && variant !== "button" && variant !== "text" && variant !== "bare" && ui !== "default";
|
|
67136
67192
|
const inputRef = useRef(null);
|
|
67137
67193
|
const [pickerRemainingProps, inputProps, facadeChildrenProps] = useControlFacadeProps({
|
|
67138
67194
|
...props,
|
|
@@ -67211,6 +67267,7 @@ const PickerButton = props => {
|
|
|
67211
67267
|
rightSlotIconSize: undefined,
|
|
67212
67268
|
rightSlot: undefined,
|
|
67213
67269
|
clearConfirm: undefined,
|
|
67270
|
+
picksNothing: undefined,
|
|
67214
67271
|
openWhileReadOnly: undefined,
|
|
67215
67272
|
ui: undefined,
|
|
67216
67273
|
maxLines: undefined,
|
|
@@ -67763,7 +67820,7 @@ const css$s = /* css */`@layer navi {
|
|
|
67763
67820
|
--x-picker-spin-padding-bottom: var(--picker-spin-padding-bottom, var(--picker-spin-padding-y, var(--picker-spin-padding, var(--picker-spin-padding-y-default))));
|
|
67764
67821
|
--x-picker-spin-padding-left: var(--picker-spin-padding-left, var(--picker-spin-padding-x, var(--picker-spin-padding, var(--picker-spin-padding-x-default))));
|
|
67765
67822
|
font-size: var(--navi-control-font-size);
|
|
67766
|
-
font-family: var(--navi-control-font-family);
|
|
67823
|
+
font-family: var(--navi-control-font-family, inherit);
|
|
67767
67824
|
border: var(--navi-control-border-width) solid
|
|
67768
67825
|
var(--navi-control-border-color);
|
|
67769
67826
|
border-top-left-radius: var(--x-corner-top-left-radius, var(--navi-control-border-radius));
|
|
@@ -67913,7 +67970,7 @@ const css$s = /* css */`@layer navi {
|
|
|
67913
67970
|
|
|
67914
67971
|
.navi_spin_group {
|
|
67915
67972
|
font-size: var(--navi-control-font-size);
|
|
67916
|
-
font-family: var(--navi-control-font-family);
|
|
67973
|
+
font-family: var(--navi-control-font-family, inherit);
|
|
67917
67974
|
border: var(--navi-control-border-width) solid
|
|
67918
67975
|
var(--navi-control-border-color);
|
|
67919
67976
|
border-top-left-radius: var(--x-corner-top-left-radius, var(--navi-control-border-radius));
|
|
@@ -70811,7 +70868,7 @@ const css$m = /* css */`.navi_wheel_container {
|
|
|
70811
70868
|
transparent);
|
|
70812
70869
|
color: var(--wheel-color);
|
|
70813
70870
|
font-size: var(--navi-control-font-size);
|
|
70814
|
-
font-family: var(--navi-control-font-family);
|
|
70871
|
+
font-family: var(--navi-control-font-family, inherit);
|
|
70815
70872
|
border: var(--navi-control-border-width) solid
|
|
70816
70873
|
var(--navi-control-border-color);
|
|
70817
70874
|
border-radius: var(--navi-control-border-radius);
|
|
@@ -71101,7 +71158,7 @@ const css$m = /* css */`.navi_wheel_container {
|
|
|
71101
71158
|
color: var(--wheel-color, light-dark(#111, #eee));
|
|
71102
71159
|
font-weight: 600;
|
|
71103
71160
|
font-size: var(--navi-control-font-size);
|
|
71104
|
-
font-family: var(--navi-control-font-family);
|
|
71161
|
+
font-family: var(--navi-control-font-family, inherit);
|
|
71105
71162
|
white-space: nowrap;
|
|
71106
71163
|
user-select: none;
|
|
71107
71164
|
justify-content: center;
|
|
@@ -75862,7 +75919,6 @@ const css$g = /* css */`.navi_table_root {
|
|
|
75862
75919
|
|
|
75863
75920
|
.navi_table {
|
|
75864
75921
|
--editing-border-color: #a8c7fa;
|
|
75865
|
-
font-family: Arial;
|
|
75866
75922
|
font-size: 16px;
|
|
75867
75923
|
}
|
|
75868
75924
|
|