@vuetify/nightly 3.9.5-dev.2025-08-12 → 3.9.5-dev.2025-08-24

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 (40) hide show
  1. package/CHANGELOG.md +6 -3
  2. package/dist/json/attributes.json +2183 -2175
  3. package/dist/json/importMap-labs.json +40 -40
  4. package/dist/json/importMap.json +156 -156
  5. package/dist/json/tags.json +4 -1
  6. package/dist/json/web-types.json +4199 -4178
  7. package/dist/vuetify-labs.cjs +202 -98
  8. package/dist/vuetify-labs.css +5261 -5261
  9. package/dist/vuetify-labs.d.ts +112 -84
  10. package/dist/vuetify-labs.esm.js +202 -98
  11. package/dist/vuetify-labs.esm.js.map +1 -1
  12. package/dist/vuetify-labs.js +202 -98
  13. package/dist/vuetify-labs.min.css +2 -2
  14. package/dist/vuetify.cjs +85 -65
  15. package/dist/vuetify.cjs.map +1 -1
  16. package/dist/vuetify.css +2218 -2218
  17. package/dist/vuetify.d.ts +91 -63
  18. package/dist/vuetify.esm.js +85 -65
  19. package/dist/vuetify.esm.js.map +1 -1
  20. package/dist/vuetify.js +85 -65
  21. package/dist/vuetify.js.map +1 -1
  22. package/dist/vuetify.min.css +2 -2
  23. package/dist/vuetify.min.js +367 -366
  24. package/dist/vuetify.min.js.map +1 -1
  25. package/lib/components/VCard/VCardActions.d.ts +44 -0
  26. package/lib/components/VCard/VCardActions.js +11 -6
  27. package/lib/components/VCard/VCardActions.js.map +1 -1
  28. package/lib/components/VCard/VCardItem.d.ts +25 -0
  29. package/lib/components/VCard/VCardItem.js +64 -60
  30. package/lib/components/VCard/VCardItem.js.map +1 -1
  31. package/lib/composables/filter.d.ts +1 -0
  32. package/lib/composables/filter.js +13 -0
  33. package/lib/composables/filter.js.map +1 -1
  34. package/lib/entry-bundler.js +1 -1
  35. package/lib/framework.d.ts +63 -63
  36. package/lib/framework.js +1 -1
  37. package/lib/labs/VMaskInput/VMaskInput.d.ts +22 -21
  38. package/lib/labs/VMaskInput/VMaskInput.js +118 -34
  39. package/lib/labs/VMaskInput/VMaskInput.js.map +1 -1
  40. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.9.5-dev.2025-08-12
2
+ * Vuetify v3.9.5-dev.2025-08-24
3
3
  * Forged by John Leider
4
4
  * Released under the MIT License.
5
5
  */
@@ -13747,6 +13747,7 @@
13747
13747
  const keys = options?.filterKeys ? wrapInArray(options.filterKeys) : false;
13748
13748
  const customFiltersLength = Object.keys(options?.customKeyFilter ?? {}).length;
13749
13749
  if (!items?.length) return array;
13750
+ let lookAheadItem = null;
13750
13751
  loop: for (let i = 0; i < items.length; i++) {
13751
13752
  const [item, transformed = item] = wrapInArray(items[i]);
13752
13753
  const customMatches = {};
@@ -13755,6 +13756,14 @@
13755
13756
  if ((query || customFiltersLength > 0) && !options?.noFilter) {
13756
13757
  if (typeof item === 'object') {
13757
13758
  if (item.type === 'divider' || item.type === 'subheader') {
13759
+ if (lookAheadItem?.type === 'divider' && item.type === 'subheader') {
13760
+ array.push(lookAheadItem); // divider before subheader
13761
+ }
13762
+ lookAheadItem = {
13763
+ index: i,
13764
+ matches: {},
13765
+ type: item.type
13766
+ };
13758
13767
  continue;
13759
13768
  }
13760
13769
  const filterKeys = keys || Object.keys(transformed);
@@ -13780,6 +13789,10 @@
13780
13789
  if (options?.filterMode === 'union' && customMatchesLength !== customFiltersLength && !defaultMatchesLength) continue;
13781
13790
  if (options?.filterMode === 'intersection' && (customMatchesLength !== customFiltersLength || !defaultMatchesLength)) continue;
13782
13791
  }
13792
+ if (lookAheadItem) {
13793
+ array.push(lookAheadItem);
13794
+ lookAheadItem = null;
13795
+ }
13783
13796
  array.push({
13784
13797
  index: i,
13785
13798
  matches: {
@@ -15040,9 +15053,13 @@
15040
15053
  }
15041
15054
  });
15042
15055
 
15056
+ const makeVCardActionsProps = propsFactory({
15057
+ ...makeComponentProps(),
15058
+ ...makeTagProps()
15059
+ }, 'VCardActions');
15043
15060
  const VCardActions = genericComponent()({
15044
15061
  name: 'VCardActions',
15045
- props: makeComponentProps(),
15062
+ props: makeVCardActionsProps(),
15046
15063
  setup(props, _ref) {
15047
15064
  let {
15048
15065
  slots
@@ -15053,10 +15070,10 @@
15053
15070
  variant: 'text'
15054
15071
  }
15055
15072
  });
15056
- useRender(() => vue.createElementVNode("div", {
15073
+ useRender(() => vue.createVNode(props.tag, {
15057
15074
  "class": vue.normalizeClass(['v-card-actions', props.class]),
15058
15075
  "style": vue.normalizeStyle(props.style)
15059
- }, [slots.default?.()]));
15076
+ }, slots));
15060
15077
  return {};
15061
15078
  }
15062
15079
  });
