@vuetify/nightly 3.8.4-master.2025-05-13 → 3.8.5-master.2025-05-14

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.
Files changed (56) hide show
  1. package/CHANGELOG.md +3 -27
  2. package/dist/_component-variables-labs.sass +1 -0
  3. package/dist/json/attributes.json +3177 -2841
  4. package/dist/json/importMap-labs.json +36 -32
  5. package/dist/json/importMap.json +180 -180
  6. package/dist/json/tags.json +89 -0
  7. package/dist/json/web-types.json +6734 -5547
  8. package/dist/vuetify-labs.cjs +272 -82
  9. package/dist/vuetify-labs.css +5164 -5136
  10. package/dist/vuetify-labs.d.ts +1371 -309
  11. package/dist/vuetify-labs.esm.js +272 -82
  12. package/dist/vuetify-labs.esm.js.map +1 -1
  13. package/dist/vuetify-labs.js +272 -82
  14. package/dist/vuetify-labs.min.css +2 -2
  15. package/dist/vuetify.cjs +5 -4
  16. package/dist/vuetify.cjs.map +1 -1
  17. package/dist/vuetify.css +3047 -3022
  18. package/dist/vuetify.d.ts +70 -67
  19. package/dist/vuetify.esm.js +5 -4
  20. package/dist/vuetify.esm.js.map +1 -1
  21. package/dist/vuetify.js +5 -4
  22. package/dist/vuetify.js.map +1 -1
  23. package/dist/vuetify.min.css +2 -2
  24. package/dist/vuetify.min.js +4 -4
  25. package/dist/vuetify.min.js.map +1 -1
  26. package/lib/components/VBottomSheet/VBottomSheet.css +1 -1
  27. package/lib/components/VBottomSheet/VBottomSheet.sass +1 -1
  28. package/lib/components/VBtn/VBtn.css +25 -0
  29. package/lib/components/VBtn/VBtn.sass +9 -0
  30. package/lib/components/VBtn/_variables.scss +1 -0
  31. package/lib/components/VSnackbarQueue/VSnackbarQueue.d.ts +3 -1
  32. package/lib/components/VSnackbarQueue/VSnackbarQueue.js.map +1 -1
  33. package/lib/composables/dateFormat.d.ts +24 -0
  34. package/lib/composables/dateFormat.js +112 -0
  35. package/lib/composables/dateFormat.js.map +1 -0
  36. package/lib/entry-bundler.js +1 -1
  37. package/lib/framework.d.ts +70 -67
  38. package/lib/framework.js +1 -1
  39. package/lib/iconsets/mdi.js +2 -1
  40. package/lib/iconsets/mdi.js.map +1 -1
  41. package/lib/labs/VColorInput/VColorInput.css +4 -0
  42. package/lib/labs/VColorInput/VColorInput.d.ts +1767 -0
  43. package/lib/labs/VColorInput/VColorInput.js +129 -0
  44. package/lib/labs/VColorInput/VColorInput.js.map +1 -0
  45. package/lib/labs/VColorInput/VColorInput.sass +7 -0
  46. package/lib/labs/VColorInput/_variables.scss +2 -0
  47. package/lib/labs/VColorInput/index.d.ts +1 -0
  48. package/lib/labs/VColorInput/index.js +2 -0
  49. package/lib/labs/VColorInput/index.js.map +1 -0
  50. package/lib/labs/VDateInput/VDateInput.d.ts +28 -31
  51. package/lib/labs/VDateInput/VDateInput.js +38 -79
  52. package/lib/labs/VDateInput/VDateInput.js.map +1 -1
  53. package/lib/labs/components.d.ts +1 -0
  54. package/lib/labs/components.js +1 -0
  55. package/lib/labs/components.js.map +1 -1
  56. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.8.4-master.2025-05-13
2
+ * Vuetify v3.8.5-master.2025-05-14
3
3
  * Forged by John Leider
4
4
  * Released under the MIT License.
