@vuetify/nightly 3.8.8-master.2025-06-06 → 3.8.8-master.2025-06-08

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 (61) hide show
  1. package/CHANGELOG.md +14 -3
  2. package/dist/json/attributes.json +2080 -2080
  3. package/dist/json/importMap-labs.json +20 -20
  4. package/dist/json/importMap.json +160 -160
  5. package/dist/json/web-types.json +3925 -3925
  6. package/dist/vuetify-labs.cjs +117 -59
  7. package/dist/vuetify-labs.css +3446 -3446
  8. package/dist/vuetify-labs.d.ts +65 -59
  9. package/dist/vuetify-labs.esm.js +117 -59
  10. package/dist/vuetify-labs.esm.js.map +1 -1
  11. package/dist/vuetify-labs.js +117 -59
  12. package/dist/vuetify-labs.min.css +2 -2
  13. package/dist/vuetify.cjs +104 -40
  14. package/dist/vuetify.cjs.map +1 -1
  15. package/dist/vuetify.css +3061 -3061
  16. package/dist/vuetify.d.ts +60 -59
  17. package/dist/vuetify.esm.js +104 -40
  18. package/dist/vuetify.esm.js.map +1 -1
  19. package/dist/vuetify.js +104 -40
  20. package/dist/vuetify.js.map +1 -1
  21. package/dist/vuetify.min.css +2 -2
  22. package/dist/vuetify.min.js +147 -140
  23. package/dist/vuetify.min.js.map +1 -1
  24. package/lib/components/VDataTable/VDataTableColumn.js +1 -0
  25. package/lib/components/VDataTable/VDataTableColumn.js.map +1 -1
  26. package/lib/components/VDataTable/VDataTableFooter.js +3 -1
  27. package/lib/components/VDataTable/VDataTableFooter.js.map +1 -1
  28. package/lib/components/VDataTable/VDataTableHeaders.js +8 -1
  29. package/lib/components/VDataTable/VDataTableHeaders.js.map +1 -1
  30. package/lib/components/VDatePicker/VDatePickerMonth.js +2 -2
  31. package/lib/components/VDatePicker/VDatePickerMonth.js.map +1 -1
  32. package/lib/components/VFileInput/VFileInput.js +8 -3
  33. package/lib/components/VFileInput/VFileInput.js.map +1 -1
  34. package/lib/components/VNumberInput/VNumberInput.d.ts +5 -0
  35. package/lib/components/VNumberInput/VNumberInput.js +7 -11
  36. package/lib/components/VNumberInput/VNumberInput.js.map +1 -1
  37. package/lib/components/VOtpInput/VOtpInput.js +5 -2
  38. package/lib/components/VOtpInput/VOtpInput.js.map +1 -1
  39. package/lib/components/VSlider/VSliderThumb.js +1 -1
  40. package/lib/components/VSlider/VSliderThumb.js.map +1 -1
  41. package/lib/components/VTextField/VTextField.js +5 -4
  42. package/lib/components/VTextField/VTextField.js.map +1 -1
  43. package/lib/composables/date/date.d.ts +1 -4
  44. package/lib/composables/date/date.js +13 -14
  45. package/lib/composables/date/date.js.map +1 -1
  46. package/lib/composables/fileDrop.d.ts +4 -0
  47. package/lib/composables/fileDrop.js +50 -0
  48. package/lib/composables/fileDrop.js.map +1 -0
  49. package/lib/entry-bundler.d.ts +0 -3
  50. package/lib/entry-bundler.js +1 -1
  51. package/lib/framework.d.ts +55 -59
  52. package/lib/framework.js +1 -1
  53. package/lib/labs/VColorInput/VColorInput.js +3 -8
  54. package/lib/labs/VColorInput/VColorInput.js.map +1 -1
  55. package/lib/labs/VDateInput/VDateInput.d.ts +5 -0
  56. package/lib/labs/VDateInput/VDateInput.js +7 -10
  57. package/lib/labs/VDateInput/VDateInput.js.map +1 -1
  58. package/lib/labs/VFileUpload/VFileUpload.js +7 -3
  59. package/lib/labs/VFileUpload/VFileUpload.js.map +1 -1
  60. package/lib/labs/entry-bundler.d.ts +0 -3
  61. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.8.8-master.2025-06-06