@@ -15100,7 +15117,8 @@
15100
15117
  default: undefined
15101
15118
  },
15102
15119
  ...makeComponentProps(),
15103
- ...makeDensityProps()
15120
+ ...makeDensityProps(),
15121
+ ...makeTagProps()
15104
15122
  }, 'VCardItem');
15105
15123
  const VCardItem = genericComponent()({
15106
15124
  name: 'VCardItem',
@@ -15116,68 +15134,70 @@
15116
15134
  const hasAppend = !!(hasAppendMedia || slots.append);
15117
15135
  const hasTitle = !!(props.title != null || slots.title);
15118
15136
  const hasSubtitle = !!(props.subtitle != null || slots.subtitle);
15119
- return vue.createElementVNode("div", {
15137
+ return vue.createVNode(props.tag, {
15120
15138
  "class": vue.normalizeClass(['v-card-item', props.class]),
15121
15139
  "style": vue.normalizeStyle(props.style)
15122
- }, [hasPrepend && vue.createElementVNode("div", {
15123
- "key": "prepend",
15124
- "class": "v-card-item__prepend"
15125
- }, [!slots.prepend ? vue.createElementVNode(vue.Fragment, null, [props.prependAvatar && vue.createVNode(VAvatar, {
15126
- "key": "prepend-avatar",
15127
- "density": props.density,
15128
- "image": props.prependAvatar
15129
- }, null), props.prependIcon && vue.createVNode(VIcon, {
15130
- "key": "prepend-icon",
15131
- "density": props.density,
15132
- "icon": props.prependIcon
15133
- }, null)]) : vue.createVNode(VDefaultsProvider, {
15134
- "key": "prepend-defaults",
15135
- "disabled": !hasPrependMedia,
15136
- "defaults": {
15137
- VAvatar: {
15138
- density: props.density,
15139
- image: props.prependAvatar
15140
- },
15141
- VIcon: {
15142
- density: props.density,
15143
- icon: props.prependIcon
15144
- }
15145
- }
15146
- }, slots.prepend)]), vue.createElementVNode("div", {
15147
- "class": "v-card-item__content"
15148
- }, [hasTitle && vue.createVNode(VCardTitle, {
15149
- "key": "title"
15150
15140
  }, {
15151
- default: () => [slots.title?.() ?? vue.toDisplayString(props.title)]
15152
- }), hasSubtitle && vue.createVNode(VCardSubtitle, {
15153
- "key": "subtitle"
15154
- }, {
15155
- default: () => [slots.subtitle?.() ?? vue.toDisplayString(props.subtitle)]
15156
- }), slots.default?.()]), hasAppend && vue.createElementVNode("div", {
15157
- "key": "append",
15158
- "class": "v-card-item__append"
15159
- }, [!slots.append ? vue.createElementVNode(vue.Fragment, null, [props.appendIcon && vue.createVNode(VIcon, {
15160
- "key": "append-icon",
15161
- "density": props.density,
15162
- "icon": props.appendIcon
15163
- }, null), props.appendAvatar && vue.createVNode(VAvatar, {
15164
- "key": "append-avatar",
15165
- "density": props.density,
15166
- "image": props.appendAvatar
15167
- }, null)]) : vue.createVNode(VDefaultsProvider, {
15168
- "key": "append-defaults",
15169
- "disabled": !hasAppendMedia,
15170
- "defaults": {
15171
- VAvatar: {
15172
- density: props.density,
15173
- image: props.appendAvatar
15174
- },
15175
- VIcon: {
15176
- density: props.density,
15177
- icon: props.appendIcon
15141
+ default: () => [hasPrepend && vue.createElementVNode("div", {
15142
+ "key": "prepend",
15143
+ "class": "v-card-item__prepend"
15144
+ }, [!slots.prepend ? vue.createElementVNode(vue.Fragment, null, [props.prependAvatar && vue.createVNode(VAvatar, {
15145
+ "key": "prepend-avatar",
15146
+ "density": props.density,
15147
+ "image": props.prependAvatar
15148
+ }, null), props.prependIcon && vue.createVNode(VIcon, {
15149
+ "key": "prepend-icon",
15150
+ "density": props.density,
15151
+ "icon": props.prependIcon
15152
+ }, null)]) : vue.createVNode(VDefaultsProvider, {
15153
+ "key": "prepend-defaults",
15154
+ "disabled": !hasPrependMedia,
15155
+ "defaults": {
15156
+ VAvatar: {
15157
+ density: props.density,
15158
+ image: props.prependAvatar
15159
+ },
15160
+ VIcon: {
15161
+ density: props.density,
15162
+ icon: props.prependIcon
15163
+ }
15178
15164
  }
15179
- }
15180
- }, slots.append)])]);
15165
+ }, slots.prepend)]), vue.createElementVNode("div", {
15166
+ "class": "v-card-item__content"
15167
+ }, [hasTitle && vue.createVNode(VCardTitle, {
15168
+ "key": "title"
15169
+ }, {
15170
+ default: () => [slots.title?.() ?? vue.toDisplayString(props.title)]
15171
+ }), hasSubtitle && vue.createVNode(VCardSubtitle, {
15172
+ "key": "subtitle"
15173
+ }, {
15174
+ default: () => [slots.subtitle?.() ?? vue.toDisplayString(props.subtitle)]
15175
+ }), slots.default?.()]), hasAppend && vue.createElementVNode("div", {
15176
+ "key": "append",
15177
+ "class": "v-card-item__append"
15178
+ }, [!slots.append ? vue.createElementVNode(vue.Fragment, null, [props.appendIcon && vue.createVNode(VIcon, {
15179
+ "key": "append-icon",
15180
+ "density": props.density,
15181
+ "icon": props.appendIcon
15182
+ }, null), props.appendAvatar && vue.createVNode(VAvatar, {
15183
+ "key": "append-avatar",
15184
+ "density": props.density,
15185
+ "image": props.appendAvatar
15186
+ }, null)]) : vue.createVNode(VDefaultsProvider, {
15187
+ "key": "append-defaults",
15188
+ "disabled": !hasAppendMedia,
15189
+ "defaults": {
15190
+ VAvatar: {
15191
+ density: props.density,
15192
+ image: props.appendAvatar
15193
+ },
15194
+ VIcon: {
15195
+ density: props.density,
15196
+ icon: props.appendIcon
15197
+ }
15198
+ }
15199
+ }, slots.append)])]
15200
+ });
15181
15201
  });
15182
15202
  return {};
15183
15203
  }
