@jsenv/navi 0.29.470 → 0.29.471
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 +576 -303
- package/dist/dev/jsenv_navi.js.map +19 -17
- package/dist/jsenv_navi.js +556 -303
- package/dist/jsenv_navi.js.map +19 -17
- 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
|
};
|
|
@@ -59404,6 +59429,10 @@ const Label = props => {
|
|
|
59404
59429
|
requiredIndicator
|
|
59405
59430
|
} = props;
|
|
59406
59431
|
const controlId = useContext(ControlIdContext);
|
|
59432
|
+
// What a popup opened from the control is named by (see getTriggerLabelIds
|
|
59433
|
+
// in picker_custom.jsx): aria-labelledby can only point at an id.
|
|
59434
|
+
const idDefault = useId();
|
|
59435
|
+
props.id = props.id || `label_${idDefault}`;
|
|
59407
59436
|
const [disabled, setDisabled] = useState(false);
|
|
59408
59437
|
const [readOnly, setReadOnly] = useState(false);
|
|
59409
59438
|
const [required, setRequired] = useState(false);
|
|
@@ -69182,9 +69211,297 @@ const PopupClose = ({
|
|
|
69182
69211
|
});
|
|
69183
69212
|
};
|
|
69184
69213
|
|
|
69214
|
+
const SuccessSvg = () => {
|
|
69215
|
+
return jsx("svg", {
|
|
69216
|
+
viewBox: "0 0 16 16",
|
|
69217
|
+
fill: "currentColor",
|
|
69218
|
+
children: jsx("path", {
|
|
69219
|
+
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"
|
|
69220
|
+
})
|
|
69221
|
+
});
|
|
69222
|
+
};
|
|
69223
|
+
const ErrorSvg = () => {
|
|
69224
|
+
return jsx("svg", {
|
|
69225
|
+
viewBox: "0 0 16 16",
|
|
69226
|
+
fill: "currentColor",
|
|
69227
|
+
children: jsx("path", {
|
|
69228
|
+
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"
|
|
69229
|
+
})
|
|
69230
|
+
});
|
|
69231
|
+
};
|
|
69232
|
+
const InfoSvg$1 = () => {
|
|
69233
|
+
return jsx("svg", {
|
|
69234
|
+
viewBox: "0 0 16 16",
|
|
69235
|
+
fill: "currentColor",
|
|
69236
|
+
children: jsx("path", {
|
|
69237
|
+
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"
|
|
69238
|
+
})
|
|
69239
|
+
});
|
|
69240
|
+
};
|
|
69241
|
+
const WarningSvg = () => {
|
|
69242
|
+
return jsx("svg", {
|
|
69243
|
+
viewBox: "0 0 16 16",
|
|
69244
|
+
fill: "currentColor",
|
|
69245
|
+
children: jsx("path", {
|
|
69246
|
+
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"
|
|
69247
|
+
})
|
|
69248
|
+
});
|
|
69249
|
+
};
|
|
69250
|
+
|
|
69251
|
+
installImportMetaCssBuild(import.meta);
|
|
69252
|
+
const css$E = /* css */`@layer navi {
|
|
69253
|
+
.navi_message_box {
|
|
69254
|
+
--background-color-info: var(--navi-info-color-light);
|
|
69255
|
+
--color-info: var(--navi-info-color);
|
|
69256
|
+
--background-color-success: var(--navi-success-color-light);
|
|
69257
|
+
--color-success: var(--navi-success-color);
|
|
69258
|
+
--background-color-warning: var(--navi-warning-color-light);
|
|
69259
|
+
--color-warning: var(--navi-warning-color);
|
|
69260
|
+
--background-color-error: var(--navi-error-color-light);
|
|
69261
|
+
--color-error: var(--navi-error-color);
|
|
69262
|
+
}
|
|
69263
|
+
}
|
|
69264
|
+
|
|
69265
|
+
.navi_message_box {
|
|
69266
|
+
--x-message-background-color: var(--background-color-info);
|
|
69267
|
+
--x-message-color: var(--color-info);
|
|
69268
|
+
background-color: var(--x-message-background-color);
|
|
69269
|
+
|
|
69270
|
+
& > .navi_icon {
|
|
69271
|
+
flex-shrink: 0;
|
|
69272
|
+
}
|
|
69273
|
+
}
|
|
69274
|
+
|
|
69275
|
+
.navi_message_box[data-status-info] {
|
|
69276
|
+
--x-message-background-color: var(--background-color-info);
|
|
69277
|
+
--x-message-color: var(--color-info);
|
|
69278
|
+
}
|
|
69279
|
+
|
|
69280
|
+
.navi_message_box[data-status-success] {
|
|
69281
|
+
--x-message-background-color: var(--background-color-success);
|
|
69282
|
+
--x-message-color: var(--color-success);
|
|
69283
|
+
}
|
|
69284
|
+
|
|
69285
|
+
.navi_message_box[data-status-warning] {
|
|
69286
|
+
--x-message-background-color: var(--background-color-warning);
|
|
69287
|
+
--x-message-color: var(--color-warning);
|
|
69288
|
+
}
|
|
69289
|
+
|
|
69290
|
+
.navi_message_box[data-status-error] {
|
|
69291
|
+
--x-message-background-color: var(--background-color-error);
|
|
69292
|
+
--x-message-color: var(--color-error);
|
|
69293
|
+
}
|
|
69294
|
+
|
|
69295
|
+
.navi_message_box[data-left-stripe] {
|
|
69296
|
+
border-left: 6px solid var(--x-message-color);
|
|
69297
|
+
border-top-left-radius: 6px;
|
|
69298
|
+
border-bottom-left-radius: 6px;
|
|
69299
|
+
}
|
|
69300
|
+
`;
|
|
69301
|
+
const MessageBox = ({
|
|
69302
|
+
status = "info",
|
|
69303
|
+
padding = "sm",
|
|
69304
|
+
icon,
|
|
69305
|
+
leftStripe,
|
|
69306
|
+
children,
|
|
69307
|
+
onClose,
|
|
69308
|
+
...rest
|
|
69309
|
+
}) => {
|
|
69310
|
+
import.meta.css = [css$E, "@jsenv/navi/src/text/message_box.jsx"];
|
|
69311
|
+
const [hasTitleChild, setHasTitleChild] = useState(false);
|
|
69312
|
+
const innerLeftStripe = leftStripe === undefined ? hasTitleChild : leftStripe;
|
|
69313
|
+
if (icon === true) {
|
|
69314
|
+
icon = status === "info" ? jsx(InfoSvg$1, {}) : status === "success" ? jsx(SuccessSvg, {}) : status === "warning" ? jsx(WarningSvg, {}) : status === "error" ? jsx(ErrorSvg, {}) : null;
|
|
69315
|
+
} else if (typeof icon === "function") {
|
|
69316
|
+
const Comp = icon;
|
|
69317
|
+
icon = jsx(Comp, {});
|
|
69318
|
+
}
|
|
69319
|
+
return jsx(Box, {
|
|
69320
|
+
as: "div",
|
|
69321
|
+
role: status === "info" ? "status" : "alert",
|
|
69322
|
+
"data-left-stripe": innerLeftStripe ? "" : undefined,
|
|
69323
|
+
inline: true,
|
|
69324
|
+
column: true,
|
|
69325
|
+
alignY: "center",
|
|
69326
|
+
spacing: "s",
|
|
69327
|
+
...rest,
|
|
69328
|
+
className: withPropsClassName("navi_message_box", rest.className),
|
|
69329
|
+
padding: padding,
|
|
69330
|
+
pseudoClasses: MessageBoxPseudoClasses,
|
|
69331
|
+
basePseudoState: {
|
|
69332
|
+
":-navi-status-info": status === "info",
|
|
69333
|
+
":-navi-status-success": status === "success",
|
|
69334
|
+
":-navi-status-warning": status === "warning",
|
|
69335
|
+
":-navi-status-error": status === "error"
|
|
69336
|
+
},
|
|
69337
|
+
children: jsx(MessageBoxStatusContext.Provider, {
|
|
69338
|
+
value: status,
|
|
69339
|
+
children: jsxs(MessageBoxReportTitleChildContext.Provider, {
|
|
69340
|
+
value: setHasTitleChild,
|
|
69341
|
+
children: [icon && jsx(Icon, {
|
|
69342
|
+
color: "var(--x-message-color)",
|
|
69343
|
+
height: "1lh",
|
|
69344
|
+
maxHeight: "auto",
|
|
69345
|
+
selfAlignY: "start",
|
|
69346
|
+
aspectRatio: "auto",
|
|
69347
|
+
children: icon
|
|
69348
|
+
}), jsx(Text, {
|
|
69349
|
+
children: children
|
|
69350
|
+
}), onClose &&
|
|
69351
|
+
// A column as tall as the first line of the message, pinned to the
|
|
69352
|
+
// top, the button centered in it: the close button stays level
|
|
69353
|
+
// with the first line however many lines the message takes (same
|
|
69354
|
+
// layout as Callout).
|
|
69355
|
+
jsx(Box, {
|
|
69356
|
+
flex: true,
|
|
69357
|
+
alignY: "center",
|
|
69358
|
+
height: "1lh",
|
|
69359
|
+
selfAlignY: "start",
|
|
69360
|
+
shrink: false,
|
|
69361
|
+
children: jsx(Button, {
|
|
69362
|
+
action: onClose,
|
|
69363
|
+
icon: true,
|
|
69364
|
+
border: "none",
|
|
69365
|
+
style: {
|
|
69366
|
+
":hover": {
|
|
69367
|
+
backgroundColor: "rgba(0, 0, 0, 0.1)"
|
|
69368
|
+
}
|
|
69369
|
+
},
|
|
69370
|
+
children: jsx(Icon, {
|
|
69371
|
+
children: jsx(CloseSvg, {})
|
|
69372
|
+
})
|
|
69373
|
+
})
|
|
69374
|
+
})]
|
|
69375
|
+
})
|
|
69376
|
+
})
|
|
69377
|
+
});
|
|
69378
|
+
};
|
|
69379
|
+
const MessageBoxPseudoClasses = [":-navi-status-info", ":-navi-status-success", ":-navi-status-warning", ":-navi-status-error"];
|
|
69380
|
+
const MessageBoxStatusContext = createContext();
|
|
69381
|
+
const MessageBoxReportTitleChildContext = createContext();
|
|
69382
|
+
|
|
69383
|
+
installImportMetaCssBuild(import.meta);
|
|
69384
|
+
const css$D = /* css */`.navi_message_box {
|
|
69385
|
+
& .navi_title {
|
|
69386
|
+
margin-top: 0;
|
|
69387
|
+
margin-bottom: var(--navi-s);
|
|
69388
|
+
color: var(--x-message-color);
|
|
69389
|
+
}
|
|
69390
|
+
}
|
|
69391
|
+
`;
|
|
69392
|
+
const Title = props => {
|
|
69393
|
+
import.meta.css = [css$D, "@jsenv/navi/src/text/title.jsx"];
|
|
69394
|
+
const messageBoxStatus = useContext(MessageBoxStatusContext);
|
|
69395
|
+
const innerAs = props.as || (messageBoxStatus ? "h4" : "h1");
|
|
69396
|
+
const titleLevel = parseInt(innerAs.slice(1));
|
|
69397
|
+
const reportTitleToMessageBox = useContext(MessageBoxReportTitleChildContext);
|
|
69398
|
+
reportTitleToMessageBox?.(true);
|
|
69399
|
+
return jsx(TitleLevelContext.Provider, {
|
|
69400
|
+
value: titleLevel,
|
|
69401
|
+
children: jsx(Text, {
|
|
69402
|
+
bold: true,
|
|
69403
|
+
className: withPropsClassName("navi_title"),
|
|
69404
|
+
as: messageBoxStatus ? "h4" : "h1",
|
|
69405
|
+
...props,
|
|
69406
|
+
pseudoClasses: TitlePseudoClasses,
|
|
69407
|
+
children: props.children
|
|
69408
|
+
})
|
|
69409
|
+
});
|
|
69410
|
+
};
|
|
69411
|
+
const TitleLevelContext = createContext();
|
|
69412
|
+
const useTitleLevel = () => {
|
|
69413
|
+
return useContext(TitleLevelContext);
|
|
69414
|
+
};
|
|
69415
|
+
const TitlePseudoClasses = [":hover"];
|
|
69416
|
+
|
|
69417
|
+
/**
|
|
69418
|
+
* What a popup is called, decided by Dialog and Popover alike: the name the
|
|
69419
|
+
* caller writes on it (aria-label/aria-labelledby), else the title it holds
|
|
69420
|
+
* (`<Popup.Title>`), else the name of what opened it (`openerAriaLabelledBy` /
|
|
69421
|
+
* `openerAriaLabel`, which a Picker fills with its trigger's). A popup no one
|
|
69422
|
+
* names is announced as "dialog" and nothing else.
|
|
69423
|
+
*
|
|
69424
|
+
* The title tells the popup it exists rather than the popup looking for it:
|
|
69425
|
+
* the content is built after the popup and thrown away before it (see
|
|
69426
|
+
* popup_content_mount.js), and a title may sit anywhere in it — a header, a
|
|
69427
|
+
* step of a form — so only the title knows when it is there.
|
|
69428
|
+
*/
|
|
69429
|
+
|
|
69430
|
+
const PopupTitleContext = createContext(null);
|
|
69431
|
+
|
|
69432
|
+
/**
|
|
69433
|
+
* The title of the popup it sits in — reached as `<Popup.Title>`,
|
|
69434
|
+
* `<Dialog.Title>` or `<Popover.Title>`. A heading (`h2` unless `as` says
|
|
69435
|
+
* otherwise) that is also the popup's accessible name: a screen reader
|
|
69436
|
+
* announces the popup by it, and `getByRole("dialog", { name })` finds it.
|
|
69437
|
+
* An `aria-label`/`aria-labelledby` written on the popup itself wins over it.
|
|
69438
|
+
*
|
|
69439
|
+
* @type {import("ignore:preact").FunctionComponent<{
|
|
69440
|
+
* as?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6",
|
|
69441
|
+
* id?: string,
|
|
69442
|
+
* children?: import("ignore:preact").ComponentChildren,
|
|
69443
|
+
* } & Record<string, any>>}
|
|
69444
|
+
*/
|
|
69445
|
+
const PopupTitle = props => {
|
|
69446
|
+
const registerTitle = useContext(PopupTitleContext);
|
|
69447
|
+
const idDefault = useId();
|
|
69448
|
+
const id = props.id || `popup_title_${idDefault}`;
|
|
69449
|
+
useLayoutEffect(() => {
|
|
69450
|
+
if (!registerTitle) {
|
|
69451
|
+
return undefined;
|
|
69452
|
+
}
|
|
69453
|
+
return registerTitle(id);
|
|
69454
|
+
}, [registerTitle, id]);
|
|
69455
|
+
return jsx(Title, {
|
|
69456
|
+
as: "h2",
|
|
69457
|
+
...props,
|
|
69458
|
+
id: id
|
|
69459
|
+
});
|
|
69460
|
+
};
|
|
69461
|
+
|
|
69462
|
+
/**
|
|
69463
|
+
* The name props of a popup element, and what its titles register with —
|
|
69464
|
+
* handed to its children through PopupTitleContext.
|
|
69465
|
+
*/
|
|
69466
|
+
const usePopupName = ({
|
|
69467
|
+
ariaLabel,
|
|
69468
|
+
ariaLabelledBy,
|
|
69469
|
+
openerAriaLabel,
|
|
69470
|
+
openerAriaLabelledBy
|
|
69471
|
+
}) => {
|
|
69472
|
+
// Several titles is a content of the caller's own making (two steps both
|
|
69473
|
+
// mounted): the first one registered names the popup.
|
|
69474
|
+
const [titleIds, setTitleIds] = useState(NO_TITLE);
|
|
69475
|
+
const registerTitle = useMemo(() => {
|
|
69476
|
+
return id => {
|
|
69477
|
+
setTitleIds(ids => [...ids, id]);
|
|
69478
|
+
return () => {
|
|
69479
|
+
setTitleIds(ids => ids.filter(each => each !== id));
|
|
69480
|
+
};
|
|
69481
|
+
};
|
|
69482
|
+
}, []);
|
|
69483
|
+
let labelledBy;
|
|
69484
|
+
let label;
|
|
69485
|
+
if (ariaLabelledBy !== undefined || ariaLabel !== undefined) {
|
|
69486
|
+
labelledBy = ariaLabelledBy;
|
|
69487
|
+
label = ariaLabel;
|
|
69488
|
+
} else if (titleIds.length > 0) {
|
|
69489
|
+
labelledBy = titleIds[0];
|
|
69490
|
+
} else if (openerAriaLabelledBy !== undefined) {
|
|
69491
|
+
labelledBy = openerAriaLabelledBy;
|
|
69492
|
+
} else {
|
|
69493
|
+
label = openerAriaLabel;
|
|
69494
|
+
}
|
|
69495
|
+
return [{
|
|
69496
|
+
"aria-labelledby": labelledBy,
|
|
69497
|
+
"aria-label": label
|
|
69498
|
+
}, registerTitle];
|
|
69499
|
+
};
|
|
69500
|
+
const NO_TITLE = [];
|
|
69501
|
+
|
|
69185
69502
|
installImportMetaCssBuild(import.meta);
|
|
69186
69503
|
let openLocalDialogCount = 0;
|
|
69187
|
-
const css$
|
|
69504
|
+
const css$C = /* css */`
|
|
69188
69505
|
/* jsenv-css-opaque: popupCss overlaps these rules, own sheet = cascade
|
|
69189
69506
|
order depending on which popup renders first. */
|
|
69190
69507
|
|
|
@@ -70253,10 +70570,14 @@ const css$E = /* css */`
|
|
|
70253
70570
|
* under `"while-opened"`, only a press on what opens the popup does (a
|
|
70254
70571
|
* `--navi-open` button, a picker's trigger), never with an `onOpen`, and a
|
|
70255
70572
|
* press that does not open the popup throws it away.
|
|
70573
|
+
* @param {string} [props.openerAriaLabelledBy] - The id(s) naming what opened
|
|
70574
|
+
* the dialog: its accessible name when neither `aria-label`/`aria-labelledby`
|
|
70575
|
+
* nor a `<Dialog.Title>` names it. A Picker passes its trigger's.
|
|
70576
|
+
* @param {string} [props.openerAriaLabel] - The same, as a string.
|
|
70256
70577
|
* @param {import("ignore:preact").ComponentChildren} props.children
|
|
70257
70578
|
*/
|
|
70258
70579
|
const Dialog = props => {
|
|
70259
|
-
import.meta.css = [css$
|
|
70580
|
+
import.meta.css = [css$C, "@jsenv/navi/src/layout/dialog.jsx"];
|
|
70260
70581
|
if (props.openController) {
|
|
70261
70582
|
return jsx(ControlledDialog, {
|
|
70262
70583
|
...props
|
|
@@ -70632,6 +70953,9 @@ const useDialogProps = props => {
|
|
|
70632
70953
|
onOpen,
|
|
70633
70954
|
children: childrenProp,
|
|
70634
70955
|
mount,
|
|
70956
|
+
// Read by usePopupName below, never written on the element.
|
|
70957
|
+
openerAriaLabel,
|
|
70958
|
+
openerAriaLabelledBy,
|
|
70635
70959
|
...rest
|
|
70636
70960
|
} = props;
|
|
70637
70961
|
// Assigned on every render, like openEffect below, so it always closes over
|
|
@@ -70642,7 +70966,16 @@ const useDialogProps = props => {
|
|
|
70642
70966
|
mount,
|
|
70643
70967
|
anchor
|
|
70644
70968
|
});
|
|
70645
|
-
const
|
|
70969
|
+
const [nameProps, registerTitle] = usePopupName({
|
|
70970
|
+
ariaLabel: rest["aria-label"],
|
|
70971
|
+
ariaLabelledBy: rest["aria-labelledby"],
|
|
70972
|
+
openerAriaLabel,
|
|
70973
|
+
openerAriaLabelledBy
|
|
70974
|
+
});
|
|
70975
|
+
const children = contentMounted ? jsx(PopupTitleContext.Provider, {
|
|
70976
|
+
value: registerTitle,
|
|
70977
|
+
children: childrenProp
|
|
70978
|
+
}) : null;
|
|
70646
70979
|
// Where it is placed, and whether there is a wall — the two questions that
|
|
70647
70980
|
// pick the show call (see this file's top comment).
|
|
70648
70981
|
const isTopLayer = layer === "top";
|
|
@@ -71492,6 +71825,7 @@ const useDialogProps = props => {
|
|
|
71492
71825
|
"backdropFilter": backdrop ? backdropFilter : undefined,
|
|
71493
71826
|
"styleCSSVars": DIALOG_STYLE_CSS_VARS,
|
|
71494
71827
|
...rest,
|
|
71828
|
+
...nameProps,
|
|
71495
71829
|
...autoFocusProps,
|
|
71496
71830
|
"as": "dialog",
|
|
71497
71831
|
ref,
|
|
@@ -71692,10 +72026,11 @@ const DIALOG_STYLE_CSS_VARS = {
|
|
|
71692
72026
|
maxHeight: "--dialog-max-height"
|
|
71693
72027
|
};
|
|
71694
72028
|
Dialog.Close = PopupClose;
|
|
72029
|
+
Dialog.Title = PopupTitle;
|
|
71695
72030
|
|
|
71696
72031
|
installImportMetaCssBuild(import.meta);
|
|
71697
72032
|
let openLocalPopoverCount = 0;
|
|
71698
|
-
const css$
|
|
72033
|
+
const css$B = /* css */`
|
|
71699
72034
|
/* jsenv-css-opaque: popupCss overlaps these rules, own sheet = cascade
|
|
71700
72035
|
order depending on which popup renders first. */
|
|
71701
72036
|
|
|
@@ -72294,10 +72629,17 @@ const css$D = /* css */`
|
|
|
72294
72629
|
* under `"while-opened"`, only a press on what opens the popup does (a
|
|
72295
72630
|
* `--navi-open` button, a picker's trigger), never with an `onOpen`, and a
|
|
72296
72631
|
* press that does not open the popup throws it away.
|
|
72632
|
+
* @param {string} [props.openerAriaLabelledBy] - The id(s) naming what opened
|
|
72633
|
+
* the popover: its accessible name when neither `aria-label`/`aria-labelledby`
|
|
72634
|
+
* nor a `<Popover.Title>` names it. A Picker passes its trigger's.
|
|
72635
|
+
* @param {string} [props.openerAriaLabel] - The same, as a string. A popover
|
|
72636
|
+
* something names — these, `aria-label`/`aria-labelledby`, a
|
|
72637
|
+
* `<Popover.Title>` — is a `dialog`, unless given another `role`: a name on
|
|
72638
|
+
* an element with no role is read by nobody.
|
|
72297
72639
|
* @param {import("ignore:preact").ComponentChildren} props.children
|
|
72298
72640
|
*/
|
|
72299
72641
|
const Popover = props => {
|
|
72300
|
-
import.meta.css = [css$
|
|
72642
|
+
import.meta.css = [css$B, "@jsenv/navi/src/layout/popover.jsx"];
|
|
72301
72643
|
if (props.openController) {
|
|
72302
72644
|
return jsx(ControlledPopover, {
|
|
72303
72645
|
...props
|
|
@@ -72536,6 +72878,9 @@ const usePopoverProps = props => {
|
|
|
72536
72878
|
onOpen,
|
|
72537
72879
|
children: childrenProp,
|
|
72538
72880
|
mount,
|
|
72881
|
+
// Read by usePopupName below, never written on the element.
|
|
72882
|
+
openerAriaLabel,
|
|
72883
|
+
openerAriaLabelledBy,
|
|
72539
72884
|
...rest
|
|
72540
72885
|
} = props;
|
|
72541
72886
|
// Assigned on every render, like openEffect below, so it always closes over
|
|
@@ -72546,7 +72891,16 @@ const usePopoverProps = props => {
|
|
|
72546
72891
|
mount,
|
|
72547
72892
|
anchor
|
|
72548
72893
|
});
|
|
72549
|
-
const
|
|
72894
|
+
const [nameProps, registerTitle] = usePopupName({
|
|
72895
|
+
ariaLabel: rest["aria-label"],
|
|
72896
|
+
ariaLabelledBy: rest["aria-labelledby"],
|
|
72897
|
+
openerAriaLabel,
|
|
72898
|
+
openerAriaLabelledBy
|
|
72899
|
+
});
|
|
72900
|
+
const children = contentMounted ? jsx(PopupTitleContext.Provider, {
|
|
72901
|
+
value: registerTitle,
|
|
72902
|
+
children: childrenProp
|
|
72903
|
+
}) : null;
|
|
72550
72904
|
const isTopLayer = layer === "top";
|
|
72551
72905
|
const ref = props.ref;
|
|
72552
72906
|
const backdropRef = useRef();
|
|
@@ -73361,6 +73715,10 @@ const usePopoverProps = props => {
|
|
|
73361
73715
|
"navi-hidden": openController.openedInDom ? undefined : "",
|
|
73362
73716
|
"styleCSSVars": POPUP_STYLE_CSS_VARS,
|
|
73363
73717
|
...rest,
|
|
73718
|
+
...nameProps,
|
|
73719
|
+
// A <div> has no role, and a name on an element without one is read by
|
|
73720
|
+
// nobody: a popover something names is a dialog, unless told what else.
|
|
73721
|
+
"role": rest.role ?? (nameProps["aria-labelledby"] === undefined && nameProps["aria-label"] === undefined ? undefined : "dialog"),
|
|
73364
73722
|
...autoFocusProps,
|
|
73365
73723
|
ref,
|
|
73366
73724
|
// Not a control, but still something the rest of navi has to be able to
|
|
@@ -73476,9 +73834,10 @@ const resolvePositionAreaAndAnimationKind = ({
|
|
|
73476
73834
|
};
|
|
73477
73835
|
};
|
|
73478
73836
|
Popover.Close = PopupClose;
|
|
73837
|
+
Popover.Title = PopupTitle;
|
|
73479
73838
|
|
|
73480
73839
|
installImportMetaCssBuild(import.meta);
|
|
73481
|
-
const css$
|
|
73840
|
+
const css$A = /* css */`@layer navi {
|
|
73482
73841
|
.navi_popup {
|
|
73483
73842
|
--popup-border-radius: var(--navi-popup-border-radius);
|
|
73484
73843
|
--popup-border-width: 1px;
|
|
@@ -73619,6 +73978,10 @@ const css$C = /* css */`@layer navi {
|
|
|
73619
73978
|
* @param {string} [props.className] - Merged with the shared
|
|
73620
73979
|
* `"navi_popup"` class (see this file's own CSS) rather than replacing
|
|
73621
73980
|
* it.
|
|
73981
|
+
* @param {string} [props.openerAriaLabelledBy] - Forwarded as-is: the name the
|
|
73982
|
+
* popup takes when neither `aria-label`/`aria-labelledby` nor a
|
|
73983
|
+
* `<Popup.Title>` in `children` names it (see `Dialog`/`Popover`).
|
|
73984
|
+
* @param {string} [props.openerAriaLabel] - Forwarded as-is, same.
|
|
73622
73985
|
* @param {"always"|"idle"|"from-first-open"|"while-opened"} [props.mount] - When
|
|
73623
73986
|
* `children` are built and thrown away (see popup_content_mount.js).
|
|
73624
73987
|
* `"from-first-open"` (the default) builds them on the first open and keeps
|
|
@@ -73634,7 +73997,7 @@ const css$C = /* css */`@layer navi {
|
|
|
73634
73997
|
* @param {import("ignore:preact").ComponentChildren} props.children
|
|
73635
73998
|
*/
|
|
73636
73999
|
const Popup = props => {
|
|
73637
|
-
import.meta.css = [css$
|
|
74000
|
+
import.meta.css = [css$A, "@jsenv/navi/src/layout/popup.jsx"];
|
|
73638
74001
|
const {
|
|
73639
74002
|
mode: modeProp,
|
|
73640
74003
|
maxWidth,
|
|
@@ -73717,6 +74080,7 @@ const Popup = props => {
|
|
|
73717
74080
|
});
|
|
73718
74081
|
};
|
|
73719
74082
|
Popup.Close = PopupClose;
|
|
74083
|
+
Popup.Title = PopupTitle;
|
|
73720
74084
|
|
|
73721
74085
|
// What Dialog's own animation values mean to a popover, which has no lift
|
|
73722
74086
|
// (see the `animation` doc above).
|
|
@@ -73765,6 +74129,54 @@ const pickerUIIsNaviOwn = ui => {
|
|
|
73765
74129
|
return Boolean(ui) && typeof ui === "object" && Boolean(ui.type?.isPickerOwnUI);
|
|
73766
74130
|
};
|
|
73767
74131
|
|
|
74132
|
+
/*
|
|
74133
|
+
* What the picker really is, said on the element that holds the name and takes
|
|
74134
|
+
* the focus (the host input in picker.jsx), which is both what a screen reader
|
|
74135
|
+
* announces and what getByRole(role, { name }) finds:
|
|
74136
|
+
* - a picker that picks nothing is a door — its popup is a question
|
|
74137
|
+
* (type="confirm") or something to read (mode="callout", which says it for
|
|
74138
|
+
* itself) — and a door is pressed: "button";
|
|
74139
|
+
* - a picker holding a value and opening a popup of navi's is a select-only
|
|
74140
|
+
* combobox: it shows a value the user does not type, and opens what changes
|
|
74141
|
+
* it. A textbox could not say the rest — aria-expanded is not allowed on one,
|
|
74142
|
+
* so "open" and "closed" would never be announced;
|
|
74143
|
+
* - a picker showing the browser's own picker (no popup of navi's) stays the
|
|
74144
|
+
* textbox its <input> is.
|
|
74145
|
+
*/
|
|
74146
|
+
const getPickerHostRole = props => {
|
|
74147
|
+
if (props.role !== undefined) {
|
|
74148
|
+
return props.role;
|
|
74149
|
+
}
|
|
74150
|
+
if (props.picksNothing) {
|
|
74151
|
+
return "button";
|
|
74152
|
+
}
|
|
74153
|
+
if (props["aria-haspopup"] !== undefined) {
|
|
74154
|
+
return "combobox";
|
|
74155
|
+
}
|
|
74156
|
+
return undefined;
|
|
74157
|
+
};
|
|
74158
|
+
|
|
74159
|
+
/*
|
|
74160
|
+
* And what that button is called, when the caller wrote it as a drawing rather
|
|
74161
|
+
* than as a word: a door draws no value, so what sits in its value slot IS its
|
|
74162
|
+
* label — the `ui` a caller gave it, or its placeholder. Undefined the moment
|
|
74163
|
+
* the caller names it themselves (aria-label/aria-labelledby), which is the
|
|
74164
|
+
* only way to name a door drawn as an icon. Read by the popup too: what the
|
|
74165
|
+
* user pressed is a fair name for what it opened.
|
|
74166
|
+
*/
|
|
74167
|
+
const getPickerHostLabelId = (id, props) => {
|
|
74168
|
+
if (getPickerHostRole(props) !== "button") {
|
|
74169
|
+
return undefined;
|
|
74170
|
+
}
|
|
74171
|
+
if (props["aria-label"] !== undefined || props["aria-labelledby"] !== undefined) {
|
|
74172
|
+
return undefined;
|
|
74173
|
+
}
|
|
74174
|
+
if (props.variant === "headless" || props.ui === "default") {
|
|
74175
|
+
return undefined;
|
|
74176
|
+
}
|
|
74177
|
+
return `${id}_picker_label`;
|
|
74178
|
+
};
|
|
74179
|
+
|
|
73768
74180
|
/**
|
|
73769
74181
|
* What the picker holds, read from inside its `ui` — for a drawing given as
|
|
73770
74182
|
* an element (`ui={<MyCard game={game} />}`), which the picker cannot hand
|
|
@@ -73794,7 +74206,7 @@ const usePickerState = () => {
|
|
|
73794
74206
|
};
|
|
73795
74207
|
|
|
73796
74208
|
installImportMetaCssBuild(import.meta);
|
|
73797
|
-
const css$
|
|
74209
|
+
const css$z = /* css */`.navi_picker_callout_dock > [data-picker-content] {
|
|
73798
74210
|
display: none;
|
|
73799
74211
|
}
|
|
73800
74212
|
|
|
@@ -73823,7 +74235,7 @@ const css$B = /* css */`.navi_picker_callout_dock > [data-picker-content] {
|
|
|
73823
74235
|
}
|
|
73824
74236
|
}
|
|
73825
74237
|
|
|
73826
|
-
.navi_picker[
|
|
74238
|
+
.navi_picker[navi-popover-mode="overlay"][aria-expanded="true"] {
|
|
73827
74239
|
border-color: #0000;
|
|
73828
74240
|
}
|
|
73829
74241
|
|
|
@@ -73851,7 +74263,7 @@ const css$B = /* css */`.navi_picker_callout_dock > [data-picker-content] {
|
|
|
73851
74263
|
}
|
|
73852
74264
|
`;
|
|
73853
74265
|
const PickerCustomResolver = props => {
|
|
73854
|
-
import.meta.css = [css$
|
|
74266
|
+
import.meta.css = [css$z, "@jsenv/navi/src/control/picker/picker_custom.jsx"];
|
|
73855
74267
|
if (props.children === undefined) {
|
|
73856
74268
|
return renderResolver(PickerNative, props);
|
|
73857
74269
|
}
|
|
@@ -74674,6 +75086,24 @@ const isPressDisputedByHold = pickerEl => Boolean(pickerEl?.parentElement?.close
|
|
|
74674
75086
|
const getPickerInput = pickerEl => {
|
|
74675
75087
|
return pickerEl.querySelector(".navi_picker_input");
|
|
74676
75088
|
};
|
|
75089
|
+
|
|
75090
|
+
// The <label>s naming a picker's trigger, by id. Read off the document: it is
|
|
75091
|
+
// the one place a label[for] and its control meet (navi's own Label carries an
|
|
75092
|
+
// id for this). A label wrapping the picker is left out — it holds the trigger
|
|
75093
|
+
// and the popup with it, and the popup would be named after its own content.
|
|
75094
|
+
const getTriggerLabelIds = pickerEl => {
|
|
75095
|
+
const labels = pickerEl && getPickerInput(pickerEl)?.labels;
|
|
75096
|
+
if (!labels) {
|
|
75097
|
+
return undefined;
|
|
75098
|
+
}
|
|
75099
|
+
const ids = [];
|
|
75100
|
+
for (const label of labels) {
|
|
75101
|
+
if (label.id && !label.contains(pickerEl)) {
|
|
75102
|
+
ids.push(label.id);
|
|
75103
|
+
}
|
|
75104
|
+
}
|
|
75105
|
+
return ids.length === 0 ? undefined : ids.join(" ");
|
|
75106
|
+
};
|
|
74677
75107
|
const getPickerInputUIState = pickerEl => {
|
|
74678
75108
|
const pickerInput = getPickerInput(pickerEl);
|
|
74679
75109
|
return getUIStateFromElement(pickerInput);
|
|
@@ -74696,6 +75126,11 @@ const PickerContentInsidePopup = props => {
|
|
|
74696
75126
|
// Same reason: a `data-testid` on the picker names the trigger (see
|
|
74697
75127
|
// docs/testid.md) — this one names the popup.
|
|
74698
75128
|
popupTestId,
|
|
75129
|
+
// Same again for the accessible name: aria-label/aria-labelledby on the
|
|
75130
|
+
// picker name the trigger (see control_context.js), these the popup.
|
|
75131
|
+
popupAriaLabel,
|
|
75132
|
+
popupAriaLabelledBy,
|
|
75133
|
+
popupAriaDescribedBy,
|
|
74699
75134
|
positionArea,
|
|
74700
75135
|
popoverMode = "nearby",
|
|
74701
75136
|
popoverSpacing = popoverMode === "nearby" ? 5 : 0,
|
|
@@ -74757,8 +75192,25 @@ const PickerContentInsidePopup = props => {
|
|
|
74757
75192
|
} = props;
|
|
74758
75193
|
const isPopover = mode === "popover";
|
|
74759
75194
|
const isCallout = mode === "callout";
|
|
74760
|
-
|
|
74761
|
-
|
|
75195
|
+
// The trigger's name, in the order the browser reads it, for the popup to
|
|
75196
|
+
// take when neither the caller nor a <Popup.Title> names it: "Report this
|
|
75197
|
+
// book" is a fair name for the sheet it opens, "Start date" for a calendar.
|
|
75198
|
+
let openerAriaLabelledBy = rest["aria-labelledby"] ?? getPickerHostLabelId(props.id, props);
|
|
75199
|
+
let openerAriaLabel;
|
|
75200
|
+
if (openerAriaLabelledBy === undefined) {
|
|
75201
|
+
openerAriaLabel = rest["aria-label"];
|
|
75202
|
+
// Read only while open: the labels are a question for the document, and
|
|
75203
|
+
// a closed popup has nobody to announce it.
|
|
75204
|
+
if (openerAriaLabel === undefined && rest["aria-expanded"]) {
|
|
75205
|
+
openerAriaLabelledBy = getTriggerLabelIds(props.ref.current);
|
|
75206
|
+
}
|
|
75207
|
+
}
|
|
75208
|
+
return jsx(Next
|
|
75209
|
+
// A dialog in either mode: what a picker opens is content of the
|
|
75210
|
+
// caller's, never a listbox (a selectable List is a group of radios or
|
|
75211
|
+
// checkboxes). The popover says so with its role, below.
|
|
75212
|
+
, {
|
|
75213
|
+
"aria-haspopup": "dialog",
|
|
74762
75214
|
"navi-popover-mode": isPopover ? popoverMode : undefined,
|
|
74763
75215
|
...rest,
|
|
74764
75216
|
// On popupProps already (see the picker's popup assembly); they mean
|
|
@@ -74803,11 +75255,23 @@ const PickerContentInsidePopup = props => {
|
|
|
74803
75255
|
pressOutside: pressOutside,
|
|
74804
75256
|
children: jsx(PopupModeContext.Provider, {
|
|
74805
75257
|
value: mode,
|
|
74806
|
-
children:
|
|
75258
|
+
children: jsx(PopupTitleContext.Provider, {
|
|
75259
|
+
value: null,
|
|
75260
|
+
children: children
|
|
75261
|
+
})
|
|
74807
75262
|
})
|
|
74808
75263
|
}) : jsx(Popup, {
|
|
74809
75264
|
...popupProps,
|
|
74810
75265
|
"data-testid": popupTestId
|
|
75266
|
+
// What the trigger's aria-haspopup announces; a <dialog> says it
|
|
75267
|
+
// for itself.
|
|
75268
|
+
,
|
|
75269
|
+
role: isPopover ? "dialog" : undefined,
|
|
75270
|
+
"aria-label": popupAriaLabel,
|
|
75271
|
+
"aria-labelledby": popupAriaLabelledBy,
|
|
75272
|
+
"aria-describedby": popupAriaDescribedBy,
|
|
75273
|
+
openerAriaLabel: openerAriaLabel,
|
|
75274
|
+
openerAriaLabelledBy: openerAriaLabelledBy
|
|
74811
75275
|
// What the CSS above keys on: this picker's own popup, and no other
|
|
74812
75276
|
// popup below the picker.
|
|
74813
75277
|
,
|
|
@@ -75077,7 +75541,7 @@ const showNativePicker = (pickerInput, event) => {
|
|
|
75077
75541
|
};
|
|
75078
75542
|
|
|
75079
75543
|
installImportMetaCssBuild(import.meta);
|
|
75080
|
-
const css$
|
|
75544
|
+
const css$y = /* css */`.navi_picker_confirm_body {
|
|
75081
75545
|
min-width: 180px;
|
|
75082
75546
|
max-width: 320px;
|
|
75083
75547
|
padding: var(--navi-m);
|
|
@@ -75093,7 +75557,7 @@ const css$A = /* css */`.navi_picker_confirm_body {
|
|
|
75093
75557
|
}
|
|
75094
75558
|
`;
|
|
75095
75559
|
const PickerConfirmResolver = props => {
|
|
75096
|
-
import.meta.css = [css$
|
|
75560
|
+
import.meta.css = [css$y, "@jsenv/navi/src/control/picker/picker_confirm.jsx"];
|
|
75097
75561
|
const Next = useNextResolver();
|
|
75098
75562
|
if (props.type !== "confirm") {
|
|
75099
75563
|
return jsx(Next, {
|
|
@@ -75619,7 +76083,7 @@ const LoadingIndicator = ({
|
|
|
75619
76083
|
};
|
|
75620
76084
|
|
|
75621
76085
|
installImportMetaCssBuild(import.meta);
|
|
75622
|
-
const css$
|
|
76086
|
+
const css$x = /* css */`@layer navi {
|
|
75623
76087
|
.navi_separator {
|
|
75624
76088
|
--size: 1px;
|
|
75625
76089
|
--color: var(--navi-separator-color-default);
|
|
@@ -75693,7 +76157,7 @@ const Separator = ({
|
|
|
75693
76157
|
style,
|
|
75694
76158
|
...props
|
|
75695
76159
|
}) => {
|
|
75696
|
-
import.meta.css = [css$
|
|
76160
|
+
import.meta.css = [css$x, "@jsenv/navi/src/layout/separator.jsx"];
|
|
75697
76161
|
return jsx(Box, {
|
|
75698
76162
|
as: vertical ? "span" : "hr",
|
|
75699
76163
|
...props,
|
|
@@ -76487,7 +76951,7 @@ const listItemBlockedMessage = (loading, props) => {
|
|
|
76487
76951
|
};
|
|
76488
76952
|
|
|
76489
76953
|
installImportMetaCssBuild(import.meta);
|
|
76490
|
-
const css$
|
|
76954
|
+
const css$w = /* css */`@layer navi {
|
|
76491
76955
|
.navi_list_container[navi-selectable] {
|
|
76492
76956
|
--list-item-outline-width: var(--navi-focus-outline-width);
|
|
76493
76957
|
--list-item-outline-offset: calc(-1 * var(--list-item-outline-width));
|
|
@@ -76660,7 +77124,7 @@ const ListSelectableResolver = props => {
|
|
|
76660
77124
|
};
|
|
76661
77125
|
const ListSelectable = props => {
|
|
76662
77126
|
const Next = useNextResolver();
|
|
76663
|
-
import.meta.css = [css$
|
|
77127
|
+
import.meta.css = [css$w, "@jsenv/navi/src/control/list/list_selectable.jsx"];
|
|
76664
77128
|
// we allow ourselves to auto-generate a name
|
|
76665
77129
|
const defaultName = useId();
|
|
76666
77130
|
props.name = props.name || `listbox_${defaultName}`;
|
|
@@ -77329,7 +77793,7 @@ const ListRunItemContext = createContext(null);
|
|
|
77329
77793
|
// item takes its place in the collection by slot: the place is then the list's
|
|
77330
77794
|
// to move, and the item's to follow — see list_items.js.
|
|
77331
77795
|
const ListSlotContext = createContext(null);
|
|
77332
|
-
const css$
|
|
77796
|
+
const css$v = /* css */`@property --list-group-label-height {
|
|
77333
77797
|
syntax: "<length>";
|
|
77334
77798
|
inherits: false;
|
|
77335
77799
|
initial-value: 0;
|
|
@@ -77857,7 +78321,7 @@ const resolveRenderBudget = renderBudget => {
|
|
|
77857
78321
|
};
|
|
77858
78322
|
};
|
|
77859
78323
|
const ListUI = props => {
|
|
77860
|
-
import.meta.css = [css$
|
|
78324
|
+
import.meta.css = [css$v, "@jsenv/navi/src/control/list/list.jsx"];
|
|
77861
78325
|
const {
|
|
77862
78326
|
ref,
|
|
77863
78327
|
renderBudget: renderBudgetProp,
|
|
@@ -84147,7 +84611,7 @@ const createBadgeRegistry = () => {
|
|
|
84147
84611
|
};
|
|
84148
84612
|
|
|
84149
84613
|
installImportMetaCssBuild(import.meta);
|
|
84150
|
-
const css$
|
|
84614
|
+
const css$u = /* css */`@layer navi;
|
|
84151
84615
|
|
|
84152
84616
|
.navi_badge {
|
|
84153
84617
|
--font-size: .7em;
|
|
@@ -84250,7 +84714,7 @@ const BadgeUI = ({
|
|
|
84250
84714
|
className,
|
|
84251
84715
|
...props
|
|
84252
84716
|
}) => {
|
|
84253
|
-
import.meta.css = [css$
|
|
84717
|
+
import.meta.css = [css$u, "@jsenv/navi/src/text/badge.jsx"];
|
|
84254
84718
|
const defaultRef = useRef();
|
|
84255
84719
|
props.ref = props.ref || defaultRef;
|
|
84256
84720
|
const {
|
|
@@ -84358,7 +84822,7 @@ const wrapLabels = childArray => {
|
|
|
84358
84822
|
};
|
|
84359
84823
|
|
|
84360
84824
|
installImportMetaCssBuild(import.meta);
|
|
84361
|
-
const css$
|
|
84825
|
+
const css$t = /* css */`@layer navi;
|
|
84362
84826
|
|
|
84363
84827
|
.navi_badge_list {
|
|
84364
84828
|
flex-wrap: wrap;
|
|
@@ -84493,7 +84957,7 @@ const useBadgeRegistry = (children, enabled) => {
|
|
|
84493
84957
|
* component grants (a <Picker>, see max_lines_context.js).
|
|
84494
84958
|
*/
|
|
84495
84959
|
const BadgeList = props => {
|
|
84496
|
-
import.meta.css = [css$
|
|
84960
|
+
import.meta.css = [css$t, "@jsenv/navi/src/text/badge_list.jsx"];
|
|
84497
84961
|
const {
|
|
84498
84962
|
maxLines,
|
|
84499
84963
|
max,
|
|
@@ -84837,7 +85301,7 @@ const BadgeListContent = ({
|
|
|
84837
85301
|
};
|
|
84838
85302
|
|
|
84839
85303
|
installImportMetaCssBuild(import.meta);
|
|
84840
|
-
const css$
|
|
85304
|
+
const css$s = /* css */`.navi_color {
|
|
84841
85305
|
aspect-ratio: 1;
|
|
84842
85306
|
background-color: currentColor;
|
|
84843
85307
|
border: 1px solid #0003;
|
|
@@ -84857,7 +85321,7 @@ const Color = ({
|
|
|
84857
85321
|
children,
|
|
84858
85322
|
...rest
|
|
84859
85323
|
}) => {
|
|
84860
|
-
import.meta.css = [css$
|
|
85324
|
+
import.meta.css = [css$s, "@jsenv/navi/src/text/color.jsx"];
|
|
84861
85325
|
const color = children || undefined;
|
|
84862
85326
|
return jsx(Box, {
|
|
84863
85327
|
as: "span",
|
|
@@ -85344,7 +85808,7 @@ const PickerFileUI = /*#__PURE__*/asPickerOwnUI(() => {
|
|
|
85344
85808
|
});
|
|
85345
85809
|
|
|
85346
85810
|
installImportMetaCssBuild(import.meta);
|
|
85347
|
-
const css$
|
|
85811
|
+
const css$r = /* css */`@layer navi {
|
|
85348
85812
|
.navi_picker {
|
|
85349
85813
|
--picker-border-radius: var(--navi-control-border-radius);
|
|
85350
85814
|
--picker-border-width: var(--navi-control-border-width);
|
|
@@ -85813,7 +86277,7 @@ const css$t = /* css */`@layer navi {
|
|
|
85813
86277
|
}
|
|
85814
86278
|
`;
|
|
85815
86279
|
const PickerButton = props => {
|
|
85816
|
-
import.meta.css = [css$
|
|
86280
|
+
import.meta.css = [css$r, "@jsenv/navi/src/control/picker/picker.jsx"];
|
|
85817
86281
|
warnOnUnknownPickerType(props);
|
|
85818
86282
|
warnOnUIDrawnByNobody(props);
|
|
85819
86283
|
if (typeof props.maxLines === "string") {
|
|
@@ -85856,11 +86320,6 @@ const PickerButton = props => {
|
|
|
85856
86320
|
// confirm resolver (see picker_confirm.jsx), which is the picker that is
|
|
85857
86321
|
// one — a caller whose popup is a menu of actions says it for themselves.
|
|
85858
86322
|
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
86323
|
readOnly,
|
|
85865
86324
|
error,
|
|
85866
86325
|
// Who draws the loading outline. Left unsaid, the picker does, around its
|
|
@@ -85943,21 +86402,8 @@ const PickerButton = props => {
|
|
|
85943
86402
|
// clearing being a modification like any other.
|
|
85944
86403
|
const interactive = !basePseudoState[":disabled"] && !basePseudoState[":read-only"] && !loading;
|
|
85945
86404
|
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;
|
|
86405
|
+
const hostRole = getPickerHostRole(props);
|
|
86406
|
+
const hostLabelId = getPickerHostLabelId(inputProps.id, props);
|
|
85961
86407
|
// What the picker knows about itself, for the pieces it does not place: the
|
|
85962
86408
|
// drawings of its value (Picker.UI.*), and the affordances a caller may put
|
|
85963
86409
|
// in their own `ui` (Picker.Clear) as much as the ones it puts in its slot.
|
|
@@ -86026,8 +86472,16 @@ const PickerButton = props => {
|
|
|
86026
86472
|
basePseudoState: basePseudoState,
|
|
86027
86473
|
styleCSSVars: PickerStyleCSSVars,
|
|
86028
86474
|
variant: undefined,
|
|
86029
|
-
icon: undefined
|
|
86475
|
+
icon: undefined
|
|
86476
|
+
// The caller's own role goes onto the host, beside the name (see
|
|
86477
|
+
// control_context.js): a role and a name on two different elements
|
|
86478
|
+
// name nothing at all. What the trigger opens is said there too, and
|
|
86479
|
+
// aria-haspopup with it. aria-expanded stays here as well: commands.js
|
|
86480
|
+
// and the CSS read the open state off the root (see
|
|
86481
|
+
// expandableRepeatedBy in commands.js).
|
|
86482
|
+
,
|
|
86030
86483
|
role: undefined,
|
|
86484
|
+
"aria-haspopup": undefined,
|
|
86031
86485
|
rightSlotIcon: undefined,
|
|
86032
86486
|
rightSlotIconSize: undefined,
|
|
86033
86487
|
rightSlot: undefined,
|
|
@@ -86067,6 +86521,8 @@ const PickerButton = props => {
|
|
|
86067
86521
|
inset: loadingOutlineInset
|
|
86068
86522
|
}), jsx(PickerInput, {
|
|
86069
86523
|
role: hostRole,
|
|
86524
|
+
"aria-haspopup": props["aria-haspopup"],
|
|
86525
|
+
"aria-expanded": props["aria-expanded"],
|
|
86070
86526
|
"aria-labelledby": hostLabelId,
|
|
86071
86527
|
tabIndex: variant === "headless" ? -1 : undefined,
|
|
86072
86528
|
"aria-hidden": variant === "headless" ? "true" : undefined,
|
|
@@ -86574,6 +87030,10 @@ const PickerFirstResolver = props => {
|
|
|
86574
87030
|
* Without `children`, opens the browser-native picker for the given `type`.
|
|
86575
87031
|
* With `children`, opens a popover (desktop) or dialog (mobile) containing the children.
|
|
86576
87032
|
* Pass `mode="popover"` or `mode="dialog"` to override the automatic choice.
|
|
87033
|
+
* Either way the popup is a `dialog`, named by a `<Popup.Title>` in the
|
|
87034
|
+
* children (see `popupAriaLabelledBy`), and the trigger answers to `combobox` —
|
|
87035
|
+
* `button` under `picksNothing` — with `aria-haspopup="dialog"` and
|
|
87036
|
+
* `aria-expanded` (see docs/testid.md).
|
|
86577
87037
|
*
|
|
86578
87038
|
* `type="confirm"` is the picker that asks "are you sure?" before doing what it
|
|
86579
87039
|
* stands for: its popup is the question, `ui` its label, and yes runs its
|
|
@@ -86647,6 +87107,9 @@ const PickerFirstResolver = props => {
|
|
|
86647
87107
|
* standalone?: boolean,
|
|
86648
87108
|
* popupLayer?: "top" | "local",
|
|
86649
87109
|
* popupTestId?: string,
|
|
87110
|
+
* popupAriaLabel?: string,
|
|
87111
|
+
* popupAriaLabelledBy?: string,
|
|
87112
|
+
* popupAriaDescribedBy?: string,
|
|
86650
87113
|
* confirmTestId?: string,
|
|
86651
87114
|
* cancelTestId?: string,
|
|
86652
87115
|
* mount?: "always" | "idle" | "from-first-open" | "while-opened",
|
|
@@ -87106,6 +87569,19 @@ const PickerFirstResolver = props => {
|
|
|
87106
87569
|
* not only what it holds, which a testid inside the children already names.
|
|
87107
87570
|
* Under `mode="callout"` it names the callout element — the control's own,
|
|
87108
87571
|
* shared with its constraint messages — while the children are shown in it.
|
|
87572
|
+
* @param {string} [popupAriaLabelledBy] The id(s) of what names the popup:
|
|
87573
|
+
* `aria-labelledby` on the popup element, which is a dialog in either mode
|
|
87574
|
+
* (the trigger says `aria-haspopup="dialog"`). `aria-label`/`aria-labelledby`
|
|
87575
|
+
* on the picker itself name the trigger. Rarely needed: a `<Popup.Title>`
|
|
87576
|
+
* in the children names the popup with nothing to wire, and without one
|
|
87577
|
+
* the popup takes the trigger's own name — the picker's `aria-labelledby`,
|
|
87578
|
+
* the label a picker that picks nothing draws, its `aria-label`, or the
|
|
87579
|
+
* `<Label>`/`<label for>` pointing at it (one that has an id, and does not
|
|
87580
|
+
* wrap the picker). A `mode="callout"` popup is read as its message.
|
|
87581
|
+
* @param {string} [popupAriaLabel] The same, as a string, for a popup whose
|
|
87582
|
+
* title is not an element.
|
|
87583
|
+
* @param {string} [popupAriaDescribedBy] The id(s) of what describes the
|
|
87584
|
+
* popup: `aria-describedby` on the popup element.
|
|
87109
87585
|
* @param {string} [confirmTestId] `type="confirm"`, default body: the
|
|
87110
87586
|
* `data-testid` of the yes button; `cancelTestId` that of the no button.
|
|
87111
87587
|
* Both are elements navi builds, which a test may not name by class (see
|
|
@@ -87243,7 +87719,7 @@ const Picker = /*#__PURE__*/Object.assign(PickerResolved, {
|
|
|
87243
87719
|
});
|
|
87244
87720
|
|
|
87245
87721
|
installImportMetaCssBuild(import.meta);
|
|
87246
|
-
const css$
|
|
87722
|
+
const css$q = /* css */`@layer navi {
|
|
87247
87723
|
.navi_picker_spin {
|
|
87248
87724
|
--picker-spin-padding-x-default: var(--navi-picker-padding-x-default);
|
|
87249
87725
|
--picker-spin-padding-y-default: var(--navi-picker-padding-y-default);
|
|
@@ -87593,7 +88069,7 @@ const Spin = ({
|
|
|
87593
88069
|
nextLabel,
|
|
87594
88070
|
...rest
|
|
87595
88071
|
}) => {
|
|
87596
|
-
import.meta.css = [css$
|
|
88072
|
+
import.meta.css = [css$q, "@jsenv/navi/src/control/picker/picker_spin.jsx"];
|
|
87597
88073
|
const id = useId();
|
|
87598
88074
|
// What the group around it says, when there is one: how big the whole thing
|
|
87599
88075
|
// is written is said once, on the group, and every spin in it follows.
|
|
@@ -88304,7 +88780,7 @@ const renderValueDefault = value => String(value ?? "");
|
|
|
88304
88780
|
* are passed on to the spins sitting in them.
|
|
88305
88781
|
*/
|
|
88306
88782
|
const SpinGroup = props => {
|
|
88307
|
-
import.meta.css = [css$
|
|
88783
|
+
import.meta.css = [css$q, "@jsenv/navi/src/control/picker/picker_spin.jsx"];
|
|
88308
88784
|
const {
|
|
88309
88785
|
size
|
|
88310
88786
|
} = props;
|
|
@@ -88813,7 +89289,7 @@ const TimeRangeSpin = ({
|
|
|
88813
89289
|
};
|
|
88814
89290
|
|
|
88815
89291
|
installImportMetaCssBuild(import.meta);
|
|
88816
|
-
const css$
|
|
89292
|
+
const css$p = /* css */`.navi_checkbox_group {
|
|
88817
89293
|
border-style: solid;
|
|
88818
89294
|
|
|
88819
89295
|
&[data-callout] {
|
|
@@ -88873,7 +89349,7 @@ const CheckboxGroup = props => {
|
|
|
88873
89349
|
return checkboxGroup;
|
|
88874
89350
|
};
|
|
88875
89351
|
const CheckboxGroupInterface = props => {
|
|
88876
|
-
import.meta.css = [css$
|
|
89352
|
+
import.meta.css = [css$p, "@jsenv/navi/src/control/input/checkbox_group.jsx"];
|
|
88877
89353
|
const {
|
|
88878
89354
|
ref
|
|
88879
89355
|
} = props;
|
|
@@ -88991,7 +89467,7 @@ const formatIntlUnit = (unit, {
|
|
|
88991
89467
|
};
|
|
88992
89468
|
|
|
88993
89469
|
installImportMetaCssBuild(import.meta);
|
|
88994
|
-
const css$
|
|
89470
|
+
const css$o = /* css */`.navi_input_duration {
|
|
88995
89471
|
--duration-separator-spacing: 4px;
|
|
88996
89472
|
--loader-color: var(--navi-loader-color);
|
|
88997
89473
|
position: relative;
|
|
@@ -89056,7 +89532,7 @@ const css$q = /* css */`.navi_input_duration {
|
|
|
89056
89532
|
* "auto" aligns each field toward its neighbouring separator (first→right, last→left, middle/solo→center).
|
|
89057
89533
|
*/
|
|
89058
89534
|
const InputDuration = props => {
|
|
89059
|
-
import.meta.css = [css$
|
|
89535
|
+
import.meta.css = [css$o, "@jsenv/navi/src/control/input/input_duration.jsx"];
|
|
89060
89536
|
const defaultRef = useRef();
|
|
89061
89537
|
props.ref = props.ref || defaultRef;
|
|
89062
89538
|
props.max = props.max || "23h59";
|
|
@@ -89557,7 +90033,7 @@ const InputDurationPart = ({
|
|
|
89557
90033
|
};
|
|
89558
90034
|
|
|
89559
90035
|
installImportMetaCssBuild(import.meta);
|
|
89560
|
-
const css$
|
|
90036
|
+
const css$n = /* css */`.navi_radio_group {
|
|
89561
90037
|
border-style: solid;
|
|
89562
90038
|
|
|
89563
90039
|
&[data-callout] {
|
|
@@ -89597,7 +90073,7 @@ const RadioGroup = props => {
|
|
|
89597
90073
|
return radioGroup;
|
|
89598
90074
|
};
|
|
89599
90075
|
const RadioGroupInterface = props => {
|
|
89600
|
-
import.meta.css = [css$
|
|
90076
|
+
import.meta.css = [css$n, "@jsenv/navi/src/control/input/radio_group.jsx"];
|
|
89601
90077
|
const {
|
|
89602
90078
|
ref
|
|
89603
90079
|
} = props;
|
|
@@ -89627,7 +90103,7 @@ const RadioGroupInterface = props => {
|
|
|
89627
90103
|
};
|
|
89628
90104
|
|
|
89629
90105
|
installImportMetaCssBuild(import.meta);
|
|
89630
|
-
const css$
|
|
90106
|
+
const css$m = /* css */`.navi_input.navi_select {
|
|
89631
90107
|
& .navi_control_input {
|
|
89632
90108
|
padding-right: calc(var(--x-padding-right) + 1em);
|
|
89633
90109
|
line-height: var(--navi-control-line-height);
|
|
@@ -89674,7 +90150,7 @@ const Select = ({
|
|
|
89674
90150
|
...props
|
|
89675
90151
|
}) => {
|
|
89676
90152
|
installInputCss();
|
|
89677
|
-
import.meta.css = [css$
|
|
90153
|
+
import.meta.css = [css$m, "@jsenv/navi/src/control/input/select.jsx"];
|
|
89678
90154
|
const defaultRef = useRef(null);
|
|
89679
90155
|
props.ref = props.ref || defaultRef;
|
|
89680
90156
|
seedDefaultValueFromSignal(props);
|
|
@@ -89727,7 +90203,7 @@ const Select = ({
|
|
|
89727
90203
|
};
|
|
89728
90204
|
|
|
89729
90205
|
installImportMetaCssBuild(import.meta);
|
|
89730
|
-
const css$
|
|
90206
|
+
const css$l = /* css */`.navi_split_button {
|
|
89731
90207
|
border-radius: var(--navi-control-border-radius);
|
|
89732
90208
|
display: inline-flex;
|
|
89733
90209
|
position: relative;
|
|
@@ -89849,7 +90325,7 @@ const css$n = /* css */`.navi_split_button {
|
|
|
89849
90325
|
* on the split button's own box.
|
|
89850
90326
|
*/
|
|
89851
90327
|
const SplitButton = props => {
|
|
89852
|
-
import.meta.css = [css$
|
|
90328
|
+
import.meta.css = [css$l, "@jsenv/navi/src/control/input/split_button.jsx"];
|
|
89853
90329
|
const {
|
|
89854
90330
|
options = [],
|
|
89855
90331
|
value,
|
|
@@ -90868,7 +91344,7 @@ const createItemTracker = (onChange) => {
|
|
|
90868
91344
|
};
|
|
90869
91345
|
|
|
90870
91346
|
installImportMetaCssBuild(import.meta);
|
|
90871
|
-
const css$
|
|
91347
|
+
const css$k = /* css */`.navi_wheel_container {
|
|
90872
91348
|
--wheel-item-height: round(1.8em, 1px);
|
|
90873
91349
|
--wheel-emphasis-size: round(1.5em, 1px);
|
|
90874
91350
|
--wheel-item-width: 3.5ch;
|
|
@@ -91817,7 +92293,7 @@ const useWheelKeyboard = ({
|
|
|
91817
92293
|
}, [isHorizontal, interactive, isLoop]);
|
|
91818
92294
|
};
|
|
91819
92295
|
function WheelUI(props) {
|
|
91820
|
-
import.meta.css = [css$
|
|
92296
|
+
import.meta.css = [css$k, "@jsenv/navi/src/control/wheel/wheel.jsx"];
|
|
91821
92297
|
const {
|
|
91822
92298
|
ref,
|
|
91823
92299
|
visibleCount = 3,
|
|
@@ -92814,7 +93290,7 @@ Wheel.Item = WheelItem;
|
|
|
92814
93290
|
* @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
93291
|
*/
|
|
92816
93292
|
const WheelGroup = props => {
|
|
92817
|
-
import.meta.css = [css$
|
|
93293
|
+
import.meta.css = [css$k, "@jsenv/navi/src/control/wheel/wheel.jsx"];
|
|
92818
93294
|
// WheelGroup IS a control group: it aggregates its named wheels ("hours",
|
|
92819
93295
|
// "minutes"…) into one object value, so it can sit directly inside a Form or a
|
|
92820
93296
|
// Picker with no extra <ControlGroup> wrapper. The wheel-specific presentation
|
|
@@ -92987,7 +93463,7 @@ const WheelColon = props => {
|
|
|
92987
93463
|
Wheel.Colon = WheelColon;
|
|
92988
93464
|
|
|
92989
93465
|
installImportMetaCssBuild(import.meta);
|
|
92990
|
-
const css$
|
|
93466
|
+
const css$j = /* css */`.navi_time_range_label {
|
|
92991
93467
|
--wheel-item-height: round(1.8em, 1px);
|
|
92992
93468
|
color: var(--wheel-color, light-dark(#111, #eee));
|
|
92993
93469
|
line-height: var(--wheel-item-height);
|
|
@@ -93211,7 +93687,7 @@ const TimeRangeWheel = ({
|
|
|
93211
93687
|
endTimeProps,
|
|
93212
93688
|
...rest
|
|
93213
93689
|
}) => {
|
|
93214
|
-
import.meta.css = [css$
|
|
93690
|
+
import.meta.css = [css$j, "@jsenv/navi/src/control/wheel/wheel_time.jsx"];
|
|
93215
93691
|
const startId = useId();
|
|
93216
93692
|
const startRef = useRef(null);
|
|
93217
93693
|
const endRef = useRef(null);
|
|
@@ -93799,7 +94275,7 @@ const Z_INDEX_DROP_PREVIEW = Z_INDEX_STICKY_CORNER + 1;
|
|
|
93799
94275
|
const Z_INDEX_TABLE_UI = Z_INDEX_STICKY_CORNER + 1;
|
|
93800
94276
|
|
|
93801
94277
|
installImportMetaCssBuild(import.meta);
|
|
93802
|
-
const css$
|
|
94278
|
+
const css$i = /* css */`.navi_table_drag_clone_container {
|
|
93803
94279
|
top: var(--table-visual-top);
|
|
93804
94280
|
left: var(--table-visual-left);
|
|
93805
94281
|
width: var(--table-visual-width);
|
|
@@ -93954,7 +94430,7 @@ const useTableDragContextValue = ({
|
|
|
93954
94430
|
}, [grabTarget, canChangeColumnOrder]);
|
|
93955
94431
|
};
|
|
93956
94432
|
const TableDragCloneContainer = /*#__PURE__*/forwardRef((props, ref) => {
|
|
93957
|
-
import.meta.css = [css$
|
|
94433
|
+
import.meta.css = [css$i, "@jsenv/navi/src/control/table/drag/table_drag.jsx"];
|
|
93958
94434
|
const {
|
|
93959
94435
|
tableId
|
|
93960
94436
|
} = props;
|
|
@@ -94253,7 +94729,7 @@ const ROW_MIN_HEIGHT = 30;
|
|
|
94253
94729
|
const ROW_MAX_HEIGHT = 100;
|
|
94254
94730
|
const COLUMN_MIN_WIDTH = 50;
|
|
94255
94731
|
const COLUMN_MAX_WIDTH = 500;
|
|
94256
|
-
const css$
|
|
94732
|
+
const css$h = /* css */`@layer navi {
|
|
94257
94733
|
.navi_table {
|
|
94258
94734
|
--table-resizer-handle-color: #063b7c;
|
|
94259
94735
|
--table-resizer-color: #387ec9;
|
|
@@ -94422,7 +94898,7 @@ const css$j = /* css */`@layer navi {
|
|
|
94422
94898
|
|
|
94423
94899
|
// Column resize components
|
|
94424
94900
|
const TableColumnResizer = props => {
|
|
94425
|
-
import.meta.css = [css$
|
|
94901
|
+
import.meta.css = [css$h, "@jsenv/navi/src/control/table/resize/table_resize.jsx"];
|
|
94426
94902
|
const defaultRef = useRef();
|
|
94427
94903
|
const ref = props.ref || defaultRef;
|
|
94428
94904
|
return jsxs("div", {
|
|
@@ -94894,7 +95370,7 @@ const findPreviousTableRow = currentRow => {
|
|
|
94894
95370
|
};
|
|
94895
95371
|
|
|
94896
95372
|
installImportMetaCssBuild(import.meta);
|
|
94897
|
-
const css$
|
|
95373
|
+
const css$g = /* css */`@layer navi {
|
|
94898
95374
|
.navi_table {
|
|
94899
95375
|
--selection-border-color: var(--navi-selection-border-color, #0078d4);
|
|
94900
95376
|
--selection-background-color: var(--navi-selection-background-color, #eaf1fd);
|
|
@@ -94988,7 +95464,7 @@ const useTableSelectionController = ({
|
|
|
94988
95464
|
onSelectionChange,
|
|
94989
95465
|
selectionColor
|
|
94990
95466
|
}) => {
|
|
94991
|
-
import.meta.css = [css$
|
|
95467
|
+
import.meta.css = [css$g, "@jsenv/navi/src/control/table/selection/table_selection.jsx"];
|
|
94992
95468
|
const selectionController = useSelectionController({
|
|
94993
95469
|
elementRef: tableRef,
|
|
94994
95470
|
layout: "grid",
|
|
@@ -95459,7 +95935,7 @@ const useTableStickyContextValue = ({
|
|
|
95459
95935
|
};
|
|
95460
95936
|
|
|
95461
95937
|
installImportMetaCssBuild(import.meta);
|
|
95462
|
-
const css$
|
|
95938
|
+
const css$f = /* css */`@layer navi {
|
|
95463
95939
|
.navi_table {
|
|
95464
95940
|
--sticky-frontier-color: silver;
|
|
95465
95941
|
--sticky-frontier-size: 12px;
|
|
@@ -95632,7 +96108,7 @@ const css$h = /* css */`@layer navi {
|
|
|
95632
96108
|
const TableStickyFrontier = ({
|
|
95633
96109
|
tableRef
|
|
95634
96110
|
}) => {
|
|
95635
|
-
import.meta.css = [css$
|
|
96111
|
+
import.meta.css = [css$f, "@jsenv/navi/src/control/table/sticky/table_sticky.jsx"];
|
|
95636
96112
|
const stickyLeftFrontierGhostRef = useRef();
|
|
95637
96113
|
const stickyLeftFrontierPreviewRef = useRef();
|
|
95638
96114
|
const stickyTopFrontierGhostRef = useRef();
|
|
@@ -95863,7 +96339,7 @@ installImportMetaCssBuild(import.meta);
|
|
|
95863
96339
|
* inset 0 -1px 0 0 color; // Bottom border
|
|
95864
96340
|
*/
|
|
95865
96341
|
|
|
95866
|
-
const css$
|
|
96342
|
+
const css$e = /* css */ `.navi_table_root {
|
|
95867
96343
|
max-width: var(--table-max-width, none);
|
|
95868
96344
|
max-height: var(--table-max-height, none);
|
|
95869
96345
|
position: relative;
|
|
@@ -96048,11 +96524,11 @@ const css$g = /* css */ `.navi_table_root {
|
|
|
96048
96524
|
// table must not carry this sheet, and a build that sees no caller drops the
|
|
96049
96525
|
// css with the function.
|
|
96050
96526
|
const installTableCss = () => {
|
|
96051
|
-
import.meta.css = [css$
|
|
96527
|
+
import.meta.css = [css$e, "@jsenv/navi/src/control/table/table_css.js"];
|
|
96052
96528
|
};
|
|
96053
96529
|
|
|
96054
96530
|
installImportMetaCssBuild(import.meta);
|
|
96055
|
-
const css$
|
|
96531
|
+
const css$d = /* css */`.navi_table_ui {
|
|
96056
96532
|
z-index: ${Z_INDEX_TABLE_UI};
|
|
96057
96533
|
pointer-events: none;
|
|
96058
96534
|
position: fixed;
|
|
@@ -96061,7 +96537,7 @@ const css$f = /* css */`.navi_table_ui {
|
|
|
96061
96537
|
}
|
|
96062
96538
|
`;
|
|
96063
96539
|
const TableUI = /*#__PURE__*/forwardRef((props, ref) => {
|
|
96064
|
-
import.meta.css = [css$
|
|
96540
|
+
import.meta.css = [css$d, "@jsenv/navi/src/control/table/table_ui.jsx"];
|
|
96065
96541
|
const {
|
|
96066
96542
|
tableRef,
|
|
96067
96543
|
tableId,
|
|
@@ -96983,7 +97459,7 @@ const normalizeKey = (key) => {
|
|
|
96983
97459
|
};
|
|
96984
97460
|
|
|
96985
97461
|
installImportMetaCssBuild(import.meta);
|
|
96986
|
-
const css$
|
|
97462
|
+
const css$c = /* css */`.navi_shortcut_container[data-visually-hidden], .navi_shortcut_button[data-visually-hidden] {
|
|
96987
97463
|
clip: rect(0, 0, 0, 0);
|
|
96988
97464
|
white-space: nowrap;
|
|
96989
97465
|
opacity: 0;
|
|
@@ -97000,7 +97476,7 @@ const css$e = /* css */`.navi_shortcut_container[data-visually-hidden], .navi_sh
|
|
|
97000
97476
|
const ActiveKeyboardShortcuts = ({
|
|
97001
97477
|
visible
|
|
97002
97478
|
}) => {
|
|
97003
|
-
import.meta.css = [css$
|
|
97479
|
+
import.meta.css = [css$c, "@jsenv/navi/src/keyboard/active_keyboard_shortcuts.jsx"];
|
|
97004
97480
|
const activeShortcuts = activeShortcutsSignal.value;
|
|
97005
97481
|
return jsx("div", {
|
|
97006
97482
|
className: "navi_shortcut_container",
|
|
@@ -97040,7 +97516,7 @@ const KeyboardShortcutAriaElement = ({
|
|
|
97040
97516
|
};
|
|
97041
97517
|
|
|
97042
97518
|
installImportMetaCssBuild(import.meta);
|
|
97043
|
-
const css$
|
|
97519
|
+
const css$b = /* css */`@layer navi {
|
|
97044
97520
|
.navi_clipboard_container {
|
|
97045
97521
|
--height: 1.5em;
|
|
97046
97522
|
--notif-spacing: .5em;
|
|
@@ -97071,7 +97547,7 @@ const ButtonCopyToClipboard = ({
|
|
|
97071
97547
|
children,
|
|
97072
97548
|
...props
|
|
97073
97549
|
}) => {
|
|
97074
|
-
import.meta.css = [css$
|
|
97550
|
+
import.meta.css = [css$b, "@jsenv/navi/src/control/input/button_copy_to_clipboard.jsx"];
|
|
97075
97551
|
const [copied, setCopied] = useState(false);
|
|
97076
97552
|
const renderedRef = useRef();
|
|
97077
97553
|
useEffect(() => {
|
|
@@ -97151,7 +97627,7 @@ const Address = ({
|
|
|
97151
97627
|
};
|
|
97152
97628
|
|
|
97153
97629
|
installImportMetaCssBuild(import.meta);
|
|
97154
|
-
const css$
|
|
97630
|
+
const css$a = /* css */`@layer navi;
|
|
97155
97631
|
|
|
97156
97632
|
.navi_text.navi_badge_count {
|
|
97157
97633
|
white-space: nowrap;
|
|
@@ -97280,7 +97756,7 @@ const BadgeCount = ({
|
|
|
97280
97756
|
lineLayout,
|
|
97281
97757
|
...props
|
|
97282
97758
|
}) => {
|
|
97283
|
-
import.meta.css = [css$
|
|
97759
|
+
import.meta.css = [css$a, "@jsenv/navi/src/text/badge_count.jsx"];
|
|
97284
97760
|
const defaultRef = useRef();
|
|
97285
97761
|
props.ref = props.ref || defaultRef;
|
|
97286
97762
|
const {
|
|
@@ -97423,7 +97899,7 @@ const BadgeCountCircle = ({
|
|
|
97423
97899
|
};
|
|
97424
97900
|
|
|
97425
97901
|
installImportMetaCssBuild(import.meta);
|
|
97426
|
-
const css$
|
|
97902
|
+
const css$9 = /* css */`@layer navi {
|
|
97427
97903
|
.navi_caption {
|
|
97428
97904
|
--color: #6b7280;
|
|
97429
97905
|
}
|
|
@@ -97443,7 +97919,7 @@ const Caption = ({
|
|
|
97443
97919
|
className,
|
|
97444
97920
|
...rest
|
|
97445
97921
|
}) => {
|
|
97446
|
-
import.meta.css = [css$
|
|
97922
|
+
import.meta.css = [css$9, "@jsenv/navi/src/text/caption.jsx"];
|
|
97447
97923
|
return jsx(Text, {
|
|
97448
97924
|
as: "small",
|
|
97449
97925
|
size: "0.8em" // We use em to be relative to the parent (we want to be smaller than the surrounding text)
|
|
@@ -97839,177 +98315,8 @@ const Interpolate = ({
|
|
|
97839
98315
|
});
|
|
97840
98316
|
};
|
|
97841
98317
|
|
|
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
98318
|
installImportMetaCssBuild(import.meta);
|
|
97880
|
-
const css$
|
|
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
|
-
installImportMetaCssBuild(import.meta);
|
|
98012
|
-
const css$9 = /* css */`@layer navi;
|
|
98319
|
+
const css$8 = /* css */`@layer navi;
|
|
98013
98320
|
|
|
98014
98321
|
.navi_quantity {
|
|
98015
98322
|
flex-direction: column;
|
|
@@ -98110,7 +98417,7 @@ const Quantity = ({
|
|
|
98110
98417
|
bold = true,
|
|
98111
98418
|
...props
|
|
98112
98419
|
}) => {
|
|
98113
|
-
import.meta.css = [css$
|
|
98420
|
+
import.meta.css = [css$8, "@jsenv/navi/src/text/quantity.jsx"];
|
|
98114
98421
|
const value = parseQuantityValue(children);
|
|
98115
98422
|
const valueRounded = integer && typeof value === "number" ? Math.round(value) : value;
|
|
98116
98423
|
const valueFormatted = typeof valueRounded === "number" ? formatNumber(valueRounded, {
|
|
@@ -98169,7 +98476,7 @@ const parseQuantityValue = children => {
|
|
|
98169
98476
|
};
|
|
98170
98477
|
|
|
98171
98478
|
installImportMetaCssBuild(import.meta);
|
|
98172
|
-
const css$
|
|
98479
|
+
const css$7 = /* css */`@layer navi {
|
|
98173
98480
|
.navi_meter {
|
|
98174
98481
|
--loader-color: var(--navi-loader-color);
|
|
98175
98482
|
--track-color: #efefef;
|
|
@@ -98308,7 +98615,7 @@ const Meter = ({
|
|
|
98308
98615
|
style,
|
|
98309
98616
|
...rest
|
|
98310
98617
|
}) => {
|
|
98311
|
-
import.meta.css = [css$
|
|
98618
|
+
import.meta.css = [css$7, "@jsenv/navi/src/text/meter.jsx"];
|
|
98312
98619
|
const defaultRef = useRef();
|
|
98313
98620
|
const ref = rest.ref || defaultRef;
|
|
98314
98621
|
value = Number(value);
|
|
@@ -98423,7 +98730,7 @@ const Paragraph = props => {
|
|
|
98423
98730
|
};
|
|
98424
98731
|
|
|
98425
98732
|
installImportMetaCssBuild(import.meta);
|
|
98426
|
-
const css$
|
|
98733
|
+
const css$6 = /* css */`.navi_text_box {
|
|
98427
98734
|
align-items: flex-start;
|
|
98428
98735
|
min-width: 0;
|
|
98429
98736
|
}
|
|
@@ -98465,7 +98772,7 @@ const TextBox = ({
|
|
|
98465
98772
|
children,
|
|
98466
98773
|
...rest
|
|
98467
98774
|
}) => {
|
|
98468
|
-
import.meta.css = [css$
|
|
98775
|
+
import.meta.css = [css$6, "@jsenv/navi/src/text/text_box.jsx"];
|
|
98469
98776
|
const boxRef = useRef(null);
|
|
98470
98777
|
const contentRef = useRef(null);
|
|
98471
98778
|
useLayoutEffect(() => {
|
|
@@ -98511,40 +98818,6 @@ const adjustWidth = (boxEl, contentEl) => {
|
|
|
98511
98818
|
contentEl.style.width = `${Math.ceil(optimalWidth)}px`;
|
|
98512
98819
|
};
|
|
98513
98820
|
|
|
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
98821
|
installImportMetaCssBuild(import.meta);
|
|
98549
98822
|
const css$5 = /* css */`@keyframes navi_image_shimmer {
|
|
98550
98823
|
0% {
|