5
5
  */
@@ -4510,7 +4510,8 @@
4510
4510
  treeviewCollapse: 'mdi-menu-down',
4511
4511
  treeviewExpand: 'mdi-menu-right',
4512
4512
  eyeDropper: 'mdi-eyedropper',
4513
- upload: 'mdi-cloud-upload'
4513
+ upload: 'mdi-cloud-upload',
4514
+ color: 'mdi-palette'
4514
4515
  };
4515
4516
  const mdi = {
4516
4517
  // Not using mergeProps here, functional components merge props by default (?)
@@ -29076,11 +29077,240 @@
29076
29077
 
29077
29078
  // Types
29078
29079
 
29080
+ const makeVColorInputProps = propsFactory({
29081
+ pip: Boolean,
29082
+ pipIcon: {
29083
+ type: String,
29084
+ default: '$color'
29085
+ },
29086
+ ...makeFocusProps(),
29087
+ ...makeVConfirmEditProps(),
29088
+ ...makeVTextFieldProps(),
29089
+ ...omit(makeVColorPickerProps(), ['width'])
29090
+ }, 'VColorInput');
29091
+ const VColorInput = genericComponent()({
29092
+ name: 'VColorInput',
29093
+ props: makeVColorInputProps(),
29094
+ emits: {
29095
+ 'update:modelValue': val => true
29096
+ },
29097
+ setup(props, _ref) {
29098
+ let {
29099
+ slots
29100
+ } = _ref;
29101
+ const {
29102
+ isFocused,
29103
+ focus,
29104
+ blur
29105
+ } = useFocus(props);
29106
+ const model = useProxiedModel(props, 'modelValue');
29107
+ const menu = vue.shallowRef(false);
29108
+ const isInteractive = vue.computed(() => !props.disabled && !props.readonly);
29109
+ const display = vue.computed(() => model.value || null);
29110
+ function onKeydown(e) {
29111
+ if (e.key !== 'Enter') return;
29112
+ if (!menu.value || !isFocused.value) {
29113
+ menu.value = true;
29114
+ return;
29115
+ }
29116
+ const target = e.target;
29117
+ model.value = target.value;
29118
+ }
29119
+ function onClick(e) {
29120
+ e.preventDefault();
29121
+ e.stopPropagation();
29122
+ menu.value = true;
29123
+ }
29124
+ function onSave() {
29125
+ menu.value = false;
29126
+ }
29127
+ useRender(() => {
29128
+ const confirmEditProps = VConfirmEdit.filterProps(props);
29129
+ const colorPickerProps = VColorPicker.filterProps(omit(props, ['active', 'color']));
29130
+ const textFieldProps = VTextField.filterProps(omit(props, ['prependInnerIcon']));
29131
+ const hasPrepend = !!(slots.prepend || props.pipIcon);
29132
+ return vue.createVNode(VTextField, vue.mergeProps(textFieldProps, {
29133
+ "class": ['v-color-input', props.class],
29134
+ "style": props.style,
29135
+ "modelValue": display.value,
29136
+ "onKeydown": isInteractive.value ? onKeydown : undefined,
29137
+ "focused": menu.value || isFocused.value,
29138
+ "onFocus": focus,
29139
+ "onBlur": blur,
29140
+ "onClick:control": isInteractive.value ? onClick : undefined,
29141
+ "onClick:prependInner": isInteractive.value ? onClick : undefined,
29142
+ "onClick:appendInner": isInteractive.value ? onClick : undefined,
29143
+ "onUpdate:modelValue": val => {
29144
+ model.value = val;
29145
+ }
29146
+ }), {
29147
+ ...slots,
29148
+ prepend: props.pipIcon ? arg => vue.createVNode(vue.Fragment, null, [hasPrepend && vue.createVNode(VIcon, {
29149
+ "color": props.pip ? model.value : undefined,
29150
+ "icon": props.pipIcon
29151
+ }, null), slots.prepend?.(arg)]) : undefined,
29152
+ default: () => vue.createVNode(vue.Fragment, null, [vue.createVNode(VMenu, {
29153
+ "modelValue": menu.value,
29154
+ "onUpdate:modelValue": $event => menu.value = $event,
29155
+ "activator": "parent",
29156
+ "min-width": "0",
29157
+ "closeOnContentClick": false,
29158
+ "openOnClick": false
29159
+ }, {
29160
+ default: () => [vue.createVNode(VConfirmEdit, vue.mergeProps(confirmEditProps, {
29161
+ "modelValue": model.value,
29162
+ "onUpdate:modelValue": $event => model.value = $event,
29163
+ "onSave": onSave
29164
+ }), {
29165
+ default: _ref2 => {
29166
+ let {
29167
+ actions,
29168
+ model: proxyModel,
29169
+ save,
29170
+ cancel,
29171
+ isPristine
29172
+ } = _ref2;
29173
+ return vue.createVNode(VColorPicker, vue.mergeProps(colorPickerProps, {
29174
+ "modelValue": proxyModel.value,
29175
+ "onUpdate:modelValue": val => {
29176
+ proxyModel.value = val;
29177
+ model.value = val;
29178
+ },
29179
+ "onMousedown": e => e.preventDefault()
29180
+ }), {
29181
+ actions: !props.hideActions ? () => slots.actions?.({
29182
+ save,
29183
+ cancel,
29184
+ isPristine
29185
+ }) ?? actions() : undefined
29186
+ });
29187
+ }
29188
+ })]
29189
+ }), slots.default?.()])
29190
+ });
29191
+ });
29192
+ }
29193
+ });
29194
+
29195
+ // Composables
29196
+
29197
+ // Types
29198
+
29199
+ // Types
29200
+
29201
+ class DateFormatSpec {
29202
+ constructor(order,
29203
+ // mdy | dmy | ymd
29204
+ separator // / | - | .
29205
+ ) {
29206
+ this.order = order;
29207
+ this.separator = separator;
29208
+ }
29209
+ get format() {
29210
+ return this.order.split('').map(sign => `${sign}${sign}`).join(this.separator).replace('yy', 'yyyy');
29211
+ }
29212
+ static canBeParsed(v) {
29213
+ if (typeof v !== 'string') return false;
29214
+ const lowercase = v.toLowerCase();
29215
+ return ['y', 'm', 'd'].every(sign => lowercase.includes(sign)) && ['/', '-', '.'].some(sign => v.includes(sign));
29216
+ }
29217
+ static parse(v) {
29218
+ if (!DateFormatSpec.canBeParsed(v)) {
29219
+ throw new Error(`[${v}] cannot be parsed into date format specification`);
29220
+ }
29221
+ const order = v.toLowerCase().split('').filter((c, i, all) => 'dmy'.includes(c) && all.indexOf(c) === i).join('');
29222
+ const separator = ['/', '-', '.'].find(sign => v.includes(sign));
29223
+ return new DateFormatSpec(order, separator);
29224
+ }
29225
+ }
29226
+ const makeDateFormatProps = propsFactory({
29227
+ inputFormat: {
29228
+ type: String,
29229
+ validator: v => !v || DateFormatSpec.canBeParsed(v)
29230
+ }
29231
+ }, 'date-format');
29232
+ function useDateFormat(props, locale) {
29233
+ const adapter = useDate();
29234
+ function inferFromLocale() {
29235
+ const localeForDateFormat = locale.value ?? 'en-US';
29236
+ const formatFromLocale = Intl.DateTimeFormat(localeForDateFormat, {
29237
+ year: 'numeric',
29238
+ month: '2-digit',
29239
+ day: '2-digit'
29240
+ }).format(adapter.toJsDate(adapter.parseISO('1999-12-07'))).replace(/(07)|(٠٧)|(٢٩)|(۱۶)|(০৭)/, 'dd').replace(/(12)|(١٢)|(٠٨)|(۰۹)|(১২)/, 'mm').replace(/(1999)|(2542)|(١٩٩٩)|(١٤٢٠)|(۱۳۷۸)|(১৯৯৯)/, 'yyyy').replace(/[^ymd\-/.]/g, '').replace(/\.$/, '');
29241
+ if (!DateFormatSpec.canBeParsed(formatFromLocale)) {
29242
+ consoleWarn(`Date format inferred from locale [${localeForDateFormat}] is invalid: [${formatFromLocale}]`);
29243
+ return 'mm/dd/yyyy';
29244
+ }
29245
+ return formatFromLocale;
29246
+ }
29247
+ const currentFormat = vue.toRef(() => {
29248
+ return DateFormatSpec.canBeParsed(props.inputFormat) ? DateFormatSpec.parse(props.inputFormat) : DateFormatSpec.parse(inferFromLocale());
29249
+ });
29250
+ function parseDate(dateString) {
29251
+ function parseDateParts(text) {
29252
+ const parts = text.trim().split(currentFormat.value.separator);
29253
+ return {
29254
+ y: Number(parts[currentFormat.value.order.indexOf('y')]),
29255
+ m: Number(parts[currentFormat.value.order.indexOf('m')]),
29256
+ d: Number(parts[currentFormat.value.order.indexOf('d')])
29257
+ };
29258
+ }
29259
+ function validateDateParts(dateParts) {
29260
+ const {
29261
+ y: year,
29262
+ m: month,
29263
+ d: day
29264
+ } = dateParts;
29265
+ if (!year || !month || !day) return null;
29266
+ if (month < 1 || month > 12) return null;
29267
+ if (day < 1 || day > 31) return null;
29268
+ return {
29269
+ year: autoFixYear(year),
29270
+ month,
29271
+ day
29272
+ };
29273
+ }
29274
+ function autoFixYear(year) {
29275
+ const currentYear = adapter.getYear(adapter.date());
29276
+ if (year > 100 || currentYear % 100 >= 50) {
29277
+ return year;
29278
+ }
29279
+ const currentCentury = ~~(currentYear / 100) * 100;
29280
+ return year < 50 ? currentCentury + year : currentCentury - 100 + year;
29281
+ }
29282
+ const dateParts = parseDateParts(dateString);
29283
+ const validatedParts = validateDateParts(dateParts);
29284
+ if (!validatedParts) return null;
29285
+ const {
29286
+ year,
29287
+ month,
29288
+ day
29289
+ } = validatedParts;
29290
+ const pad = v => String(v).padStart(2, '0');
29291
+ return adapter.parseISO(`${year}-${pad(month)}-${pad(day)}`);
29292
+ }
29293
+ function isValid(text) {
29294
+ return !!parseDate(text);
29295
+ }
29296
+ function formatDate(value) {
29297
+ const parts = adapter.toISO(value).split('-');
29298
+ return currentFormat.value.order.split('').map(sign => parts['ymd'.indexOf(sign)]).join(currentFormat.value.separator);
29299
+ }
29300
+ return {
29301
+ isValid,
29302
+ parseDate,
29303
+ formatDate,
29304
+ parserFormat: vue.toRef(() => currentFormat.value.format)
29305
+ };
29306
+ }
29307
+
29308
+ // Types
29309
+
29079
29310
  // Types
29080
29311
 
29081
29312
  const makeVDateInputProps = propsFactory({
29082
29313
  displayFormat: [Function, String],
29083
- inputFormat: [Function, String],
29084
29314
  location: {
29085
29315
  type: String,
29086
29316
  default: 'bottom start'
@@ -29090,6 +29320,7 @@
29090
29320
  type: Array,
29091
29321
  default: () => ['blur', 'enter']
29092
29322
  },
29323
+ ...makeDateFormatProps(),
29093
29324
  ...makeDisplayProps({
29094
29325
  mobile: null
29095
29326
  }),
@@ -29098,7 +29329,6 @@
29098
29329
  hideActions: true
29099
29330
  }),
29100
29331
  ...makeVTextFieldProps({
29101
- placeholder: 'mm/dd/yyyy',
29102
29332
  prependIcon: '$calendar'
29103
29333
  }),
29104
29334
  ...omit(makeVDatePickerProps({
@@ -29121,9 +29351,16 @@
29121
29351
  slots
29122
29352
  } = _ref;
29123
29353
  const {
29124
- t
29354
+ t,
29355
+ current: currentLocale
29125
29356
  } = useLocale();
29126
29357
  const adapter = useDate();
29358
+ const {
29359
+ isValid,
29360
+ parseDate,
29361
+ formatDate,
29362
+ parserFormat
29363
+ } = useDateFormat(props, currentLocale);
29127
29364
  const {
29128
29365
  mobile
29129
29366
  } = useDisplay(props);
@@ -29142,80 +29379,10 @@
29142
29379
  if (typeof props.displayFormat === 'function') {
29143
29380
  return props.displayFormat(date);
29144
29381
  }
29145
- return adapter.format(date, props.displayFormat ?? 'keyboardDate');
29146
- }
29147
- function parseDateString(dateString, format) {
29148
- function countConsecutiveChars(str, startIndex) {
29149
- const char = str[startIndex];
29150
- let count = 0;
29151
- while (str[startIndex + count] === char) count++;
29152
- return count;
29153
- }
29154
- function parseDateParts(dateString, format) {
29155
- const dateParts = {};
29156
- let stringIndex = 0;
29157
- const upperFormat = format.toUpperCase();
29158
- for (let formatIndex = 0; formatIndex < upperFormat.length;) {
29159
- const formatChar = upperFormat[formatIndex];
29160
- const charCount = countConsecutiveChars(upperFormat, formatIndex);
29161
- const dateValue = dateString.slice(stringIndex, stringIndex + charCount);
29162
- if (['Y', 'M', 'D'].includes(formatChar)) {
29163
- const numValue = parseInt(dateValue);
29164
- if (isNaN(numValue)) return null;
29165
- dateParts[formatChar] = numValue;
29166
- }
29167
- formatIndex += charCount;
29168
- stringIndex += charCount;
29169
- }
29170
- return dateParts;
29382
+ if (props.displayFormat) {
29383
+ return adapter.format(date, props.displayFormat ?? 'keyboardDate');
29171
29384
  }
29172
- function validateDateParts(dateParts) {
29173
- const {
29174
- Y: year,
29175
- M: month,
29176
- D: day
29177
- } = dateParts;
29178
- if (!year || !month || !day) return null;
29179
- if (month < 1 || month > 12) return null;
29180
- if (day < 1 || day > 31) return null;
29181
- return {
29182
- year,
29183
- month,
29184
- day
29185
- };
29186
- }
29187
- const dateParts = parseDateParts(dateString, format);
29188
- if (!dateParts) return null;
29189
- const validatedParts = validateDateParts(dateParts);
29190
- if (!validatedParts) return null;
29191
- const {
29192
- year,
29193
- month,
29194
- day
29195
- } = validatedParts;
29196
- return {
29197
- year,
29198
- month,
29199
- day
29200
- };
29201
- }
29202
- function parseUserInput(value) {
29203
- if (typeof props.inputFormat === 'function') {
29204
- return props.inputFormat(value);
29205
- }
29206
- if (typeof props.inputFormat === 'string') {
29207
- const formattedDate = parseDateString(value, props.inputFormat);
29208
- if (!formattedDate) {
29209
- return model.value;
29210
- }
29211
- const {
29212
- year,
29213
- month,
29214
- day
29215
- } = formattedDate;
29216
- return adapter.parseISO(`${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`);
29217
- }
29218
- return adapter.isValid(value) ? adapter.date(value) : model.value;
29385
+ return formatDate(date);
29219
29386
  }
29220
29387
  const display = vue.computed(() => {
29221
29388
  const value = wrapInArray(model.value);
@@ -29293,12 +29460,32 @@
29293
29460
  let {
29294
29461
  value
29295
29462
  } = _ref2;
29296
- model.value = !value ? emptyModelValue() : parseUserInput(value);
29463
+ if (!value.trim()) {
29464
+ model.value = emptyModelValue();
29465
+ } else if (!props.multiple) {
29466
+ if (isValid(value)) {
29467
+ model.value = parseDate(value);
29468
+ }
29469
+ } else {
29470
+ const parts = value.trim().split(/\D+-\D+|[^\d\-/.]+/);
29471
+ if (parts.every(isValid)) {
29472
+ if (props.multiple === 'range') {
29473
+ model.value = getRange(parts);
29474
+ } else {
29475
+ model.value = parts.map(parseDate);
29476
+ }
29477
+ }
29478
+ }
29479
+ }
29480
+ function getRange(inputDates) {
29481
+ const [start, stop] = inputDates.map(parseDate).toSorted((a, b) => adapter.isAfter(a, b) ? 1 : -1);
29482
+ const diff = adapter.getDiff(stop ?? start, start, 'days');
29483
+ return [start, ...createRange(diff, 1).map(i => adapter.addDays(start, i))];
29297
29484
  }
29298
29485
  useRender(() => {
29299
29486
  const confirmEditProps = VConfirmEdit.filterProps(props);
29300
29487
  const datePickerProps = VDatePicker.filterProps(omit(props, ['active', 'location', 'rounded']));
29301
- const textFieldProps = VTextField.filterProps(props);
29488
+ const textFieldProps = VTextField.filterProps(omit(props, ['placeholder']));
29302
29489
  return vue.createVNode(VTextField, vue.mergeProps({
29303
29490
  "ref": vTextFieldRef
29304
29491
  }, textFieldProps, {
@@ -29306,11 +29493,13 @@
29306
29493
  "style": props.style,
29307
29494
  "modelValue": display.value,
29308
29495
  "inputmode": inputmode.value,
29496
+ "placeholder": props.placeholder ?? parserFormat.value,
29309
29497
  "readonly": isReadonly.value,
29310
29498
  "onKeydown": isInteractive.value ? onKeydown : undefined,
29311
29499
  "focused": menu.value || isFocused.value,
29312
29500
  "onFocus": focus,
29313
29501
  "onBlur": onBlur,
29502
+ "validationValue": model.value,
29314
29503
  "onClick:control": isInteractive.value ? onClick : undefined,
29315
29504
  "onClick:prepend": isInteractive.value ? onClick : undefined,
29316
29505
  "onUpdate:modelValue": onUpdateDisplayModel
@@ -31277,6 +31466,7 @@
31277
31466
  VClassIcon: VClassIcon,
31278
31467
  VCode: VCode,
31279
31468
  VCol: VCol,
31469
+ VColorInput: VColorInput,
31280
31470
  VColorPicker: VColorPicker,
31281
31471
  VCombobox: VCombobox,
31282
31472
  VComponentIcon: VComponentIcon,
@@ -31743,7 +31933,7 @@
31743
31933
  };
31744
31934
  });
31745
31935
  }
31746
- const version$1 = "3.8.4-master.2025-05-13";
31936
+ const version$1 = "3.8.5-master.2025-05-14";
31747
31937
  createVuetify$1.version = version$1;
31748
31938
 
31749
31939
  // Vue's inject() can only be used in setup
@@ -32041,7 +32231,7 @@
32041
32231
 
32042
32232
  /* eslint-disable local-rules/sort-imports */
32043
32233
 
32044
- const version = "3.8.4-master.2025-05-13";
32234
+ const version = "3.8.5-master.2025-05-14";
32045
32235
 
32046
32236
  /* eslint-disable local-rules/sort-imports */
32047
32237