vuetify 3.8.3 → 3.8.5

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 (117) hide show
  1. package/dist/_component-variables-labs.sass +1 -0
  2. package/dist/json/attributes.json +4267 -3919
  3. package/dist/json/importMap-labs.json +28 -24
  4. package/dist/json/importMap.json +164 -164
  5. package/dist/json/tags.json +92 -0
  6. package/dist/json/web-types.json +8380 -7153
  7. package/dist/vuetify-labs.cjs +374 -79
  8. package/dist/vuetify-labs.css +3864 -3836
  9. package/dist/vuetify-labs.d.ts +5818 -1810
  10. package/dist/vuetify-labs.esm.js +374 -79
  11. package/dist/vuetify-labs.esm.js.map +1 -1
  12. package/dist/vuetify-labs.js +374 -79
  13. package/dist/vuetify-labs.min.css +2 -2
  14. package/dist/vuetify.cjs +53 -30
  15. package/dist/vuetify.cjs.map +1 -1
  16. package/dist/vuetify.css +3556 -3531
  17. package/dist/vuetify.d.ts +4121 -1210
  18. package/dist/vuetify.esm.js +53 -30
  19. package/dist/vuetify.esm.js.map +1 -1
  20. package/dist/vuetify.js +53 -30
  21. package/dist/vuetify.js.map +1 -1
  22. package/dist/vuetify.min.css +2 -2
  23. package/dist/vuetify.min.js +30 -27
  24. package/dist/vuetify.min.js.map +1 -1
  25. package/lib/components/VAutocomplete/VAutocomplete.d.ts +795 -77
  26. package/lib/components/VBadge/VBadge.d.ts +22 -46
  27. package/lib/components/VBottomNavigation/VBottomNavigation.d.ts +6 -6
  28. package/lib/components/VBottomSheet/VBottomSheet.css +1 -1
  29. package/lib/components/VBottomSheet/VBottomSheet.d.ts +1434 -80
  30. package/lib/components/VBottomSheet/VBottomSheet.sass +1 -1
  31. package/lib/components/VBtn/VBtn.css +25 -0
  32. package/lib/components/VBtn/VBtn.sass +9 -0
  33. package/lib/components/VBtn/_variables.scss +1 -0
  34. package/lib/components/VCombobox/VCombobox.d.ts +795 -77
  35. package/lib/components/VCounter/VCounter.d.ts +22 -46
  36. package/lib/components/VDataIterator/VDataIterator.d.ts +22 -46
  37. package/lib/components/VDataTable/VDataTable.d.ts +110 -110
  38. package/lib/components/VDataTable/VDataTableHeaders.js +1 -2
  39. package/lib/components/VDataTable/VDataTableHeaders.js.map +1 -1
  40. package/lib/components/VDataTable/VDataTableServer.d.ts +62 -189
  41. package/lib/components/VDataTable/VDataTableServer.js.map +1 -1
  42. package/lib/components/VDataTable/VDataTableVirtual.d.ts +62 -189
  43. package/lib/components/VDataTable/VDataTableVirtual.js.map +1 -1
  44. package/lib/components/VDataTable/composables/headers.d.ts +75 -75
  45. package/lib/components/VDataTable/composables/select.js +1 -1
  46. package/lib/components/VDataTable/composables/select.js.map +1 -1
  47. package/lib/components/VDatePicker/VDatePicker.d.ts +3 -3
  48. package/lib/components/VDatePicker/VDatePickerMonth.d.ts +6 -6
  49. package/lib/components/VDialog/VDialog.d.ts +1048 -146
  50. package/lib/components/VDialog/VDialog.js +1 -1
  51. package/lib/components/VDialog/VDialog.js.map +1 -1
  52. package/lib/components/VFab/VFab.d.ts +22 -46
  53. package/lib/components/VFileInput/VFileInput.css +4 -0
  54. package/lib/components/VFileInput/VFileInput.js +21 -3
  55. package/lib/components/VFileInput/VFileInput.js.map +1 -1
  56. package/lib/components/VFileInput/VFileInput.sass +4 -0
  57. package/lib/components/VImg/VImg.d.ts +22 -49
  58. package/lib/components/VLazy/VLazy.d.ts +22 -46
  59. package/lib/components/VMenu/VMenu.d.ts +1048 -146
  60. package/lib/components/VMenu/VMenu.js.map +1 -1
  61. package/lib/components/VMessages/VMessages.d.ts +22 -46
  62. package/lib/components/VNumberInput/VNumberInput.d.ts +3 -3
  63. package/lib/components/VOverlay/VOverlay.d.ts +22 -49
  64. package/lib/components/VOverlay/locationStrategies.js +1 -1
  65. package/lib/components/VOverlay/locationStrategies.js.map +1 -1
  66. package/lib/components/VSelect/VSelect.d.ts +1235 -93
  67. package/lib/components/VSnackbar/VSnackbar.d.ts +58 -109
  68. package/lib/components/VSnackbarQueue/VSnackbarQueue.d.ts +25 -47
  69. package/lib/components/VSnackbarQueue/VSnackbarQueue.js.map +1 -1
  70. package/lib/components/VSpeedDial/VSpeedDial.d.ts +1434 -80
  71. package/lib/components/VTable/VTable.css +2 -6
  72. package/lib/components/VTable/VTable.sass +4 -22
  73. package/lib/components/VTabs/VTabs.d.ts +6 -6
  74. package/lib/components/VTextField/VTextField.js +5 -3
  75. package/lib/components/VTextField/VTextField.js.map +1 -1
  76. package/lib/components/VTooltip/VTooltip.d.ts +58 -109
  77. package/lib/components/VTooltip/VTooltip.js +2 -2
  78. package/lib/components/VTooltip/VTooltip.js.map +1 -1
  79. package/lib/components/transitions/dialog-transition.js +3 -3
  80. package/lib/components/transitions/dialog-transition.js.map +1 -1
  81. package/lib/composables/dateFormat.d.ts +24 -0
  82. package/lib/composables/dateFormat.js +112 -0
  83. package/lib/composables/dateFormat.js.map +1 -0
  84. package/lib/composables/transition.d.ts +10 -20
  85. package/lib/composables/transition.js +15 -12
  86. package/lib/composables/transition.js.map +1 -1
  87. package/lib/entry-bundler.d.ts +6 -6
  88. package/lib/entry-bundler.js +1 -1
  89. package/lib/framework.d.ts +113 -149
  90. package/lib/framework.js +1 -1
  91. package/lib/iconsets/mdi.js +2 -1
  92. package/lib/iconsets/mdi.js.map +1 -1
  93. package/lib/labs/VCalendar/VCalendar.d.ts +3 -3
  94. package/lib/labs/VCalendar/VCalendarDay.d.ts +3 -3
  95. package/lib/labs/VCalendar/VCalendarInterval.d.ts +3 -3
  96. package/lib/labs/VCalendar/VCalendarMonthDay.d.ts +3 -3
  97. package/lib/labs/VColorInput/VColorInput.css +4 -0
  98. package/lib/labs/VColorInput/VColorInput.d.ts +1767 -0
  99. package/lib/labs/VColorInput/VColorInput.js +129 -0
  100. package/lib/labs/VColorInput/VColorInput.js.map +1 -0
  101. package/lib/labs/VColorInput/VColorInput.sass +7 -0
  102. package/lib/labs/VColorInput/_variables.scss +2 -0
  103. package/lib/labs/VColorInput/index.d.ts +1 -0
  104. package/lib/labs/VColorInput/index.js +2 -0
  105. package/lib/labs/VColorInput/index.js.map +1 -0
  106. package/lib/labs/VDateInput/VDateInput.d.ts +96 -34
  107. package/lib/labs/VDateInput/VDateInput.js +71 -17
  108. package/lib/labs/VDateInput/VDateInput.js.map +1 -1
  109. package/lib/labs/VFileUpload/VFileUpload.js +19 -31
  110. package/lib/labs/VFileUpload/VFileUpload.js.map +1 -1
  111. package/lib/labs/VTimePicker/VTimePickerClock.js +2 -2
  112. package/lib/labs/VTimePicker/VTimePickerClock.js.map +1 -1
  113. package/lib/labs/components.d.ts +1 -0
  114. package/lib/labs/components.js +1 -0
  115. package/lib/labs/components.js.map +1 -1
  116. package/lib/util/helpers.js.map +1 -1
  117. package/package.json +7 -8
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.8.3
2
+ * Vuetify v3.8.5
3
3
  * Forged by John Leider