2
+ * Vuetify v3.8.8-master.2025-06-08
3
3
  * Forged by John Leider
4
4
  * Released under the MIT License.
5
5
  */
@@ -12118,10 +12118,12 @@
12118
12118
  const inputRef = vue.ref();
12119
12119
  const isActive = vue.computed(() => activeTypes.includes(props.type) || props.persistentPlaceholder || isFocused.value || props.active);
12120
12120
  function onFocus() {
12121
- if (inputRef.value !== document.activeElement) {
12122
- inputRef.value?.focus();
12123
- }
12124
12121
  if (!isFocused.value) focus();
12122
+ vue.nextTick(() => {
12123
+ if (inputRef.value !== document.activeElement) {
12124
+ inputRef.value?.focus();
12125
+ }
12126
+ });
12125
12127
  }
12126
12128
  function onControlMousedown(e) {
12127
12129
  emit('mousedown:control', e);
@@ -12130,7 +12132,6 @@
12130
12132
  e.preventDefault();
12131
12133
  }
12132
12134
  function onControlClick(e) {
12133
- onFocus();
12134
12135
  emit('click:control', e);
12135
12136
  }
12136
12137
  function onClear(e, reset) {
@@ -16259,7 +16260,7 @@
16259
16260
  default: () => [vue.withDirectives(vue.createElementVNode("div", {
16260
16261
  "class": "v-slider-thumb__label-container"
16261
16262
  }, [vue.createElementVNode("div", {
16262
- "class": vue.normalizeClass(['v-slider-thumb__label'])
16263
+ "class": vue.normalizeClass(['v-slider-thumb__label', textColorClasses.value])
16263
16264
  }, [vue.createElementVNode("div", null, [slots['thumb-label']?.({
16264
16265
  modelValue: props.modelValue
16265
16266
  }) ?? props.modelValue.toFixed(step.value ? decimals.value : 1)])])]), [[vue.vShow, thumbLabel.value && props.focused || thumbLabel.value === 'always']])]
@@ -17831,6 +17832,18 @@
17831
17832
  instance: createInstance(_options, locale)
17832
17833
  };
17833
17834
  }