@@ -33009,59 +33029,140 @@
33009
33029
  emit
33010
33030
  } = _ref;
33011
33031
  const vTextFieldRef = vue.ref();
33012
- const selection = vue.shallowRef(0);
33013
- const lazySelection = vue.shallowRef(0);
33032
+ const inputAction = vue.shallowRef();
33033
+ const caretPosition = vue.shallowRef(0);
33014
33034
  const mask = useMask(props);
33015
33035
  const returnMaskedValue = vue.computed(() => props.mask && props.returnMaskedValue);
33016
33036
  const model = useProxiedModel(props, 'modelValue', undefined,
33017
33037
  // Always display masked value in input when mask is applied
33018
33038
  val => props.mask ? mask.mask(mask.unmask(val)) : val, val => {
33019
33039
  if (props.mask) {
33020
- const valueBeforeChange = mask.unmask(model.value);
33040
+ const valueWithoutDelimiters = removeMaskDelimiters(val);
33041
+
33021
33042
  // E.g. mask is #-# and the input value is '2-23'
33022
33043
  // model-value should be enforced to '2-2'
33023
- const enforcedMaskedValue = mask.mask(mask.unmask(val));
33024
- const newUnmaskedValue = mask.unmask(enforcedMaskedValue);
33025
- if (newUnmaskedValue === valueBeforeChange) {
33026
- vTextFieldRef.value.value = enforcedMaskedValue;
33027
- }
33028
- val = newUnmaskedValue;
33029
- updateRange();
33030
- return returnMaskedValue.value ? mask.mask(val) : val;
33044
+ const newMaskedValue = mask.mask(valueWithoutDelimiters);
33045
+ const newUnmaskedValue = mask.unmask(newMaskedValue);
33046
+ const newCaretPosition = getNewCaretPosition({
33047
+ oldValue: model.value,
33048
+ newValue: newMaskedValue,
33049
+ oldCaret: caretPosition.value
33050
+ });
33051
+ vTextFieldRef.value.value = newMaskedValue;
33052
+ vTextFieldRef.value.setSelectionRange(newCaretPosition, newCaretPosition);
33053
+ return returnMaskedValue.value ? mask.mask(newUnmaskedValue) : newUnmaskedValue;
33031
33054
  }
33032
33055
  return val;
33033
33056
  });