4
4
  * Released under the MIT License.
5
5
  */
@@ -2927,10 +2927,10 @@
2927
2927
  async onLeave(el, done) {
2928
2928
  await new Promise(resolve => requestAnimationFrame(resolve));
2929
2929
  let dimensions;
2930
- if (!Array.isArray(props.target) && !props.target.offsetParent && saved.has(el)) {
2931
- dimensions = saved.get(el);
2932
- } else {
2930
+ if (!saved.has(el) || Array.isArray(props.target) || props.target.offsetParent || props.target.getClientRects().length) {
2933
2931
  dimensions = getDimensions(props.target, el);
2932
+ } else {
2933
+ dimensions = saved.get(el);
2934
2934
  }
2935
2935
  const {
2936
2936
  x,
@@ -3255,7 +3255,7 @@
3255
3255
 
3256
3256
  const makeTransitionProps = propsFactory({
3257
3257
  transition: {
3258
- type: [Boolean, String, Object],
3258
+ type: null,
3259
3259
  default: 'fade-transition',
3260
3260
  validator: val => val !== true
3261
3261
  }
@@ -3273,16 +3273,19 @@
3273
3273
  const {
3274
3274
  component = group ? vue.TransitionGroup : vue.Transition,
3275
3275
  ...customProps
3276
- } = typeof transition === 'object' ? transition : {};
3277
- return vue.h(component, vue.mergeProps(typeof transition === 'string' ? {
3278
- name: disabled ? '' : transition
3279
- } : customProps, typeof transition === 'string' ? {} : Object.fromEntries(Object.entries({
3280
- disabled,
3281
- group
3282
- }).filter(_ref2 => {
3283
- let [_, v] = _ref2;
3284
- return v !== undefined;
3285
- })), rest), slots);
3276
+ } = isObject(transition) ? transition : {};
3277
+ let transitionProps;
3278
+ if (isObject(transition)) {
3279
+ transitionProps = vue.mergeProps(customProps, JSON.parse(JSON.stringify({
3280
+ disabled,
3281
+ group
3282
+ })), rest);
3283
+ } else {
3284
+ transitionProps = vue.mergeProps({
3285
+ name: disabled || !transition ? '' : transition
3286
+ }, rest);
3287
+ }
3288
+ return vue.h(component, transitionProps, slots);
3286
3289
  };
3287
3290
 
3288
3291
  // Utilities
@@ -4507,7 +4510,8 @@
4507
4510
  treeviewCollapse: 'mdi-menu-down',
4508
4511
  treeviewExpand: 'mdi-menu-right',
4509
4512
  eyeDropper: 'mdi-eyedropper',
4510
- upload: 'mdi-cloud-upload'
4513
+ upload: 'mdi-cloud-upload',
4514
+ color: 'mdi-palette'
4511
4515
  };
4512
4516
  const mdi = {
4513
4517
  // Not using mergeProps here, functional components merge props by default (?)
@@ -10165,7 +10169,7 @@
10165
10169
  observe = false;
10166
10170
  requestAnimationFrame(() => observe = true);
10167
10171
  if (!data.target.value || !data.contentEl.value) return;
10168
- if (Array.isArray(data.target.value) || data.target.value.offsetParent) {
10172
+ if (Array.isArray(data.target.value) || data.target.value.offsetParent || data.target.value.getClientRects().length) {
10169
10173
  targetBox = getTargetBox(data.target.value);
10170
10174
  } // Otherwise target element is hidden, use last known value
10171
10175
 
@@ -12085,11 +12089,12 @@
12085
12089
  onFocus();
12086
12090
  emit('click:control', e);
12087
12091
  }
12088
- function onClear(e) {
12092
+ function onClear(e, reset) {
12089
12093
  e.stopPropagation();
12090
12094
  onFocus();
12091
12095
  vue.nextTick(() => {
12092
12096
  model.value = null;
12097
+ reset();
12093
12098
  callEvent(props['onClick:clear'], e);
12094
12099
  });
12095
12100
  }
@@ -12134,13 +12139,14 @@
12134
12139
  isDisabled,
12135
12140
  isDirty,
12136
12141
  isReadonly,
12137
- isValid
12142
+ isValid,
12143
+ reset
12138
12144
  } = _ref2;
12139
12145
  return vue.createVNode(VField, vue.mergeProps({
12140
12146
  "ref": vFieldRef,
12141
12147
  "onMousedown": onControlMousedown,
12142
12148
  "onClick": onControlClick,
12143
- "onClick:clear": onClear,
12149
+ "onClick:clear": e => onClear(e, reset),
12144
12150
  "onClick:prependInner": props['onClick:prependInner'],
12145
12151
  "onClick:appendInner": props['onClick:appendInner'],
12146
12152
  "role": props.role
@@ -14120,7 +14126,7 @@
14120
14126
  }
14121
14127
  function onAfterEnter() {
14122
14128
  emit('afterEnter');
14123
- if (overlay.value?.contentEl && !overlay.value.contentEl.contains(document.activeElement)) {
14129
+ if ((props.scrim || props.retainFocus) && overlay.value?.contentEl && !overlay.value.contentEl.contains(document.activeElement)) {
14124
14130
  overlay.value.contentEl.focus({
14125
14131
  preventScroll: true
14126
14132
  });
@@ -18992,7 +18998,7 @@
18992
18998
  index = index ?? currentPage.value.findIndex(i => i.value === item.value);
18993
18999
  if (props.selectStrategy !== 'single' && event?.shiftKey && lastSelectedIndex.value !== null) {
18994
19000
  const [start, end] = [lastSelectedIndex.value, index].sort((a, b) => a - b);
18995
- items.push(...currentPage.value.slice(start, end + 1));
19001
+ items.push(...currentPage.value.slice(start, end + 1).filter(item => item.selectable));
18996
19002
  } else {
18997
19003
  items.push(item);
18998
19004
  lastSelectedIndex.value = index;
@@ -20328,7 +20334,6 @@
20328
20334
  });
20329
20335
  };
20330
20336
  const VDataTableMobileHeaderCell = () => {
20331
- const headerProps = vue.mergeProps(props.headerProps ?? {} ?? {});
20332
20337
  const displayItems = vue.computed(() => {
20333
20338
  return columns.value.filter(column => column?.sortable && !props.disableSort);
20334
20339
  });
@@ -20341,7 +20346,7 @@
20341
20346
  "tag": "th",
20342
20347
  "class": [...headerCellClasses.value],
20343
20348
  "colspan": headers.value.length + 1
20344
- }, headerProps), {
20349
+ }, props.headerProps), {
20345
20350
  default: () => [vue.createVNode("div", {
20346
20351
  "class": "v-data-table-header__content"
20347
20352
  }, [vue.createVNode(VSelect, {
@@ -23264,6 +23269,7 @@
23264
23269
  const inputRef = vue.ref();
23265
23270
  const isActive = vue.toRef(() => isFocused.value || props.active);
23266
23271
  const isPlainOrUnderlined = vue.computed(() => ['plain', 'underlined'].includes(props.variant));
23272
+ const isDragging = vue.shallowRef(false);
23267
23273
  function onFocus() {
23268
23274
  if (inputRef.value !== document.activeElement) {
23269
23275
  inputRef.value?.focus();
@@ -23290,11 +23296,26 @@
23290
23296
  }
23291
23297
  function onDragover(e) {
23292
23298
  e.preventDefault();
23299
+ e.stopImmediatePropagation();
23300
+ isDragging.value = true;
23301
+ }
23302
+ function onDragleave(e) {
23303
+ e.preventDefault();
23304
+ isDragging.value = false;
23293
23305
  }
23294
23306
  function onDrop(e) {
23295
23307
  e.preventDefault();
23296
- if (!e.dataTransfer) return;
23297
- model.value = [...(e.dataTransfer.files ?? [])];
23308
+ e.stopImmediatePropagation();
23309
+ isDragging.value = false;
23310
+ if (!e.dataTransfer?.files?.length || !inputRef.value) return;
23311
+ const dataTransfer = new DataTransfer();
23312
+ for (const file of e.dataTransfer.files) {
23313
+ dataTransfer.items.add(file);
23314
+ }
23315
+ inputRef.value.files = dataTransfer.files;
23316
+ inputRef.value.dispatchEvent(new Event('change', {
23317
+ bubbles: true
23318
+ }));
23298
23319
  }
23299
23320
  vue.watch(model, newValue => {
23300
23321
  const hasModelReset = !Array.isArray(newValue) || !newValue.length;
@@ -23316,6 +23337,7 @@
23316
23337
  "modelValue": props.multiple ? model.value : model.value[0],
23317
23338
  "class": ['v-file-input', {
23318
23339
  'v-file-input--chips': !!props.chips,
23340
+ 'v-file-input--dragging': isDragging.value,
23319
23341
  'v-file-input--hide': props.hideInput,
23320
23342
  'v-input--plain-underlined': isPlainOrUnderlined.value
23321
23343
  }, props.class],
@@ -23377,6 +23399,7 @@
23377
23399
  const target = e.target;
23378
23400
  model.value = [...(target.files ?? [])];
23379
23401
  },
23402
+ "onDragleave": onDragleave,
23380
23403
  "onFocus": onFocus,
23381
23404
  "onBlur": blur
23382
23405
  }, slotProps, inputAttrs), null), vue.createVNode("div", {
@@ -28364,7 +28387,7 @@
28364
28387
  origin: 'auto',
28365
28388
  scrim: false,
28366
28389
  scrollStrategy: 'reposition',
28367
- transition: false
28390
+ transition: null
28368
28391
  }), ['absolute', 'persistent'])
28369
28392
  }, 'VTooltip');
28370
28393
  const VTooltip = genericComponent()({
@@ -28391,7 +28414,7 @@
28391
28414
  return props.origin === 'auto' || props.origin === 'overlap' || props.origin.split(' ').length > 1 || props.location.split(' ').length > 1 ? props.origin : props.origin + ' center';
28392
28415
  });
28393
28416
  const transition = vue.toRef(() => {
28394
- if (props.transition) return props.transition;
28417
+ if (props.transition != null) return props.transition;
28395
28418
  return isActive.value ? 'scale-transition' : 'fade-transition';
28396
28419
  });
28397
28420
  const activatorProps = vue.computed(() => vue.mergeProps({
@@ -29054,6 +29077,236 @@
29054
29077
 
29055
29078
  // Types
29056
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
+
29057
29310
  // Types
29058
29311
 
29059
29312
  const makeVDateInputProps = propsFactory({
@@ -29062,13 +29315,20 @@
29062
29315
  type: String,
29063
29316
  default: 'bottom start'
29064
29317
  },
29065
- ...makeDisplayProps(),
29318
+ menu: Boolean,
29319
+ updateOn: {
29320
+ type: Array,
29321
+ default: () => ['blur', 'enter']
29322
+ },
29323
+ ...makeDateFormatProps(),
29324
+ ...makeDisplayProps({
29325
+ mobile: null
29326
+ }),
29066
29327
  ...makeFocusProps(),
29067
29328
  ...makeVConfirmEditProps({
29068
29329
  hideActions: true
29069
29330
  }),
29070
29331
  ...makeVTextFieldProps({
29071
- placeholder: 'mm/dd/yyyy',
29072
29332
  prependIcon: '$calendar'
29073
29333
  }),
29074
29334
  ...omit(makeVDatePickerProps({
@@ -29082,7 +29342,8 @@
29082
29342
  emits: {
29083
29343
  save: value => true,
29084
29344
  cancel: () => true,
29085
- 'update:modelValue': val => true
29345
+ 'update:modelValue': val => true,
29346
+ 'update:menu': val => true
29086
29347
  },
29087
29348
  setup(props, _ref) {
29088
29349
  let {
@@ -29090,9 +29351,16 @@
29090
29351
  slots
29091
29352
  } = _ref;
29092
29353
  const {
29093
- t
29354
+ t,
29355
+ current: currentLocale
29094
29356
  } = useLocale();
29095
29357
  const adapter = useDate();
29358
+ const {
29359
+ isValid,
29360
+ parseDate,
29361
+ formatDate,
29362
+ parserFormat
29363
+ } = useDateFormat(props, currentLocale);
29096
29364
  const {
29097
29365
  mobile
29098
29366
  } = useDisplay(props);
@@ -29101,8 +29369,9 @@
29101
29369
  focus,
29102
29370
  blur
29103
29371
  } = useFocus(props);
29104
- const model = useProxiedModel(props, 'modelValue', props.multiple ? [] : null, 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);
29105
- const menu = vue.shallowRef(false);
29372
+ const emptyModelValue = () => props.multiple ? [] : null;
29373
+ 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);
29374
+ const menu = useProxiedModel(props, 'menu');
29106
29375
  const isEditingInput = vue.shallowRef(false);
29107
29376
  const vTextFieldRef = vue.ref();
29108
29377
  const disabledActions = vue.ref(['save']);
@@ -29110,7 +29379,10 @@
29110
29379
  if (typeof props.displayFormat === 'function') {
29111
29380
  return props.displayFormat(date);
29112
29381
  }
29113
- return adapter.format(date, props.displayFormat ?? 'keyboardDate');
29382
+ if (props.displayFormat) {
29383
+ return adapter.format(date, props.displayFormat ?? 'keyboardDate');
29384
+ }
29385
+ return formatDate(date);
29114
29386
  }
29115
29387
  const display = vue.computed(() => {
29116
29388
  const value = wrapInArray(model.value);
@@ -29132,7 +29404,10 @@
29132
29404
  return 'none';
29133
29405
  });
29134
29406
  const isInteractive = vue.computed(() => !props.disabled && !props.readonly);
29135
- const isReadonly = vue.computed(() => !(mobile.value && isEditingInput.value) && props.readonly);
29407
+ const isReadonly = vue.computed(() => {
29408
+ if (!props.updateOn.length) return true;
29409
+ return !(mobile.value && isEditingInput.value) && props.readonly;
29410
+ });
29136
29411
  vue.watch(menu, val => {
29137
29412
  if (val) return;
29138
29413
  isEditingInput.value = false;
@@ -29142,10 +29417,10 @@
29142
29417
  if (e.key !== 'Enter') return;
29143
29418
  if (!menu.value || !isFocused.value) {
29144
29419
  menu.value = true;
29145
- return;
29146
29420
  }
29147
- const target = e.target;
29148
- model.value = adapter.isValid(target.value) ? target.value : null;
29421
+ if (props.updateOn.includes('enter')) {
29422
+ onUserInput(e.target);
29423
+ }
29149
29424
  }
29150
29425
  function onClick(e) {
29151
29426
  e.preventDefault();
@@ -29167,9 +29442,12 @@
29167
29442
  }
29168
29443
  function onUpdateDisplayModel(value) {
29169
29444
  if (value != null) return;
29170
- model.value = null;
29445
+ model.value = emptyModelValue();
29171
29446
  }
29172
- function onBlur() {
29447
+ function onBlur(e) {
29448
+ if (props.updateOn.includes('blur')) {
29449
+ onUserInput(e.target);
29450
+ }
29173
29451
  blur();
29174
29452
 
29175
29453
  // When in mobile mode and editing is done (due to keyboard dismissal), close the menu
@@ -29178,10 +29456,36 @@
29178
29456
  isEditingInput.value = false;
29179
29457
  }
29180
29458
  }
29459
+ function onUserInput(_ref2) {
29460
+ let {
29461
+ value
29462
+ } = _ref2;
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))];
29484
+ }
29181
29485
  useRender(() => {
29182
29486
  const confirmEditProps = VConfirmEdit.filterProps(props);
29183
29487
  const datePickerProps = VDatePicker.filterProps(omit(props, ['active', 'location', 'rounded']));
29184
- const textFieldProps = VTextField.filterProps(props);
29488
+ const textFieldProps = VTextField.filterProps(omit(props, ['placeholder']));
29185
29489
  return vue.createVNode(VTextField, vue.mergeProps({
29186
29490
  "ref": vTextFieldRef
29187
29491
  }, textFieldProps, {
@@ -29189,11 +29493,13 @@
29189
29493
  "style": props.style,
29190
29494
  "modelValue": display.value,
29191
29495
  "inputmode": inputmode.value,
29496
+ "placeholder": props.placeholder ?? parserFormat.value,
29192
29497
  "readonly": isReadonly.value,
29193
29498
  "onKeydown": isInteractive.value ? onKeydown : undefined,
29194
29499
  "focused": menu.value || isFocused.value,
29195
29500
  "onFocus": focus,
29196
29501
  "onBlur": onBlur,
29502
+ "validationValue": model.value,
29197
29503
  "onClick:control": isInteractive.value ? onClick : undefined,
29198
29504
  "onClick:prepend": isInteractive.value ? onClick : undefined,
29199
29505
  "onUpdate:modelValue": onUpdateDisplayModel
@@ -29216,14 +29522,14 @@
29216
29522
  "onSave": onSave,
29217
29523
  "onCancel": onCancel
29218
29524
  }), {
29219
- default: _ref2 => {
29525
+ default: _ref3 => {
29220
29526
  let {
29221
29527
  actions,
29222
29528
  model: proxyModel,
29223
29529
  save,
29224
29530
  cancel,
29225
29531
  isPristine
29226
- } = _ref2;
29532
+ } = _ref3;
29227
29533
  function onUpdateModel(value) {
29228
29534
  if (!props.hideActions) {
29229
29535
  proxyModel.value = value;
@@ -29408,43 +29714,31 @@
29408
29714
  densityClasses
29409
29715
  } = useDensity(props);
29410
29716
  const model = useProxiedModel(props, 'modelValue', props.modelValue, val => wrapInArray(val), val => props.multiple || Array.isArray(props.modelValue) ? val : val[0]);
29411
- const dragOver = vue.shallowRef(false);
29717
+ const isDragging = vue.shallowRef(false);
29412
29718
  const vSheetRef = vue.ref(null);
29413
29719
  const inputRef = vue.ref(null);
29414
- vue.onMounted(() => {
29415
- vSheetRef.value?.$el.addEventListener('dragover', onDragOver);
29416
- vSheetRef.value?.$el.addEventListener('drop', onDrop);
29417
- });
29418
- vue.onUnmounted(() => {
29419
- vSheetRef.value?.$el.removeEventListener('dragover', onDragOver);
29420
- vSheetRef.value?.$el.removeEventListener('drop', onDrop);
29421
- });
29422
- function onDragOver(e) {
29720
+ function onDragover(e) {
29423
29721
  e.preventDefault();
29424
29722
  e.stopImmediatePropagation();
29425
- dragOver.value = true;
29723
+ isDragging.value = true;
29426
29724
  }
29427
- function onDragLeave(e) {
29725
+ function onDragleave(e) {
29428
29726
  e.preventDefault();
29429
- dragOver.value = false;
29727
+ isDragging.value = false;
29430
29728
  }
29431
29729
  function onDrop(e) {
29432
29730
  e.preventDefault();
29433
29731
  e.stopImmediatePropagation();
29434
- dragOver.value = false;
29435
- const files = Array.from(e.dataTransfer?.files ?? []);
29436
- if (!files.length) return;
29437
- if (!props.multiple) {
29438
- model.value = [files[0]];
29439
- return;
29440
- }
29441
- const array = model.value.slice();
29442
- for (const file of files) {
29443
- if (!array.some(f => f.name === file.name)) {
29444
- array.push(file);
29445
- }
29446
- }
29447
- model.value = array;
29732
+ isDragging.value = false;
29733
+ if (!e.dataTransfer?.files?.length || !inputRef.value) return;
29734
+ const dataTransfer = new DataTransfer();
29735
+ for (const file of e.dataTransfer.files) {
29736
+ dataTransfer.items.add(file);
29737
+ }
29738
+ inputRef.value.files = dataTransfer.files;
29739
+ inputRef.value.dispatchEvent(new Event('change', {
29740
+ bubbles: true
29741
+ }));
29448
29742
  }
29449
29743
  function onClick() {
29450
29744
  inputRef.value?.click();
@@ -29480,11 +29774,11 @@
29480
29774
  "class": ['v-file-upload', {
29481
29775
  'v-file-upload--clickable': !hasBrowse,
29482
29776
  'v-file-upload--disabled': props.disabled,
29483
- 'v-file-upload--dragging': dragOver.value
29777
+ 'v-file-upload--dragging': isDragging.value
29484
29778
  }, densityClasses.value, props.class],
29485
29779
  "style": [props.style],
29486
- "onDragleave": onDragLeave,
29487
- "onDragover": onDragOver,
29780
+ "onDragleave": onDragleave,
29781
+ "onDragover": onDragover,
29488
29782
  "onDrop": onDrop,
29489
29783
  "onClick": !hasBrowse ? onClick : undefined
29490
29784
  }, rootAttrs), {
@@ -29535,7 +29829,7 @@
29535
29829
  })]), props.subtitle && vue.createVNode("div", {
29536
29830
  "class": "v-file-upload-subtitle"
29537
29831
  }, [props.subtitle])]), vue.createVNode(VOverlay, {
29538
- "model-value": dragOver.value,
29832
+ "model-value": isDragging.value,
29539
29833
  "contained": true,
29540
29834
  "scrim": props.scrim
29541
29835
  }, null), slots.input?.({
@@ -30233,8 +30527,8 @@
30233
30527
  y
30234
30528
  } = getPosition(i);
30235
30529
  return {
30236
- left: `${50 + x * 50}%`,
30237
- top: `${50 + y * 50}%`
30530
+ left: `${Math.round(50 + x * 50)}%`,
30531
+ top: `${Math.round(50 + y * 50)}%`
30238
30532
  };
30239
30533
  }
30240
30534
  function euclidean(p0, p1) {
@@ -31172,6 +31466,7 @@
31172
31466
  VClassIcon: VClassIcon,
31173
31467
  VCode: VCode,
31174
31468
  VCol: VCol,
31469
+ VColorInput: VColorInput,
31175
31470
  VColorPicker: VColorPicker,
31176
31471
  VCombobox: VCombobox,
31177
31472
  VComponentIcon: VComponentIcon,
@@ -31638,7 +31933,7 @@
31638
31933
  };
31639
31934
  });
31640
31935
  }
31641
- const version$1 = "3.8.3";
31936
+ const version$1 = "3.8.5";
31642
31937
  createVuetify$1.version = version$1;
31643
31938
 
31644
31939
  // Vue's inject() can only be used in setup
@@ -31936,7 +32231,7 @@
31936
32231
 
31937
32232
  /* eslint-disable local-rules/sort-imports */
31938
32233
 
31939
- const version = "3.8.3";
32234
+ const version = "3.8.5";
31940
32235
 
31941
32236
  /* eslint-disable local-rules/sort-imports */
31942
32237