17835
+ function createDateRange(adapter, start, stop) {
17836
+ const diff = adapter.getDiff(stop ?? start, start, 'days');
17837
+ const datesInRange = [start];
17838
+ for (let i = 1; i < diff; i++) {
17839
+ const nextDate = adapter.addDays(start, i);
17840
+ datesInRange.push(nextDate);
17841
+ }
17842
+ if (stop) {
17843
+ datesInRange.push(adapter.endOfDay(stop));
17844
+ }
17845
+ return datesInRange;
17846
+ }
17834
17847
  function createInstance(options, locale) {
17835
17848
  const instance = vue.reactive(typeof options.adapter === 'function'
17836
17849
  // eslint-disable-next-line new-cap
@@ -17841,20 +17854,7 @@
17841
17854
  vue.watch(locale.current, value => {
17842
17855
  instance.locale = options.locale[value] ?? value ?? instance.locale;
17843
17856
  });
17844
- return Object.assign(instance, {
17845
- createDateRange(start, stop) {
17846
- const diff = instance.getDiff(stop ?? start, start, 'days');
17847
- const datesInRange = [start];
17848
- for (let i = 1; i < diff; i++) {
17849
- const nextDate = instance.addDays(start, i);
17850
- datesInRange.push(nextDate);
17851
- }
17852
- if (stop) {
17853
- datesInRange.push(instance.endOfDay(stop));
17854
- }
17855
- return datesInRange;
17856
- }
17857
- });
17857
+ return instance;
17858
17858
  }
17859
17859
  function useDate() {
17860
17860
  const options = vue.inject(DateOptionsSymbol);
@@ -19943,7 +19943,9 @@
19943
19943
  "class": "v-data-table-footer"
19944
19944
  }, [slots.prepend?.(), vue.createElementVNode("div", {
19945
19945
  "class": "v-data-table-footer__items-per-page"
19946
- }, [vue.createElementVNode("span", null, [t(props.itemsPerPageText)]), vue.createVNode(VSelect, {
19946
+ }, [vue.createElementVNode("span", {
19947
+ "aria-label": t(props.itemsPerPageText)
19948
+ }, [t(props.itemsPerPageText)]), vue.createVNode(VSelect, {
19947
19949
  "items": itemsPerPageOptions.value,
19948
19950
  "modelValue": itemsPerPage.value,
19949
19951
  "onUpdate:modelValue": v => setItemsPerPage(Number(v)),
@@ -19995,6 +19997,7 @@
19995
19997
  } = _ref;
19996
19998
  const Tag = props.tag ?? 'td';
19997
19999
  return vue.createVNode(Tag, {
20000
+ "tabindex": "0",
19998
20001
  "class": vue.normalizeClass(['v-data-table__td', {
19999
20002
  'v-data-table-column--fixed': props.fixed,
20000
20003
  'v-data-table-column--last-fixed': props.lastFixed,
@@ -20339,6 +20342,11 @@
20339
20342
  top: props.sticky || props.fixedHeader ? `calc(var(--v-table-header-height) * ${y})` : undefined
20340
20343
  };
20341
20344
  }
20345
+ function handleEnterKeyPress(event, column) {
20346
+ if (event.key === 'Enter' && !props.disableSort) {
20347
+ toggleSort(column);
20348
+ }
20349
+ }
20342
20350
  function getSortIcon(column) {
20343
20351
  const item = sortBy.value.find(item => item.key === column.key);
20344
20352
  if (!item) return props.sortAscIcon;
@@ -20395,7 +20403,9 @@
20395
20403
  "nowrap": column.nowrap,
20396
20404
  "lastFixed": column.lastFixed,
20397
20405
  "noPadding": noPadding
20398
- }, headerProps), {
20406
+ }, headerProps, {
20407
+ "onKeydown": event => column.sortable && handleEnterKeyPress(event, column)
20408
+ }), {
20399
20409
  default: () => {
20400
20410
  const columnSlotName = `header.${column.key}`;
20401
20411
  const columnSlotProps = {
@@ -22248,7 +22258,7 @@
22248
22258
  } else {
22249
22259
  rangeStop.value = adapter.endOfDay(_value);
22250
22260
  }
22251
- model.value = adapter.createDateRange(rangeStart.value, rangeStop.value);
22261
+ model.value = createDateRange(adapter, rangeStart.value, rangeStop.value);
22252
22262
  } else {
22253
22263
  rangeStart.value = value;
22254
22264
  rangeStop.value = undefined;
@@ -23335,6 +23345,56 @@
23335
23345
 
23336
23346
  // Types
23337
23347
 
23348
+ function useFileDrop() {
23349
+ function hasFilesOrFolders(e) {
23350
+ const entries = [...(e.dataTransfer?.items ?? [])].filter(x => x.kind === 'file').map(x => x.webkitGetAsEntry()).filter(Boolean);
23351
+ return entries.length > 0 || [...(e.dataTransfer?.files ?? [])].length > 0;
23352
+ }
23353
+ async function handleDrop(e) {
23354
+ const result = [];
23355
+ const entries = [...(e.dataTransfer?.items ?? [])].filter(x => x.kind === 'file').map(x => x.webkitGetAsEntry()).filter(Boolean);
23356
+ if (entries.length) {
23357
+ for (const entry of entries) {
23358
+ const files = await traverseFileTree(entry, appendIfDirectory('.', entry));
23359
+ result.push(...files.map(x => x.file));
23360
+ }
23361
+ } else {
23362
+ result.push(...[...(e.dataTransfer?.files ?? [])]);
23363
+ }
23364
+ return result;
23365
+ }
23366
+ return {
23367
+ handleDrop,
23368
+ hasFilesOrFolders
23369
+ };
23370
+ }
23371
+ function traverseFileTree(item) {
23372
+ let path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
23373
+ return new Promise((resolve, reject) => {
23374
+ if (item.isFile) {
23375
+ const fileEntry = item;
23376
+ fileEntry.file(file => resolve([{
23377
+ file,
23378
+ path
23379
+ }]), reject);
23380
+ } else if (item.isDirectory) {
23381
+ const directoryReader = item.createReader();
23382
+ directoryReader.readEntries(async entries => {
23383
+ const files = [];
23384
+ for (const entry of entries) {
23385
+ files.push(...(await traverseFileTree(entry, appendIfDirectory(path, entry))));
23386
+ }
23387
+ resolve(files);
23388
+ });
23389
+ }
23390
+ });
23391
+ }
23392
+ function appendIfDirectory(path, item) {
23393
+ return item.isDirectory ? `${path}/${item.name}` : path;
23394
+ }
23395
+
23396
+ // Types
23397
+
23338
23398
  const makeVFileInputProps = propsFactory({
23339
23399
  chips: Boolean,
23340
23400
  counter: Boolean,
@@ -23419,6 +23479,10 @@
23419
23479
  const isActive = vue.toRef(() => isFocused.value || props.active);
23420
23480
  const isPlainOrUnderlined = vue.computed(() => ['plain', 'underlined'].includes(props.variant));
23421
23481
  const isDragging = vue.shallowRef(false);
23482
+ const {
23483
+ handleDrop,
23484
+ hasFilesOrFolders
23485
+ } = useFileDrop();
23422
23486
  function onFocus() {
23423
23487
  if (inputRef.value !== document.activeElement) {
23424
23488
  inputRef.value?.focus();
@@ -23452,13 +23516,13 @@
23452
23516
  e.preventDefault();
23453
23517
  isDragging.value = false;
23454
23518
  }
23455
- function onDrop(e) {
23519
+ async function onDrop(e) {
23456
23520
  e.preventDefault();
23457
23521
  e.stopImmediatePropagation();
23458
23522
  isDragging.value = false;
23459
- if (!e.dataTransfer?.files?.length || !inputRef.value) return;
23523
+ if (!inputRef.value || !hasFilesOrFolders(e)) return;
23460
23524
  const dataTransfer = new DataTransfer();
23461
- for (const file of e.dataTransfer.files) {
23525
+ for (const file of await handleDrop(e)) {
23462
23526
  dataTransfer.items.add(file);
23463
23527
  }
23464
23528
  inputRef.value.files = dataTransfer.files;
@@ -24889,6 +24953,7 @@
24889
24953
  ...makeVNumberInputProps()
24890
24954
  },
24891
24955
  emits: {
24956
+ 'update:focused': val => true,
24892
24957
  'update:modelValue': val => true
24893
24958
  },
24894
24959
  setup(props, _ref) {
@@ -24904,11 +24969,7 @@
24904
24969
  });
24905
24970
  const form = useForm(props);
24906
24971
  const controlsDisabled = vue.computed(() => form.isDisabled.value || form.isReadonly.value);
24907
- const {
24908
- isFocused,
24909
- focus,
24910
- blur
24911
- } = useFocus(props);
24972
+ const isFocused = vue.shallowRef(props.focused);
24912
24973
  function correctPrecision(val) {
24913
24974
  let precision = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : props.precision;
24914
24975
  const fixed = precision == null ? String(val) : val.toFixed(precision);
@@ -25093,11 +25154,9 @@
25093
25154
  inputText.value = model.value.toString();
25094
25155
  }
25095
25156
  function onFocus() {
25096
- focus();
25097
25157
  trimDecimalZeros();
25098
25158
  }
25099
25159
  function onBlur() {
25100
- blur();
25101
25160
  clampModel();
25102
25161
  }
25103
25162
  useRender(() => {
@@ -25190,9 +25249,12 @@
25190
25249
  }, null)]) : props.reverse && controlVariant.value !== 'hidden' ? vue.createElementVNode(vue.Fragment, null, [controlNode(), dividerNode()]) : undefined;
25191
25250
  const hasPrependInner = slots['prepend-inner'] || prependInnerControl;
25192
25251
  return vue.createVNode(VTextField, vue.mergeProps({
25193
- "ref": vTextFieldRef,
25252
+ "ref": vTextFieldRef
25253
+ }, textFieldProps, {
25194
25254
  "modelValue": inputText.value,
25195
25255
  "onUpdate:modelValue": $event => inputText.value = $event,
25256
+ "focused": isFocused.value,
25257
+ "onUpdate:focused": $event => isFocused.value = $event,
25196
25258
  "validationValue": model.value,
25197
25259
  "onBeforeinput": onBeforeinput,
25198
25260
  "onFocus": onFocus,
@@ -25205,8 +25267,7 @@
25205
25267
  'v-number-input--reverse': props.reverse,
25206
25268
  'v-number-input--split': controlVariant.value === 'split',
25207
25269
  'v-number-input--stacked': controlVariant.value === 'stacked'
25208
- }, props.class]
25209
- }, textFieldProps, {
25270
+ }, props.class],
25210
25271
  "style": props.style,
25211
25272
  "inputmode": "decimal"
25212
25273
  }), {
@@ -25341,7 +25402,7 @@
25341
25402
  function onPaste(index, e) {
25342
25403
  e.preventDefault();
25343
25404
  e.stopPropagation();
25344
- const clipboardText = e?.clipboardData?.getData('Text').slice(0, length.value) ?? '';
25405
+ const clipboardText = e?.clipboardData?.getData('Text').trim().slice(0, length.value) ?? '';
25345
25406
  if (isValidNumber(clipboardText)) return;
25346
25407
  model.value = clipboardText.split('');
25347
25408
  inputRef.value?.[index].blur();
@@ -25373,7 +25434,10 @@
25373
25434
  scoped: true
25374
25435
  });
25375
25436
  vue.watch(model, val => {
25376
- if (val.length === length.value) emit('finish', val.join(''));
25437
+ if (val.length === length.value) {
25438
+ focusIndex.value = length.value - 1;
25439
+ emit('finish', val.join(''));
25440
+ }
25377
25441
  }, {
25378
25442
  deep: true
25379
25443
  });
@@ -29264,13 +29328,9 @@
29264
29328
  let {
29265
29329
  slots
29266
29330
  } = _ref;
29267
- const {
29268
- isFocused,
29269
- focus,
29270
- blur
29271
- } = useFocus(props);
29272
29331
  const model = useProxiedModel(props, 'modelValue');
29273
29332
  const menu = vue.shallowRef(false);
29333
+ const isFocused = vue.shallowRef(props.focused);
29274
29334
  const isInteractive = vue.computed(() => !props.disabled && !props.readonly);
29275
29335
  const display = vue.computed(() => model.value || null);
29276
29336
  function onKeydown(e) {
@@ -29301,10 +29361,9 @@
29301
29361
  "modelValue": display.value,
29302
29362
  "onKeydown": isInteractive.value ? onKeydown : undefined,
29303
29363
  "focused": menu.value || isFocused.value,
29304
- "onFocus": focus,
29305
- "onBlur": blur,
29306
29364
  "onClick:control": isInteractive.value ? onClick : undefined,
29307
29365
  "onClick:prependInner": isInteractive.value ? onClick : undefined,
29366
+ "onUpdate:focused": event => isFocused.value = event,
29308
29367
  "onClick:appendInner": isInteractive.value ? onClick : undefined,
29309
29368
  "onUpdate:modelValue": val => {
29310
29369
  model.value = val;
@@ -29508,6 +29567,7 @@
29508
29567
  emits: {
29509
29568
  save: value => true,
29510
29569
  cancel: () => true,
29570
+ 'update:focused': val => true,
29511
29571
  'update:modelValue': val => true,
29512
29572
  'update:menu': val => true
29513
29573
  },
@@ -29530,15 +29590,11 @@
29530
29590
  const {
29531
29591
  mobile
29532
29592
  } = useDisplay(props);
29533
- const {
29534
- isFocused,
29535
- focus,
29536
- blur
29537
- } = useFocus(props);
29538
29593
  const emptyModelValue = () => props.multiple ? [] : null;
29539
29594
  const model = useProxiedModel(props, 'modelValue', emptyModelValue(), val => Array.isArray(val) ? val.map(item => adapter.toJsDate(item)) : val ? adapter.toJsDate(val) : val, val => Array.isArray(val) ? val.map(item => adapter.date(item)) : val ? adapter.date(val) : val);
29540
29595
  const menu = useProxiedModel(props, 'menu');
29541
29596
  const isEditingInput = vue.shallowRef(false);
29597
+ const isFocused = vue.shallowRef(props.focused);
29542
29598
  const vTextFieldRef = vue.ref();
29543
29599
  const disabledActions = vue.ref(['save']);
29544
29600
  function format(date) {
@@ -29614,7 +29670,6 @@
29614
29670
  if (props.updateOn.includes('blur')) {
29615
29671
  onUserInput(e.target);
29616
29672
  }
29617
- blur();
29618
29673
 
29619
29674
  // When in mobile mode and editing is done (due to keyboard dismissal), close the menu
29620
29675
  if (mobile.value && isEditingInput.value && !isFocused.value) {
@@ -29637,7 +29692,7 @@
29637
29692
  if (parts.every(isValid)) {
29638
29693
  if (props.multiple === 'range') {
29639
29694
  const [start, stop] = parts.map(parseDate).toSorted((a, b) => adapter.isAfter(a, b) ? 1 : -1);
29640
- model.value = adapter.createDateRange(start, stop);
29695
+ model.value = createDateRange(adapter, start, stop);
29641
29696
  } else {
29642
29697
  model.value = parts.map(parseDate);
29643
29698
  }
@@ -29659,12 +29714,12 @@
29659
29714
  "readonly": isReadonly.value,
29660
29715
  "onKeydown": isInteractive.value ? onKeydown : undefined,
29661
29716
  "focused": menu.value || isFocused.value,
29662
- "onFocus": focus,
29663
29717
  "onBlur": onBlur,
29664
29718
  "validationValue": model.value,
29665
29719
  "onClick:control": isInteractive.value ? onClick : undefined,
29666
29720
  "onClick:prepend": isInteractive.value ? onClick : undefined,
29667
- "onUpdate:modelValue": onUpdateDisplayModel
29721
+ "onUpdate:modelValue": onUpdateDisplayModel,
29722
+ "onUpdate:focused": event => isFocused.value = event
29668
29723
  }), {
29669
29724
  ...slots,
29670
29725
  default: () => vue.createElementVNode(vue.Fragment, null, [vue.createVNode(VMenu, {
@@ -29879,6 +29934,9 @@
29879
29934
  const isDragging = vue.shallowRef(false);
29880
29935
  const vSheetRef = vue.ref(null);
29881
29936
  const inputRef = vue.ref(null);
29937
+ const {
29938
+ handleDrop
29939
+ } = useFileDrop();
29882
29940
  function onDragover(e) {
29883
29941
  e.preventDefault();
29884
29942
  e.stopImmediatePropagation();
@@ -29888,13 +29946,13 @@
29888
29946
  e.preventDefault();
29889
29947
  isDragging.value = false;
29890
29948
  }
29891
- function onDrop(e) {
29949
+ async function onDrop(e) {
29892
29950
  e.preventDefault();
29893
29951
  e.stopImmediatePropagation();
29894
29952
  isDragging.value = false;
29895
- if (!e.dataTransfer?.files?.length || !inputRef.value) return;
29953
+ if (!inputRef.value) return;
29896
29954
  const dataTransfer = new DataTransfer();
29897
- for (const file of e.dataTransfer.files) {
29955
+ for (const file of await handleDrop(e)) {
29898
29956
  dataTransfer.items.add(file);
29899
29957
  }
29900
29958
  inputRef.value.files = dataTransfer.files;
@@ -32095,7 +32153,7 @@
32095
32153
  };
32096
32154
  });
32097
32155
  }
32098
- const version$1 = "3.8.8-master.2025-06-06";
32156
+ const version$1 = "3.8.8-master.2025-06-08";
32099
32157
  createVuetify$1.version = version$1;
32100
32158
 
32101
32159
  // Vue's inject() can only be used in setup
@@ -32393,7 +32451,7 @@
32393
32451
 
32394
32452
  /* eslint-disable local-rules/sort-imports */
32395
32453
 
32396
- const version = "3.8.8-master.2025-06-06";
32454
+ const version = "3.8.8-master.2025-06-08";
32397
32455
 
32398
32456
  /* eslint-disable local-rules/sort-imports */
32399
32457