33034
33057
  const validationValue = vue.toRef(() => returnMaskedValue.value ? model.value : mask.unmask(model.value));
33058
+ function removeMaskDelimiters(val) {
33059
+ return val.split('').filter(ch => !isMaskDelimiter(ch)).join('');
33060
+ }
33061
+ function getNewCaretPosition(_ref2) {
33062
+ let {
33063
+ oldValue,
33064
+ newValue,
33065
+ oldCaret
33066
+ } = _ref2;
33067
+ if (!newValue) return 0;
33068
+ if (!oldValue) return newValue.length;
33069
+ let newCaret;
33070
+ if (inputAction.value === 'Backspace') {
33071
+ newCaret = oldCaret - 1;
33072
+ while (newCaret > 0 && isMaskDelimiter(newValue[newCaret - 1])) newCaret--;
33073
+ } else if (inputAction.value === 'Delete') {
33074
+ newCaret = oldCaret;
33075
+ } else {
33076
+ // insertion
33077
+ newCaret = oldCaret + 1;
33078
+ while (isMaskDelimiter(newValue[newCaret])) newCaret++;
33079
+ if (isMaskDelimiter(newValue[oldCaret])) newCaret++;
33080
+ }
33081
+ return newCaret;
33082
+ }
33035
33083
  vue.onBeforeMount(() => {
33036
33084
  if (props.returnMaskedValue) {
33037
33085
  emit('update:modelValue', model.value);
33038
33086
  }
33039
33087
  });
