@vuetify/nightly 3.8.9-dev.2025-06-11 → 3.8.9-dev.2025-06-13
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/CHANGELOG.md +12 -3
- package/dist/json/attributes.json +3441 -3169
- package/dist/json/importMap-labs.json +40 -36
- package/dist/json/importMap.json +166 -166
- package/dist/json/tags.json +74 -1
- package/dist/json/web-types.json +6884 -5821
- package/dist/vuetify-labs.cjs +357 -47
- package/dist/vuetify-labs.css +5881 -5870
- package/dist/vuetify-labs.d.ts +8448 -1672
- package/dist/vuetify-labs.esm.js +357 -47
- package/dist/vuetify-labs.esm.js.map +1 -1
- package/dist/vuetify-labs.js +357 -47
- package/dist/vuetify-labs.min.css +2 -2
- package/dist/vuetify.cjs +111 -47
- package/dist/vuetify.cjs.map +1 -1
- package/dist/vuetify.css +5075 -5064
- package/dist/vuetify.d.ts +1499 -1302
- package/dist/vuetify.esm.js +111 -47
- package/dist/vuetify.esm.js.map +1 -1
- package/dist/vuetify.js +111 -47
- package/dist/vuetify.js.map +1 -1
- package/dist/vuetify.min.css +2 -2
- package/dist/vuetify.min.js +1063 -1057
- package/dist/vuetify.min.js.map +1 -1
- package/lib/components/VAutocomplete/VAutocomplete.d.ts +21 -7
- package/lib/components/VCombobox/VCombobox.d.ts +21 -7
- package/lib/components/VDatePicker/VDatePicker.d.ts +70 -5
- package/lib/components/VDatePicker/VDatePicker.js +10 -4
- package/lib/components/VDatePicker/VDatePicker.js.map +1 -1
- package/lib/components/VKbd/VKbd.css +13 -2
- package/lib/components/VKbd/VKbd.d.ts +221 -0
- package/lib/components/VKbd/VKbd.js +55 -0
- package/lib/components/VKbd/VKbd.js.map +1 -0
- package/lib/components/VKbd/VKbd.sass +2 -1
- package/lib/components/VKbd/_variables.scss +12 -1
- package/lib/components/VKbd/index.d.ts +1 -95
- package/lib/components/VKbd/index.js +1 -4
- package/lib/components/VKbd/index.js.map +1 -1
- package/lib/components/VMenu/VMenu.d.ts +13 -0
- package/lib/components/VMenu/VMenu.js +2 -1
- package/lib/components/VMenu/VMenu.js.map +1 -1
- package/lib/components/VNumberInput/VNumberInput.d.ts +11 -0
- package/lib/components/VNumberInput/VNumberInput.js +37 -29
- package/lib/components/VNumberInput/VNumberInput.js.map +1 -1
- package/lib/components/VSelect/VSelect.d.ts +33 -11
- package/lib/components/VSpeedDial/VSpeedDial.d.ts +13 -0
- package/lib/composables/locale.d.ts +5 -1
- package/lib/composables/locale.js.map +1 -1
- package/lib/composables/mask.d.ts +38 -0
- package/lib/composables/mask.js +183 -0
- package/lib/composables/mask.js.map +1 -0
- package/lib/composables/theme.js +3 -3
- package/lib/composables/theme.js.map +1 -1
- package/lib/entry-bundler.d.ts +1 -0
- package/lib/entry-bundler.js +1 -1
- package/lib/framework.d.ts +67 -63
- package/lib/framework.js +1 -1
- package/lib/labs/VMaskInput/VMaskInput.d.ts +6993 -0
- package/lib/labs/VMaskInput/VMaskInput.js +67 -0
- package/lib/labs/VMaskInput/VMaskInput.js.map +1 -0
- package/lib/labs/VMaskInput/index.d.ts +1 -0
- package/lib/labs/VMaskInput/index.js +2 -0
- package/lib/labs/VMaskInput/index.js.map +1 -0
- package/lib/labs/components.d.ts +1 -0
- package/lib/labs/components.js +1 -0
- package/lib/labs/components.js.map +1 -1
- package/lib/labs/entry-bundler.d.ts +1 -0
- package/lib/locale/adapters/vue-i18n.js +6 -1
- package/lib/locale/adapters/vue-i18n.js.map +1 -1
- package/lib/locale/adapters/vuetify.js +7 -1
- package/lib/locale/adapters/vuetify.js.map +1 -1
- package/lib/util/helpers.d.ts +2 -1
- package/lib/util/helpers.js +12 -7
- package/lib/util/helpers.js.map +1 -1
- package/package.json +1 -1
package/dist/vuetify-labs.cjs
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/*!
|
2
|
-
* Vuetify v3.8.9-dev.2025-06-
|
2
|
+
* Vuetify v3.8.9-dev.2025-06-13
|
3
3
|
* Forged by John Leider
|
4
4
|
* Released under the MIT License.
|
5
5
|
*/
|
@@ -592,18 +592,23 @@
|
|
592
592
|
function isPrimitive(value) {
|
593
593
|
return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint';
|
594
594
|
}
|
595
|
-
function
|
596
|
-
|
595
|
+
function escapeForRegex(sign) {
|
596
|
+
return '\\^$*+?.()|{}[]'.includes(sign) ? `\\${sign}` : sign;
|
597
|
+
}
|
598
|
+
function extractNumber(text, decimalDigitsLimit, decimalSeparator) {
|
599
|
+
const onlyValidCharacters = new RegExp(`[\\d\\-${escapeForRegex(decimalSeparator)}]`);
|
600
|
+
const cleanText = text.split('').filter(x => onlyValidCharacters.test(x)).filter((x, i, all) => i === 0 && /[-]/.test(x) ||
|
597
601
|
// sign allowed at the start
|
598
|
-
x ===
|
602
|
+
x === decimalSeparator && i === all.indexOf(x) ||
|
599
603
|
// decimal separator allowed only once
|
600
604
|
/\d/.test(x)).join('');
|
601
605
|
if (decimalDigitsLimit === 0) {
|
602
|
-
return cleanText.split(
|
606
|
+
return cleanText.split(decimalSeparator)[0];
|
603
607
|
}
|
604
|
-
|
605
|
-
|
606
|
-
|
608
|
+
const decimalPart = new RegExp(`${escapeForRegex(decimalSeparator)}\\d`);
|
609
|
+
if (decimalDigitsLimit !== null && decimalPart.test(cleanText)) {
|
610
|
+
const parts = cleanText.split(decimalSeparator);
|
611
|
+
return [parts[0], parts[1].substring(0, decimalDigitsLimit)].join(decimalSeparator);
|
607
612
|
}
|
608
613
|
return cleanText;
|
609
614
|
}
|
@@ -2179,6 +2184,10 @@
|
|
2179
2184
|
return numberFormat.format(value);
|
2180
2185
|
};
|
2181
2186
|
}
|
2187
|
+
function inferDecimalSeparator(current, fallback) {
|
2188
|
+
const format = createNumberFunction(current, fallback);
|
2189
|
+
return format(0.1).includes(',') ? ',' : '.';
|
2190
|
+
}
|
2182
2191
|
function useProvided(props, prop, provided) {
|
2183
2192
|
const internal = useProxiedModel(props, prop, props[prop] ?? provided.value);
|
2184
2193
|
|
@@ -2201,6 +2210,7 @@
|
|
2201
2210
|
current,
|
2202
2211
|
fallback,
|
2203
2212
|
messages,
|
2213
|
+
decimalSeparator: vue.toRef(() => inferDecimalSeparator(current, fallback)),
|
2204
2214
|
t: createTranslateFunction(current, fallback, messages),
|
2205
2215
|
n: createNumberFunction(current, fallback),
|
2206
2216
|
provide: createProvideFunction({
|
@@ -2223,6 +2233,7 @@
|
|
2223
2233
|
current,
|
2224
2234
|
fallback,
|
2225
2235
|
messages,
|
2236
|
+
decimalSeparator: vue.toRef(() => options?.decimalSeparator ?? inferDecimalSeparator(current, fallback)),
|
2226
2237
|
t: createTranslateFunction(current, fallback, messages),
|
2227
2238
|
n: createNumberFunction(current, fallback),
|
2228
2239
|
provide: createProvideFunction({
|
@@ -2387,8 +2398,8 @@
|
|
2387
2398
|
'activated-opacity': 0.12,
|
2388
2399
|
'pressed-opacity': 0.12,
|
2389
2400
|
'dragged-opacity': 0.08,
|
2390
|
-
'theme-kbd': '#
|
2391
|
-
'theme-on-kbd': '#
|
2401
|
+
'theme-kbd': '#EEEEEE',
|
2402
|
+
'theme-on-kbd': '#000000',
|
2392
2403
|
'theme-code': '#F5F5F5',
|
2393
2404
|
'theme-on-code': '#000000'
|
2394
2405
|
}
|
@@ -2424,7 +2435,7 @@
|
|
2424
2435
|
'activated-opacity': 0.12,
|
2425
2436
|
'pressed-opacity': 0.16,
|
2426
2437
|
'dragged-opacity': 0.08,
|
2427
|
-
'theme-kbd': '#
|
2438
|
+
'theme-kbd': '#424242',
|
2428
2439
|
'theme-on-kbd': '#FFFFFF',
|
2429
2440
|
'theme-code': '#343434',
|
2430
2441
|
'theme-on-code': '#CCCCCC'
|
@@ -11634,6 +11645,7 @@
|
|
11634
11645
|
// disableKeys: Boolean,
|
11635
11646
|
id: String,
|
11636
11647
|
submenu: Boolean,
|
11648
|
+
disableInitialFocus: Boolean,
|
11637
11649
|
...omit(makeVOverlayProps({
|
11638
11650
|
closeDelay: 250,
|
11639
11651
|
closeOnContentClick: true,
|
@@ -11708,7 +11720,7 @@
|
|
11708
11720
|
vue.watch(isActive, val => {
|
11709
11721
|
if (val) {
|
11710
11722
|
parent?.register();
|
11711
|
-
if (IN_BROWSER) {
|
11723
|
+
if (IN_BROWSER && !props.disableInitialFocus) {
|
11712
11724
|
document.addEventListener('focusin', onFocusIn, {
|
11713
11725
|
once: true
|
11714
11726
|
});
|
@@ -23009,7 +23021,9 @@
|
|
23009
23021
|
"max": maxDate.value,
|
23010
23022
|
"year": year.value,
|
23011
23023
|
"allowedMonths": allowedMonths
|
23012
|
-
}),
|
23024
|
+
}), {
|
23025
|
+
...pick(slots, ['month'])
|
23026
|
+
}) : viewMode.value === 'year' ? vue.createVNode(VDatePickerYears, vue.mergeProps({
|
23013
23027
|
"key": "date-picker-years"
|
23014
23028
|
}, datePickerYearsProps, {
|
23015
23029
|
"modelValue": year.value,
|
@@ -23017,7 +23031,9 @@
|
|
23017
23031
|
"min": minDate.value,
|
23018
23032
|
"max": maxDate.value,
|
23019
23033
|
"allowedYears": allowedYears
|
23020
|
-
}),
|
23034
|
+
}), {
|
23035
|
+
...pick(slots, ['year'])
|
23036
|
+
}) : vue.createVNode(VDatePickerMonth, vue.mergeProps({
|
23021
23037
|
"key": "date-picker-month"
|
23022
23038
|
}, datePickerMonthProps, {
|
23023
23039
|
"modelValue": model.value,
|
@@ -23028,7 +23044,9 @@
|
|
23028
23044
|
"onUpdate:year": [$event => year.value = $event, onUpdateYear],
|
23029
23045
|
"min": minDate.value,
|
23030
23046
|
"max": maxDate.value
|
23031
|
-
}),
|
23047
|
+
}), {
|
23048
|
+
...pick(slots, ['day'])
|
23049
|
+
})]
|
23032
23050
|
})]),
|
23033
23051
|
actions: slots.actions
|
23034
23052
|
});
|
@@ -24338,8 +24356,47 @@
|
|
24338
24356
|
}
|
24339
24357
|
});
|
24340
24358
|
|
24341
|
-
|
24342
|
-
|
24359
|
+
const makeVKbdProps = propsFactory({
|
24360
|
+
...makeBorderProps(),
|
24361
|
+
...makeComponentProps(),
|
24362
|
+
...makeRoundedProps(),
|
24363
|
+
...makeTagProps({
|
24364
|
+
tag: 'kbd'
|
24365
|
+
}),
|
24366
|
+
...makeThemeProps(),
|
24367
|
+
...makeElevationProps(),
|
24368
|
+
color: String
|
24369
|
+
}, 'VKbd');
|
24370
|
+
const VKbd = genericComponent()({
|
24371
|
+
name: 'VKbd',
|
24372
|
+
props: makeVKbdProps(),
|
24373
|
+
setup(props, _ref) {
|
24374
|
+
let {
|
24375
|
+
slots
|
24376
|
+
} = _ref;
|
24377
|
+
const {
|
24378
|
+
themeClasses
|
24379
|
+
} = provideTheme(props);
|
24380
|
+
const {
|
24381
|
+
borderClasses
|
24382
|
+
} = useBorder(props);
|
24383
|
+
const {
|
24384
|
+
roundedClasses
|
24385
|
+
} = useRounded(props);
|
24386
|
+
const {
|
24387
|
+
backgroundColorClasses,
|
24388
|
+
backgroundColorStyles
|
24389
|
+
} = useBackgroundColor(() => props.color);
|
24390
|
+
const {
|
24391
|
+
elevationClasses
|
24392
|
+
} = useElevation(props);
|
24393
|
+
useRender(() => vue.createVNode(props.tag, {
|
24394
|
+
"class": vue.normalizeClass(['v-kbd', themeClasses.value, backgroundColorClasses.value, borderClasses.value, elevationClasses.value, roundedClasses.value, props.class]),
|
24395
|
+
"style": vue.normalizeStyle([backgroundColorStyles.value, props.style])
|
24396
|
+
}, slots));
|
24397
|
+
return {};
|
24398
|
+
}
|
24399
|
+
});
|
24343
24400
|
|
24344
24401
|
const makeVLayoutProps = propsFactory({
|
24345
24402
|
...makeComponentProps(),
|
@@ -25181,6 +25238,10 @@
|
|
25181
25238
|
type: Number,
|
25182
25239
|
default: null
|
25183
25240
|
},
|
25241
|
+
decimalSeparator: {
|
25242
|
+
type: String,
|
25243
|
+
validator: v => !v || v.length === 1
|
25244
|
+
},
|
25184
25245
|
...omit(makeVTextFieldProps(), ['modelValue', 'validationValue'])
|
25185
25246
|
}, 'VNumberInput');
|
25186
25247
|
const VNumberInput = genericComponent()({
|
@@ -25206,21 +25267,24 @@
|
|
25206
25267
|
const form = useForm(props);
|
25207
25268
|
const controlsDisabled = vue.computed(() => form.isDisabled.value || form.isReadonly.value);
|
25208
25269
|
const isFocused = vue.shallowRef(props.focused);
|
25270
|
+
const {
|
25271
|
+
decimalSeparator: decimalSeparatorFromLocale
|
25272
|
+
} = useLocale();
|
25273
|
+
const decimalSeparator = vue.computed(() => props.decimalSeparator?.[0] || decimalSeparatorFromLocale.value);
|
25209
25274
|
function correctPrecision(val) {
|
25210
25275
|
let precision = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : props.precision;
|
25211
|
-
|
25212
|
-
|
25213
|
-
|
25214
|
-
|
25215
|
-
|
25216
|
-
return Number(fixed).toString(); // trim zeros
|
25276
|
+
let trim = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
25277
|
+
const fixed = precision == null ? String(val) : val.toFixed(precision);
|
25278
|
+
if (isFocused.value && trim) {
|
25279
|
+
return Number(fixed).toString() // trim zeros
|
25280
|
+
.replace('.', decimalSeparator.value);
|
25217
25281
|
}
|
25218
|
-
if (
|
25219
|
-
|
25220
|
-
const [baseDigits, fractionDigits] = fixed.split('.');
|
25221
|
-
fixed = [baseDigits, fractionDigits.replace(new RegExp(`0{1,${trimLimit}}$`), '')].filter(Boolean).join('.');
|
25282
|
+
if (props.minFractionDigits === null || precision !== null && precision < props.minFractionDigits) {
|
25283
|
+
return fixed.replace('.', decimalSeparator.value);
|
25222
25284
|
}
|
25223
|
-
|
25285
|
+
let [baseDigits, fractionDigits] = fixed.split('.');
|
25286
|
+
fractionDigits = (fractionDigits ?? '').padEnd(props.minFractionDigits, '0').replace(new RegExp(`(?<=\\d{${props.minFractionDigits}})0`, 'g'), '');
|
25287
|
+
return [baseDigits, fractionDigits].filter(Boolean).join(decimalSeparator.value);
|
25224
25288
|
}
|
25225
25289
|
const model = useProxiedModel(props, 'modelValue', null, val => val ?? null, val => val == null ? val ?? null : clamp(Number(val), props.min, props.max));
|
25226
25290
|
const _inputText = vue.shallowRef(null);
|
@@ -25237,8 +25301,11 @@
|
|
25237
25301
|
if (val === null || val === '') {
|
25238
25302
|
model.value = null;
|
25239
25303
|
_inputText.value = null;
|
25240
|
-
|
25241
|
-
|
25304
|
+
return;
|
25305
|
+
}
|
25306
|
+
const parsedValue = Number(val.replace(decimalSeparator.value, '.'));
|
25307
|
+
if (!isNaN(parsedValue) && parsedValue <= props.max && parsedValue >= props.min) {
|
25308
|
+
model.value = parsedValue;
|
25242
25309
|
_inputText.value = val;
|
25243
25310
|
}
|
25244
25311
|
}
|
@@ -25309,24 +25376,24 @@
|
|
25309
25376
|
selectionEnd
|
25310
25377
|
} = inputElement ?? {};
|
25311
25378
|
const potentialNewInputVal = existingTxt ? existingTxt.slice(0, selectionStart) + e.data + existingTxt.slice(selectionEnd) : e.data;
|
25312
|
-
const potentialNewNumber = extractNumber(potentialNewInputVal, props.precision);
|
25379
|
+
const potentialNewNumber = extractNumber(potentialNewInputVal, props.precision, decimalSeparator.value);
|
25313
25380
|
|
25314
|
-
//
|
25315
|
-
//
|
25316
|
-
//
|
25317
|
-
if (
|
25381
|
+
// Allow only numbers, "-" and {decimal separator}
|
25382
|
+
// Allow "-" and {decimal separator} only once
|
25383
|
+
// Allow "-" only at the start
|
25384
|
+
if (!new RegExp(`^-?\\d*${escapeForRegex(decimalSeparator.value)}?\\d*$`).test(potentialNewInputVal)) {
|
25318
25385
|
e.preventDefault();
|
25319
25386
|
inputElement.value = potentialNewNumber;
|
25320
25387
|
}
|
25321
25388
|
if (props.precision == null) return;
|
25322
25389
|
|
25323
25390
|
// Ignore decimal digits above precision limit
|
25324
|
-
if (potentialNewInputVal.split(
|
25391
|
+
if (potentialNewInputVal.split(decimalSeparator.value)[1]?.length > props.precision) {
|
25325
25392
|
e.preventDefault();
|
25326
25393
|
inputElement.value = potentialNewNumber;
|
25327
25394
|
}
|
25328
25395
|
// Ignore decimal separator when precision = 0
|
25329
|
-
if (props.precision === 0 && potentialNewInputVal.includes(
|
25396
|
+
if (props.precision === 0 && potentialNewInputVal.includes(decimalSeparator.value)) {
|
25330
25397
|
e.preventDefault();
|
25331
25398
|
inputElement.value = potentialNewNumber;
|
25332
25399
|
}
|
@@ -25378,19 +25445,16 @@
|
|
25378
25445
|
if (controlsDisabled.value) return;
|
25379
25446
|
if (!vTextFieldRef.value) return;
|
25380
25447
|
const actualText = vTextFieldRef.value.value;
|
25381
|
-
|
25382
|
-
|
25448
|
+
const parsedValue = Number(actualText.replace(decimalSeparator.value, '.'));
|
25449
|
+
if (actualText && !isNaN(parsedValue)) {
|
25450
|
+
inputText.value = correctPrecision(clamp(parsedValue, props.min, props.max));
|
25383
25451
|
} else {
|
25384
25452
|
inputText.value = null;
|
25385
25453
|
}
|
25386
25454
|
}
|
25387
25455
|
function formatInputValue() {
|
25388
25456
|
if (controlsDisabled.value) return;
|
25389
|
-
|
25390
|
-
inputText.value = null;
|
25391
|
-
return;
|
25392
|
-
}
|
25393
|
-
inputText.value = correctPrecision(model.value);
|
25457
|
+
inputText.value = model.value !== null && !isNaN(model.value) ? correctPrecision(model.value, props.precision, false) : null;
|
25394
25458
|
}
|
25395
25459
|
function trimDecimalZeros() {
|
25396
25460
|
if (controlsDisabled.value) return;
|
@@ -25398,7 +25462,7 @@
|
|
25398
25462
|
inputText.value = null;
|
25399
25463
|
return;
|
25400
25464
|
}
|
25401
|
-
inputText.value = model.value.toString();
|
25465
|
+
inputText.value = model.value.toString().replace('.', decimalSeparator.value);
|
25402
25466
|
}
|
25403
25467
|
function onFocus() {
|
25404
25468
|
trimDecimalZeros();
|
@@ -30494,6 +30558,251 @@
|
|
30494
30558
|
}
|
30495
30559
|
});
|
30496
30560
|
|
30561
|
+
// Utilities
|
30562
|
+
|
30563
|
+
// Types
|
30564
|
+
|
30565
|
+
const makeMaskProps = propsFactory({
|
30566
|
+
mask: [String, Object],
|
30567
|
+
returnMaskedValue: Boolean
|
30568
|
+
}, 'mask');
|
30569
|
+
const defaultDelimiters = /[-!$%^&*()_+|~=`{}[\]:";'<>?,./\\ ]/;
|
30570
|
+
const presets = {
|
30571
|
+
'credit-card': '#### - #### - #### - ####',
|
30572
|
+
date: '##/##/####',
|
30573
|
+
'date-time': '##/##/#### ##:##',
|
30574
|
+
'iso-date': '####-##-##',
|
30575
|
+
'iso-date-time': '####-##-## ##:##',
|
30576
|
+
phone: '(###) ### - ####',
|
30577
|
+
social: '###-##-####',
|
30578
|
+
time: '##:##',
|
30579
|
+
'time-with-seconds': '##:##:##'
|
30580
|
+
};
|
30581
|
+
function isMaskDelimiter(char) {
|
30582
|
+
return char ? defaultDelimiters.test(char) : false;
|
30583
|
+
}
|
30584
|
+
const defaultTokens = {
|
30585
|
+
'#': {
|
30586
|
+
pattern: /[0-9]/
|
30587
|
+
},
|
30588
|
+
A: {
|
30589
|
+
pattern: /[A-Z]/i,
|
30590
|
+
convert: v => v.toUpperCase()
|
30591
|
+
},
|
30592
|
+
a: {
|
30593
|
+
pattern: /[a-z]/i,
|
30594
|
+
convert: v => v.toLowerCase()
|
30595
|
+
},
|
30596
|
+
N: {
|
30597
|
+
pattern: /[0-9A-Z]/i,
|
30598
|
+
convert: v => v.toUpperCase()
|
30599
|
+
},
|
30600
|
+
n: {
|
30601
|
+
pattern: /[0-9a-z]/i,
|
30602
|
+
convert: v => v.toLowerCase()
|
30603
|
+
},
|
30604
|
+
X: {
|
30605
|
+
pattern: defaultDelimiters
|
30606
|
+
}
|
30607
|
+
};
|
30608
|
+
function useMask(props, inputRef) {
|
30609
|
+
const mask = vue.computed(() => {
|
30610
|
+
if (typeof props.mask === 'string') {
|
30611
|
+
if (props.mask in presets) return presets[props.mask];
|
30612
|
+
return props.mask;
|
30613
|
+
}
|
30614
|
+
return props.mask?.mask ?? '';
|
30615
|
+
});
|
30616
|
+
const tokens = vue.computed(() => {
|
30617
|
+
return {
|
30618
|
+
...defaultTokens,
|
30619
|
+
...(isObject(props.mask) ? props.mask.tokens : null)
|
30620
|
+
};
|
30621
|
+
});
|
30622
|
+
const selection = vue.shallowRef(0);
|
30623
|
+
const lazySelection = vue.shallowRef(0);
|
30624
|
+
function isMask(char) {
|
30625
|
+
return char in tokens.value;
|
30626
|
+
}
|
30627
|
+
function maskValidates(mask, char) {
|
30628
|
+
if (char == null || !isMask(mask)) return false;
|
30629
|
+
const item = tokens.value[mask];
|
30630
|
+
if (item.pattern) return item.pattern.test(char);
|
30631
|
+
return item.test(char);
|
30632
|
+
}
|
30633
|
+
function convert(mask, char) {
|
30634
|
+
const item = tokens.value[mask];
|
30635
|
+
return item.convert ? item.convert(char) : char;
|
30636
|
+
}
|
30637
|
+
function maskText(text) {
|
30638
|
+
const trimmedText = text?.trim().replace(/\s+/g, ' ');
|
30639
|
+
if (trimmedText == null) return '';
|
30640
|
+
if (!mask.value.length || !trimmedText.length) return trimmedText;
|
30641
|
+
let textIndex = 0;
|
30642
|
+
let maskIndex = 0;
|
30643
|
+
let newText = '';
|
30644
|
+
while (maskIndex < mask.value.length) {
|
30645
|
+
const mchar = mask.value[maskIndex];
|
30646
|
+
const tchar = trimmedText[textIndex];
|
30647
|
+
|
30648
|
+
// Escaped character in mask, the next mask character is inserted
|
30649
|
+
if (mchar === '\\') {
|
30650
|
+
newText += mask.value[maskIndex + 1];
|
30651
|
+
maskIndex += 2;
|
30652
|
+
continue;
|
30653
|
+
}
|
30654
|
+
if (!isMask(mchar)) {
|
30655
|
+
newText += mchar;
|
30656
|
+
if (tchar === mchar) {
|
30657
|
+
textIndex++;
|
30658
|
+
}
|
30659
|
+
} else if (maskValidates(mchar, tchar)) {
|
30660
|
+
newText += convert(mchar, tchar);
|
30661
|
+
textIndex++;
|
30662
|
+
} else {
|
30663
|
+
break;
|
30664
|
+
}
|
30665
|
+
maskIndex++;
|
30666
|
+
}
|
30667
|
+
return newText;
|
30668
|
+
}
|
30669
|
+
function unmaskText(text) {
|
30670
|
+
if (text == null) return null;
|
30671
|
+
if (!mask.value.length || !text.length) return text;
|
30672
|
+
let textIndex = 0;
|
30673
|
+
let maskIndex = 0;
|
30674
|
+
let newText = '';
|
30675
|
+
while (true) {
|
30676
|
+
const mchar = mask.value[maskIndex];
|
30677
|
+
const tchar = text[textIndex];
|
30678
|
+
if (tchar == null) break;
|
30679
|
+
if (mchar == null) {
|
30680
|
+
newText += tchar;
|
30681
|
+
textIndex++;
|
30682
|
+
continue;
|
30683
|
+
}
|
30684
|
+
|
30685
|
+
// Escaped character in mask, skip the next input character
|
30686
|
+
if (mchar === '\\') {
|
30687
|
+
if (tchar === mask.value[maskIndex + 1]) {
|
30688
|
+
textIndex++;
|
30689
|
+
}
|
30690
|
+
maskIndex += 2;
|
30691
|
+
continue;
|
30692
|
+
}
|
30693
|
+
if (maskValidates(mchar, tchar)) {
|
30694
|
+
// masked char
|
30695
|
+
newText += tchar;
|
30696
|
+
textIndex++;
|
30697
|
+
maskIndex++;
|
30698
|
+
continue;
|
30699
|
+
} else if (mchar !== tchar) {
|
30700
|
+
// input doesn't match mask, skip forward until it does
|
30701
|
+
while (true) {
|
30702
|
+
const mchar = mask.value[maskIndex++];
|
30703
|
+
if (mchar == null || maskValidates(mchar, tchar)) break;
|
30704
|
+
}
|
30705
|
+
continue;
|
30706
|
+
}
|
30707
|
+
textIndex++;
|
30708
|
+
maskIndex++;
|
30709
|
+
}
|
30710
|
+
return newText;
|
30711
|
+
}
|
30712
|
+
function setCaretPosition(newSelection) {
|
30713
|
+
selection.value = newSelection;
|
30714
|
+
inputRef.value && inputRef.value.setSelectionRange(selection.value, selection.value);
|
30715
|
+
}
|
30716
|
+
function resetSelections() {
|
30717
|
+
if (!inputRef.value?.selectionEnd) return;
|
30718
|
+
selection.value = inputRef.value.selectionEnd;
|
30719
|
+
lazySelection.value = 0;
|
30720
|
+
for (let index = 0; index < selection.value; index++) {
|
30721
|
+
isMaskDelimiter(inputRef.value.value[index]) || lazySelection.value++;
|
30722
|
+
}
|
30723
|
+
}
|
30724
|
+
function updateRange() {
|
30725
|
+
if (!inputRef.value) return;
|
30726
|
+
resetSelections();
|
30727
|
+
let selection = 0;
|
30728
|
+
const newValue = inputRef.value.value;
|
30729
|
+
if (newValue) {
|
30730
|
+
for (let index = 0; index < newValue.length; index++) {
|
30731
|
+
if (lazySelection.value <= 0) break;
|
30732
|
+
isMaskDelimiter(newValue[index]) || lazySelection.value--;
|
30733
|
+
selection++;
|
30734
|
+
}
|
30735
|
+
}
|
30736
|
+
setCaretPosition(selection);
|
30737
|
+
}
|
30738
|
+
return {
|
30739
|
+
updateRange,
|
30740
|
+
maskText,
|
30741
|
+
unmaskText
|
30742
|
+
};
|
30743
|
+
}
|
30744
|
+
|
30745
|
+
// Types
|
30746
|
+
|
30747
|
+
const makeVMaskInputProps = propsFactory({
|
30748
|
+
...makeVTextFieldProps(),
|
30749
|
+
...makeMaskProps()
|
30750
|
+
}, 'VMaskInput');
|
30751
|
+
const VMaskInput = genericComponent()({
|
30752
|
+
name: 'VMaskInput',
|
30753
|
+
props: makeVMaskInputProps(),
|
30754
|
+
emits: {
|
30755
|
+
'update:modelValue': val => true
|
30756
|
+
},
|
30757
|
+
setup(props, _ref) {
|
30758
|
+
let {
|
30759
|
+
slots,
|
30760
|
+
emit
|
30761
|
+
} = _ref;
|
30762
|
+
const vTextFieldRef = vue.ref();
|
30763
|
+
const {
|
30764
|
+
maskText,
|
30765
|
+
updateRange,
|
30766
|
+
unmaskText
|
30767
|
+
} = useMask(props, vTextFieldRef);
|
30768
|
+
const returnMaskedValue = vue.computed(() => props.mask && props.returnMaskedValue);
|
30769
|
+
const model = useProxiedModel(props, 'modelValue', undefined,
|
30770
|
+
// Always display masked value in input when mask is applied
|
30771
|
+
val => props.mask ? maskText(unmaskText(val)) : val, val => {
|
30772
|
+
if (props.mask) {
|
30773
|
+
const valueBeforeChange = unmaskText(model.value);
|
30774
|
+
// E.g. mask is #-# and the input value is '2-23'
|
30775
|
+
// model-value should be enforced to '2-2'
|
30776
|
+
const enforcedMaskedValue = maskText(unmaskText(val));
|
30777
|
+
const newUnmaskedValue = unmaskText(enforcedMaskedValue);
|
30778
|
+
if (newUnmaskedValue === valueBeforeChange) {
|
30779
|
+
vTextFieldRef.value.value = enforcedMaskedValue;
|
30780
|
+
}
|
30781
|
+
val = newUnmaskedValue;
|
30782
|
+
updateRange();
|
30783
|
+
return returnMaskedValue.value ? maskText(val) : val;
|
30784
|
+
}
|
30785
|
+
return val;
|
30786
|
+
});
|
30787
|
+
vue.onBeforeMount(() => {
|
30788
|
+
if (props.returnMaskedValue) {
|
30789
|
+
emit('update:modelValue', model.value);
|
30790
|
+
}
|
30791
|
+
});
|
30792
|
+
useRender(() => {
|
30793
|
+
const textFieldProps = VTextField.filterProps(props);
|
30794
|
+
return vue.createVNode(VTextField, vue.mergeProps(textFieldProps, {
|
30795
|
+
"modelValue": model.value,
|
30796
|
+
"onUpdate:modelValue": $event => model.value = $event,
|
30797
|
+
"ref": vTextFieldRef
|
30798
|
+
}), {
|
30799
|
+
...slots
|
30800
|
+
});
|
30801
|
+
});
|
30802
|
+
return forwardRefs({}, vTextFieldRef);
|
30803
|
+
}
|
30804
|
+
});
|
30805
|
+
|
30497
30806
|
// Types
|
30498
30807
|
|
30499
30808
|
const makeVStepperVerticalActionsProps = propsFactory({
|
@@ -31999,6 +32308,7 @@
|
|
31999
32308
|
VListSubheader: VListSubheader,
|
32000
32309
|
VLocaleProvider: VLocaleProvider,
|
32001
32310
|
VMain: VMain,
|
32311
|
+
VMaskInput: VMaskInput,
|
32002
32312
|
VMenu: VMenu,
|
32003
32313
|
VMessages: VMessages,
|
32004
32314
|
VNavigationDrawer: VNavigationDrawer,
|
@@ -32396,7 +32706,7 @@
|
|
32396
32706
|
};
|
32397
32707
|
});
|
32398
32708
|
}
|
32399
|
-
const version$1 = "3.8.9-dev.2025-06-
|
32709
|
+
const version$1 = "3.8.9-dev.2025-06-13";
|
32400
32710
|
createVuetify$1.version = version$1;
|
32401
32711
|
|
32402
32712
|
// Vue's inject() can only be used in setup
|
@@ -32694,7 +33004,7 @@
|
|
32694
33004
|
|
32695
33005
|
/* eslint-disable local-rules/sort-imports */
|
32696
33006
|
|
32697
|
-
const version = "3.8.9-dev.2025-06-
|
33007
|
+
const version = "3.8.9-dev.2025-06-13";
|
32698
33008
|
|
32699
33009
|
/* eslint-disable local-rules/sort-imports */
|
32700
33010
|
|