@jsenv/navi 0.29.306 → 0.29.308
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 +237 -182
- package/dist/dev/jsenv_navi.js.map +11 -11
- package/dist/jsenv_navi.js +211 -176
- package/dist/jsenv_navi.js.map +11 -11
- package/docs/dialog_shape.md +2 -2
- package/docs/popup_open.md +6 -2
- package/package.json +3 -3
package/dist/jsenv_navi.js
CHANGED
|
@@ -12,7 +12,7 @@ import { useErrorBoundary, useLayoutEffect, useContext, useCallback, useRef, use
|
|
|
12
12
|
import { humanizeI18n, prefixFirstAndIndentRemainingLines, setRuntimeLangSource, formatDuration, formatMonth, formatDay, resolveTimeRangePrecision, formatDatePlaceholder, toDate, getRelativeDay, formatDayRelative, formatMonthPlaceholder, formatWeekPlaceholder, formatDatetimePlaceholder, formatDatetime, toTimeOfDay, formatTimeOfDay, formatTime, formatMinuteDuration, formatSecondDuration, formatHourDuration, formatTimeRelative, formatNumber, interpolateText, installInterpolateJsx } from "@jsenv/humanize";
|
|
13
13
|
export { createI18n, formatDatetime, formatDay, formatDayRelative, formatDuration, formatHourDuration, formatMinuteDuration, formatMonth, formatNumber, formatSecondDuration, formatTime, formatTimeOfDay, formatTimeRange, formatTimeRelative, interpolateText } from "@jsenv/humanize";
|
|
14
14
|
import { jsxs, jsx, Fragment } from "preact/jsx-runtime";
|
|
15
|
-
import { durationContainsNaN, compareTwoDurations, durationToSeconds, DISPLAYABLE_RULE, MAX_LINE_BREAKS_RULE, NO_EMOJI_RULE, SINGLE_SPACE_RULE, createValidity, resolveCharClass, getCharClassMessageKey, compileCharClassAnchored, compileCharClass, CHAR_CLASS_PRESETS, parseDuration, durationToISOString } from "@jsenv/validity";
|
|
15
|
+
import { TYPE_RULE, durationContainsNaN, compareTwoDurations, durationToSeconds, DISPLAYABLE_RULE, MAX_LINE_BREAKS_RULE, NO_EMOJI_RULE, SINGLE_SPACE_RULE, createValidity, resolveCharClass, getCharClassMessageKey, compileCharClassAnchored, compileCharClass, CHAR_CLASS_PRESETS, parseDuration, durationToISOString } from "@jsenv/validity";
|
|
16
16
|
export { compareTwoDurations, durationContainsNaN, durationToHours, durationToISOString, durationToMinutes, durationToNumber, durationToSeconds, durationToString, parseDuration } from "@jsenv/validity";
|
|
17
17
|
import { Suspense, createPortal, forwardRef } from "preact/compat";
|
|
18
18
|
|
|
@@ -8211,6 +8211,75 @@ const languagesSignal = computed(() => {
|
|
|
8211
8211
|
// (nor the "languagechange" listener above).
|
|
8212
8212
|
setRuntimeLangSource(() => languagesSignal.value);
|
|
8213
8213
|
|
|
8214
|
+
/**
|
|
8215
|
+
* Where navi meets @jsenv/validity.
|
|
8216
|
+
*
|
|
8217
|
+
* validity names a refusal with a key and its parameters rather than a
|
|
8218
|
+
* sentence, so that a field and a server can refuse in the same words in the
|
|
8219
|
+
* language of the person reading. navi is one of those two callers: it says the
|
|
8220
|
+
* sentence, in the browser, through `naviI18n`. The keys line up on purpose —
|
|
8221
|
+
* validity's `"single_space.start"` is navi's `"constraint.single_space.start"`
|
|
8222
|
+
* — so overriding a message is looking up one key, not going through a
|
|
8223
|
+
* translation table.
|
|
8224
|
+
*
|
|
8225
|
+
* The other direction is `constraintFromValidityRule`: a rule an app wrote for
|
|
8226
|
+
* its server, worn by a control as a constraint.
|
|
8227
|
+
*/
|
|
8228
|
+
|
|
8229
|
+
|
|
8230
|
+
/**
|
|
8231
|
+
* Turns a @jsenv/validity rule into a constraint a control can wear, so an app
|
|
8232
|
+
* rule written once — in the package its server reads too — is checked on both
|
|
8233
|
+
* sides instead of being written twice.
|
|
8234
|
+
*
|
|
8235
|
+
* @param {object} rule
|
|
8236
|
+
* `{ name, applyOn(ruleValue, value, ruleConfig) }`, the same object passed
|
|
8237
|
+
* to `createValidity({ rules })`.
|
|
8238
|
+
* @param {object} [ruleConfig]
|
|
8239
|
+
* What parameterizes the rule, under its own name — `{ maxWords: 40 }` for a
|
|
8240
|
+
* rule named `maxWords`. Pass `formatMessage` here to say the refusal through
|
|
8241
|
+
* the app's own i18n; without it the key is looked up in `naviI18n` under
|
|
8242
|
+
* `constraint.<key>`, and a rule answering with a finished sentence is shown
|
|
8243
|
+
* as-is.
|
|
8244
|
+
*
|
|
8245
|
+
* Call it once, at module level: a constraint rebuilt on every render is a new
|
|
8246
|
+
* object on every check.
|
|
8247
|
+
*/
|
|
8248
|
+
const constraintFromValidityRule = (rule, ruleConfig = {}) => {
|
|
8249
|
+
const { formatMessage, ...ruleParams } = ruleConfig;
|
|
8250
|
+
return {
|
|
8251
|
+
name: rule.name,
|
|
8252
|
+
check: (field) => {
|
|
8253
|
+
const result = rule.applyOn(
|
|
8254
|
+
ruleParams[rule.name],
|
|
8255
|
+
field.uiState,
|
|
8256
|
+
ruleParams,
|
|
8257
|
+
);
|
|
8258
|
+
if (!result) {
|
|
8259
|
+
return null;
|
|
8260
|
+
}
|
|
8261
|
+
if (typeof result === "string") {
|
|
8262
|
+
return result;
|
|
8263
|
+
}
|
|
8264
|
+
if (formatMessage) {
|
|
8265
|
+
return formatMessage(result.key, result.params);
|
|
8266
|
+
}
|
|
8267
|
+
return naviI18nFromValidityMessage(result);
|
|
8268
|
+
},
|
|
8269
|
+
};
|
|
8270
|
+
};
|
|
8271
|
+
|
|
8272
|
+
const naviI18nFromValidityMessage = ({ key, params }) => {
|
|
8273
|
+
if (params && typeof params.max === "number") {
|
|
8274
|
+
// Lets a template pluralize on the bound it names: "[max] retour[s]".
|
|
8275
|
+
return naviI18n(`constraint.${key}`, {
|
|
8276
|
+
...params,
|
|
8277
|
+
s: params.max > 1 ? "s" : "",
|
|
8278
|
+
});
|
|
8279
|
+
}
|
|
8280
|
+
return naviI18n(`constraint.${key}`, params);
|
|
8281
|
+
};
|
|
8282
|
+
|
|
8214
8283
|
/**
|
|
8215
8284
|
* https://developer.mozilla.org/en-US/docs/Web/HTML/Guides/Constraint_validation
|
|
8216
8285
|
*/
|
|
@@ -8360,9 +8429,8 @@ const PATTERN_CONSTRAINT = {
|
|
|
8360
8429
|
};
|
|
8361
8430
|
CONSTRAINT_ATTRIBUTE_SET.add("pattern");
|
|
8362
8431
|
|
|
8363
|
-
//
|
|
8364
|
-
|
|
8365
|
-
/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
|
|
8432
|
+
// What an address is, is @jsenv/validity's `type: "email"`: a server checking
|
|
8433
|
+
// the value again refuses it for the same reason and in the same words.
|
|
8366
8434
|
const TYPE_EMAIL_CONSTRAINT = {
|
|
8367
8435
|
name: "type_email",
|
|
8368
8436
|
messageAttribute: "data-type-message",
|
|
@@ -8376,14 +8444,11 @@ const TYPE_EMAIL_CONSTRAINT = {
|
|
|
8376
8444
|
if (!valueAsString) {
|
|
8377
8445
|
return null;
|
|
8378
8446
|
}
|
|
8379
|
-
|
|
8447
|
+
const result = TYPE_RULE.applyOn("email", valueAsString);
|
|
8448
|
+
if (!result) {
|
|
8380
8449
|
return null;
|
|
8381
8450
|
}
|
|
8382
|
-
|
|
8383
|
-
if (!valueAsString.includes("@")) {
|
|
8384
|
-
return naviI18n("constraint.type.email.at", { value: valueAsString });
|
|
8385
|
-
}
|
|
8386
|
-
return naviI18n("constraint.type.email.invalid");
|
|
8451
|
+
return naviI18nFromValidityMessage(result);
|
|
8387
8452
|
},
|
|
8388
8453
|
};
|
|
8389
8454
|
|
|
@@ -11542,75 +11607,6 @@ const isFunctionButNotAnActionFunction = (action) => {
|
|
|
11542
11607
|
return typeof action === "function" && !action.isAction;
|
|
11543
11608
|
};
|
|
11544
11609
|
|
|
11545
|
-
/**
|
|
11546
|
-
* Where navi meets @jsenv/validity.
|
|
11547
|
-
*
|
|
11548
|
-
* validity names a refusal with a key and its parameters rather than a
|
|
11549
|
-
* sentence, so that a field and a server can refuse in the same words in the
|
|
11550
|
-
* language of the person reading. navi is one of those two callers: it says the
|
|
11551
|
-
* sentence, in the browser, through `naviI18n`. The keys line up on purpose —
|
|
11552
|
-
* validity's `"single_space.start"` is navi's `"constraint.single_space.start"`
|
|
11553
|
-
* — so overriding a message is looking up one key, not going through a
|
|
11554
|
-
* translation table.
|
|
11555
|
-
*
|
|
11556
|
-
* The other direction is `constraintFromValidityRule`: a rule an app wrote for
|
|
11557
|
-
* its server, worn by a control as a constraint.
|
|
11558
|
-
*/
|
|
11559
|
-
|
|
11560
|
-
|
|
11561
|
-
/**
|
|
11562
|
-
* Turns a @jsenv/validity rule into a constraint a control can wear, so an app
|
|
11563
|
-
* rule written once — in the package its server reads too — is checked on both
|
|
11564
|
-
* sides instead of being written twice.
|
|
11565
|
-
*
|
|
11566
|
-
* @param {object} rule
|
|
11567
|
-
* `{ name, applyOn(ruleValue, value, ruleConfig) }`, the same object passed
|
|
11568
|
-
* to `createValidity({ rules })`.
|
|
11569
|
-
* @param {object} [ruleConfig]
|
|
11570
|
-
* What parameterizes the rule, under its own name — `{ maxWords: 40 }` for a
|
|
11571
|
-
* rule named `maxWords`. Pass `formatMessage` here to say the refusal through
|
|
11572
|
-
* the app's own i18n; without it the key is looked up in `naviI18n` under
|
|
11573
|
-
* `constraint.<key>`, and a rule answering with a finished sentence is shown
|
|
11574
|
-
* as-is.
|
|
11575
|
-
*
|
|
11576
|
-
* Call it once, at module level: a constraint rebuilt on every render is a new
|
|
11577
|
-
* object on every check.
|
|
11578
|
-
*/
|
|
11579
|
-
const constraintFromValidityRule = (rule, ruleConfig = {}) => {
|
|
11580
|
-
const { formatMessage, ...ruleParams } = ruleConfig;
|
|
11581
|
-
return {
|
|
11582
|
-
name: rule.name,
|
|
11583
|
-
check: (field) => {
|
|
11584
|
-
const result = rule.applyOn(
|
|
11585
|
-
ruleParams[rule.name],
|
|
11586
|
-
field.uiState,
|
|
11587
|
-
ruleParams,
|
|
11588
|
-
);
|
|
11589
|
-
if (!result) {
|
|
11590
|
-
return null;
|
|
11591
|
-
}
|
|
11592
|
-
if (typeof result === "string") {
|
|
11593
|
-
return result;
|
|
11594
|
-
}
|
|
11595
|
-
if (formatMessage) {
|
|
11596
|
-
return formatMessage(result.key, result.params);
|
|
11597
|
-
}
|
|
11598
|
-
return naviI18nFromValidityMessage(result);
|
|
11599
|
-
},
|
|
11600
|
-
};
|
|
11601
|
-
};
|
|
11602
|
-
|
|
11603
|
-
const naviI18nFromValidityMessage = ({ key, params }) => {
|
|
11604
|
-
if (params && typeof params.max === "number") {
|
|
11605
|
-
// Lets a template pluralize on the bound it names: "[max] retour[s]".
|
|
11606
|
-
return naviI18n(`constraint.${key}`, {
|
|
11607
|
-
...params,
|
|
11608
|
-
s: params.max > 1 ? "s" : "",
|
|
11609
|
-
});
|
|
11610
|
-
}
|
|
11611
|
-
return naviI18n(`constraint.${key}`, params);
|
|
11612
|
-
};
|
|
11613
|
-
|
|
11614
11610
|
/**
|
|
11615
11611
|
* `data-displayable` — the value must be something the layout can actually
|
|
11616
11612
|
* draw. What it refuses and why lives in @jsenv/validity's DISPLAYABLE_RULE:
|
|
@@ -40002,7 +39998,15 @@ const LoadingRectangleSvg = ({
|
|
|
40002
39998
|
strokeWidth,
|
|
40003
39999
|
networkSpeed: networkSpeedForced
|
|
40004
40000
|
}) => {
|
|
40005
|
-
|
|
40001
|
+
// The stroke is centered on the path, so half of it falls outside: drawing
|
|
40002
|
+
// at half the stroke width puts its outer edge exactly on the box, whatever
|
|
40003
|
+
// the box. It used to be a share of the smaller dimension (3%, floored at
|
|
40004
|
+
// 2px), which held the line further and further inside as the box grew — a
|
|
40005
|
+
// caller placing the outline with `inset` got the distance it asked for on a
|
|
40006
|
+
// field and something several pixels inward on a card. Nothing needs the
|
|
40007
|
+
// extra room: the svg is `overflow: visible` and whoever positions the
|
|
40008
|
+
// wrapper already reserves the half stroke.
|
|
40009
|
+
const margin = strokeWidth / 2;
|
|
40006
40010
|
|
|
40007
40011
|
// Calculate the drawable area
|
|
40008
40012
|
const drawableWidth = width - margin * 2;
|
|
@@ -48125,10 +48129,11 @@ const ButtonUI = props => {
|
|
|
48125
48129
|
cta,
|
|
48126
48130
|
spacing,
|
|
48127
48131
|
contentDisplay,
|
|
48128
|
-
//
|
|
48129
|
-
//
|
|
48130
|
-
// the outline belongs around the whole
|
|
48131
|
-
|
|
48132
|
+
// Who draws the loading outline. Left unsaid, the button does; "custom"
|
|
48133
|
+
// says someone else does — a button that is one half of a bigger control:
|
|
48134
|
+
// what is busy is the control, and the outline belongs around the whole
|
|
48135
|
+
// of it (see split_button.jsx).
|
|
48136
|
+
loadingOutline
|
|
48132
48137
|
} = props;
|
|
48133
48138
|
const [buttonControlRootProps, buttonControlHostProps, controlChildrenWrapperProps] = useControlProps(props, {
|
|
48134
48139
|
controlType: "button"
|
|
@@ -48254,7 +48259,7 @@ const ButtonUI = props => {
|
|
|
48254
48259
|
visualSelector: visualSelector,
|
|
48255
48260
|
hasChildUsingForwardedProps: true,
|
|
48256
48261
|
children: [jsx(LoadingOutline, {
|
|
48257
|
-
loading: loadingOutline
|
|
48262
|
+
loading: loadingOutline === "custom" ? false : loading,
|
|
48258
48263
|
inset: -1,
|
|
48259
48264
|
color: "var(--button-loader-color)"
|
|
48260
48265
|
}), jsx(ControlChildrenWrapper, {
|
|
@@ -60436,6 +60441,9 @@ const DIALOG_STYLE_CSS_VARS = {
|
|
|
60436
60441
|
animationDuration: "--popup-animation-duration",
|
|
60437
60442
|
backdropColor: "--backdrop-background",
|
|
60438
60443
|
backdropFilter: "--backdrop-filter",
|
|
60444
|
+
backgroundColor: "--dialog-background-color",
|
|
60445
|
+
boxShadow: "--dialog-box-shadow",
|
|
60446
|
+
borderWidth: "--dialog-border-width",
|
|
60439
60447
|
borderRadius: "--dialog-border-radius",
|
|
60440
60448
|
minWidth: "--dialog-min-width",
|
|
60441
60449
|
maxWidth: "--dialog-max-width",
|
|
@@ -62023,10 +62031,17 @@ const POPOVER_PSEUDO_CLASSES = [":hover", ":active", ":focus", ":focus-visible",
|
|
|
62023
62031
|
// Lets consumers pass animationDuration="0.5s"/borderRadius="8px" as regular
|
|
62024
62032
|
// props; Box maps them to the CSS vars for us (see box.jsx's styleCSSVars
|
|
62025
62033
|
// handling).
|
|
62034
|
+
// The paint props go through the popover's own vars rather than the properties
|
|
62035
|
+
// themselves, so the stylesheet keeps the last word on them (the same reason
|
|
62036
|
+
// dialog.jsx gives for borderRadius).
|
|
62026
62037
|
const POPUP_STYLE_CSS_VARS = {
|
|
62027
62038
|
animationDuration: "--popup-animation-duration",
|
|
62028
62039
|
backdropColor: "--backdrop-background",
|
|
62029
62040
|
backdropFilter: "--backdrop-filter",
|
|
62041
|
+
backgroundColor: "--popover-background-color",
|
|
62042
|
+
boxShadow: "--popover-box-shadow",
|
|
62043
|
+
borderWidth: "--popover-border-width",
|
|
62044
|
+
borderRadius: "--popover-border-radius",
|
|
62030
62045
|
minWidth: "--popover-min-width",
|
|
62031
62046
|
maxWidth: "--popover-max-width",
|
|
62032
62047
|
minHeight: "--popover-min-height",
|
|
@@ -62289,83 +62304,56 @@ const Popup = props => {
|
|
|
62289
62304
|
Popup.Close = PopupClose;
|
|
62290
62305
|
|
|
62291
62306
|
installImportMetaCssBuild(import.meta);
|
|
62292
|
-
const css$B = /* css */`.
|
|
62293
|
-
|
|
62294
|
-
|
|
62295
|
-
|
|
62296
|
-
|
|
62297
|
-
|
|
62298
|
-
|
|
62299
|
-
--popover-outline-width: var(--picker-outline-width);
|
|
62300
|
-
--popover-outline-color: var(--picker-outline-color);
|
|
62301
|
-
--popover-box-shadow: var(--picker-popup-box-shadow, var(--navi-popup-box-shadow));
|
|
62302
|
-
--popover-max-height: var(--picker-popover-max-height);
|
|
62303
|
-
min-width: var(--picker-popover-min-width, var(--anchor-width, 0px));
|
|
62304
|
-
cursor: default;
|
|
62305
|
-
|
|
62306
|
-
& .navi_list_container {
|
|
62307
|
-
--list-border-radius: max(0px,
|
|
62308
|
-
var(--popover-border-radius) - var(--popover-border-width));
|
|
62309
|
-
overscroll-behavior: none;
|
|
62310
|
-
width: 100%;
|
|
62307
|
+
const css$B = /* css */`.navi_popover[data-picker-popup] {
|
|
62308
|
+
--popover-border-radius: var(--picker-border-radius);
|
|
62309
|
+
--popover-border-width: var(--picker-border-width);
|
|
62310
|
+
--popover-border-color: var(--x-picker-border-color);
|
|
62311
|
+
--popover-outline-width: var(--picker-outline-width);
|
|
62312
|
+
--popover-outline-color: var(--picker-outline-color);
|
|
62313
|
+
cursor: default;
|
|
62311
62314
|
|
|
62312
|
-
|
|
62313
|
-
|
|
62314
|
-
|
|
62315
|
-
|
|
62316
|
-
}
|
|
62315
|
+
&:not([navi-hidden]) {
|
|
62316
|
+
flex-direction: column;
|
|
62317
|
+
display: flex;
|
|
62318
|
+
}
|
|
62317
62319
|
|
|
62318
|
-
|
|
62319
|
-
|
|
62320
|
-
border-
|
|
62321
|
-
|
|
62320
|
+
& .navi_list_container {
|
|
62321
|
+
--list-border-radius: max(0px,
|
|
62322
|
+
var(--popover-border-radius) - var(--popover-border-width));
|
|
62323
|
+
overscroll-behavior: none;
|
|
62324
|
+
width: 100%;
|
|
62322
62325
|
|
|
62323
|
-
|
|
62324
|
-
|
|
62325
|
-
display: flex;
|
|
62326
|
-
}
|
|
62326
|
+
&:not([data-overflow-visible]) {
|
|
62327
|
+
overflow: auto;
|
|
62327
62328
|
}
|
|
62328
62329
|
}
|
|
62330
|
+
}
|
|
62329
62331
|
|
|
62330
|
-
|
|
62331
|
-
|
|
62332
|
-
|
|
62333
|
-
--dialog-border-width: var(--picker-dialog-border-width, 0px);
|
|
62334
|
-
--dialog-border-color: var(--x-picker-border-color);
|
|
62335
|
-
--dialog-background-color: var(--picker-popup-background-color, var(--navi-popup-background-color));
|
|
62336
|
-
--dialog-outline-width: var(--picker-outline-width);
|
|
62337
|
-
--dialog-outline-color: var(--picker-outline-color);
|
|
62338
|
-
--dialog-box-shadow: var(--picker-popup-box-shadow, var(--navi-popup-box-shadow));
|
|
62339
|
-
--dialog-min-width: var(--picker-dialog-min-width);
|
|
62340
|
-
--dialog-min-height: var(--picker-dialog-min-height);
|
|
62341
|
-
--dialog-max-width: var(--picker-dialog-max-width);
|
|
62342
|
-
--dialog-max-height: var(--picker-dialog-max-height);
|
|
62343
|
-
cursor: default;
|
|
62332
|
+
.navi_picker[aria-haspopup="listbox"][aria-expanded="true"][navi-popover-mode="overlay"] {
|
|
62333
|
+
border-color: #0000;
|
|
62334
|
+
}
|
|
62344
62335
|
|
|
62345
|
-
|
|
62346
|
-
|
|
62347
|
-
|
|
62336
|
+
.navi_dialog[data-picker-popup] {
|
|
62337
|
+
--dialog-border-radius: var(--picker-border-radius);
|
|
62338
|
+
--dialog-border-color: var(--x-picker-border-color);
|
|
62339
|
+
--dialog-outline-width: var(--picker-outline-width);
|
|
62340
|
+
--dialog-outline-color: var(--picker-outline-color);
|
|
62341
|
+
cursor: default;
|
|
62348
62342
|
|
|
62349
|
-
|
|
62350
|
-
|
|
62351
|
-
|
|
62352
|
-
overscroll-behavior: none;
|
|
62353
|
-
width: 100%;
|
|
62343
|
+
&[open] {
|
|
62344
|
+
flex-direction: column;
|
|
62345
|
+
}
|
|
62354
62346
|
|
|
62355
|
-
|
|
62356
|
-
|
|
62357
|
-
|
|
62358
|
-
|
|
62359
|
-
|
|
62347
|
+
& .navi_list_container {
|
|
62348
|
+
--list-border-radius: max(0px,
|
|
62349
|
+
var(--dialog-border-radius) - var(--dialog-border-width));
|
|
62350
|
+
overscroll-behavior: none;
|
|
62351
|
+
width: 100%;
|
|
62360
62352
|
|
|
62361
|
-
|
|
62362
|
-
|
|
62353
|
+
&:not([data-overflow-visible]) {
|
|
62354
|
+
overflow: auto;
|
|
62363
62355
|
}
|
|
62364
62356
|
}
|
|
62365
|
-
|
|
62366
|
-
&[data-popup-width-fit-content] {
|
|
62367
|
-
--picker-popover-min-width: 0px;
|
|
62368
|
-
}
|
|
62369
62357
|
}
|
|
62370
62358
|
`;
|
|
62371
62359
|
const PickerCustomResolver = props => {
|
|
@@ -63129,6 +63117,22 @@ const PickerContentInsidePopup = props => {
|
|
|
63129
63117
|
// dialogMaxWidth="var(--anchor-width)", as a ceiling) — what keeps a card
|
|
63130
63118
|
// its own width once lifted. Dialog's own `sizeFromAnchor`.
|
|
63131
63119
|
dialogSizeFromAnchor,
|
|
63120
|
+
// The caller's word on the popup's own box. Written on the popup element,
|
|
63121
|
+
// where Popover/Dialog map them to their own vars, rather than as vars on
|
|
63122
|
+
// the picker: a var on the picker inherits into everything the popup
|
|
63123
|
+
// holds, and the pickers in there would read it as their own.
|
|
63124
|
+
popupBackgroundColor,
|
|
63125
|
+
popupBorderRadius,
|
|
63126
|
+
popupBoxShadow,
|
|
63127
|
+
popoverMaxHeight,
|
|
63128
|
+
dialogBorderWidth,
|
|
63129
|
+
dialogMinWidth,
|
|
63130
|
+
dialogMinHeight,
|
|
63131
|
+
dialogMaxWidth,
|
|
63132
|
+
dialogMaxHeight,
|
|
63133
|
+
// The popover is at least as wide as the trigger. True when the CONTENT
|
|
63134
|
+
// should size it (a Wheel) instead of being stretched to the trigger.
|
|
63135
|
+
popupWidthFitContent,
|
|
63132
63136
|
animation,
|
|
63133
63137
|
grow,
|
|
63134
63138
|
animationDuration,
|
|
@@ -63147,7 +63151,6 @@ const PickerContentInsidePopup = props => {
|
|
|
63147
63151
|
return jsx(Next, {
|
|
63148
63152
|
"aria-haspopup": isPopover ? "listbox" : "dialog",
|
|
63149
63153
|
"navi-popover-mode": isPopover ? popoverMode : undefined,
|
|
63150
|
-
"data-dialog-size-from-anchor": !isPopover && dialogSizeFromAnchor ? "" : undefined,
|
|
63151
63154
|
...rest,
|
|
63152
63155
|
// On popupProps already (see the picker's popup assembly); they mean
|
|
63153
63156
|
// nothing to the picker element.
|
|
@@ -63189,7 +63192,23 @@ const PickerContentInsidePopup = props => {
|
|
|
63189
63192
|
})
|
|
63190
63193
|
}) : jsx(Popup, {
|
|
63191
63194
|
...popupProps,
|
|
63192
|
-
"data-testid": popupTestId
|
|
63195
|
+
"data-testid": popupTestId
|
|
63196
|
+
// What the CSS above keys on: this picker's own popup, and no other
|
|
63197
|
+
// popup below the picker.
|
|
63198
|
+
,
|
|
63199
|
+
"data-picker-popup": "",
|
|
63200
|
+
backgroundColor: popupBackgroundColor,
|
|
63201
|
+
borderRadius: popupBorderRadius,
|
|
63202
|
+
boxShadow: popupBoxShadow,
|
|
63203
|
+
borderWidth: isPopover ? undefined : dialogBorderWidth,
|
|
63204
|
+
minWidth: isPopover ? popupWidthFitContent ? undefined : "var(--anchor-width, 0px)" : dialogMinWidth,
|
|
63205
|
+
minHeight: isPopover ? undefined : dialogMinHeight
|
|
63206
|
+
// As wide as the trigger under dialogSizeFromAnchor: Dialog's own
|
|
63207
|
+
// sizeFromAnchor is a floor, this is the ceiling. A dialogMaxWidth of
|
|
63208
|
+
// the caller's still wins.
|
|
63209
|
+
,
|
|
63210
|
+
maxWidth: isPopover ? undefined : dialogMaxWidth === undefined && dialogSizeFromAnchor ? "var(--anchor-width)" : dialogMaxWidth,
|
|
63211
|
+
maxHeight: isPopover ? popoverMaxHeight : dialogMaxHeight,
|
|
63193
63212
|
mode: mode,
|
|
63194
63213
|
layer: popupLayer,
|
|
63195
63214
|
animation: animation,
|
|
@@ -71229,6 +71248,26 @@ const css$t = /* css */`@layer navi {
|
|
|
71229
71248
|
}
|
|
71230
71249
|
}
|
|
71231
71250
|
|
|
71251
|
+
& [data-picker-content] {
|
|
71252
|
+
--picker-padding: initial;
|
|
71253
|
+
--picker-padding-x: initial;
|
|
71254
|
+
--picker-padding-y: initial;
|
|
71255
|
+
--picker-padding-top: initial;
|
|
71256
|
+
--picker-padding-right: initial;
|
|
71257
|
+
--picker-padding-bottom: initial;
|
|
71258
|
+
--picker-padding-left: initial;
|
|
71259
|
+
--picker-press-padding: initial;
|
|
71260
|
+
--picker-press-padding-x: initial;
|
|
71261
|
+
--picker-press-padding-y: initial;
|
|
71262
|
+
--picker-press-padding-top: initial;
|
|
71263
|
+
--picker-press-padding-right: initial;
|
|
71264
|
+
--picker-press-padding-bottom: initial;
|
|
71265
|
+
--picker-press-padding-left: initial;
|
|
71266
|
+
--picker-slot-spacing: initial;
|
|
71267
|
+
--picker-align-x: initial;
|
|
71268
|
+
--picker-align-y: initial;
|
|
71269
|
+
}
|
|
71270
|
+
|
|
71232
71271
|
& .navi_picker_content {
|
|
71233
71272
|
--x-corner-top-left-radius: initial;
|
|
71234
71273
|
--x-corner-top-right-radius: initial;
|
|
@@ -71430,11 +71469,6 @@ const PickerButton = props => {
|
|
|
71430
71469
|
placeholder,
|
|
71431
71470
|
ui,
|
|
71432
71471
|
maxLines: maxLinesProp = 1,
|
|
71433
|
-
// By default the popover is at least as wide as the trigger (min-width:
|
|
71434
|
-
// --anchor-width). Set true when the CONTENT should dictate the popover width
|
|
71435
|
-
// (e.g. a Wheel) instead of being stretched to the trigger — see
|
|
71436
|
-
// picker_custom.jsx.
|
|
71437
|
-
popupWidthFitContent,
|
|
71438
71472
|
// Adds a clear button to the right slot, the same one type="search" puts at
|
|
71439
71473
|
// the end of an input: a picker holds a value the user chose, and unsetting
|
|
71440
71474
|
// it should not require reopening the popup to hunt for a "none" entry.
|
|
@@ -71459,7 +71493,13 @@ const PickerButton = props => {
|
|
|
71459
71493
|
// (see PickerInput below).
|
|
71460
71494
|
role,
|
|
71461
71495
|
readOnly,
|
|
71462
|
-
error
|
|
71496
|
+
error,
|
|
71497
|
+
// Who draws the loading outline. Left unsaid, the picker does, around its
|
|
71498
|
+
// own box; "custom" says someone else does — a bigger surface this box is
|
|
71499
|
+
// a piece of, waiting as a whole (see the `loadingOutline` doc).
|
|
71500
|
+
loadingOutline,
|
|
71501
|
+
// Where the outline runs, in px from the picker's box: negative is outside.
|
|
71502
|
+
loadingOutlineInset = -2
|
|
71463
71503
|
} = props;
|
|
71464
71504
|
// A word in a sentence is never truncated — and the clamp's overflow: hidden
|
|
71465
71505
|
// would cut its dotted underline, which sits on the edge of the line box
|
|
@@ -71578,7 +71618,6 @@ const PickerButton = props => {
|
|
|
71578
71618
|
"navi-single-line": isSingleLine ? "" : undefined,
|
|
71579
71619
|
"navi-ui-custom": ui === "default" ? undefined : "",
|
|
71580
71620
|
"data-readonly-opens": readOnlyOpens ? "" : undefined,
|
|
71581
|
-
"data-popup-width-fit-content": popupWidthFitContent ? "" : undefined,
|
|
71582
71621
|
...pickerRemainingProps,
|
|
71583
71622
|
basePseudoState: basePseudoState,
|
|
71584
71623
|
styleCSSVars: PickerStyleCSSVars,
|
|
@@ -71593,9 +71632,10 @@ const PickerButton = props => {
|
|
|
71593
71632
|
openWhileReadOnly: undefined,
|
|
71594
71633
|
ui: undefined,
|
|
71595
71634
|
maxLines: undefined,
|
|
71596
|
-
popupWidthFitContent: undefined,
|
|
71597
71635
|
error: undefined,
|
|
71598
|
-
dayLabel: undefined
|
|
71636
|
+
dayLabel: undefined,
|
|
71637
|
+
loadingOutline: undefined,
|
|
71638
|
+
loadingOutlineInset: undefined
|
|
71599
71639
|
// This wrapper will receive keyboard event bubbling from the picker popup content
|
|
71600
71640
|
// we re-dispatch on the input (to get escape to close for instance)
|
|
71601
71641
|
,
|
|
@@ -71626,9 +71666,9 @@ const PickerButton = props => {
|
|
|
71626
71666
|
children: jsxs(PickerContext.Provider, {
|
|
71627
71667
|
value: pickerContext,
|
|
71628
71668
|
children: [variant === "headless" ? null : jsx(LoadingOutline, {
|
|
71629
|
-
loading: loading,
|
|
71669
|
+
loading: loadingOutline === "custom" ? false : loading,
|
|
71630
71670
|
color: "var(--picker-loader-color)",
|
|
71631
|
-
inset:
|
|
71671
|
+
inset: loadingOutlineInset
|
|
71632
71672
|
}), jsx(PickerInput, {
|
|
71633
71673
|
role: hostRole,
|
|
71634
71674
|
"aria-labelledby": hostLabelId,
|
|
@@ -71862,7 +71902,7 @@ const PickerClear = ({
|
|
|
71862
71902
|
// removed is the whole field's, and the picker already draws the wait
|
|
71863
71903
|
// around all of it. Two outlines for one wait is one too many.
|
|
71864
71904
|
,
|
|
71865
|
-
loadingOutline:
|
|
71905
|
+
loadingOutline: "custom"
|
|
71866
71906
|
// preventDefault, not just tabIndex="-1": a mousedown focuses its target
|
|
71867
71907
|
// before any click happens, and this button should never hold focus at
|
|
71868
71908
|
// all — the field keeps it.
|
|
@@ -72025,21 +72065,16 @@ const PICKER_BUTTON_PSEUDO_CLASSES = [":hover", ":focus", ":focus-visible", ":fo
|
|
|
72025
72065
|
const PickerInputPseudoClasses = [":focus", ":focus-visible", ":read-only", ":disabled", ":-navi-loading", ":-navi-has-value", ":-navi-expanded"];
|
|
72026
72066
|
|
|
72027
72067
|
// A pair is [the css variable, the style whose values the prop is written in]:
|
|
72028
|
-
//
|
|
72029
|
-
//
|
|
72068
|
+
// slotSpacing takes what margin takes, pressPadding what padding takes — see
|
|
72069
|
+
// box.jsx's readCSSVarEntry.
|
|
72070
|
+
// What the props say about the picker's own box only. The popup props
|
|
72071
|
+
// (popupBackgroundColor, dialogMaxWidth…) are handed to the popup element by
|
|
72072
|
+
// picker_custom.jsx: a variable on the root inherits into everything the popup
|
|
72073
|
+
// holds, and the pickers in there would read it as their own.
|
|
72030
72074
|
const PickerStyleCSSVars = {
|
|
72031
72075
|
"outlineWidth": "--picker-outline-width",
|
|
72032
72076
|
"borderWidth": "--picker-border-width",
|
|
72033
72077
|
"borderRadius": "--picker-border-radius",
|
|
72034
|
-
"popoverMaxHeight": ["--picker-popover-max-height", "maxHeight"],
|
|
72035
|
-
"dialogMinWidth": ["--picker-dialog-min-width", "minWidth"],
|
|
72036
|
-
"dialogMinHeight": ["--picker-dialog-min-height", "minHeight"],
|
|
72037
|
-
"dialogMaxWidth": ["--picker-dialog-max-width", "maxWidth"],
|
|
72038
|
-
"dialogMaxHeight": ["--picker-dialog-max-height", "maxHeight"],
|
|
72039
|
-
"popupBackgroundColor": "--picker-popup-background-color",
|
|
72040
|
-
"popupBorderRadius": ["--picker-popup-border-radius", "borderRadius"],
|
|
72041
|
-
"popupBoxShadow": ["--picker-popup-box-shadow", "boxShadow"],
|
|
72042
|
-
"dialogBorderWidth": ["--picker-dialog-border-width", "borderWidth"],
|
|
72043
72078
|
"slotSpacing": ["--picker-slot-spacing", "margin"],
|
|
72044
72079
|
"pressPadding": ["--picker-press-padding", "padding"],
|
|
72045
72080
|
"pressPaddingX": ["--picker-press-padding-x", "padding"],
|
|
@@ -74604,7 +74639,7 @@ const SplitButton = props => {
|
|
|
74604
74639
|
readOnly,
|
|
74605
74640
|
disabled,
|
|
74606
74641
|
// The outline belongs around the pair, drawn below.
|
|
74607
|
-
loadingOutline:
|
|
74642
|
+
loadingOutline: "custom"
|
|
74608
74643
|
};
|
|
74609
74644
|
return jsxs(Box, {
|
|
74610
74645
|
ref: rootRef,
|