33040
- function setCaretPosition(newSelection) {
33041
- selection.value = newSelection;
33042
- vTextFieldRef.value && vTextFieldRef.value.setSelectionRange(selection.value, selection.value);
33088
+ function onKeyDown(e) {
33089
+ if (e.metaKey) return;
33090
+ const inputElement = e.target;
33091
+ caretPosition.value = inputElement.selectionStart || 0;
33092
+ inputAction.value = e.key;
33093
+ const hasSelection = inputElement.selectionStart !== inputElement.selectionEnd;
33094
+ if (e.key === 'Backspace' && hasSelection) {
33095
+ e.preventDefault();
33096
+ deleteSelection(e);
33097
+ }
33098
+ }
33099
+ async function onCut(e) {
33100
+ e.preventDefault();
33101
+ copySelectionToClipboard(e);
33102
+ deleteSelection(e);
33043
33103
  }
33044
- function resetSelections() {
33045
- if (!vTextFieldRef.value?.selectionEnd) return;
33046
- selection.value = vTextFieldRef.value.selectionEnd;
33047
- lazySelection.value = 0;
33048
- for (let index = 0; index < selection.value; index++) {
33049
- isMaskDelimiter(vTextFieldRef.value.value[index]) || lazySelection.value++;
33104
+ async function onPaste(e) {
33105
+ e.preventDefault();
33106
+ const inputElement = e.target;
33107
+ const pastedString = removeMaskDelimiters(e.clipboardData?.getData('text') || '');
33108
+ if (!pastedString) return;
33109
+ const pastedCharacters = [...pastedString];
33110
+ const hasSelection = inputElement.selectionStart !== inputElement.selectionEnd;
33111
+ if (hasSelection) {
33112
+ replaceSelection(inputElement, pastedCharacters);
33113
+ } else {
33114
+ insertCharacters(inputElement, pastedCharacters);
33050
33115
  }
33051
33116
  }
33052
- function updateRange() {
33053
- if (!vTextFieldRef.value) return;
33054
- resetSelections();
33055
- let selection = 0;
33056
- const newValue = vTextFieldRef.value.value;
33057
- if (newValue) {
33058
- for (let index = 0; index < newValue.length; index++) {
33059
- if (lazySelection.value <= 0) break;
33060
- isMaskDelimiter(newValue[index]) || lazySelection.value--;
33061
- selection++;
33062
- }
33117
+ function copySelectionToClipboard(e) {
33118
+ const inputElement = e.target;
33119
+ const start = inputElement.selectionStart || 0;
33120
+ const end = inputElement.selectionEnd || 0;
33121
+ const selectedText = inputElement.value.substring(start, end);
33122
+ navigator.clipboard.writeText(selectedText);
33123
+ }
33124
+ async function deleteSelection(e) {
33125
+ const inputElement = e.target;
33126
+ const curStart = inputElement.selectionStart || 0;
33127
+ caretPosition.value = inputElement.selectionEnd || 0;
33128
+ while (caretPosition.value > curStart) {
33129
+ const success = await simulateBackspace(inputElement);
33130
+ if (!success) break;
33131
+ }
33132
+ }
33133
+ async function simulateBackspace(inputElement) {
33134
+ inputAction.value = 'Backspace';
33135
+ model.value = inputElement.value.slice(0, caretPosition.value - 1) + inputElement.value.slice(caretPosition.value);
33136
+ inputAction.value = '';
33137
+ if (caretPosition.value === inputElement.selectionEnd) return false;
33138
+ caretPosition.value = inputElement.selectionEnd || 0;
33139
+ await vue.nextTick();
33140
+ return true;
33141
+ }
33142
+ async function insertCharacters(inputElement, pastedCharacters) {
33143
+ for (let i = 0; i < pastedCharacters.length; i++) {
33144
+ await insertCharacter(inputElement, pastedCharacters[i]);
33063
33145
  }
33064
- setCaretPosition(selection);
33146
+ }
33147
+ async function insertCharacter(inputElement, character) {
33148
+ caretPosition.value = inputElement.selectionEnd || 0;
33149
+ model.value = inputElement.value.slice(0, caretPosition.value) + character + inputElement.value.slice(caretPosition.value);
33150
+ await vue.nextTick();
33151
+ }
33152
+ async function replaceSelection(inputElement, pastedCharacters) {
33153
+ caretPosition.value = inputElement.selectionStart || 0;
33154
+ for (let i = 0; i < pastedCharacters.length; i++) {
33155
+ await replaceCharacter(caretPosition.value, pastedCharacters[i]);
33156
+ caretPosition.value++;
33157
+ }
33158
+ }
33159
+ async function replaceCharacter(index, character) {
33160
+ let targetIndex = index;
33161
+
33162
+ // Find next non-delimiter position
33163
+ while (targetIndex < model.value.length && isMaskDelimiter(model.value[targetIndex])) targetIndex++;
33164
+ model.value = model.value.slice(0, targetIndex) + character + model.value.slice(targetIndex + 1);
33165
+ await vue.nextTick();
33065
33166
  }
33066
33167
  useRender(() => {
33067
33168
  const textFieldProps = VTextField.filterProps(props);
@@ -33069,7 +33170,10 @@
33069
33170
  "modelValue": model.value,
33070
33171
  "onUpdate:modelValue": $event => model.value = $event,
33071
33172
  "ref": vTextFieldRef,
33072
- "validationValue": validationValue.value
33173
+ "validationValue": validationValue.value,
33174
+ "onCut": onCut,
33175
+ "onPaste": onPaste,
33176
+ "onKeydown": onKeyDown
33073
33177
  }), {
33074
33178
  ...slots
33075
33179
  });
@@ -35695,7 +35799,7 @@
35695
35799
  };
35696
35800
  });
35697
35801
  }
35698
- const version$1 = "3.9.5-dev.2025-08-12";
35802
+ const version$1 = "3.9.5-dev.2025-08-24";
35699
35803
  createVuetify$1.version = version$1;
35700
35804
 
35701
35805
  // Vue's inject() can only be used in setup
@@ -35993,7 +36097,7 @@
35993
36097
 
35994
36098
  /* eslint-disable local-rules/sort-imports */
35995
36099
 
35996
- const version = "3.9.5-dev.2025-08-12";
36100
+ const version = "3.9.5-dev.2025-08-24";
35997
36101
 
35998
36102
  /* eslint-disable local-rules/sort-imports */
35999
36103