@jsenv/navi 0.29.470 → 0.29.472
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dev/jsenv_navi.js +595 -313
- package/dist/dev/jsenv_navi.js.map +22 -20
- package/dist/jsenv_navi.js +566 -311
- package/dist/jsenv_navi.js.map +22 -20
- package/docs/AI_INSTRUCTIONS.md +2 -2
- package/docs/popup_open.md +52 -0
- package/docs/testid.md +15 -2
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -39055,8 +39055,29 @@ const resolveFirstChildControl = (el) => {
|
|
|
39055
39055
|
}
|
|
39056
39056
|
return startEl.querySelector("[navi-control-host]");
|
|
39057
39057
|
};
|
|
39058
|
+
// The element a popup command is about: the closest one keeping an open state.
|
|
39058
39059
|
const resolveClosestExpandable = (el) => {
|
|
39059
|
-
|
|
39060
|
+
const expandable = el.closest("[aria-expanded]");
|
|
39061
|
+
if (!expandable) {
|
|
39062
|
+
return null;
|
|
39063
|
+
}
|
|
39064
|
+
return expandableRepeatedBy(expandable) || expandable;
|
|
39065
|
+
};
|
|
39066
|
+
// A control's host repeats the aria-expanded of its root, beside its role, for
|
|
39067
|
+
// assistive tech to read (a picker's <input>, a combobox or a button). The root
|
|
39068
|
+
// is the expandable: the host is a leaf the walk lands on only when it is the
|
|
39069
|
+
// source itself, and it carries the control's own `command`/`commandfor`, which
|
|
39070
|
+
// a command resolved again from it (a close after a clear) would follow.
|
|
39071
|
+
const expandableRepeatedBy = (el) => {
|
|
39072
|
+
const controlRoot = findControlRoot(el);
|
|
39073
|
+
if (
|
|
39074
|
+
controlRoot &&
|
|
39075
|
+
controlRoot !== el &&
|
|
39076
|
+
controlRoot.hasAttribute("aria-expanded")
|
|
39077
|
+
) {
|
|
39078
|
+
return controlRoot;
|
|
39079
|
+
}
|
|
39080
|
+
return null;
|
|
39060
39081
|
};
|
|
39061
39082
|
// The surface a send is decided on: the expandable holding the CONTROL that
|
|
39062
39083
|
// sends, never one that control is itself. A picker's own root carries
|
|
@@ -39067,7 +39088,7 @@ const resolveClosestExpandable = (el) => {
|
|
|
39067
39088
|
const resolveExpandableAround = (source) => {
|
|
39068
39089
|
const sender = findControlRoot(source) || source;
|
|
39069
39090
|
const parent = sender.parentElement;
|
|
39070
|
-
return parent ? parent
|
|
39091
|
+
return parent ? resolveClosestExpandable(parent) : null;
|
|
39071
39092
|
};
|
|
39072
39093
|
// An element carrying navi-command-proxy-for="anchorId" stands in for that
|
|
39073
39094
|
// other element as the command's source when the source is forwarded to
|
|
@@ -39368,8 +39389,12 @@ const sendCommand = (source, event, { requester }) => {
|
|
|
39368
39389
|
// looking at, and a decision just taken there is a reason to leave it. The
|
|
39369
39390
|
// NEAREST surface answers, and only that one — a form inside a slide inside a
|
|
39370
39391
|
// dialog goes back a slide, it does not also close the dialog.
|
|
39371
|
-
// send inside expandable
|
|
39372
|
-
|
|
39392
|
+
// send inside expandable — the control itself when it sends from its host,
|
|
39393
|
+
// whose aria-expanded is its root's (see expandableRepeatedBy)
|
|
39394
|
+
if (
|
|
39395
|
+
target.getAttribute("aria-expanded") === "true" &&
|
|
39396
|
+
!expandableRepeatedBy(target)
|
|
39397
|
+
) {
|
|
39373
39398
|
return {
|
|
39374
39399
|
target,
|
|
39375
39400
|
implementation: () => {
|
|
@@ -39804,7 +39829,7 @@ const requestCloseUpward = (target, detail) => {
|
|
|
39804
39829
|
return false;
|
|
39805
39830
|
}
|
|
39806
39831
|
const parent = expandable.parentElement;
|
|
39807
|
-
expandable = parent ? parent
|
|
39832
|
+
expandable = parent ? resolveClosestExpandable(parent) : null;
|
|
39808
39833
|
}
|
|
39809
39834
|
return true;
|
|
39810
39835
|
};
|
|
@@ -51639,6 +51664,9 @@ const LinkWithRoute = ({
|
|
|
51639
51664
|
currentExcept,
|
|
51640
51665
|
currentAlso,
|
|
51641
51666
|
children,
|
|
51667
|
+
// Kept out of `rest`: spread after the route's url, an `href={undefined}`
|
|
51668
|
+
// riding along would erase it.
|
|
51669
|
+
href,
|
|
51642
51670
|
...rest
|
|
51643
51671
|
}) => {
|
|
51644
51672
|
const url = route.buildUrl(routeParams);
|
|
@@ -56811,11 +56839,14 @@ const ButtonRouteResolver = props => {
|
|
|
56811
56839
|
};
|
|
56812
56840
|
const ButtonWithRoute = props => {
|
|
56813
56841
|
const Next = useNextResolver();
|
|
56842
|
+
// `href` is kept out of `rest`: spread after the route's url, an
|
|
56843
|
+
// `href={undefined}` riding along would erase it.
|
|
56814
56844
|
const {
|
|
56815
56845
|
route,
|
|
56816
56846
|
routeParams,
|
|
56817
56847
|
children,
|
|
56818
56848
|
pseudoState,
|
|
56849
|
+
href,
|
|
56819
56850
|
...rest
|
|
56820
56851
|
} = props;
|
|
56821
56852
|
const url = route.buildUrl(routeParams);
|
|
@@ -58184,6 +58215,10 @@ const Label = props => {
|
|
|
58184
58215
|
requiredIndicator
|
|
58185
58216
|
} = props;
|
|
58186
58217
|
const controlId = useContext(ControlIdContext);
|
|
58218
|
+
// What a popup opened from the control is named by (see getTriggerLabelIds
|
|
58219
|
+
// in picker_custom.jsx): aria-labelledby can only point at an id.
|
|
58220
|
+
const idDefault = useId();
|
|
58221
|
+
props.id = props.id || `label_${idDefault}`;
|
|
58187
58222
|
const [disabled, setDisabled] = useState(false);
|
|
58188
58223
|
const [readOnly, setReadOnly] = useState(false);
|
|
58189
58224
|
const [required, setRequired] = useState(false);
|
|
@@ -67877,9 +67912,297 @@ const PopupClose = ({
|
|
|
67877
67912
|
});
|
|
67878
67913
|
};
|
|
67879
67914
|
|
|
67915
|
+
const SuccessSvg = () => {
|
|
67916
|
+
return jsx("svg", {
|
|
67917
|
+
viewBox: "0 0 16 16",
|
|
67918
|
+
fill: "currentColor",
|
|
67919
|
+
children: jsx("path", {
|
|
67920
|
+
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"
|
|
67921
|
+
})
|
|
67922
|
+
});
|
|
67923
|
+
};
|
|
67924
|
+
const ErrorSvg = () => {
|
|
67925
|
+
return jsx("svg", {
|
|
67926
|
+
viewBox: "0 0 16 16",
|
|
67927
|
+
fill: "currentColor",
|
|
67928
|
+
children: jsx("path", {
|
|
67929
|
+
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"
|
|
67930
|
+
})
|
|
67931
|
+
});
|
|
67932
|
+
};
|
|
67933
|
+
const InfoSvg$1 = () => {
|
|
67934
|
+
return jsx("svg", {
|
|
67935
|
+
viewBox: "0 0 16 16",
|
|
67936
|
+
fill: "currentColor",
|
|
67937
|
+
children: jsx("path", {
|
|
67938
|
+
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"
|
|
67939
|
+
})
|
|
67940
|
+
});
|
|
67941
|
+
};
|
|
67942
|
+
const WarningSvg = () => {
|
|
67943
|
+
return jsx("svg", {
|
|
67944
|
+
viewBox: "0 0 16 16",
|
|
67945
|
+
fill: "currentColor",
|
|
67946
|
+
children: jsx("path", {
|
|
67947
|
+
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"
|
|
67948
|
+
})
|
|
67949
|
+
});
|
|
67950
|
+
};
|
|
67951
|
+
|
|
67952
|
+
installImportMetaCssBuild(import.meta);
|
|
67953
|
+
const css$E = /* css */`@layer navi {
|
|
67954
|
+
.navi_message_box {
|
|
67955
|
+
--background-color-info: var(--navi-info-color-light);
|
|
67956
|
+
--color-info: var(--navi-info-color);
|
|
67957
|
+
--background-color-success: var(--navi-success-color-light);
|
|
67958
|
+
--color-success: var(--navi-success-color);
|
|
67959
|
+
--background-color-warning: var(--navi-warning-color-light);
|
|
67960
|
+
--color-warning: var(--navi-warning-color);
|
|
67961
|
+
--background-color-error: var(--navi-error-color-light);
|
|
67962
|
+
--color-error: var(--navi-error-color);
|
|
67963
|
+
}
|
|
67964
|
+
}
|
|
67965
|
+
|
|
67966
|
+
.navi_message_box {
|
|
67967
|
+
--x-message-background-color: var(--background-color-info);
|
|
67968
|
+
--x-message-color: var(--color-info);
|
|
67969
|
+
background-color: var(--x-message-background-color);
|
|
67970
|
+
|
|
67971
|
+
& > .navi_icon {
|
|
67972
|
+
flex-shrink: 0;
|
|
67973
|
+
}
|
|
67974
|
+
}
|
|
67975
|
+
|
|
67976
|
+
.navi_message_box[data-status-info] {
|
|
67977
|
+
--x-message-background-color: var(--background-color-info);
|
|
67978
|
+
--x-message-color: var(--color-info);
|
|
67979
|
+
}
|
|
67980
|
+
|
|
67981
|
+
.navi_message_box[data-status-success] {
|
|
67982
|
+
--x-message-background-color: var(--background-color-success);
|
|
67983
|
+
--x-message-color: var(--color-success);
|
|
67984
|
+
}
|
|
67985
|
+
|
|
67986
|
+
.navi_message_box[data-status-warning] {
|
|
67987
|
+
--x-message-background-color: var(--background-color-warning);
|
|
67988
|
+
--x-message-color: var(--color-warning);
|
|
67989
|
+
}
|
|
67990
|
+
|
|
67991
|
+
.navi_message_box[data-status-error] {
|
|
67992
|
+
--x-message-background-color: var(--background-color-error);
|
|
67993
|
+
--x-message-color: var(--color-error);
|
|
67994
|
+
}
|
|
67995
|
+
|
|
67996
|
+
.navi_message_box[data-left-stripe] {
|
|
67997
|
+
border-left: 6px solid var(--x-message-color);
|
|
67998
|
+
border-top-left-radius: 6px;
|
|
67999
|
+
border-bottom-left-radius: 6px;
|
|
68000
|
+
}
|
|
68001
|
+
`;
|
|
68002
|
+
const MessageBox = ({
|
|
68003
|
+
status = "info",
|
|
68004
|
+
padding = "sm",
|
|
68005
|
+
icon,
|
|
68006
|
+
leftStripe,
|
|
68007
|
+
children,
|
|
68008
|
+
onClose,
|
|
68009
|
+
...rest
|
|
68010
|
+
}) => {
|
|
68011
|
+
import.meta.css = [css$E, "@jsenv/navi/src/text/message_box.jsx"];
|
|
68012
|
+
const [hasTitleChild, setHasTitleChild] = useState(false);
|
|
68013
|
+
const innerLeftStripe = leftStripe === undefined ? hasTitleChild : leftStripe;
|
|
68014
|
+
if (icon === true) {
|
|
68015
|
+
icon = status === "info" ? jsx(InfoSvg$1, {}) : status === "success" ? jsx(SuccessSvg, {}) : status === "warning" ? jsx(WarningSvg, {}) : status === "error" ? jsx(ErrorSvg, {}) : null;
|
|
68016
|
+
} else if (typeof icon === "function") {
|
|
68017
|
+
const Comp = icon;
|
|
68018
|
+
icon = jsx(Comp, {});
|
|
68019
|
+
}
|
|
68020
|
+
return jsx(Box, {
|
|
68021
|
+
as: "div",
|
|
68022
|
+
role: status === "info" ? "status" : "alert",
|
|
68023
|
+
"data-left-stripe": innerLeftStripe ? "" : undefined,
|
|
68024
|
+
inline: true,
|
|
68025
|
+
column: true,
|
|
68026
|
+
alignY: "center",
|
|
68027
|
+
spacing: "s",
|
|
68028
|
+
...rest,
|
|
68029
|
+
className: withPropsClassName("navi_message_box", rest.className),
|
|
68030
|
+
padding: padding,
|
|
68031
|
+
pseudoClasses: MessageBoxPseudoClasses,
|
|
68032
|
+
basePseudoState: {
|
|
68033
|
+
":-navi-status-info": status === "info",
|
|
68034
|
+
":-navi-status-success": status === "success",
|
|
68035
|
+
":-navi-status-warning": status === "warning",
|
|
68036
|
+
":-navi-status-error": status === "error"
|
|
68037
|
+
},
|
|
68038
|
+
children: jsx(MessageBoxStatusContext.Provider, {
|
|
68039
|
+
value: status,
|
|
68040
|
+
children: jsxs(MessageBoxReportTitleChildContext.Provider, {
|
|
68041
|
+
value: setHasTitleChild,
|
|
68042
|
+
children: [icon && jsx(Icon, {
|
|
68043
|
+
color: "var(--x-message-color)",
|
|
68044
|
+
height: "1lh",
|
|
68045
|
+
maxHeight: "auto",
|
|
68046
|
+
selfAlignY: "start",
|
|
68047
|
+
aspectRatio: "auto",
|
|
68048
|
+
children: icon
|
|
68049
|
+
}), jsx(Text, {
|
|
68050
|
+
children: children
|
|
68051
|
+
}), onClose &&
|
|
68052
|
+
// A column as tall as the first line of the message, pinned to the
|
|
68053
|
+
// top, the button centered in it: the close button stays level
|
|
68054
|
+
// with the first line however many lines the message takes (same
|
|
68055
|
+
// layout as Callout).
|
|
68056
|
+
jsx(Box, {
|
|
68057
|
+
flex: true,
|
|
68058
|
+
alignY: "center",
|
|
68059
|
+
height: "1lh",
|
|
68060
|
+
selfAlignY: "start",
|
|
68061
|
+
shrink: false,
|
|
68062
|
+
children: jsx(Button, {
|
|
68063
|
+
action: onClose,
|
|
68064
|
+
icon: true,
|
|
68065
|
+
border: "none",
|
|
68066
|
+
style: {
|
|
68067
|
+
":hover": {
|
|
68068
|
+
backgroundColor: "rgba(0, 0, 0, 0.1)"
|
|
68069
|
+
}
|
|
68070
|
+
},
|
|
68071
|
+
children: jsx(Icon, {
|
|
68072
|
+
children: jsx(CloseSvg, {})
|
|
68073
|
+
})
|
|
68074
|
+
})
|
|
68075
|
+
})]
|
|
68076
|
+
})
|
|
68077
|
+
})
|
|
68078
|
+
});
|
|
68079
|
+
};
|
|
68080
|
+
const MessageBoxPseudoClasses = [":-navi-status-info", ":-navi-status-success", ":-navi-status-warning", ":-navi-status-error"];
|
|
68081
|
+
const MessageBoxStatusContext = createContext();
|
|
68082
|
+
const MessageBoxReportTitleChildContext = createContext();
|
|
68083
|
+
|
|
68084
|
+
installImportMetaCssBuild(import.meta);
|
|
68085
|
+
const css$D = /* css */`.navi_message_box {
|
|
68086
|
+
& .navi_title {
|
|
68087
|
+
margin-top: 0;
|
|
68088
|
+
margin-bottom: var(--navi-s);
|
|
68089
|
+
color: var(--x-message-color);
|
|
68090
|
+
}
|
|
68091
|
+
}
|
|
68092
|
+
`;
|
|
68093
|
+
const Title = props => {
|
|
68094
|
+
import.meta.css = [css$D, "@jsenv/navi/src/text/title.jsx"];
|
|
68095
|
+
const messageBoxStatus = useContext(MessageBoxStatusContext);
|
|
68096
|
+
const innerAs = props.as || (messageBoxStatus ? "h4" : "h1");
|
|
68097
|
+
const titleLevel = parseInt(innerAs.slice(1));
|
|
68098
|
+
const reportTitleToMessageBox = useContext(MessageBoxReportTitleChildContext);
|
|
68099
|
+
reportTitleToMessageBox?.(true);
|
|
68100
|
+
return jsx(TitleLevelContext.Provider, {
|
|
68101
|
+
value: titleLevel,
|
|
68102
|
+
children: jsx(Text, {
|
|
68103
|
+
bold: true,
|
|
68104
|
+
className: withPropsClassName("navi_title"),
|
|
68105
|
+
as: messageBoxStatus ? "h4" : "h1",
|
|
68106
|
+
...props,
|
|
68107
|
+
pseudoClasses: TitlePseudoClasses,
|
|
68108
|
+
children: props.children
|
|
68109
|
+
})
|
|
68110
|
+
});
|
|
68111
|
+
};
|
|
68112
|
+
const TitleLevelContext = createContext();
|
|
68113
|
+
const useTitleLevel = () => {
|
|
68114
|
+
return useContext(TitleLevelContext);
|
|
68115
|
+
};
|
|
68116
|
+
const TitlePseudoClasses = [":hover"];
|
|
68117
|
+
|
|
68118
|
+
/**
|
|
68119
|
+
* What a popup is called, decided by Dialog and Popover alike: the name the
|
|
68120
|
+
* caller writes on it (aria-label/aria-labelledby), else the title it holds
|
|
68121
|
+
* (`<Popup.Title>`), else the name of what opened it (`openerAriaLabelledBy` /
|
|
68122
|
+
* `openerAriaLabel`, which a Picker fills with its trigger's). A popup no one
|
|
68123
|
+
* names is announced as "dialog" and nothing else.
|
|
68124
|
+
*
|
|
68125
|
+
* The title tells the popup it exists rather than the popup looking for it:
|
|
68126
|
+
* the content is built after the popup and thrown away before it (see
|
|
68127
|
+
* popup_content_mount.js), and a title may sit anywhere in it — a header, a
|
|
68128
|
+
* step of a form — so only the title knows when it is there.
|
|
68129
|
+
*/
|
|
68130
|
+
|
|
68131
|
+
const PopupTitleContext = createContext(null);
|
|
68132
|
+
|
|
68133
|
+
/**
|
|
68134
|
+
* The title of the popup it sits in — reached as `<Popup.Title>`,
|
|
68135
|
+
* `<Dialog.Title>` or `<Popover.Title>`. A heading (`h2` unless `as` says
|
|
68136
|
+
* otherwise) that is also the popup's accessible name: a screen reader
|
|
68137
|
+
* announces the popup by it, and `getByRole("dialog", { name })` finds it.
|
|
68138
|
+
* An `aria-label`/`aria-labelledby` written on the popup itself wins over it.
|
|
68139
|
+
*
|
|
68140
|
+
* @type {import("ignore:preact").FunctionComponent<{
|
|
68141
|
+
* as?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6",
|
|
68142
|
+
* id?: string,
|
|
68143
|
+
* children?: import("ignore:preact").ComponentChildren,
|
|
68144
|
+
* } & Record<string, any>>}
|
|
68145
|
+
*/
|
|
68146
|
+
const PopupTitle = props => {
|
|
68147
|
+
const registerTitle = useContext(PopupTitleContext);
|
|
68148
|
+
const idDefault = useId();
|
|
68149
|
+
const id = props.id || `popup_title_${idDefault}`;
|
|
68150
|
+
useLayoutEffect(() => {
|
|
68151
|
+
if (!registerTitle) {
|
|
68152
|
+
return undefined;
|
|
68153
|
+
}
|
|
68154
|
+
return registerTitle(id);
|
|
68155
|
+
}, [registerTitle, id]);
|
|
68156
|
+
return jsx(Title, {
|
|
68157
|
+
as: "h2",
|
|
68158
|
+
...props,
|
|
68159
|
+
id: id
|
|
68160
|
+
});
|
|
68161
|
+
};
|
|
68162
|
+
|
|
68163
|
+
/**
|
|
68164
|
+
* The name props of a popup element, and what its titles register with —
|
|
68165
|
+
* handed to its children through PopupTitleContext.
|
|
68166
|
+
*/
|
|
68167
|
+
const usePopupName = ({
|
|
68168
|
+
ariaLabel,
|
|
68169
|
+
ariaLabelledBy,
|
|
68170
|
+
openerAriaLabel,
|
|
68171
|
+
openerAriaLabelledBy
|
|
68172
|
+
}) => {
|
|
68173
|
+
// Several titles is a content of the caller's own making (two steps both
|
|
68174
|
+
// mounted): the first one registered names the popup.
|
|
68175
|
+
const [titleIds, setTitleIds] = useState(NO_TITLE);
|
|
68176
|
+
const registerTitle = useMemo(() => {
|
|
68177
|
+
return id => {
|
|
68178
|
+
setTitleIds(ids => [...ids, id]);
|
|
68179
|
+
return () => {
|
|
68180
|
+
setTitleIds(ids => ids.filter(each => each !== id));
|
|
68181
|
+
};
|
|
68182
|
+
};
|
|
68183
|
+
}, []);
|
|
68184
|
+
let labelledBy;
|
|
68185
|
+
let label;
|
|
68186
|
+
if (ariaLabelledBy !== undefined || ariaLabel !== undefined) {
|
|
68187
|
+
labelledBy = ariaLabelledBy;
|
|
68188
|
+
label = ariaLabel;
|
|
68189
|
+
} else if (titleIds.length > 0) {
|
|
68190
|
+
labelledBy = titleIds[0];
|
|
68191
|
+
} else if (openerAriaLabelledBy !== undefined) {
|
|
68192
|
+
labelledBy = openerAriaLabelledBy;
|
|
68193
|
+
} else {
|
|
68194
|
+
label = openerAriaLabel;
|
|
68195
|
+
}
|
|
68196
|
+
return [{
|
|
68197
|
+
"aria-labelledby": labelledBy,
|
|
68198
|
+
"aria-label": label
|
|
68199
|
+
}, registerTitle];
|
|
68200
|
+
};
|
|
68201
|
+
const NO_TITLE = [];
|
|
68202
|
+
|
|
67880
68203
|
installImportMetaCssBuild(import.meta);
|
|
67881
68204
|
let openLocalDialogCount = 0;
|
|
67882
|
-
const css$
|
|
68205
|
+
const css$C = /* css */`
|
|
67883
68206
|
/* jsenv-css-opaque: popupCss overlaps these rules, own sheet = cascade
|
|
67884
68207
|
order depending on which popup renders first. */
|
|
67885
68208
|
|
|
@@ -68948,10 +69271,14 @@ const css$E = /* css */`
|
|
|
68948
69271
|
* under `"while-opened"`, only a press on what opens the popup does (a
|
|
68949
69272
|
* `--navi-open` button, a picker's trigger), never with an `onOpen`, and a
|
|
68950
69273
|
* press that does not open the popup throws it away.
|
|
69274
|
+
* @param {string} [props.openerAriaLabelledBy] - The id(s) naming what opened
|
|
69275
|
+
* the dialog: its accessible name when neither `aria-label`/`aria-labelledby`
|
|
69276
|
+
* nor a `<Dialog.Title>` names it. A Picker passes its trigger's.
|
|
69277
|
+
* @param {string} [props.openerAriaLabel] - The same, as a string.
|
|
68951
69278
|
* @param {import("ignore:preact").ComponentChildren} props.children
|
|
68952
69279
|
*/
|
|
68953
69280
|
const Dialog = props => {
|
|
68954
|
-
import.meta.css = [css$
|
|
69281
|
+
import.meta.css = [css$C, "@jsenv/navi/src/layout/dialog.jsx"];
|
|
68955
69282
|
if (props.openController) {
|
|
68956
69283
|
return jsx(ControlledDialog, {
|
|
68957
69284
|
...props
|
|
@@ -69325,6 +69652,9 @@ const useDialogProps = props => {
|
|
|
69325
69652
|
onOpen,
|
|
69326
69653
|
children: childrenProp,
|
|
69327
69654
|
mount,
|
|
69655
|
+
// Read by usePopupName below, never written on the element.
|
|
69656
|
+
openerAriaLabel,
|
|
69657
|
+
openerAriaLabelledBy,
|
|
69328
69658
|
...rest
|
|
69329
69659
|
} = props;
|
|
69330
69660
|
// Assigned on every render, like openEffect below, so it always closes over
|
|
@@ -69335,7 +69665,16 @@ const useDialogProps = props => {
|
|
|
69335
69665
|
mount,
|
|
69336
69666
|
anchor
|
|
69337
69667
|
});
|
|
69338
|
-
const
|
|
69668
|
+
const [nameProps, registerTitle] = usePopupName({
|
|
69669
|
+
ariaLabel: rest["aria-label"],
|
|
69670
|
+
ariaLabelledBy: rest["aria-labelledby"],
|
|
69671
|
+
openerAriaLabel,
|
|
69672
|
+
openerAriaLabelledBy
|
|
69673
|
+
});
|
|
69674
|
+
const children = contentMounted ? jsx(PopupTitleContext.Provider, {
|
|
69675
|
+
value: registerTitle,
|
|
69676
|
+
children: childrenProp
|
|
69677
|
+
}) : null;
|
|
69339
69678
|
// Where it is placed, and whether there is a wall — the two questions that
|
|
69340
69679
|
// pick the show call (see this file's top comment).
|
|
69341
69680
|
const isTopLayer = layer === "top";
|
|
@@ -70125,6 +70464,7 @@ const useDialogProps = props => {
|
|
|
70125
70464
|
"backdropFilter": backdrop ? backdropFilter : undefined,
|
|
70126
70465
|
"styleCSSVars": DIALOG_STYLE_CSS_VARS,
|
|
70127
70466
|
...rest,
|
|
70467
|
+
...nameProps,
|
|
70128
70468
|
...autoFocusProps,
|
|
70129
70469
|
"as": "dialog",
|
|
70130
70470
|
ref,
|
|
@@ -70298,10 +70638,11 @@ const DIALOG_STYLE_CSS_VARS = {
|
|
|
70298
70638
|
maxHeight: "--dialog-max-height"
|
|
70299
70639
|
};
|
|
70300
70640
|
Dialog.Close = PopupClose;
|
|
70641
|
+
Dialog.Title = PopupTitle;
|
|
70301
70642
|
|
|
70302
70643
|
installImportMetaCssBuild(import.meta);
|
|
70303
70644
|
let openLocalPopoverCount = 0;
|
|
70304
|
-
const css$
|
|
70645
|
+
const css$B = /* css */`
|
|
70305
70646
|
/* jsenv-css-opaque: popupCss overlaps these rules, own sheet = cascade
|
|
70306
70647
|
order depending on which popup renders first. */
|
|
70307
70648
|
|
|
@@ -70900,10 +71241,17 @@ const css$D = /* css */`
|
|
|
70900
71241
|
* under `"while-opened"`, only a press on what opens the popup does (a
|
|
70901
71242
|
* `--navi-open` button, a picker's trigger), never with an `onOpen`, and a
|
|
70902
71243
|
* press that does not open the popup throws it away.
|
|
71244
|
+
* @param {string} [props.openerAriaLabelledBy] - The id(s) naming what opened
|
|
71245
|
+
* the popover: its accessible name when neither `aria-label`/`aria-labelledby`
|
|
71246
|
+
* nor a `<Popover.Title>` names it. A Picker passes its trigger's.
|
|
71247
|
+
* @param {string} [props.openerAriaLabel] - The same, as a string. A popover
|
|
71248
|
+
* something names — these, `aria-label`/`aria-labelledby`, a
|
|
71249
|
+
* `<Popover.Title>` — is a `dialog`, unless given another `role`: a name on
|
|
71250
|
+
* an element with no role is read by nobody.
|
|
70903
71251
|
* @param {import("ignore:preact").ComponentChildren} props.children
|
|
70904
71252
|
*/
|
|
70905
71253
|
const Popover = props => {
|
|
70906
|
-
import.meta.css = [css$
|
|
71254
|
+
import.meta.css = [css$B, "@jsenv/navi/src/layout/popover.jsx"];
|
|
70907
71255
|
if (props.openController) {
|
|
70908
71256
|
return jsx(ControlledPopover, {
|
|
70909
71257
|
...props
|
|
@@ -71140,6 +71488,9 @@ const usePopoverProps = props => {
|
|
|
71140
71488
|
onOpen,
|
|
71141
71489
|
children: childrenProp,
|
|
71142
71490
|
mount,
|
|
71491
|
+
// Read by usePopupName below, never written on the element.
|
|
71492
|
+
openerAriaLabel,
|
|
71493
|
+
openerAriaLabelledBy,
|
|
71143
71494
|
...rest
|
|
71144
71495
|
} = props;
|
|
71145
71496
|
// Assigned on every render, like openEffect below, so it always closes over
|
|
@@ -71150,7 +71501,16 @@ const usePopoverProps = props => {
|
|
|
71150
71501
|
mount,
|
|
71151
71502
|
anchor
|
|
71152
71503
|
});
|
|
71153
|
-
const
|
|
71504
|
+
const [nameProps, registerTitle] = usePopupName({
|
|
71505
|
+
ariaLabel: rest["aria-label"],
|
|
71506
|
+
ariaLabelledBy: rest["aria-labelledby"],
|
|
71507
|
+
openerAriaLabel,
|
|
71508
|
+
openerAriaLabelledBy
|
|
71509
|
+
});
|
|
71510
|
+
const children = contentMounted ? jsx(PopupTitleContext.Provider, {
|
|
71511
|
+
value: registerTitle,
|
|
71512
|
+
children: childrenProp
|
|
71513
|
+
}) : null;
|
|
71154
71514
|
const isTopLayer = layer === "top";
|
|
71155
71515
|
const ref = props.ref;
|
|
71156
71516
|
const backdropRef = useRef();
|
|
@@ -71955,6 +72315,10 @@ const usePopoverProps = props => {
|
|
|
71955
72315
|
"navi-hidden": openController.openedInDom ? undefined : "",
|
|
71956
72316
|
"styleCSSVars": POPUP_STYLE_CSS_VARS,
|
|
71957
72317
|
...rest,
|
|
72318
|
+
...nameProps,
|
|
72319
|
+
// A <div> has no role, and a name on an element without one is read by
|
|
72320
|
+
// nobody: a popover something names is a dialog, unless told what else.
|
|
72321
|
+
"role": rest.role ?? (nameProps["aria-labelledby"] === undefined && nameProps["aria-label"] === undefined ? undefined : "dialog"),
|
|
71958
72322
|
...autoFocusProps,
|
|
71959
72323
|
ref,
|
|
71960
72324
|
// Not a control, but still something the rest of navi has to be able to
|
|
@@ -72070,9 +72434,10 @@ const resolvePositionAreaAndAnimationKind = ({
|
|
|
72070
72434
|
};
|
|
72071
72435
|
};
|
|
72072
72436
|
Popover.Close = PopupClose;
|
|
72437
|
+
Popover.Title = PopupTitle;
|
|
72073
72438
|
|
|
72074
72439
|
installImportMetaCssBuild(import.meta);
|
|
72075
|
-
const css$
|
|
72440
|
+
const css$A = /* css */`@layer navi {
|
|
72076
72441
|
.navi_popup {
|
|
72077
72442
|
--popup-border-radius: var(--navi-popup-border-radius);
|
|
72078
72443
|
--popup-border-width: 1px;
|
|
@@ -72213,6 +72578,10 @@ const css$C = /* css */`@layer navi {
|
|
|
72213
72578
|
* @param {string} [props.className] - Merged with the shared
|
|
72214
72579
|
* `"navi_popup"` class (see this file's own CSS) rather than replacing
|
|
72215
72580
|
* it.
|
|
72581
|
+
* @param {string} [props.openerAriaLabelledBy] - Forwarded as-is: the name the
|
|
72582
|
+
* popup takes when neither `aria-label`/`aria-labelledby` nor a
|
|
72583
|
+
* `<Popup.Title>` in `children` names it (see `Dialog`/`Popover`).
|
|
72584
|
+
* @param {string} [props.openerAriaLabel] - Forwarded as-is, same.
|
|
72216
72585
|
* @param {"always"|"idle"|"from-first-open"|"while-opened"} [props.mount] - When
|
|
72217
72586
|
* `children` are built and thrown away (see popup_content_mount.js).
|
|
72218
72587
|
* `"from-first-open"` (the default) builds them on the first open and keeps
|
|
@@ -72228,7 +72597,7 @@ const css$C = /* css */`@layer navi {
|
|
|
72228
72597
|
* @param {import("ignore:preact").ComponentChildren} props.children
|
|
72229
72598
|
*/
|
|
72230
72599
|
const Popup = props => {
|
|
72231
|
-
import.meta.css = [css$
|
|
72600
|
+
import.meta.css = [css$A, "@jsenv/navi/src/layout/popup.jsx"];
|
|
72232
72601
|
const {
|
|
72233
72602
|
mode: modeProp,
|
|
72234
72603
|
maxWidth,
|
|
@@ -72311,6 +72680,7 @@ const Popup = props => {
|
|
|
72311
72680
|
});
|
|
72312
72681
|
};
|
|
72313
72682
|
Popup.Close = PopupClose;
|
|
72683
|
+
Popup.Title = PopupTitle;
|
|
72314
72684
|
|
|
72315
72685
|
// What Dialog's own animation values mean to a popover, which has no lift
|
|
72316
72686
|
// (see the `animation` doc above).
|
|
@@ -72359,6 +72729,54 @@ const pickerUIIsNaviOwn = ui => {
|
|
|
72359
72729
|
return Boolean(ui) && typeof ui === "object" && Boolean(ui.type?.isPickerOwnUI);
|
|
72360
72730
|
};
|
|
72361
72731
|
|
|
72732
|
+
/*
|
|
72733
|
+
* What the picker really is, said on the element that holds the name and takes
|
|
72734
|
+
* the focus (the host input in picker.jsx), which is both what a screen reader
|
|
72735
|
+
* announces and what getByRole(role, { name }) finds:
|
|
72736
|
+
* - a picker that picks nothing is a door — its popup is a question
|
|
72737
|
+
* (type="confirm") or something to read (mode="callout", which says it for
|
|
72738
|
+
* itself) — and a door is pressed: "button";
|
|
72739
|
+
* - a picker holding a value and opening a popup of navi's is a select-only
|
|
72740
|
+
* combobox: it shows a value the user does not type, and opens what changes
|
|
72741
|
+
* it. A textbox could not say the rest — aria-expanded is not allowed on one,
|
|
72742
|
+
* so "open" and "closed" would never be announced;
|
|
72743
|
+
* - a picker showing the browser's own picker (no popup of navi's) stays the
|
|
72744
|
+
* textbox its <input> is.
|
|
72745
|
+
*/
|
|
72746
|
+
const getPickerHostRole = props => {
|
|
72747
|
+
if (props.role !== undefined) {
|
|
72748
|
+
return props.role;
|
|
72749
|
+
}
|
|
72750
|
+
if (props.picksNothing) {
|
|
72751
|
+
return "button";
|
|
72752
|
+
}
|
|
72753
|
+
if (props["aria-haspopup"] !== undefined) {
|
|
72754
|
+
return "combobox";
|
|
72755
|
+
}
|
|
72756
|
+
return undefined;
|
|
72757
|
+
};
|
|
72758
|
+
|
|
72759
|
+
/*
|
|
72760
|
+
* And what that button is called, when the caller wrote it as a drawing rather
|
|
72761
|
+
* than as a word: a door draws no value, so what sits in its value slot IS its
|
|
72762
|
+
* label — the `ui` a caller gave it, or its placeholder. Undefined the moment
|
|
72763
|
+
* the caller names it themselves (aria-label/aria-labelledby), which is the
|
|
72764
|
+
* only way to name a door drawn as an icon. Read by the popup too: what the
|
|
72765
|
+
* user pressed is a fair name for what it opened.
|
|
72766
|
+
*/
|
|
72767
|
+
const getPickerHostLabelId = (id, props) => {
|
|
72768
|
+
if (getPickerHostRole(props) !== "button") {
|
|
72769
|
+
return undefined;
|
|
72770
|
+
}
|
|
72771
|
+
if (props["aria-label"] !== undefined || props["aria-labelledby"] !== undefined) {
|
|
72772
|
+
return undefined;
|
|
72773
|
+
}
|
|
72774
|
+
if (props.variant === "headless" || props.ui === "default") {
|
|
72775
|
+
return undefined;
|
|
72776
|
+
}
|
|
72777
|
+
return `${id}_picker_label`;
|
|
72778
|
+
};
|
|
72779
|
+
|
|
72362
72780
|
/**
|
|
72363
72781
|
* What the picker holds, read from inside its `ui` — for a drawing given as
|
|
72364
72782
|
* an element (`ui={<MyCard game={game} />}`), which the picker cannot hand
|
|
@@ -72388,7 +72806,7 @@ const usePickerState = () => {
|
|
|
72388
72806
|
};
|
|
72389
72807
|
|
|
72390
72808
|
installImportMetaCssBuild(import.meta);
|
|
72391
|
-
const css$
|
|
72809
|
+
const css$z = /* css */`.navi_picker_callout_dock > [data-picker-content] {
|
|
72392
72810
|
display: none;
|
|
72393
72811
|
}
|
|
72394
72812
|
|
|
@@ -72417,7 +72835,7 @@ const css$B = /* css */`.navi_picker_callout_dock > [data-picker-content] {
|
|
|
72417
72835
|
}
|
|
72418
72836
|
}
|
|
72419
72837
|
|
|
72420
|
-
.navi_picker[
|
|
72838
|
+
.navi_picker[navi-popover-mode="overlay"][aria-expanded="true"] {
|
|
72421
72839
|
border-color: #0000;
|
|
72422
72840
|
}
|
|
72423
72841
|
|
|
@@ -72445,7 +72863,7 @@ const css$B = /* css */`.navi_picker_callout_dock > [data-picker-content] {
|
|
|
72445
72863
|
}
|
|
72446
72864
|
`;
|
|
72447
72865
|
const PickerCustomResolver = props => {
|
|
72448
|
-
import.meta.css = [css$
|
|
72866
|
+
import.meta.css = [css$z, "@jsenv/navi/src/control/picker/picker_custom.jsx"];
|
|
72449
72867
|
if (props.children === undefined) {
|
|
72450
72868
|
return renderResolver(PickerNative, props);
|
|
72451
72869
|
}
|
|
@@ -72616,8 +73034,9 @@ const PickerCustom = props => {
|
|
|
72616
73034
|
props.id = props.id || controlId || idDefault;
|
|
72617
73035
|
// Given no value, the picker holds what the control in its popup holds (see
|
|
72618
73036
|
// the `mount` decision below) — and a group around it collects that from the
|
|
72619
|
-
// moment both exist.
|
|
72620
|
-
|
|
73037
|
+
// moment both exist. A picker that picks nothing holds none: its popup's
|
|
73038
|
+
// controls are never adopted (see canRegisterAsFacadeChild).
|
|
73039
|
+
const valueInPopup = !props.picksNothing && !isControlValueGivenByProps(props);
|
|
72621
73040
|
const parentController = useContext(ParentUIStateControllerContext);
|
|
72622
73041
|
const answersToGroup = Boolean(parentController) && !props.standalone;
|
|
72623
73042
|
// Same narrow-container/maxWidth-compact heuristic Popup itself uses (see
|
|
@@ -73254,6 +73673,24 @@ const isPressDisputedByHold = pickerEl => Boolean(pickerEl?.parentElement?.close
|
|
|
73254
73673
|
const getPickerInput = pickerEl => {
|
|
73255
73674
|
return pickerEl.querySelector(".navi_picker_input");
|
|
73256
73675
|
};
|
|
73676
|
+
|
|
73677
|
+
// The <label>s naming a picker's trigger, by id. Read off the document: it is
|
|
73678
|
+
// the one place a label[for] and its control meet (navi's own Label carries an
|
|
73679
|
+
// id for this). A label wrapping the picker is left out — it holds the trigger
|
|
73680
|
+
// and the popup with it, and the popup would be named after its own content.
|
|
73681
|
+
const getTriggerLabelIds = pickerEl => {
|
|
73682
|
+
const labels = pickerEl && getPickerInput(pickerEl)?.labels;
|
|
73683
|
+
if (!labels) {
|
|
73684
|
+
return undefined;
|
|
73685
|
+
}
|
|
73686
|
+
const ids = [];
|
|
73687
|
+
for (const label of labels) {
|
|
73688
|
+
if (label.id && !label.contains(pickerEl)) {
|
|
73689
|
+
ids.push(label.id);
|
|
73690
|
+
}
|
|
73691
|
+
}
|
|
73692
|
+
return ids.length === 0 ? undefined : ids.join(" ");
|
|
73693
|
+
};
|
|
73257
73694
|
const getPickerInputUIState = pickerEl => {
|
|
73258
73695
|
const pickerInput = getPickerInput(pickerEl);
|
|
73259
73696
|
return getUIStateFromElement(pickerInput);
|
|
@@ -73276,6 +73713,11 @@ const PickerContentInsidePopup = props => {
|
|
|
73276
73713
|
// Same reason: a `data-testid` on the picker names the trigger (see
|
|
73277
73714
|
// docs/testid.md) — this one names the popup.
|
|
73278
73715
|
popupTestId,
|
|
73716
|
+
// Same again for the accessible name: aria-label/aria-labelledby on the
|
|
73717
|
+
// picker name the trigger (see control_context.js), these the popup.
|
|
73718
|
+
popupAriaLabel,
|
|
73719
|
+
popupAriaLabelledBy,
|
|
73720
|
+
popupAriaDescribedBy,
|
|
73279
73721
|
positionArea,
|
|
73280
73722
|
popoverMode = "nearby",
|
|
73281
73723
|
popoverSpacing = popoverMode === "nearby" ? 5 : 0,
|
|
@@ -73337,8 +73779,25 @@ const PickerContentInsidePopup = props => {
|
|
|
73337
73779
|
} = props;
|
|
73338
73780
|
const isPopover = mode === "popover";
|
|
73339
73781
|
const isCallout = mode === "callout";
|
|
73340
|
-
|
|
73341
|
-
|
|
73782
|
+
// The trigger's name, in the order the browser reads it, for the popup to
|
|
73783
|
+
// take when neither the caller nor a <Popup.Title> names it: "Report this
|
|
73784
|
+
// book" is a fair name for the sheet it opens, "Start date" for a calendar.
|
|
73785
|
+
let openerAriaLabelledBy = rest["aria-labelledby"] ?? getPickerHostLabelId(props.id, props);
|
|
73786
|
+
let openerAriaLabel;
|
|
73787
|
+
if (openerAriaLabelledBy === undefined) {
|
|
73788
|
+
openerAriaLabel = rest["aria-label"];
|
|
73789
|
+
// Read only while open: the labels are a question for the document, and
|
|
73790
|
+
// a closed popup has nobody to announce it.
|
|
73791
|
+
if (openerAriaLabel === undefined && rest["aria-expanded"]) {
|
|
73792
|
+
openerAriaLabelledBy = getTriggerLabelIds(props.ref.current);
|
|
73793
|
+
}
|
|
73794
|
+
}
|
|
73795
|
+
return jsx(Next
|
|
73796
|
+
// A dialog in either mode: what a picker opens is content of the
|
|
73797
|
+
// caller's, never a listbox (a selectable List is a group of radios or
|
|
73798
|
+
// checkboxes). The popover says so with its role, below.
|
|
73799
|
+
, {
|
|
73800
|
+
"aria-haspopup": "dialog",
|
|
73342
73801
|
"navi-popover-mode": isPopover ? popoverMode : undefined,
|
|
73343
73802
|
...rest,
|
|
73344
73803
|
// On popupProps already (see the picker's popup assembly); they mean
|
|
@@ -73383,11 +73842,23 @@ const PickerContentInsidePopup = props => {
|
|
|
73383
73842
|
pressOutside: pressOutside,
|
|
73384
73843
|
children: jsx(PopupModeContext.Provider, {
|
|
73385
73844
|
value: mode,
|
|
73386
|
-
children:
|
|
73845
|
+
children: jsx(PopupTitleContext.Provider, {
|
|
73846
|
+
value: null,
|
|
73847
|
+
children: children
|
|
73848
|
+
})
|
|
73387
73849
|
})
|
|
73388
73850
|
}) : jsx(Popup, {
|
|
73389
73851
|
...popupProps,
|
|
73390
73852
|
"data-testid": popupTestId
|
|
73853
|
+
// What the trigger's aria-haspopup announces; a <dialog> says it
|
|
73854
|
+
// for itself.
|
|
73855
|
+
,
|
|
73856
|
+
role: isPopover ? "dialog" : undefined,
|
|
73857
|
+
"aria-label": popupAriaLabel,
|
|
73858
|
+
"aria-labelledby": popupAriaLabelledBy,
|
|
73859
|
+
"aria-describedby": popupAriaDescribedBy,
|
|
73860
|
+
openerAriaLabel: openerAriaLabel,
|
|
73861
|
+
openerAriaLabelledBy: openerAriaLabelledBy
|
|
73391
73862
|
// What the CSS above keys on: this picker's own popup, and no other
|
|
73392
73863
|
// popup below the picker.
|
|
73393
73864
|
,
|
|
@@ -73657,7 +74128,7 @@ const showNativePicker = (pickerInput, event) => {
|
|
|
73657
74128
|
};
|
|
73658
74129
|
|
|
73659
74130
|
installImportMetaCssBuild(import.meta);
|
|
73660
|
-
const css$
|
|
74131
|
+
const css$y = /* css */`.navi_picker_confirm_body {
|
|
73661
74132
|
min-width: 180px;
|
|
73662
74133
|
max-width: 320px;
|
|
73663
74134
|
padding: var(--navi-m);
|
|
@@ -73673,7 +74144,7 @@ const css$A = /* css */`.navi_picker_confirm_body {
|
|
|
73673
74144
|
}
|
|
73674
74145
|
`;
|
|
73675
74146
|
const PickerConfirmResolver = props => {
|
|
73676
|
-
import.meta.css = [css$
|
|
74147
|
+
import.meta.css = [css$y, "@jsenv/navi/src/control/picker/picker_confirm.jsx"];
|
|
73677
74148
|
const Next = useNextResolver();
|
|
73678
74149
|
if (props.type !== "confirm") {
|
|
73679
74150
|
return jsx(Next, {
|
|
@@ -73747,12 +74218,7 @@ const PickerConfirmResolver = props => {
|
|
|
73747
74218
|
mode: mode,
|
|
73748
74219
|
focusCapture: focusCapture,
|
|
73749
74220
|
openWhileReadOnly: openWhileReadOnly,
|
|
73750
|
-
onConfirm: onConfirm
|
|
73751
|
-
// A question holds no value to read before it is asked: the popup is
|
|
73752
|
-
// built on the first open, like that of a picker told its value (see
|
|
73753
|
-
// the `mount` resolution in picker_custom.jsx).
|
|
73754
|
-
,
|
|
73755
|
-
mount: MOUNT_DEFAULT,
|
|
74221
|
+
onConfirm: onConfirm,
|
|
73756
74222
|
message: undefined,
|
|
73757
74223
|
confirmLabel: undefined,
|
|
73758
74224
|
cancelLabel: undefined,
|
|
@@ -74199,7 +74665,7 @@ const LoadingIndicator = ({
|
|
|
74199
74665
|
};
|
|
74200
74666
|
|
|
74201
74667
|
installImportMetaCssBuild(import.meta);
|
|
74202
|
-
const css$
|
|
74668
|
+
const css$x = /* css */`@layer navi {
|
|
74203
74669
|
.navi_separator {
|
|
74204
74670
|
--size: 1px;
|
|
74205
74671
|
--color: var(--navi-separator-color-default);
|
|
@@ -74273,7 +74739,7 @@ const Separator = ({
|
|
|
74273
74739
|
style,
|
|
74274
74740
|
...props
|
|
74275
74741
|
}) => {
|
|
74276
|
-
import.meta.css = [css$
|
|
74742
|
+
import.meta.css = [css$x, "@jsenv/navi/src/layout/separator.jsx"];
|
|
74277
74743
|
return jsx(Box, {
|
|
74278
74744
|
as: vertical ? "span" : "hr",
|
|
74279
74745
|
...props,
|
|
@@ -75067,7 +75533,7 @@ const listItemBlockedMessage = (loading, props) => {
|
|
|
75067
75533
|
};
|
|
75068
75534
|
|
|
75069
75535
|
installImportMetaCssBuild(import.meta);
|
|
75070
|
-
const css$
|
|
75536
|
+
const css$w = /* css */`@layer navi {
|
|
75071
75537
|
.navi_list_container[navi-selectable] {
|
|
75072
75538
|
--list-item-outline-width: var(--navi-focus-outline-width);
|
|
75073
75539
|
--list-item-outline-offset: calc(-1 * var(--list-item-outline-width));
|
|
@@ -75240,7 +75706,7 @@ const ListSelectableResolver = props => {
|
|
|
75240
75706
|
};
|
|
75241
75707
|
const ListSelectable = props => {
|
|
75242
75708
|
const Next = useNextResolver();
|
|
75243
|
-
import.meta.css = [css$
|
|
75709
|
+
import.meta.css = [css$w, "@jsenv/navi/src/control/list/list_selectable.jsx"];
|
|
75244
75710
|
// we allow ourselves to auto-generate a name
|
|
75245
75711
|
const defaultName = useId();
|
|
75246
75712
|
props.name = props.name || `listbox_${defaultName}`;
|
|
@@ -75909,7 +76375,7 @@ const ListRunItemContext = createContext(null);
|
|
|
75909
76375
|
// item takes its place in the collection by slot: the place is then the list's
|
|
75910
76376
|
// to move, and the item's to follow — see list_items.js.
|
|
75911
76377
|
const ListSlotContext = createContext(null);
|
|
75912
|
-
const css$
|
|
76378
|
+
const css$v = /* css */`@property --list-group-label-height {
|
|
75913
76379
|
syntax: "<length>";
|
|
75914
76380
|
inherits: false;
|
|
75915
76381
|
initial-value: 0;
|
|
@@ -76437,7 +76903,7 @@ const resolveRenderBudget = renderBudget => {
|
|
|
76437
76903
|
};
|
|
76438
76904
|
};
|
|
76439
76905
|
const ListUI = props => {
|
|
76440
|
-
import.meta.css = [css$
|
|
76906
|
+
import.meta.css = [css$v, "@jsenv/navi/src/control/list/list.jsx"];
|
|
76441
76907
|
const {
|
|
76442
76908
|
ref,
|
|
76443
76909
|
renderBudget: renderBudgetProp,
|
|
@@ -82552,7 +83018,7 @@ const createBadgeRegistry = () => {
|
|
|
82552
83018
|
};
|
|
82553
83019
|
|
|
82554
83020
|
installImportMetaCssBuild(import.meta);
|
|
82555
|
-
const css$
|
|
83021
|
+
const css$u = /* css */`@layer navi;
|
|
82556
83022
|
|
|
82557
83023
|
.navi_badge {
|
|
82558
83024
|
--font-size: .7em;
|
|
@@ -82655,7 +83121,7 @@ const BadgeUI = ({
|
|
|
82655
83121
|
className,
|
|
82656
83122
|
...props
|
|
82657
83123
|
}) => {
|
|
82658
|
-
import.meta.css = [css$
|
|
83124
|
+
import.meta.css = [css$u, "@jsenv/navi/src/text/badge.jsx"];
|
|
82659
83125
|
const defaultRef = useRef();
|
|
82660
83126
|
props.ref = props.ref || defaultRef;
|
|
82661
83127
|
const {
|
|
@@ -82763,7 +83229,7 @@ const wrapLabels = childArray => {
|
|
|
82763
83229
|
};
|
|
82764
83230
|
|
|
82765
83231
|
installImportMetaCssBuild(import.meta);
|
|
82766
|
-
const css$
|
|
83232
|
+
const css$t = /* css */`@layer navi;
|
|
82767
83233
|
|
|
82768
83234
|
.navi_badge_list {
|
|
82769
83235
|
flex-wrap: wrap;
|
|
@@ -82898,7 +83364,7 @@ const useBadgeRegistry = (children, enabled) => {
|
|
|
82898
83364
|
* component grants (a <Picker>, see max_lines_context.js).
|
|
82899
83365
|
*/
|
|
82900
83366
|
const BadgeList = props => {
|
|
82901
|
-
import.meta.css = [css$
|
|
83367
|
+
import.meta.css = [css$t, "@jsenv/navi/src/text/badge_list.jsx"];
|
|
82902
83368
|
const {
|
|
82903
83369
|
maxLines,
|
|
82904
83370
|
max,
|
|
@@ -83242,7 +83708,7 @@ const BadgeListContent = ({
|
|
|
83242
83708
|
};
|
|
83243
83709
|
|
|
83244
83710
|
installImportMetaCssBuild(import.meta);
|
|
83245
|
-
const css$
|
|
83711
|
+
const css$s = /* css */`.navi_color {
|
|
83246
83712
|
aspect-ratio: 1;
|
|
83247
83713
|
background-color: currentColor;
|
|
83248
83714
|
border: 1px solid #0003;
|
|
@@ -83262,7 +83728,7 @@ const Color = ({
|
|
|
83262
83728
|
children,
|
|
83263
83729
|
...rest
|
|
83264
83730
|
}) => {
|
|
83265
|
-
import.meta.css = [css$
|
|
83731
|
+
import.meta.css = [css$s, "@jsenv/navi/src/text/color.jsx"];
|
|
83266
83732
|
const color = children || undefined;
|
|
83267
83733
|
return jsx(Box, {
|
|
83268
83734
|
as: "span",
|
|
@@ -83749,7 +84215,7 @@ const PickerFileUI = /*#__PURE__*/asPickerOwnUI(() => {
|
|
|
83749
84215
|
});
|
|
83750
84216
|
|
|
83751
84217
|
installImportMetaCssBuild(import.meta);
|
|
83752
|
-
const css$
|
|
84218
|
+
const css$r = /* css */`@layer navi {
|
|
83753
84219
|
.navi_picker {
|
|
83754
84220
|
--picker-border-radius: var(--navi-control-border-radius);
|
|
83755
84221
|
--picker-border-width: var(--navi-control-border-width);
|
|
@@ -84218,7 +84684,7 @@ const css$t = /* css */`@layer navi {
|
|
|
84218
84684
|
}
|
|
84219
84685
|
`;
|
|
84220
84686
|
const PickerButton = props => {
|
|
84221
|
-
import.meta.css = [css$
|
|
84687
|
+
import.meta.css = [css$r, "@jsenv/navi/src/control/picker/picker.jsx"];
|
|
84222
84688
|
if (typeof props.maxLines === "string") {
|
|
84223
84689
|
props.maxLines = parseInt(props.maxLines);
|
|
84224
84690
|
}
|
|
@@ -84259,11 +84725,6 @@ const PickerButton = props => {
|
|
|
84259
84725
|
// confirm resolver (see picker_confirm.jsx), which is the picker that is
|
|
84260
84726
|
// one — a caller whose popup is a menu of actions says it for themselves.
|
|
84261
84727
|
picksNothing,
|
|
84262
|
-
// Where the caller's own role goes: onto the host, beside the name (see
|
|
84263
|
-
// control_context.js) — a role and a name on two different elements name
|
|
84264
|
-
// nothing at all. Left unsaid, a picker that picks nothing takes "button"
|
|
84265
|
-
// (see PickerInput below).
|
|
84266
|
-
role,
|
|
84267
84728
|
readOnly,
|
|
84268
84729
|
error,
|
|
84269
84730
|
// Who draws the loading outline. Left unsaid, the picker does, around its
|
|
@@ -84344,21 +84805,8 @@ const PickerButton = props => {
|
|
|
84344
84805
|
// clearing being a modification like any other.
|
|
84345
84806
|
const interactive = !basePseudoState[":disabled"] && !basePseudoState[":read-only"] && !loading;
|
|
84346
84807
|
usePickerErrorCallout(uiStateController, error);
|
|
84347
|
-
|
|
84348
|
-
|
|
84349
|
-
// door — its popup is a question (type="confirm") or something to read
|
|
84350
|
-
// (mode="callout", which says it for itself) — and a door is pressed. So it
|
|
84351
|
-
// answers to "button" rather than to the "textbox" its <input> would
|
|
84352
|
-
// otherwise be, which is both what a screen reader announces and what
|
|
84353
|
-
// getByRole("button", { name }) finds. A picker holding a value stays a
|
|
84354
|
-
// textbox: it does hold text.
|
|
84355
|
-
const hostRole = role ?? (picksNothing ? "button" : undefined);
|
|
84356
|
-
// And what that button is called, when the caller wrote it as a drawing
|
|
84357
|
-
// rather than as a word: a door draws no value, so what sits in its value
|
|
84358
|
-
// slot IS its label — the `ui` a caller gave it, or its placeholder. Skipped
|
|
84359
|
-
// the moment the caller names it themselves (aria-label/aria-labelledby),
|
|
84360
|
-
// which is the only way to name a door drawn as an icon.
|
|
84361
|
-
const hostLabelId = hostRole === "button" && inputProps["aria-label"] === undefined && inputProps["aria-labelledby"] === undefined && variant !== "headless" && ui !== "default" ? `${inputProps.id}_picker_label` : undefined;
|
|
84808
|
+
const hostRole = getPickerHostRole(props);
|
|
84809
|
+
const hostLabelId = getPickerHostLabelId(inputProps.id, props);
|
|
84362
84810
|
// What the picker knows about itself, for the pieces it does not place: the
|
|
84363
84811
|
// drawings of its value (Picker.UI.*), and the affordances a caller may put
|
|
84364
84812
|
// in their own `ui` (Picker.Clear) as much as the ones it puts in its slot.
|
|
@@ -84427,8 +84875,16 @@ const PickerButton = props => {
|
|
|
84427
84875
|
basePseudoState: basePseudoState,
|
|
84428
84876
|
styleCSSVars: PickerStyleCSSVars,
|
|
84429
84877
|
variant: undefined,
|
|
84430
|
-
icon: undefined
|
|
84878
|
+
icon: undefined
|
|
84879
|
+
// The caller's own role goes onto the host, beside the name (see
|
|
84880
|
+
// control_context.js): a role and a name on two different elements
|
|
84881
|
+
// name nothing at all. What the trigger opens is said there too, and
|
|
84882
|
+
// aria-haspopup with it. aria-expanded stays here as well: commands.js
|
|
84883
|
+
// and the CSS read the open state off the root (see
|
|
84884
|
+
// expandableRepeatedBy in commands.js).
|
|
84885
|
+
,
|
|
84431
84886
|
role: undefined,
|
|
84887
|
+
"aria-haspopup": undefined,
|
|
84432
84888
|
rightSlotIcon: undefined,
|
|
84433
84889
|
rightSlotIconSize: undefined,
|
|
84434
84890
|
rightSlot: undefined,
|
|
@@ -84468,6 +84924,8 @@ const PickerButton = props => {
|
|
|
84468
84924
|
inset: loadingOutlineInset
|
|
84469
84925
|
}), jsx(PickerInput, {
|
|
84470
84926
|
role: hostRole,
|
|
84927
|
+
"aria-haspopup": props["aria-haspopup"],
|
|
84928
|
+
"aria-expanded": props["aria-expanded"],
|
|
84471
84929
|
"aria-labelledby": hostLabelId,
|
|
84472
84930
|
tabIndex: variant === "headless" ? -1 : undefined,
|
|
84473
84931
|
"aria-hidden": variant === "headless" ? "true" : undefined,
|
|
@@ -84993,7 +85451,7 @@ const Picker = /*#__PURE__*/Object.assign(PickerResolved, {
|
|
|
84993
85451
|
});
|
|
84994
85452
|
|
|
84995
85453
|
installImportMetaCssBuild(import.meta);
|
|
84996
|
-
const css$
|
|
85454
|
+
const css$q = /* css */`@layer navi {
|
|
84997
85455
|
.navi_picker_spin {
|
|
84998
85456
|
--picker-spin-padding-x-default: var(--navi-picker-padding-x-default);
|
|
84999
85457
|
--picker-spin-padding-y-default: var(--navi-picker-padding-y-default);
|
|
@@ -85343,7 +85801,7 @@ const Spin = ({
|
|
|
85343
85801
|
nextLabel,
|
|
85344
85802
|
...rest
|
|
85345
85803
|
}) => {
|
|
85346
|
-
import.meta.css = [css$
|
|
85804
|
+
import.meta.css = [css$q, "@jsenv/navi/src/control/picker/picker_spin.jsx"];
|
|
85347
85805
|
const id = useId();
|
|
85348
85806
|
// What the group around it says, when there is one: how big the whole thing
|
|
85349
85807
|
// is written is said once, on the group, and every spin in it follows.
|
|
@@ -86054,7 +86512,7 @@ const renderValueDefault = value => String(value ?? "");
|
|
|
86054
86512
|
* are passed on to the spins sitting in them.
|
|
86055
86513
|
*/
|
|
86056
86514
|
const SpinGroup = props => {
|
|
86057
|
-
import.meta.css = [css$
|
|
86515
|
+
import.meta.css = [css$q, "@jsenv/navi/src/control/picker/picker_spin.jsx"];
|
|
86058
86516
|
const {
|
|
86059
86517
|
size
|
|
86060
86518
|
} = props;
|
|
@@ -86563,7 +87021,7 @@ const TimeRangeSpin = ({
|
|
|
86563
87021
|
};
|
|
86564
87022
|
|
|
86565
87023
|
installImportMetaCssBuild(import.meta);
|
|
86566
|
-
const css$
|
|
87024
|
+
const css$p = /* css */`.navi_checkbox_group {
|
|
86567
87025
|
border-style: solid;
|
|
86568
87026
|
|
|
86569
87027
|
&[data-callout] {
|
|
@@ -86623,7 +87081,7 @@ const CheckboxGroup = props => {
|
|
|
86623
87081
|
return checkboxGroup;
|
|
86624
87082
|
};
|
|
86625
87083
|
const CheckboxGroupInterface = props => {
|
|
86626
|
-
import.meta.css = [css$
|
|
87084
|
+
import.meta.css = [css$p, "@jsenv/navi/src/control/input/checkbox_group.jsx"];
|
|
86627
87085
|
const {
|
|
86628
87086
|
ref
|
|
86629
87087
|
} = props;
|
|
@@ -86741,7 +87199,7 @@ const formatIntlUnit = (unit, {
|
|
|
86741
87199
|
};
|
|
86742
87200
|
|
|
86743
87201
|
installImportMetaCssBuild(import.meta);
|
|
86744
|
-
const css$
|
|
87202
|
+
const css$o = /* css */`.navi_input_duration {
|
|
86745
87203
|
--duration-separator-spacing: 4px;
|
|
86746
87204
|
--loader-color: var(--navi-loader-color);
|
|
86747
87205
|
position: relative;
|
|
@@ -86806,7 +87264,7 @@ const css$q = /* css */`.navi_input_duration {
|
|
|
86806
87264
|
* "auto" aligns each field toward its neighbouring separator (first→right, last→left, middle/solo→center).
|
|
86807
87265
|
*/
|
|
86808
87266
|
const InputDuration = props => {
|
|
86809
|
-
import.meta.css = [css$
|
|
87267
|
+
import.meta.css = [css$o, "@jsenv/navi/src/control/input/input_duration.jsx"];
|
|
86810
87268
|
const defaultRef = useRef();
|
|
86811
87269
|
props.ref = props.ref || defaultRef;
|
|
86812
87270
|
props.max = props.max || "23h59";
|
|
@@ -87307,7 +87765,7 @@ const InputDurationPart = ({
|
|
|
87307
87765
|
};
|
|
87308
87766
|
|
|
87309
87767
|
installImportMetaCssBuild(import.meta);
|
|
87310
|
-
const css$
|
|
87768
|
+
const css$n = /* css */`.navi_radio_group {
|
|
87311
87769
|
border-style: solid;
|
|
87312
87770
|
|
|
87313
87771
|
&[data-callout] {
|
|
@@ -87347,7 +87805,7 @@ const RadioGroup = props => {
|
|
|
87347
87805
|
return radioGroup;
|
|
87348
87806
|
};
|
|
87349
87807
|
const RadioGroupInterface = props => {
|
|
87350
|
-
import.meta.css = [css$
|
|
87808
|
+
import.meta.css = [css$n, "@jsenv/navi/src/control/input/radio_group.jsx"];
|
|
87351
87809
|
const {
|
|
87352
87810
|
ref
|
|
87353
87811
|
} = props;
|
|
@@ -87377,7 +87835,7 @@ const RadioGroupInterface = props => {
|
|
|
87377
87835
|
};
|
|
87378
87836
|
|
|
87379
87837
|
installImportMetaCssBuild(import.meta);
|
|
87380
|
-
const css$
|
|
87838
|
+
const css$m = /* css */`.navi_input.navi_select {
|
|
87381
87839
|
& .navi_control_input {
|
|
87382
87840
|
padding-right: calc(var(--x-padding-right) + 1em);
|
|
87383
87841
|
line-height: var(--navi-control-line-height);
|
|
@@ -87424,7 +87882,7 @@ const Select = ({
|
|
|
87424
87882
|
...props
|
|
87425
87883
|
}) => {
|
|
87426
87884
|
installInputCss();
|
|
87427
|
-
import.meta.css = [css$
|
|
87885
|
+
import.meta.css = [css$m, "@jsenv/navi/src/control/input/select.jsx"];
|
|
87428
87886
|
const defaultRef = useRef(null);
|
|
87429
87887
|
props.ref = props.ref || defaultRef;
|
|
87430
87888
|
seedDefaultValueFromSignal(props);
|
|
@@ -87474,7 +87932,7 @@ const Select = ({
|
|
|
87474
87932
|
};
|
|
87475
87933
|
|
|
87476
87934
|
installImportMetaCssBuild(import.meta);
|
|
87477
|
-
const css$
|
|
87935
|
+
const css$l = /* css */`.navi_split_button {
|
|
87478
87936
|
border-radius: var(--navi-control-border-radius);
|
|
87479
87937
|
display: inline-flex;
|
|
87480
87938
|
position: relative;
|
|
@@ -87596,7 +88054,7 @@ const css$n = /* css */`.navi_split_button {
|
|
|
87596
88054
|
* on the split button's own box.
|
|
87597
88055
|
*/
|
|
87598
88056
|
const SplitButton = props => {
|
|
87599
|
-
import.meta.css = [css$
|
|
88057
|
+
import.meta.css = [css$l, "@jsenv/navi/src/control/input/split_button.jsx"];
|
|
87600
88058
|
const {
|
|
87601
88059
|
options = [],
|
|
87602
88060
|
value,
|
|
@@ -88615,7 +89073,7 @@ const createItemTracker = (onChange) => {
|
|
|
88615
89073
|
};
|
|
88616
89074
|
|
|
88617
89075
|
installImportMetaCssBuild(import.meta);
|
|
88618
|
-
const css$
|
|
89076
|
+
const css$k = /* css */`.navi_wheel_container {
|
|
88619
89077
|
--wheel-item-height: round(1.8em, 1px);
|
|
88620
89078
|
--wheel-emphasis-size: round(1.5em, 1px);
|
|
88621
89079
|
--wheel-item-width: 3.5ch;
|
|
@@ -89563,7 +90021,7 @@ const useWheelKeyboard = ({
|
|
|
89563
90021
|
}, [isHorizontal, interactive, isLoop]);
|
|
89564
90022
|
};
|
|
89565
90023
|
function WheelUI(props) {
|
|
89566
|
-
import.meta.css = [css$
|
|
90024
|
+
import.meta.css = [css$k, "@jsenv/navi/src/control/wheel/wheel.jsx"];
|
|
89567
90025
|
const {
|
|
89568
90026
|
ref,
|
|
89569
90027
|
visibleCount = 3,
|
|
@@ -90553,7 +91011,7 @@ Wheel.Item = WheelItem;
|
|
|
90553
91011
|
* @param {boolean|number} [props.zoom] - Enlarge the centered value of every wheel (see Wheel's zoom prop) with one prop for the whole group.
|
|
90554
91012
|
*/
|
|
90555
91013
|
const WheelGroup = props => {
|
|
90556
|
-
import.meta.css = [css$
|
|
91014
|
+
import.meta.css = [css$k, "@jsenv/navi/src/control/wheel/wheel.jsx"];
|
|
90557
91015
|
// WheelGroup IS a control group: it aggregates its named wheels ("hours",
|
|
90558
91016
|
// "minutes"…) into one object value, so it can sit directly inside a Form or a
|
|
90559
91017
|
// Picker with no extra <ControlGroup> wrapper. The wheel-specific presentation
|
|
@@ -90726,7 +91184,7 @@ const WheelColon = props => {
|
|
|
90726
91184
|
Wheel.Colon = WheelColon;
|
|
90727
91185
|
|
|
90728
91186
|
installImportMetaCssBuild(import.meta);
|
|
90729
|
-
const css$
|
|
91187
|
+
const css$j = /* css */`.navi_time_range_label {
|
|
90730
91188
|
--wheel-item-height: round(1.8em, 1px);
|
|
90731
91189
|
color: var(--wheel-color, light-dark(#111, #eee));
|
|
90732
91190
|
line-height: var(--wheel-item-height);
|
|
@@ -90950,7 +91408,7 @@ const TimeRangeWheel = ({
|
|
|
90950
91408
|
endTimeProps,
|
|
90951
91409
|
...rest
|
|
90952
91410
|
}) => {
|
|
90953
|
-
import.meta.css = [css$
|
|
91411
|
+
import.meta.css = [css$j, "@jsenv/navi/src/control/wheel/wheel_time.jsx"];
|
|
90954
91412
|
const startId = useId();
|
|
90955
91413
|
const startRef = useRef(null);
|
|
90956
91414
|
const endRef = useRef(null);
|
|
@@ -91538,7 +91996,7 @@ const Z_INDEX_DROP_PREVIEW = Z_INDEX_STICKY_CORNER + 1;
|
|
|
91538
91996
|
const Z_INDEX_TABLE_UI = Z_INDEX_STICKY_CORNER + 1;
|
|
91539
91997
|
|
|
91540
91998
|
installImportMetaCssBuild(import.meta);
|
|
91541
|
-
const css$
|
|
91999
|
+
const css$i = /* css */`.navi_table_drag_clone_container {
|
|
91542
92000
|
top: var(--table-visual-top);
|
|
91543
92001
|
left: var(--table-visual-left);
|
|
91544
92002
|
width: var(--table-visual-width);
|
|
@@ -91693,7 +92151,7 @@ const useTableDragContextValue = ({
|
|
|
91693
92151
|
}, [grabTarget, canChangeColumnOrder]);
|
|
91694
92152
|
};
|
|
91695
92153
|
const TableDragCloneContainer = /*#__PURE__*/forwardRef((props, ref) => {
|
|
91696
|
-
import.meta.css = [css$
|
|
92154
|
+
import.meta.css = [css$i, "@jsenv/navi/src/control/table/drag/table_drag.jsx"];
|
|
91697
92155
|
const {
|
|
91698
92156
|
tableId
|
|
91699
92157
|
} = props;
|
|
@@ -91992,7 +92450,7 @@ const ROW_MIN_HEIGHT = 30;
|
|
|
91992
92450
|
const ROW_MAX_HEIGHT = 100;
|
|
91993
92451
|
const COLUMN_MIN_WIDTH = 50;
|
|
91994
92452
|
const COLUMN_MAX_WIDTH = 500;
|
|
91995
|
-
const css$
|
|
92453
|
+
const css$h = /* css */`@layer navi {
|
|
91996
92454
|
.navi_table {
|
|
91997
92455
|
--table-resizer-handle-color: #063b7c;
|
|
91998
92456
|
--table-resizer-color: #387ec9;
|
|
@@ -92161,7 +92619,7 @@ const css$j = /* css */`@layer navi {
|
|
|
92161
92619
|
|
|
92162
92620
|
// Column resize components
|
|
92163
92621
|
const TableColumnResizer = props => {
|
|
92164
|
-
import.meta.css = [css$
|
|
92622
|
+
import.meta.css = [css$h, "@jsenv/navi/src/control/table/resize/table_resize.jsx"];
|
|
92165
92623
|
const defaultRef = useRef();
|
|
92166
92624
|
const ref = props.ref || defaultRef;
|
|
92167
92625
|
return jsxs("div", {
|
|
@@ -92633,7 +93091,7 @@ const findPreviousTableRow = currentRow => {
|
|
|
92633
93091
|
};
|
|
92634
93092
|
|
|
92635
93093
|
installImportMetaCssBuild(import.meta);
|
|
92636
|
-
const css$
|
|
93094
|
+
const css$g = /* css */`@layer navi {
|
|
92637
93095
|
.navi_table {
|
|
92638
93096
|
--selection-border-color: var(--navi-selection-border-color, #0078d4);
|
|
92639
93097
|
--selection-background-color: var(--navi-selection-background-color, #eaf1fd);
|
|
@@ -92727,7 +93185,7 @@ const useTableSelectionController = ({
|
|
|
92727
93185
|
onSelectionChange,
|
|
92728
93186
|
selectionColor
|
|
92729
93187
|
}) => {
|
|
92730
|
-
import.meta.css = [css$
|
|
93188
|
+
import.meta.css = [css$g, "@jsenv/navi/src/control/table/selection/table_selection.jsx"];
|
|
92731
93189
|
const selectionController = useSelectionController({
|
|
92732
93190
|
elementRef: tableRef,
|
|
92733
93191
|
layout: "grid",
|
|
@@ -93198,7 +93656,7 @@ const useTableStickyContextValue = ({
|
|
|
93198
93656
|
};
|
|
93199
93657
|
|
|
93200
93658
|
installImportMetaCssBuild(import.meta);
|
|
93201
|
-
const css$
|
|
93659
|
+
const css$f = /* css */`@layer navi {
|
|
93202
93660
|
.navi_table {
|
|
93203
93661
|
--sticky-frontier-color: silver;
|
|
93204
93662
|
--sticky-frontier-size: 12px;
|
|
@@ -93371,7 +93829,7 @@ const css$h = /* css */`@layer navi {
|
|
|
93371
93829
|
const TableStickyFrontier = ({
|
|
93372
93830
|
tableRef
|
|
93373
93831
|
}) => {
|
|
93374
|
-
import.meta.css = [css$
|
|
93832
|
+
import.meta.css = [css$f, "@jsenv/navi/src/control/table/sticky/table_sticky.jsx"];
|
|
93375
93833
|
const stickyLeftFrontierGhostRef = useRef();
|
|
93376
93834
|
const stickyLeftFrontierPreviewRef = useRef();
|
|
93377
93835
|
const stickyTopFrontierGhostRef = useRef();
|
|
@@ -93602,7 +94060,7 @@ installImportMetaCssBuild(import.meta);
|
|
|
93602
94060
|
* inset 0 -1px 0 0 color; // Bottom border
|
|
93603
94061
|
*/
|
|
93604
94062
|
|
|
93605
|
-
const css$
|
|
94063
|
+
const css$e = /* css */ `.navi_table_root {
|
|
93606
94064
|
max-width: var(--table-max-width, none);
|
|
93607
94065
|
max-height: var(--table-max-height, none);
|
|
93608
94066
|
position: relative;
|
|
@@ -93787,11 +94245,11 @@ const css$g = /* css */ `.navi_table_root {
|
|
|
93787
94245
|
// table must not carry this sheet, and a build that sees no caller drops the
|
|
93788
94246
|
// css with the function.
|
|
93789
94247
|
const installTableCss = () => {
|
|
93790
|
-
import.meta.css = [css$
|
|
94248
|
+
import.meta.css = [css$e, "@jsenv/navi/src/control/table/table_css.js"];
|
|
93791
94249
|
};
|
|
93792
94250
|
|
|
93793
94251
|
installImportMetaCssBuild(import.meta);
|
|
93794
|
-
const css$
|
|
94252
|
+
const css$d = /* css */`.navi_table_ui {
|
|
93795
94253
|
z-index: ${Z_INDEX_TABLE_UI};
|
|
93796
94254
|
pointer-events: none;
|
|
93797
94255
|
position: fixed;
|
|
@@ -93800,7 +94258,7 @@ const css$f = /* css */`.navi_table_ui {
|
|
|
93800
94258
|
}
|
|
93801
94259
|
`;
|
|
93802
94260
|
const TableUI = /*#__PURE__*/forwardRef((props, ref) => {
|
|
93803
|
-
import.meta.css = [css$
|
|
94261
|
+
import.meta.css = [css$d, "@jsenv/navi/src/control/table/table_ui.jsx"];
|
|
93804
94262
|
const {
|
|
93805
94263
|
tableRef,
|
|
93806
94264
|
tableId,
|
|
@@ -94722,7 +95180,7 @@ const normalizeKey = (key) => {
|
|
|
94722
95180
|
};
|
|
94723
95181
|
|
|
94724
95182
|
installImportMetaCssBuild(import.meta);
|
|
94725
|
-
const css$
|
|
95183
|
+
const css$c = /* css */`.navi_shortcut_container[data-visually-hidden], .navi_shortcut_button[data-visually-hidden] {
|
|
94726
95184
|
clip: rect(0, 0, 0, 0);
|
|
94727
95185
|
white-space: nowrap;
|
|
94728
95186
|
opacity: 0;
|
|
@@ -94739,7 +95197,7 @@ const css$e = /* css */`.navi_shortcut_container[data-visually-hidden], .navi_sh
|
|
|
94739
95197
|
const ActiveKeyboardShortcuts = ({
|
|
94740
95198
|
visible
|
|
94741
95199
|
}) => {
|
|
94742
|
-
import.meta.css = [css$
|
|
95200
|
+
import.meta.css = [css$c, "@jsenv/navi/src/keyboard/active_keyboard_shortcuts.jsx"];
|
|
94743
95201
|
const activeShortcuts = activeShortcutsSignal.value;
|
|
94744
95202
|
return jsx("div", {
|
|
94745
95203
|
className: "navi_shortcut_container",
|
|
@@ -94779,7 +95237,7 @@ const KeyboardShortcutAriaElement = ({
|
|
|
94779
95237
|
};
|
|
94780
95238
|
|
|
94781
95239
|
installImportMetaCssBuild(import.meta);
|
|
94782
|
-
const css$
|
|
95240
|
+
const css$b = /* css */`@layer navi {
|
|
94783
95241
|
.navi_clipboard_container {
|
|
94784
95242
|
--height: 1.5em;
|
|
94785
95243
|
--notif-spacing: .5em;
|
|
@@ -94810,7 +95268,7 @@ const ButtonCopyToClipboard = ({
|
|
|
94810
95268
|
children,
|
|
94811
95269
|
...props
|
|
94812
95270
|
}) => {
|
|
94813
|
-
import.meta.css = [css$
|
|
95271
|
+
import.meta.css = [css$b, "@jsenv/navi/src/control/input/button_copy_to_clipboard.jsx"];
|
|
94814
95272
|
const [copied, setCopied] = useState(false);
|
|
94815
95273
|
const renderedRef = useRef();
|
|
94816
95274
|
useEffect(() => {
|
|
@@ -94890,7 +95348,7 @@ const Address = ({
|
|
|
94890
95348
|
};
|
|
94891
95349
|
|
|
94892
95350
|
installImportMetaCssBuild(import.meta);
|
|
94893
|
-
const css$
|
|
95351
|
+
const css$a = /* css */`@layer navi;
|
|
94894
95352
|
|
|
94895
95353
|
.navi_text.navi_badge_count {
|
|
94896
95354
|
white-space: nowrap;
|
|
@@ -95019,7 +95477,7 @@ const BadgeCount = ({
|
|
|
95019
95477
|
lineLayout,
|
|
95020
95478
|
...props
|
|
95021
95479
|
}) => {
|
|
95022
|
-
import.meta.css = [css$
|
|
95480
|
+
import.meta.css = [css$a, "@jsenv/navi/src/text/badge_count.jsx"];
|
|
95023
95481
|
const defaultRef = useRef();
|
|
95024
95482
|
props.ref = props.ref || defaultRef;
|
|
95025
95483
|
const {
|
|
@@ -95162,7 +95620,7 @@ const BadgeCountCircle = ({
|
|
|
95162
95620
|
};
|
|
95163
95621
|
|
|
95164
95622
|
installImportMetaCssBuild(import.meta);
|
|
95165
|
-
const css$
|
|
95623
|
+
const css$9 = /* css */`@layer navi {
|
|
95166
95624
|
.navi_caption {
|
|
95167
95625
|
--color: #6b7280;
|
|
95168
95626
|
}
|
|
@@ -95182,7 +95640,7 @@ const Caption = ({
|
|
|
95182
95640
|
className,
|
|
95183
95641
|
...rest
|
|
95184
95642
|
}) => {
|
|
95185
|
-
import.meta.css = [css$
|
|
95643
|
+
import.meta.css = [css$9, "@jsenv/navi/src/text/caption.jsx"];
|
|
95186
95644
|
return jsx(Text, {
|
|
95187
95645
|
as: "small",
|
|
95188
95646
|
size: "0.8em" // We use em to be relative to the parent (we want to be smaller than the surrounding text)
|
|
@@ -95578,177 +96036,8 @@ const Interpolate = ({
|
|
|
95578
96036
|
});
|
|
95579
96037
|
};
|
|
95580
96038
|
|
|
95581
|
-
const SuccessSvg = () => {
|
|
95582
|
-
return jsx("svg", {
|
|
95583
|
-
viewBox: "0 0 16 16",
|
|
95584
|
-
fill: "currentColor",
|
|
95585
|
-
children: jsx("path", {
|
|
95586
|
-
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"
|
|
95587
|
-
})
|
|
95588
|
-
});
|
|
95589
|
-
};
|
|
95590
|
-
const ErrorSvg = () => {
|
|
95591
|
-
return jsx("svg", {
|
|
95592
|
-
viewBox: "0 0 16 16",
|
|
95593
|
-
fill: "currentColor",
|
|
95594
|
-
children: jsx("path", {
|
|
95595
|
-
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"
|
|
95596
|
-
})
|
|
95597
|
-
});
|
|
95598
|
-
};
|
|
95599
|
-
const InfoSvg$1 = () => {
|
|
95600
|
-
return jsx("svg", {
|
|
95601
|
-
viewBox: "0 0 16 16",
|
|
95602
|
-
fill: "currentColor",
|
|
95603
|
-
children: jsx("path", {
|
|
95604
|
-
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"
|
|
95605
|
-
})
|
|
95606
|
-
});
|
|
95607
|
-
};
|
|
95608
|
-
const WarningSvg = () => {
|
|
95609
|
-
return jsx("svg", {
|
|
95610
|
-
viewBox: "0 0 16 16",
|
|
95611
|
-
fill: "currentColor",
|
|
95612
|
-
children: jsx("path", {
|
|
95613
|
-
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"
|
|
95614
|
-
})
|
|
95615
|
-
});
|
|
95616
|
-
};
|
|
95617
|
-
|
|
95618
96039
|
installImportMetaCssBuild(import.meta);
|
|
95619
|
-
const css$
|
|
95620
|
-
.navi_message_box {
|
|
95621
|
-
--background-color-info: var(--navi-info-color-light);
|
|
95622
|
-
--color-info: var(--navi-info-color);
|
|
95623
|
-
--background-color-success: var(--navi-success-color-light);
|
|
95624
|
-
--color-success: var(--navi-success-color);
|
|
95625
|
-
--background-color-warning: var(--navi-warning-color-light);
|
|
95626
|
-
--color-warning: var(--navi-warning-color);
|
|
95627
|
-
--background-color-error: var(--navi-error-color-light);
|
|
95628
|
-
--color-error: var(--navi-error-color);
|
|
95629
|
-
}
|
|
95630
|
-
}
|
|
95631
|
-
|
|
95632
|
-
.navi_message_box {
|
|
95633
|
-
--x-message-background-color: var(--background-color-info);
|
|
95634
|
-
--x-message-color: var(--color-info);
|
|
95635
|
-
background-color: var(--x-message-background-color);
|
|
95636
|
-
|
|
95637
|
-
& > .navi_icon {
|
|
95638
|
-
flex-shrink: 0;
|
|
95639
|
-
}
|
|
95640
|
-
}
|
|
95641
|
-
|
|
95642
|
-
.navi_message_box[data-status-info] {
|
|
95643
|
-
--x-message-background-color: var(--background-color-info);
|
|
95644
|
-
--x-message-color: var(--color-info);
|
|
95645
|
-
}
|
|
95646
|
-
|
|
95647
|
-
.navi_message_box[data-status-success] {
|
|
95648
|
-
--x-message-background-color: var(--background-color-success);
|
|
95649
|
-
--x-message-color: var(--color-success);
|
|
95650
|
-
}
|
|
95651
|
-
|
|
95652
|
-
.navi_message_box[data-status-warning] {
|
|
95653
|
-
--x-message-background-color: var(--background-color-warning);
|
|
95654
|
-
--x-message-color: var(--color-warning);
|
|
95655
|
-
}
|
|
95656
|
-
|
|
95657
|
-
.navi_message_box[data-status-error] {
|
|
95658
|
-
--x-message-background-color: var(--background-color-error);
|
|
95659
|
-
--x-message-color: var(--color-error);
|
|
95660
|
-
}
|
|
95661
|
-
|
|
95662
|
-
.navi_message_box[data-left-stripe] {
|
|
95663
|
-
border-left: 6px solid var(--x-message-color);
|
|
95664
|
-
border-top-left-radius: 6px;
|
|
95665
|
-
border-bottom-left-radius: 6px;
|
|
95666
|
-
}
|
|
95667
|
-
`;
|
|
95668
|
-
const MessageBox = ({
|
|
95669
|
-
status = "info",
|
|
95670
|
-
padding = "sm",
|
|
95671
|
-
icon,
|
|
95672
|
-
leftStripe,
|
|
95673
|
-
children,
|
|
95674
|
-
onClose,
|
|
95675
|
-
...rest
|
|
95676
|
-
}) => {
|
|
95677
|
-
import.meta.css = [css$a, "@jsenv/navi/src/text/message_box.jsx"];
|
|
95678
|
-
const [hasTitleChild, setHasTitleChild] = useState(false);
|
|
95679
|
-
const innerLeftStripe = leftStripe === undefined ? hasTitleChild : leftStripe;
|
|
95680
|
-
if (icon === true) {
|
|
95681
|
-
icon = status === "info" ? jsx(InfoSvg$1, {}) : status === "success" ? jsx(SuccessSvg, {}) : status === "warning" ? jsx(WarningSvg, {}) : status === "error" ? jsx(ErrorSvg, {}) : null;
|
|
95682
|
-
} else if (typeof icon === "function") {
|
|
95683
|
-
const Comp = icon;
|
|
95684
|
-
icon = jsx(Comp, {});
|
|
95685
|
-
}
|
|
95686
|
-
return jsx(Box, {
|
|
95687
|
-
as: "div",
|
|
95688
|
-
role: status === "info" ? "status" : "alert",
|
|
95689
|
-
"data-left-stripe": innerLeftStripe ? "" : undefined,
|
|
95690
|
-
inline: true,
|
|
95691
|
-
column: true,
|
|
95692
|
-
alignY: "center",
|
|
95693
|
-
spacing: "s",
|
|
95694
|
-
...rest,
|
|
95695
|
-
className: withPropsClassName("navi_message_box", rest.className),
|
|
95696
|
-
padding: padding,
|
|
95697
|
-
pseudoClasses: MessageBoxPseudoClasses,
|
|
95698
|
-
basePseudoState: {
|
|
95699
|
-
":-navi-status-info": status === "info",
|
|
95700
|
-
":-navi-status-success": status === "success",
|
|
95701
|
-
":-navi-status-warning": status === "warning",
|
|
95702
|
-
":-navi-status-error": status === "error"
|
|
95703
|
-
},
|
|
95704
|
-
children: jsx(MessageBoxStatusContext.Provider, {
|
|
95705
|
-
value: status,
|
|
95706
|
-
children: jsxs(MessageBoxReportTitleChildContext.Provider, {
|
|
95707
|
-
value: setHasTitleChild,
|
|
95708
|
-
children: [icon && jsx(Icon, {
|
|
95709
|
-
color: "var(--x-message-color)",
|
|
95710
|
-
height: "1lh",
|
|
95711
|
-
maxHeight: "auto",
|
|
95712
|
-
selfAlignY: "start",
|
|
95713
|
-
aspectRatio: "auto",
|
|
95714
|
-
children: icon
|
|
95715
|
-
}), jsx(Text, {
|
|
95716
|
-
children: children
|
|
95717
|
-
}), onClose &&
|
|
95718
|
-
// A column as tall as the first line of the message, pinned to the
|
|
95719
|
-
// top, the button centered in it: the close button stays level
|
|
95720
|
-
// with the first line however many lines the message takes (same
|
|
95721
|
-
// layout as Callout).
|
|
95722
|
-
jsx(Box, {
|
|
95723
|
-
flex: true,
|
|
95724
|
-
alignY: "center",
|
|
95725
|
-
height: "1lh",
|
|
95726
|
-
selfAlignY: "start",
|
|
95727
|
-
shrink: false,
|
|
95728
|
-
children: jsx(Button, {
|
|
95729
|
-
action: onClose,
|
|
95730
|
-
icon: true,
|
|
95731
|
-
border: "none",
|
|
95732
|
-
style: {
|
|
95733
|
-
":hover": {
|
|
95734
|
-
backgroundColor: "rgba(0, 0, 0, 0.1)"
|
|
95735
|
-
}
|
|
95736
|
-
},
|
|
95737
|
-
children: jsx(Icon, {
|
|
95738
|
-
children: jsx(CloseSvg, {})
|
|
95739
|
-
})
|
|
95740
|
-
})
|
|
95741
|
-
})]
|
|
95742
|
-
})
|
|
95743
|
-
})
|
|
95744
|
-
});
|
|
95745
|
-
};
|
|
95746
|
-
const MessageBoxPseudoClasses = [":-navi-status-info", ":-navi-status-success", ":-navi-status-warning", ":-navi-status-error"];
|
|
95747
|
-
const MessageBoxStatusContext = createContext();
|
|
95748
|
-
const MessageBoxReportTitleChildContext = createContext();
|
|
95749
|
-
|
|
95750
|
-
installImportMetaCssBuild(import.meta);
|
|
95751
|
-
const css$9 = /* css */`@layer navi;
|
|
96040
|
+
const css$8 = /* css */`@layer navi;
|
|
95752
96041
|
|
|
95753
96042
|
.navi_quantity {
|
|
95754
96043
|
flex-direction: column;
|
|
@@ -95849,7 +96138,7 @@ const Quantity = ({
|
|
|
95849
96138
|
bold = true,
|
|
95850
96139
|
...props
|
|
95851
96140
|
}) => {
|
|
95852
|
-
import.meta.css = [css$
|
|
96141
|
+
import.meta.css = [css$8, "@jsenv/navi/src/text/quantity.jsx"];
|
|
95853
96142
|
const value = parseQuantityValue(children);
|
|
95854
96143
|
const valueRounded = integer && typeof value === "number" ? Math.round(value) : value;
|
|
95855
96144
|
const valueFormatted = typeof valueRounded === "number" ? formatNumber(valueRounded, {
|
|
@@ -95908,7 +96197,7 @@ const parseQuantityValue = children => {
|
|
|
95908
96197
|
};
|
|
95909
96198
|
|
|
95910
96199
|
installImportMetaCssBuild(import.meta);
|
|
95911
|
-
const css$
|
|
96200
|
+
const css$7 = /* css */`@layer navi {
|
|
95912
96201
|
.navi_meter {
|
|
95913
96202
|
--loader-color: var(--navi-loader-color);
|
|
95914
96203
|
--track-color: #efefef;
|
|
@@ -96047,7 +96336,7 @@ const Meter = ({
|
|
|
96047
96336
|
style,
|
|
96048
96337
|
...rest
|
|
96049
96338
|
}) => {
|
|
96050
|
-
import.meta.css = [css$
|
|
96339
|
+
import.meta.css = [css$7, "@jsenv/navi/src/text/meter.jsx"];
|
|
96051
96340
|
const defaultRef = useRef();
|
|
96052
96341
|
const ref = rest.ref || defaultRef;
|
|
96053
96342
|
value = Number(value);
|
|
@@ -96162,7 +96451,7 @@ const Paragraph = props => {
|
|
|
96162
96451
|
};
|
|
96163
96452
|
|
|
96164
96453
|
installImportMetaCssBuild(import.meta);
|
|
96165
|
-
const css$
|
|
96454
|
+
const css$6 = /* css */`.navi_text_box {
|
|
96166
96455
|
align-items: flex-start;
|
|
96167
96456
|
min-width: 0;
|
|
96168
96457
|
}
|
|
@@ -96204,7 +96493,7 @@ const TextBox = ({
|
|
|
96204
96493
|
children,
|
|
96205
96494
|
...rest
|
|
96206
96495
|
}) => {
|
|
96207
|
-
import.meta.css = [css$
|
|
96496
|
+
import.meta.css = [css$6, "@jsenv/navi/src/text/text_box.jsx"];
|
|
96208
96497
|
const boxRef = useRef(null);
|
|
96209
96498
|
const contentRef = useRef(null);
|
|
96210
96499
|
useLayoutEffect(() => {
|
|
@@ -96250,40 +96539,6 @@ const adjustWidth = (boxEl, contentEl) => {
|
|
|
96250
96539
|
contentEl.style.width = `${Math.ceil(optimalWidth)}px`;
|
|
96251
96540
|
};
|
|
96252
96541
|
|
|
96253
|
-
installImportMetaCssBuild(import.meta);
|
|
96254
|
-
const css$6 = /* css */`.navi_message_box {
|
|
96255
|
-
& .navi_title {
|
|
96256
|
-
margin-top: 0;
|
|
96257
|
-
margin-bottom: var(--navi-s);
|
|
96258
|
-
color: var(--x-message-color);
|
|
96259
|
-
}
|
|
96260
|
-
}
|
|
96261
|
-
`;
|
|
96262
|
-
const Title = props => {
|
|
96263
|
-
import.meta.css = [css$6, "@jsenv/navi/src/text/title.jsx"];
|
|
96264
|
-
const messageBoxStatus = useContext(MessageBoxStatusContext);
|
|
96265
|
-
const innerAs = props.as || (messageBoxStatus ? "h4" : "h1");
|
|
96266
|
-
const titleLevel = parseInt(innerAs.slice(1));
|
|
96267
|
-
const reportTitleToMessageBox = useContext(MessageBoxReportTitleChildContext);
|
|
96268
|
-
reportTitleToMessageBox?.(true);
|
|
96269
|
-
return jsx(TitleLevelContext.Provider, {
|
|
96270
|
-
value: titleLevel,
|
|
96271
|
-
children: jsx(Text, {
|
|
96272
|
-
bold: true,
|
|
96273
|
-
className: withPropsClassName("navi_title"),
|
|
96274
|
-
as: messageBoxStatus ? "h4" : "h1",
|
|
96275
|
-
...props,
|
|
96276
|
-
pseudoClasses: TitlePseudoClasses,
|
|
96277
|
-
children: props.children
|
|
96278
|
-
})
|
|
96279
|
-
});
|
|
96280
|
-
};
|
|
96281
|
-
const TitleLevelContext = createContext();
|
|
96282
|
-
const useTitleLevel = () => {
|
|
96283
|
-
return useContext(TitleLevelContext);
|
|
96284
|
-
};
|
|
96285
|
-
const TitlePseudoClasses = [":hover"];
|
|
96286
|
-
|
|
96287
96542
|
installImportMetaCssBuild(import.meta);
|
|
96288
96543
|
const css$5 = /* css */`@keyframes navi_image_shimmer {
|
|
96289
96544
|
0% {
|