@jsenv/navi 0.27.48 → 0.27.50
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/jsenv_navi.js +209 -139
- package/dist/jsenv_navi.js.map +36 -43
- package/package.json +2 -2
package/dist/jsenv_navi.js
CHANGED
|
@@ -19687,11 +19687,6 @@ const MIN_CONSTRAINT = {
|
|
|
19687
19687
|
name: "min",
|
|
19688
19688
|
messageAttribute: "data-min-message",
|
|
19689
19689
|
check: (field) => {
|
|
19690
|
-
// Sub-inputs inside a duration_group: min/max is validated at the group level, not per-field.
|
|
19691
|
-
// Per-field min/max attributes are kept for arrow-key navigation bounds only.
|
|
19692
|
-
if (field.parentUIStateController?.controlType === "duration_group") {
|
|
19693
|
-
return null;
|
|
19694
|
-
}
|
|
19695
19690
|
if (field.controlType === "duration_group") {
|
|
19696
19691
|
const min = field.controlHostProps.min;
|
|
19697
19692
|
if (min === undefined || min === null) {
|
|
@@ -19795,11 +19790,6 @@ const MAX_CONSTRAINT = {
|
|
|
19795
19790
|
name: "max",
|
|
19796
19791
|
messageAttribute: "data-max-message",
|
|
19797
19792
|
check: (field) => {
|
|
19798
|
-
// Sub-inputs inside a duration_group: min/max is validated at the group level, not per-field.
|
|
19799
|
-
// Per-field min/max attributes are kept for arrow-key navigation bounds only.
|
|
19800
|
-
if (field.parentUIStateController?.controlType === "duration_group") {
|
|
19801
|
-
return null;
|
|
19802
|
-
}
|
|
19803
19793
|
if (field.controlType === "duration_group") {
|
|
19804
19794
|
const max = field.controlHostProps.max;
|
|
19805
19795
|
if (max === undefined || max === null) {
|
|
@@ -20171,21 +20161,21 @@ const NAVI_VALIDITY_CHANGE_CUSTOM_EVENT = "navi_validity_change";
|
|
|
20171
20161
|
|
|
20172
20162
|
const VALIDATION_TOKEN = createOpenToken();
|
|
20173
20163
|
|
|
20164
|
+
// the order matters here, the first constraint is picked first when multiple constraints fail
|
|
20165
|
+
// so it's better to keep the most complex constraints at the end of the list
|
|
20166
|
+
// so the more basic ones shows up first
|
|
20174
20167
|
const STANDARD_CONSTRAINT_SET = new Set([
|
|
20175
20168
|
REQUIRED_CONSTRAINT,
|
|
20176
20169
|
PATTERN_CONSTRAINT,
|
|
20177
20170
|
TYPE_EMAIL_CONSTRAINT,
|
|
20178
20171
|
TYPE_NUMBER_CONSTRAINT,
|
|
20179
|
-
MIN_LENGTH_CONSTRAINT,
|
|
20180
|
-
MAX_LENGTH_CONSTRAINT,
|
|
20181
20172
|
MIN_CONSTRAINT,
|
|
20182
20173
|
MAX_CONSTRAINT,
|
|
20183
20174
|
STEP_CONSTRAINT,
|
|
20175
|
+
MIN_LENGTH_CONSTRAINT,
|
|
20176
|
+
MAX_LENGTH_CONSTRAINT,
|
|
20184
20177
|
]);
|
|
20185
20178
|
const NAVI_CONSTRAINT_SET = new Set([
|
|
20186
|
-
// the order matters here, the last constraint is picked first when multiple constraints fail
|
|
20187
|
-
// so it's better to keep the most complex constraints at the beginning of the list
|
|
20188
|
-
// so the more basic ones shows up first
|
|
20189
20179
|
MIN_SPECIAL_CHAR_CONSTRAINT,
|
|
20190
20180
|
SINGLE_SPACE_CONSTRAINT,
|
|
20191
20181
|
MIN_DIGIT_CONSTRAINT,
|
|
@@ -20483,10 +20473,10 @@ const createControlValidation = (
|
|
|
20483
20473
|
const pickConstraintFailureInfo = (a, b) => {
|
|
20484
20474
|
const aPrio = getConstraintFailureInfoPriority(a);
|
|
20485
20475
|
const bPrio = getConstraintFailureInfoPriority(b);
|
|
20486
|
-
if (
|
|
20487
|
-
return
|
|
20476
|
+
if (bPrio > aPrio) {
|
|
20477
|
+
return b;
|
|
20488
20478
|
}
|
|
20489
|
-
return
|
|
20479
|
+
return a;
|
|
20490
20480
|
};
|
|
20491
20481
|
const getConstraintFailureInfoPriority = (failureInfo) => {
|
|
20492
20482
|
if (failureInfo.status === "error") {
|
|
@@ -21294,7 +21284,7 @@ const isAncestorOpen = (ancestor) => {
|
|
|
21294
21284
|
* the browser's built-in scroll-into-view that accompanies focus.
|
|
21295
21285
|
* @param {boolean} [options.focusVisible]
|
|
21296
21286
|
* Passed as `focusVisible` to `element.focus()`.
|
|
21297
|
-
* @param {boolean} [options.
|
|
21287
|
+
* @param {boolean} [options.autoFocusSelect]
|
|
21298
21288
|
* When true, also calls `element.select()` after focusing (useful for text inputs).
|
|
21299
21289
|
* @returns {Function} triggerAutofocus — can be called manually with a synthetic
|
|
21300
21290
|
* event to re-run the focus logic outside of the layout-effect lifecycle.
|
|
@@ -21407,7 +21397,7 @@ const useAutoFocus = (
|
|
|
21407
21397
|
? ""
|
|
21408
21398
|
: autoFocus
|
|
21409
21399
|
: undefined,
|
|
21410
|
-
"navi-autofocus-select":
|
|
21400
|
+
"navi-autofocus-select": autoSelect ? "" : undefined,
|
|
21411
21401
|
};
|
|
21412
21402
|
};
|
|
21413
21403
|
|
|
@@ -21924,7 +21914,7 @@ const CONTROL_PROP_SET = new Set([
|
|
|
21924
21914
|
|
|
21925
21915
|
"autoFocus",
|
|
21926
21916
|
"autoFocusVisible",
|
|
21927
|
-
"
|
|
21917
|
+
"autoFocusSelect",
|
|
21928
21918
|
|
|
21929
21919
|
"onMouseDown",
|
|
21930
21920
|
"onClick",
|
|
@@ -21972,36 +21962,30 @@ const FormContext = createContext();
|
|
|
21972
21962
|
* Each value is a regex character class (including the [ ] delimiters).
|
|
21973
21963
|
*/
|
|
21974
21964
|
const CHAR_CLASS_PRESETS = {
|
|
21975
|
-
numeric:
|
|
21976
|
-
alpha:
|
|
21977
|
-
alphanumeric: "[0-9A-Za-z]",
|
|
21978
|
-
|
|
21979
|
-
|
|
21980
|
-
|
|
21981
|
-
|
|
21982
|
-
|
|
21983
|
-
|
|
21984
|
-
|
|
21985
|
-
|
|
21986
|
-
|
|
21987
|
-
|
|
21988
|
-
// Presets that imply a specific mobile keyboard layout
|
|
21989
|
-
const INPUT_MODE_FROM_PRESET = {
|
|
21990
|
-
numeric: "numeric",
|
|
21991
|
-
pin: "numeric",
|
|
21992
|
-
card: "numeric",
|
|
21993
|
-
tel: "tel",
|
|
21965
|
+
numeric: "[0-9]", // digits only
|
|
21966
|
+
alpha: "[A-Za-z]", // letters only
|
|
21967
|
+
alphanumeric: "[0-9A-Za-z]", // letters and digits
|
|
21968
|
+
decimal: "[-0-9.,]", // digits, minus, dot, comma
|
|
21969
|
+
uppercase: "[A-Z]", // uppercase letters only
|
|
21970
|
+
tel: "[-0-9+() ]", // phone: digits, +, -, parens, space
|
|
21971
|
+
email: "[a-zA-Z0-9._%+@-]", // email characters
|
|
21972
|
+
card: "[0-9 ]", // credit card: digits and spaces
|
|
21973
|
+
hex: "[0-9A-Fa-f]", // hexadecimal digits
|
|
21974
|
+
pin: "[0-9]", // numeric PIN
|
|
21975
|
+
postal: "[0-9A-Za-z -]", // postal code (FR, UK, US)
|
|
21976
|
+
iban: "[0-9A-Z]", // IBAN: uppercase and digits
|
|
21977
|
+
slug: "[a-z0-9-]", // URL slug
|
|
21994
21978
|
};
|
|
21995
21979
|
|
|
21996
21980
|
// Specific i18n keys per preset — more informative than the generic fallback
|
|
21997
21981
|
const MESSAGE_KEY_FROM_PRESET = {
|
|
21998
|
-
numeric:
|
|
21999
|
-
pin:
|
|
22000
|
-
alpha:
|
|
21982
|
+
numeric: "constraint.guard.number",
|
|
21983
|
+
pin: "constraint.guard.number",
|
|
21984
|
+
alpha: "constraint.guard.alpha",
|
|
22001
21985
|
alphanumeric: "constraint.guard.alphanumeric",
|
|
22002
|
-
uppercase:
|
|
22003
|
-
hex:
|
|
22004
|
-
slug:
|
|
21986
|
+
uppercase: "constraint.guard.uppercase",
|
|
21987
|
+
hex: "constraint.guard.hex",
|
|
21988
|
+
slug: "constraint.guard.slug",
|
|
22005
21989
|
// tel, card, postal, iban, custom → generic fallback
|
|
22006
21990
|
};
|
|
22007
21991
|
|
|
@@ -22014,13 +21998,6 @@ const resolveCharClass = (value) => {
|
|
|
22014
21998
|
return CHAR_CLASS_PRESETS[value] ?? value;
|
|
22015
21999
|
};
|
|
22016
22000
|
|
|
22017
|
-
/**
|
|
22018
|
-
* Returns the inputMode to auto-apply for the given preset, or null.
|
|
22019
|
-
*/
|
|
22020
|
-
const resolveInputModeFromAllowedChars = (value) => {
|
|
22021
|
-
return INPUT_MODE_FROM_PRESET[value] ?? null;
|
|
22022
|
-
};
|
|
22023
|
-
|
|
22024
22001
|
/**
|
|
22025
22002
|
* Returns the i18n key for the char guard rejection message.
|
|
22026
22003
|
* Falls back to the generic "constraint.guard.chars" for custom classes and
|
|
@@ -24588,11 +24565,11 @@ const useInteractiveProps = (props, {
|
|
|
24588
24565
|
const {
|
|
24589
24566
|
autoFocus,
|
|
24590
24567
|
autoFocusVisible,
|
|
24591
|
-
|
|
24568
|
+
autoFocusSelect
|
|
24592
24569
|
} = props;
|
|
24593
24570
|
const autoFocusProps = useAutoFocus(ref, autoFocus, {
|
|
24594
24571
|
focusVisible: autoFocusVisible,
|
|
24595
|
-
autoSelect
|
|
24572
|
+
autoSelect: autoFocusSelect
|
|
24596
24573
|
});
|
|
24597
24574
|
Object.assign(controlHostProps, autoFocusProps);
|
|
24598
24575
|
}
|
|
@@ -32213,20 +32190,99 @@ const resolveInputProps = (props) => {
|
|
|
32213
32190
|
if (currentTypeStepFormatter) {
|
|
32214
32191
|
props.step = currentTypeStepFormatter(props.step);
|
|
32215
32192
|
}
|
|
32193
|
+
|
|
32194
|
+
// For navi_number: choose inputMode based on whether step/min/max suggest decimals.
|
|
32195
|
+
// inputMode="numeric" (integer keyboard) vs "decimal" (keyboard with decimal separator).
|
|
32196
|
+
if (currentType === "navi_number") {
|
|
32197
|
+
if (props.inputMode === undefined) {
|
|
32198
|
+
props.inputMode =
|
|
32199
|
+
hasDecimalPlaces(props.step) ||
|
|
32200
|
+
hasDecimalPlaces(props.min) ||
|
|
32201
|
+
hasDecimalPlaces(props.max)
|
|
32202
|
+
? "decimal"
|
|
32203
|
+
: "numeric";
|
|
32204
|
+
}
|
|
32205
|
+
}
|
|
32206
|
+
|
|
32207
|
+
const { charGuard } = props;
|
|
32208
|
+
if (charGuard) {
|
|
32209
|
+
if (charGuard === true || charGuard === "auto") {
|
|
32210
|
+
// Auto-resolve charGuard from context.
|
|
32211
|
+
let charGuardResolved;
|
|
32212
|
+
const inputMode = props.inputMode;
|
|
32213
|
+
if (inputMode === "numeric") {
|
|
32214
|
+
charGuardResolved = "numeric";
|
|
32215
|
+
} else if (inputMode === "decimal") {
|
|
32216
|
+
charGuardResolved = "decimal";
|
|
32217
|
+
} else if (currentType === "tel") {
|
|
32218
|
+
charGuardResolved = "tel";
|
|
32219
|
+
} else if (currentType === "email") {
|
|
32220
|
+
charGuardResolved = "email";
|
|
32221
|
+
}
|
|
32222
|
+
if (charGuardResolved !== undefined) {
|
|
32223
|
+
props.charGuard = charGuardResolved;
|
|
32224
|
+
}
|
|
32225
|
+
}
|
|
32226
|
+
// charGuard is now resolved: derive inputMode from it if not already set.
|
|
32227
|
+
if (props.inputMode === undefined && props.charGuard) {
|
|
32228
|
+
const autoMode = INPUT_MODE_FROM_CHAR_GUARD[props.charGuard];
|
|
32229
|
+
if (autoMode) {
|
|
32230
|
+
props.inputMode = autoMode;
|
|
32231
|
+
}
|
|
32232
|
+
}
|
|
32233
|
+
// Build pattern from the resolved charGuard (preset name → class, or raw class passthrough).
|
|
32234
|
+
if (props.pattern === undefined && props.charGuard) {
|
|
32235
|
+
const charClass = CHAR_CLASS_PRESETS[props.charGuard] ?? props.charGuard;
|
|
32236
|
+
props.pattern = `${charClass}*`;
|
|
32237
|
+
}
|
|
32238
|
+
}
|
|
32239
|
+
|
|
32240
|
+
// Compute maxLength from max when inputMode is numeric/decimal.
|
|
32241
|
+
// Done here (after inputMode is set) so controller.props has the resolved value.
|
|
32242
|
+
if (props.maxLength === undefined) {
|
|
32243
|
+
if (props.inputMode === "numeric") {
|
|
32244
|
+
const { min, max } = props;
|
|
32245
|
+
if (max === undefined) ; else {
|
|
32246
|
+
const canBeNegative = min === undefined ? max < 0 : min < 0;
|
|
32247
|
+
const signCharCount = canBeNegative ? 1 : 0;
|
|
32248
|
+
const integerDigitCount = String(Math.floor(Math.abs(max))).length;
|
|
32249
|
+
props.maxLength = signCharCount + integerDigitCount;
|
|
32250
|
+
}
|
|
32251
|
+
} else if (props.inputMode === "decimal") {
|
|
32252
|
+
const { min, max, step } = props;
|
|
32253
|
+
if (max === undefined) ; else if (step === undefined) ; else {
|
|
32254
|
+
const canBeNegative = min === undefined ? max < 0 : min < 0;
|
|
32255
|
+
const signCharCount = canBeNegative ? 1 : 0;
|
|
32256
|
+
const integerDigitCount = String(Math.floor(Math.abs(max))).length;
|
|
32257
|
+
const stepStr = String(step);
|
|
32258
|
+
const dotIndex = stepStr.indexOf(".");
|
|
32259
|
+
// integer step + decimal inputMode is an unusual combo, but we stay consistent:
|
|
32260
|
+
// no decimal part in maxLength since valid values are whole numbers anyway
|
|
32261
|
+
const isIntegerStep = dotIndex === -1;
|
|
32262
|
+
const decimalSignCharCount = isIntegerStep ? 0 : 1;
|
|
32263
|
+
const decimalDigitCount = isIntegerStep
|
|
32264
|
+
? 0
|
|
32265
|
+
: stepStr.length - dotIndex - 1;
|
|
32266
|
+
props.maxLength =
|
|
32267
|
+
signCharCount +
|
|
32268
|
+
integerDigitCount +
|
|
32269
|
+
decimalSignCharCount +
|
|
32270
|
+
decimalDigitCount;
|
|
32271
|
+
}
|
|
32272
|
+
}
|
|
32273
|
+
}
|
|
32274
|
+
|
|
32275
|
+
// Resolve maxLengthGuard boolean/auto → the computed maxLength number.
|
|
32276
|
+
if (props.maxLengthGuard === true || props.maxLengthGuard === "auto") {
|
|
32277
|
+
props.maxLengthGuard =
|
|
32278
|
+
typeof props.maxLength === "number" ? props.maxLength : undefined;
|
|
32279
|
+
}
|
|
32280
|
+
|
|
32216
32281
|
const currentTypeDefaults = NAVI_TYPE_DEFAULTS[currentType];
|
|
32217
32282
|
if (!currentTypeDefaults) {
|
|
32218
32283
|
return;
|
|
32219
32284
|
}
|
|
32220
|
-
|
|
32221
|
-
// inputMode="numeric" (integer keyboard) vs "decimal" (keyboard with decimal separator).
|
|
32222
|
-
if (currentType === "navi_number" && props.inputMode === undefined) {
|
|
32223
|
-
props.inputMode =
|
|
32224
|
-
hasDecimalPlaces(props.step) ||
|
|
32225
|
-
hasDecimalPlaces(props.min) ||
|
|
32226
|
-
hasDecimalPlaces(props.max)
|
|
32227
|
-
? "decimal"
|
|
32228
|
-
: "numeric";
|
|
32229
|
-
}
|
|
32285
|
+
|
|
32230
32286
|
for (const key of Object.keys(currentTypeDefaults)) {
|
|
32231
32287
|
if (props[key] === undefined) {
|
|
32232
32288
|
props[key] = currentTypeDefaults[key];
|
|
@@ -32237,6 +32293,15 @@ const resolveInputProps = (props) => {
|
|
|
32237
32293
|
resolveInputProps(props);
|
|
32238
32294
|
};
|
|
32239
32295
|
|
|
32296
|
+
// Presets that imply a specific mobile keyboard inputMode.
|
|
32297
|
+
const INPUT_MODE_FROM_CHAR_GUARD = {
|
|
32298
|
+
numeric: "numeric",
|
|
32299
|
+
pin: "numeric",
|
|
32300
|
+
card: "numeric",
|
|
32301
|
+
tel: "tel",
|
|
32302
|
+
decimal: "decimal",
|
|
32303
|
+
};
|
|
32304
|
+
|
|
32240
32305
|
const normalizeToDate = (value) => {
|
|
32241
32306
|
if (value === undefined || value === null) {
|
|
32242
32307
|
return null;
|
|
@@ -32702,7 +32767,7 @@ const RangePseudoElements = ["::-navi-loader"];
|
|
|
32702
32767
|
const InputModeResolver = props => {
|
|
32703
32768
|
const Next = useNextResolver();
|
|
32704
32769
|
if (props.inputMode === "numeric" || props.inputMode === "decimal") {
|
|
32705
|
-
return jsx(
|
|
32770
|
+
return jsx(InputModeNumericOrDecimal, {
|
|
32706
32771
|
...props
|
|
32707
32772
|
});
|
|
32708
32773
|
}
|
|
@@ -32710,37 +32775,26 @@ const InputModeResolver = props => {
|
|
|
32710
32775
|
...props
|
|
32711
32776
|
});
|
|
32712
32777
|
};
|
|
32713
|
-
const
|
|
32778
|
+
const InputModeNumericOrDecimal = props => {
|
|
32714
32779
|
const Next = useNextResolver();
|
|
32715
|
-
const {
|
|
32716
|
-
min,
|
|
32717
|
-
max,
|
|
32718
|
-
step = 1
|
|
32719
|
-
} = props;
|
|
32720
|
-
let maxLength;
|
|
32721
|
-
if (max !== undefined) {
|
|
32722
|
-
const integerDigits = String(Math.floor(max)).length;
|
|
32723
|
-
// If step has decimal places, the value can contain a separator + those digits
|
|
32724
|
-
const stepStr = String(step);
|
|
32725
|
-
const dotIndex = stepStr.indexOf(".");
|
|
32726
|
-
const decimalDigits = dotIndex === -1 ? 0 : stepStr.length - dotIndex - 1;
|
|
32727
|
-
// If min is negative (or unknown and max itself is negative), a "-" sign can appear
|
|
32728
|
-
const canBeNegative = min !== undefined ? min < 0 : max < 0;
|
|
32729
|
-
const signChar = canBeNegative ? 1 : 0;
|
|
32730
|
-
maxLength = signChar + integerDigits + (decimalDigits > 0 ? 1 + decimalDigits : 0);
|
|
32731
|
-
}
|
|
32732
32780
|
return jsx(Next, {
|
|
32733
|
-
maxLength: maxLength,
|
|
32734
32781
|
...props,
|
|
32735
32782
|
onInput: e => {
|
|
32736
32783
|
props.onInput?.(e);
|
|
32737
32784
|
if (e.defaultPrevented) {
|
|
32738
32785
|
return;
|
|
32739
32786
|
}
|
|
32740
|
-
if (maxLength === undefined) {
|
|
32741
|
-
return;
|
|
32742
|
-
}
|
|
32743
32787
|
const input = e.currentTarget;
|
|
32788
|
+
let maxLength;
|
|
32789
|
+
const maxLengthProp = input.maxLength;
|
|
32790
|
+
if (maxLengthProp === -1) {
|
|
32791
|
+
const naviMaxLengthAttr = input.getAttribute("navi-max-length");
|
|
32792
|
+
if (naviMaxLengthAttr === null) {
|
|
32793
|
+
// no max length
|
|
32794
|
+
return;
|
|
32795
|
+
}
|
|
32796
|
+
maxLength = Number(naviMaxLengthAttr);
|
|
32797
|
+
}
|
|
32744
32798
|
if (input.value.length < maxLength) {
|
|
32745
32799
|
return;
|
|
32746
32800
|
}
|
|
@@ -33705,18 +33759,6 @@ const InputTextualFirstResolver = props => {
|
|
|
33705
33759
|
const defaultRef = useRef(null);
|
|
33706
33760
|
props.ref = props.ref || defaultRef;
|
|
33707
33761
|
resolveInputProps(props);
|
|
33708
|
-
|
|
33709
|
-
// charGuard → auto inputMode + auto pattern for mobile keyboard hints
|
|
33710
|
-
if (props.charGuard) {
|
|
33711
|
-
if (props.inputMode === undefined) {
|
|
33712
|
-
const autoMode = resolveInputModeFromAllowedChars(props.charGuard);
|
|
33713
|
-
if (autoMode) props.inputMode = autoMode;
|
|
33714
|
-
}
|
|
33715
|
-
if (props.pattern === undefined) {
|
|
33716
|
-
const charClass = resolveCharClass(props.charGuard);
|
|
33717
|
-
props.pattern = `${charClass}*`;
|
|
33718
|
-
}
|
|
33719
|
-
}
|
|
33720
33762
|
return jsx(Next, {
|
|
33721
33763
|
...props
|
|
33722
33764
|
});
|
|
@@ -33732,6 +33774,10 @@ const RealInput = props => {
|
|
|
33732
33774
|
// Never set native maxLength — our guard handles it. maxLength stays in
|
|
33733
33775
|
// inputControlHostProps so form validation constraints still read it.
|
|
33734
33776
|
maxLength: undefined
|
|
33777
|
+
// But do expose it (needed by navi_input_full event)
|
|
33778
|
+
,
|
|
33779
|
+
|
|
33780
|
+
"navi-max-length": props.maxLength
|
|
33735
33781
|
});
|
|
33736
33782
|
};
|
|
33737
33783
|
const InputStyleCSSVars = {
|
|
@@ -33885,7 +33931,7 @@ const Editable = props => {
|
|
|
33885
33931
|
maxLength,
|
|
33886
33932
|
pattern,
|
|
33887
33933
|
wrapperProps,
|
|
33888
|
-
|
|
33934
|
+
autoFocusSelect = true,
|
|
33889
33935
|
width,
|
|
33890
33936
|
height,
|
|
33891
33937
|
...rest
|
|
@@ -33930,7 +33976,7 @@ const Editable = props => {
|
|
|
33930
33976
|
valueSignal: valueSignal,
|
|
33931
33977
|
autoFocus: editing,
|
|
33932
33978
|
autoFocusVisible: true,
|
|
33933
|
-
|
|
33979
|
+
autoFocusSelect: autoFocusSelect,
|
|
33934
33980
|
cancelOnEscape: true,
|
|
33935
33981
|
cancelOnBlurInvalid: true,
|
|
33936
33982
|
constraints: constraints,
|
|
@@ -34671,7 +34717,9 @@ const InputDuration = props => {
|
|
|
34671
34717
|
uiAction,
|
|
34672
34718
|
action,
|
|
34673
34719
|
unitHour,
|
|
34674
|
-
textAlign = "auto"
|
|
34720
|
+
textAlign = "auto",
|
|
34721
|
+
maxLengthGuard,
|
|
34722
|
+
charGuard
|
|
34675
34723
|
} = props;
|
|
34676
34724
|
const minDuration = parseDuration(props.min);
|
|
34677
34725
|
const maxDuration = parseDuration(props.max);
|
|
@@ -34799,6 +34847,8 @@ const InputDuration = props => {
|
|
|
34799
34847
|
className: "navi_input_duration",
|
|
34800
34848
|
"data-callout-arrow-x": "center",
|
|
34801
34849
|
width: "fit-content",
|
|
34850
|
+
flex: true,
|
|
34851
|
+
spacing: "xxs",
|
|
34802
34852
|
...groupRootProps,
|
|
34803
34853
|
unit: undefined,
|
|
34804
34854
|
unitHour: undefined,
|
|
@@ -34818,37 +34868,34 @@ const InputDuration = props => {
|
|
|
34818
34868
|
} : {
|
|
34819
34869
|
defaultValue: initialIsoString
|
|
34820
34870
|
})
|
|
34821
|
-
}), jsx(
|
|
34822
|
-
|
|
34823
|
-
|
|
34824
|
-
|
|
34825
|
-
|
|
34826
|
-
|
|
34827
|
-
|
|
34828
|
-
|
|
34829
|
-
|
|
34830
|
-
|
|
34831
|
-
|
|
34832
|
-
|
|
34833
|
-
|
|
34834
|
-
|
|
34835
|
-
|
|
34836
|
-
|
|
34837
|
-
|
|
34838
|
-
|
|
34839
|
-
|
|
34840
|
-
|
|
34841
|
-
|
|
34842
|
-
|
|
34843
|
-
|
|
34844
|
-
|
|
34845
|
-
|
|
34846
|
-
|
|
34847
|
-
|
|
34848
|
-
|
|
34849
|
-
disabled: disabled,
|
|
34850
|
-
basePseudoState: basePseudoState
|
|
34851
|
-
})
|
|
34871
|
+
}), jsx(ControlgroupChildrenWrapper, {
|
|
34872
|
+
...childrenWrapperProps,
|
|
34873
|
+
name: undefined,
|
|
34874
|
+
children: jsx(InputDurationFields, {
|
|
34875
|
+
showHours: showHours,
|
|
34876
|
+
showMinutes: showMinutes,
|
|
34877
|
+
showSeconds: showSeconds,
|
|
34878
|
+
showMilliseconds: showMilliseconds,
|
|
34879
|
+
minutesReadOnly: minutesReadOnly,
|
|
34880
|
+
secondsReadOnly: secondsReadOnly,
|
|
34881
|
+
millisecondsReadOnly: millisecondsReadOnly,
|
|
34882
|
+
stepHasMilliseconds: stepHasMilliseconds,
|
|
34883
|
+
controlled: hasValue,
|
|
34884
|
+
hourValue: hourValue,
|
|
34885
|
+
minuteValue: minuteValue,
|
|
34886
|
+
secondValue: secondValue,
|
|
34887
|
+
millisecondValue: millisecondValue,
|
|
34888
|
+
minSeconds: minSeconds,
|
|
34889
|
+
maxSeconds: maxSeconds,
|
|
34890
|
+
stepSeconds: stepSeconds,
|
|
34891
|
+
unitHour: unitHour,
|
|
34892
|
+
textAlign: textAlign,
|
|
34893
|
+
maxLengthGuard: maxLengthGuard,
|
|
34894
|
+
charGuard: charGuard,
|
|
34895
|
+
required: required,
|
|
34896
|
+
readOnly: readOnly,
|
|
34897
|
+
disabled: disabled,
|
|
34898
|
+
basePseudoState: basePseudoState
|
|
34852
34899
|
})
|
|
34853
34900
|
})]
|
|
34854
34901
|
});
|
|
@@ -34908,7 +34955,20 @@ const useClipboardProps = groupRef => {
|
|
|
34908
34955
|
});
|
|
34909
34956
|
e.preventDefault();
|
|
34910
34957
|
};
|
|
34958
|
+
const isFromDurationField = e => {
|
|
34959
|
+
const target = e.target;
|
|
34960
|
+
if (!target.matches) {
|
|
34961
|
+
return false;
|
|
34962
|
+
}
|
|
34963
|
+
if (!target.matches(".navi_duration_part")) {
|
|
34964
|
+
return false;
|
|
34965
|
+
}
|
|
34966
|
+
return true;
|
|
34967
|
+
};
|
|
34911
34968
|
const onCopy = e => {
|
|
34969
|
+
if (!isFromDurationField(e)) {
|
|
34970
|
+
return;
|
|
34971
|
+
}
|
|
34912
34972
|
const payload = getClipboardPayload();
|
|
34913
34973
|
if (!payload) {
|
|
34914
34974
|
return;
|
|
@@ -34918,6 +34978,9 @@ const useClipboardProps = groupRef => {
|
|
|
34918
34978
|
e.preventDefault();
|
|
34919
34979
|
};
|
|
34920
34980
|
const onCut = e => {
|
|
34981
|
+
if (!isFromDurationField(e)) {
|
|
34982
|
+
return;
|
|
34983
|
+
}
|
|
34921
34984
|
const payload = getClipboardPayload();
|
|
34922
34985
|
if (!payload) {
|
|
34923
34986
|
return;
|
|
@@ -34927,6 +34990,9 @@ const useClipboardProps = groupRef => {
|
|
|
34927
34990
|
applyToGroup("", e);
|
|
34928
34991
|
};
|
|
34929
34992
|
const onPaste = e => {
|
|
34993
|
+
if (!isFromDurationField(e)) {
|
|
34994
|
+
return;
|
|
34995
|
+
}
|
|
34930
34996
|
const naviData = e.clipboardData.getData("application/x-navi");
|
|
34931
34997
|
const textData = e.clipboardData.getData("text/plain");
|
|
34932
34998
|
let isoValue = null;
|
|
@@ -35119,11 +35185,13 @@ const InputDurationPart = ({
|
|
|
35119
35185
|
return jsxs(Label, {
|
|
35120
35186
|
flex: "y",
|
|
35121
35187
|
"data-separator": separator || undefined,
|
|
35122
|
-
children: [jsx(Input
|
|
35123
|
-
|
|
35124
|
-
|
|
35125
|
-
|
|
35126
|
-
|
|
35188
|
+
children: [jsx(Input, {
|
|
35189
|
+
className: "navi_duration_part"
|
|
35190
|
+
// When autofocused this field should be selected
|
|
35191
|
+
// this help to modify the value on mobile
|
|
35192
|
+
,
|
|
35193
|
+
|
|
35194
|
+
autoFocusSelect: true,
|
|
35127
35195
|
type: "navi_number",
|
|
35128
35196
|
"navi-input-type": unit,
|
|
35129
35197
|
name: unit,
|
|
@@ -35396,6 +35464,7 @@ const Dialog = props => {
|
|
|
35396
35464
|
const topOffset = vv.offsetTop;
|
|
35397
35465
|
const marginTop = availableHeight > dialogHeight ? topOffset + (availableHeight - dialogHeight) / 2 : topOffset;
|
|
35398
35466
|
dialogEl.style.setProperty("--dialog-top-inset", `${snapToPixel(marginTop)}px`);
|
|
35467
|
+
dispatchCustomEvent(dialogEl, "navi_position_change");
|
|
35399
35468
|
};
|
|
35400
35469
|
const onScroll = () => {
|
|
35401
35470
|
updatePosition();
|
|
@@ -40454,6 +40523,7 @@ installImportMetaCssBuild(import.meta);const css$i = /* css */`
|
|
|
40454
40523
|
outline: none;
|
|
40455
40524
|
cursor: inherit;
|
|
40456
40525
|
pointer-events: auto;
|
|
40526
|
+
user-select: all;
|
|
40457
40527
|
|
|
40458
40528
|
&::-webkit-calendar-picker-indicator {
|
|
40459
40529
|
cursor: inherit;
|