@jsenv/navi 0.29.470 → 0.29.472
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/dev/jsenv_navi.js +595 -313
- package/dist/dev/jsenv_navi.js.map +22 -20
- package/dist/jsenv_navi.js +566 -311
- package/dist/jsenv_navi.js.map +22 -20
- package/docs/AI_INSTRUCTIONS.md +2 -2
- package/docs/popup_open.md +52 -0
- package/docs/testid.md +15 -2
- package/package.json +1 -1
package/dist/dev/jsenv_navi.js
CHANGED
|
@@ -40048,8 +40048,29 @@ const resolveFirstChildControl = (el) => {
|
|
|
40048
40048
|
}
|
|
40049
40049
|
return startEl.querySelector("[navi-control-host]");
|
|
40050
40050
|
};
|
|
40051
|
+
// The element a popup command is about: the closest one keeping an open state.
|
|
40051
40052
|
const resolveClosestExpandable = (el) => {
|
|
40052
|
-
|
|
40053
|
+
const expandable = el.closest("[aria-expanded]");
|
|
40054
|
+
if (!expandable) {
|
|
40055
|
+
return null;
|
|
40056
|
+
}
|
|
40057
|
+
return expandableRepeatedBy(expandable) || expandable;
|
|
40058
|
+
};
|
|
40059
|
+
// A control's host repeats the aria-expanded of its root, beside its role, for
|
|
40060
|
+
// assistive tech to read (a picker's <input>, a combobox or a button). The root
|
|
40061
|
+
// is the expandable: the host is a leaf the walk lands on only when it is the
|
|
40062
|
+
// source itself, and it carries the control's own `command`/`commandfor`, which
|
|
40063
|
+
// a command resolved again from it (a close after a clear) would follow.
|
|
40064
|
+
const expandableRepeatedBy = (el) => {
|
|
40065
|
+
const controlRoot = findControlRoot(el);
|
|
40066
|
+
if (
|
|
40067
|
+
controlRoot &&
|
|
40068
|
+
controlRoot !== el &&
|
|
40069
|
+
controlRoot.hasAttribute("aria-expanded")
|
|
40070
|
+
) {
|
|
40071
|
+
return controlRoot;
|
|
40072
|
+
}
|
|
40073
|
+
return null;
|
|
40053
40074
|
};
|
|
40054
40075
|
// The surface a send is decided on: the expandable holding the CONTROL that
|
|
40055
40076
|
// sends, never one that control is itself. A picker's own root carries
|
|
@@ -40060,7 +40081,7 @@ const resolveClosestExpandable = (el) => {
|
|
|
40060
40081
|
const resolveExpandableAround = (source) => {
|
|
40061
40082
|
const sender = findControlRoot(source) || source;
|
|
40062
40083
|
const parent = sender.parentElement;
|
|
40063
|
-
return parent ? parent
|
|
40084
|
+
return parent ? resolveClosestExpandable(parent) : null;
|
|
40064
40085
|
};
|
|
40065
40086
|
// An element carrying navi-command-proxy-for="anchorId" stands in for that
|
|
40066
40087
|
// other element as the command's source when the source is forwarded to
|
|
@@ -40377,8 +40398,12 @@ const sendCommand = (source, event, { requester }) => {
|
|
|
40377
40398
|
// looking at, and a decision just taken there is a reason to leave it. The
|
|
40378
40399
|
// NEAREST surface answers, and only that one — a form inside a slide inside a
|
|
40379
40400
|
// dialog goes back a slide, it does not also close the dialog.
|
|
40380
|
-
// send inside expandable
|
|
40381
|
-
|
|
40401
|
+
// send inside expandable — the control itself when it sends from its host,
|
|
40402
|
+
// whose aria-expanded is its root's (see expandableRepeatedBy)
|
|
40403
|
+
if (
|
|
40404
|
+
target.getAttribute("aria-expanded") === "true" &&
|
|
40405
|
+
!expandableRepeatedBy(target)
|
|
40406
|
+
) {
|
|
40382
40407
|
return {
|
|
40383
40408
|
target,
|
|
40384
40409
|
implementation: () => {
|
|
@@ -40813,7 +40838,7 @@ const requestCloseUpward = (target, detail) => {
|
|
|
40813
40838
|
return false;
|
|
40814
40839
|
}
|
|
40815
40840
|
const parent = expandable.parentElement;
|
|
40816
|
-
expandable = parent ? parent
|
|
40841
|
+
expandable = parent ? resolveClosestExpandable(parent) : null;
|
|
40817
40842
|
}
|
|
40818
40843
|
return true;
|
|
40819
40844
|
};
|
|
@@ -52832,10 +52857,16 @@ const LinkWithRoute = ({
|
|
|
52832
52857
|
currentExcept,
|
|
52833
52858
|
currentAlso,
|
|
52834
52859
|
children,
|
|
52860
|
+
// Kept out of `rest`: spread after the route's url, an `href={undefined}`
|
|
52861
|
+
// riding along would erase it.
|
|
52862
|
+
href,
|
|
52835
52863
|
...rest
|
|
52836
52864
|
}) => {
|
|
52837
52865
|
{
|
|
52838
52866
|
assertRoute(route);
|
|
52867
|
+
if (href !== undefined) {
|
|
52868
|
+
console.warn(`A link with a "route" ignores its "href" (${href}): the route builds the address.`);
|
|
52869
|
+
}
|
|
52839
52870
|
}
|
|
52840
52871
|
const url = route.buildUrl(routeParams);
|
|
52841
52872
|
{
|
|
@@ -58014,15 +58045,21 @@ const ButtonRouteResolver = props => {
|
|
|
58014
58045
|
};
|
|
58015
58046
|
const ButtonWithRoute = props => {
|
|
58016
58047
|
const Next = useNextResolver();
|
|
58048
|
+
// `href` is kept out of `rest`: spread after the route's url, an
|
|
58049
|
+
// `href={undefined}` riding along would erase it.
|
|
58017
58050
|
const {
|
|
58018
58051
|
route,
|
|
58019
58052
|
routeParams,
|
|
58020
58053
|
children,
|
|
58021
58054
|
pseudoState,
|
|
58055
|
+
href,
|
|
58022
58056
|
...rest
|
|
58023
58057
|
} = props;
|
|
58024
58058
|
{
|
|
58025
58059
|
assertRoute(route);
|
|
58060
|
+
if (href !== undefined) {
|
|
58061
|
+
console.warn(`A button with a "route" ignores its "href" (${href}): the route builds the address.`);
|
|
58062
|
+
}
|
|
58026
58063
|
}
|
|
58027
58064
|
const url = route.buildUrl(routeParams);
|
|
58028
58065
|
const linkMatching = useRouteCurrent(route, routeParams);
|
|
@@ -59404,6 +59441,10 @@ const Label = props => {
|
|
|
59404
59441
|
requiredIndicator
|
|
59405
59442
|
} = props;
|
|
59406
59443
|
const controlId = useContext(ControlIdContext);
|
|
59444
|
+
// What a popup opened from the control is named by (see getTriggerLabelIds
|
|
59445
|
+
// in picker_custom.jsx): aria-labelledby can only point at an id.
|
|
59446
|
+
const idDefault = useId();
|
|
59447
|
+
props.id = props.id || `label_${idDefault}`;
|
|
59407
59448
|
const [disabled, setDisabled] = useState(false);
|
|
59408
59449
|
const [readOnly, setReadOnly] = useState(false);
|
|
59409
59450
|
const [required, setRequired] = useState(false);
|
|
@@ -69182,9 +69223,297 @@ const PopupClose = ({
|
|
|
69182
69223
|
});
|
|
69183
69224
|
};
|
|
69184
69225
|
|
|
69226
|
+
const SuccessSvg = () => {
|
|
69227
|
+
return jsx("svg", {
|
|
69228
|
+
viewBox: "0 0 16 16",
|
|
69229
|
+
fill: "currentColor",
|
|
69230
|
+
children: jsx("path", {
|
|
69231
|
+
d: "M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm1.5 0a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm10.28-1.72-4.5 4.5a.75.75 0 0 1-1.06 0l-2-2a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018l1.47 1.47 3.97-3.97a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"
|
|
69232
|
+
})
|
|
69233
|
+
});
|
|
69234
|
+
};
|
|
69235
|
+
const ErrorSvg = () => {
|
|
69236
|
+
return jsx("svg", {
|
|
69237
|
+
viewBox: "0 0 16 16",
|
|
69238
|
+
fill: "currentColor",
|
|
69239
|
+
children: jsx("path", {
|
|
69240
|
+
d: "M4.47.22A.749.749 0 0 1 5 0h6c.199 0 .389.079.53.22l4.25 4.25c.141.14.22.331.22.53v6a.749.749 0 0 1-.22.53l-4.25 4.25A.749.749 0 0 1 11 16H5a.749.749 0 0 1-.53-.22L.22 11.53A.749.749 0 0 1 0 11V5c0-.199.079-.389.22-.53Zm.84 1.28L1.5 5.31v5.38l3.81 3.81h5.38l3.81-3.81V5.31L10.69 1.5ZM8 4a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"
|
|
69241
|
+
})
|
|
69242
|
+
});
|
|
69243
|
+
};
|
|
69244
|
+
const InfoSvg$1 = () => {
|
|
69245
|
+
return jsx("svg", {
|
|
69246
|
+
viewBox: "0 0 16 16",
|
|
69247
|
+
fill: "currentColor",
|
|
69248
|
+
children: jsx("path", {
|
|
69249
|
+
d: "M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"
|
|
69250
|
+
})
|
|
69251
|
+
});
|
|
69252
|
+
};
|
|
69253
|
+
const WarningSvg = () => {
|
|
69254
|
+
return jsx("svg", {
|
|
69255
|
+
viewBox: "0 0 16 16",
|
|
69256
|
+
fill: "currentColor",
|
|
69257
|
+
children: jsx("path", {
|
|
69258
|
+
d: "M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"
|
|
69259
|
+
})
|
|
69260
|
+
});
|
|
69261
|
+
};
|
|
69262
|
+
|
|
69263
|
+
installImportMetaCssBuild(import.meta);
|
|
69264
|
+
const css$E = /* css */`@layer navi {
|
|
69265
|
+
.navi_message_box {
|
|
69266
|
+
--background-color-info: var(--navi-info-color-light);
|
|
69267
|
+
--color-info: var(--navi-info-color);
|
|
69268
|
+
--background-color-success: var(--navi-success-color-light);
|
|
69269
|
+
--color-success: var(--navi-success-color);
|
|
69270
|
+
--background-color-warning: var(--navi-warning-color-light);
|
|
69271
|
+
--color-warning: var(--navi-warning-color);
|
|
69272
|
+
--background-color-error: var(--navi-error-color-light);
|
|
69273
|
+
--color-error: var(--navi-error-color);
|
|
69274
|
+
}
|
|
69275
|
+
}
|
|
69276
|
+
|
|
69277
|
+
.navi_message_box {
|
|
69278
|
+
--x-message-background-color: var(--background-color-info);
|
|
69279
|
+
--x-message-color: var(--color-info);
|
|
69280
|
+
background-color: var(--x-message-background-color);
|
|
69281
|
+
|
|
69282
|
+
& > .navi_icon {
|
|
69283
|
+
flex-shrink: 0;
|
|
69284
|
+
}
|
|
69285
|
+
}
|
|
69286
|
+
|
|
69287
|
+
.navi_message_box[data-status-info] {
|
|
69288
|
+
--x-message-background-color: var(--background-color-info);
|
|
69289
|
+
--x-message-color: var(--color-info);
|
|
69290
|
+
}
|
|
69291
|
+
|
|
69292
|
+
.navi_message_box[data-status-success] {
|
|
69293
|
+
--x-message-background-color: var(--background-color-success);
|
|
69294
|
+
--x-message-color: var(--color-success);
|
|
69295
|
+
}
|
|
69296
|
+
|
|
69297
|
+
.navi_message_box[data-status-warning] {
|
|
69298
|
+
--x-message-background-color: var(--background-color-warning);
|
|
69299
|
+
--x-message-color: var(--color-warning);
|
|
69300
|
+
}
|
|
69301
|
+
|
|
69302
|
+
.navi_message_box[data-status-error] {
|
|
69303
|
+
--x-message-background-color: var(--background-color-error);
|
|
69304
|
+
--x-message-color: var(--color-error);
|
|
69305
|
+
}
|
|
69306
|
+
|
|
69307
|
+
.navi_message_box[data-left-stripe] {
|
|
69308
|
+
border-left: 6px solid var(--x-message-color);
|
|
69309
|
+
border-top-left-radius: 6px;
|
|
69310
|
+
border-bottom-left-radius: 6px;
|
|
69311
|
+
}
|
|
69312
|
+
`;
|
|
69313
|
+
const MessageBox = ({
|
|
69314
|
+
status = "info",
|
|
69315
|
+
padding = "sm",
|
|
69316
|
+
icon,
|
|
69317
|
+
leftStripe,
|
|
69318
|
+
children,
|
|
69319
|
+
onClose,
|
|
69320
|
+
...rest
|
|
69321
|
+
}) => {
|
|
69322
|
+
import.meta.css = [css$E, "@jsenv/navi/src/text/message_box.jsx"];
|
|
69323
|
+
const [hasTitleChild, setHasTitleChild] = useState(false);
|
|
69324
|
+
const innerLeftStripe = leftStripe === undefined ? hasTitleChild : leftStripe;
|
|
69325
|
+
if (icon === true) {
|
|
69326
|
+
icon = status === "info" ? jsx(InfoSvg$1, {}) : status === "success" ? jsx(SuccessSvg, {}) : status === "warning" ? jsx(WarningSvg, {}) : status === "error" ? jsx(ErrorSvg, {}) : null;
|
|
69327
|
+
} else if (typeof icon === "function") {
|
|
69328
|
+
const Comp = icon;
|
|
69329
|
+
icon = jsx(Comp, {});
|
|
69330
|
+
}
|
|
69331
|
+
return jsx(Box, {
|
|
69332
|
+
as: "div",
|
|
69333
|
+
role: status === "info" ? "status" : "alert",
|
|
69334
|
+
"data-left-stripe": innerLeftStripe ? "" : undefined,
|
|
69335
|
+
inline: true,
|
|
69336
|
+
column: true,
|
|
69337
|
+
alignY: "center",
|
|
69338
|
+
spacing: "s",
|
|
69339
|
+
...rest,
|
|
69340
|
+
className: withPropsClassName("navi_message_box", rest.className),
|
|
69341
|
+
padding: padding,
|
|
69342
|
+
pseudoClasses: MessageBoxPseudoClasses,
|
|
69343
|
+
basePseudoState: {
|
|
69344
|
+
":-navi-status-info": status === "info",
|
|
69345
|
+
":-navi-status-success": status === "success",
|
|
69346
|
+
":-navi-status-warning": status === "warning",
|
|
69347
|
+
":-navi-status-error": status === "error"
|
|
69348
|
+
},
|
|
69349
|
+
children: jsx(MessageBoxStatusContext.Provider, {
|
|
69350
|
+
value: status,
|
|
69351
|
+
children: jsxs(MessageBoxReportTitleChildContext.Provider, {
|
|
69352
|
+
value: setHasTitleChild,
|
|
69353
|
+
children: [icon && jsx(Icon, {
|
|
69354
|
+
color: "var(--x-message-color)",
|
|
69355
|
+
height: "1lh",
|
|
69356
|
+
maxHeight: "auto",
|
|
69357
|
+
selfAlignY: "start",
|
|
69358
|
+
aspectRatio: "auto",
|
|
69359
|
+
children: icon
|
|
69360
|
+
}), jsx(Text, {
|
|
69361
|
+
children: children
|
|
69362
|
+
}), onClose &&
|
|
69363
|
+
// A column as tall as the first line of the message, pinned to the
|
|
69364
|
+
// top, the button centered in it: the close button stays level
|
|
69365
|
+
// with the first line however many lines the message takes (same
|
|
69366
|
+
// layout as Callout).
|
|
69367
|
+
jsx(Box, {
|
|
69368
|
+
flex: true,
|
|
69369
|
+
alignY: "center",
|
|
69370
|
+
height: "1lh",
|
|
69371
|
+
selfAlignY: "start",
|
|
69372
|
+
shrink: false,
|
|
69373
|
+
children: jsx(Button, {
|
|
69374
|
+
action: onClose,
|
|
69375
|
+
icon: true,
|
|
69376
|
+
border: "none",
|
|
69377
|
+
style: {
|
|
69378
|
+
":hover": {
|
|
69379
|
+
backgroundColor: "rgba(0, 0, 0, 0.1)"
|
|
69380
|
+
}
|
|
69381
|
+
},
|
|
69382
|
+
children: jsx(Icon, {
|
|
69383
|
+
children: jsx(CloseSvg, {})
|
|
69384
|
+
})
|
|
69385
|
+
})
|
|
69386
|
+
})]
|
|
69387
|
+
})
|
|
69388
|
+
})
|
|
69389
|
+
});
|
|
69390
|
+
};
|
|
69391
|
+
const MessageBoxPseudoClasses = [":-navi-status-info", ":-navi-status-success", ":-navi-status-warning", ":-navi-status-error"];
|
|
69392
|
+
const MessageBoxStatusContext = createContext();
|
|
69393
|
+
const MessageBoxReportTitleChildContext = createContext();
|
|
69394
|
+
|
|
69395
|
+
installImportMetaCssBuild(import.meta);
|
|
69396
|
+
const css$D = /* css */`.navi_message_box {
|
|
69397
|
+
& .navi_title {
|
|
69398
|
+
margin-top: 0;
|
|
69399
|
+
margin-bottom: var(--navi-s);
|
|
69400
|
+
color: var(--x-message-color);
|
|
69401
|
+
}
|
|
69402
|
+
}
|
|
69403
|
+
`;
|
|
69404
|
+
const Title = props => {
|
|
69405
|
+
import.meta.css = [css$D, "@jsenv/navi/src/text/title.jsx"];
|
|
69406
|
+
const messageBoxStatus = useContext(MessageBoxStatusContext);
|
|
69407
|
+
const innerAs = props.as || (messageBoxStatus ? "h4" : "h1");
|
|
69408
|
+
const titleLevel = parseInt(innerAs.slice(1));
|
|
69409
|
+
const reportTitleToMessageBox = useContext(MessageBoxReportTitleChildContext);
|
|
69410
|
+
reportTitleToMessageBox?.(true);
|
|
69411
|
+
return jsx(TitleLevelContext.Provider, {
|
|
69412
|
+
value: titleLevel,
|
|
69413
|
+
children: jsx(Text, {
|
|
69414
|
+
bold: true,
|
|
69415
|
+
className: withPropsClassName("navi_title"),
|
|
69416
|
+
as: messageBoxStatus ? "h4" : "h1",
|
|
69417
|
+
...props,
|
|
69418
|
+
pseudoClasses: TitlePseudoClasses,
|
|
69419
|
+
children: props.children
|
|
69420
|
+
})
|
|
69421
|
+
});
|
|
69422
|
+
};
|
|
69423
|
+
const TitleLevelContext = createContext();
|
|
69424
|
+
const useTitleLevel = () => {
|
|
69425
|
+
return useContext(TitleLevelContext);
|
|
69426
|
+
};
|
|
69427
|
+
const TitlePseudoClasses = [":hover"];
|
|
69428
|
+
|
|
69429
|
+
/**
|
|
69430
|
+
* What a popup is called, decided by Dialog and Popover alike: the name the
|
|
69431
|
+
* caller writes on it (aria-label/aria-labelledby), else the title it holds
|
|
69432
|
+
* (`<Popup.Title>`), else the name of what opened it (`openerAriaLabelledBy` /
|
|
69433
|
+
* `openerAriaLabel`, which a Picker fills with its trigger's). A popup no one
|
|
69434
|
+
* names is announced as "dialog" and nothing else.
|
|
69435
|
+
*
|
|
69436
|
+
* The title tells the popup it exists rather than the popup looking for it:
|
|
69437
|
+
* the content is built after the popup and thrown away before it (see
|
|
69438
|
+
* popup_content_mount.js), and a title may sit anywhere in it — a header, a
|
|
69439
|
+
* step of a form — so only the title knows when it is there.
|
|
69440
|
+
*/
|
|
69441
|
+
|
|
69442
|
+
const PopupTitleContext = createContext(null);
|
|
69443
|
+
|
|
69444
|
+
/**
|
|
69445
|
+
* The title of the popup it sits in — reached as `<Popup.Title>`,
|
|
69446
|
+
* `<Dialog.Title>` or `<Popover.Title>`. A heading (`h2` unless `as` says
|
|
69447
|
+
* otherwise) that is also the popup's accessible name: a screen reader
|
|
69448
|
+
* announces the popup by it, and `getByRole("dialog", { name })` finds it.
|
|
69449
|
+
* An `aria-label`/`aria-labelledby` written on the popup itself wins over it.
|
|
69450
|
+
*
|
|
69451
|
+
* @type {import("ignore:preact").FunctionComponent<{
|
|
69452
|
+
* as?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6",
|
|
69453
|
+
* id?: string,
|
|
69454
|
+
* children?: import("ignore:preact").ComponentChildren,
|
|
69455
|
+
* } & Record<string, any>>}
|
|
69456
|
+
*/
|
|
69457
|
+
const PopupTitle = props => {
|
|
69458
|
+
const registerTitle = useContext(PopupTitleContext);
|
|
69459
|
+
const idDefault = useId();
|
|
69460
|
+
const id = props.id || `popup_title_${idDefault}`;
|
|
69461
|
+
useLayoutEffect(() => {
|
|
69462
|
+
if (!registerTitle) {
|
|
69463
|
+
return undefined;
|
|
69464
|
+
}
|
|
69465
|
+
return registerTitle(id);
|
|
69466
|
+
}, [registerTitle, id]);
|
|
69467
|
+
return jsx(Title, {
|
|
69468
|
+
as: "h2",
|
|
69469
|
+
...props,
|
|
69470
|
+
id: id
|
|
69471
|
+
});
|
|
69472
|
+
};
|
|
69473
|
+
|
|
69474
|
+
/**
|
|
69475
|
+
* The name props of a popup element, and what its titles register with —
|
|
69476
|
+
* handed to its children through PopupTitleContext.
|
|
69477
|
+
*/
|
|
69478
|
+
const usePopupName = ({
|
|
69479
|
+
ariaLabel,
|
|
69480
|
+
ariaLabelledBy,
|
|
69481
|
+
openerAriaLabel,
|
|
69482
|
+
openerAriaLabelledBy
|
|
69483
|
+
}) => {
|
|
69484
|
+
// Several titles is a content of the caller's own making (two steps both
|
|
69485
|
+
// mounted): the first one registered names the popup.
|
|
69486
|
+
const [titleIds, setTitleIds] = useState(NO_TITLE);
|
|
69487
|
+
const registerTitle = useMemo(() => {
|
|
69488
|
+
return id => {
|
|
69489
|
+
setTitleIds(ids => [...ids, id]);
|
|
69490
|
+
return () => {
|
|
69491
|
+
setTitleIds(ids => ids.filter(each => each !== id));
|
|
69492
|
+
};
|
|
69493
|
+
};
|
|
69494
|
+
}, []);
|
|
69495
|
+
let labelledBy;
|
|
69496
|
+
let label;
|
|
69497
|
+
if (ariaLabelledBy !== undefined || ariaLabel !== undefined) {
|
|
69498
|
+
labelledBy = ariaLabelledBy;
|
|
69499
|
+
label = ariaLabel;
|
|
69500
|
+
} else if (titleIds.length > 0) {
|
|
69501
|
+
labelledBy = titleIds[0];
|
|
69502
|
+
} else if (openerAriaLabelledBy !== undefined) {
|
|
69503
|
+
labelledBy = openerAriaLabelledBy;
|
|
69504
|
+
} else {
|
|
69505
|
+
label = openerAriaLabel;
|
|
69506
|
+
}
|
|
69507
|
+
return [{
|
|
69508
|
+
"aria-labelledby": labelledBy,
|
|
69509
|
+
"aria-label": label
|
|
69510
|
+
}, registerTitle];
|
|
69511
|
+
};
|
|
69512
|
+
const NO_TITLE = [];
|
|
69513
|
+
|
|
69185
69514
|
installImportMetaCssBuild(import.meta);
|
|
69186
69515
|
let openLocalDialogCount = 0;
|
|
69187
|
-
const css$
|
|
69516
|
+
const css$C = /* css */`
|
|
69188
69517
|
/* jsenv-css-opaque: popupCss overlaps these rules, own sheet = cascade
|
|
69189
69518
|
order depending on which popup renders first. */
|
|
69190
69519
|
|
|
@@ -70253,10 +70582,14 @@ const css$E = /* css */`
|
|
|
70253
70582
|
* under `"while-opened"`, only a press on what opens the popup does (a
|
|
70254
70583
|
* `--navi-open` button, a picker's trigger), never with an `onOpen`, and a
|
|
70255
70584
|
* press that does not open the popup throws it away.
|
|
70585
|
+
* @param {string} [props.openerAriaLabelledBy] - The id(s) naming what opened
|
|
70586
|
+
* the dialog: its accessible name when neither `aria-label`/`aria-labelledby`
|
|
70587
|
+
* nor a `<Dialog.Title>` names it. A Picker passes its trigger's.
|
|
70588
|
+
* @param {string} [props.openerAriaLabel] - The same, as a string.
|
|
70256
70589
|
* @param {import("ignore:preact").ComponentChildren} props.children
|
|
70257
70590
|
*/
|
|
70258
70591
|
const Dialog = props => {
|
|
70259
|
-
import.meta.css = [css$
|
|
70592
|
+
import.meta.css = [css$C, "@jsenv/navi/src/layout/dialog.jsx"];
|
|
70260
70593
|
if (props.openController) {
|
|
70261
70594
|
return jsx(ControlledDialog, {
|
|
70262
70595
|
...props
|
|
@@ -70632,6 +70965,9 @@ const useDialogProps = props => {
|
|
|
70632
70965
|
onOpen,
|
|
70633
70966
|
children: childrenProp,
|
|
70634
70967
|
mount,
|
|
70968
|
+
// Read by usePopupName below, never written on the element.
|
|
70969
|
+
openerAriaLabel,
|
|
70970
|
+
openerAriaLabelledBy,
|
|
70635
70971
|
...rest
|
|
70636
70972
|
} = props;
|
|
70637
70973
|
// Assigned on every render, like openEffect below, so it always closes over
|
|
@@ -70642,7 +70978,16 @@ const useDialogProps = props => {
|
|
|
70642
70978
|
mount,
|
|
70643
70979
|
anchor
|
|
70644
70980
|
});
|
|
70645
|
-
const
|
|
70981
|
+
const [nameProps, registerTitle] = usePopupName({
|
|
70982
|
+
ariaLabel: rest["aria-label"],
|
|
70983
|
+
ariaLabelledBy: rest["aria-labelledby"],
|
|
70984
|
+
openerAriaLabel,
|
|
70985
|
+
openerAriaLabelledBy
|
|
70986
|
+
});
|
|
70987
|
+
const children = contentMounted ? jsx(PopupTitleContext.Provider, {
|
|
70988
|
+
value: registerTitle,
|
|
70989
|
+
children: childrenProp
|
|
70990
|
+
}) : null;
|
|
70646
70991
|
// Where it is placed, and whether there is a wall — the two questions that
|
|
70647
70992
|
// pick the show call (see this file's top comment).
|
|
70648
70993
|
const isTopLayer = layer === "top";
|
|
@@ -71492,6 +71837,7 @@ const useDialogProps = props => {
|
|
|
71492
71837
|
"backdropFilter": backdrop ? backdropFilter : undefined,
|
|
71493
71838
|
"styleCSSVars": DIALOG_STYLE_CSS_VARS,
|
|
71494
71839
|
...rest,
|
|
71840
|
+
...nameProps,
|
|
71495
71841
|
...autoFocusProps,
|
|
71496
71842
|
"as": "dialog",
|
|
71497
71843
|
ref,
|
|
@@ -71692,10 +72038,11 @@ const DIALOG_STYLE_CSS_VARS = {
|
|
|
71692
72038
|
maxHeight: "--dialog-max-height"
|
|
71693
72039
|
};
|
|
71694
72040
|
Dialog.Close = PopupClose;
|
|
72041
|
+
Dialog.Title = PopupTitle;
|
|
71695
72042
|
|
|
71696
72043
|
installImportMetaCssBuild(import.meta);
|
|
71697
72044
|
let openLocalPopoverCount = 0;
|
|
71698
|
-
const css$
|
|
72045
|
+
const css$B = /* css */`
|
|
71699
72046
|
/* jsenv-css-opaque: popupCss overlaps these rules, own sheet = cascade
|
|
71700
72047
|
order depending on which popup renders first. */
|
|
71701
72048
|
|
|
@@ -72294,10 +72641,17 @@ const css$D = /* css */`
|
|
|
72294
72641
|
* under `"while-opened"`, only a press on what opens the popup does (a
|
|
72295
72642
|
* `--navi-open` button, a picker's trigger), never with an `onOpen`, and a
|
|
72296
72643
|
* press that does not open the popup throws it away.
|
|
72644
|
+
* @param {string} [props.openerAriaLabelledBy] - The id(s) naming what opened
|
|
72645
|
+
* the popover: its accessible name when neither `aria-label`/`aria-labelledby`
|
|
72646
|
+
* nor a `<Popover.Title>` names it. A Picker passes its trigger's.
|
|
72647
|
+
* @param {string} [props.openerAriaLabel] - The same, as a string. A popover
|
|
72648
|
+
* something names — these, `aria-label`/`aria-labelledby`, a
|
|
72649
|
+
* `<Popover.Title>` — is a `dialog`, unless given another `role`: a name on
|
|
72650
|
+
* an element with no role is read by nobody.
|
|
72297
72651
|
* @param {import("ignore:preact").ComponentChildren} props.children
|
|
72298
72652
|
*/
|
|
72299
72653
|
const Popover = props => {
|
|
72300
|
-
import.meta.css = [css$
|
|
72654
|
+
import.meta.css = [css$B, "@jsenv/navi/src/layout/popover.jsx"];
|
|
72301
72655
|
if (props.openController) {
|
|
72302
72656
|
return jsx(ControlledPopover, {
|
|
72303
72657
|
...props
|
|
@@ -72536,6 +72890,9 @@ const usePopoverProps = props => {
|
|
|
72536
72890
|
onOpen,
|
|
72537
72891
|
children: childrenProp,
|
|
72538
72892
|
mount,
|
|
72893
|
+
// Read by usePopupName below, never written on the element.
|
|
72894
|
+
openerAriaLabel,
|
|
72895
|
+
openerAriaLabelledBy,
|
|
72539
72896
|
...rest
|
|
72540
72897
|
} = props;
|
|
72541
72898
|
// Assigned on every render, like openEffect below, so it always closes over
|
|
@@ -72546,7 +72903,16 @@ const usePopoverProps = props => {
|
|
|
72546
72903
|
mount,
|
|
72547
72904
|
anchor
|
|
72548
72905
|
});
|
|
72549
|
-
const
|
|
72906
|
+
const [nameProps, registerTitle] = usePopupName({
|
|
72907
|
+
ariaLabel: rest["aria-label"],
|
|
72908
|
+
ariaLabelledBy: rest["aria-labelledby"],
|
|
72909
|
+
openerAriaLabel,
|
|
72910
|
+
openerAriaLabelledBy
|
|
72911
|
+
});
|
|
72912
|
+
const children = contentMounted ? jsx(PopupTitleContext.Provider, {
|
|
72913
|
+
value: registerTitle,
|
|
72914
|
+
children: childrenProp
|
|
72915
|
+
}) : null;
|
|
72550
72916
|
const isTopLayer = layer === "top";
|
|
72551
72917
|
const ref = props.ref;
|
|
72552
72918
|
const backdropRef = useRef();
|
|
@@ -73361,6 +73727,10 @@ const usePopoverProps = props => {
|
|
|
73361
73727
|
"navi-hidden": openController.openedInDom ? undefined : "",
|
|
73362
73728
|
"styleCSSVars": POPUP_STYLE_CSS_VARS,
|
|
73363
73729
|
...rest,
|
|
73730
|
+
...nameProps,
|
|
73731
|
+
// A <div> has no role, and a name on an element without one is read by
|
|
73732
|
+
// nobody: a popover something names is a dialog, unless told what else.
|
|
73733
|
+
"role": rest.role ?? (nameProps["aria-labelledby"] === undefined && nameProps["aria-label"] === undefined ? undefined : "dialog"),
|
|
73364
73734
|
...autoFocusProps,
|
|
73365
73735
|
ref,
|
|
73366
73736
|
// Not a control, but still something the rest of navi has to be able to
|
|
@@ -73476,9 +73846,10 @@ const resolvePositionAreaAndAnimationKind = ({
|
|
|
73476
73846
|
};
|
|
73477
73847
|
};
|
|
73478
73848
|
Popover.Close = PopupClose;
|
|
73849
|
+
Popover.Title = PopupTitle;
|
|
73479
73850
|
|
|
73480
73851
|
installImportMetaCssBuild(import.meta);
|
|
73481
|
-
const css$
|
|
73852
|
+
const css$A = /* css */`@layer navi {
|
|
73482
73853
|
.navi_popup {
|
|
73483
73854
|
--popup-border-radius: var(--navi-popup-border-radius);
|
|
73484
73855
|
--popup-border-width: 1px;
|
|
@@ -73619,6 +73990,10 @@ const css$C = /* css */`@layer navi {
|
|
|
73619
73990
|
* @param {string} [props.className] - Merged with the shared
|
|
73620
73991
|
* `"navi_popup"` class (see this file's own CSS) rather than replacing
|
|
73621
73992
|
* it.
|
|
73993
|
+
* @param {string} [props.openerAriaLabelledBy] - Forwarded as-is: the name the
|
|
73994
|
+
* popup takes when neither `aria-label`/`aria-labelledby` nor a
|
|
73995
|
+
* `<Popup.Title>` in `children` names it (see `Dialog`/`Popover`).
|
|
73996
|
+
* @param {string} [props.openerAriaLabel] - Forwarded as-is, same.
|
|
73622
73997
|
* @param {"always"|"idle"|"from-first-open"|"while-opened"} [props.mount] - When
|
|
73623
73998
|
* `children` are built and thrown away (see popup_content_mount.js).
|
|
73624
73999
|
* `"from-first-open"` (the default) builds them on the first open and keeps
|
|
@@ -73634,7 +74009,7 @@ const css$C = /* css */`@layer navi {
|
|
|
73634
74009
|
* @param {import("ignore:preact").ComponentChildren} props.children
|
|
73635
74010
|
*/
|
|
73636
74011
|
const Popup = props => {
|
|
73637
|
-
import.meta.css = [css$
|
|
74012
|
+
import.meta.css = [css$A, "@jsenv/navi/src/layout/popup.jsx"];
|
|
73638
74013
|
const {
|
|
73639
74014
|
mode: modeProp,
|
|
73640
74015
|
maxWidth,
|
|
@@ -73717,6 +74092,7 @@ const Popup = props => {
|
|
|
73717
74092
|
});
|
|
73718
74093
|
};
|
|
73719
74094
|
Popup.Close = PopupClose;
|
|
74095
|
+
Popup.Title = PopupTitle;
|
|
73720
74096
|
|
|
73721
74097
|
// What Dialog's own animation values mean to a popover, which has no lift
|
|
73722
74098
|
// (see the `animation` doc above).
|
|
@@ -73765,6 +74141,54 @@ const pickerUIIsNaviOwn = ui => {
|
|
|
73765
74141
|
return Boolean(ui) && typeof ui === "object" && Boolean(ui.type?.isPickerOwnUI);
|
|
73766
74142
|
};
|
|
73767
74143
|
|
|
74144
|
+
/*
|
|
74145
|
+
* What the picker really is, said on the element that holds the name and takes
|
|
74146
|
+
* the focus (the host input in picker.jsx), which is both what a screen reader
|
|
74147
|
+
* announces and what getByRole(role, { name }) finds:
|
|
74148
|
+
* - a picker that picks nothing is a door — its popup is a question
|
|
74149
|
+
* (type="confirm") or something to read (mode="callout", which says it for
|
|
74150
|
+
* itself) — and a door is pressed: "button";
|
|
74151
|
+
* - a picker holding a value and opening a popup of navi's is a select-only
|
|
74152
|
+
* combobox: it shows a value the user does not type, and opens what changes
|
|
74153
|
+
* it. A textbox could not say the rest — aria-expanded is not allowed on one,
|
|
74154
|
+
* so "open" and "closed" would never be announced;
|
|
74155
|
+
* - a picker showing the browser's own picker (no popup of navi's) stays the
|
|
74156
|
+
* textbox its <input> is.
|
|
74157
|
+
*/
|
|
74158
|
+
const getPickerHostRole = props => {
|
|
74159
|
+
if (props.role !== undefined) {
|
|
74160
|
+
return props.role;
|
|
74161
|
+
}
|
|
74162
|
+
if (props.picksNothing) {
|
|
74163
|
+
return "button";
|
|
74164
|
+
}
|
|
74165
|
+
if (props["aria-haspopup"] !== undefined) {
|
|
74166
|
+
return "combobox";
|
|
74167
|
+
}
|
|
74168
|
+
return undefined;
|
|
74169
|
+
};
|
|
74170
|
+
|
|
74171
|
+
/*
|
|
74172
|
+
* And what that button is called, when the caller wrote it as a drawing rather
|
|
74173
|
+
* than as a word: a door draws no value, so what sits in its value slot IS its
|
|
74174
|
+
* label — the `ui` a caller gave it, or its placeholder. Undefined the moment
|
|
74175
|
+
* the caller names it themselves (aria-label/aria-labelledby), which is the
|
|
74176
|
+
* only way to name a door drawn as an icon. Read by the popup too: what the
|
|
74177
|
+
* user pressed is a fair name for what it opened.
|
|
74178
|
+
*/
|
|
74179
|
+
const getPickerHostLabelId = (id, props) => {
|
|
74180
|
+
if (getPickerHostRole(props) !== "button") {
|
|
74181
|
+
return undefined;
|
|
74182
|
+
}
|
|
74183
|
+
if (props["aria-label"] !== undefined || props["aria-labelledby"] !== undefined) {
|
|
74184
|
+
return undefined;
|
|
74185
|
+
}
|
|
74186
|
+
if (props.variant === "headless" || props.ui === "default") {
|
|
74187
|
+
return undefined;
|
|
74188
|
+
}
|
|
74189
|
+
return `${id}_picker_label`;
|
|
74190
|
+
};
|
|
74191
|
+
|
|
73768
74192
|
/**
|
|
73769
74193
|
* What the picker holds, read from inside its `ui` — for a drawing given as
|
|
73770
74194
|
* an element (`ui={<MyCard game={game} />}`), which the picker cannot hand
|
|
@@ -73794,7 +74218,7 @@ const usePickerState = () => {
|
|
|
73794
74218
|
};
|
|
73795
74219
|
|
|
73796
74220
|
installImportMetaCssBuild(import.meta);
|
|
73797
|
-
const css$
|
|
74221
|
+
const css$z = /* css */`.navi_picker_callout_dock > [data-picker-content] {
|
|
73798
74222
|
display: none;
|
|
73799
74223
|
}
|
|
73800
74224
|
|
|
@@ -73823,7 +74247,7 @@ const css$B = /* css */`.navi_picker_callout_dock > [data-picker-content] {
|
|
|
73823
74247
|
}
|
|
73824
74248
|
}
|
|
73825
74249
|
|
|
73826
|
-
.navi_picker[
|
|
74250
|
+
.navi_picker[navi-popover-mode="overlay"][aria-expanded="true"] {
|
|
73827
74251
|
border-color: #0000;
|
|
73828
74252
|
}
|
|
73829
74253
|
|
|
@@ -73851,7 +74275,7 @@ const css$B = /* css */`.navi_picker_callout_dock > [data-picker-content] {
|
|
|
73851
74275
|
}
|
|
73852
74276
|
`;
|
|
73853
74277
|
const PickerCustomResolver = props => {
|
|
73854
|
-
import.meta.css = [css$
|
|
74278
|
+
import.meta.css = [css$z, "@jsenv/navi/src/control/picker/picker_custom.jsx"];
|
|
73855
74279
|
if (props.children === undefined) {
|
|
73856
74280
|
return renderResolver(PickerNative, props);
|
|
73857
74281
|
}
|
|
@@ -74022,8 +74446,9 @@ const PickerCustom = props => {
|
|
|
74022
74446
|
props.id = props.id || controlId || idDefault;
|
|
74023
74447
|
// Given no value, the picker holds what the control in its popup holds (see
|
|
74024
74448
|
// the `mount` decision below) — and a group around it collects that from the
|
|
74025
|
-
// moment both exist.
|
|
74026
|
-
|
|
74449
|
+
// moment both exist. A picker that picks nothing holds none: its popup's
|
|
74450
|
+
// controls are never adopted (see canRegisterAsFacadeChild).
|
|
74451
|
+
const valueInPopup = !props.picksNothing && !isControlValueGivenByProps(props);
|
|
74027
74452
|
const parentController = useContext(ParentUIStateControllerContext);
|
|
74028
74453
|
const answersToGroup = Boolean(parentController) && !props.standalone;
|
|
74029
74454
|
// Same narrow-container/maxWidth-compact heuristic Popup itself uses (see
|
|
@@ -74674,6 +75099,24 @@ const isPressDisputedByHold = pickerEl => Boolean(pickerEl?.parentElement?.close
|
|
|
74674
75099
|
const getPickerInput = pickerEl => {
|
|
74675
75100
|
return pickerEl.querySelector(".navi_picker_input");
|
|
74676
75101
|
};
|
|
75102
|
+
|
|
75103
|
+
// The <label>s naming a picker's trigger, by id. Read off the document: it is
|
|
75104
|
+
// the one place a label[for] and its control meet (navi's own Label carries an
|
|
75105
|
+
// id for this). A label wrapping the picker is left out — it holds the trigger
|
|
75106
|
+
// and the popup with it, and the popup would be named after its own content.
|
|
75107
|
+
const getTriggerLabelIds = pickerEl => {
|
|
75108
|
+
const labels = pickerEl && getPickerInput(pickerEl)?.labels;
|
|
75109
|
+
if (!labels) {
|
|
75110
|
+
return undefined;
|
|
75111
|
+
}
|
|
75112
|
+
const ids = [];
|
|
75113
|
+
for (const label of labels) {
|
|
75114
|
+
if (label.id && !label.contains(pickerEl)) {
|
|
75115
|
+
ids.push(label.id);
|
|
75116
|
+
}
|
|
75117
|
+
}
|
|
75118
|
+
return ids.length === 0 ? undefined : ids.join(" ");
|
|
75119
|
+
};
|
|
74677
75120
|
const getPickerInputUIState = pickerEl => {
|
|
74678
75121
|
const pickerInput = getPickerInput(pickerEl);
|
|
74679
75122
|
return getUIStateFromElement(pickerInput);
|
|
@@ -74696,6 +75139,11 @@ const PickerContentInsidePopup = props => {
|
|
|
74696
75139
|
// Same reason: a `data-testid` on the picker names the trigger (see
|
|
74697
75140
|
// docs/testid.md) — this one names the popup.
|
|
74698
75141
|
popupTestId,
|
|
75142
|
+
// Same again for the accessible name: aria-label/aria-labelledby on the
|
|
75143
|
+
// picker name the trigger (see control_context.js), these the popup.
|
|
75144
|
+
popupAriaLabel,
|
|
75145
|
+
popupAriaLabelledBy,
|
|
75146
|
+
popupAriaDescribedBy,
|
|
74699
75147
|
positionArea,
|
|
74700
75148
|
popoverMode = "nearby",
|
|
74701
75149
|
popoverSpacing = popoverMode === "nearby" ? 5 : 0,
|
|
@@ -74757,8 +75205,25 @@ const PickerContentInsidePopup = props => {
|
|
|
74757
75205
|
} = props;
|
|
74758
75206
|
const isPopover = mode === "popover";
|
|
74759
75207
|
const isCallout = mode === "callout";
|
|
74760
|
-
|
|
74761
|
-
|
|
75208
|
+
// The trigger's name, in the order the browser reads it, for the popup to
|
|
75209
|
+
// take when neither the caller nor a <Popup.Title> names it: "Report this
|
|
75210
|
+
// book" is a fair name for the sheet it opens, "Start date" for a calendar.
|
|
75211
|
+
let openerAriaLabelledBy = rest["aria-labelledby"] ?? getPickerHostLabelId(props.id, props);
|
|
75212
|
+
let openerAriaLabel;
|
|
75213
|
+
if (openerAriaLabelledBy === undefined) {
|
|
75214
|
+
openerAriaLabel = rest["aria-label"];
|
|
75215
|
+
// Read only while open: the labels are a question for the document, and
|
|
75216
|
+
// a closed popup has nobody to announce it.
|
|
75217
|
+
if (openerAriaLabel === undefined && rest["aria-expanded"]) {
|
|
75218
|
+
openerAriaLabelledBy = getTriggerLabelIds(props.ref.current);
|
|
75219
|
+
}
|
|
75220
|
+
}
|
|
75221
|
+
return jsx(Next
|
|
75222
|
+
// A dialog in either mode: what a picker opens is content of the
|
|
75223
|
+
// caller's, never a listbox (a selectable List is a group of radios or
|
|
75224
|
+
// checkboxes). The popover says so with its role, below.
|
|
75225
|
+
, {
|
|
75226
|
+
"aria-haspopup": "dialog",
|
|
74762
75227
|
"navi-popover-mode": isPopover ? popoverMode : undefined,
|
|
74763
75228
|
...rest,
|
|
74764
75229
|
// On popupProps already (see the picker's popup assembly); they mean
|
|
@@ -74803,11 +75268,23 @@ const PickerContentInsidePopup = props => {
|
|
|
74803
75268
|
pressOutside: pressOutside,
|
|
74804
75269
|
children: jsx(PopupModeContext.Provider, {
|
|
74805
75270
|
value: mode,
|
|
74806
|
-
children:
|
|
75271
|
+
children: jsx(PopupTitleContext.Provider, {
|
|
75272
|
+
value: null,
|
|
75273
|
+
children: children
|
|
75274
|
+
})
|
|
74807
75275
|
})
|
|
74808
75276
|
}) : jsx(Popup, {
|
|
74809
75277
|
...popupProps,
|
|
74810
75278
|
"data-testid": popupTestId
|
|
75279
|
+
// What the trigger's aria-haspopup announces; a <dialog> says it
|
|
75280
|
+
// for itself.
|
|
75281
|
+
,
|
|
75282
|
+
role: isPopover ? "dialog" : undefined,
|
|
75283
|
+
"aria-label": popupAriaLabel,
|
|
75284
|
+
"aria-labelledby": popupAriaLabelledBy,
|
|
75285
|
+
"aria-describedby": popupAriaDescribedBy,
|
|
75286
|
+
openerAriaLabel: openerAriaLabel,
|
|
75287
|
+
openerAriaLabelledBy: openerAriaLabelledBy
|
|
74811
75288
|
// What the CSS above keys on: this picker's own popup, and no other
|
|
74812
75289
|
// popup below the picker.
|
|
74813
75290
|
,
|
|
@@ -75077,7 +75554,7 @@ const showNativePicker = (pickerInput, event) => {
|
|
|
75077
75554
|
};
|
|
75078
75555
|
|
|
75079
75556
|
installImportMetaCssBuild(import.meta);
|
|
75080
|
-
const css$
|
|
75557
|
+
const css$y = /* css */`.navi_picker_confirm_body {
|
|
75081
75558
|
min-width: 180px;
|
|
75082
75559
|
max-width: 320px;
|
|
75083
75560
|
padding: var(--navi-m);
|
|
@@ -75093,7 +75570,7 @@ const css$A = /* css */`.navi_picker_confirm_body {
|
|
|
75093
75570
|
}
|
|
75094
75571
|
`;
|
|
75095
75572
|
const PickerConfirmResolver = props => {
|
|
75096
|
-
import.meta.css = [css$
|
|
75573
|
+
import.meta.css = [css$y, "@jsenv/navi/src/control/picker/picker_confirm.jsx"];
|
|
75097
75574
|
const Next = useNextResolver();
|
|
75098
75575
|
if (props.type !== "confirm") {
|
|
75099
75576
|
return jsx(Next, {
|
|
@@ -75167,12 +75644,7 @@ const PickerConfirmResolver = props => {
|
|
|
75167
75644
|
mode: mode,
|
|
75168
75645
|
focusCapture: focusCapture,
|
|
75169
75646
|
openWhileReadOnly: openWhileReadOnly,
|
|
75170
|
-
onConfirm: onConfirm
|
|
75171
|
-
// A question holds no value to read before it is asked: the popup is
|
|
75172
|
-
// built on the first open, like that of a picker told its value (see
|
|
75173
|
-
// the `mount` resolution in picker_custom.jsx).
|
|
75174
|
-
,
|
|
75175
|
-
mount: MOUNT_DEFAULT,
|
|
75647
|
+
onConfirm: onConfirm,
|
|
75176
75648
|
message: undefined,
|
|
75177
75649
|
confirmLabel: undefined,
|
|
75178
75650
|
cancelLabel: undefined,
|
|
@@ -75619,7 +76091,7 @@ const LoadingIndicator = ({
|
|
|
75619
76091
|
};
|
|
75620
76092
|
|
|
75621
76093
|
installImportMetaCssBuild(import.meta);
|
|
75622
|
-
const css$
|
|
76094
|
+
const css$x = /* css */`@layer navi {
|
|
75623
76095
|
.navi_separator {
|
|
75624
76096
|
--size: 1px;
|
|
75625
76097
|
--color: var(--navi-separator-color-default);
|
|
@@ -75693,7 +76165,7 @@ const Separator = ({
|
|
|
75693
76165
|
style,
|
|
75694
76166
|
...props
|
|
75695
76167
|
}) => {
|
|
75696
|
-
import.meta.css = [css$
|
|
76168
|
+
import.meta.css = [css$x, "@jsenv/navi/src/layout/separator.jsx"];
|
|
75697
76169
|
return jsx(Box, {
|
|
75698
76170
|
as: vertical ? "span" : "hr",
|
|
75699
76171
|
...props,
|
|
@@ -76487,7 +76959,7 @@ const listItemBlockedMessage = (loading, props) => {
|
|
|
76487
76959
|
};
|
|
76488
76960
|
|
|
76489
76961
|
installImportMetaCssBuild(import.meta);
|
|
76490
|
-
const css$
|
|
76962
|
+
const css$w = /* css */`@layer navi {
|
|
76491
76963
|
.navi_list_container[navi-selectable] {
|
|
76492
76964
|
--list-item-outline-width: var(--navi-focus-outline-width);
|
|
76493
76965
|
--list-item-outline-offset: calc(-1 * var(--list-item-outline-width));
|
|
@@ -76660,7 +77132,7 @@ const ListSelectableResolver = props => {
|
|
|
76660
77132
|
};
|
|
76661
77133
|
const ListSelectable = props => {
|
|
76662
77134
|
const Next = useNextResolver();
|
|
76663
|
-
import.meta.css = [css$
|
|
77135
|
+
import.meta.css = [css$w, "@jsenv/navi/src/control/list/list_selectable.jsx"];
|
|
76664
77136
|
// we allow ourselves to auto-generate a name
|
|
76665
77137
|
const defaultName = useId();
|
|
76666
77138
|
props.name = props.name || `listbox_${defaultName}`;
|
|
@@ -77329,7 +77801,7 @@ const ListRunItemContext = createContext(null);
|
|
|
77329
77801
|
// item takes its place in the collection by slot: the place is then the list's
|
|
77330
77802
|
// to move, and the item's to follow — see list_items.js.
|
|
77331
77803
|
const ListSlotContext = createContext(null);
|
|
77332
|
-
const css$
|
|
77804
|
+
const css$v = /* css */`@property --list-group-label-height {
|
|
77333
77805
|
syntax: "<length>";
|
|
77334
77806
|
inherits: false;
|
|
77335
77807
|
initial-value: 0;
|
|
@@ -77857,7 +78329,7 @@ const resolveRenderBudget = renderBudget => {
|
|
|
77857
78329
|
};
|
|
77858
78330
|
};
|
|
77859
78331
|
const ListUI = props => {
|
|
77860
|
-
import.meta.css = [css$
|
|
78332
|
+
import.meta.css = [css$v, "@jsenv/navi/src/control/list/list.jsx"];
|
|
77861
78333
|
const {
|
|
77862
78334
|
ref,
|
|
77863
78335
|
renderBudget: renderBudgetProp,
|
|
@@ -84147,7 +84619,7 @@ const createBadgeRegistry = () => {
|
|
|
84147
84619
|
};
|
|
84148
84620
|
|
|
84149
84621
|
installImportMetaCssBuild(import.meta);
|
|
84150
|
-
const css$
|
|
84622
|
+
const css$u = /* css */`@layer navi;
|
|
84151
84623
|
|
|
84152
84624
|
.navi_badge {
|
|
84153
84625
|
--font-size: .7em;
|
|
@@ -84250,7 +84722,7 @@ const BadgeUI = ({
|
|
|
84250
84722
|
className,
|
|
84251
84723
|
...props
|
|
84252
84724
|
}) => {
|
|
84253
|
-
import.meta.css = [css$
|
|
84725
|
+
import.meta.css = [css$u, "@jsenv/navi/src/text/badge.jsx"];
|
|
84254
84726
|
const defaultRef = useRef();
|
|
84255
84727
|
props.ref = props.ref || defaultRef;
|
|
84256
84728
|
const {
|
|
@@ -84358,7 +84830,7 @@ const wrapLabels = childArray => {
|
|
|
84358
84830
|
};
|
|
84359
84831
|
|
|
84360
84832
|
installImportMetaCssBuild(import.meta);
|
|
84361
|
-
const css$
|
|
84833
|
+
const css$t = /* css */`@layer navi;
|
|
84362
84834
|
|
|
84363
84835
|
.navi_badge_list {
|
|
84364
84836
|
flex-wrap: wrap;
|
|
@@ -84493,7 +84965,7 @@ const useBadgeRegistry = (children, enabled) => {
|
|
|
84493
84965
|
* component grants (a <Picker>, see max_lines_context.js).
|
|
84494
84966
|
*/
|
|
84495
84967
|
const BadgeList = props => {
|
|
84496
|
-
import.meta.css = [css$
|
|
84968
|
+
import.meta.css = [css$t, "@jsenv/navi/src/text/badge_list.jsx"];
|
|
84497
84969
|
const {
|
|
84498
84970
|
maxLines,
|
|
84499
84971
|
max,
|
|
@@ -84837,7 +85309,7 @@ const BadgeListContent = ({
|
|
|
84837
85309
|
};
|
|
84838
85310
|
|
|
84839
85311
|
installImportMetaCssBuild(import.meta);
|
|
84840
|
-
const css$
|
|
85312
|
+
const css$s = /* css */`.navi_color {
|
|
84841
85313
|
aspect-ratio: 1;
|
|
84842
85314
|
background-color: currentColor;
|
|
84843
85315
|
border: 1px solid #0003;
|
|
@@ -84857,7 +85329,7 @@ const Color = ({
|
|
|
84857
85329
|
children,
|
|
84858
85330
|
...rest
|
|
84859
85331
|
}) => {
|
|
84860
|
-
import.meta.css = [css$
|
|
85332
|
+
import.meta.css = [css$s, "@jsenv/navi/src/text/color.jsx"];
|
|
84861
85333
|
const color = children || undefined;
|
|
84862
85334
|
return jsx(Box, {
|
|
84863
85335
|
as: "span",
|
|
@@ -85344,7 +85816,7 @@ const PickerFileUI = /*#__PURE__*/asPickerOwnUI(() => {
|
|
|
85344
85816
|
});
|
|
85345
85817
|
|
|
85346
85818
|
installImportMetaCssBuild(import.meta);
|
|
85347
|
-
const css$
|
|
85819
|
+
const css$r = /* css */`@layer navi {
|
|
85348
85820
|
.navi_picker {
|
|
85349
85821
|
--picker-border-radius: var(--navi-control-border-radius);
|
|
85350
85822
|
--picker-border-width: var(--navi-control-border-width);
|
|
@@ -85813,7 +86285,7 @@ const css$t = /* css */`@layer navi {
|
|
|
85813
86285
|
}
|
|
85814
86286
|
`;
|
|
85815
86287
|
const PickerButton = props => {
|
|
85816
|
-
import.meta.css = [css$
|
|
86288
|
+
import.meta.css = [css$r, "@jsenv/navi/src/control/picker/picker.jsx"];
|
|
85817
86289
|
warnOnUnknownPickerType(props);
|
|
85818
86290
|
warnOnUIDrawnByNobody(props);
|
|
85819
86291
|
if (typeof props.maxLines === "string") {
|
|
@@ -85856,11 +86328,6 @@ const PickerButton = props => {
|
|
|
85856
86328
|
// confirm resolver (see picker_confirm.jsx), which is the picker that is
|
|
85857
86329
|
// one — a caller whose popup is a menu of actions says it for themselves.
|
|
85858
86330
|
picksNothing,
|
|
85859
|
-
// Where the caller's own role goes: onto the host, beside the name (see
|
|
85860
|
-
// control_context.js) — a role and a name on two different elements name
|
|
85861
|
-
// nothing at all. Left unsaid, a picker that picks nothing takes "button"
|
|
85862
|
-
// (see PickerInput below).
|
|
85863
|
-
role,
|
|
85864
86331
|
readOnly,
|
|
85865
86332
|
error,
|
|
85866
86333
|
// Who draws the loading outline. Left unsaid, the picker does, around its
|
|
@@ -85943,21 +86410,8 @@ const PickerButton = props => {
|
|
|
85943
86410
|
// clearing being a modification like any other.
|
|
85944
86411
|
const interactive = !basePseudoState[":disabled"] && !basePseudoState[":read-only"] && !loading;
|
|
85945
86412
|
usePickerErrorCallout(uiStateController, error);
|
|
85946
|
-
|
|
85947
|
-
|
|
85948
|
-
// door — its popup is a question (type="confirm") or something to read
|
|
85949
|
-
// (mode="callout", which says it for itself) — and a door is pressed. So it
|
|
85950
|
-
// answers to "button" rather than to the "textbox" its <input> would
|
|
85951
|
-
// otherwise be, which is both what a screen reader announces and what
|
|
85952
|
-
// getByRole("button", { name }) finds. A picker holding a value stays a
|
|
85953
|
-
// textbox: it does hold text.
|
|
85954
|
-
const hostRole = role ?? (picksNothing ? "button" : undefined);
|
|
85955
|
-
// And what that button is called, when the caller wrote it as a drawing
|
|
85956
|
-
// rather than as a word: a door draws no value, so what sits in its value
|
|
85957
|
-
// slot IS its label — the `ui` a caller gave it, or its placeholder. Skipped
|
|
85958
|
-
// the moment the caller names it themselves (aria-label/aria-labelledby),
|
|
85959
|
-
// which is the only way to name a door drawn as an icon.
|
|
85960
|
-
const hostLabelId = hostRole === "button" && inputProps["aria-label"] === undefined && inputProps["aria-labelledby"] === undefined && variant !== "headless" && ui !== "default" ? `${inputProps.id}_picker_label` : undefined;
|
|
86413
|
+
const hostRole = getPickerHostRole(props);
|
|
86414
|
+
const hostLabelId = getPickerHostLabelId(inputProps.id, props);
|
|
85961
86415
|
// What the picker knows about itself, for the pieces it does not place: the
|
|
85962
86416
|
// drawings of its value (Picker.UI.*), and the affordances a caller may put
|
|
85963
86417
|
// in their own `ui` (Picker.Clear) as much as the ones it puts in its slot.
|
|
@@ -86026,8 +86480,16 @@ const PickerButton = props => {
|
|
|
86026
86480
|
basePseudoState: basePseudoState,
|
|
86027
86481
|
styleCSSVars: PickerStyleCSSVars,
|
|
86028
86482
|
variant: undefined,
|
|
86029
|
-
icon: undefined
|
|
86483
|
+
icon: undefined
|
|
86484
|
+
// The caller's own role goes onto the host, beside the name (see
|
|
86485
|
+
// control_context.js): a role and a name on two different elements
|
|
86486
|
+
// name nothing at all. What the trigger opens is said there too, and
|
|
86487
|
+
// aria-haspopup with it. aria-expanded stays here as well: commands.js
|
|
86488
|
+
// and the CSS read the open state off the root (see
|
|
86489
|
+
// expandableRepeatedBy in commands.js).
|
|
86490
|
+
,
|
|
86030
86491
|
role: undefined,
|
|
86492
|
+
"aria-haspopup": undefined,
|
|
86031
86493
|
rightSlotIcon: undefined,
|
|
86032
86494
|
rightSlotIconSize: undefined,
|
|
86033
86495
|
rightSlot: undefined,
|
|
@@ -86067,6 +86529,8 @@ const PickerButton = props => {
|
|
|
86067
86529
|
inset: loadingOutlineInset
|
|
86068
86530
|
}), jsx(PickerInput, {
|
|
86069
86531
|
role: hostRole,
|
|
86532
|
+
"aria-haspopup": props["aria-haspopup"],
|
|
86533
|
+
"aria-expanded": props["aria-expanded"],
|
|
86070
86534
|
"aria-labelledby": hostLabelId,
|
|
86071
86535
|
tabIndex: variant === "headless" ? -1 : undefined,
|
|
86072
86536
|
"aria-hidden": variant === "headless" ? "true" : undefined,
|
|
@@ -86574,6 +87038,10 @@ const PickerFirstResolver = props => {
|
|
|
86574
87038
|
* Without `children`, opens the browser-native picker for the given `type`.
|
|
86575
87039
|
* With `children`, opens a popover (desktop) or dialog (mobile) containing the children.
|
|
86576
87040
|
* Pass `mode="popover"` or `mode="dialog"` to override the automatic choice.
|
|
87041
|
+
* Either way the popup is a `dialog`, named by a `<Popup.Title>` in the
|
|
87042
|
+
* children (see `popupAriaLabelledBy`), and the trigger answers to `combobox` —
|
|
87043
|
+
* `button` under `picksNothing` — with `aria-haspopup="dialog"` and
|
|
87044
|
+
* `aria-expanded` (see docs/testid.md).
|
|
86577
87045
|
*
|
|
86578
87046
|
* `type="confirm"` is the picker that asks "are you sure?" before doing what it
|
|
86579
87047
|
* stands for: its popup is the question, `ui` its label, and yes runs its
|
|
@@ -86647,6 +87115,9 @@ const PickerFirstResolver = props => {
|
|
|
86647
87115
|
* standalone?: boolean,
|
|
86648
87116
|
* popupLayer?: "top" | "local",
|
|
86649
87117
|
* popupTestId?: string,
|
|
87118
|
+
* popupAriaLabel?: string,
|
|
87119
|
+
* popupAriaLabelledBy?: string,
|
|
87120
|
+
* popupAriaDescribedBy?: string,
|
|
86650
87121
|
* confirmTestId?: string,
|
|
86651
87122
|
* cancelTestId?: string,
|
|
86652
87123
|
* mount?: "always" | "idle" | "from-first-open" | "while-opened",
|
|
@@ -87106,6 +87577,19 @@ const PickerFirstResolver = props => {
|
|
|
87106
87577
|
* not only what it holds, which a testid inside the children already names.
|
|
87107
87578
|
* Under `mode="callout"` it names the callout element — the control's own,
|
|
87108
87579
|
* shared with its constraint messages — while the children are shown in it.
|
|
87580
|
+
* @param {string} [popupAriaLabelledBy] The id(s) of what names the popup:
|
|
87581
|
+
* `aria-labelledby` on the popup element, which is a dialog in either mode
|
|
87582
|
+
* (the trigger says `aria-haspopup="dialog"`). `aria-label`/`aria-labelledby`
|
|
87583
|
+
* on the picker itself name the trigger. Rarely needed: a `<Popup.Title>`
|
|
87584
|
+
* in the children names the popup with nothing to wire, and without one
|
|
87585
|
+
* the popup takes the trigger's own name — the picker's `aria-labelledby`,
|
|
87586
|
+
* the label a picker that picks nothing draws, its `aria-label`, or the
|
|
87587
|
+
* `<Label>`/`<label for>` pointing at it (one that has an id, and does not
|
|
87588
|
+
* wrap the picker). A `mode="callout"` popup is read as its message.
|
|
87589
|
+
* @param {string} [popupAriaLabel] The same, as a string, for a popup whose
|
|
87590
|
+
* title is not an element.
|
|
87591
|
+
* @param {string} [popupAriaDescribedBy] The id(s) of what describes the
|
|
87592
|
+
* popup: `aria-describedby` on the popup element.
|
|
87109
87593
|
* @param {string} [confirmTestId] `type="confirm"`, default body: the
|
|
87110
87594
|
* `data-testid` of the yes button; `cancelTestId` that of the no button.
|
|
87111
87595
|
* Both are elements navi builds, which a test may not name by class (see
|
|
@@ -87118,8 +87602,9 @@ const PickerFirstResolver = props => {
|
|
|
87118
87602
|
* it (no `ui`, a `Picker.UI.*`, a component `ui`), when there is a clear
|
|
87119
87603
|
* cross, or when a form or group around the picker collects it; when an
|
|
87120
87604
|
* element `ui` calls `usePickerState()`. Read by nothing, it waits for the
|
|
87121
|
-
* first open, like a picker told a value. A `
|
|
87122
|
-
* builds them early: its popup
|
|
87605
|
+
* first open, like a picker told a value. A `picksNothing` picker (and so
|
|
87606
|
+
* `type="confirm"`) never builds them early: its popup holds no value, there
|
|
87607
|
+
* is nothing to read.
|
|
87123
87608
|
*/
|
|
87124
87609
|
// Every picker type is resolved into one of these before it gets here (see
|
|
87125
87610
|
// PickerTypeResolver and resolveInputProps): a native input type, or navi_js
|
|
@@ -87243,7 +87728,7 @@ const Picker = /*#__PURE__*/Object.assign(PickerResolved, {
|
|
|
87243
87728
|
});
|
|
87244
87729
|
|
|
87245
87730
|
installImportMetaCssBuild(import.meta);
|
|
87246
|
-
const css$
|
|
87731
|
+
const css$q = /* css */`@layer navi {
|
|
87247
87732
|
.navi_picker_spin {
|
|
87248
87733
|
--picker-spin-padding-x-default: var(--navi-picker-padding-x-default);
|
|
87249
87734
|
--picker-spin-padding-y-default: var(--navi-picker-padding-y-default);
|
|
@@ -87593,7 +88078,7 @@ const Spin = ({
|
|
|
87593
88078
|
nextLabel,
|
|
87594
88079
|
...rest
|
|
87595
88080
|
}) => {
|
|
87596
|
-
import.meta.css = [css$
|
|
88081
|
+
import.meta.css = [css$q, "@jsenv/navi/src/control/picker/picker_spin.jsx"];
|
|
87597
88082
|
const id = useId();
|
|
87598
88083
|
// What the group around it says, when there is one: how big the whole thing
|
|
87599
88084
|
// is written is said once, on the group, and every spin in it follows.
|
|
@@ -88304,7 +88789,7 @@ const renderValueDefault = value => String(value ?? "");
|
|
|
88304
88789
|
* are passed on to the spins sitting in them.
|
|
88305
88790
|
*/
|
|
88306
88791
|
const SpinGroup = props => {
|
|
88307
|
-
import.meta.css = [css$
|
|
88792
|
+
import.meta.css = [css$q, "@jsenv/navi/src/control/picker/picker_spin.jsx"];
|
|
88308
88793
|
const {
|
|
88309
88794
|
size
|
|
88310
88795
|
} = props;
|
|
@@ -88813,7 +89298,7 @@ const TimeRangeSpin = ({
|
|
|
88813
89298
|
};
|
|
88814
89299
|
|
|
88815
89300
|
installImportMetaCssBuild(import.meta);
|
|
88816
|
-
const css$
|
|
89301
|
+
const css$p = /* css */`.navi_checkbox_group {
|
|
88817
89302
|
border-style: solid;
|
|
88818
89303
|
|
|
88819
89304
|
&[data-callout] {
|
|
@@ -88873,7 +89358,7 @@ const CheckboxGroup = props => {
|
|
|
88873
89358
|
return checkboxGroup;
|
|
88874
89359
|
};
|
|
88875
89360
|
const CheckboxGroupInterface = props => {
|
|
88876
|
-
import.meta.css = [css$
|
|
89361
|
+
import.meta.css = [css$p, "@jsenv/navi/src/control/input/checkbox_group.jsx"];
|
|
88877
89362
|
const {
|
|
88878
89363
|
ref
|
|
88879
89364
|
} = props;
|
|
@@ -88991,7 +89476,7 @@ const formatIntlUnit = (unit, {
|
|
|
88991
89476
|
};
|
|
88992
89477
|
|
|
88993
89478
|
installImportMetaCssBuild(import.meta);
|
|
88994
|
-
const css$
|
|
89479
|
+
const css$o = /* css */`.navi_input_duration {
|
|
88995
89480
|
--duration-separator-spacing: 4px;
|
|
88996
89481
|
--loader-color: var(--navi-loader-color);
|
|
88997
89482
|
position: relative;
|
|
@@ -89056,7 +89541,7 @@ const css$q = /* css */`.navi_input_duration {
|
|
|
89056
89541
|
* "auto" aligns each field toward its neighbouring separator (first→right, last→left, middle/solo→center).
|
|
89057
89542
|
*/
|
|
89058
89543
|
const InputDuration = props => {
|
|
89059
|
-
import.meta.css = [css$
|
|
89544
|
+
import.meta.css = [css$o, "@jsenv/navi/src/control/input/input_duration.jsx"];
|
|
89060
89545
|
const defaultRef = useRef();
|
|
89061
89546
|
props.ref = props.ref || defaultRef;
|
|
89062
89547
|
props.max = props.max || "23h59";
|
|
@@ -89557,7 +90042,7 @@ const InputDurationPart = ({
|
|
|
89557
90042
|
};
|
|
89558
90043
|
|
|
89559
90044
|
installImportMetaCssBuild(import.meta);
|
|
89560
|
-
const css$
|
|
90045
|
+
const css$n = /* css */`.navi_radio_group {
|
|
89561
90046
|
border-style: solid;
|
|
89562
90047
|
|
|
89563
90048
|
&[data-callout] {
|
|
@@ -89597,7 +90082,7 @@ const RadioGroup = props => {
|
|
|
89597
90082
|
return radioGroup;
|
|
89598
90083
|
};
|
|
89599
90084
|
const RadioGroupInterface = props => {
|
|
89600
|
-
import.meta.css = [css$
|
|
90085
|
+
import.meta.css = [css$n, "@jsenv/navi/src/control/input/radio_group.jsx"];
|
|
89601
90086
|
const {
|
|
89602
90087
|
ref
|
|
89603
90088
|
} = props;
|
|
@@ -89627,7 +90112,7 @@ const RadioGroupInterface = props => {
|
|
|
89627
90112
|
};
|
|
89628
90113
|
|
|
89629
90114
|
installImportMetaCssBuild(import.meta);
|
|
89630
|
-
const css$
|
|
90115
|
+
const css$m = /* css */`.navi_input.navi_select {
|
|
89631
90116
|
& .navi_control_input {
|
|
89632
90117
|
padding-right: calc(var(--x-padding-right) + 1em);
|
|
89633
90118
|
line-height: var(--navi-control-line-height);
|
|
@@ -89674,7 +90159,7 @@ const Select = ({
|
|
|
89674
90159
|
...props
|
|
89675
90160
|
}) => {
|
|
89676
90161
|
installInputCss();
|
|
89677
|
-
import.meta.css = [css$
|
|
90162
|
+
import.meta.css = [css$m, "@jsenv/navi/src/control/input/select.jsx"];
|
|
89678
90163
|
const defaultRef = useRef(null);
|
|
89679
90164
|
props.ref = props.ref || defaultRef;
|
|
89680
90165
|
seedDefaultValueFromSignal(props);
|
|
@@ -89727,7 +90212,7 @@ const Select = ({
|
|
|
89727
90212
|
};
|
|
89728
90213
|
|
|
89729
90214
|
installImportMetaCssBuild(import.meta);
|
|
89730
|
-
const css$
|
|
90215
|
+
const css$l = /* css */`.navi_split_button {
|
|
89731
90216
|
border-radius: var(--navi-control-border-radius);
|
|
89732
90217
|
display: inline-flex;
|
|
89733
90218
|
position: relative;
|
|
@@ -89849,7 +90334,7 @@ const css$n = /* css */`.navi_split_button {
|
|
|
89849
90334
|
* on the split button's own box.
|
|
89850
90335
|
*/
|
|
89851
90336
|
const SplitButton = props => {
|
|
89852
|
-
import.meta.css = [css$
|
|
90337
|
+
import.meta.css = [css$l, "@jsenv/navi/src/control/input/split_button.jsx"];
|
|
89853
90338
|
const {
|
|
89854
90339
|
options = [],
|
|
89855
90340
|
value,
|
|
@@ -90868,7 +91353,7 @@ const createItemTracker = (onChange) => {
|
|
|
90868
91353
|
};
|
|
90869
91354
|
|
|
90870
91355
|
installImportMetaCssBuild(import.meta);
|
|
90871
|
-
const css$
|
|
91356
|
+
const css$k = /* css */`.navi_wheel_container {
|
|
90872
91357
|
--wheel-item-height: round(1.8em, 1px);
|
|
90873
91358
|
--wheel-emphasis-size: round(1.5em, 1px);
|
|
90874
91359
|
--wheel-item-width: 3.5ch;
|
|
@@ -91817,7 +92302,7 @@ const useWheelKeyboard = ({
|
|
|
91817
92302
|
}, [isHorizontal, interactive, isLoop]);
|
|
91818
92303
|
};
|
|
91819
92304
|
function WheelUI(props) {
|
|
91820
|
-
import.meta.css = [css$
|
|
92305
|
+
import.meta.css = [css$k, "@jsenv/navi/src/control/wheel/wheel.jsx"];
|
|
91821
92306
|
const {
|
|
91822
92307
|
ref,
|
|
91823
92308
|
visibleCount = 3,
|
|
@@ -92814,7 +93299,7 @@ Wheel.Item = WheelItem;
|
|
|
92814
93299
|
* @param {boolean|number} [props.zoom] - Enlarge the centered value of every wheel (see Wheel's zoom prop) with one prop for the whole group.
|
|
92815
93300
|
*/
|
|
92816
93301
|
const WheelGroup = props => {
|
|
92817
|
-
import.meta.css = [css$
|
|
93302
|
+
import.meta.css = [css$k, "@jsenv/navi/src/control/wheel/wheel.jsx"];
|
|
92818
93303
|
// WheelGroup IS a control group: it aggregates its named wheels ("hours",
|
|
92819
93304
|
// "minutes"…) into one object value, so it can sit directly inside a Form or a
|
|
92820
93305
|
// Picker with no extra <ControlGroup> wrapper. The wheel-specific presentation
|
|
@@ -92987,7 +93472,7 @@ const WheelColon = props => {
|
|
|
92987
93472
|
Wheel.Colon = WheelColon;
|
|
92988
93473
|
|
|
92989
93474
|
installImportMetaCssBuild(import.meta);
|
|
92990
|
-
const css$
|
|
93475
|
+
const css$j = /* css */`.navi_time_range_label {
|
|
92991
93476
|
--wheel-item-height: round(1.8em, 1px);
|
|
92992
93477
|
color: var(--wheel-color, light-dark(#111, #eee));
|
|
92993
93478
|
line-height: var(--wheel-item-height);
|
|
@@ -93211,7 +93696,7 @@ const TimeRangeWheel = ({
|
|
|
93211
93696
|
endTimeProps,
|
|
93212
93697
|
...rest
|
|
93213
93698
|
}) => {
|
|
93214
|
-
import.meta.css = [css$
|
|
93699
|
+
import.meta.css = [css$j, "@jsenv/navi/src/control/wheel/wheel_time.jsx"];
|
|
93215
93700
|
const startId = useId();
|
|
93216
93701
|
const startRef = useRef(null);
|
|
93217
93702
|
const endRef = useRef(null);
|
|
@@ -93799,7 +94284,7 @@ const Z_INDEX_DROP_PREVIEW = Z_INDEX_STICKY_CORNER + 1;
|
|
|
93799
94284
|
const Z_INDEX_TABLE_UI = Z_INDEX_STICKY_CORNER + 1;
|
|
93800
94285
|
|
|
93801
94286
|
installImportMetaCssBuild(import.meta);
|
|
93802
|
-
const css$
|
|
94287
|
+
const css$i = /* css */`.navi_table_drag_clone_container {
|
|
93803
94288
|
top: var(--table-visual-top);
|
|
93804
94289
|
left: var(--table-visual-left);
|
|
93805
94290
|
width: var(--table-visual-width);
|
|
@@ -93954,7 +94439,7 @@ const useTableDragContextValue = ({
|
|
|
93954
94439
|
}, [grabTarget, canChangeColumnOrder]);
|
|
93955
94440
|
};
|
|
93956
94441
|
const TableDragCloneContainer = /*#__PURE__*/forwardRef((props, ref) => {
|
|
93957
|
-
import.meta.css = [css$
|
|
94442
|
+
import.meta.css = [css$i, "@jsenv/navi/src/control/table/drag/table_drag.jsx"];
|
|
93958
94443
|
const {
|
|
93959
94444
|
tableId
|
|
93960
94445
|
} = props;
|
|
@@ -94253,7 +94738,7 @@ const ROW_MIN_HEIGHT = 30;
|
|
|
94253
94738
|
const ROW_MAX_HEIGHT = 100;
|
|
94254
94739
|
const COLUMN_MIN_WIDTH = 50;
|
|
94255
94740
|
const COLUMN_MAX_WIDTH = 500;
|
|
94256
|
-
const css$
|
|
94741
|
+
const css$h = /* css */`@layer navi {
|
|
94257
94742
|
.navi_table {
|
|
94258
94743
|
--table-resizer-handle-color: #063b7c;
|
|
94259
94744
|
--table-resizer-color: #387ec9;
|
|
@@ -94422,7 +94907,7 @@ const css$j = /* css */`@layer navi {
|
|
|
94422
94907
|
|
|
94423
94908
|
// Column resize components
|
|
94424
94909
|
const TableColumnResizer = props => {
|
|
94425
|
-
import.meta.css = [css$
|
|
94910
|
+
import.meta.css = [css$h, "@jsenv/navi/src/control/table/resize/table_resize.jsx"];
|
|
94426
94911
|
const defaultRef = useRef();
|
|
94427
94912
|
const ref = props.ref || defaultRef;
|
|
94428
94913
|
return jsxs("div", {
|
|
@@ -94894,7 +95379,7 @@ const findPreviousTableRow = currentRow => {
|
|
|
94894
95379
|
};
|
|
94895
95380
|
|
|
94896
95381
|
installImportMetaCssBuild(import.meta);
|
|
94897
|
-
const css$
|
|
95382
|
+
const css$g = /* css */`@layer navi {
|
|
94898
95383
|
.navi_table {
|
|
94899
95384
|
--selection-border-color: var(--navi-selection-border-color, #0078d4);
|
|
94900
95385
|
--selection-background-color: var(--navi-selection-background-color, #eaf1fd);
|
|
@@ -94988,7 +95473,7 @@ const useTableSelectionController = ({
|
|
|
94988
95473
|
onSelectionChange,
|
|
94989
95474
|
selectionColor
|
|
94990
95475
|
}) => {
|
|
94991
|
-
import.meta.css = [css$
|
|
95476
|
+
import.meta.css = [css$g, "@jsenv/navi/src/control/table/selection/table_selection.jsx"];
|
|
94992
95477
|
const selectionController = useSelectionController({
|
|
94993
95478
|
elementRef: tableRef,
|
|
94994
95479
|
layout: "grid",
|
|
@@ -95459,7 +95944,7 @@ const useTableStickyContextValue = ({
|
|
|
95459
95944
|
};
|
|
95460
95945
|
|
|
95461
95946
|
installImportMetaCssBuild(import.meta);
|
|
95462
|
-
const css$
|
|
95947
|
+
const css$f = /* css */`@layer navi {
|
|
95463
95948
|
.navi_table {
|
|
95464
95949
|
--sticky-frontier-color: silver;
|
|
95465
95950
|
--sticky-frontier-size: 12px;
|
|
@@ -95632,7 +96117,7 @@ const css$h = /* css */`@layer navi {
|
|
|
95632
96117
|
const TableStickyFrontier = ({
|
|
95633
96118
|
tableRef
|
|
95634
96119
|
}) => {
|
|
95635
|
-
import.meta.css = [css$
|
|
96120
|
+
import.meta.css = [css$f, "@jsenv/navi/src/control/table/sticky/table_sticky.jsx"];
|
|
95636
96121
|
const stickyLeftFrontierGhostRef = useRef();
|
|
95637
96122
|
const stickyLeftFrontierPreviewRef = useRef();
|
|
95638
96123
|
const stickyTopFrontierGhostRef = useRef();
|
|
@@ -95863,7 +96348,7 @@ installImportMetaCssBuild(import.meta);
|
|
|
95863
96348
|
* inset 0 -1px 0 0 color; // Bottom border
|
|
95864
96349
|
*/
|
|
95865
96350
|
|
|
95866
|
-
const css$
|
|
96351
|
+
const css$e = /* css */ `.navi_table_root {
|
|
95867
96352
|
max-width: var(--table-max-width, none);
|
|
95868
96353
|
max-height: var(--table-max-height, none);
|
|
95869
96354
|
position: relative;
|
|
@@ -96048,11 +96533,11 @@ const css$g = /* css */ `.navi_table_root {
|
|
|
96048
96533
|
// table must not carry this sheet, and a build that sees no caller drops the
|
|
96049
96534
|
// css with the function.
|
|
96050
96535
|
const installTableCss = () => {
|
|
96051
|
-
import.meta.css = [css$
|
|
96536
|
+
import.meta.css = [css$e, "@jsenv/navi/src/control/table/table_css.js"];
|
|
96052
96537
|
};
|
|
96053
96538
|
|
|
96054
96539
|
installImportMetaCssBuild(import.meta);
|
|
96055
|
-
const css$
|
|
96540
|
+
const css$d = /* css */`.navi_table_ui {
|
|
96056
96541
|
z-index: ${Z_INDEX_TABLE_UI};
|
|
96057
96542
|
pointer-events: none;
|
|
96058
96543
|
position: fixed;
|
|
@@ -96061,7 +96546,7 @@ const css$f = /* css */`.navi_table_ui {
|
|
|
96061
96546
|
}
|
|
96062
96547
|
`;
|
|
96063
96548
|
const TableUI = /*#__PURE__*/forwardRef((props, ref) => {
|
|
96064
|
-
import.meta.css = [css$
|
|
96549
|
+
import.meta.css = [css$d, "@jsenv/navi/src/control/table/table_ui.jsx"];
|
|
96065
96550
|
const {
|
|
96066
96551
|
tableRef,
|
|
96067
96552
|
tableId,
|
|
@@ -96983,7 +97468,7 @@ const normalizeKey = (key) => {
|
|
|
96983
97468
|
};
|
|
96984
97469
|
|
|
96985
97470
|
installImportMetaCssBuild(import.meta);
|
|
96986
|
-
const css$
|
|
97471
|
+
const css$c = /* css */`.navi_shortcut_container[data-visually-hidden], .navi_shortcut_button[data-visually-hidden] {
|
|
96987
97472
|
clip: rect(0, 0, 0, 0);
|
|
96988
97473
|
white-space: nowrap;
|
|
96989
97474
|
opacity: 0;
|
|
@@ -97000,7 +97485,7 @@ const css$e = /* css */`.navi_shortcut_container[data-visually-hidden], .navi_sh
|
|
|
97000
97485
|
const ActiveKeyboardShortcuts = ({
|
|
97001
97486
|
visible
|
|
97002
97487
|
}) => {
|
|
97003
|
-
import.meta.css = [css$
|
|
97488
|
+
import.meta.css = [css$c, "@jsenv/navi/src/keyboard/active_keyboard_shortcuts.jsx"];
|
|
97004
97489
|
const activeShortcuts = activeShortcutsSignal.value;
|
|
97005
97490
|
return jsx("div", {
|
|
97006
97491
|
className: "navi_shortcut_container",
|
|
@@ -97040,7 +97525,7 @@ const KeyboardShortcutAriaElement = ({
|
|
|
97040
97525
|
};
|
|
97041
97526
|
|
|
97042
97527
|
installImportMetaCssBuild(import.meta);
|
|
97043
|
-
const css$
|
|
97528
|
+
const css$b = /* css */`@layer navi {
|
|
97044
97529
|
.navi_clipboard_container {
|
|
97045
97530
|
--height: 1.5em;
|
|
97046
97531
|
--notif-spacing: .5em;
|
|
@@ -97071,7 +97556,7 @@ const ButtonCopyToClipboard = ({
|
|
|
97071
97556
|
children,
|
|
97072
97557
|
...props
|
|
97073
97558
|
}) => {
|
|
97074
|
-
import.meta.css = [css$
|
|
97559
|
+
import.meta.css = [css$b, "@jsenv/navi/src/control/input/button_copy_to_clipboard.jsx"];
|
|
97075
97560
|
const [copied, setCopied] = useState(false);
|
|
97076
97561
|
const renderedRef = useRef();
|
|
97077
97562
|
useEffect(() => {
|
|
@@ -97151,7 +97636,7 @@ const Address = ({
|
|
|
97151
97636
|
};
|
|
97152
97637
|
|
|
97153
97638
|
installImportMetaCssBuild(import.meta);
|
|
97154
|
-
const css$
|
|
97639
|
+
const css$a = /* css */`@layer navi;
|
|
97155
97640
|
|
|
97156
97641
|
.navi_text.navi_badge_count {
|
|
97157
97642
|
white-space: nowrap;
|
|
@@ -97280,7 +97765,7 @@ const BadgeCount = ({
|
|
|
97280
97765
|
lineLayout,
|
|
97281
97766
|
...props
|
|
97282
97767
|
}) => {
|
|
97283
|
-
import.meta.css = [css$
|
|
97768
|
+
import.meta.css = [css$a, "@jsenv/navi/src/text/badge_count.jsx"];
|
|
97284
97769
|
const defaultRef = useRef();
|
|
97285
97770
|
props.ref = props.ref || defaultRef;
|
|
97286
97771
|
const {
|
|
@@ -97423,7 +97908,7 @@ const BadgeCountCircle = ({
|
|
|
97423
97908
|
};
|
|
97424
97909
|
|
|
97425
97910
|
installImportMetaCssBuild(import.meta);
|
|
97426
|
-
const css$
|
|
97911
|
+
const css$9 = /* css */`@layer navi {
|
|
97427
97912
|
.navi_caption {
|
|
97428
97913
|
--color: #6b7280;
|
|
97429
97914
|
}
|
|
@@ -97443,7 +97928,7 @@ const Caption = ({
|
|
|
97443
97928
|
className,
|
|
97444
97929
|
...rest
|
|
97445
97930
|
}) => {
|
|
97446
|
-
import.meta.css = [css$
|
|
97931
|
+
import.meta.css = [css$9, "@jsenv/navi/src/text/caption.jsx"];
|
|
97447
97932
|
return jsx(Text, {
|
|
97448
97933
|
as: "small",
|
|
97449
97934
|
size: "0.8em" // We use em to be relative to the parent (we want to be smaller than the surrounding text)
|
|
@@ -97839,177 +98324,8 @@ const Interpolate = ({
|
|
|
97839
98324
|
});
|
|
97840
98325
|
};
|
|
97841
98326
|
|
|
97842
|
-
const SuccessSvg = () => {
|
|
97843
|
-
return jsx("svg", {
|
|
97844
|
-
viewBox: "0 0 16 16",
|
|
97845
|
-
fill: "currentColor",
|
|
97846
|
-
children: jsx("path", {
|
|
97847
|
-
d: "M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm1.5 0a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm10.28-1.72-4.5 4.5a.75.75 0 0 1-1.06 0l-2-2a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018l1.47 1.47 3.97-3.97a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"
|
|
97848
|
-
})
|
|
97849
|
-
});
|
|
97850
|
-
};
|
|
97851
|
-
const ErrorSvg = () => {
|
|
97852
|
-
return jsx("svg", {
|
|
97853
|
-
viewBox: "0 0 16 16",
|
|
97854
|
-
fill: "currentColor",
|
|
97855
|
-
children: jsx("path", {
|
|
97856
|
-
d: "M4.47.22A.749.749 0 0 1 5 0h6c.199 0 .389.079.53.22l4.25 4.25c.141.14.22.331.22.53v6a.749.749 0 0 1-.22.53l-4.25 4.25A.749.749 0 0 1 11 16H5a.749.749 0 0 1-.53-.22L.22 11.53A.749.749 0 0 1 0 11V5c0-.199.079-.389.22-.53Zm.84 1.28L1.5 5.31v5.38l3.81 3.81h5.38l3.81-3.81V5.31L10.69 1.5ZM8 4a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"
|
|
97857
|
-
})
|
|
97858
|
-
});
|
|
97859
|
-
};
|
|
97860
|
-
const InfoSvg$1 = () => {
|
|
97861
|
-
return jsx("svg", {
|
|
97862
|
-
viewBox: "0 0 16 16",
|
|
97863
|
-
fill: "currentColor",
|
|
97864
|
-
children: jsx("path", {
|
|
97865
|
-
d: "M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"
|
|
97866
|
-
})
|
|
97867
|
-
});
|
|
97868
|
-
};
|
|
97869
|
-
const WarningSvg = () => {
|
|
97870
|
-
return jsx("svg", {
|
|
97871
|
-
viewBox: "0 0 16 16",
|
|
97872
|
-
fill: "currentColor",
|
|
97873
|
-
children: jsx("path", {
|
|
97874
|
-
d: "M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"
|
|
97875
|
-
})
|
|
97876
|
-
});
|
|
97877
|
-
};
|
|
97878
|
-
|
|
97879
|
-
installImportMetaCssBuild(import.meta);
|
|
97880
|
-
const css$a = /* css */`@layer navi {
|
|
97881
|
-
.navi_message_box {
|
|
97882
|
-
--background-color-info: var(--navi-info-color-light);
|
|
97883
|
-
--color-info: var(--navi-info-color);
|
|
97884
|
-
--background-color-success: var(--navi-success-color-light);
|
|
97885
|
-
--color-success: var(--navi-success-color);
|
|
97886
|
-
--background-color-warning: var(--navi-warning-color-light);
|
|
97887
|
-
--color-warning: var(--navi-warning-color);
|
|
97888
|
-
--background-color-error: var(--navi-error-color-light);
|
|
97889
|
-
--color-error: var(--navi-error-color);
|
|
97890
|
-
}
|
|
97891
|
-
}
|
|
97892
|
-
|
|
97893
|
-
.navi_message_box {
|
|
97894
|
-
--x-message-background-color: var(--background-color-info);
|
|
97895
|
-
--x-message-color: var(--color-info);
|
|
97896
|
-
background-color: var(--x-message-background-color);
|
|
97897
|
-
|
|
97898
|
-
& > .navi_icon {
|
|
97899
|
-
flex-shrink: 0;
|
|
97900
|
-
}
|
|
97901
|
-
}
|
|
97902
|
-
|
|
97903
|
-
.navi_message_box[data-status-info] {
|
|
97904
|
-
--x-message-background-color: var(--background-color-info);
|
|
97905
|
-
--x-message-color: var(--color-info);
|
|
97906
|
-
}
|
|
97907
|
-
|
|
97908
|
-
.navi_message_box[data-status-success] {
|
|
97909
|
-
--x-message-background-color: var(--background-color-success);
|
|
97910
|
-
--x-message-color: var(--color-success);
|
|
97911
|
-
}
|
|
97912
|
-
|
|
97913
|
-
.navi_message_box[data-status-warning] {
|
|
97914
|
-
--x-message-background-color: var(--background-color-warning);
|
|
97915
|
-
--x-message-color: var(--color-warning);
|
|
97916
|
-
}
|
|
97917
|
-
|
|
97918
|
-
.navi_message_box[data-status-error] {
|
|
97919
|
-
--x-message-background-color: var(--background-color-error);
|
|
97920
|
-
--x-message-color: var(--color-error);
|
|
97921
|
-
}
|
|
97922
|
-
|
|
97923
|
-
.navi_message_box[data-left-stripe] {
|
|
97924
|
-
border-left: 6px solid var(--x-message-color);
|
|
97925
|
-
border-top-left-radius: 6px;
|
|
97926
|
-
border-bottom-left-radius: 6px;
|
|
97927
|
-
}
|
|
97928
|
-
`;
|
|
97929
|
-
const MessageBox = ({
|
|
97930
|
-
status = "info",
|
|
97931
|
-
padding = "sm",
|
|
97932
|
-
icon,
|
|
97933
|
-
leftStripe,
|
|
97934
|
-
children,
|
|
97935
|
-
onClose,
|
|
97936
|
-
...rest
|
|
97937
|
-
}) => {
|
|
97938
|
-
import.meta.css = [css$a, "@jsenv/navi/src/text/message_box.jsx"];
|
|
97939
|
-
const [hasTitleChild, setHasTitleChild] = useState(false);
|
|
97940
|
-
const innerLeftStripe = leftStripe === undefined ? hasTitleChild : leftStripe;
|
|
97941
|
-
if (icon === true) {
|
|
97942
|
-
icon = status === "info" ? jsx(InfoSvg$1, {}) : status === "success" ? jsx(SuccessSvg, {}) : status === "warning" ? jsx(WarningSvg, {}) : status === "error" ? jsx(ErrorSvg, {}) : null;
|
|
97943
|
-
} else if (typeof icon === "function") {
|
|
97944
|
-
const Comp = icon;
|
|
97945
|
-
icon = jsx(Comp, {});
|
|
97946
|
-
}
|
|
97947
|
-
return jsx(Box, {
|
|
97948
|
-
as: "div",
|
|
97949
|
-
role: status === "info" ? "status" : "alert",
|
|
97950
|
-
"data-left-stripe": innerLeftStripe ? "" : undefined,
|
|
97951
|
-
inline: true,
|
|
97952
|
-
column: true,
|
|
97953
|
-
alignY: "center",
|
|
97954
|
-
spacing: "s",
|
|
97955
|
-
...rest,
|
|
97956
|
-
className: withPropsClassName("navi_message_box", rest.className),
|
|
97957
|
-
padding: padding,
|
|
97958
|
-
pseudoClasses: MessageBoxPseudoClasses,
|
|
97959
|
-
basePseudoState: {
|
|
97960
|
-
":-navi-status-info": status === "info",
|
|
97961
|
-
":-navi-status-success": status === "success",
|
|
97962
|
-
":-navi-status-warning": status === "warning",
|
|
97963
|
-
":-navi-status-error": status === "error"
|
|
97964
|
-
},
|
|
97965
|
-
children: jsx(MessageBoxStatusContext.Provider, {
|
|
97966
|
-
value: status,
|
|
97967
|
-
children: jsxs(MessageBoxReportTitleChildContext.Provider, {
|
|
97968
|
-
value: setHasTitleChild,
|
|
97969
|
-
children: [icon && jsx(Icon, {
|
|
97970
|
-
color: "var(--x-message-color)",
|
|
97971
|
-
height: "1lh",
|
|
97972
|
-
maxHeight: "auto",
|
|
97973
|
-
selfAlignY: "start",
|
|
97974
|
-
aspectRatio: "auto",
|
|
97975
|
-
children: icon
|
|
97976
|
-
}), jsx(Text, {
|
|
97977
|
-
children: children
|
|
97978
|
-
}), onClose &&
|
|
97979
|
-
// A column as tall as the first line of the message, pinned to the
|
|
97980
|
-
// top, the button centered in it: the close button stays level
|
|
97981
|
-
// with the first line however many lines the message takes (same
|
|
97982
|
-
// layout as Callout).
|
|
97983
|
-
jsx(Box, {
|
|
97984
|
-
flex: true,
|
|
97985
|
-
alignY: "center",
|
|
97986
|
-
height: "1lh",
|
|
97987
|
-
selfAlignY: "start",
|
|
97988
|
-
shrink: false,
|
|
97989
|
-
children: jsx(Button, {
|
|
97990
|
-
action: onClose,
|
|
97991
|
-
icon: true,
|
|
97992
|
-
border: "none",
|
|
97993
|
-
style: {
|
|
97994
|
-
":hover": {
|
|
97995
|
-
backgroundColor: "rgba(0, 0, 0, 0.1)"
|
|
97996
|
-
}
|
|
97997
|
-
},
|
|
97998
|
-
children: jsx(Icon, {
|
|
97999
|
-
children: jsx(CloseSvg, {})
|
|
98000
|
-
})
|
|
98001
|
-
})
|
|
98002
|
-
})]
|
|
98003
|
-
})
|
|
98004
|
-
})
|
|
98005
|
-
});
|
|
98006
|
-
};
|
|
98007
|
-
const MessageBoxPseudoClasses = [":-navi-status-info", ":-navi-status-success", ":-navi-status-warning", ":-navi-status-error"];
|
|
98008
|
-
const MessageBoxStatusContext = createContext();
|
|
98009
|
-
const MessageBoxReportTitleChildContext = createContext();
|
|
98010
|
-
|
|
98011
98327
|
installImportMetaCssBuild(import.meta);
|
|
98012
|
-
const css$
|
|
98328
|
+
const css$8 = /* css */`@layer navi;
|
|
98013
98329
|
|
|
98014
98330
|
.navi_quantity {
|
|
98015
98331
|
flex-direction: column;
|
|
@@ -98110,7 +98426,7 @@ const Quantity = ({
|
|
|
98110
98426
|
bold = true,
|
|
98111
98427
|
...props
|
|
98112
98428
|
}) => {
|
|
98113
|
-
import.meta.css = [css$
|
|
98429
|
+
import.meta.css = [css$8, "@jsenv/navi/src/text/quantity.jsx"];
|
|
98114
98430
|
const value = parseQuantityValue(children);
|
|
98115
98431
|
const valueRounded = integer && typeof value === "number" ? Math.round(value) : value;
|
|
98116
98432
|
const valueFormatted = typeof valueRounded === "number" ? formatNumber(valueRounded, {
|
|
@@ -98169,7 +98485,7 @@ const parseQuantityValue = children => {
|
|
|
98169
98485
|
};
|
|
98170
98486
|
|
|
98171
98487
|
installImportMetaCssBuild(import.meta);
|
|
98172
|
-
const css$
|
|
98488
|
+
const css$7 = /* css */`@layer navi {
|
|
98173
98489
|
.navi_meter {
|
|
98174
98490
|
--loader-color: var(--navi-loader-color);
|
|
98175
98491
|
--track-color: #efefef;
|
|
@@ -98308,7 +98624,7 @@ const Meter = ({
|
|
|
98308
98624
|
style,
|
|
98309
98625
|
...rest
|
|
98310
98626
|
}) => {
|
|
98311
|
-
import.meta.css = [css$
|
|
98627
|
+
import.meta.css = [css$7, "@jsenv/navi/src/text/meter.jsx"];
|
|
98312
98628
|
const defaultRef = useRef();
|
|
98313
98629
|
const ref = rest.ref || defaultRef;
|
|
98314
98630
|
value = Number(value);
|
|
@@ -98423,7 +98739,7 @@ const Paragraph = props => {
|
|
|
98423
98739
|
};
|
|
98424
98740
|
|
|
98425
98741
|
installImportMetaCssBuild(import.meta);
|
|
98426
|
-
const css$
|
|
98742
|
+
const css$6 = /* css */`.navi_text_box {
|
|
98427
98743
|
align-items: flex-start;
|
|
98428
98744
|
min-width: 0;
|
|
98429
98745
|
}
|
|
@@ -98465,7 +98781,7 @@ const TextBox = ({
|
|
|
98465
98781
|
children,
|
|
98466
98782
|
...rest
|
|
98467
98783
|
}) => {
|
|
98468
|
-
import.meta.css = [css$
|
|
98784
|
+
import.meta.css = [css$6, "@jsenv/navi/src/text/text_box.jsx"];
|
|
98469
98785
|
const boxRef = useRef(null);
|
|
98470
98786
|
const contentRef = useRef(null);
|
|
98471
98787
|
useLayoutEffect(() => {
|
|
@@ -98511,40 +98827,6 @@ const adjustWidth = (boxEl, contentEl) => {
|
|
|
98511
98827
|
contentEl.style.width = `${Math.ceil(optimalWidth)}px`;
|
|
98512
98828
|
};
|
|
98513
98829
|
|
|
98514
|
-
installImportMetaCssBuild(import.meta);
|
|
98515
|
-
const css$6 = /* css */`.navi_message_box {
|
|
98516
|
-
& .navi_title {
|
|
98517
|
-
margin-top: 0;
|
|
98518
|
-
margin-bottom: var(--navi-s);
|
|
98519
|
-
color: var(--x-message-color);
|
|
98520
|
-
}
|
|
98521
|
-
}
|
|
98522
|
-
`;
|
|
98523
|
-
const Title = props => {
|
|
98524
|
-
import.meta.css = [css$6, "@jsenv/navi/src/text/title.jsx"];
|
|
98525
|
-
const messageBoxStatus = useContext(MessageBoxStatusContext);
|
|
98526
|
-
const innerAs = props.as || (messageBoxStatus ? "h4" : "h1");
|
|
98527
|
-
const titleLevel = parseInt(innerAs.slice(1));
|
|
98528
|
-
const reportTitleToMessageBox = useContext(MessageBoxReportTitleChildContext);
|
|
98529
|
-
reportTitleToMessageBox?.(true);
|
|
98530
|
-
return jsx(TitleLevelContext.Provider, {
|
|
98531
|
-
value: titleLevel,
|
|
98532
|
-
children: jsx(Text, {
|
|
98533
|
-
bold: true,
|
|
98534
|
-
className: withPropsClassName("navi_title"),
|
|
98535
|
-
as: messageBoxStatus ? "h4" : "h1",
|
|
98536
|
-
...props,
|
|
98537
|
-
pseudoClasses: TitlePseudoClasses,
|
|
98538
|
-
children: props.children
|
|
98539
|
-
})
|
|
98540
|
-
});
|
|
98541
|
-
};
|
|
98542
|
-
const TitleLevelContext = createContext();
|
|
98543
|
-
const useTitleLevel = () => {
|
|
98544
|
-
return useContext(TitleLevelContext);
|
|
98545
|
-
};
|
|
98546
|
-
const TitlePseudoClasses = [":hover"];
|
|
98547
|
-
|
|
98548
98830
|
installImportMetaCssBuild(import.meta);
|
|
98549
98831
|
const css$5 = /* css */`@keyframes navi_image_shimmer {
|
|
98550
98832
|
0% {
|