@jsenv/navi 0.29.469 → 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 +622 -305
- package/dist/dev/jsenv_navi.js.map +22 -20
- package/dist/jsenv_navi.js +602 -305
- 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
|
};
|
|
@@ -47811,8 +47836,10 @@ const createControlInfo = (props, {
|
|
|
47811
47836
|
} else if (controlType === "details") {
|
|
47812
47837
|
statePropName = "open";
|
|
47813
47838
|
defaultStatePropName = "defaultOpen";
|
|
47814
|
-
stateInitial = props.open || props.defaultOpen;
|
|
47815
47839
|
value = props.value || "open";
|
|
47840
|
+
// Held like a checkbox: the value while open, nothing while closed — the
|
|
47841
|
+
// shape the toggle writes back (see details.jsx).
|
|
47842
|
+
stateInitial = props.open || props.defaultOpen ? value : undefined;
|
|
47816
47843
|
} else if (controlType === "picker" || controlType === "select") {
|
|
47817
47844
|
statePropName = "value";
|
|
47818
47845
|
defaultStatePropName = "defaultValue";
|
|
@@ -55877,6 +55904,9 @@ const DetailsField = props => {
|
|
|
55877
55904
|
value,
|
|
55878
55905
|
children
|
|
55879
55906
|
} = detailsProps;
|
|
55907
|
+
const {
|
|
55908
|
+
uiStateController
|
|
55909
|
+
} = controlChildrenWrapperProps;
|
|
55880
55910
|
const open = Boolean(value);
|
|
55881
55911
|
useFocusGroup(ref, {
|
|
55882
55912
|
enabled: focusGroup,
|
|
@@ -55958,6 +55988,10 @@ const DetailsField = props => {
|
|
|
55958
55988
|
return;
|
|
55959
55989
|
}
|
|
55960
55990
|
const details = ref.current;
|
|
55991
|
+
// The browser has already toggled the element (a summary press, the
|
|
55992
|
+
// arrow shortcuts): the state follows it whatever the gate says, or the
|
|
55993
|
+
// marker and whoever reads the value keep the old one.
|
|
55994
|
+
uiStateController.setUIState(details.open ? uiStateController.value : undefined, e);
|
|
55961
55995
|
dispatchRequestInteraction(details, {
|
|
55962
55996
|
event: e,
|
|
55963
55997
|
wantAction: true,
|
|
@@ -59395,6 +59429,10 @@ const Label = props => {
|
|
|
59395
59429
|
requiredIndicator
|
|
59396
59430
|
} = props;
|
|
59397
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}`;
|
|
59398
59436
|
const [disabled, setDisabled] = useState(false);
|
|
59399
59437
|
const [readOnly, setReadOnly] = useState(false);
|
|
59400
59438
|
const [required, setRequired] = useState(false);
|
|
@@ -69173,9 +69211,297 @@ const PopupClose = ({
|
|
|
69173
69211
|
});
|
|
69174
69212
|
};
|
|
69175
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
|
+
|
|
69176
69502
|
installImportMetaCssBuild(import.meta);
|
|
69177
69503
|
let openLocalDialogCount = 0;
|
|
69178
|
-
const css$
|
|
69504
|
+
const css$C = /* css */`
|
|
69179
69505
|
/* jsenv-css-opaque: popupCss overlaps these rules, own sheet = cascade
|
|
69180
69506
|
order depending on which popup renders first. */
|
|
69181
69507
|
|
|
@@ -70244,10 +70570,14 @@ const css$E = /* css */`
|
|
|
70244
70570
|
* under `"while-opened"`, only a press on what opens the popup does (a
|
|
70245
70571
|
* `--navi-open` button, a picker's trigger), never with an `onOpen`, and a
|
|
70246
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.
|
|
70247
70577
|
* @param {import("ignore:preact").ComponentChildren} props.children
|
|
70248
70578
|
*/
|
|
70249
70579
|
const Dialog = props => {
|
|
70250
|
-
import.meta.css = [css$
|
|
70580
|
+
import.meta.css = [css$C, "@jsenv/navi/src/layout/dialog.jsx"];
|
|
70251
70581
|
if (props.openController) {
|
|
70252
70582
|
return jsx(ControlledDialog, {
|
|
70253
70583
|
...props
|
|
@@ -70623,6 +70953,9 @@ const useDialogProps = props => {
|
|
|
70623
70953
|
onOpen,
|
|
70624
70954
|
children: childrenProp,
|
|
70625
70955
|
mount,
|
|
70956
|
+
// Read by usePopupName below, never written on the element.
|
|
70957
|
+
openerAriaLabel,
|
|
70958
|
+
openerAriaLabelledBy,
|
|
70626
70959
|
...rest
|
|
70627
70960
|
} = props;
|
|
70628
70961
|
// Assigned on every render, like openEffect below, so it always closes over
|
|
@@ -70633,7 +70966,16 @@ const useDialogProps = props => {
|
|
|
70633
70966
|
mount,
|
|
70634
70967
|
anchor
|
|
70635
70968
|
});
|
|
70636
|
-
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;
|
|
70637
70979
|
// Where it is placed, and whether there is a wall — the two questions that
|
|
70638
70980
|
// pick the show call (see this file's top comment).
|
|
70639
70981
|
const isTopLayer = layer === "top";
|
|
@@ -71483,6 +71825,7 @@ const useDialogProps = props => {
|
|
|
71483
71825
|
"backdropFilter": backdrop ? backdropFilter : undefined,
|
|
71484
71826
|
"styleCSSVars": DIALOG_STYLE_CSS_VARS,
|
|
71485
71827
|
...rest,
|
|
71828
|
+
...nameProps,
|
|
71486
71829
|
...autoFocusProps,
|
|
71487
71830
|
"as": "dialog",
|
|
71488
71831
|
ref,
|
|
@@ -71683,10 +72026,11 @@ const DIALOG_STYLE_CSS_VARS = {
|
|
|
71683
72026
|
maxHeight: "--dialog-max-height"
|
|
71684
72027
|
};
|
|
71685
72028
|
Dialog.Close = PopupClose;
|
|
72029
|
+
Dialog.Title = PopupTitle;
|
|
71686
72030
|
|
|
71687
72031
|
installImportMetaCssBuild(import.meta);
|
|
71688
72032
|
let openLocalPopoverCount = 0;
|
|
71689
|
-
const css$
|
|
72033
|
+
const css$B = /* css */`
|
|
71690
72034
|
/* jsenv-css-opaque: popupCss overlaps these rules, own sheet = cascade
|
|
71691
72035
|
order depending on which popup renders first. */
|
|
71692
72036
|
|
|
@@ -72285,10 +72629,17 @@ const css$D = /* css */`
|
|
|
72285
72629
|
* under `"while-opened"`, only a press on what opens the popup does (a
|
|
72286
72630
|
* `--navi-open` button, a picker's trigger), never with an `onOpen`, and a
|
|
72287
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.
|
|
72288
72639
|
* @param {import("ignore:preact").ComponentChildren} props.children
|
|
72289
72640
|
*/
|
|
72290
72641
|
const Popover = props => {
|
|
72291
|
-
import.meta.css = [css$
|
|
72642
|
+
import.meta.css = [css$B, "@jsenv/navi/src/layout/popover.jsx"];
|
|
72292
72643
|
if (props.openController) {
|
|
72293
72644
|
return jsx(ControlledPopover, {
|
|
72294
72645
|
...props
|
|
@@ -72527,6 +72878,9 @@ const usePopoverProps = props => {
|
|
|
72527
72878
|
onOpen,
|
|
72528
72879
|
children: childrenProp,
|
|
72529
72880
|
mount,
|
|
72881
|
+
// Read by usePopupName below, never written on the element.
|
|
72882
|
+
openerAriaLabel,
|
|
72883
|
+
openerAriaLabelledBy,
|
|
72530
72884
|
...rest
|
|
72531
72885
|
} = props;
|
|
72532
72886
|
// Assigned on every render, like openEffect below, so it always closes over
|
|
@@ -72537,7 +72891,16 @@ const usePopoverProps = props => {
|
|
|
72537
72891
|
mount,
|
|
72538
72892
|
anchor
|
|
72539
72893
|
});
|
|
72540
|
-
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;
|
|
72541
72904
|
const isTopLayer = layer === "top";
|
|
72542
72905
|
const ref = props.ref;
|
|
72543
72906
|
const backdropRef = useRef();
|
|
@@ -73352,6 +73715,10 @@ const usePopoverProps = props => {
|
|
|
73352
73715
|
"navi-hidden": openController.openedInDom ? undefined : "",
|
|
73353
73716
|
"styleCSSVars": POPUP_STYLE_CSS_VARS,
|
|
73354
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"),
|
|
73355
73722
|
...autoFocusProps,
|
|
73356
73723
|
ref,
|
|
73357
73724
|
// Not a control, but still something the rest of navi has to be able to
|
|
@@ -73467,9 +73834,10 @@ const resolvePositionAreaAndAnimationKind = ({
|
|
|
73467
73834
|
};
|
|
73468
73835
|
};
|
|
73469
73836
|
Popover.Close = PopupClose;
|
|
73837
|
+
Popover.Title = PopupTitle;
|
|
73470
73838
|
|
|
73471
73839
|
installImportMetaCssBuild(import.meta);
|
|
73472
|
-
const css$
|
|
73840
|
+
const css$A = /* css */`@layer navi {
|
|
73473
73841
|
.navi_popup {
|
|
73474
73842
|
--popup-border-radius: var(--navi-popup-border-radius);
|
|
73475
73843
|
--popup-border-width: 1px;
|
|
@@ -73610,6 +73978,10 @@ const css$C = /* css */`@layer navi {
|
|
|
73610
73978
|
* @param {string} [props.className] - Merged with the shared
|
|
73611
73979
|
* `"navi_popup"` class (see this file's own CSS) rather than replacing
|
|
73612
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.
|
|
73613
73985
|
* @param {"always"|"idle"|"from-first-open"|"while-opened"} [props.mount] - When
|
|
73614
73986
|
* `children` are built and thrown away (see popup_content_mount.js).
|
|
73615
73987
|
* `"from-first-open"` (the default) builds them on the first open and keeps
|
|
@@ -73625,7 +73997,7 @@ const css$C = /* css */`@layer navi {
|
|
|
73625
73997
|
* @param {import("ignore:preact").ComponentChildren} props.children
|
|
73626
73998
|
*/
|
|
73627
73999
|
const Popup = props => {
|
|
73628
|
-
import.meta.css = [css$
|
|
74000
|
+
import.meta.css = [css$A, "@jsenv/navi/src/layout/popup.jsx"];
|
|
73629
74001
|
const {
|
|
73630
74002
|
mode: modeProp,
|
|
73631
74003
|
maxWidth,
|
|
@@ -73708,6 +74080,7 @@ const Popup = props => {
|
|
|
73708
74080
|
});
|
|
73709
74081
|
};
|
|
73710
74082
|
Popup.Close = PopupClose;
|
|
74083
|
+
Popup.Title = PopupTitle;
|
|
73711
74084
|
|
|
73712
74085
|
// What Dialog's own animation values mean to a popover, which has no lift
|
|
73713
74086
|
// (see the `animation` doc above).
|
|
@@ -73756,6 +74129,54 @@ const pickerUIIsNaviOwn = ui => {
|
|
|
73756
74129
|
return Boolean(ui) && typeof ui === "object" && Boolean(ui.type?.isPickerOwnUI);
|
|
73757
74130
|
};
|
|
73758
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
|
+
|
|
73759
74180
|
/**
|
|
73760
74181
|
* What the picker holds, read from inside its `ui` — for a drawing given as
|
|
73761
74182
|
* an element (`ui={<MyCard game={game} />}`), which the picker cannot hand
|
|
@@ -73785,7 +74206,7 @@ const usePickerState = () => {
|
|
|
73785
74206
|
};
|
|
73786
74207
|
|
|
73787
74208
|
installImportMetaCssBuild(import.meta);
|
|
73788
|
-
const css$
|
|
74209
|
+
const css$z = /* css */`.navi_picker_callout_dock > [data-picker-content] {
|
|
73789
74210
|
display: none;
|
|
73790
74211
|
}
|
|
73791
74212
|
|
|
@@ -73814,7 +74235,7 @@ const css$B = /* css */`.navi_picker_callout_dock > [data-picker-content] {
|
|
|
73814
74235
|
}
|
|
73815
74236
|
}
|
|
73816
74237
|
|
|
73817
|
-
.navi_picker[
|
|
74238
|
+
.navi_picker[navi-popover-mode="overlay"][aria-expanded="true"] {
|
|
73818
74239
|
border-color: #0000;
|
|
73819
74240
|
}
|
|
73820
74241
|
|
|
@@ -73842,7 +74263,7 @@ const css$B = /* css */`.navi_picker_callout_dock > [data-picker-content] {
|
|
|
73842
74263
|
}
|
|
73843
74264
|
`;
|
|
73844
74265
|
const PickerCustomResolver = props => {
|
|
73845
|
-
import.meta.css = [css$
|
|
74266
|
+
import.meta.css = [css$z, "@jsenv/navi/src/control/picker/picker_custom.jsx"];
|
|
73846
74267
|
if (props.children === undefined) {
|
|
73847
74268
|
return renderResolver(PickerNative, props);
|
|
73848
74269
|
}
|
|
@@ -74665,6 +75086,24 @@ const isPressDisputedByHold = pickerEl => Boolean(pickerEl?.parentElement?.close
|
|
|
74665
75086
|
const getPickerInput = pickerEl => {
|
|
74666
75087
|
return pickerEl.querySelector(".navi_picker_input");
|
|
74667
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
|
+
};
|
|
74668
75107
|
const getPickerInputUIState = pickerEl => {
|
|
74669
75108
|
const pickerInput = getPickerInput(pickerEl);
|
|
74670
75109
|
return getUIStateFromElement(pickerInput);
|
|
@@ -74687,6 +75126,11 @@ const PickerContentInsidePopup = props => {
|
|
|
74687
75126
|
// Same reason: a `data-testid` on the picker names the trigger (see
|
|
74688
75127
|
// docs/testid.md) — this one names the popup.
|
|
74689
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,
|
|
74690
75134
|
positionArea,
|
|
74691
75135
|
popoverMode = "nearby",
|
|
74692
75136
|
popoverSpacing = popoverMode === "nearby" ? 5 : 0,
|
|
@@ -74748,8 +75192,25 @@ const PickerContentInsidePopup = props => {
|
|
|
74748
75192
|
} = props;
|
|
74749
75193
|
const isPopover = mode === "popover";
|
|
74750
75194
|
const isCallout = mode === "callout";
|
|
74751
|
-
|
|
74752
|
-
|
|
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",
|
|
74753
75214
|
"navi-popover-mode": isPopover ? popoverMode : undefined,
|
|
74754
75215
|
...rest,
|
|
74755
75216
|
// On popupProps already (see the picker's popup assembly); they mean
|
|
@@ -74794,11 +75255,23 @@ const PickerContentInsidePopup = props => {
|
|
|
74794
75255
|
pressOutside: pressOutside,
|
|
74795
75256
|
children: jsx(PopupModeContext.Provider, {
|
|
74796
75257
|
value: mode,
|
|
74797
|
-
children:
|
|
75258
|
+
children: jsx(PopupTitleContext.Provider, {
|
|
75259
|
+
value: null,
|
|
75260
|
+
children: children
|
|
75261
|
+
})
|
|
74798
75262
|
})
|
|
74799
75263
|
}) : jsx(Popup, {
|
|
74800
75264
|
...popupProps,
|
|
74801
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
|
|
74802
75275
|
// What the CSS above keys on: this picker's own popup, and no other
|
|
74803
75276
|
// popup below the picker.
|
|
74804
75277
|
,
|
|
@@ -75068,7 +75541,7 @@ const showNativePicker = (pickerInput, event) => {
|
|
|
75068
75541
|
};
|
|
75069
75542
|
|
|
75070
75543
|
installImportMetaCssBuild(import.meta);
|
|
75071
|
-
const css$
|
|
75544
|
+
const css$y = /* css */`.navi_picker_confirm_body {
|
|
75072
75545
|
min-width: 180px;
|
|
75073
75546
|
max-width: 320px;
|
|
75074
75547
|
padding: var(--navi-m);
|
|
@@ -75084,7 +75557,7 @@ const css$A = /* css */`.navi_picker_confirm_body {
|
|
|
75084
75557
|
}
|
|
75085
75558
|
`;
|
|
75086
75559
|
const PickerConfirmResolver = props => {
|
|
75087
|
-
import.meta.css = [css$
|
|
75560
|
+
import.meta.css = [css$y, "@jsenv/navi/src/control/picker/picker_confirm.jsx"];
|
|
75088
75561
|
const Next = useNextResolver();
|
|
75089
75562
|
if (props.type !== "confirm") {
|
|
75090
75563
|
return jsx(Next, {
|
|
@@ -75610,7 +76083,7 @@ const LoadingIndicator = ({
|
|
|
75610
76083
|
};
|
|
75611
76084
|
|
|
75612
76085
|
installImportMetaCssBuild(import.meta);
|
|
75613
|
-
const css$
|
|
76086
|
+
const css$x = /* css */`@layer navi {
|
|
75614
76087
|
.navi_separator {
|
|
75615
76088
|
--size: 1px;
|
|
75616
76089
|
--color: var(--navi-separator-color-default);
|
|
@@ -75684,7 +76157,7 @@ const Separator = ({
|
|
|
75684
76157
|
style,
|
|
75685
76158
|
...props
|
|
75686
76159
|
}) => {
|
|
75687
|
-
import.meta.css = [css$
|
|
76160
|
+
import.meta.css = [css$x, "@jsenv/navi/src/layout/separator.jsx"];
|
|
75688
76161
|
return jsx(Box, {
|
|
75689
76162
|
as: vertical ? "span" : "hr",
|
|
75690
76163
|
...props,
|
|
@@ -76478,7 +76951,7 @@ const listItemBlockedMessage = (loading, props) => {
|
|
|
76478
76951
|
};
|
|
76479
76952
|
|
|
76480
76953
|
installImportMetaCssBuild(import.meta);
|
|
76481
|
-
const css$
|
|
76954
|
+
const css$w = /* css */`@layer navi {
|
|
76482
76955
|
.navi_list_container[navi-selectable] {
|
|
76483
76956
|
--list-item-outline-width: var(--navi-focus-outline-width);
|
|
76484
76957
|
--list-item-outline-offset: calc(-1 * var(--list-item-outline-width));
|
|
@@ -76651,7 +77124,7 @@ const ListSelectableResolver = props => {
|
|
|
76651
77124
|
};
|
|
76652
77125
|
const ListSelectable = props => {
|
|
76653
77126
|
const Next = useNextResolver();
|
|
76654
|
-
import.meta.css = [css$
|
|
77127
|
+
import.meta.css = [css$w, "@jsenv/navi/src/control/list/list_selectable.jsx"];
|
|
76655
77128
|
// we allow ourselves to auto-generate a name
|
|
76656
77129
|
const defaultName = useId();
|
|
76657
77130
|
props.name = props.name || `listbox_${defaultName}`;
|
|
@@ -77320,7 +77793,7 @@ const ListRunItemContext = createContext(null);
|
|
|
77320
77793
|
// item takes its place in the collection by slot: the place is then the list's
|
|
77321
77794
|
// to move, and the item's to follow — see list_items.js.
|
|
77322
77795
|
const ListSlotContext = createContext(null);
|
|
77323
|
-
const css$
|
|
77796
|
+
const css$v = /* css */`@property --list-group-label-height {
|
|
77324
77797
|
syntax: "<length>";
|
|
77325
77798
|
inherits: false;
|
|
77326
77799
|
initial-value: 0;
|
|
@@ -77848,7 +78321,7 @@ const resolveRenderBudget = renderBudget => {
|
|
|
77848
78321
|
};
|
|
77849
78322
|
};
|
|
77850
78323
|
const ListUI = props => {
|
|
77851
|
-
import.meta.css = [css$
|
|
78324
|
+
import.meta.css = [css$v, "@jsenv/navi/src/control/list/list.jsx"];
|
|
77852
78325
|
const {
|
|
77853
78326
|
ref,
|
|
77854
78327
|
renderBudget: renderBudgetProp,
|
|
@@ -84138,7 +84611,7 @@ const createBadgeRegistry = () => {
|
|
|
84138
84611
|
};
|
|
84139
84612
|
|
|
84140
84613
|
installImportMetaCssBuild(import.meta);
|
|
84141
|
-
const css$
|
|
84614
|
+
const css$u = /* css */`@layer navi;
|
|
84142
84615
|
|
|
84143
84616
|
.navi_badge {
|
|
84144
84617
|
--font-size: .7em;
|
|
@@ -84241,7 +84714,7 @@ const BadgeUI = ({
|
|
|
84241
84714
|
className,
|
|
84242
84715
|
...props
|
|
84243
84716
|
}) => {
|
|
84244
|
-
import.meta.css = [css$
|
|
84717
|
+
import.meta.css = [css$u, "@jsenv/navi/src/text/badge.jsx"];
|
|
84245
84718
|
const defaultRef = useRef();
|
|
84246
84719
|
props.ref = props.ref || defaultRef;
|
|
84247
84720
|
const {
|
|
@@ -84349,7 +84822,7 @@ const wrapLabels = childArray => {
|
|
|
84349
84822
|
};
|
|
84350
84823
|
|
|
84351
84824
|
installImportMetaCssBuild(import.meta);
|
|
84352
|
-
const css$
|
|
84825
|
+
const css$t = /* css */`@layer navi;
|
|
84353
84826
|
|
|
84354
84827
|
.navi_badge_list {
|
|
84355
84828
|
flex-wrap: wrap;
|
|
@@ -84484,7 +84957,7 @@ const useBadgeRegistry = (children, enabled) => {
|
|
|
84484
84957
|
* component grants (a <Picker>, see max_lines_context.js).
|
|
84485
84958
|
*/
|
|
84486
84959
|
const BadgeList = props => {
|
|
84487
|
-
import.meta.css = [css$
|
|
84960
|
+
import.meta.css = [css$t, "@jsenv/navi/src/text/badge_list.jsx"];
|
|
84488
84961
|
const {
|
|
84489
84962
|
maxLines,
|
|
84490
84963
|
max,
|
|
@@ -84828,7 +85301,7 @@ const BadgeListContent = ({
|
|
|
84828
85301
|
};
|
|
84829
85302
|
|
|
84830
85303
|
installImportMetaCssBuild(import.meta);
|
|
84831
|
-
const css$
|
|
85304
|
+
const css$s = /* css */`.navi_color {
|
|
84832
85305
|
aspect-ratio: 1;
|
|
84833
85306
|
background-color: currentColor;
|
|
84834
85307
|
border: 1px solid #0003;
|
|
@@ -84848,7 +85321,7 @@ const Color = ({
|
|
|
84848
85321
|
children,
|
|
84849
85322
|
...rest
|
|
84850
85323
|
}) => {
|
|
84851
|
-
import.meta.css = [css$
|
|
85324
|
+
import.meta.css = [css$s, "@jsenv/navi/src/text/color.jsx"];
|
|
84852
85325
|
const color = children || undefined;
|
|
84853
85326
|
return jsx(Box, {
|
|
84854
85327
|
as: "span",
|
|
@@ -85335,7 +85808,7 @@ const PickerFileUI = /*#__PURE__*/asPickerOwnUI(() => {
|
|
|
85335
85808
|
});
|
|
85336
85809
|
|
|
85337
85810
|
installImportMetaCssBuild(import.meta);
|
|
85338
|
-
const css$
|
|
85811
|
+
const css$r = /* css */`@layer navi {
|
|
85339
85812
|
.navi_picker {
|
|
85340
85813
|
--picker-border-radius: var(--navi-control-border-radius);
|
|
85341
85814
|
--picker-border-width: var(--navi-control-border-width);
|
|
@@ -85804,7 +86277,7 @@ const css$t = /* css */`@layer navi {
|
|
|
85804
86277
|
}
|
|
85805
86278
|
`;
|
|
85806
86279
|
const PickerButton = props => {
|
|
85807
|
-
import.meta.css = [css$
|
|
86280
|
+
import.meta.css = [css$r, "@jsenv/navi/src/control/picker/picker.jsx"];
|
|
85808
86281
|
warnOnUnknownPickerType(props);
|
|
85809
86282
|
warnOnUIDrawnByNobody(props);
|
|
85810
86283
|
if (typeof props.maxLines === "string") {
|
|
@@ -85847,11 +86320,6 @@ const PickerButton = props => {
|
|
|
85847
86320
|
// confirm resolver (see picker_confirm.jsx), which is the picker that is
|
|
85848
86321
|
// one — a caller whose popup is a menu of actions says it for themselves.
|
|
85849
86322
|
picksNothing,
|
|
85850
|
-
// Where the caller's own role goes: onto the host, beside the name (see
|
|
85851
|
-
// control_context.js) — a role and a name on two different elements name
|
|
85852
|
-
// nothing at all. Left unsaid, a picker that picks nothing takes "button"
|
|
85853
|
-
// (see PickerInput below).
|
|
85854
|
-
role,
|
|
85855
86323
|
readOnly,
|
|
85856
86324
|
error,
|
|
85857
86325
|
// Who draws the loading outline. Left unsaid, the picker does, around its
|
|
@@ -85934,21 +86402,8 @@ const PickerButton = props => {
|
|
|
85934
86402
|
// clearing being a modification like any other.
|
|
85935
86403
|
const interactive = !basePseudoState[":disabled"] && !basePseudoState[":read-only"] && !loading;
|
|
85936
86404
|
usePickerErrorCallout(uiStateController, error);
|
|
85937
|
-
|
|
85938
|
-
|
|
85939
|
-
// door — its popup is a question (type="confirm") or something to read
|
|
85940
|
-
// (mode="callout", which says it for itself) — and a door is pressed. So it
|
|
85941
|
-
// answers to "button" rather than to the "textbox" its <input> would
|
|
85942
|
-
// otherwise be, which is both what a screen reader announces and what
|
|
85943
|
-
// getByRole("button", { name }) finds. A picker holding a value stays a
|
|
85944
|
-
// textbox: it does hold text.
|
|
85945
|
-
const hostRole = role ?? (picksNothing ? "button" : undefined);
|
|
85946
|
-
// And what that button is called, when the caller wrote it as a drawing
|
|
85947
|
-
// rather than as a word: a door draws no value, so what sits in its value
|
|
85948
|
-
// slot IS its label — the `ui` a caller gave it, or its placeholder. Skipped
|
|
85949
|
-
// the moment the caller names it themselves (aria-label/aria-labelledby),
|
|
85950
|
-
// which is the only way to name a door drawn as an icon.
|
|
85951
|
-
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);
|
|
85952
86407
|
// What the picker knows about itself, for the pieces it does not place: the
|
|
85953
86408
|
// drawings of its value (Picker.UI.*), and the affordances a caller may put
|
|
85954
86409
|
// in their own `ui` (Picker.Clear) as much as the ones it puts in its slot.
|
|
@@ -86017,8 +86472,16 @@ const PickerButton = props => {
|
|
|
86017
86472
|
basePseudoState: basePseudoState,
|
|
86018
86473
|
styleCSSVars: PickerStyleCSSVars,
|
|
86019
86474
|
variant: undefined,
|
|
86020
|
-
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
|
+
,
|
|
86021
86483
|
role: undefined,
|
|
86484
|
+
"aria-haspopup": undefined,
|
|
86022
86485
|
rightSlotIcon: undefined,
|
|
86023
86486
|
rightSlotIconSize: undefined,
|
|
86024
86487
|
rightSlot: undefined,
|
|
@@ -86058,6 +86521,8 @@ const PickerButton = props => {
|
|
|
86058
86521
|
inset: loadingOutlineInset
|
|
86059
86522
|
}), jsx(PickerInput, {
|
|
86060
86523
|
role: hostRole,
|
|
86524
|
+
"aria-haspopup": props["aria-haspopup"],
|
|
86525
|
+
"aria-expanded": props["aria-expanded"],
|
|
86061
86526
|
"aria-labelledby": hostLabelId,
|
|
86062
86527
|
tabIndex: variant === "headless" ? -1 : undefined,
|
|
86063
86528
|
"aria-hidden": variant === "headless" ? "true" : undefined,
|
|
@@ -86565,6 +87030,10 @@ const PickerFirstResolver = props => {
|
|
|
86565
87030
|
* Without `children`, opens the browser-native picker for the given `type`.
|
|
86566
87031
|
* With `children`, opens a popover (desktop) or dialog (mobile) containing the children.
|
|
86567
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).
|
|
86568
87037
|
*
|
|
86569
87038
|
* `type="confirm"` is the picker that asks "are you sure?" before doing what it
|
|
86570
87039
|
* stands for: its popup is the question, `ui` its label, and yes runs its
|
|
@@ -86638,6 +87107,9 @@ const PickerFirstResolver = props => {
|
|
|
86638
87107
|
* standalone?: boolean,
|
|
86639
87108
|
* popupLayer?: "top" | "local",
|
|
86640
87109
|
* popupTestId?: string,
|
|
87110
|
+
* popupAriaLabel?: string,
|
|
87111
|
+
* popupAriaLabelledBy?: string,
|
|
87112
|
+
* popupAriaDescribedBy?: string,
|
|
86641
87113
|
* confirmTestId?: string,
|
|
86642
87114
|
* cancelTestId?: string,
|
|
86643
87115
|
* mount?: "always" | "idle" | "from-first-open" | "while-opened",
|
|
@@ -87097,6 +87569,19 @@ const PickerFirstResolver = props => {
|
|
|
87097
87569
|
* not only what it holds, which a testid inside the children already names.
|
|
87098
87570
|
* Under `mode="callout"` it names the callout element — the control's own,
|
|
87099
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.
|
|
87100
87585
|
* @param {string} [confirmTestId] `type="confirm"`, default body: the
|
|
87101
87586
|
* `data-testid` of the yes button; `cancelTestId` that of the no button.
|
|
87102
87587
|
* Both are elements navi builds, which a test may not name by class (see
|
|
@@ -87234,7 +87719,7 @@ const Picker = /*#__PURE__*/Object.assign(PickerResolved, {
|
|
|
87234
87719
|
});
|
|
87235
87720
|
|
|
87236
87721
|
installImportMetaCssBuild(import.meta);
|
|
87237
|
-
const css$
|
|
87722
|
+
const css$q = /* css */`@layer navi {
|
|
87238
87723
|
.navi_picker_spin {
|
|
87239
87724
|
--picker-spin-padding-x-default: var(--navi-picker-padding-x-default);
|
|
87240
87725
|
--picker-spin-padding-y-default: var(--navi-picker-padding-y-default);
|
|
@@ -87584,7 +88069,7 @@ const Spin = ({
|
|
|
87584
88069
|
nextLabel,
|
|
87585
88070
|
...rest
|
|
87586
88071
|
}) => {
|
|
87587
|
-
import.meta.css = [css$
|
|
88072
|
+
import.meta.css = [css$q, "@jsenv/navi/src/control/picker/picker_spin.jsx"];
|
|
87588
88073
|
const id = useId();
|
|
87589
88074
|
// What the group around it says, when there is one: how big the whole thing
|
|
87590
88075
|
// is written is said once, on the group, and every spin in it follows.
|
|
@@ -87958,7 +88443,42 @@ const Spin = ({
|
|
|
87958
88443
|
variant: "discrete",
|
|
87959
88444
|
outlineWidth: group ? undefined : "0",
|
|
87960
88445
|
textAlign: "center",
|
|
87961
|
-
expandX: true
|
|
88446
|
+
expandX: true
|
|
88447
|
+
// The arrow keys are the chevrons at the keyboard: one step the way
|
|
88448
|
+
// the spin steps (`valueAtStep`, round at the ends when it loops),
|
|
88449
|
+
// refused at a bound in the chevron's words. The field's own
|
|
88450
|
+
// stepping (input_resolver_mode) stands down on a prevented keydown.
|
|
88451
|
+
,
|
|
88452
|
+
onKeyDown: e => {
|
|
88453
|
+
controlProps?.onKeyDown?.(e);
|
|
88454
|
+
if (e.defaultPrevented) {
|
|
88455
|
+
return;
|
|
88456
|
+
}
|
|
88457
|
+
if (e.key !== "ArrowUp" && e.key !== "ArrowDown") {
|
|
88458
|
+
return;
|
|
88459
|
+
}
|
|
88460
|
+
// Up is towards the bigger values however the spin lies: what a
|
|
88461
|
+
// field means by it, and what ▲ means on a NumberSpin.
|
|
88462
|
+
const isNext = e.key === "ArrowUp";
|
|
88463
|
+
if (!(isNext ? nextAllowed : previousAllowed)) {
|
|
88464
|
+
e.preventDefault();
|
|
88465
|
+
openCallout(boundMessage(isNext), {
|
|
88466
|
+
anchorElement: middleRef.current,
|
|
88467
|
+
status: "info",
|
|
88468
|
+
openingEvent: e
|
|
88469
|
+
});
|
|
88470
|
+
return;
|
|
88471
|
+
}
|
|
88472
|
+
dispatchRequestInteraction(e.currentTarget, {
|
|
88473
|
+
event: e,
|
|
88474
|
+
name: "--navi-arrow-up-down",
|
|
88475
|
+
prevented: () => e.preventDefault(),
|
|
88476
|
+
allowed: () => {
|
|
88477
|
+
setValue(isNext ? valueNext : valuePrevious, e);
|
|
88478
|
+
e.preventDefault();
|
|
88479
|
+
}
|
|
88480
|
+
});
|
|
88481
|
+
},
|
|
87962
88482
|
uiAction: (valueNext, event) => {
|
|
87963
88483
|
uiAction?.(valueNext, stepEventRef.current ?? event);
|
|
87964
88484
|
}
|
|
@@ -88260,7 +88780,7 @@ const renderValueDefault = value => String(value ?? "");
|
|
|
88260
88780
|
* are passed on to the spins sitting in them.
|
|
88261
88781
|
*/
|
|
88262
88782
|
const SpinGroup = props => {
|
|
88263
|
-
import.meta.css = [css$
|
|
88783
|
+
import.meta.css = [css$q, "@jsenv/navi/src/control/picker/picker_spin.jsx"];
|
|
88264
88784
|
const {
|
|
88265
88785
|
size
|
|
88266
88786
|
} = props;
|
|
@@ -88769,7 +89289,7 @@ const TimeRangeSpin = ({
|
|
|
88769
89289
|
};
|
|
88770
89290
|
|
|
88771
89291
|
installImportMetaCssBuild(import.meta);
|
|
88772
|
-
const css$
|
|
89292
|
+
const css$p = /* css */`.navi_checkbox_group {
|
|
88773
89293
|
border-style: solid;
|
|
88774
89294
|
|
|
88775
89295
|
&[data-callout] {
|
|
@@ -88829,7 +89349,7 @@ const CheckboxGroup = props => {
|
|
|
88829
89349
|
return checkboxGroup;
|
|
88830
89350
|
};
|
|
88831
89351
|
const CheckboxGroupInterface = props => {
|
|
88832
|
-
import.meta.css = [css$
|
|
89352
|
+
import.meta.css = [css$p, "@jsenv/navi/src/control/input/checkbox_group.jsx"];
|
|
88833
89353
|
const {
|
|
88834
89354
|
ref
|
|
88835
89355
|
} = props;
|
|
@@ -88947,7 +89467,7 @@ const formatIntlUnit = (unit, {
|
|
|
88947
89467
|
};
|
|
88948
89468
|
|
|
88949
89469
|
installImportMetaCssBuild(import.meta);
|
|
88950
|
-
const css$
|
|
89470
|
+
const css$o = /* css */`.navi_input_duration {
|
|
88951
89471
|
--duration-separator-spacing: 4px;
|
|
88952
89472
|
--loader-color: var(--navi-loader-color);
|
|
88953
89473
|
position: relative;
|
|
@@ -89012,7 +89532,7 @@ const css$q = /* css */`.navi_input_duration {
|
|
|
89012
89532
|
* "auto" aligns each field toward its neighbouring separator (first→right, last→left, middle/solo→center).
|
|
89013
89533
|
*/
|
|
89014
89534
|
const InputDuration = props => {
|
|
89015
|
-
import.meta.css = [css$
|
|
89535
|
+
import.meta.css = [css$o, "@jsenv/navi/src/control/input/input_duration.jsx"];
|
|
89016
89536
|
const defaultRef = useRef();
|
|
89017
89537
|
props.ref = props.ref || defaultRef;
|
|
89018
89538
|
props.max = props.max || "23h59";
|
|
@@ -89513,7 +90033,7 @@ const InputDurationPart = ({
|
|
|
89513
90033
|
};
|
|
89514
90034
|
|
|
89515
90035
|
installImportMetaCssBuild(import.meta);
|
|
89516
|
-
const css$
|
|
90036
|
+
const css$n = /* css */`.navi_radio_group {
|
|
89517
90037
|
border-style: solid;
|
|
89518
90038
|
|
|
89519
90039
|
&[data-callout] {
|
|
@@ -89553,7 +90073,7 @@ const RadioGroup = props => {
|
|
|
89553
90073
|
return radioGroup;
|
|
89554
90074
|
};
|
|
89555
90075
|
const RadioGroupInterface = props => {
|
|
89556
|
-
import.meta.css = [css$
|
|
90076
|
+
import.meta.css = [css$n, "@jsenv/navi/src/control/input/radio_group.jsx"];
|
|
89557
90077
|
const {
|
|
89558
90078
|
ref
|
|
89559
90079
|
} = props;
|
|
@@ -89583,7 +90103,7 @@ const RadioGroupInterface = props => {
|
|
|
89583
90103
|
};
|
|
89584
90104
|
|
|
89585
90105
|
installImportMetaCssBuild(import.meta);
|
|
89586
|
-
const css$
|
|
90106
|
+
const css$m = /* css */`.navi_input.navi_select {
|
|
89587
90107
|
& .navi_control_input {
|
|
89588
90108
|
padding-right: calc(var(--x-padding-right) + 1em);
|
|
89589
90109
|
line-height: var(--navi-control-line-height);
|
|
@@ -89630,7 +90150,7 @@ const Select = ({
|
|
|
89630
90150
|
...props
|
|
89631
90151
|
}) => {
|
|
89632
90152
|
installInputCss();
|
|
89633
|
-
import.meta.css = [css$
|
|
90153
|
+
import.meta.css = [css$m, "@jsenv/navi/src/control/input/select.jsx"];
|
|
89634
90154
|
const defaultRef = useRef(null);
|
|
89635
90155
|
props.ref = props.ref || defaultRef;
|
|
89636
90156
|
seedDefaultValueFromSignal(props);
|
|
@@ -89683,7 +90203,7 @@ const Select = ({
|
|
|
89683
90203
|
};
|
|
89684
90204
|
|
|
89685
90205
|
installImportMetaCssBuild(import.meta);
|
|
89686
|
-
const css$
|
|
90206
|
+
const css$l = /* css */`.navi_split_button {
|
|
89687
90207
|
border-radius: var(--navi-control-border-radius);
|
|
89688
90208
|
display: inline-flex;
|
|
89689
90209
|
position: relative;
|
|
@@ -89805,7 +90325,7 @@ const css$n = /* css */`.navi_split_button {
|
|
|
89805
90325
|
* on the split button's own box.
|
|
89806
90326
|
*/
|
|
89807
90327
|
const SplitButton = props => {
|
|
89808
|
-
import.meta.css = [css$
|
|
90328
|
+
import.meta.css = [css$l, "@jsenv/navi/src/control/input/split_button.jsx"];
|
|
89809
90329
|
const {
|
|
89810
90330
|
options = [],
|
|
89811
90331
|
value,
|
|
@@ -90824,7 +91344,7 @@ const createItemTracker = (onChange) => {
|
|
|
90824
91344
|
};
|
|
90825
91345
|
|
|
90826
91346
|
installImportMetaCssBuild(import.meta);
|
|
90827
|
-
const css$
|
|
91347
|
+
const css$k = /* css */`.navi_wheel_container {
|
|
90828
91348
|
--wheel-item-height: round(1.8em, 1px);
|
|
90829
91349
|
--wheel-emphasis-size: round(1.5em, 1px);
|
|
90830
91350
|
--wheel-item-width: 3.5ch;
|
|
@@ -91773,7 +92293,7 @@ const useWheelKeyboard = ({
|
|
|
91773
92293
|
}, [isHorizontal, interactive, isLoop]);
|
|
91774
92294
|
};
|
|
91775
92295
|
function WheelUI(props) {
|
|
91776
|
-
import.meta.css = [css$
|
|
92296
|
+
import.meta.css = [css$k, "@jsenv/navi/src/control/wheel/wheel.jsx"];
|
|
91777
92297
|
const {
|
|
91778
92298
|
ref,
|
|
91779
92299
|
visibleCount = 3,
|
|
@@ -92770,7 +93290,7 @@ Wheel.Item = WheelItem;
|
|
|
92770
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.
|
|
92771
93291
|
*/
|
|
92772
93292
|
const WheelGroup = props => {
|
|
92773
|
-
import.meta.css = [css$
|
|
93293
|
+
import.meta.css = [css$k, "@jsenv/navi/src/control/wheel/wheel.jsx"];
|
|
92774
93294
|
// WheelGroup IS a control group: it aggregates its named wheels ("hours",
|
|
92775
93295
|
// "minutes"…) into one object value, so it can sit directly inside a Form or a
|
|
92776
93296
|
// Picker with no extra <ControlGroup> wrapper. The wheel-specific presentation
|
|
@@ -92943,7 +93463,7 @@ const WheelColon = props => {
|
|
|
92943
93463
|
Wheel.Colon = WheelColon;
|
|
92944
93464
|
|
|
92945
93465
|
installImportMetaCssBuild(import.meta);
|
|
92946
|
-
const css$
|
|
93466
|
+
const css$j = /* css */`.navi_time_range_label {
|
|
92947
93467
|
--wheel-item-height: round(1.8em, 1px);
|
|
92948
93468
|
color: var(--wheel-color, light-dark(#111, #eee));
|
|
92949
93469
|
line-height: var(--wheel-item-height);
|
|
@@ -93167,7 +93687,7 @@ const TimeRangeWheel = ({
|
|
|
93167
93687
|
endTimeProps,
|
|
93168
93688
|
...rest
|
|
93169
93689
|
}) => {
|
|
93170
|
-
import.meta.css = [css$
|
|
93690
|
+
import.meta.css = [css$j, "@jsenv/navi/src/control/wheel/wheel_time.jsx"];
|
|
93171
93691
|
const startId = useId();
|
|
93172
93692
|
const startRef = useRef(null);
|
|
93173
93693
|
const endRef = useRef(null);
|
|
@@ -93755,7 +94275,7 @@ const Z_INDEX_DROP_PREVIEW = Z_INDEX_STICKY_CORNER + 1;
|
|
|
93755
94275
|
const Z_INDEX_TABLE_UI = Z_INDEX_STICKY_CORNER + 1;
|
|
93756
94276
|
|
|
93757
94277
|
installImportMetaCssBuild(import.meta);
|
|
93758
|
-
const css$
|
|
94278
|
+
const css$i = /* css */`.navi_table_drag_clone_container {
|
|
93759
94279
|
top: var(--table-visual-top);
|
|
93760
94280
|
left: var(--table-visual-left);
|
|
93761
94281
|
width: var(--table-visual-width);
|
|
@@ -93910,7 +94430,7 @@ const useTableDragContextValue = ({
|
|
|
93910
94430
|
}, [grabTarget, canChangeColumnOrder]);
|
|
93911
94431
|
};
|
|
93912
94432
|
const TableDragCloneContainer = /*#__PURE__*/forwardRef((props, ref) => {
|
|
93913
|
-
import.meta.css = [css$
|
|
94433
|
+
import.meta.css = [css$i, "@jsenv/navi/src/control/table/drag/table_drag.jsx"];
|
|
93914
94434
|
const {
|
|
93915
94435
|
tableId
|
|
93916
94436
|
} = props;
|
|
@@ -94209,7 +94729,7 @@ const ROW_MIN_HEIGHT = 30;
|
|
|
94209
94729
|
const ROW_MAX_HEIGHT = 100;
|
|
94210
94730
|
const COLUMN_MIN_WIDTH = 50;
|
|
94211
94731
|
const COLUMN_MAX_WIDTH = 500;
|
|
94212
|
-
const css$
|
|
94732
|
+
const css$h = /* css */`@layer navi {
|
|
94213
94733
|
.navi_table {
|
|
94214
94734
|
--table-resizer-handle-color: #063b7c;
|
|
94215
94735
|
--table-resizer-color: #387ec9;
|
|
@@ -94378,7 +94898,7 @@ const css$j = /* css */`@layer navi {
|
|
|
94378
94898
|
|
|
94379
94899
|
// Column resize components
|
|
94380
94900
|
const TableColumnResizer = props => {
|
|
94381
|
-
import.meta.css = [css$
|
|
94901
|
+
import.meta.css = [css$h, "@jsenv/navi/src/control/table/resize/table_resize.jsx"];
|
|
94382
94902
|
const defaultRef = useRef();
|
|
94383
94903
|
const ref = props.ref || defaultRef;
|
|
94384
94904
|
return jsxs("div", {
|
|
@@ -94850,7 +95370,7 @@ const findPreviousTableRow = currentRow => {
|
|
|
94850
95370
|
};
|
|
94851
95371
|
|
|
94852
95372
|
installImportMetaCssBuild(import.meta);
|
|
94853
|
-
const css$
|
|
95373
|
+
const css$g = /* css */`@layer navi {
|
|
94854
95374
|
.navi_table {
|
|
94855
95375
|
--selection-border-color: var(--navi-selection-border-color, #0078d4);
|
|
94856
95376
|
--selection-background-color: var(--navi-selection-background-color, #eaf1fd);
|
|
@@ -94944,7 +95464,7 @@ const useTableSelectionController = ({
|
|
|
94944
95464
|
onSelectionChange,
|
|
94945
95465
|
selectionColor
|
|
94946
95466
|
}) => {
|
|
94947
|
-
import.meta.css = [css$
|
|
95467
|
+
import.meta.css = [css$g, "@jsenv/navi/src/control/table/selection/table_selection.jsx"];
|
|
94948
95468
|
const selectionController = useSelectionController({
|
|
94949
95469
|
elementRef: tableRef,
|
|
94950
95470
|
layout: "grid",
|
|
@@ -95415,7 +95935,7 @@ const useTableStickyContextValue = ({
|
|
|
95415
95935
|
};
|
|
95416
95936
|
|
|
95417
95937
|
installImportMetaCssBuild(import.meta);
|
|
95418
|
-
const css$
|
|
95938
|
+
const css$f = /* css */`@layer navi {
|
|
95419
95939
|
.navi_table {
|
|
95420
95940
|
--sticky-frontier-color: silver;
|
|
95421
95941
|
--sticky-frontier-size: 12px;
|
|
@@ -95588,7 +96108,7 @@ const css$h = /* css */`@layer navi {
|
|
|
95588
96108
|
const TableStickyFrontier = ({
|
|
95589
96109
|
tableRef
|
|
95590
96110
|
}) => {
|
|
95591
|
-
import.meta.css = [css$
|
|
96111
|
+
import.meta.css = [css$f, "@jsenv/navi/src/control/table/sticky/table_sticky.jsx"];
|
|
95592
96112
|
const stickyLeftFrontierGhostRef = useRef();
|
|
95593
96113
|
const stickyLeftFrontierPreviewRef = useRef();
|
|
95594
96114
|
const stickyTopFrontierGhostRef = useRef();
|
|
@@ -95819,7 +96339,7 @@ installImportMetaCssBuild(import.meta);
|
|
|
95819
96339
|
* inset 0 -1px 0 0 color; // Bottom border
|
|
95820
96340
|
*/
|
|
95821
96341
|
|
|
95822
|
-
const css$
|
|
96342
|
+
const css$e = /* css */ `.navi_table_root {
|
|
95823
96343
|
max-width: var(--table-max-width, none);
|
|
95824
96344
|
max-height: var(--table-max-height, none);
|
|
95825
96345
|
position: relative;
|
|
@@ -96004,11 +96524,11 @@ const css$g = /* css */ `.navi_table_root {
|
|
|
96004
96524
|
// table must not carry this sheet, and a build that sees no caller drops the
|
|
96005
96525
|
// css with the function.
|
|
96006
96526
|
const installTableCss = () => {
|
|
96007
|
-
import.meta.css = [css$
|
|
96527
|
+
import.meta.css = [css$e, "@jsenv/navi/src/control/table/table_css.js"];
|
|
96008
96528
|
};
|
|
96009
96529
|
|
|
96010
96530
|
installImportMetaCssBuild(import.meta);
|
|
96011
|
-
const css$
|
|
96531
|
+
const css$d = /* css */`.navi_table_ui {
|
|
96012
96532
|
z-index: ${Z_INDEX_TABLE_UI};
|
|
96013
96533
|
pointer-events: none;
|
|
96014
96534
|
position: fixed;
|
|
@@ -96017,7 +96537,7 @@ const css$f = /* css */`.navi_table_ui {
|
|
|
96017
96537
|
}
|
|
96018
96538
|
`;
|
|
96019
96539
|
const TableUI = /*#__PURE__*/forwardRef((props, ref) => {
|
|
96020
|
-
import.meta.css = [css$
|
|
96540
|
+
import.meta.css = [css$d, "@jsenv/navi/src/control/table/table_ui.jsx"];
|
|
96021
96541
|
const {
|
|
96022
96542
|
tableRef,
|
|
96023
96543
|
tableId,
|
|
@@ -96939,7 +97459,7 @@ const normalizeKey = (key) => {
|
|
|
96939
97459
|
};
|
|
96940
97460
|
|
|
96941
97461
|
installImportMetaCssBuild(import.meta);
|
|
96942
|
-
const css$
|
|
97462
|
+
const css$c = /* css */`.navi_shortcut_container[data-visually-hidden], .navi_shortcut_button[data-visually-hidden] {
|
|
96943
97463
|
clip: rect(0, 0, 0, 0);
|
|
96944
97464
|
white-space: nowrap;
|
|
96945
97465
|
opacity: 0;
|
|
@@ -96956,7 +97476,7 @@ const css$e = /* css */`.navi_shortcut_container[data-visually-hidden], .navi_sh
|
|
|
96956
97476
|
const ActiveKeyboardShortcuts = ({
|
|
96957
97477
|
visible
|
|
96958
97478
|
}) => {
|
|
96959
|
-
import.meta.css = [css$
|
|
97479
|
+
import.meta.css = [css$c, "@jsenv/navi/src/keyboard/active_keyboard_shortcuts.jsx"];
|
|
96960
97480
|
const activeShortcuts = activeShortcutsSignal.value;
|
|
96961
97481
|
return jsx("div", {
|
|
96962
97482
|
className: "navi_shortcut_container",
|
|
@@ -96996,7 +97516,7 @@ const KeyboardShortcutAriaElement = ({
|
|
|
96996
97516
|
};
|
|
96997
97517
|
|
|
96998
97518
|
installImportMetaCssBuild(import.meta);
|
|
96999
|
-
const css$
|
|
97519
|
+
const css$b = /* css */`@layer navi {
|
|
97000
97520
|
.navi_clipboard_container {
|
|
97001
97521
|
--height: 1.5em;
|
|
97002
97522
|
--notif-spacing: .5em;
|
|
@@ -97027,7 +97547,7 @@ const ButtonCopyToClipboard = ({
|
|
|
97027
97547
|
children,
|
|
97028
97548
|
...props
|
|
97029
97549
|
}) => {
|
|
97030
|
-
import.meta.css = [css$
|
|
97550
|
+
import.meta.css = [css$b, "@jsenv/navi/src/control/input/button_copy_to_clipboard.jsx"];
|
|
97031
97551
|
const [copied, setCopied] = useState(false);
|
|
97032
97552
|
const renderedRef = useRef();
|
|
97033
97553
|
useEffect(() => {
|
|
@@ -97107,7 +97627,7 @@ const Address = ({
|
|
|
97107
97627
|
};
|
|
97108
97628
|
|
|
97109
97629
|
installImportMetaCssBuild(import.meta);
|
|
97110
|
-
const css$
|
|
97630
|
+
const css$a = /* css */`@layer navi;
|
|
97111
97631
|
|
|
97112
97632
|
.navi_text.navi_badge_count {
|
|
97113
97633
|
white-space: nowrap;
|
|
@@ -97236,7 +97756,7 @@ const BadgeCount = ({
|
|
|
97236
97756
|
lineLayout,
|
|
97237
97757
|
...props
|
|
97238
97758
|
}) => {
|
|
97239
|
-
import.meta.css = [css$
|
|
97759
|
+
import.meta.css = [css$a, "@jsenv/navi/src/text/badge_count.jsx"];
|
|
97240
97760
|
const defaultRef = useRef();
|
|
97241
97761
|
props.ref = props.ref || defaultRef;
|
|
97242
97762
|
const {
|
|
@@ -97379,7 +97899,7 @@ const BadgeCountCircle = ({
|
|
|
97379
97899
|
};
|
|
97380
97900
|
|
|
97381
97901
|
installImportMetaCssBuild(import.meta);
|
|
97382
|
-
const css$
|
|
97902
|
+
const css$9 = /* css */`@layer navi {
|
|
97383
97903
|
.navi_caption {
|
|
97384
97904
|
--color: #6b7280;
|
|
97385
97905
|
}
|
|
@@ -97399,7 +97919,7 @@ const Caption = ({
|
|
|
97399
97919
|
className,
|
|
97400
97920
|
...rest
|
|
97401
97921
|
}) => {
|
|
97402
|
-
import.meta.css = [css$
|
|
97922
|
+
import.meta.css = [css$9, "@jsenv/navi/src/text/caption.jsx"];
|
|
97403
97923
|
return jsx(Text, {
|
|
97404
97924
|
as: "small",
|
|
97405
97925
|
size: "0.8em" // We use em to be relative to the parent (we want to be smaller than the surrounding text)
|
|
@@ -97795,177 +98315,8 @@ const Interpolate = ({
|
|
|
97795
98315
|
});
|
|
97796
98316
|
};
|
|
97797
98317
|
|
|
97798
|
-
const SuccessSvg = () => {
|
|
97799
|
-
return jsx("svg", {
|
|
97800
|
-
viewBox: "0 0 16 16",
|
|
97801
|
-
fill: "currentColor",
|
|
97802
|
-
children: jsx("path", {
|
|
97803
|
-
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"
|
|
97804
|
-
})
|
|
97805
|
-
});
|
|
97806
|
-
};
|
|
97807
|
-
const ErrorSvg = () => {
|
|
97808
|
-
return jsx("svg", {
|
|
97809
|
-
viewBox: "0 0 16 16",
|
|
97810
|
-
fill: "currentColor",
|
|
97811
|
-
children: jsx("path", {
|
|
97812
|
-
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"
|
|
97813
|
-
})
|
|
97814
|
-
});
|
|
97815
|
-
};
|
|
97816
|
-
const InfoSvg$1 = () => {
|
|
97817
|
-
return jsx("svg", {
|
|
97818
|
-
viewBox: "0 0 16 16",
|
|
97819
|
-
fill: "currentColor",
|
|
97820
|
-
children: jsx("path", {
|
|
97821
|
-
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"
|
|
97822
|
-
})
|
|
97823
|
-
});
|
|
97824
|
-
};
|
|
97825
|
-
const WarningSvg = () => {
|
|
97826
|
-
return jsx("svg", {
|
|
97827
|
-
viewBox: "0 0 16 16",
|
|
97828
|
-
fill: "currentColor",
|
|
97829
|
-
children: jsx("path", {
|
|
97830
|
-
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"
|
|
97831
|
-
})
|
|
97832
|
-
});
|
|
97833
|
-
};
|
|
97834
|
-
|
|
97835
98318
|
installImportMetaCssBuild(import.meta);
|
|
97836
|
-
const css$
|
|
97837
|
-
.navi_message_box {
|
|
97838
|
-
--background-color-info: var(--navi-info-color-light);
|
|
97839
|
-
--color-info: var(--navi-info-color);
|
|
97840
|
-
--background-color-success: var(--navi-success-color-light);
|
|
97841
|
-
--color-success: var(--navi-success-color);
|
|
97842
|
-
--background-color-warning: var(--navi-warning-color-light);
|
|
97843
|
-
--color-warning: var(--navi-warning-color);
|
|
97844
|
-
--background-color-error: var(--navi-error-color-light);
|
|
97845
|
-
--color-error: var(--navi-error-color);
|
|
97846
|
-
}
|
|
97847
|
-
}
|
|
97848
|
-
|
|
97849
|
-
.navi_message_box {
|
|
97850
|
-
--x-message-background-color: var(--background-color-info);
|
|
97851
|
-
--x-message-color: var(--color-info);
|
|
97852
|
-
background-color: var(--x-message-background-color);
|
|
97853
|
-
|
|
97854
|
-
& > .navi_icon {
|
|
97855
|
-
flex-shrink: 0;
|
|
97856
|
-
}
|
|
97857
|
-
}
|
|
97858
|
-
|
|
97859
|
-
.navi_message_box[data-status-info] {
|
|
97860
|
-
--x-message-background-color: var(--background-color-info);
|
|
97861
|
-
--x-message-color: var(--color-info);
|
|
97862
|
-
}
|
|
97863
|
-
|
|
97864
|
-
.navi_message_box[data-status-success] {
|
|
97865
|
-
--x-message-background-color: var(--background-color-success);
|
|
97866
|
-
--x-message-color: var(--color-success);
|
|
97867
|
-
}
|
|
97868
|
-
|
|
97869
|
-
.navi_message_box[data-status-warning] {
|
|
97870
|
-
--x-message-background-color: var(--background-color-warning);
|
|
97871
|
-
--x-message-color: var(--color-warning);
|
|
97872
|
-
}
|
|
97873
|
-
|
|
97874
|
-
.navi_message_box[data-status-error] {
|
|
97875
|
-
--x-message-background-color: var(--background-color-error);
|
|
97876
|
-
--x-message-color: var(--color-error);
|
|
97877
|
-
}
|
|
97878
|
-
|
|
97879
|
-
.navi_message_box[data-left-stripe] {
|
|
97880
|
-
border-left: 6px solid var(--x-message-color);
|
|
97881
|
-
border-top-left-radius: 6px;
|
|
97882
|
-
border-bottom-left-radius: 6px;
|
|
97883
|
-
}
|
|
97884
|
-
`;
|
|
97885
|
-
const MessageBox = ({
|
|
97886
|
-
status = "info",
|
|
97887
|
-
padding = "sm",
|
|
97888
|
-
icon,
|
|
97889
|
-
leftStripe,
|
|
97890
|
-
children,
|
|
97891
|
-
onClose,
|
|
97892
|
-
...rest
|
|
97893
|
-
}) => {
|
|
97894
|
-
import.meta.css = [css$a, "@jsenv/navi/src/text/message_box.jsx"];
|
|
97895
|
-
const [hasTitleChild, setHasTitleChild] = useState(false);
|
|
97896
|
-
const innerLeftStripe = leftStripe === undefined ? hasTitleChild : leftStripe;
|
|
97897
|
-
if (icon === true) {
|
|
97898
|
-
icon = status === "info" ? jsx(InfoSvg$1, {}) : status === "success" ? jsx(SuccessSvg, {}) : status === "warning" ? jsx(WarningSvg, {}) : status === "error" ? jsx(ErrorSvg, {}) : null;
|
|
97899
|
-
} else if (typeof icon === "function") {
|
|
97900
|
-
const Comp = icon;
|
|
97901
|
-
icon = jsx(Comp, {});
|
|
97902
|
-
}
|
|
97903
|
-
return jsx(Box, {
|
|
97904
|
-
as: "div",
|
|
97905
|
-
role: status === "info" ? "status" : "alert",
|
|
97906
|
-
"data-left-stripe": innerLeftStripe ? "" : undefined,
|
|
97907
|
-
inline: true,
|
|
97908
|
-
column: true,
|
|
97909
|
-
alignY: "center",
|
|
97910
|
-
spacing: "s",
|
|
97911
|
-
...rest,
|
|
97912
|
-
className: withPropsClassName("navi_message_box", rest.className),
|
|
97913
|
-
padding: padding,
|
|
97914
|
-
pseudoClasses: MessageBoxPseudoClasses,
|
|
97915
|
-
basePseudoState: {
|
|
97916
|
-
":-navi-status-info": status === "info",
|
|
97917
|
-
":-navi-status-success": status === "success",
|
|
97918
|
-
":-navi-status-warning": status === "warning",
|
|
97919
|
-
":-navi-status-error": status === "error"
|
|
97920
|
-
},
|
|
97921
|
-
children: jsx(MessageBoxStatusContext.Provider, {
|
|
97922
|
-
value: status,
|
|
97923
|
-
children: jsxs(MessageBoxReportTitleChildContext.Provider, {
|
|
97924
|
-
value: setHasTitleChild,
|
|
97925
|
-
children: [icon && jsx(Icon, {
|
|
97926
|
-
color: "var(--x-message-color)",
|
|
97927
|
-
height: "1lh",
|
|
97928
|
-
maxHeight: "auto",
|
|
97929
|
-
selfAlignY: "start",
|
|
97930
|
-
aspectRatio: "auto",
|
|
97931
|
-
children: icon
|
|
97932
|
-
}), jsx(Text, {
|
|
97933
|
-
children: children
|
|
97934
|
-
}), onClose &&
|
|
97935
|
-
// A column as tall as the first line of the message, pinned to the
|
|
97936
|
-
// top, the button centered in it: the close button stays level
|
|
97937
|
-
// with the first line however many lines the message takes (same
|
|
97938
|
-
// layout as Callout).
|
|
97939
|
-
jsx(Box, {
|
|
97940
|
-
flex: true,
|
|
97941
|
-
alignY: "center",
|
|
97942
|
-
height: "1lh",
|
|
97943
|
-
selfAlignY: "start",
|
|
97944
|
-
shrink: false,
|
|
97945
|
-
children: jsx(Button, {
|
|
97946
|
-
action: onClose,
|
|
97947
|
-
icon: true,
|
|
97948
|
-
border: "none",
|
|
97949
|
-
style: {
|
|
97950
|
-
":hover": {
|
|
97951
|
-
backgroundColor: "rgba(0, 0, 0, 0.1)"
|
|
97952
|
-
}
|
|
97953
|
-
},
|
|
97954
|
-
children: jsx(Icon, {
|
|
97955
|
-
children: jsx(CloseSvg, {})
|
|
97956
|
-
})
|
|
97957
|
-
})
|
|
97958
|
-
})]
|
|
97959
|
-
})
|
|
97960
|
-
})
|
|
97961
|
-
});
|
|
97962
|
-
};
|
|
97963
|
-
const MessageBoxPseudoClasses = [":-navi-status-info", ":-navi-status-success", ":-navi-status-warning", ":-navi-status-error"];
|
|
97964
|
-
const MessageBoxStatusContext = createContext();
|
|
97965
|
-
const MessageBoxReportTitleChildContext = createContext();
|
|
97966
|
-
|
|
97967
|
-
installImportMetaCssBuild(import.meta);
|
|
97968
|
-
const css$9 = /* css */`@layer navi;
|
|
98319
|
+
const css$8 = /* css */`@layer navi;
|
|
97969
98320
|
|
|
97970
98321
|
.navi_quantity {
|
|
97971
98322
|
flex-direction: column;
|
|
@@ -98066,7 +98417,7 @@ const Quantity = ({
|
|
|
98066
98417
|
bold = true,
|
|
98067
98418
|
...props
|
|
98068
98419
|
}) => {
|
|
98069
|
-
import.meta.css = [css$
|
|
98420
|
+
import.meta.css = [css$8, "@jsenv/navi/src/text/quantity.jsx"];
|
|
98070
98421
|
const value = parseQuantityValue(children);
|
|
98071
98422
|
const valueRounded = integer && typeof value === "number" ? Math.round(value) : value;
|
|
98072
98423
|
const valueFormatted = typeof valueRounded === "number" ? formatNumber(valueRounded, {
|
|
@@ -98125,7 +98476,7 @@ const parseQuantityValue = children => {
|
|
|
98125
98476
|
};
|
|
98126
98477
|
|
|
98127
98478
|
installImportMetaCssBuild(import.meta);
|
|
98128
|
-
const css$
|
|
98479
|
+
const css$7 = /* css */`@layer navi {
|
|
98129
98480
|
.navi_meter {
|
|
98130
98481
|
--loader-color: var(--navi-loader-color);
|
|
98131
98482
|
--track-color: #efefef;
|
|
@@ -98264,7 +98615,7 @@ const Meter = ({
|
|
|
98264
98615
|
style,
|
|
98265
98616
|
...rest
|
|
98266
98617
|
}) => {
|
|
98267
|
-
import.meta.css = [css$
|
|
98618
|
+
import.meta.css = [css$7, "@jsenv/navi/src/text/meter.jsx"];
|
|
98268
98619
|
const defaultRef = useRef();
|
|
98269
98620
|
const ref = rest.ref || defaultRef;
|
|
98270
98621
|
value = Number(value);
|
|
@@ -98379,7 +98730,7 @@ const Paragraph = props => {
|
|
|
98379
98730
|
};
|
|
98380
98731
|
|
|
98381
98732
|
installImportMetaCssBuild(import.meta);
|
|
98382
|
-
const css$
|
|
98733
|
+
const css$6 = /* css */`.navi_text_box {
|
|
98383
98734
|
align-items: flex-start;
|
|
98384
98735
|
min-width: 0;
|
|
98385
98736
|
}
|
|
@@ -98421,7 +98772,7 @@ const TextBox = ({
|
|
|
98421
98772
|
children,
|
|
98422
98773
|
...rest
|
|
98423
98774
|
}) => {
|
|
98424
|
-
import.meta.css = [css$
|
|
98775
|
+
import.meta.css = [css$6, "@jsenv/navi/src/text/text_box.jsx"];
|
|
98425
98776
|
const boxRef = useRef(null);
|
|
98426
98777
|
const contentRef = useRef(null);
|
|
98427
98778
|
useLayoutEffect(() => {
|
|
@@ -98467,40 +98818,6 @@ const adjustWidth = (boxEl, contentEl) => {
|
|
|
98467
98818
|
contentEl.style.width = `${Math.ceil(optimalWidth)}px`;
|
|
98468
98819
|
};
|
|
98469
98820
|
|
|
98470
|
-
installImportMetaCssBuild(import.meta);
|
|
98471
|
-
const css$6 = /* css */`.navi_message_box {
|
|
98472
|
-
& .navi_title {
|
|
98473
|
-
margin-top: 0;
|
|
98474
|
-
margin-bottom: var(--navi-s);
|
|
98475
|
-
color: var(--x-message-color);
|
|
98476
|
-
}
|
|
98477
|
-
}
|
|
98478
|
-
`;
|
|
98479
|
-
const Title = props => {
|
|
98480
|
-
import.meta.css = [css$6, "@jsenv/navi/src/text/title.jsx"];
|
|
98481
|
-
const messageBoxStatus = useContext(MessageBoxStatusContext);
|
|
98482
|
-
const innerAs = props.as || (messageBoxStatus ? "h4" : "h1");
|
|
98483
|
-
const titleLevel = parseInt(innerAs.slice(1));
|
|
98484
|
-
const reportTitleToMessageBox = useContext(MessageBoxReportTitleChildContext);
|
|
98485
|
-
reportTitleToMessageBox?.(true);
|
|
98486
|
-
return jsx(TitleLevelContext.Provider, {
|
|
98487
|
-
value: titleLevel,
|
|
98488
|
-
children: jsx(Text, {
|
|
98489
|
-
bold: true,
|
|
98490
|
-
className: withPropsClassName("navi_title"),
|
|
98491
|
-
as: messageBoxStatus ? "h4" : "h1",
|
|
98492
|
-
...props,
|
|
98493
|
-
pseudoClasses: TitlePseudoClasses,
|
|
98494
|
-
children: props.children
|
|
98495
|
-
})
|
|
98496
|
-
});
|
|
98497
|
-
};
|
|
98498
|
-
const TitleLevelContext = createContext();
|
|
98499
|
-
const useTitleLevel = () => {
|
|
98500
|
-
return useContext(TitleLevelContext);
|
|
98501
|
-
};
|
|
98502
|
-
const TitlePseudoClasses = [":hover"];
|
|
98503
|
-
|
|
98504
98821
|
installImportMetaCssBuild(import.meta);
|
|
98505
98822
|
const css$5 = /* css */`@keyframes navi_image_shimmer {
|
|
98506
98823
|
0% {
|