@jsenv/navi 0.29.54 → 0.29.56
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 +654 -160
- package/dist/jsenv_navi.js.map +54 -24
- package/package.json +2 -2
package/dist/jsenv_navi.js
CHANGED
|
@@ -38,7 +38,7 @@ installImportMetaCssBuild(import.meta);/**
|
|
|
38
38
|
* any of these, and a number is the last resort, not the first tool.
|
|
39
39
|
*/
|
|
40
40
|
|
|
41
|
-
const css$
|
|
41
|
+
const css$11 = /* css */`
|
|
42
42
|
@layer navi {
|
|
43
43
|
:root {
|
|
44
44
|
/* A control that overlaps its neighbours (the members of a Group share
|
|
@@ -90,7 +90,7 @@ const css$10 = /* css */`
|
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
`;
|
|
93
|
-
import.meta.css = [css$
|
|
93
|
+
import.meta.css = [css$11, "@jsenv/navi/src/navi_z_indexes.js"];
|
|
94
94
|
|
|
95
95
|
const addIntoArray = (array, ...valuesToAdd) => {
|
|
96
96
|
if (valuesToAdd.length === 1) {
|
|
@@ -359,7 +359,7 @@ installImportMetaCssBuild(import.meta);/**
|
|
|
359
359
|
* the very first render and the browser does everything on its own.
|
|
360
360
|
*/
|
|
361
361
|
const URL_TARGET_ATTRIBUTE = "data-url-target";
|
|
362
|
-
const css
|
|
362
|
+
const css$10 = /* css */`
|
|
363
363
|
@layer navi {
|
|
364
364
|
[${URL_TARGET_ATTRIBUTE}] {
|
|
365
365
|
animation: navi_url_target var(--navi-url-target-duration, 2000ms)
|
|
@@ -377,7 +377,7 @@ const css$$ = /* css */`
|
|
|
377
377
|
}
|
|
378
378
|
}
|
|
379
379
|
`;
|
|
380
|
-
import.meta.css = [css
|
|
380
|
+
import.meta.css = [css$10, "@jsenv/navi/src/nav/url_target/url_target.js"];
|
|
381
381
|
let urlTargetOptions = {
|
|
382
382
|
block: "center",
|
|
383
383
|
behavior: "smooth",
|
|
@@ -1299,6 +1299,10 @@ naviI18n.addAll({
|
|
|
1299
1299
|
en: "Confirm",
|
|
1300
1300
|
fr: "Confirmer",
|
|
1301
1301
|
},
|
|
1302
|
+
"button.more_actions": {
|
|
1303
|
+
en: "More actions",
|
|
1304
|
+
fr: "Autres actions",
|
|
1305
|
+
},
|
|
1302
1306
|
});
|
|
1303
1307
|
|
|
1304
1308
|
// Default built-in translations — apps can override any key via add()
|
|
@@ -7725,7 +7729,7 @@ installImportMetaCssBuild(import.meta);/**
|
|
|
7725
7729
|
* - Arrow automatically shows when pointing at a valid anchor element
|
|
7726
7730
|
* - Centers in viewport when no anchor element provided or anchor is too big
|
|
7727
7731
|
*/
|
|
7728
|
-
const css
|
|
7732
|
+
const css$$ = /* css */`
|
|
7729
7733
|
@layer navi {
|
|
7730
7734
|
.navi_callout {
|
|
7731
7735
|
/* A callout is parented to what it explains, so it inherits from it — and
|
|
@@ -7964,7 +7968,7 @@ const openCallout = (message, {
|
|
|
7964
7968
|
skipFocus = false,
|
|
7965
7969
|
debug = () => {}
|
|
7966
7970
|
} = {}) => {
|
|
7967
|
-
import.meta.css = [css
|
|
7971
|
+
import.meta.css = [css$$, "@jsenv/navi/src/control/rules/callout/callout.js"];
|
|
7968
7972
|
if (debug === true) {
|
|
7969
7973
|
debug = (e, ...args) => console.debug(`"${e.type}" -> `, ...args);
|
|
7970
7974
|
}
|
|
@@ -20031,7 +20035,7 @@ const setupNetworkMonitoring = () => {
|
|
|
20031
20035
|
};
|
|
20032
20036
|
setupNetworkMonitoring();
|
|
20033
20037
|
|
|
20034
|
-
installImportMetaCssBuild(import.meta);const css$
|
|
20038
|
+
installImportMetaCssBuild(import.meta);const css$_ = /* css */`
|
|
20035
20039
|
.navi_loading_indicator_fluid_container {
|
|
20036
20040
|
position: relative;
|
|
20037
20041
|
display: flex;
|
|
@@ -20063,7 +20067,7 @@ const LoadingIndicatorFluid = ({
|
|
|
20063
20067
|
visuallyHidden,
|
|
20064
20068
|
...rest
|
|
20065
20069
|
}) => {
|
|
20066
|
-
import.meta.css = [css$
|
|
20070
|
+
import.meta.css = [css$_, "@jsenv/navi/src/graphic/loading/loading_indicator_fluid.jsx"];
|
|
20067
20071
|
const ref = useRef(null);
|
|
20068
20072
|
// The container dimensions can be deduced from the ref itself as the indicator is absolute inset 0
|
|
20069
20073
|
const [containerWidth, setContainerWidth] = useState(0);
|
|
@@ -20268,7 +20272,7 @@ const LoadingRectangleSvg = ({
|
|
|
20268
20272
|
});
|
|
20269
20273
|
};
|
|
20270
20274
|
|
|
20271
|
-
installImportMetaCssBuild(import.meta);const css$
|
|
20275
|
+
installImportMetaCssBuild(import.meta);const css$Z = /* css */`
|
|
20272
20276
|
.navi_loading_outline_wrapper {
|
|
20273
20277
|
position: absolute;
|
|
20274
20278
|
/* Controls place the outline slightly outside their box, right on top of
|
|
@@ -20305,7 +20309,7 @@ installImportMetaCssBuild(import.meta);const css$Y = /* css */`
|
|
|
20305
20309
|
}
|
|
20306
20310
|
`;
|
|
20307
20311
|
const LoadingOutline = props => {
|
|
20308
|
-
import.meta.css = [css$
|
|
20312
|
+
import.meta.css = [css$Z, "@jsenv/navi/src/graphic/loading/loading_outline.jsx"];
|
|
20309
20313
|
if (props.containerRef) {
|
|
20310
20314
|
const container = props.containerRef.current;
|
|
20311
20315
|
if (!container) {
|
|
@@ -20595,7 +20599,7 @@ const selectByTextStrings = (element, range, startText, endText) => {
|
|
|
20595
20599
|
};
|
|
20596
20600
|
|
|
20597
20601
|
installImportMetaCssBuild(import.meta);// https://jsfiddle.net/v5xzJ/4/
|
|
20598
|
-
const css$
|
|
20602
|
+
const css$Y = /* css */`
|
|
20599
20603
|
@layer navi {
|
|
20600
20604
|
.navi_text {
|
|
20601
20605
|
&[data-skeleton] {
|
|
@@ -21101,7 +21105,7 @@ const TextShrinkWrap = props => {
|
|
|
21101
21105
|
});
|
|
21102
21106
|
};
|
|
21103
21107
|
const TextUI = props => {
|
|
21104
|
-
import.meta.css = [css$
|
|
21108
|
+
import.meta.css = [css$Y, "@jsenv/navi/src/text/text.jsx"];
|
|
21105
21109
|
let {
|
|
21106
21110
|
ref,
|
|
21107
21111
|
spacing,
|
|
@@ -26982,7 +26986,7 @@ const getAssociatedLabels = element => {
|
|
|
26982
26986
|
return Array.from(element.labels);
|
|
26983
26987
|
};
|
|
26984
26988
|
|
|
26985
|
-
installImportMetaCssBuild(import.meta);const css$
|
|
26989
|
+
installImportMetaCssBuild(import.meta);const css$X = /* css */`
|
|
26986
26990
|
@layer navi {
|
|
26987
26991
|
.navi_button {
|
|
26988
26992
|
--button-border-radius: var(--navi-control-border-radius);
|
|
@@ -27413,7 +27417,7 @@ installImportMetaCssBuild(import.meta);const css$W = /* css */`
|
|
|
27413
27417
|
}
|
|
27414
27418
|
`;
|
|
27415
27419
|
const ButtonUI = props => {
|
|
27416
|
-
import.meta.css = [css$
|
|
27420
|
+
import.meta.css = [css$X, "@jsenv/navi/src/control/input/button_ui.jsx"];
|
|
27417
27421
|
const {
|
|
27418
27422
|
ref,
|
|
27419
27423
|
// href/link
|
|
@@ -27425,7 +27429,11 @@ const ButtonUI = props => {
|
|
|
27425
27429
|
pressEffect,
|
|
27426
27430
|
icon,
|
|
27427
27431
|
cta,
|
|
27428
|
-
spacing
|
|
27432
|
+
spacing,
|
|
27433
|
+
// Whether the button draws the loading outline itself. A button that is
|
|
27434
|
+
// one half of a bigger control says no: what is busy is the control, and
|
|
27435
|
+
// the outline belongs around the whole of it (see split_button.jsx).
|
|
27436
|
+
loadingOutline = true
|
|
27429
27437
|
} = props;
|
|
27430
27438
|
const [buttonControlRootProps, buttonControlHostProps, controlChildrenWrapperProps] = useControlProps(props, {
|
|
27431
27439
|
controlType: "button",
|
|
@@ -27481,6 +27489,7 @@ const ButtonUI = props => {
|
|
|
27481
27489
|
spacing: undefined,
|
|
27482
27490
|
cta: undefined,
|
|
27483
27491
|
pressEffect: undefined,
|
|
27492
|
+
loadingOutline: undefined,
|
|
27484
27493
|
ref: ref,
|
|
27485
27494
|
as: as,
|
|
27486
27495
|
href: href,
|
|
@@ -27524,7 +27533,7 @@ const ButtonUI = props => {
|
|
|
27524
27533
|
visualSelector: visualSelector,
|
|
27525
27534
|
hasChildUsingForwardedProps: true,
|
|
27526
27535
|
children: [jsx(LoadingOutline, {
|
|
27527
|
-
loading: loading,
|
|
27536
|
+
loading: loadingOutline && loading,
|
|
27528
27537
|
inset: -1,
|
|
27529
27538
|
color: "var(--button-loader-color)"
|
|
27530
27539
|
}), jsx(ControlChildrenWrapper, {
|
|
@@ -29247,7 +29256,7 @@ installImportMetaCssBuild(import.meta);/**
|
|
|
29247
29256
|
* reaches the real container.
|
|
29248
29257
|
*/
|
|
29249
29258
|
let openLocalDialogCount = 0;
|
|
29250
|
-
const css$
|
|
29259
|
+
const css$W = /* css */`
|
|
29251
29260
|
@layer navi {
|
|
29252
29261
|
.navi_dialog {
|
|
29253
29262
|
/* Min gap between the dialog and the edges of its container. Written
|
|
@@ -29633,7 +29642,10 @@ const css$V = /* css */`
|
|
|
29633
29642
|
* from where the finger just tapped, and size alone would dock a narrow
|
|
29634
29643
|
* desktop window, which is still a mouse. It supplies defaults for
|
|
29635
29644
|
* `positionArea`, `marginWithContainer`, `expandX` and `scrollCapture`, so
|
|
29636
|
-
* any of them can still be pinned explicitly.
|
|
29645
|
+
* any of them can still be pinned explicitly. Ignored entirely when `expandY`
|
|
29646
|
+
* (or `expand`) is set: a dialog already filling the height is on the bottom
|
|
29647
|
+
* edge docking would bring it to, so docking could only take away the shape
|
|
29648
|
+
* the caller asked for. Re-resolves live as the pointer
|
|
29637
29649
|
* type or the window size changes. A sheet resting on the bottom edge is also
|
|
29638
29650
|
* pushed back down to close it, held by its header (a direct child `Box` with
|
|
29639
29651
|
* the `header` prop) — or from anywhere when it has none. See `swipe_to_close.js`.
|
|
@@ -29652,7 +29664,7 @@ const css$V = /* css */`
|
|
|
29652
29664
|
* container allows (`--dialog-maxmax-width`). Set by
|
|
29653
29665
|
* `dockedOnSmallTouchScreen` on a small touch screen.
|
|
29654
29666
|
* @param {boolean} [props.expandY] - Same, vertically
|
|
29655
|
-
* (`--dialog-maxmax-height`).
|
|
29667
|
+
* (`--dialog-maxmax-height`). Cancels `dockedOnSmallTouchScreen`.
|
|
29656
29668
|
* @param {string|number} [props.marginWithContainer="3appw"] - Minimum gap kept
|
|
29657
29669
|
* between the dialog and the edges of its container, whatever its
|
|
29658
29670
|
* `positionArea`: it both caps the dialog's own size (via
|
|
@@ -29756,7 +29768,7 @@ const css$V = /* css */`
|
|
|
29756
29768
|
* @param {import("ignore:preact").ComponentChildren} props.children
|
|
29757
29769
|
*/
|
|
29758
29770
|
const Dialog = props => {
|
|
29759
|
-
import.meta.css = [css$
|
|
29771
|
+
import.meta.css = [css$W, "@jsenv/navi/src/layout/dialog.jsx"];
|
|
29760
29772
|
if (props.openController) {
|
|
29761
29773
|
return jsx(ControlledDialog, {
|
|
29762
29774
|
...props
|
|
@@ -29984,10 +29996,15 @@ const useDialogProps = props => {
|
|
|
29984
29996
|
});
|
|
29985
29997
|
const isModal = layer === "top";
|
|
29986
29998
|
const ref = props.ref;
|
|
29999
|
+
const expandY = Boolean(expand) || Boolean(expandYProp);
|
|
29987
30000
|
// Only a small touch screen changes anything: on a mouse — and on a touch
|
|
29988
30001
|
// screen too big to reach the bottom edge of — a dialog already wants to be
|
|
29989
30002
|
// the centered box it is by default, so there is nothing to resolve.
|
|
29990
|
-
|
|
30003
|
+
// expandY cancels the docking outright: docking exists to bring the dialog
|
|
30004
|
+
// down to the edge the thumb is on, and a dialog already filling the height
|
|
30005
|
+
// is on that edge — all docking could still do is take away the shape the
|
|
30006
|
+
// caller asked for (and arm a swipe-down on something that never rose).
|
|
30007
|
+
const isDocked = dockedOnSmallTouchScreen && smallTouchScreenSignal.value && !expandY;
|
|
29991
30008
|
const positionArea = positionAreaProp ?? (isDocked ? DOCKED.positionArea : "center");
|
|
29992
30009
|
const marginWithContainer = marginWithContainerProp ?? (isDocked ? DOCKED.marginWithContainer :
|
|
29993
30010
|
// A share of whatever holds the dialog: the app's own screen for a
|
|
@@ -30000,7 +30017,6 @@ const useDialogProps = props => {
|
|
|
30000
30017
|
// handing them over — the docked default only applies when neither was said
|
|
30001
30018
|
const expandXUnset = expand === undefined && expandXProp === undefined;
|
|
30002
30019
|
const expandX = expandXUnset ? isDocked && DOCKED.expandX : Boolean(expand) || Boolean(expandXProp);
|
|
30003
|
-
const expandY = Boolean(expand) || Boolean(expandYProp);
|
|
30004
30020
|
const scrollCapture = scrollCaptureProp ?? (isDocked ? DOCKED.scrollCapture : false);
|
|
30005
30021
|
const backdropRef = useRef();
|
|
30006
30022
|
// Disarms a still-pending backdrop hide from a previous close (see
|
|
@@ -30670,7 +30686,7 @@ installImportMetaCssBuild(import.meta);/**
|
|
|
30670
30686
|
* and applied.
|
|
30671
30687
|
*/
|
|
30672
30688
|
let openLocalPopoverCount = 0;
|
|
30673
|
-
const css$
|
|
30689
|
+
const css$V = /* css */`
|
|
30674
30690
|
@layer navi {
|
|
30675
30691
|
.navi_popover {
|
|
30676
30692
|
/* soft: user-configurable preferred max-height. Kept as a *default*
|
|
@@ -31103,7 +31119,7 @@ const css$U = /* css */`
|
|
|
31103
31119
|
* @param {import("ignore:preact").ComponentChildren} props.children
|
|
31104
31120
|
*/
|
|
31105
31121
|
const Popover = props => {
|
|
31106
|
-
import.meta.css = [css$
|
|
31122
|
+
import.meta.css = [css$V, "@jsenv/navi/src/layout/popover.jsx"];
|
|
31107
31123
|
if (props.openController) {
|
|
31108
31124
|
return jsx(ControlledPopover, {
|
|
31109
31125
|
...props
|
|
@@ -32122,7 +32138,7 @@ installImportMetaCssBuild(import.meta);/**
|
|
|
32122
32138
|
* event, and a caller replacing the body entirely then has one protocol to
|
|
32123
32139
|
* follow — `--navi-confirm` for yes, anything that closes for no.
|
|
32124
32140
|
*/
|
|
32125
|
-
const css$
|
|
32141
|
+
const css$U = /* css */`
|
|
32126
32142
|
/* The width lives on the body rather than on the popup, so that custom
|
|
32127
32143
|
content (which replaces this body entirely) sizes itself instead of
|
|
32128
32144
|
inheriting a ceiling meant for a sentence-long question. */
|
|
@@ -32259,7 +32275,7 @@ const ConfirmPopup = ({
|
|
|
32259
32275
|
onAnswer,
|
|
32260
32276
|
onClosed
|
|
32261
32277
|
}) => {
|
|
32262
|
-
import.meta.css = [css$
|
|
32278
|
+
import.meta.css = [css$U, "@jsenv/navi/src/action/confirm_popup.jsx"];
|
|
32263
32279
|
const {
|
|
32264
32280
|
mode,
|
|
32265
32281
|
confirmLabel,
|
|
@@ -32343,7 +32359,7 @@ const defaultBody = (message, {
|
|
|
32343
32359
|
});
|
|
32344
32360
|
};
|
|
32345
32361
|
|
|
32346
|
-
installImportMetaCssBuild(import.meta);const css$
|
|
32362
|
+
installImportMetaCssBuild(import.meta);const css$T = /* css */`
|
|
32347
32363
|
.action_error {
|
|
32348
32364
|
margin-top: 0;
|
|
32349
32365
|
margin-bottom: 20px;
|
|
@@ -32368,7 +32384,7 @@ const ActionRenderer = ({
|
|
|
32368
32384
|
children,
|
|
32369
32385
|
disabled
|
|
32370
32386
|
}) => {
|
|
32371
|
-
import.meta.css = [css$
|
|
32387
|
+
import.meta.css = [css$T, "@jsenv/navi/src/action/action_renderer.jsx"];
|
|
32372
32388
|
if (action === undefined) {
|
|
32373
32389
|
throw new Error("ActionRenderer requires an action to render, but none was provided.");
|
|
32374
32390
|
}
|
|
@@ -37927,7 +37943,7 @@ const TRAVEL_HEIGHT_PROPERTY = "--navi-route-travel-height";
|
|
|
37927
37943
|
const TRAVEL_OLD_TOP_PROPERTY = "--navi-route-travel-old-top";
|
|
37928
37944
|
const TRAVEL_OLD_LEFT_PROPERTY = "--navi-route-travel-old-left";
|
|
37929
37945
|
const TRAVEL_GEOMETRY_PROPERTIES = [TRAVEL_TOP_PROPERTY, TRAVEL_LEFT_PROPERTY, TRAVEL_WIDTH_PROPERTY, TRAVEL_HEIGHT_PROPERTY, TRAVEL_OLD_TOP_PROPERTY, TRAVEL_OLD_LEFT_PROPERTY];
|
|
37930
|
-
const css$
|
|
37946
|
+
const css$S = /* css */`
|
|
37931
37947
|
/* The name that makes the page inside this box a picture of its own during a
|
|
37932
37948
|
transition — rather than part of the one big picture the document takes, so
|
|
37933
37949
|
the two pages can move past each other while everything else stays where it
|
|
@@ -38309,7 +38325,7 @@ const RouteTravel = ({
|
|
|
38309
38325
|
children,
|
|
38310
38326
|
...rest
|
|
38311
38327
|
}) => {
|
|
38312
|
-
import.meta.css = [css$
|
|
38328
|
+
import.meta.css = [css$S, "@jsenv/navi/src/nav/route_travel.jsx"];
|
|
38313
38329
|
const elementRef = useRef();
|
|
38314
38330
|
const gestureRef = useRef(null);
|
|
38315
38331
|
// The travel in hand: the transition keeping the picture of the page being
|
|
@@ -40969,7 +40985,7 @@ const PhoneSvg = () => {
|
|
|
40969
40985
|
};
|
|
40970
40986
|
|
|
40971
40987
|
installImportMetaCssBuild(import.meta);// # TextAnchor — how it works
|
|
40972
|
-
const css$
|
|
40988
|
+
const css$R = /* css */`
|
|
40973
40989
|
.navi_text_anchor {
|
|
40974
40990
|
vertical-align: baseline;
|
|
40975
40991
|
user-select: none;
|
|
@@ -41004,7 +41020,7 @@ const TextAnchor = ({
|
|
|
41004
41020
|
textSize,
|
|
41005
41021
|
lineLayout
|
|
41006
41022
|
}) => {
|
|
41007
|
-
import.meta.css = [css$
|
|
41023
|
+
import.meta.css = [css$R, "@jsenv/navi/src/text/text_anchor.jsx"];
|
|
41008
41024
|
const anchorRef = useRef();
|
|
41009
41025
|
|
|
41010
41026
|
// Plain useLayoutEffect would also fire while an ancestor dialog/popover
|
|
@@ -41119,7 +41135,7 @@ const computeTopOffset = ({
|
|
|
41119
41135
|
};
|
|
41120
41136
|
const charTopCanvas = document.createElement("canvas");
|
|
41121
41137
|
|
|
41122
|
-
installImportMetaCssBuild(import.meta);const css$
|
|
41138
|
+
installImportMetaCssBuild(import.meta);const css$Q = /* css */`
|
|
41123
41139
|
@layer navi {
|
|
41124
41140
|
/* Ensure data attributes from box.jsx can win to update display */
|
|
41125
41141
|
.navi_icon {
|
|
@@ -41277,7 +41293,7 @@ const Icon = ({
|
|
|
41277
41293
|
fillLine,
|
|
41278
41294
|
...props
|
|
41279
41295
|
}) => {
|
|
41280
|
-
import.meta.css = [css$
|
|
41296
|
+
import.meta.css = [css$Q, "@jsenv/navi/src/text/icon.jsx"];
|
|
41281
41297
|
const innerChildren = href ? jsx("svg", {
|
|
41282
41298
|
width: "100%",
|
|
41283
41299
|
height: "100%",
|
|
@@ -41439,7 +41455,7 @@ const useDimColorWhen = (elementRef, shouldDim) => {
|
|
|
41439
41455
|
});
|
|
41440
41456
|
};
|
|
41441
41457
|
|
|
41442
|
-
installImportMetaCssBuild(import.meta);const css$
|
|
41458
|
+
installImportMetaCssBuild(import.meta);const css$P = /* css */`
|
|
41443
41459
|
@layer navi {
|
|
41444
41460
|
.navi_link {
|
|
41445
41461
|
--link-border-radius: unset;
|
|
@@ -41887,7 +41903,7 @@ Object.assign(PSEUDO_CLASSES, {
|
|
|
41887
41903
|
* @param {boolean} [props.readOnly]
|
|
41888
41904
|
*/
|
|
41889
41905
|
const Link = props => {
|
|
41890
|
-
import.meta.css = [css$
|
|
41906
|
+
import.meta.css = [css$P, "@jsenv/navi/src/nav/link/link.jsx"];
|
|
41891
41907
|
if (props.route) {
|
|
41892
41908
|
return jsx(LinkWithRoute, {
|
|
41893
41909
|
...props
|
|
@@ -42190,7 +42206,7 @@ installImportMetaCssBuild(import.meta);/**
|
|
|
42190
42206
|
* https://dribbble.com/search/tabs
|
|
42191
42207
|
*/
|
|
42192
42208
|
let navCount = 0;
|
|
42193
|
-
const css$
|
|
42209
|
+
const css$O = /* css */`
|
|
42194
42210
|
@layer navi {
|
|
42195
42211
|
.navi_nav {
|
|
42196
42212
|
--nav-border: none;
|
|
@@ -42473,7 +42489,7 @@ const Nav = ({
|
|
|
42473
42489
|
slideContainer,
|
|
42474
42490
|
...props
|
|
42475
42491
|
}) => {
|
|
42476
|
-
import.meta.css = [css$
|
|
42492
|
+
import.meta.css = [css$O, "@jsenv/navi/src/nav/link/nav.jsx"];
|
|
42477
42493
|
const defaultRef = useRef();
|
|
42478
42494
|
props.ref = props.ref || defaultRef;
|
|
42479
42495
|
const navRef = props.ref;
|
|
@@ -43000,7 +43016,7 @@ installImportMetaCssBuild(import.meta);/**
|
|
|
43000
43016
|
* Border width participates in layout (it is added to the tab and page
|
|
43001
43017
|
* padding): a thick border grows the binder rather than eating into the text.
|
|
43002
43018
|
*/
|
|
43003
|
-
const css$
|
|
43019
|
+
const css$N = /* css */`
|
|
43004
43020
|
@layer navi {
|
|
43005
43021
|
.navi_binder {
|
|
43006
43022
|
--binder-border-width: var(--navi-control-border-width);
|
|
@@ -43313,7 +43329,7 @@ const Binder = ({
|
|
|
43313
43329
|
pagePadding,
|
|
43314
43330
|
...props
|
|
43315
43331
|
}) => {
|
|
43316
|
-
import.meta.css = [css$
|
|
43332
|
+
import.meta.css = [css$N, "@jsenv/navi/src/nav/binder/binder.jsx"];
|
|
43317
43333
|
const items = toChildArray(children).map((child, index) => {
|
|
43318
43334
|
const {
|
|
43319
43335
|
value: itemValue,
|
|
@@ -43797,7 +43813,7 @@ installImportMetaCssBuild(import.meta);/**
|
|
|
43797
43813
|
* into the size; a box-shadow draws the identical line and stays out of
|
|
43798
43814
|
* layout.
|
|
43799
43815
|
*/
|
|
43800
|
-
const css$
|
|
43816
|
+
const css$M = /* css */`
|
|
43801
43817
|
@layer navi {
|
|
43802
43818
|
:root {
|
|
43803
43819
|
--navi-fixed-bar-width: 56px;
|
|
@@ -43933,7 +43949,7 @@ const FixedBar = ({
|
|
|
43933
43949
|
border = true,
|
|
43934
43950
|
...props
|
|
43935
43951
|
}) => {
|
|
43936
|
-
import.meta.css = [css$
|
|
43952
|
+
import.meta.css = [css$M, "@jsenv/navi/src/layout/fixed_bar/fixed_bar.jsx"];
|
|
43937
43953
|
const defaultRef = useRef();
|
|
43938
43954
|
props.ref = props.ref || defaultRef;
|
|
43939
43955
|
// Whichever of width/height crosses the edge the bar sits on is what the
|
|
@@ -44021,7 +44037,7 @@ const FixedBar = ({
|
|
|
44021
44037
|
// Subpixel layout rounds rectangles up on boxes that fit exactly.
|
|
44022
44038
|
const OVERFLOW_TOLERANCE = 1;
|
|
44023
44039
|
|
|
44024
|
-
const css$
|
|
44040
|
+
const css$L = /* css */ `
|
|
44025
44041
|
[data-navi-overflow-x] {
|
|
44026
44042
|
outline: 2px dashed #e74c3c;
|
|
44027
44043
|
outline-offset: -2px;
|
|
@@ -44045,7 +44061,7 @@ const detectHorizontalOverflow = ({
|
|
|
44045
44061
|
let styleEl = null;
|
|
44046
44062
|
if (highlight) {
|
|
44047
44063
|
styleEl = document.createElement("style");
|
|
44048
|
-
styleEl.textContent = css$
|
|
44064
|
+
styleEl.textContent = css$L;
|
|
44049
44065
|
document.head.appendChild(styleEl);
|
|
44050
44066
|
}
|
|
44051
44067
|
|
|
@@ -44201,7 +44217,7 @@ const useFocusGroup = (
|
|
|
44201
44217
|
|
|
44202
44218
|
installImportMetaCssBuild(import.meta);const rightArrowPath = "M680-480L360-160l-80-80 240-240-240-240 80-80 320 320z";
|
|
44203
44219
|
const downArrowPath = "M480-280L160-600l80-80 240 240 240-240 80 80-320 320z";
|
|
44204
|
-
const css$
|
|
44220
|
+
const css$K = /* css */`
|
|
44205
44221
|
.navi_summary_marker {
|
|
44206
44222
|
width: 1em;
|
|
44207
44223
|
height: 1em;
|
|
@@ -44286,7 +44302,7 @@ const SummaryMarker = ({
|
|
|
44286
44302
|
open,
|
|
44287
44303
|
loading
|
|
44288
44304
|
}) => {
|
|
44289
|
-
import.meta.css = [css$
|
|
44305
|
+
import.meta.css = [css$K, "@jsenv/navi/src/control/details/summary_marker.jsx"];
|
|
44290
44306
|
const showLoading = useDebounceTrue(loading, 300);
|
|
44291
44307
|
const mountedRef = useRef(false);
|
|
44292
44308
|
const prevOpenRef = useRef(open);
|
|
@@ -44340,7 +44356,7 @@ const SummaryMarker = ({
|
|
|
44340
44356
|
});
|
|
44341
44357
|
};
|
|
44342
44358
|
|
|
44343
|
-
installImportMetaCssBuild(import.meta);const css$
|
|
44359
|
+
installImportMetaCssBuild(import.meta);const css$J = /* css */`
|
|
44344
44360
|
.navi_details {
|
|
44345
44361
|
position: relative;
|
|
44346
44362
|
z-index: 1;
|
|
@@ -44386,7 +44402,7 @@ const Details = props => {
|
|
|
44386
44402
|
return details;
|
|
44387
44403
|
};
|
|
44388
44404
|
const DetailsField = props => {
|
|
44389
|
-
import.meta.css = [css$
|
|
44405
|
+
import.meta.css = [css$J, "@jsenv/navi/src/control/details/details.jsx"];
|
|
44390
44406
|
const {
|
|
44391
44407
|
ref,
|
|
44392
44408
|
persists,
|
|
@@ -44642,7 +44658,7 @@ const ControlGroup = props => {
|
|
|
44642
44658
|
};
|
|
44643
44659
|
const CONTROL_GROUP_PSEUDO_CLASSES = [":hover", ":focus", ":focus-visible", ":read-only", ":disabled", ":-navi-loading"];
|
|
44644
44660
|
|
|
44645
|
-
installImportMetaCssBuild(import.meta);const css$
|
|
44661
|
+
installImportMetaCssBuild(import.meta);const css$I = /* css */`
|
|
44646
44662
|
@layer navi {
|
|
44647
44663
|
.navi_checkbox {
|
|
44648
44664
|
--switch-margin: 0; /* Useful to reserve space for outline */
|
|
@@ -44720,7 +44736,7 @@ installImportMetaCssBuild(import.meta);const css$H = /* css */`
|
|
|
44720
44736
|
}
|
|
44721
44737
|
`;
|
|
44722
44738
|
const SwitchUI = () => {
|
|
44723
|
-
import.meta.css = [css$
|
|
44739
|
+
import.meta.css = [css$I, "@jsenv/navi/src/control/input/switch_ui.jsx"];
|
|
44724
44740
|
return jsx(Box, {
|
|
44725
44741
|
className: "navi_switch",
|
|
44726
44742
|
as: "svg",
|
|
@@ -44762,7 +44778,7 @@ const useCheckableProps = (props, options) => {
|
|
|
44762
44778
|
return result;
|
|
44763
44779
|
};
|
|
44764
44780
|
|
|
44765
|
-
installImportMetaCssBuild(import.meta);const css$
|
|
44781
|
+
installImportMetaCssBuild(import.meta);const css$H = /* css */`
|
|
44766
44782
|
@layer navi {
|
|
44767
44783
|
.navi_checkbox {
|
|
44768
44784
|
--border-radius: var(--navi-checkbox-border-radius);
|
|
@@ -45089,7 +45105,7 @@ const InputCheckboxHeadless = props => {
|
|
|
45089
45105
|
});
|
|
45090
45106
|
};
|
|
45091
45107
|
const InputCheckboxFieldInterface = props => {
|
|
45092
|
-
import.meta.css = [css$
|
|
45108
|
+
import.meta.css = [css$H, "@jsenv/navi/src/control/input/input_checkbox.jsx"];
|
|
45093
45109
|
const [checkboxRootProps, checkboxHostProps] = useCheckableProps(props);
|
|
45094
45110
|
const {
|
|
45095
45111
|
icon,
|
|
@@ -45211,7 +45227,7 @@ const CheckboxButtonStyleCSSVars = {
|
|
|
45211
45227
|
const CheckboxPseudoClasses = [":hover", ":active", ":focus", ":focus-visible", ":read-only", ":disabled", ":checked", ":-navi-loading"];
|
|
45212
45228
|
const CheckboxPseudoElements = ["::-navi-loader", "::-navi-checkmark"];
|
|
45213
45229
|
|
|
45214
|
-
installImportMetaCssBuild(import.meta);const css$
|
|
45230
|
+
installImportMetaCssBuild(import.meta);const css$G = /* css */`
|
|
45215
45231
|
@layer navi {
|
|
45216
45232
|
.navi_label {
|
|
45217
45233
|
--label-required-indicator-color: var(--navi-color-danger, #b42318);
|
|
@@ -45291,7 +45307,7 @@ installImportMetaCssBuild(import.meta);const css$F = /* css */`
|
|
|
45291
45307
|
* </Field>
|
|
45292
45308
|
*/
|
|
45293
45309
|
const Field = props => {
|
|
45294
|
-
import.meta.css = [css$
|
|
45310
|
+
import.meta.css = [css$G, "@jsenv/navi/src/control/field.jsx"];
|
|
45295
45311
|
const refDefault = useRef();
|
|
45296
45312
|
props.ref = props.ref || refDefault;
|
|
45297
45313
|
const {
|
|
@@ -45326,7 +45342,7 @@ const FieldCSSVars = {
|
|
|
45326
45342
|
spacingWithControl: "--spacing-with-control"
|
|
45327
45343
|
};
|
|
45328
45344
|
const FieldAsContainer = props => {
|
|
45329
|
-
import.meta.css = [css$
|
|
45345
|
+
import.meta.css = [css$G, "@jsenv/navi/src/control/field.jsx"];
|
|
45330
45346
|
const {
|
|
45331
45347
|
children
|
|
45332
45348
|
} = props;
|
|
@@ -45358,7 +45374,7 @@ const FieldAsContainer = props => {
|
|
|
45358
45374
|
};
|
|
45359
45375
|
const FIELD_PSEUDO_CLASSES = [":hover", ":active", ":focus", ":focus-visible", ":read-only", ":disabled", ":-navi-loading"];
|
|
45360
45376
|
const Label = props => {
|
|
45361
|
-
import.meta.css = [css$
|
|
45377
|
+
import.meta.css = [css$G, "@jsenv/navi/src/control/field.jsx"];
|
|
45362
45378
|
const {
|
|
45363
45379
|
children,
|
|
45364
45380
|
// Marks the label when its control is required. Takes what to show, or
|
|
@@ -45520,7 +45536,7 @@ const InputSlot = ({
|
|
|
45520
45536
|
});
|
|
45521
45537
|
};
|
|
45522
45538
|
|
|
45523
|
-
installImportMetaCssBuild(import.meta);const css$
|
|
45539
|
+
installImportMetaCssBuild(import.meta);const css$F = /* css */`
|
|
45524
45540
|
@layer navi {
|
|
45525
45541
|
.navi_radio {
|
|
45526
45542
|
--margin: 3px 3px 3px 5px;
|
|
@@ -45883,7 +45899,7 @@ const InputRadioHeadless = props => {
|
|
|
45883
45899
|
};
|
|
45884
45900
|
const VARIANT_SET = new Set(["icon", "button", "radio"]);
|
|
45885
45901
|
const InputRadioFieldInterface = props => {
|
|
45886
|
-
import.meta.css = [css$
|
|
45902
|
+
import.meta.css = [css$F, "@jsenv/navi/src/control/input/input_radio.jsx"];
|
|
45887
45903
|
const [radioRootProps, radioHostProps] = useCheckableProps(props);
|
|
45888
45904
|
const {
|
|
45889
45905
|
icon,
|
|
@@ -46029,7 +46045,7 @@ const RadioButtonStyleCSSVars = {
|
|
|
46029
46045
|
const RadioPseudoClasses = [":hover", ":active", ":focus", ":focus-visible", ":read-only", ":disabled", ":checked", ":-navi-loading"];
|
|
46030
46046
|
const RadioPseudoElements = ["::-navi-loader", "::-navi-radiomark"];
|
|
46031
46047
|
|
|
46032
|
-
installImportMetaCssBuild(import.meta);const css$
|
|
46048
|
+
installImportMetaCssBuild(import.meta);const css$E = /* css */`
|
|
46033
46049
|
@layer navi {
|
|
46034
46050
|
.navi_input_range {
|
|
46035
46051
|
--border-radius: 6px;
|
|
@@ -46284,7 +46300,7 @@ const InputRange = props => {
|
|
|
46284
46300
|
});
|
|
46285
46301
|
};
|
|
46286
46302
|
const InputRangeFieldInterface = props => {
|
|
46287
|
-
import.meta.css = [css$
|
|
46303
|
+
import.meta.css = [css$E, "@jsenv/navi/src/control/input/input_range.jsx"];
|
|
46288
46304
|
const {
|
|
46289
46305
|
ref
|
|
46290
46306
|
} = props;
|
|
@@ -46411,24 +46427,68 @@ const InputModeResolver = props => {
|
|
|
46411
46427
|
};
|
|
46412
46428
|
const InputModeNumericOrDecimal = props => {
|
|
46413
46429
|
const Next = useNextResolver();
|
|
46430
|
+
// Where a finger landed, to tell a tap that placed the caret from a drag that
|
|
46431
|
+
// selected a part of the number (see onPointerUp below).
|
|
46432
|
+
const pointerDownRef = useRef(null);
|
|
46414
46433
|
return jsx(Next, {
|
|
46415
46434
|
...props,
|
|
46435
|
+
// A field with no room for one more digit is a field one can only
|
|
46436
|
+
// REPLACE: typing into it does nothing at all, so taking the caret
|
|
46437
|
+
// selects what is there and the first digit typed starts a new number.
|
|
46438
|
+
// The same handover navi_input_full does once a field fills up, asked at
|
|
46439
|
+
// the other end — when the field is entered rather than when it is
|
|
46440
|
+
// filled.
|
|
46441
|
+
onFocus: e => {
|
|
46442
|
+
props.onFocus?.(e);
|
|
46443
|
+
if (e.defaultPrevented) {
|
|
46444
|
+
return;
|
|
46445
|
+
}
|
|
46446
|
+
selectIfFull(e.currentTarget);
|
|
46447
|
+
},
|
|
46448
|
+
onPointerDown: e => {
|
|
46449
|
+
props.onPointerDown?.(e);
|
|
46450
|
+
pointerDownRef.current = {
|
|
46451
|
+
x: e.clientX,
|
|
46452
|
+
y: e.clientY
|
|
46453
|
+
};
|
|
46454
|
+
}
|
|
46455
|
+
// Once more on release, for a finger: a phone places the caret where it
|
|
46456
|
+
// was tapped AFTER the focus above, which undoes the selection made
|
|
46457
|
+
// there — and a field one cannot type into is then back to being a field
|
|
46458
|
+
// one cannot type into. Not for a mouse, which is how one selects a
|
|
46459
|
+
// single digit by dragging across it; and not for a finger that
|
|
46460
|
+
// travelled, which was scrolling the page rather than aiming at the
|
|
46461
|
+
// number.
|
|
46462
|
+
,
|
|
46463
|
+
onPointerUp: e => {
|
|
46464
|
+
props.onPointerUp?.(e);
|
|
46465
|
+
if (e.defaultPrevented) {
|
|
46466
|
+
return;
|
|
46467
|
+
}
|
|
46468
|
+
if (e.pointerType !== "touch") {
|
|
46469
|
+
return;
|
|
46470
|
+
}
|
|
46471
|
+
const pointerDown = pointerDownRef.current;
|
|
46472
|
+
if (pointerDown) {
|
|
46473
|
+
const dx = e.clientX - pointerDown.x;
|
|
46474
|
+
const dy = e.clientY - pointerDown.y;
|
|
46475
|
+
if (dx * dx + dy * dy > TAP_SLOP * TAP_SLOP) {
|
|
46476
|
+
return;
|
|
46477
|
+
}
|
|
46478
|
+
}
|
|
46479
|
+
selectIfFull(e.currentTarget);
|
|
46480
|
+
},
|
|
46416
46481
|
onInput: e => {
|
|
46417
46482
|
props.onInput?.(e);
|
|
46418
46483
|
if (e.defaultPrevented) {
|
|
46419
46484
|
return;
|
|
46420
46485
|
}
|
|
46421
46486
|
const input = e.currentTarget;
|
|
46422
|
-
let maxLength = input.maxLength;
|
|
46423
|
-
if (maxLength === -1) {
|
|
46424
|
-
const naviMaxLengthAttr = input.getAttribute("navi-max-length");
|
|
46425
|
-
maxLength = naviMaxLengthAttr === null ? undefined : Number(naviMaxLengthAttr);
|
|
46426
|
-
}
|
|
46427
46487
|
const caretAtEnd = input.selectionStart === input.value.length;
|
|
46428
46488
|
if (!caretAtEnd) {
|
|
46429
46489
|
return;
|
|
46430
46490
|
}
|
|
46431
|
-
if (!isFull(input,
|
|
46491
|
+
if (!isFull(input, readMaxLength(input))) {
|
|
46432
46492
|
return;
|
|
46433
46493
|
}
|
|
46434
46494
|
// Field is full and caret is at the end: notify listeners then
|
|
@@ -46458,6 +46518,37 @@ const InputModeNumericOrDecimal = props => {
|
|
|
46458
46518
|
});
|
|
46459
46519
|
};
|
|
46460
46520
|
|
|
46521
|
+
// How far a finger may travel and still be aiming at what it landed on, in
|
|
46522
|
+
// pixels: past that it was scrolling the page.
|
|
46523
|
+
const TAP_SLOP = 10;
|
|
46524
|
+
|
|
46525
|
+
// Everything already in the field, selected — but only when nothing more can be
|
|
46526
|
+
// typed after it, which is when replacing is the only edit left. A field one is
|
|
46527
|
+
// merely half-way through filling keeps its caret where it was put.
|
|
46528
|
+
const selectIfFull = input => {
|
|
46529
|
+
if (input.readOnly || input.disabled) {
|
|
46530
|
+
return;
|
|
46531
|
+
}
|
|
46532
|
+
if (!isFull(input, readMaxLength(input))) {
|
|
46533
|
+
return;
|
|
46534
|
+
}
|
|
46535
|
+
if (input.selectionStart === 0 && input.selectionEnd === input.value.length) {
|
|
46536
|
+
return;
|
|
46537
|
+
}
|
|
46538
|
+
input.select();
|
|
46539
|
+
};
|
|
46540
|
+
|
|
46541
|
+
// What the field accepts at most: our own attribute first, since the native
|
|
46542
|
+
// maxLength is deliberately left unset (see RealInput in input_textual.jsx).
|
|
46543
|
+
const readMaxLength = input => {
|
|
46544
|
+
const maxLength = input.maxLength;
|
|
46545
|
+
if (maxLength !== -1) {
|
|
46546
|
+
return maxLength;
|
|
46547
|
+
}
|
|
46548
|
+
const naviMaxLengthAttr = input.getAttribute("navi-max-length");
|
|
46549
|
+
return naviMaxLengthAttr === null ? undefined : Number(naviMaxLengthAttr);
|
|
46550
|
+
};
|
|
46551
|
+
|
|
46461
46552
|
// A field is full when there is no room for another digit — and room is not
|
|
46462
46553
|
// only a number of characters: an hour of two digits at most is also full at
|
|
46463
46554
|
// "7", because 7 followed by anything is past the 23 it accepts. Both are the
|
|
@@ -48249,7 +48340,7 @@ installImportMetaCssBuild(import.meta);/**
|
|
|
48249
48340
|
* This means an editable thing MUST have a parent with position relative that wraps the content and the eventual editable input
|
|
48250
48341
|
*
|
|
48251
48342
|
*/
|
|
48252
|
-
const css$
|
|
48343
|
+
const css$D = /* css */`
|
|
48253
48344
|
.navi_editable_wrapper {
|
|
48254
48345
|
--inset-top: 0px;
|
|
48255
48346
|
--inset-right: 0px;
|
|
@@ -48298,7 +48389,7 @@ const useEditionController = () => {
|
|
|
48298
48389
|
};
|
|
48299
48390
|
};
|
|
48300
48391
|
const Editable = props => {
|
|
48301
|
-
import.meta.css = [css$
|
|
48392
|
+
import.meta.css = [css$D, "@jsenv/navi/src/control/edition/editable.jsx"];
|
|
48302
48393
|
let {
|
|
48303
48394
|
children,
|
|
48304
48395
|
action,
|
|
@@ -48847,7 +48938,7 @@ installImportMetaCssBuild(import.meta);/**
|
|
|
48847
48938
|
* meet are drawn once instead of twice, and only the outer corners stay
|
|
48848
48939
|
* rounded. See docs/control_group.md.
|
|
48849
48940
|
*/
|
|
48850
|
-
const css$
|
|
48941
|
+
const css$C = /* css */`
|
|
48851
48942
|
.navi_group {
|
|
48852
48943
|
--group-border-width: var(--navi-control-border-width);
|
|
48853
48944
|
|
|
@@ -48963,7 +49054,7 @@ const Group = ({
|
|
|
48963
49054
|
vertical = row,
|
|
48964
49055
|
...props
|
|
48965
49056
|
}) => {
|
|
48966
|
-
import.meta.css = [css$
|
|
49057
|
+
import.meta.css = [css$C, "@jsenv/navi/src/control/group.jsx"];
|
|
48967
49058
|
return jsx(Box, {
|
|
48968
49059
|
baseClassName: "navi_group",
|
|
48969
49060
|
"data-vertical": vertical ? "" : undefined
|
|
@@ -49129,7 +49220,7 @@ installImportMetaCssBuild(import.meta);/**
|
|
|
49129
49220
|
* So: nothing scrollable between the cap and the slides (a shared [data-body]
|
|
49130
49221
|
* around them IS a scroller, see box.jsx), and `overflow="auto"` on each Slide.
|
|
49131
49222
|
*/
|
|
49132
|
-
const css$
|
|
49223
|
+
const css$B = /* css */`
|
|
49133
49224
|
/* Where the picture stands relative to the slide that is current, in boxes
|
|
49134
49225
|
(see paintTravelProgress). Declared, so that it is a NUMBER the browser can
|
|
49135
49226
|
interpolate: the trait an indicator draws has to travel with the slides,
|
|
@@ -49613,7 +49704,7 @@ const SlideContainer = ({
|
|
|
49613
49704
|
children,
|
|
49614
49705
|
...rest
|
|
49615
49706
|
}) => {
|
|
49616
|
-
import.meta.css = [css$
|
|
49707
|
+
import.meta.css = [css$B, "@jsenv/navi/src/layout/slide_container.jsx"];
|
|
49617
49708
|
const debugFocus = useDebugFocus();
|
|
49618
49709
|
const trackRef = useRef();
|
|
49619
49710
|
// The box itself: it is what takes the keyboard when what is on screen holds
|
|
@@ -52434,7 +52525,7 @@ installImportMetaCssBuild(import.meta);/**
|
|
|
52434
52525
|
* pass through untouched via `...rest` to whichever of Popover/Dialog
|
|
52435
52526
|
* actually renders.
|
|
52436
52527
|
*/
|
|
52437
|
-
const css$
|
|
52528
|
+
const css$A = /* css */`
|
|
52438
52529
|
@layer navi {
|
|
52439
52530
|
.navi_popup {
|
|
52440
52531
|
--popup-border-radius: var(--navi-popup-border-radius);
|
|
@@ -52547,7 +52638,7 @@ const css$z = /* css */`
|
|
|
52547
52638
|
* @param {import("ignore:preact").ComponentChildren} props.children
|
|
52548
52639
|
*/
|
|
52549
52640
|
const Popup = props => {
|
|
52550
|
-
import.meta.css = [css$
|
|
52641
|
+
import.meta.css = [css$A, "@jsenv/navi/src/layout/popup.jsx"];
|
|
52551
52642
|
const {
|
|
52552
52643
|
mode: modeProp,
|
|
52553
52644
|
maxWidth,
|
|
@@ -52610,7 +52701,7 @@ const Popup = props => {
|
|
|
52610
52701
|
});
|
|
52611
52702
|
};
|
|
52612
52703
|
|
|
52613
|
-
installImportMetaCssBuild(import.meta);const css$
|
|
52704
|
+
installImportMetaCssBuild(import.meta);const css$z = /* css */`
|
|
52614
52705
|
.navi_picker {
|
|
52615
52706
|
/* Sizing ceilings (maxmax), background, box-shadow, outline, padding,
|
|
52616
52707
|
overflow... are already handled correctly by Popup/Popover/Dialog
|
|
@@ -52728,7 +52819,7 @@ installImportMetaCssBuild(import.meta);const css$y = /* css */`
|
|
|
52728
52819
|
}
|
|
52729
52820
|
`;
|
|
52730
52821
|
const PickerCustomResolver = props => {
|
|
52731
|
-
import.meta.css = [css$
|
|
52822
|
+
import.meta.css = [css$z, "@jsenv/navi/src/control/picker/picker_custom.jsx"];
|
|
52732
52823
|
if (props.children === undefined) {
|
|
52733
52824
|
return jsx(PickerNative, {
|
|
52734
52825
|
...props
|
|
@@ -52840,6 +52931,9 @@ const PickerCustom = props => {
|
|
|
52840
52931
|
delete pickerProps.open;
|
|
52841
52932
|
delete pickerProps.defaultOpen;
|
|
52842
52933
|
delete pickerProps.escapeEffect;
|
|
52934
|
+
// Read below for the popup alone; on the trigger it would land on the DOM as
|
|
52935
|
+
// an unknown attribute holding a ref object.
|
|
52936
|
+
delete pickerProps.anchor;
|
|
52843
52937
|
const popupProps = {};
|
|
52844
52938
|
Object.assign(pickerProps, {
|
|
52845
52939
|
popupProps,
|
|
@@ -53015,7 +53109,10 @@ const PickerCustom = props => {
|
|
|
53015
53109
|
children
|
|
53016
53110
|
});
|
|
53017
53111
|
Object.assign(popupProps, {
|
|
53018
|
-
|
|
53112
|
+
// The trigger, unless the caller names something else: a picker whose
|
|
53113
|
+
// trigger is a piece of a bigger control (the chevron half of a split
|
|
53114
|
+
// button) hangs its popup off the whole control instead.
|
|
53115
|
+
anchor: props.anchor || props.ref,
|
|
53019
53116
|
openController,
|
|
53020
53117
|
// A picker whose value was never given to it reads it off the control in
|
|
53021
53118
|
// its popup (see useUIFacadeStateController): the trigger shows what the
|
|
@@ -53502,7 +53599,7 @@ const LoadingIndicator = ({
|
|
|
53502
53599
|
});
|
|
53503
53600
|
};
|
|
53504
53601
|
|
|
53505
|
-
installImportMetaCssBuild(import.meta);const css$
|
|
53602
|
+
installImportMetaCssBuild(import.meta);const css$y = /* css */`
|
|
53506
53603
|
@layer navi {
|
|
53507
53604
|
.navi_separator {
|
|
53508
53605
|
--size: 1px;
|
|
@@ -53580,7 +53677,7 @@ const Separator = ({
|
|
|
53580
53677
|
style,
|
|
53581
53678
|
...props
|
|
53582
53679
|
}) => {
|
|
53583
|
-
import.meta.css = [css$
|
|
53680
|
+
import.meta.css = [css$y, "@jsenv/navi/src/layout/separator.jsx"];
|
|
53584
53681
|
return jsx(Box, {
|
|
53585
53682
|
as: vertical ? "span" : "hr",
|
|
53586
53683
|
...props,
|
|
@@ -54073,7 +54170,7 @@ const ListItemFooter = props => {
|
|
|
54073
54170
|
});
|
|
54074
54171
|
};
|
|
54075
54172
|
|
|
54076
|
-
installImportMetaCssBuild(import.meta);const css$
|
|
54173
|
+
installImportMetaCssBuild(import.meta);const css$x = /* css */`
|
|
54077
54174
|
@layer navi {
|
|
54078
54175
|
.navi_list_container[navi-selectable] {
|
|
54079
54176
|
/* Focus outline */
|
|
@@ -54285,7 +54382,7 @@ const ListSelectableResolver = props => {
|
|
|
54285
54382
|
};
|
|
54286
54383
|
const ListSelectable = props => {
|
|
54287
54384
|
const Next = useNextResolver();
|
|
54288
|
-
import.meta.css = [css$
|
|
54385
|
+
import.meta.css = [css$x, "@jsenv/navi/src/control/list/list_selectable.jsx"];
|
|
54289
54386
|
// we allow ourselves to auto-generate a name
|
|
54290
54387
|
const defaultName = useId();
|
|
54291
54388
|
props.name = props.name || `listbox_${defaultName}`;
|
|
@@ -54905,7 +55002,7 @@ const ListVirtualContext = createContext(null);
|
|
|
54905
55002
|
// that returning a component of one's own — instead of a bare <List.Item> —
|
|
54906
55003
|
// works the same way.
|
|
54907
55004
|
const ListRowContext = createContext(null);
|
|
54908
|
-
const css$
|
|
55005
|
+
const css$w = /* css */`
|
|
54909
55006
|
@layer navi {
|
|
54910
55007
|
.navi_list_container {
|
|
54911
55008
|
--list-outline-width: 1px;
|
|
@@ -55546,7 +55643,7 @@ const css$v = /* css */`
|
|
|
55546
55643
|
}
|
|
55547
55644
|
`;
|
|
55548
55645
|
const ListUI = props => {
|
|
55549
|
-
import.meta.css = [css$
|
|
55646
|
+
import.meta.css = [css$w, "@jsenv/navi/src/control/list/list.jsx"];
|
|
55550
55647
|
const {
|
|
55551
55648
|
ref,
|
|
55552
55649
|
renderBudget: renderBudgetProp = RENDER_BUDGET_DEFAULT,
|
|
@@ -59042,7 +59139,7 @@ const PickerPresetResolver = props => {
|
|
|
59042
59139
|
});
|
|
59043
59140
|
};
|
|
59044
59141
|
|
|
59045
|
-
installImportMetaCssBuild(import.meta);const css$
|
|
59142
|
+
installImportMetaCssBuild(import.meta);const css$v = /* css */`
|
|
59046
59143
|
@layer navi {
|
|
59047
59144
|
}
|
|
59048
59145
|
.navi_badge {
|
|
@@ -59154,7 +59251,7 @@ const Badge = ({
|
|
|
59154
59251
|
className,
|
|
59155
59252
|
...props
|
|
59156
59253
|
}) => {
|
|
59157
|
-
import.meta.css = [css$
|
|
59254
|
+
import.meta.css = [css$v, "@jsenv/navi/src/text/badge.jsx"];
|
|
59158
59255
|
const defaultRef = useRef();
|
|
59159
59256
|
props.ref = props.ref || defaultRef;
|
|
59160
59257
|
const {
|
|
@@ -59206,7 +59303,7 @@ const BadgeButton = props => {
|
|
|
59206
59303
|
};
|
|
59207
59304
|
Badge.Button = BadgeButton;
|
|
59208
59305
|
|
|
59209
|
-
installImportMetaCssBuild(import.meta);const css$
|
|
59306
|
+
installImportMetaCssBuild(import.meta);const css$u = /* css */`
|
|
59210
59307
|
@layer navi {
|
|
59211
59308
|
}
|
|
59212
59309
|
.navi_badge_list {
|
|
@@ -59231,7 +59328,7 @@ const BadgeList = ({
|
|
|
59231
59328
|
max,
|
|
59232
59329
|
...props
|
|
59233
59330
|
}) => {
|
|
59234
|
-
import.meta.css = [css$
|
|
59331
|
+
import.meta.css = [css$u, "@jsenv/navi/src/text/badge_list.jsx"];
|
|
59235
59332
|
const measureRef = useRef();
|
|
59236
59333
|
const visibleRef = useRef();
|
|
59237
59334
|
useLayoutEffect(() => {
|
|
@@ -59306,7 +59403,7 @@ const BadgeList = ({
|
|
|
59306
59403
|
});
|
|
59307
59404
|
};
|
|
59308
59405
|
|
|
59309
|
-
installImportMetaCssBuild(import.meta);const css$
|
|
59406
|
+
installImportMetaCssBuild(import.meta);const css$t = /* css */`
|
|
59310
59407
|
.navi_color {
|
|
59311
59408
|
display: block;
|
|
59312
59409
|
aspect-ratio: 1/1;
|
|
@@ -59337,7 +59434,7 @@ const Color = ({
|
|
|
59337
59434
|
children,
|
|
59338
59435
|
...rest
|
|
59339
59436
|
}) => {
|
|
59340
|
-
import.meta.css = [css$
|
|
59437
|
+
import.meta.css = [css$t, "@jsenv/navi/src/text/color.jsx"];
|
|
59341
59438
|
const color = children || undefined;
|
|
59342
59439
|
return jsx(Box, {
|
|
59343
59440
|
as: "span",
|
|
@@ -59792,7 +59889,7 @@ const PickerFileUI = () => {
|
|
|
59792
59889
|
return String(value);
|
|
59793
59890
|
};
|
|
59794
59891
|
|
|
59795
|
-
installImportMetaCssBuild(import.meta);const css$
|
|
59892
|
+
installImportMetaCssBuild(import.meta);const css$s = /* css */`
|
|
59796
59893
|
@layer navi {
|
|
59797
59894
|
.navi_picker {
|
|
59798
59895
|
--picker-border-radius: var(--navi-control-border-radius);
|
|
@@ -60181,7 +60278,7 @@ installImportMetaCssBuild(import.meta);const css$r = /* css */`
|
|
|
60181
60278
|
}
|
|
60182
60279
|
`;
|
|
60183
60280
|
const PickerButton = props => {
|
|
60184
|
-
import.meta.css = [css$
|
|
60281
|
+
import.meta.css = [css$s, "@jsenv/navi/src/control/picker/picker.jsx"];
|
|
60185
60282
|
if (typeof props.maxLines === "string") {
|
|
60186
60283
|
props.maxLines = parseInt(props.maxLines);
|
|
60187
60284
|
}
|
|
@@ -60592,7 +60689,7 @@ installImportMetaCssBuild(import.meta);/**
|
|
|
60592
60689
|
* refuse it on purpose, which is what keeps the focus where the travel happens
|
|
60593
60690
|
* instead of moving it into a slide that is about to leave.
|
|
60594
60691
|
*/
|
|
60595
|
-
const css$
|
|
60692
|
+
const css$r = /* css */`
|
|
60596
60693
|
@layer navi {
|
|
60597
60694
|
.navi_picker_spin {
|
|
60598
60695
|
/* A picker one steps through is still a picker: what themes every picker
|
|
@@ -60803,6 +60900,12 @@ const css$q = /* css */`
|
|
|
60803
60900
|
a radius there would show as a notch in the pressed background. */
|
|
60804
60901
|
border-radius: 0;
|
|
60805
60902
|
cursor: pointer;
|
|
60903
|
+
/* Pressed with a finger as readily as with a mouse: no double-tap zoom to
|
|
60904
|
+
wait for between two presses, and no word of the value getting selected
|
|
60905
|
+
under the finger of someone holding one down. */
|
|
60906
|
+
touch-action: manipulation;
|
|
60907
|
+
user-select: none;
|
|
60908
|
+
-webkit-user-select: none;
|
|
60806
60909
|
}
|
|
60807
60910
|
/* Said as data-hover rather than :hover: a touch browser synthesizes the
|
|
60808
60911
|
enter and never the leave, so a CSS :hover would stay grey under the last
|
|
@@ -61055,7 +61158,7 @@ const Spin = ({
|
|
|
61055
61158
|
nextLabel,
|
|
61056
61159
|
...rest
|
|
61057
61160
|
}) => {
|
|
61058
|
-
import.meta.css = [css$
|
|
61161
|
+
import.meta.css = [css$r, "@jsenv/navi/src/control/picker/picker_spin.jsx"];
|
|
61059
61162
|
const id = useId();
|
|
61060
61163
|
// What the group around it says, when there is one: how big the whole thing
|
|
61061
61164
|
// is written is said once, on the group, and every spin in it follows.
|
|
@@ -61414,55 +61517,11 @@ const WayOut = ({
|
|
|
61414
61517
|
onPress,
|
|
61415
61518
|
onPointerDown,
|
|
61416
61519
|
children
|
|
61417
|
-
}) =>
|
|
61418
|
-
|
|
61419
|
-
|
|
61420
|
-
|
|
61421
|
-
|
|
61422
|
-
// rounded by are keyed on (see the CSS above).
|
|
61423
|
-
,
|
|
61424
|
-
|
|
61425
|
-
"data-way-out": atStart ? "start" : "end"
|
|
61426
|
-
// Tracked rather than left to CSS :hover, which stays on after a tap on a
|
|
61427
|
-
// touch device (see the CSS above).
|
|
61428
|
-
,
|
|
61429
|
-
|
|
61430
|
-
pseudoClasses: WAY_OUT_PSEUDO_CLASSES
|
|
61431
|
-
// Announced as a button because that is what it is to whoever cannot see
|
|
61432
|
-
// the chevron — and marked unavailable rather than removed when there is
|
|
61433
|
-
// nothing that way, so it keeps its place.
|
|
61434
|
-
,
|
|
61435
|
-
|
|
61436
|
-
role: "button",
|
|
61437
|
-
"aria-label": label,
|
|
61438
|
-
"aria-disabled": unavailableMessage ? "true" : undefined,
|
|
61439
|
-
"data-unavailable": unavailableMessage ? "" : undefined
|
|
61440
|
-
// At the chevron, not beside it: a callout aims its arrow at where the
|
|
61441
|
-
// anchor's text starts, and there is no text here — only a glyph in the
|
|
61442
|
-
// middle of the box, which is what one pressed and what the answer is
|
|
61443
|
-
// about.
|
|
61444
|
-
,
|
|
61445
|
-
|
|
61446
|
-
"data-callout-arrow-x": "center"
|
|
61447
|
-
// Read by triggerNaviCommand below the same way it reads a button's own.
|
|
61448
|
-
,
|
|
61449
|
-
|
|
61450
|
-
commandfor: commandFor,
|
|
61451
|
-
flex: true,
|
|
61452
|
-
align: "center"
|
|
61453
|
-
// A press, answered where it starts: mousedown rather than click, which is
|
|
61454
|
-
// what makes holding one feel immediate — and the click after it is stopped
|
|
61455
|
-
// below, so a <Label> wrapping the whole control does not forward it to the
|
|
61456
|
-
// control and open the calendar on the way past.
|
|
61457
|
-
,
|
|
61458
|
-
|
|
61459
|
-
onClick: e => {
|
|
61460
|
-
e.preventDefault();
|
|
61461
|
-
},
|
|
61462
|
-
onPointerDown: onPointerDown,
|
|
61463
|
-
onMouseDown: e => {
|
|
61464
|
-
// No focus, no text selection: the keyboard is put on the middle below.
|
|
61465
|
-
e.preventDefault();
|
|
61520
|
+
}) => {
|
|
61521
|
+
// Where the finger landed, to tell a press from the start of a scroll (see
|
|
61522
|
+
// onPointerUp below).
|
|
61523
|
+
const pointerDownRef = useRef(null);
|
|
61524
|
+
const press = e => {
|
|
61466
61525
|
if (unavailableMessage) {
|
|
61467
61526
|
// Why it does nothing, said where one pressed: a control would have
|
|
61468
61527
|
// done this through its own interaction gate, and this one has none.
|
|
@@ -61474,11 +61533,108 @@ const WayOut = ({
|
|
|
61474
61533
|
return;
|
|
61475
61534
|
}
|
|
61476
61535
|
onPress(e);
|
|
61477
|
-
}
|
|
61478
|
-
|
|
61479
|
-
|
|
61480
|
-
|
|
61481
|
-
|
|
61536
|
+
};
|
|
61537
|
+
return jsx(Box, {
|
|
61538
|
+
as: "span",
|
|
61539
|
+
baseClassName: "navi_picker_spin_way_out"
|
|
61540
|
+
// Which end of the box it sits in, said by the chevron rather than read
|
|
61541
|
+
// from its place among its siblings: that is what the corners it is
|
|
61542
|
+
// rounded by are keyed on (see the CSS above).
|
|
61543
|
+
,
|
|
61544
|
+
|
|
61545
|
+
"data-way-out": atStart ? "start" : "end"
|
|
61546
|
+
// Tracked rather than left to CSS :hover, which stays on after a tap on a
|
|
61547
|
+
// touch device (see the CSS above).
|
|
61548
|
+
,
|
|
61549
|
+
|
|
61550
|
+
pseudoClasses: WAY_OUT_PSEUDO_CLASSES
|
|
61551
|
+
// Announced as a button because that is what it is to whoever cannot see
|
|
61552
|
+
// the chevron — and marked unavailable rather than removed when there is
|
|
61553
|
+
// nothing that way, so it keeps its place.
|
|
61554
|
+
,
|
|
61555
|
+
|
|
61556
|
+
role: "button",
|
|
61557
|
+
"aria-label": label,
|
|
61558
|
+
"aria-disabled": unavailableMessage ? "true" : undefined,
|
|
61559
|
+
"data-unavailable": unavailableMessage ? "" : undefined
|
|
61560
|
+
// At the chevron, not beside it: a callout aims its arrow at where the
|
|
61561
|
+
// anchor's text starts, and there is no text here — only a glyph in the
|
|
61562
|
+
// middle of the box, which is what one pressed and what the answer is
|
|
61563
|
+
// about.
|
|
61564
|
+
,
|
|
61565
|
+
|
|
61566
|
+
"data-callout-arrow-x": "center"
|
|
61567
|
+
// Read by triggerNaviCommand below the same way it reads a button's own.
|
|
61568
|
+
,
|
|
61569
|
+
|
|
61570
|
+
commandfor: commandFor,
|
|
61571
|
+
flex: true,
|
|
61572
|
+
align: "center"
|
|
61573
|
+
// The press is answered on the pointer events below, and the click that
|
|
61574
|
+
// follows them is stopped here: a <Label> wrapping the whole control
|
|
61575
|
+
// forwards a click to what it labels, which would open the calendar on
|
|
61576
|
+
// the way past.
|
|
61577
|
+
,
|
|
61578
|
+
|
|
61579
|
+
onClick: e => {
|
|
61580
|
+
e.preventDefault();
|
|
61581
|
+
},
|
|
61582
|
+
onPointerDown: e => {
|
|
61583
|
+
onPointerDown(e);
|
|
61584
|
+
pointerDownRef.current = {
|
|
61585
|
+
x: e.clientX,
|
|
61586
|
+
y: e.clientY
|
|
61587
|
+
};
|
|
61588
|
+
if (e.pointerType === "touch") {
|
|
61589
|
+
return;
|
|
61590
|
+
}
|
|
61591
|
+
// No focus, no text selection: the keyboard is put on the middle below.
|
|
61592
|
+
// preventDefault on the pointer event rather than on the mouse one it is
|
|
61593
|
+
// followed by, since the press is answered here.
|
|
61594
|
+
e.preventDefault();
|
|
61595
|
+
press(e);
|
|
61596
|
+
}
|
|
61597
|
+
// A finger is answered when it lifts, not when it lands: what starts on a
|
|
61598
|
+
// chevron may be a press or may be the beginning of a scroll, and only the
|
|
61599
|
+
// release tells the two apart. A mouse has no such doubt and is answered
|
|
61600
|
+
// above, as it goes down, which is what makes holding one feel immediate.
|
|
61601
|
+
,
|
|
61602
|
+
|
|
61603
|
+
onPointerUp: e => {
|
|
61604
|
+
if (e.pointerType !== "touch") {
|
|
61605
|
+
return;
|
|
61606
|
+
}
|
|
61607
|
+
const pointerDown = pointerDownRef.current;
|
|
61608
|
+
if (pointerDown) {
|
|
61609
|
+
const dx = e.clientX - pointerDown.x;
|
|
61610
|
+
const dy = e.clientY - pointerDown.y;
|
|
61611
|
+
if (dx * dx + dy * dy > WAY_OUT_TAP_SLOP * WAY_OUT_TAP_SLOP) {
|
|
61612
|
+
return;
|
|
61613
|
+
}
|
|
61614
|
+
}
|
|
61615
|
+
press(e);
|
|
61616
|
+
}
|
|
61617
|
+
// A chevron has nothing to copy, look up or share: the menu a long press
|
|
61618
|
+
// opens on a phone would only get in the way of someone stepping through
|
|
61619
|
+
// values, and the pressed state under it would stay on once it opened.
|
|
61620
|
+
,
|
|
61621
|
+
|
|
61622
|
+
onContextMenu: e => {
|
|
61623
|
+
if (e.pointerType !== "touch") {
|
|
61624
|
+
// right click is allowed
|
|
61625
|
+
return;
|
|
61626
|
+
}
|
|
61627
|
+
e.preventDefault();
|
|
61628
|
+
},
|
|
61629
|
+
children: jsx(Icon, {
|
|
61630
|
+
children: children
|
|
61631
|
+
})
|
|
61632
|
+
});
|
|
61633
|
+
};
|
|
61634
|
+
|
|
61635
|
+
// How far a finger may travel and still be pressing what it landed on, in
|
|
61636
|
+
// pixels: past that it was scrolling the page.
|
|
61637
|
+
const WAY_OUT_TAP_SLOP = 10;
|
|
61482
61638
|
const PICKER_SPIN_PSEUDO_CLASSES = [":hover", ":focus-visible"];
|
|
61483
61639
|
const WAY_OUT_PSEUDO_CLASSES = [":hover"];
|
|
61484
61640
|
|
|
@@ -61538,7 +61694,7 @@ const renderValueDefault = value => String(value ?? "");
|
|
|
61538
61694
|
* are passed on to the spins sitting in them.
|
|
61539
61695
|
*/
|
|
61540
61696
|
const SpinGroup = props => {
|
|
61541
|
-
import.meta.css = [css$
|
|
61697
|
+
import.meta.css = [css$r, "@jsenv/navi/src/control/picker/picker_spin.jsx"];
|
|
61542
61698
|
const {
|
|
61543
61699
|
size
|
|
61544
61700
|
} = props;
|
|
@@ -62069,7 +62225,7 @@ const TimeRangeSpin = ({
|
|
|
62069
62225
|
};
|
|
62070
62226
|
|
|
62071
62227
|
installImportMetaCssBuild(import.meta);// TOFIX: select in data then reset, it reset to red/blue instead of red/blue/green
|
|
62072
|
-
const css$
|
|
62228
|
+
const css$q = /* css */`
|
|
62073
62229
|
.navi_checkbox_group {
|
|
62074
62230
|
border-style: solid;
|
|
62075
62231
|
|
|
@@ -62110,7 +62266,7 @@ const CheckboxGroup = props => {
|
|
|
62110
62266
|
return checkboxGroup;
|
|
62111
62267
|
};
|
|
62112
62268
|
const CheckboxGroupInterface = props => {
|
|
62113
|
-
import.meta.css = [css$
|
|
62269
|
+
import.meta.css = [css$q, "@jsenv/navi/src/control/input/checkbox_group.jsx"];
|
|
62114
62270
|
const {
|
|
62115
62271
|
ref
|
|
62116
62272
|
} = props;
|
|
@@ -62159,7 +62315,7 @@ installImportMetaCssBuild(import.meta);/**
|
|
|
62159
62315
|
* shared sheet is registered here too — a page may render a Textarea without
|
|
62160
62316
|
* any Input.
|
|
62161
62317
|
*/
|
|
62162
|
-
const css$
|
|
62318
|
+
const css$p = /* css */`
|
|
62163
62319
|
.navi_input.navi_textarea {
|
|
62164
62320
|
.navi_control_input {
|
|
62165
62321
|
min-height: calc(var(--textarea-min-rows, 1.5) * 1lh);
|
|
@@ -62246,7 +62402,7 @@ const Textarea = ({
|
|
|
62246
62402
|
width = "35ch",
|
|
62247
62403
|
...props
|
|
62248
62404
|
}) => {
|
|
62249
|
-
import.meta.css = [inputCss + css$
|
|
62405
|
+
import.meta.css = [inputCss + css$p, "@jsenv/navi/src/control/input/textarea.jsx"];
|
|
62250
62406
|
const defaultRef = useRef(null);
|
|
62251
62407
|
props.ref = props.ref || defaultRef;
|
|
62252
62408
|
usePlaceholderHeight(props.ref, props.placeholder);
|
|
@@ -62320,7 +62476,7 @@ const TextareaCharCount = ({
|
|
|
62320
62476
|
maxLength,
|
|
62321
62477
|
...rest
|
|
62322
62478
|
}) => {
|
|
62323
|
-
import.meta.css = [css$
|
|
62479
|
+
import.meta.css = [css$p, "@jsenv/navi/src/control/input/textarea.jsx"];
|
|
62324
62480
|
const resolvedValue = signal ? signal.value : value;
|
|
62325
62481
|
const length = typeof resolvedValue === "string" ? resolvedValue.length : 0;
|
|
62326
62482
|
return jsx(Box, {
|
|
@@ -62505,7 +62661,7 @@ const formatIntlUnit = (unit, {
|
|
|
62505
62661
|
}
|
|
62506
62662
|
};
|
|
62507
62663
|
|
|
62508
|
-
installImportMetaCssBuild(import.meta);const css$
|
|
62664
|
+
installImportMetaCssBuild(import.meta);const css$o = /* css */`
|
|
62509
62665
|
.navi_input_duration {
|
|
62510
62666
|
--duration-separator-spacing: 4px;
|
|
62511
62667
|
--loader-color: var(--navi-loader-color);
|
|
@@ -62572,7 +62728,7 @@ installImportMetaCssBuild(import.meta);const css$n = /* css */`
|
|
|
62572
62728
|
* "auto" aligns each field toward its neighbouring separator (first→right, last→left, middle/solo→center).
|
|
62573
62729
|
*/
|
|
62574
62730
|
const InputDuration = props => {
|
|
62575
|
-
import.meta.css = [css$
|
|
62731
|
+
import.meta.css = [css$o, "@jsenv/navi/src/control/input/input_duration.jsx"];
|
|
62576
62732
|
const defaultRef = useRef();
|
|
62577
62733
|
props.ref = props.ref || defaultRef;
|
|
62578
62734
|
props.max = props.max || "23h59";
|
|
@@ -63074,7 +63230,7 @@ const InputDurationPart = ({
|
|
|
63074
63230
|
});
|
|
63075
63231
|
};
|
|
63076
63232
|
|
|
63077
|
-
installImportMetaCssBuild(import.meta);const css$
|
|
63233
|
+
installImportMetaCssBuild(import.meta);const css$n = /* css */`
|
|
63078
63234
|
.navi_radio_group {
|
|
63079
63235
|
border-style: solid;
|
|
63080
63236
|
|
|
@@ -63094,7 +63250,7 @@ const RadioGroup = props => {
|
|
|
63094
63250
|
return radioGroup;
|
|
63095
63251
|
};
|
|
63096
63252
|
const RadioGroupInterface = props => {
|
|
63097
|
-
import.meta.css = [css$
|
|
63253
|
+
import.meta.css = [css$n, "@jsenv/navi/src/control/input/radio_group.jsx"];
|
|
63098
63254
|
const {
|
|
63099
63255
|
ref
|
|
63100
63256
|
} = props;
|
|
@@ -63152,7 +63308,7 @@ installImportMetaCssBuild(import.meta);/**
|
|
|
63152
63308
|
* control is drawn — the list it opens stays the platform's own, which is the
|
|
63153
63309
|
* whole point of using a select.
|
|
63154
63310
|
*/
|
|
63155
|
-
const css$
|
|
63311
|
+
const css$m = /* css */`
|
|
63156
63312
|
.navi_input.navi_select {
|
|
63157
63313
|
.navi_control_input {
|
|
63158
63314
|
/* Room for the chevron, which sits over the padding rather than beside
|
|
@@ -63207,7 +63363,7 @@ const Select = ({
|
|
|
63207
63363
|
multiple,
|
|
63208
63364
|
...props
|
|
63209
63365
|
}) => {
|
|
63210
|
-
import.meta.css = [inputCss + css$
|
|
63366
|
+
import.meta.css = [inputCss + css$m, "@jsenv/navi/src/control/input/select.jsx"];
|
|
63211
63367
|
const defaultRef = useRef(null);
|
|
63212
63368
|
props.ref = props.ref || defaultRef;
|
|
63213
63369
|
seedDefaultValueFromSignal(props);
|
|
@@ -63256,6 +63412,344 @@ const Select = ({
|
|
|
63256
63412
|
});
|
|
63257
63413
|
};
|
|
63258
63414
|
|
|
63415
|
+
installImportMetaCssBuild(import.meta);/**
|
|
63416
|
+
* SplitButton — one action, several variants of it.
|
|
63417
|
+
*
|
|
63418
|
+
* The left half does the thing; the right half opens the list of the other
|
|
63419
|
+
* ways of doing it. What choosing means is the caller's call (`chooseEffect`):
|
|
63420
|
+
* the chosen way becomes what the button does, or it is done right away.
|
|
63421
|
+
*
|
|
63422
|
+
* Both halves are `<Button>`s, deliberately: the chevron half has to wear the
|
|
63423
|
+
* exact same paint as the label half for any `cta`/`variant`/`color` the
|
|
63424
|
+
* caller passes, and a `<Picker variant="icon">` next to a button paints from
|
|
63425
|
+
* its own set of custom properties — matching them would mean restating the
|
|
63426
|
+
* button's palette here and keeping the copy in step forever. So the popup
|
|
63427
|
+
* comes from a headless `<Picker>` sitting behind the chevron button, hung off
|
|
63428
|
+
* the whole split button (`anchor`) so the menu lines up with it.
|
|
63429
|
+
*
|
|
63430
|
+
* The busy state is worn by the control, not by the half that happens to be
|
|
63431
|
+
* running: one loading outline around both, which is why each half is told
|
|
63432
|
+
* `loadingOutline={false}`.
|
|
63433
|
+
*/
|
|
63434
|
+
const css$l = /* css */`
|
|
63435
|
+
/* Around the pair rather than in it: the outline is drawn against this
|
|
63436
|
+
element and follows its corners, and a Group counts its own children to
|
|
63437
|
+
know which corners to square — an outline among them would be one of the
|
|
63438
|
+
halves. Hence a box holding a group, rather than the group itself. */
|
|
63439
|
+
.navi_split_button {
|
|
63440
|
+
position: relative;
|
|
63441
|
+
display: inline-flex;
|
|
63442
|
+
border-radius: var(--navi-control-border-radius);
|
|
63443
|
+
|
|
63444
|
+
> .navi_group {
|
|
63445
|
+
flex: 1 1 auto;
|
|
63446
|
+
}
|
|
63447
|
+
}
|
|
63448
|
+
/* The chevron half is a button with a headless picker behind it: the picker
|
|
63449
|
+
box is inset: 0 of whatever is positioned above it, and that must be the
|
|
63450
|
+
chevron alone, not the whole split button. */
|
|
63451
|
+
.navi_split_button_menu {
|
|
63452
|
+
position: relative;
|
|
63453
|
+
display: flex;
|
|
63454
|
+
}
|
|
63455
|
+
`;
|
|
63456
|
+
|
|
63457
|
+
/**
|
|
63458
|
+
* @type {import("ignore:preact").FunctionComponent<{
|
|
63459
|
+
* options: Array<{value: any, label: import("ignore:preact").ComponentChildren, [key: string]: any}>,
|
|
63460
|
+
* value?: any,
|
|
63461
|
+
* defaultValue?: any,
|
|
63462
|
+
* label?: import("ignore:preact").ComponentChildren,
|
|
63463
|
+
* action?: (value: any, event: Event) => void | Promise<void>,
|
|
63464
|
+
* onValueChange?: (value: any, event: Event) => void,
|
|
63465
|
+
* chooseEffect?: "select" | "run",
|
|
63466
|
+
* menuLabel?: string,
|
|
63467
|
+
* menuIcon?: import("ignore:preact").ComponentChildren,
|
|
63468
|
+
* menuIconSize?: number | string,
|
|
63469
|
+
* loading?: boolean,
|
|
63470
|
+
* readOnly?: boolean,
|
|
63471
|
+
* disabled?: boolean,
|
|
63472
|
+
* cta?: boolean,
|
|
63473
|
+
* variant?: string,
|
|
63474
|
+
* color?: string,
|
|
63475
|
+
* backgroundColor?: string,
|
|
63476
|
+
* borderColor?: string,
|
|
63477
|
+
* borderWidth?: number | string,
|
|
63478
|
+
* borderRadius?: number | string,
|
|
63479
|
+
* pressEffect?: "none" | string,
|
|
63480
|
+
* mode?: "popover" | "dialog",
|
|
63481
|
+
* popoverMode?: "nearby" | "overlay",
|
|
63482
|
+
* positionArea?: string,
|
|
63483
|
+
* popupWidthFitContent?: boolean,
|
|
63484
|
+
* popoverMaxHeight?: number | string,
|
|
63485
|
+
* dialogMaxWidth?: number | string,
|
|
63486
|
+
* dialogMaxHeight?: number | string,
|
|
63487
|
+
* dialogExpand?: boolean,
|
|
63488
|
+
* dialogExpandX?: boolean,
|
|
63489
|
+
* dialogExpandY?: boolean,
|
|
63490
|
+
* dockedOnSmallTouchScreen?: boolean,
|
|
63491
|
+
* marginWithContainer?: number | string,
|
|
63492
|
+
* backdropVariant?: "auto" | "discrete" | "invisible",
|
|
63493
|
+
* pointerInteractionOutsideEffect?: "close" | "cancel" | "capture",
|
|
63494
|
+
* escapeEffect?: "cancel" | "close",
|
|
63495
|
+
* popupLayer?: "top" | "local",
|
|
63496
|
+
* [key: string]: any,
|
|
63497
|
+
* }>}
|
|
63498
|
+
* @param {Array<{value: any, label: import("ignore:preact").ComponentChildren}>} options
|
|
63499
|
+
* The ways of doing the thing, in the order the menu lists them. Anything
|
|
63500
|
+
* else on an entry (`disabled`, `icon`, `padding`…) reaches its row.
|
|
63501
|
+
* @param {any} [value] Which entry the button stands for — the one it runs, and
|
|
63502
|
+
* the one it is named after. `defaultValue` is the uncontrolled form; without
|
|
63503
|
+
* either, the first entry.
|
|
63504
|
+
* @param {import("ignore:preact").ComponentChildren} [label] What the button says, when
|
|
63505
|
+
* that is not the name of the entry it stands for — a button that keeps one
|
|
63506
|
+
* name whatever the menu does.
|
|
63507
|
+
* @param {(value: any, event: Event) => void} [action] Do the thing, for the
|
|
63508
|
+
* entry given. Pressed on the button it is the entry the button stands for;
|
|
63509
|
+
* with `chooseEffect="run"` it is also the entry just chosen. Awaited: the
|
|
63510
|
+
* whole split button is busy until it settles.
|
|
63511
|
+
* @param {"select"|"run"} [chooseEffect="select"] What choosing an entry does.
|
|
63512
|
+
* "select" hands the button that entry, to be run by a press on it — for
|
|
63513
|
+
* something one does again and again, where the last choice is the likely
|
|
63514
|
+
* next one. "run" does it there and then and leaves the button alone — for a
|
|
63515
|
+
* menu of one-offs around a primary action.
|
|
63516
|
+
* @param {string} [menuLabel] What the chevron half is called, for a screen
|
|
63517
|
+
* reader and for the tooltip a long press raises.
|
|
63518
|
+
* @param {import("ignore:preact").ComponentChildren} [menuIcon] What the chevron half
|
|
63519
|
+
* draws, in place of the chevron. It is the whole of what that half says, so
|
|
63520
|
+
* pass something that still reads as "there is more here" — and say what,
|
|
63521
|
+
* through `menuLabel`.
|
|
63522
|
+
* @param {number|string} [menuIconSize] How big that icon is drawn. Defaults to
|
|
63523
|
+
* the button's own font size.
|
|
63524
|
+
* @param {"popover"|"dialog"} [mode="popover"] What the menu is drawn as. A
|
|
63525
|
+
* picker left to itself turns into a dialog on a small screen; a split
|
|
63526
|
+
* button's menu stays hung off the button there, so this says popover unless
|
|
63527
|
+
* the caller asks for the dialog back.
|
|
63528
|
+
* @param {string} [positionArea="bottom-end"] Where the menu goes — relative to
|
|
63529
|
+
* the whole split button in popover mode, relative to the viewport in dialog
|
|
63530
|
+
* mode. Same grammar as Picker/Popover. The default only applies to a
|
|
63531
|
+
* popover; a dialog keeps Dialog's own "center".
|
|
63532
|
+
*
|
|
63533
|
+
* Every other prop the Picker's popup answers to is forwarded as-is —
|
|
63534
|
+
* `dockedOnSmallTouchScreen`, `dialogExpand*`, `dialogMaxWidth`/`Height`,
|
|
63535
|
+
* `marginWithContainer`, `popoverMode`, `popoverSpacing`, `popupLayer`,
|
|
63536
|
+
* `popupWidthFitContent`, `popoverMaxHeight`, `backdropVariant`,
|
|
63537
|
+
* `pointerInteractionOutsideEffect`, `escapeEffect`, `closeOnFocusOut`,
|
|
63538
|
+
* `scrollCapture`, `focusCapture`, `popupBackgroundColor`,
|
|
63539
|
+
* `popupBorderRadius`, `animation`. See picker.jsx for what each one says.
|
|
63540
|
+
* Anything else lands on the split button's own box.
|
|
63541
|
+
*/
|
|
63542
|
+
const SplitButton = props => {
|
|
63543
|
+
import.meta.css = [css$l, "@jsenv/navi/src/control/input/split_button.jsx"];
|
|
63544
|
+
const {
|
|
63545
|
+
options = [],
|
|
63546
|
+
value,
|
|
63547
|
+
defaultValue,
|
|
63548
|
+
label,
|
|
63549
|
+
action,
|
|
63550
|
+
onValueChange,
|
|
63551
|
+
chooseEffect = "select",
|
|
63552
|
+
menuLabel = naviI18n("button.more_actions"),
|
|
63553
|
+
menuIcon = jsx(ChevronDownSvg$1, {}),
|
|
63554
|
+
menuIconSize,
|
|
63555
|
+
loading,
|
|
63556
|
+
readOnly,
|
|
63557
|
+
disabled,
|
|
63558
|
+
// Shared paint: whatever the caller says about how the button looks is said
|
|
63559
|
+
// about both halves, or the seam shows.
|
|
63560
|
+
cta,
|
|
63561
|
+
variant,
|
|
63562
|
+
color,
|
|
63563
|
+
backgroundColor,
|
|
63564
|
+
borderColor,
|
|
63565
|
+
borderWidth,
|
|
63566
|
+
borderRadius,
|
|
63567
|
+
// A split button is a frame the user's eye reads as one box; the left half
|
|
63568
|
+
// shrinking under the finger while the right half stays put breaks it.
|
|
63569
|
+
pressEffect = "none",
|
|
63570
|
+
id,
|
|
63571
|
+
...rest
|
|
63572
|
+
} = props;
|
|
63573
|
+
// Everything the popup answers to travels to the Picker; everything else is
|
|
63574
|
+
// the split button's own box (margins, width, data-*). Sorted by name rather
|
|
63575
|
+
// than named one by one so a Picker popup prop is forwarded by adding it to
|
|
63576
|
+
// that list, not by threading it through here.
|
|
63577
|
+
const [popupProps, boxProps] = splitPopupProps(rest);
|
|
63578
|
+
// A split button is a control on the page, not a place one goes: its menu
|
|
63579
|
+
// hangs off it even on a phone, where a picker left to itself would decide a
|
|
63580
|
+
// small screen means a dialog. Passing mode="dialog" asks for that back.
|
|
63581
|
+
const mode = popupProps.mode === undefined ? "popover" : popupProps.mode;
|
|
63582
|
+
popupProps.mode = mode;
|
|
63583
|
+
// Read against the trigger in popover mode and against the VIEWPORT in
|
|
63584
|
+
// dialog mode, so this default only holds for the former — under the chevron
|
|
63585
|
+
// half, growing leftwards when the menu is wider than the button. A dialog
|
|
63586
|
+
// keeps Dialog's own "center".
|
|
63587
|
+
if (popupProps.positionArea === undefined && mode === "popover") {
|
|
63588
|
+
popupProps.positionArea = "bottom-end";
|
|
63589
|
+
}
|
|
63590
|
+
const idDefault = useId();
|
|
63591
|
+
const idResolved = id || idDefault;
|
|
63592
|
+
const menuId = `${idResolved}_menu`;
|
|
63593
|
+
const rootRef = useRef(null);
|
|
63594
|
+
const [valueState, setValueState] = useState(defaultValue === undefined ? options[0]?.value : defaultValue);
|
|
63595
|
+
const valueResolved = value === undefined ? valueState : value;
|
|
63596
|
+
const optionShown = options.find(option => option.value === valueResolved) || options[0];
|
|
63597
|
+
|
|
63598
|
+
// Busy is the control's, not the half that happens to be running: an action
|
|
63599
|
+
// given as a plain function is watched by running it from here, one given as
|
|
63600
|
+
// a navi action carries its own running state and is handed over untouched.
|
|
63601
|
+
const actionIsNaviAction = typeof action === "function" && action.isAction;
|
|
63602
|
+
const naviActionStatus = useActionStatus(actionIsNaviAction ? action : undefined);
|
|
63603
|
+
const [actionRunning, setActionRunning] = useState(false);
|
|
63604
|
+
const runAction = async (...args) => {
|
|
63605
|
+
setActionRunning(true);
|
|
63606
|
+
try {
|
|
63607
|
+
return await action(...args);
|
|
63608
|
+
} finally {
|
|
63609
|
+
setActionRunning(false);
|
|
63610
|
+
}
|
|
63611
|
+
};
|
|
63612
|
+
const actionResolved = actionIsNaviAction ? action : action ? runAction : undefined;
|
|
63613
|
+
const loadingResolved = Boolean(loading || actionRunning || naviActionStatus.loading);
|
|
63614
|
+
const halfProps = {
|
|
63615
|
+
cta,
|
|
63616
|
+
variant,
|
|
63617
|
+
color,
|
|
63618
|
+
backgroundColor,
|
|
63619
|
+
borderColor,
|
|
63620
|
+
borderWidth,
|
|
63621
|
+
borderRadius,
|
|
63622
|
+
pressEffect,
|
|
63623
|
+
loading: loadingResolved,
|
|
63624
|
+
readOnly,
|
|
63625
|
+
disabled,
|
|
63626
|
+
// The outline belongs around the pair, drawn below.
|
|
63627
|
+
loadingOutline: false
|
|
63628
|
+
};
|
|
63629
|
+
return jsxs(Box, {
|
|
63630
|
+
ref: rootRef,
|
|
63631
|
+
className: "navi_split_button",
|
|
63632
|
+
borderRadius: borderRadius,
|
|
63633
|
+
...boxProps,
|
|
63634
|
+
children: [jsx(LoadingOutline, {
|
|
63635
|
+
loading: loadingResolved,
|
|
63636
|
+
inset: -1,
|
|
63637
|
+
color: "var(--button-loader-color)"
|
|
63638
|
+
}), jsxs(Group, {
|
|
63639
|
+
children: [jsx(Button, {
|
|
63640
|
+
id: idResolved,
|
|
63641
|
+
value: valueResolved,
|
|
63642
|
+
action: actionResolved,
|
|
63643
|
+
...halfProps,
|
|
63644
|
+
children: label === undefined ? optionShown?.label : label
|
|
63645
|
+
}), jsxs("div", {
|
|
63646
|
+
className: "navi_split_button_menu",
|
|
63647
|
+
children: [jsx(Button, {
|
|
63648
|
+
icon: true,
|
|
63649
|
+
paddingX: "s",
|
|
63650
|
+
expandY: true
|
|
63651
|
+
// flex + align: the icon is the whole content, so it is laid out as
|
|
63652
|
+
// its own box in the middle of the button. Left to flow inline it
|
|
63653
|
+
// would sit on the baseline of a line of text that is not there,
|
|
63654
|
+
// with the descender space still kept below it.
|
|
63655
|
+
,
|
|
63656
|
+
|
|
63657
|
+
flex: true,
|
|
63658
|
+
align: "center",
|
|
63659
|
+
"aria-label": menuLabel,
|
|
63660
|
+
command: "--navi-open",
|
|
63661
|
+
commandFor: menuId,
|
|
63662
|
+
...halfProps,
|
|
63663
|
+
children: jsx(Icon, {
|
|
63664
|
+
size: menuIconSize,
|
|
63665
|
+
lineOverflow: "allow",
|
|
63666
|
+
children: menuIcon
|
|
63667
|
+
})
|
|
63668
|
+
}), jsx(Picker, {
|
|
63669
|
+
id: menuId,
|
|
63670
|
+
variant: "headless",
|
|
63671
|
+
allowNameless: true,
|
|
63672
|
+
anchor: rootRef,
|
|
63673
|
+
...popupProps,
|
|
63674
|
+
readOnly: readOnly,
|
|
63675
|
+
disabled: disabled,
|
|
63676
|
+
loading: loadingResolved,
|
|
63677
|
+
value: chooseEffect === "select" ? valueResolved : undefined,
|
|
63678
|
+
action: chooseEffect === "select" ? (chosenValue, event) => {
|
|
63679
|
+
setValueState(chosenValue);
|
|
63680
|
+
onValueChange?.(chosenValue, event);
|
|
63681
|
+
} : undefined,
|
|
63682
|
+
children: chooseEffect === "select" ? jsx(List, {
|
|
63683
|
+
selectable: true,
|
|
63684
|
+
command: "--navi-send",
|
|
63685
|
+
children: options.map((option, index) => {
|
|
63686
|
+
const {
|
|
63687
|
+
value: optionValue,
|
|
63688
|
+
label: optionLabel,
|
|
63689
|
+
...optionRest
|
|
63690
|
+
} = option;
|
|
63691
|
+
return jsx(List.Item, {
|
|
63692
|
+
selectable: true,
|
|
63693
|
+
id: `${menuId}_${index}`,
|
|
63694
|
+
index: index,
|
|
63695
|
+
value: optionValue,
|
|
63696
|
+
selected: optionValue === valueResolved,
|
|
63697
|
+
padding: "s",
|
|
63698
|
+
spacing: "s",
|
|
63699
|
+
...optionRest,
|
|
63700
|
+
children: optionLabel
|
|
63701
|
+
}, optionValue);
|
|
63702
|
+
})
|
|
63703
|
+
}) : jsx(List, {
|
|
63704
|
+
children: options.map((option, index) => {
|
|
63705
|
+
const {
|
|
63706
|
+
value: optionValue,
|
|
63707
|
+
label: optionLabel,
|
|
63708
|
+
...optionRest
|
|
63709
|
+
} = option;
|
|
63710
|
+
return jsx(List.Item, {
|
|
63711
|
+
id: `${menuId}_${index}`,
|
|
63712
|
+
index: index,
|
|
63713
|
+
padding: "0",
|
|
63714
|
+
children: jsx(Button, {
|
|
63715
|
+
variant: "bare",
|
|
63716
|
+
expandX: true,
|
|
63717
|
+
alignX: "start",
|
|
63718
|
+
padding: "s",
|
|
63719
|
+
pressEffect: "none",
|
|
63720
|
+
command: "--navi-close",
|
|
63721
|
+
commandFor: menuId,
|
|
63722
|
+
value: optionValue,
|
|
63723
|
+
action: actionResolved,
|
|
63724
|
+
...optionRest,
|
|
63725
|
+
children: optionLabel
|
|
63726
|
+
})
|
|
63727
|
+
}, optionValue);
|
|
63728
|
+
})
|
|
63729
|
+
})
|
|
63730
|
+
})]
|
|
63731
|
+
})]
|
|
63732
|
+
})]
|
|
63733
|
+
});
|
|
63734
|
+
};
|
|
63735
|
+
|
|
63736
|
+
// What the Picker's popup answers to — Picker's own popup props, named here so
|
|
63737
|
+
// a caller reaches all of them through the split button (see picker.jsx's JSDoc
|
|
63738
|
+
// for what each one says).
|
|
63739
|
+
const POPUP_PROP_SET = new Set(["mode", "popupLayer", "positionArea", "popoverMode", "popoverSpacing", "popupWidthFitContent", "popoverMaxHeight", "dialogMaxWidth", "dialogMaxHeight", "dialogExpand", "dialogExpandX", "dialogExpandY", "dockedOnSmallTouchScreen", "marginWithContainer", "backdropVariant", "pointerInteractionOutsideEffect", "escapeEffect", "closeOnFocusOut", "scrollCapture", "focusCapture", "popupBackgroundColor", "popupBorderRadius", "animation"]);
|
|
63740
|
+
const splitPopupProps = props => {
|
|
63741
|
+
const popupProps = {};
|
|
63742
|
+
const boxProps = {};
|
|
63743
|
+
for (const key of Object.keys(props)) {
|
|
63744
|
+
if (POPUP_PROP_SET.has(key)) {
|
|
63745
|
+
popupProps[key] = props[key];
|
|
63746
|
+
} else {
|
|
63747
|
+
boxProps[key] = props[key];
|
|
63748
|
+
}
|
|
63749
|
+
}
|
|
63750
|
+
return [popupProps, boxProps];
|
|
63751
|
+
};
|
|
63752
|
+
|
|
63259
63753
|
/**
|
|
63260
63754
|
* applySearch — matches value against searchText.
|
|
63261
63755
|
*
|
|
@@ -71924,5 +72418,5 @@ const UserSvg = () => jsx("svg", {
|
|
|
71924
72418
|
})
|
|
71925
72419
|
});
|
|
71926
72420
|
|
|
71927
|
-
export { ActionRenderer, ActiveKeyboardShortcuts, Address, Badge, BadgeCount, BadgeList, Binder, Box, Button, ButtonCopyToClipboard, Caption, CardLayout, CheckSvg, CheckboxGroup, CloseSvg, Code, Col, Colgroup, Color, ConstructionSvg, ControlGroup, DaySpin, Details, Dialog, Editable, ErrorBoundary, ErrorBoundaryContext, ExclamationSvg, EyeClosedSvg, EyeSvg, Field, FixedBar, Form, Group, Head, HeartSvg, HomeSvg, Icon, Image, Input, InputDuration, Interpolate, Label, Link, LinkAnchorSvg, LinkBlankTargetSvg, LinkCurrentSvg, List, ListItem, ListItemGroup, ListItems, Loading, LoadingDotsSvg, LoadingIndicator, LoadingIndicatorFluid, LoadingOutline, MessageBox, Meter, Nav, NaviDebug, NumberSpin, Paragraph, Picker, Popover, Popup, Quantity, RadioGroup, Route, RouteTravel, RowNumberCol, RowNumberTableCell, SVGMaskOverlay, SearchSvg, Select, SelectableInput, SelectionContext, Separator, SettingsSvg, SidePanel, Slide, SlideContainer, Spin, SpinGroup, StarSvg, SummaryMarker, Svg, Table, TableCell, Tbody, Text, TextBox, Textarea, TextareaCharCount, Thead, Time, TimeRangeSpin, TimeSpin, Title, Tr, UITransition, Unit, UserSvg, ViewportLayout, Wheel, WheelGroup, WheelItem, actionRunEffect, anyMatchingRouteSignal, applySearch, arraySignalMembership, compareTwoJsValues, createAction, createAvailableConstraint, createI18n, createRequestCanceller, createSearch, createSelectionKeyboardShortcuts, createSlot, defineInteractionDetector, defineNaviConfirmPopupOptions, detectHorizontalOverflow, enableDebugActions, enableDebugOnDocumentLoading, ensureDocumentStartViewTransition, errorIsDisplayed, filterTableSelection, formatDatetime, formatDay, formatDayRelative, formatMonth, formatNumber, formatTime, formatTimeRelative, getNowHours, getNowHoursRoundedToStep, interpolateText, isCellSelected, isColumnSelected, isRowSelected, isScrolling, isToday, languagesSignal, localStorageSignal, markErrorAsDisplayedBy, moveArrayItemByIndex, navBack, navForward, navIntegratedVia, navTo, naviI18n, openCallout, rawUrlPart, registerGlobalConstraint, reload, rerunActions, resource, route, routeAction, scrollActivitySignal, setBaseUrl, setPreferredLanguage, setSupportedLanguages, setUrlTargetOptions, setupRoutes, smallTouchScreenSignal, stateSignal, stopLoad, stringifyTableSelectionValue, swapArrayItemByIndex, syncOwnedResourceToSignals, syncResourceToSignals, triggerNaviCommand, updateActions, useActionStatus, useArraySignalMembership, useAsyncData, useCalloutRequestClose, useCancelPrevious, useCellGridFromRows, useConstraintValidityState, useDependenciesDiff, useDisplayedLayoutEffect, useDocumentResource, useDocumentState, useDocumentUrl, useEditionController, useFocusGroup, useInputGroup, useKeyboardShortcuts, useNavState, useOrderedColumns, usePopupMode, useRouteStatus, useRunOnMount, useSearchText, useSelectableElement, useSelectionController, useSignalSync, useSlideValue, useStateArray, useTitleLevel, useUrlSearchParam, useUrlTargetId, valueInLocalStorage, windowWidthSignal };
|
|
72421
|
+
export { ActionRenderer, ActiveKeyboardShortcuts, Address, Badge, BadgeCount, BadgeList, Binder, Box, Button, ButtonCopyToClipboard, Caption, CardLayout, CheckSvg, CheckboxGroup, CloseSvg, Code, Col, Colgroup, Color, ConstructionSvg, ControlGroup, DaySpin, Details, Dialog, Editable, ErrorBoundary, ErrorBoundaryContext, ExclamationSvg, EyeClosedSvg, EyeSvg, Field, FixedBar, Form, Group, Head, HeartSvg, HomeSvg, Icon, Image, Input, InputDuration, Interpolate, Label, Link, LinkAnchorSvg, LinkBlankTargetSvg, LinkCurrentSvg, List, ListItem, ListItemGroup, ListItems, Loading, LoadingDotsSvg, LoadingIndicator, LoadingIndicatorFluid, LoadingOutline, MessageBox, Meter, Nav, NaviDebug, NumberSpin, Paragraph, Picker, Popover, Popup, Quantity, RadioGroup, Route, RouteTravel, RowNumberCol, RowNumberTableCell, SVGMaskOverlay, SearchSvg, Select, SelectableInput, SelectionContext, Separator, SettingsSvg, SidePanel, Slide, SlideContainer, Spin, SpinGroup, SplitButton, StarSvg, SummaryMarker, Svg, Table, TableCell, Tbody, Text, TextBox, Textarea, TextareaCharCount, Thead, Time, TimeRangeSpin, TimeSpin, Title, Tr, UITransition, Unit, UserSvg, ViewportLayout, Wheel, WheelGroup, WheelItem, actionRunEffect, anyMatchingRouteSignal, applySearch, arraySignalMembership, compareTwoJsValues, createAction, createAvailableConstraint, createI18n, createRequestCanceller, createSearch, createSelectionKeyboardShortcuts, createSlot, defineInteractionDetector, defineNaviConfirmPopupOptions, detectHorizontalOverflow, enableDebugActions, enableDebugOnDocumentLoading, ensureDocumentStartViewTransition, errorIsDisplayed, filterTableSelection, formatDatetime, formatDay, formatDayRelative, formatMonth, formatNumber, formatTime, formatTimeRelative, getNowHours, getNowHoursRoundedToStep, interpolateText, isCellSelected, isColumnSelected, isRowSelected, isScrolling, isToday, languagesSignal, localStorageSignal, markErrorAsDisplayedBy, moveArrayItemByIndex, navBack, navForward, navIntegratedVia, navTo, naviI18n, openCallout, rawUrlPart, registerGlobalConstraint, reload, rerunActions, resource, route, routeAction, scrollActivitySignal, setBaseUrl, setPreferredLanguage, setSupportedLanguages, setUrlTargetOptions, setupRoutes, smallTouchScreenSignal, stateSignal, stopLoad, stringifyTableSelectionValue, swapArrayItemByIndex, syncOwnedResourceToSignals, syncResourceToSignals, triggerNaviCommand, updateActions, useActionStatus, useArraySignalMembership, useAsyncData, useCalloutRequestClose, useCancelPrevious, useCellGridFromRows, useConstraintValidityState, useDependenciesDiff, useDisplayedLayoutEffect, useDocumentResource, useDocumentState, useDocumentUrl, useEditionController, useFocusGroup, useInputGroup, useKeyboardShortcuts, useNavState, useOrderedColumns, usePopupMode, useRouteStatus, useRunOnMount, useSearchText, useSelectableElement, useSelectionController, useSignalSync, useSlideValue, useStateArray, useTitleLevel, useUrlSearchParam, useUrlTargetId, valueInLocalStorage, windowWidthSignal };
|
|
71928
72422
|
//# sourceMappingURL=jsenv_navi.js.map
|