@jsenv/navi 0.29.306 → 0.29.307
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 +228 -181
- package/dist/dev/jsenv_navi.js.map +10 -10
- package/dist/jsenv_navi.js +202 -175
- package/dist/jsenv_navi.js.map +10 -10
- 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:
|
|
@@ -48125,10 +48121,11 @@ const ButtonUI = props => {
|
|
|
48125
48121
|
cta,
|
|
48126
48122
|
spacing,
|
|
48127
48123
|
contentDisplay,
|
|
48128
|
-
//
|
|
48129
|
-
//
|
|
48130
|
-
// the outline belongs around the whole
|
|
48131
|
-
|
|
48124
|
+
// Who draws the loading outline. Left unsaid, the button does; "custom"
|
|
48125
|
+
// says someone else does — a button that is one half of a bigger control:
|
|
48126
|
+
// what is busy is the control, and the outline belongs around the whole
|
|
48127
|
+
// of it (see split_button.jsx).
|
|
48128
|
+
loadingOutline
|
|
48132
48129
|
} = props;
|
|
48133
48130
|
const [buttonControlRootProps, buttonControlHostProps, controlChildrenWrapperProps] = useControlProps(props, {
|
|
48134
48131
|
controlType: "button"
|
|
@@ -48254,7 +48251,7 @@ const ButtonUI = props => {
|
|
|
48254
48251
|
visualSelector: visualSelector,
|
|
48255
48252
|
hasChildUsingForwardedProps: true,
|
|
48256
48253
|
children: [jsx(LoadingOutline, {
|
|
48257
|
-
loading: loadingOutline
|
|
48254
|
+
loading: loadingOutline === "custom" ? false : loading,
|
|
48258
48255
|
inset: -1,
|
|
48259
48256
|
color: "var(--button-loader-color)"
|
|
48260
48257
|
}), jsx(ControlChildrenWrapper, {
|
|
@@ -60436,6 +60433,9 @@ const DIALOG_STYLE_CSS_VARS = {
|
|
|
60436
60433
|
animationDuration: "--popup-animation-duration",
|
|
60437
60434
|
backdropColor: "--backdrop-background",
|
|
60438
60435
|
backdropFilter: "--backdrop-filter",
|
|
60436
|
+
backgroundColor: "--dialog-background-color",
|
|
60437
|
+
boxShadow: "--dialog-box-shadow",
|
|
60438
|
+
borderWidth: "--dialog-border-width",
|
|
60439
60439
|
borderRadius: "--dialog-border-radius",
|
|
60440
60440
|
minWidth: "--dialog-min-width",
|
|
60441
60441
|
maxWidth: "--dialog-max-width",
|
|
@@ -62023,10 +62023,17 @@ const POPOVER_PSEUDO_CLASSES = [":hover", ":active", ":focus", ":focus-visible",
|
|
|
62023
62023
|
// Lets consumers pass animationDuration="0.5s"/borderRadius="8px" as regular
|
|
62024
62024
|
// props; Box maps them to the CSS vars for us (see box.jsx's styleCSSVars
|
|
62025
62025
|
// handling).
|
|
62026
|
+
// The paint props go through the popover's own vars rather than the properties
|
|
62027
|
+
// themselves, so the stylesheet keeps the last word on them (the same reason
|
|
62028
|
+
// dialog.jsx gives for borderRadius).
|
|
62026
62029
|
const POPUP_STYLE_CSS_VARS = {
|
|
62027
62030
|
animationDuration: "--popup-animation-duration",
|
|
62028
62031
|
backdropColor: "--backdrop-background",
|
|
62029
62032
|
backdropFilter: "--backdrop-filter",
|
|
62033
|
+
backgroundColor: "--popover-background-color",
|
|
62034
|
+
boxShadow: "--popover-box-shadow",
|
|
62035
|
+
borderWidth: "--popover-border-width",
|
|
62036
|
+
borderRadius: "--popover-border-radius",
|
|
62030
62037
|
minWidth: "--popover-min-width",
|
|
62031
62038
|
maxWidth: "--popover-max-width",
|
|
62032
62039
|
minHeight: "--popover-min-height",
|
|
@@ -62289,83 +62296,56 @@ const Popup = props => {
|
|
|
62289
62296
|
Popup.Close = PopupClose;
|
|
62290
62297
|
|
|
62291
62298
|
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%;
|
|
62299
|
+
const css$B = /* css */`.navi_popover[data-picker-popup] {
|
|
62300
|
+
--popover-border-radius: var(--picker-border-radius);
|
|
62301
|
+
--popover-border-width: var(--picker-border-width);
|
|
62302
|
+
--popover-border-color: var(--x-picker-border-color);
|
|
62303
|
+
--popover-outline-width: var(--picker-outline-width);
|
|
62304
|
+
--popover-outline-color: var(--picker-outline-color);
|
|
62305
|
+
cursor: default;
|
|
62311
62306
|
|
|
62312
|
-
|
|
62313
|
-
|
|
62314
|
-
|
|
62315
|
-
|
|
62316
|
-
}
|
|
62307
|
+
&:not([navi-hidden]) {
|
|
62308
|
+
flex-direction: column;
|
|
62309
|
+
display: flex;
|
|
62310
|
+
}
|
|
62317
62311
|
|
|
62318
|
-
|
|
62319
|
-
|
|
62320
|
-
border-
|
|
62321
|
-
|
|
62312
|
+
& .navi_list_container {
|
|
62313
|
+
--list-border-radius: max(0px,
|
|
62314
|
+
var(--popover-border-radius) - var(--popover-border-width));
|
|
62315
|
+
overscroll-behavior: none;
|
|
62316
|
+
width: 100%;
|
|
62322
62317
|
|
|
62323
|
-
|
|
62324
|
-
|
|
62325
|
-
display: flex;
|
|
62326
|
-
}
|
|
62318
|
+
&:not([data-overflow-visible]) {
|
|
62319
|
+
overflow: auto;
|
|
62327
62320
|
}
|
|
62328
62321
|
}
|
|
62322
|
+
}
|
|
62329
62323
|
|
|
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;
|
|
62324
|
+
.navi_picker[aria-haspopup="listbox"][aria-expanded="true"][navi-popover-mode="overlay"] {
|
|
62325
|
+
border-color: #0000;
|
|
62326
|
+
}
|
|
62344
62327
|
|
|
62345
|
-
|
|
62346
|
-
|
|
62347
|
-
|
|
62328
|
+
.navi_dialog[data-picker-popup] {
|
|
62329
|
+
--dialog-border-radius: var(--picker-border-radius);
|
|
62330
|
+
--dialog-border-color: var(--x-picker-border-color);
|
|
62331
|
+
--dialog-outline-width: var(--picker-outline-width);
|
|
62332
|
+
--dialog-outline-color: var(--picker-outline-color);
|
|
62333
|
+
cursor: default;
|
|
62348
62334
|
|
|
62349
|
-
|
|
62350
|
-
|
|
62351
|
-
|
|
62352
|
-
overscroll-behavior: none;
|
|
62353
|
-
width: 100%;
|
|
62335
|
+
&[open] {
|
|
62336
|
+
flex-direction: column;
|
|
62337
|
+
}
|
|
62354
62338
|
|
|
62355
|
-
|
|
62356
|
-
|
|
62357
|
-
|
|
62358
|
-
|
|
62359
|
-
|
|
62339
|
+
& .navi_list_container {
|
|
62340
|
+
--list-border-radius: max(0px,
|
|
62341
|
+
var(--dialog-border-radius) - var(--dialog-border-width));
|
|
62342
|
+
overscroll-behavior: none;
|
|
62343
|
+
width: 100%;
|
|
62360
62344
|
|
|
62361
|
-
|
|
62362
|
-
|
|
62345
|
+
&:not([data-overflow-visible]) {
|
|
62346
|
+
overflow: auto;
|
|
62363
62347
|
}
|
|
62364
62348
|
}
|
|
62365
|
-
|
|
62366
|
-
&[data-popup-width-fit-content] {
|
|
62367
|
-
--picker-popover-min-width: 0px;
|
|
62368
|
-
}
|
|
62369
62349
|
}
|
|
62370
62350
|
`;
|
|
62371
62351
|
const PickerCustomResolver = props => {
|
|
@@ -63129,6 +63109,22 @@ const PickerContentInsidePopup = props => {
|
|
|
63129
63109
|
// dialogMaxWidth="var(--anchor-width)", as a ceiling) — what keeps a card
|
|
63130
63110
|
// its own width once lifted. Dialog's own `sizeFromAnchor`.
|
|
63131
63111
|
dialogSizeFromAnchor,
|
|
63112
|
+
// The caller's word on the popup's own box. Written on the popup element,
|
|
63113
|
+
// where Popover/Dialog map them to their own vars, rather than as vars on
|
|
63114
|
+
// the picker: a var on the picker inherits into everything the popup
|
|
63115
|
+
// holds, and the pickers in there would read it as their own.
|
|
63116
|
+
popupBackgroundColor,
|
|
63117
|
+
popupBorderRadius,
|
|
63118
|
+
popupBoxShadow,
|
|
63119
|
+
popoverMaxHeight,
|
|
63120
|
+
dialogBorderWidth,
|
|
63121
|
+
dialogMinWidth,
|
|
63122
|
+
dialogMinHeight,
|
|
63123
|
+
dialogMaxWidth,
|
|
63124
|
+
dialogMaxHeight,
|
|
63125
|
+
// The popover is at least as wide as the trigger. True when the CONTENT
|
|
63126
|
+
// should size it (a Wheel) instead of being stretched to the trigger.
|
|
63127
|
+
popupWidthFitContent,
|
|
63132
63128
|
animation,
|
|
63133
63129
|
grow,
|
|
63134
63130
|
animationDuration,
|
|
@@ -63147,7 +63143,6 @@ const PickerContentInsidePopup = props => {
|
|
|
63147
63143
|
return jsx(Next, {
|
|
63148
63144
|
"aria-haspopup": isPopover ? "listbox" : "dialog",
|
|
63149
63145
|
"navi-popover-mode": isPopover ? popoverMode : undefined,
|
|
63150
|
-
"data-dialog-size-from-anchor": !isPopover && dialogSizeFromAnchor ? "" : undefined,
|
|
63151
63146
|
...rest,
|
|
63152
63147
|
// On popupProps already (see the picker's popup assembly); they mean
|
|
63153
63148
|
// nothing to the picker element.
|
|
@@ -63189,7 +63184,23 @@ const PickerContentInsidePopup = props => {
|
|
|
63189
63184
|
})
|
|
63190
63185
|
}) : jsx(Popup, {
|
|
63191
63186
|
...popupProps,
|
|
63192
|
-
"data-testid": popupTestId
|
|
63187
|
+
"data-testid": popupTestId
|
|
63188
|
+
// What the CSS above keys on: this picker's own popup, and no other
|
|
63189
|
+
// popup below the picker.
|
|
63190
|
+
,
|
|
63191
|
+
"data-picker-popup": "",
|
|
63192
|
+
backgroundColor: popupBackgroundColor,
|
|
63193
|
+
borderRadius: popupBorderRadius,
|
|
63194
|
+
boxShadow: popupBoxShadow,
|
|
63195
|
+
borderWidth: isPopover ? undefined : dialogBorderWidth,
|
|
63196
|
+
minWidth: isPopover ? popupWidthFitContent ? undefined : "var(--anchor-width, 0px)" : dialogMinWidth,
|
|
63197
|
+
minHeight: isPopover ? undefined : dialogMinHeight
|
|
63198
|
+
// As wide as the trigger under dialogSizeFromAnchor: Dialog's own
|
|
63199
|
+
// sizeFromAnchor is a floor, this is the ceiling. A dialogMaxWidth of
|
|
63200
|
+
// the caller's still wins.
|
|
63201
|
+
,
|
|
63202
|
+
maxWidth: isPopover ? undefined : dialogMaxWidth === undefined && dialogSizeFromAnchor ? "var(--anchor-width)" : dialogMaxWidth,
|
|
63203
|
+
maxHeight: isPopover ? popoverMaxHeight : dialogMaxHeight,
|
|
63193
63204
|
mode: mode,
|
|
63194
63205
|
layer: popupLayer,
|
|
63195
63206
|
animation: animation,
|
|
@@ -71229,6 +71240,26 @@ const css$t = /* css */`@layer navi {
|
|
|
71229
71240
|
}
|
|
71230
71241
|
}
|
|
71231
71242
|
|
|
71243
|
+
& [data-picker-content] {
|
|
71244
|
+
--picker-padding: initial;
|
|
71245
|
+
--picker-padding-x: initial;
|
|
71246
|
+
--picker-padding-y: initial;
|
|
71247
|
+
--picker-padding-top: initial;
|
|
71248
|
+
--picker-padding-right: initial;
|
|
71249
|
+
--picker-padding-bottom: initial;
|
|
71250
|
+
--picker-padding-left: initial;
|
|
71251
|
+
--picker-press-padding: initial;
|
|
71252
|
+
--picker-press-padding-x: initial;
|
|
71253
|
+
--picker-press-padding-y: initial;
|
|
71254
|
+
--picker-press-padding-top: initial;
|
|
71255
|
+
--picker-press-padding-right: initial;
|
|
71256
|
+
--picker-press-padding-bottom: initial;
|
|
71257
|
+
--picker-press-padding-left: initial;
|
|
71258
|
+
--picker-slot-spacing: initial;
|
|
71259
|
+
--picker-align-x: initial;
|
|
71260
|
+
--picker-align-y: initial;
|
|
71261
|
+
}
|
|
71262
|
+
|
|
71232
71263
|
& .navi_picker_content {
|
|
71233
71264
|
--x-corner-top-left-radius: initial;
|
|
71234
71265
|
--x-corner-top-right-radius: initial;
|
|
@@ -71430,11 +71461,6 @@ const PickerButton = props => {
|
|
|
71430
71461
|
placeholder,
|
|
71431
71462
|
ui,
|
|
71432
71463
|
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
71464
|
// Adds a clear button to the right slot, the same one type="search" puts at
|
|
71439
71465
|
// the end of an input: a picker holds a value the user chose, and unsetting
|
|
71440
71466
|
// it should not require reopening the popup to hunt for a "none" entry.
|
|
@@ -71459,7 +71485,13 @@ const PickerButton = props => {
|
|
|
71459
71485
|
// (see PickerInput below).
|
|
71460
71486
|
role,
|
|
71461
71487
|
readOnly,
|
|
71462
|
-
error
|
|
71488
|
+
error,
|
|
71489
|
+
// Who draws the loading outline. Left unsaid, the picker does, around its
|
|
71490
|
+
// own box; "custom" says someone else does — a bigger surface this box is
|
|
71491
|
+
// a piece of, waiting as a whole (see the `loadingOutline` doc).
|
|
71492
|
+
loadingOutline,
|
|
71493
|
+
// Where the outline runs, in px from the picker's box: negative is outside.
|
|
71494
|
+
loadingOutlineInset = -2
|
|
71463
71495
|
} = props;
|
|
71464
71496
|
// A word in a sentence is never truncated — and the clamp's overflow: hidden
|
|
71465
71497
|
// would cut its dotted underline, which sits on the edge of the line box
|
|
@@ -71578,7 +71610,6 @@ const PickerButton = props => {
|
|
|
71578
71610
|
"navi-single-line": isSingleLine ? "" : undefined,
|
|
71579
71611
|
"navi-ui-custom": ui === "default" ? undefined : "",
|
|
71580
71612
|
"data-readonly-opens": readOnlyOpens ? "" : undefined,
|
|
71581
|
-
"data-popup-width-fit-content": popupWidthFitContent ? "" : undefined,
|
|
71582
71613
|
...pickerRemainingProps,
|
|
71583
71614
|
basePseudoState: basePseudoState,
|
|
71584
71615
|
styleCSSVars: PickerStyleCSSVars,
|
|
@@ -71593,9 +71624,10 @@ const PickerButton = props => {
|
|
|
71593
71624
|
openWhileReadOnly: undefined,
|
|
71594
71625
|
ui: undefined,
|
|
71595
71626
|
maxLines: undefined,
|
|
71596
|
-
popupWidthFitContent: undefined,
|
|
71597
71627
|
error: undefined,
|
|
71598
|
-
dayLabel: undefined
|
|
71628
|
+
dayLabel: undefined,
|
|
71629
|
+
loadingOutline: undefined,
|
|
71630
|
+
loadingOutlineInset: undefined
|
|
71599
71631
|
// This wrapper will receive keyboard event bubbling from the picker popup content
|
|
71600
71632
|
// we re-dispatch on the input (to get escape to close for instance)
|
|
71601
71633
|
,
|
|
@@ -71626,9 +71658,9 @@ const PickerButton = props => {
|
|
|
71626
71658
|
children: jsxs(PickerContext.Provider, {
|
|
71627
71659
|
value: pickerContext,
|
|
71628
71660
|
children: [variant === "headless" ? null : jsx(LoadingOutline, {
|
|
71629
|
-
loading: loading,
|
|
71661
|
+
loading: loadingOutline === "custom" ? false : loading,
|
|
71630
71662
|
color: "var(--picker-loader-color)",
|
|
71631
|
-
inset:
|
|
71663
|
+
inset: loadingOutlineInset
|
|
71632
71664
|
}), jsx(PickerInput, {
|
|
71633
71665
|
role: hostRole,
|
|
71634
71666
|
"aria-labelledby": hostLabelId,
|
|
@@ -71862,7 +71894,7 @@ const PickerClear = ({
|
|
|
71862
71894
|
// removed is the whole field's, and the picker already draws the wait
|
|
71863
71895
|
// around all of it. Two outlines for one wait is one too many.
|
|
71864
71896
|
,
|
|
71865
|
-
loadingOutline:
|
|
71897
|
+
loadingOutline: "custom"
|
|
71866
71898
|
// preventDefault, not just tabIndex="-1": a mousedown focuses its target
|
|
71867
71899
|
// before any click happens, and this button should never hold focus at
|
|
71868
71900
|
// all — the field keeps it.
|
|
@@ -72025,21 +72057,16 @@ const PICKER_BUTTON_PSEUDO_CLASSES = [":hover", ":focus", ":focus-visible", ":fo
|
|
|
72025
72057
|
const PickerInputPseudoClasses = [":focus", ":focus-visible", ":read-only", ":disabled", ":-navi-loading", ":-navi-has-value", ":-navi-expanded"];
|
|
72026
72058
|
|
|
72027
72059
|
// A pair is [the css variable, the style whose values the prop is written in]:
|
|
72028
|
-
//
|
|
72029
|
-
//
|
|
72060
|
+
// slotSpacing takes what margin takes, pressPadding what padding takes — see
|
|
72061
|
+
// box.jsx's readCSSVarEntry.
|
|
72062
|
+
// What the props say about the picker's own box only. The popup props
|
|
72063
|
+
// (popupBackgroundColor, dialogMaxWidth…) are handed to the popup element by
|
|
72064
|
+
// picker_custom.jsx: a variable on the root inherits into everything the popup
|
|
72065
|
+
// holds, and the pickers in there would read it as their own.
|
|
72030
72066
|
const PickerStyleCSSVars = {
|
|
72031
72067
|
"outlineWidth": "--picker-outline-width",
|
|
72032
72068
|
"borderWidth": "--picker-border-width",
|
|
72033
72069
|
"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
72070
|
"slotSpacing": ["--picker-slot-spacing", "margin"],
|
|
72044
72071
|
"pressPadding": ["--picker-press-padding", "padding"],
|
|
72045
72072
|
"pressPaddingX": ["--picker-press-padding-x", "padding"],
|
|
@@ -74604,7 +74631,7 @@ const SplitButton = props => {
|
|
|
74604
74631
|
readOnly,
|
|
74605
74632
|
disabled,
|
|
74606
74633
|
// The outline belongs around the pair, drawn below.
|
|
74607
|
-
loadingOutline:
|
|
74634
|
+
loadingOutline: "custom"
|
|
74608
74635
|
};
|
|
74609
74636
|
return jsxs(Box, {
|
|
74610
74637
|
ref: rootRef,
|