@vuetify/nightly 3.7.15-dev.2025-03-07 → 3.7.15-dev.2025-03-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 (36) hide show
  1. package/CHANGELOG.md +9 -3
  2. package/dist/json/attributes.json +3379 -3339
  3. package/dist/json/importMap-labs.json +24 -24
  4. package/dist/json/importMap.json +170 -170
  5. package/dist/json/tags.json +10 -0
  6. package/dist/json/web-types.json +6242 -6151
  7. package/dist/vuetify-labs.css +3410 -3409
  8. package/dist/vuetify-labs.d.ts +234 -181
  9. package/dist/vuetify-labs.esm.js +810 -808
  10. package/dist/vuetify-labs.esm.js.map +1 -1
  11. package/dist/vuetify-labs.js +810 -808
  12. package/dist/vuetify-labs.min.css +2 -2
  13. package/dist/vuetify.css +2799 -2798
  14. package/dist/vuetify.d.ts +214 -161
  15. package/dist/vuetify.esm.js +810 -808
  16. package/dist/vuetify.esm.js.map +1 -1
  17. package/dist/vuetify.js +810 -808
  18. package/dist/vuetify.js.map +1 -1
  19. package/dist/vuetify.min.css +2 -2
  20. package/dist/vuetify.min.js +176 -175
  21. package/dist/vuetify.min.js.map +1 -1
  22. package/lib/components/VColorPicker/VColorPicker.css +3 -2
  23. package/lib/components/VColorPicker/VColorPicker.d.ts +259 -156
  24. package/lib/components/VColorPicker/VColorPicker.js +16 -17
  25. package/lib/components/VColorPicker/VColorPicker.js.map +1 -1
  26. package/lib/components/VColorPicker/VColorPicker.sass +2 -1
  27. package/lib/components/VColorPicker/_variables.scss +1 -0
  28. package/lib/components/VDatePicker/VDatePicker.d.ts +6 -6
  29. package/lib/components/VDatePicker/VDatePicker.js +5 -2
  30. package/lib/components/VDatePicker/VDatePicker.js.map +1 -1
  31. package/lib/entry-bundler.js +1 -1
  32. package/lib/framework.d.ts +57 -57
  33. package/lib/framework.js +1 -1
  34. package/lib/labs/VCalendar/VCalendar.d.ts +6 -6
  35. package/lib/labs/VDateInput/VDateInput.d.ts +25 -25
  36. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.7.15-dev.2025-03-07
2
+ * Vuetify v3.7.15-dev.2025-03-08
3
3
  * Forged by John Leider
4
4
  * Released under the MIT License.
5
5
  */
@@ -16728,6 +16728,9 @@
16728
16728
  }
16729
16729
  });
16730
16730
 
16731
+ // Utilities
16732
+ const VPickerTitle = createSimpleFunctional('v-picker-title');
16733
+
16731
16734
  const makeVSheetProps = propsFactory({
16732
16735
  color: String,
16733
16736
  ...makeBorderProps(),
@@ -16782,665 +16785,66 @@
16782
16785
 
16783
16786
  // Types
16784
16787
 
16785
- const makeVColorPickerProps = propsFactory({
16786
- canvasHeight: {
16787
- type: [String, Number],
16788
- default: 150
16789
- },
16790
- disabled: Boolean,
16791
- dotSize: {
16792
- type: [Number, String],
16793
- default: 10
16794
- },
16795
- hideCanvas: Boolean,
16796
- hideSliders: Boolean,
16797
- hideInputs: Boolean,
16798
- mode: {
16799
- type: String,
16800
- default: 'rgba',
16801
- validator: v => Object.keys(modes).includes(v)
16802
- },
16803
- modes: {
16804
- type: Array,
16805
- default: () => Object.keys(modes),
16806
- validator: v => Array.isArray(v) && v.every(m => Object.keys(modes).includes(m))
16807
- },
16808
- showSwatches: Boolean,
16809
- swatches: Array,
16810
- swatchesMaxHeight: {
16811
- type: [Number, String],
16812
- default: 150
16813
- },
16814
- modelValue: {
16815
- type: [Object, String]
16816
- },
16817
- ...omit(makeVSheetProps({
16818
- width: 300
16819
- }), ['height', 'location', 'minHeight', 'maxHeight', 'minWidth', 'maxWidth'])
16820
- }, 'VColorPicker');
16821
- const VColorPicker = defineComponent({
16822
- name: 'VColorPicker',
16823
- props: makeVColorPickerProps(),
16824
- emits: {
16825
- 'update:modelValue': color => true,
16826
- 'update:mode': mode => true
16827
- },
16828
- setup(props) {
16829
- const mode = useProxiedModel(props, 'mode');
16830
- const hue = vue.ref(null);
16831
- const model = useProxiedModel(props, 'modelValue', undefined, v => {
16832
- if (v == null || v === '') return null;
16833
- let c;
16834
- try {
16835
- c = RGBtoHSV(parseColor(v));
16836
- } catch (err) {
16837
- consoleWarn(err);
16838
- return null;
16839
- }
16840
- return c;
16841
- }, v => {
16842
- if (!v) return null;
16843
- return extractColor(v, props.modelValue);
16844
- });
16845
- const currentColor = vue.computed(() => {
16846
- return model.value ? {
16847
- ...model.value,
16848
- h: hue.value ?? model.value.h
16849
- } : null;
16850
- });
16788
+ const makeVPickerProps = propsFactory({
16789
+ bgColor: String,
16790
+ landscape: Boolean,
16791
+ title: String,
16792
+ hideHeader: Boolean,
16793
+ ...makeVSheetProps()
16794
+ }, 'VPicker');
16795
+ const VPicker = genericComponent()({
16796
+ name: 'VPicker',
16797
+ props: makeVPickerProps(),
16798
+ setup(props, _ref) {
16799
+ let {
16800
+ slots
16801
+ } = _ref;
16851
16802
  const {
16852
- rtlClasses
16853
- } = useRtl();
16854
- let externalChange = true;
16855
- vue.watch(model, v => {
16856
- if (!externalChange) {
16857
- // prevent hue shift from rgb conversion inaccuracy
16858
- externalChange = true;
16859
- return;
16860
- }
16861
- if (!v) return;
16862
- hue.value = v.h;
16863
- }, {
16864
- immediate: true
16865
- });
16866
- const updateColor = hsva => {
16867
- externalChange = false;
16868
- hue.value = hsva.h;
16869
- model.value = hsva;
16870
- };
16871
- vue.onBeforeMount(() => {
16872
- if (!props.modes.includes(mode.value)) mode.value = props.modes[0];
16873
- });
16874
- provideDefaults({
16875
- VSlider: {
16876
- color: undefined,
16877
- trackColor: undefined,
16878
- trackFillColor: undefined
16879
- }
16880
- });
16803
+ backgroundColorClasses,
16804
+ backgroundColorStyles
16805
+ } = useBackgroundColor(vue.toRef(props, 'color'));
16881
16806
  useRender(() => {
16882
16807
  const sheetProps = VSheet.filterProps(props);
16883
- return vue.createVNode(VSheet, vue.mergeProps({
16884
- "rounded": props.rounded,
16885
- "elevation": props.elevation,
16886
- "theme": props.theme,
16887
- "class": ['v-color-picker', rtlClasses.value, props.class],
16888
- "style": [{
16889
- '--v-color-picker-color-hsv': HSVtoCSS({
16890
- ...(currentColor.value ?? nullColor),
16891
- a: 1
16892
- })
16893
- }, props.style]
16894
- }, sheetProps, {
16895
- "maxWidth": props.width
16808
+ const hasTitle = !!(props.title || slots.title);
16809
+ return vue.createVNode(VSheet, vue.mergeProps(sheetProps, {
16810
+ "color": props.bgColor,
16811
+ "class": ['v-picker', {
16812
+ 'v-picker--landscape': props.landscape,
16813
+ 'v-picker--with-actions': !!slots.actions
16814
+ }, props.class],
16815
+ "style": props.style
16896
16816
  }), {
16897
- default: () => [!props.hideCanvas && vue.createVNode(VColorPickerCanvas, {
16898
- "key": "canvas",
16899
- "color": currentColor.value,
16900
- "onUpdate:color": updateColor,
16901
- "disabled": props.disabled,
16902
- "dotSize": props.dotSize,
16903
- "width": props.width,
16904
- "height": props.canvasHeight
16905
- }, null), (!props.hideSliders || !props.hideInputs) && vue.createVNode("div", {
16906
- "key": "controls",
16907
- "class": "v-color-picker__controls"
16908
- }, [!props.hideSliders && vue.createVNode(VColorPickerPreview, {
16909
- "key": "preview",
16910
- "color": currentColor.value,
16911
- "onUpdate:color": updateColor,
16912
- "hideAlpha": !mode.value.endsWith('a'),
16913
- "disabled": props.disabled
16914
- }, null), !props.hideInputs && vue.createVNode(VColorPickerEdit, {
16915
- "key": "edit",
16916
- "modes": props.modes,
16917
- "mode": mode.value,
16918
- "onUpdate:mode": m => mode.value = m,
16919
- "color": currentColor.value,
16920
- "onUpdate:color": updateColor,
16921
- "disabled": props.disabled
16922
- }, null)]), props.showSwatches && vue.createVNode(VColorPickerSwatches, {
16923
- "key": "swatches",
16924
- "color": currentColor.value,
16925
- "onUpdate:color": updateColor,
16926
- "maxHeight": props.swatchesMaxHeight,
16927
- "swatches": props.swatches,
16928
- "disabled": props.disabled
16929
- }, null)]
16817
+ default: () => [!props.hideHeader && vue.createVNode("div", {
16818
+ "key": "header",
16819
+ "class": [backgroundColorClasses.value],
16820
+ "style": [backgroundColorStyles.value]
16821
+ }, [hasTitle && vue.createVNode(VPickerTitle, {
16822
+ "key": "picker-title"
16823
+ }, {
16824
+ default: () => [slots.title?.() ?? props.title]
16825
+ }), slots.header && vue.createVNode("div", {
16826
+ "class": "v-picker__header"
16827
+ }, [slots.header()])]), vue.createVNode("div", {
16828
+ "class": "v-picker__body"
16829
+ }, [slots.default?.()]), slots.actions && vue.createVNode(VDefaultsProvider, {
16830
+ "defaults": {
16831
+ VBtn: {
16832
+ slim: true,
16833
+ variant: 'text'
16834
+ }
16835
+ }
16836
+ }, {
16837
+ default: () => [vue.createVNode("div", {
16838
+ "class": "v-picker__actions"
16839
+ }, [slots.actions()])]
16840
+ })]
16930
16841
  });
16931
16842
  });
16932
16843
  return {};
16933
16844
  }
16934
16845
  });
16935
-
16936
- // Types
16937
-
16938
- const makeVComboboxProps = propsFactory({
16939
- autoSelectFirst: {
16940
- type: [Boolean, String]
16941
- },
16942
- clearOnSelect: {
16943
- type: Boolean,
16944
- default: true
16945
- },
16946
- delimiters: Array,
16947
- ...makeFilterProps({
16948
- filterKeys: ['title']
16949
- }),
16950
- ...makeSelectProps({
16951
- hideNoData: true,
16952
- returnObject: true
16953
- }),
16954
- ...omit(makeVTextFieldProps({
16955
- modelValue: null,
16956
- role: 'combobox'
16957
- }), ['validationValue', 'dirty', 'appendInnerIcon']),
16958
- ...makeTransitionProps({
16959
- transition: false
16960
- })
16961
- }, 'VCombobox');
16962
- const VCombobox = genericComponent()({
16963
- name: 'VCombobox',
16964
- props: makeVComboboxProps(),
16965
- emits: {
16966
- 'update:focused': focused => true,
16967
- 'update:modelValue': value => true,
16968
- 'update:search': value => true,
16969
- 'update:menu': value => true
16970
- },
16971
- setup(props, _ref) {
16972
- let {
16973
- emit,
16974
- slots
16975
- } = _ref;
16976
- const {
16977
- t
16978
- } = useLocale();
16979
- const vTextFieldRef = vue.ref();
16980
- const isFocused = vue.shallowRef(false);
16981
- const isPristine = vue.shallowRef(true);
16982
- const listHasFocus = vue.shallowRef(false);
16983
- const vMenuRef = vue.ref();
16984
- const vVirtualScrollRef = vue.ref();
16985
- const _menu = useProxiedModel(props, 'menu');
16986
- const menu = vue.computed({
16987
- get: () => _menu.value,
16988
- set: v => {
16989
- if (_menu.value && !v && vMenuRef.value?.ΨopenChildren.size) return;
16990
- _menu.value = v;
16991
- }
16992
- });
16993
- const selectionIndex = vue.shallowRef(-1);
16994
- let cleared = false;
16995
- const color = vue.computed(() => vTextFieldRef.value?.color);
16996
- const label = vue.computed(() => menu.value ? props.closeText : props.openText);
16997
- const {
16998
- items,
16999
- transformIn,
17000
- transformOut
17001
- } = useItems(props);
17002
- const {
17003
- textColorClasses,
17004
- textColorStyles
17005
- } = useTextColor(color);
17006
- const model = useProxiedModel(props, 'modelValue', [], v => transformIn(wrapInArray(v)), v => {
17007
- const transformed = transformOut(v);
17008
- return props.multiple ? transformed : transformed[0] ?? null;
17009
- });
17010
- const form = useForm(props);
17011
- const hasChips = vue.computed(() => !!(props.chips || slots.chip));
17012
- const hasSelectionSlot = vue.computed(() => hasChips.value || !!slots.selection);
17013
- const _search = vue.shallowRef(!props.multiple && !hasSelectionSlot.value ? model.value[0]?.title ?? '' : '');
17014
- const search = vue.computed({
17015
- get: () => {
17016
- return _search.value;
17017
- },
17018
- set: val => {
17019
- _search.value = val ?? '';
17020
- if (!props.multiple && !hasSelectionSlot.value) {
17021
- model.value = [transformItem$3(props, val)];
17022
- }
17023
- if (val && props.multiple && props.delimiters?.length) {
17024
- const values = val.split(new RegExp(`(?:${props.delimiters.join('|')})+`));
17025
- if (values.length > 1) {
17026
- values.forEach(v => {
17027
- v = v.trim();
17028
- if (v) select(transformItem$3(props, v));
17029
- });
17030
- _search.value = '';
17031
- }
17032
- }
17033
- if (!val) selectionIndex.value = -1;
17034
- isPristine.value = !val;
17035
- }
17036
- });
17037
- const counterValue = vue.computed(() => {
17038
- return typeof props.counterValue === 'function' ? props.counterValue(model.value) : typeof props.counterValue === 'number' ? props.counterValue : props.multiple ? model.value.length : search.value.length;
17039
- });
17040
- vue.watch(_search, value => {
17041
- if (cleared) {
17042
- // wait for clear to finish, VTextField sets _search to null
17043
- // then search computed triggers and updates _search to ''
17044
- vue.nextTick(() => cleared = false);
17045
- } else if (isFocused.value && !menu.value) {
17046
- menu.value = true;
17047
- }
17048
- emit('update:search', value);
17049
- });
17050
- vue.watch(model, value => {
17051
- if (!props.multiple && !hasSelectionSlot.value) {
17052
- _search.value = value[0]?.title ?? '';
17053
- }
17054
- });
17055
- const {
17056
- filteredItems,
17057
- getMatches
17058
- } = useFilter(props, items, () => isPristine.value ? '' : search.value);
17059
- const displayItems = vue.computed(() => {
17060
- if (props.hideSelected) {
17061
- return filteredItems.value.filter(filteredItem => !model.value.some(s => s.value === filteredItem.value));
17062
- }
17063
- return filteredItems.value;
17064
- });
17065
- const selectedValues = vue.computed(() => model.value.map(selection => selection.value));
17066
- const highlightFirst = vue.computed(() => {
17067
- const selectFirst = props.autoSelectFirst === true || props.autoSelectFirst === 'exact' && search.value === displayItems.value[0]?.title;
17068
- return selectFirst && displayItems.value.length > 0 && !isPristine.value && !listHasFocus.value;
17069
- });
17070
- const menuDisabled = vue.computed(() => props.hideNoData && !displayItems.value.length || form.isReadonly.value || form.isDisabled.value);
17071
- const listRef = vue.ref();
17072
- const listEvents = useScrolling(listRef, vTextFieldRef);
17073
- function onClear(e) {
17074
- cleared = true;
17075
- if (props.openOnClear) {
17076
- menu.value = true;
17077
- }
17078
- }
17079
- function onMousedownControl() {
17080
- if (menuDisabled.value) return;
17081
- menu.value = true;
17082
- }
17083
- function onMousedownMenuIcon(e) {
17084
- if (menuDisabled.value) return;
17085
- if (isFocused.value) {
17086
- e.preventDefault();
17087
- e.stopPropagation();
17088
- }
17089
- menu.value = !menu.value;
17090
- }
17091
- function onListKeydown(e) {
17092
- if (e.key !== ' ' && checkPrintable(e)) {
17093
- vTextFieldRef.value?.focus();
17094
- }
17095
- }
17096
- // eslint-disable-next-line complexity
17097
- function onKeydown(e) {
17098
- if (isComposingIgnoreKey(e) || form.isReadonly.value) return;
17099
- const selectionStart = vTextFieldRef.value.selectionStart;
17100
- const length = model.value.length;
17101
- if (['Enter', 'ArrowDown', 'ArrowUp'].includes(e.key)) {
17102
- e.preventDefault();
17103
- }
17104
- if (['Enter', 'ArrowDown'].includes(e.key)) {
17105
- menu.value = true;
17106
- }
17107
- if (['Escape'].includes(e.key)) {
17108
- menu.value = false;
17109
- }
17110
- if (['Enter', 'Escape', 'Tab'].includes(e.key)) {
17111
- if (highlightFirst.value && ['Enter', 'Tab'].includes(e.key) && !model.value.some(_ref2 => {
17112
- let {
17113
- value
17114
- } = _ref2;
17115
- return value === displayItems.value[0].value;
17116
- })) {
17117
- select(filteredItems.value[0]);
17118
- }
17119
- isPristine.value = true;
17120
- }
17121
- if (e.key === 'ArrowDown' && highlightFirst.value) {
17122
- listRef.value?.focus('next');
17123
- }
17124
- if (e.key === 'Enter' && search.value) {
17125
- select(transformItem$3(props, search.value));
17126
- if (hasSelectionSlot.value) _search.value = '';
17127
- }
17128
- if (['Backspace', 'Delete'].includes(e.key)) {
17129
- if (!props.multiple && hasSelectionSlot.value && model.value.length > 0 && !search.value) return select(model.value[0], false);
17130
- if (~selectionIndex.value) {
17131
- e.preventDefault();
17132
- const originalSelectionIndex = selectionIndex.value;
17133
- select(model.value[selectionIndex.value], false);
17134
- selectionIndex.value = originalSelectionIndex >= length - 1 ? length - 2 : originalSelectionIndex;
17135
- } else if (e.key === 'Backspace' && !search.value) {
17136
- selectionIndex.value = length - 1;
17137
- }
17138
- return;
17139
- }
17140
- if (!props.multiple) return;
17141
- if (e.key === 'ArrowLeft') {
17142
- if (selectionIndex.value < 0 && selectionStart > 0) return;
17143
- const prev = selectionIndex.value > -1 ? selectionIndex.value - 1 : length - 1;
17144
- if (model.value[prev]) {
17145
- selectionIndex.value = prev;
17146
- } else {
17147
- selectionIndex.value = -1;
17148
- vTextFieldRef.value.setSelectionRange(search.value.length, search.value.length);
17149
- }
17150
- } else if (e.key === 'ArrowRight') {
17151
- if (selectionIndex.value < 0) return;
17152
- const next = selectionIndex.value + 1;
17153
- if (model.value[next]) {
17154
- selectionIndex.value = next;
17155
- } else {
17156
- selectionIndex.value = -1;
17157
- vTextFieldRef.value.setSelectionRange(0, 0);
17158
- }
17159
- } else if (~selectionIndex.value && checkPrintable(e)) {
17160
- selectionIndex.value = -1;
17161
- }
17162
- }
17163
- function onAfterEnter() {
17164
- if (props.eager) {
17165
- vVirtualScrollRef.value?.calculateVisibleItems();
17166
- }
17167
- }
17168
- function onAfterLeave() {
17169
- if (isFocused.value) {
17170
- isPristine.value = true;
17171
- vTextFieldRef.value?.focus();
17172
- }
17173
- }
17174
- /** @param set - null means toggle */
17175
- function select(item) {
17176
- let set = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
17177
- if (!item || item.props.disabled) return;
17178
- if (props.multiple) {
17179
- const index = model.value.findIndex(selection => (props.valueComparator || deepEqual)(selection.value, item.value));
17180
- const add = set == null ? !~index : set;
17181
- if (~index) {
17182
- const value = add ? [...model.value, item] : [...model.value];
17183
- value.splice(index, 1);
17184
- model.value = value;
17185
- } else if (add) {
17186
- model.value = [...model.value, item];
17187
- }
17188
- if (props.clearOnSelect) {
17189
- search.value = '';
17190
- }
17191
- } else {
17192
- const add = set !== false;
17193
- model.value = add ? [item] : [];
17194
- _search.value = add && !hasSelectionSlot.value ? item.title : '';
17195
-
17196
- // watch for search watcher to trigger
17197
- vue.nextTick(() => {
17198
- menu.value = false;
17199
- isPristine.value = true;
17200
- });
17201
- }
17202
- }
17203
- function onFocusin(e) {
17204
- isFocused.value = true;
17205
- setTimeout(() => {
17206
- listHasFocus.value = true;
17207
- });
17208
- }
17209
- function onFocusout(e) {
17210
- listHasFocus.value = false;
17211
- }
17212
- function onUpdateModelValue(v) {
17213
- if (v == null || v === '' && !props.multiple && !hasSelectionSlot.value) model.value = [];
17214
- }
17215
- vue.watch(isFocused, (val, oldVal) => {
17216
- if (val || val === oldVal) return;
17217
- selectionIndex.value = -1;
17218
- menu.value = false;
17219
- if (search.value) {
17220
- if (props.multiple) {
17221
- select(transformItem$3(props, search.value));
17222
- return;
17223
- }
17224
- if (!hasSelectionSlot.value) return;
17225
- if (model.value.some(_ref3 => {
17226
- let {
17227
- title
17228
- } = _ref3;
17229
- return title === search.value;
17230
- })) {
17231
- _search.value = '';
17232
- } else {
17233
- select(transformItem$3(props, search.value));
17234
- }
17235
- }
17236
- });
17237
- vue.watch(menu, () => {
17238
- if (!props.hideSelected && menu.value && model.value.length) {
17239
- const index = displayItems.value.findIndex(item => model.value.some(s => (props.valueComparator || deepEqual)(s.value, item.value)));
17240
- IN_BROWSER && window.requestAnimationFrame(() => {
17241
- index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index);
17242
- });
17243
- }
17244
- });
17245
- vue.watch(() => props.items, (newVal, oldVal) => {
17246
- if (menu.value) return;
17247
- if (isFocused.value && !oldVal.length && newVal.length) {
17248
- menu.value = true;
17249
- }
17250
- });
17251
- useRender(() => {
17252
- const hasList = !!(!props.hideNoData || displayItems.value.length || slots['prepend-item'] || slots['append-item'] || slots['no-data']);
17253
- const isDirty = model.value.length > 0;
17254
- const textFieldProps = VTextField.filterProps(props);
17255
- return vue.createVNode(VTextField, vue.mergeProps({
17256
- "ref": vTextFieldRef
17257
- }, textFieldProps, {
17258
- "modelValue": search.value,
17259
- "onUpdate:modelValue": [$event => search.value = $event, onUpdateModelValue],
17260
- "focused": isFocused.value,
17261
- "onUpdate:focused": $event => isFocused.value = $event,
17262
- "validationValue": model.externalValue,
17263
- "counterValue": counterValue.value,
17264
- "dirty": isDirty,
17265
- "class": ['v-combobox', {
17266
- 'v-combobox--active-menu': menu.value,
17267
- 'v-combobox--chips': !!props.chips,
17268
- 'v-combobox--selection-slot': !!hasSelectionSlot.value,
17269
- 'v-combobox--selecting-index': selectionIndex.value > -1,
17270
- [`v-combobox--${props.multiple ? 'multiple' : 'single'}`]: true
17271
- }, props.class],
17272
- "style": props.style,
17273
- "readonly": form.isReadonly.value,
17274
- "placeholder": isDirty ? undefined : props.placeholder,
17275
- "onClick:clear": onClear,
17276
- "onMousedown:control": onMousedownControl,
17277
- "onKeydown": onKeydown
17278
- }), {
17279
- ...slots,
17280
- default: () => vue.createVNode(vue.Fragment, null, [vue.createVNode(VMenu, vue.mergeProps({
17281
- "ref": vMenuRef,
17282
- "modelValue": menu.value,
17283
- "onUpdate:modelValue": $event => menu.value = $event,
17284
- "activator": "parent",
17285
- "contentClass": "v-combobox__content",
17286
- "disabled": menuDisabled.value,
17287
- "eager": props.eager,
17288
- "maxHeight": 310,
17289
- "openOnClick": false,
17290
- "closeOnContentClick": false,
17291
- "transition": props.transition,
17292
- "onAfterEnter": onAfterEnter,
17293
- "onAfterLeave": onAfterLeave
17294
- }, props.menuProps), {
17295
- default: () => [hasList && vue.createVNode(VList, vue.mergeProps({
17296
- "ref": listRef,
17297
- "selected": selectedValues.value,
17298
- "selectStrategy": props.multiple ? 'independent' : 'single-independent',
17299
- "onMousedown": e => e.preventDefault(),
17300
- "onKeydown": onListKeydown,
17301
- "onFocusin": onFocusin,
17302
- "onFocusout": onFocusout,
17303
- "tabindex": "-1",
17304
- "aria-live": "polite",
17305
- "color": props.itemColor ?? props.color
17306
- }, listEvents, props.listProps), {
17307
- default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? vue.createVNode(VListItem, {
17308
- "key": "no-data",
17309
- "title": t(props.noDataText)
17310
- }, null)), vue.createVNode(VVirtualScroll, {
17311
- "ref": vVirtualScrollRef,
17312
- "renderless": true,
17313
- "items": displayItems.value,
17314
- "itemKey": "value"
17315
- }, {
17316
- default: _ref4 => {
17317
- let {
17318
- item,
17319
- index,
17320
- itemRef
17321
- } = _ref4;
17322
- const itemProps = vue.mergeProps(item.props, {
17323
- ref: itemRef,
17324
- key: item.value,
17325
- active: highlightFirst.value && index === 0 ? true : undefined,
17326
- onClick: () => select(item, null)
17327
- });
17328
- return slots.item?.({
17329
- item,
17330
- index,
17331
- props: itemProps
17332
- }) ?? vue.createVNode(VListItem, vue.mergeProps(itemProps, {
17333
- "role": "option"
17334
- }), {
17335
- prepend: _ref5 => {
17336
- let {
17337
- isSelected
17338
- } = _ref5;
17339
- return vue.createVNode(vue.Fragment, null, [props.multiple && !props.hideSelected ? vue.createVNode(VCheckboxBtn, {
17340
- "key": item.value,
17341
- "modelValue": isSelected,
17342
- "ripple": false,
17343
- "tabindex": "-1"
17344
- }, null) : undefined, item.props.prependAvatar && vue.createVNode(VAvatar, {
17345
- "image": item.props.prependAvatar
17346
- }, null), item.props.prependIcon && vue.createVNode(VIcon, {
17347
- "icon": item.props.prependIcon
17348
- }, null)]);
17349
- },
17350
- title: () => {
17351
- return isPristine.value ? item.title : highlightResult('v-combobox', item.title, getMatches(item)?.title);
17352
- }
17353
- });
17354
- }
17355
- }), slots['append-item']?.()]
17356
- })]
17357
- }), model.value.map((item, index) => {
17358
- function onChipClose(e) {
17359
- e.stopPropagation();
17360
- e.preventDefault();
17361
- select(item, false);
17362
- }
17363
- const slotProps = {
17364
- 'onClick:close': onChipClose,
17365
- onKeydown(e) {
17366
- if (e.key !== 'Enter' && e.key !== ' ') return;
17367
- e.preventDefault();
17368
- e.stopPropagation();
17369
- onChipClose(e);
17370
- },
17371
- onMousedown(e) {
17372
- e.preventDefault();
17373
- e.stopPropagation();
17374
- },
17375
- modelValue: true,
17376
- 'onUpdate:modelValue': undefined
17377
- };
17378
- const hasSlot = hasChips.value ? !!slots.chip : !!slots.selection;
17379
- const slotContent = hasSlot ? ensureValidVNode(hasChips.value ? slots.chip({
17380
- item,
17381
- index,
17382
- props: slotProps
17383
- }) : slots.selection({
17384
- item,
17385
- index
17386
- })) : undefined;
17387
- if (hasSlot && !slotContent) return undefined;
17388
- return vue.createVNode("div", {
17389
- "key": item.value,
17390
- "class": ['v-combobox__selection', index === selectionIndex.value && ['v-combobox__selection--selected', textColorClasses.value]],
17391
- "style": index === selectionIndex.value ? textColorStyles.value : {}
17392
- }, [hasChips.value ? !slots.chip ? vue.createVNode(VChip, vue.mergeProps({
17393
- "key": "chip",
17394
- "closable": props.closableChips,
17395
- "size": "small",
17396
- "text": item.title,
17397
- "disabled": item.props.disabled
17398
- }, slotProps), null) : vue.createVNode(VDefaultsProvider, {
17399
- "key": "chip-defaults",
17400
- "defaults": {
17401
- VChip: {
17402
- closable: props.closableChips,
17403
- size: 'small',
17404
- text: item.title
17405
- }
17406
- }
17407
- }, {
17408
- default: () => [slotContent]
17409
- }) : slotContent ?? vue.createVNode("span", {
17410
- "class": "v-combobox__selection-text"
17411
- }, [item.title, props.multiple && index < model.value.length - 1 && vue.createVNode("span", {
17412
- "class": "v-combobox__selection-comma"
17413
- }, [vue.createTextVNode(",")])])]);
17414
- })]),
17415
- 'append-inner': function () {
17416
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
17417
- args[_key] = arguments[_key];
17418
- }
17419
- return vue.createVNode(vue.Fragment, null, [slots['append-inner']?.(...args), (!props.hideNoData || props.items.length) && props.menuIcon ? vue.createVNode(VIcon, {
17420
- "class": "v-combobox__menu-icon",
17421
- "icon": props.menuIcon,
17422
- "onMousedown": onMousedownMenuIcon,
17423
- "onClick": noop,
17424
- "aria-label": t(label.value),
17425
- "title": t(label.value),
17426
- "tabindex": "-1"
17427
- }, null) : undefined]);
17428
- }
17429
- });
17430
- });
17431
- return forwardRefs({
17432
- isFocused,
17433
- isPristine,
17434
- menu,
17435
- search,
17436
- selectionIndex,
17437
- filteredItems,
17438
- select
17439
- }, vTextFieldRef);
17440
- }
17441
- });
17442
-
17443
- // Utilities
16846
+
16847
+ // Utilities
17444
16848
 
17445
16849
  // Types
17446
16850
 
@@ -18162,101 +17566,760 @@
18162
17566
  endOfYear(date) {
18163
17567
  return endOfYear(date);
18164
17568
  }
18165
- }
17569
+ }
17570
+
17571
+ // Composables
17572
+ const DateOptionsSymbol = Symbol.for('vuetify:date-options');
17573
+ const DateAdapterSymbol = Symbol.for('vuetify:date-adapter');
17574
+ function createDate(options, locale) {
17575
+ const _options = mergeDeep({
17576
+ adapter: VuetifyDateAdapter,
17577
+ locale: {
17578
+ af: 'af-ZA',
17579
+ // ar: '', # not the same value for all variants
17580
+ bg: 'bg-BG',
17581
+ ca: 'ca-ES',
17582
+ ckb: '',
17583
+ cs: 'cs-CZ',
17584
+ de: 'de-DE',
17585
+ el: 'el-GR',
17586
+ en: 'en-US',
17587
+ // es: '', # not the same value for all variants
17588
+ et: 'et-EE',
17589
+ fa: 'fa-IR',
17590
+ fi: 'fi-FI',
17591
+ // fr: '', #not the same value for all variants
17592
+ hr: 'hr-HR',
17593
+ hu: 'hu-HU',
17594
+ he: 'he-IL',
17595
+ id: 'id-ID',
17596
+ it: 'it-IT',
17597
+ ja: 'ja-JP',
17598
+ ko: 'ko-KR',
17599
+ lv: 'lv-LV',
17600
+ lt: 'lt-LT',
17601
+ nl: 'nl-NL',
17602
+ no: 'no-NO',
17603
+ pl: 'pl-PL',
17604
+ pt: 'pt-PT',
17605
+ ro: 'ro-RO',
17606
+ ru: 'ru-RU',
17607
+ sk: 'sk-SK',
17608
+ sl: 'sl-SI',
17609
+ srCyrl: 'sr-SP',
17610
+ srLatn: 'sr-SP',
17611
+ sv: 'sv-SE',
17612
+ th: 'th-TH',
17613
+ tr: 'tr-TR',
17614
+ az: 'az-AZ',
17615
+ uk: 'uk-UA',
17616
+ vi: 'vi-VN',
17617
+ zhHans: 'zh-CN',
17618
+ zhHant: 'zh-TW'
17619
+ }
17620
+ }, options);
17621
+ return {
17622
+ options: _options,
17623
+ instance: createInstance(_options, locale)
17624
+ };
17625
+ }
17626
+ function createInstance(options, locale) {
17627
+ const instance = vue.reactive(typeof options.adapter === 'function'
17628
+ // eslint-disable-next-line new-cap
17629
+ ? new options.adapter({
17630
+ locale: options.locale[locale.current.value] ?? locale.current.value,
17631
+ formats: options.formats
17632
+ }) : options.adapter);
17633
+ vue.watch(locale.current, value => {
17634
+ instance.locale = options.locale[value] ?? value ?? instance.locale;
17635
+ });
17636
+ return instance;
17637
+ }
17638
+ function useDate() {
17639
+ const options = vue.inject(DateOptionsSymbol);
17640
+ if (!options) throw new Error('[Vuetify] Could not find injected date options');
17641
+ const locale = useLocale();
17642
+ return createInstance(options, locale);
17643
+ }
17644
+
17645
+ // https://stackoverflow.com/questions/274861/how-do-i-calculate-the-week-number-given-a-date/275024#275024
17646
+ function getWeek(adapter, value) {
17647
+ const date = adapter.toJsDate(value);
17648
+ let year = date.getFullYear();
17649
+ let d1w1 = new Date(year, 0, 1);
17650
+ if (date < d1w1) {
17651
+ year = year - 1;
17652
+ d1w1 = new Date(year, 0, 1);
17653
+ } else {
17654
+ const tv = new Date(year + 1, 0, 1);
17655
+ if (date >= tv) {
17656
+ year = year + 1;
17657
+ d1w1 = tv;
17658
+ }
17659
+ }
17660
+ const diffTime = Math.abs(date.getTime() - d1w1.getTime());
17661
+ const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
17662
+ return Math.floor(diffDays / 7) + 1;
17663
+ }
17664
+
17665
+ // Types
17666
+
17667
+ const makeVColorPickerProps = propsFactory({
17668
+ canvasHeight: {
17669
+ type: [String, Number],
17670
+ default: 150
17671
+ },
17672
+ disabled: Boolean,
17673
+ dotSize: {
17674
+ type: [Number, String],
17675
+ default: 10
17676
+ },
17677
+ hideCanvas: Boolean,
17678
+ hideSliders: Boolean,
17679
+ hideInputs: Boolean,
17680
+ mode: {
17681
+ type: String,
17682
+ default: 'rgba',
17683
+ validator: v => Object.keys(modes).includes(v)
17684
+ },
17685
+ modes: {
17686
+ type: Array,
17687
+ default: () => Object.keys(modes),
17688
+ validator: v => Array.isArray(v) && v.every(m => Object.keys(modes).includes(m))
17689
+ },
17690
+ showSwatches: Boolean,
17691
+ swatches: Array,
17692
+ swatchesMaxHeight: {
17693
+ type: [Number, String],
17694
+ default: 150
17695
+ },
17696
+ modelValue: {
17697
+ type: [Object, String]
17698
+ },
17699
+ ...makeVPickerProps({
17700
+ hideHeader: true
17701
+ })
17702
+ }, 'VColorPicker');
17703
+ const VColorPicker = defineComponent({
17704
+ name: 'VColorPicker',
17705
+ props: makeVColorPickerProps(),
17706
+ emits: {
17707
+ 'update:modelValue': color => true,
17708
+ 'update:mode': mode => true
17709
+ },
17710
+ setup(props, _ref) {
17711
+ let {
17712
+ slots
17713
+ } = _ref;
17714
+ const mode = useProxiedModel(props, 'mode');
17715
+ const hue = vue.ref(null);
17716
+ const model = useProxiedModel(props, 'modelValue', undefined, v => {
17717
+ if (v == null || v === '') return null;
17718
+ let c;
17719
+ try {
17720
+ c = RGBtoHSV(parseColor(v));
17721
+ } catch (err) {
17722
+ consoleWarn(err);
17723
+ return null;
17724
+ }
17725
+ return c;
17726
+ }, v => {
17727
+ if (!v) return null;
17728
+ return extractColor(v, props.modelValue);
17729
+ });
17730
+ const currentColor = vue.computed(() => {
17731
+ return model.value ? {
17732
+ ...model.value,
17733
+ h: hue.value ?? model.value.h
17734
+ } : null;
17735
+ });
17736
+ const {
17737
+ rtlClasses
17738
+ } = useRtl();
17739
+ let externalChange = true;
17740
+ vue.watch(model, v => {
17741
+ if (!externalChange) {
17742
+ // prevent hue shift from rgb conversion inaccuracy
17743
+ externalChange = true;
17744
+ return;
17745
+ }
17746
+ if (!v) return;
17747
+ hue.value = v.h;
17748
+ }, {
17749
+ immediate: true
17750
+ });
17751
+ const updateColor = hsva => {
17752
+ externalChange = false;
17753
+ hue.value = hsva.h;
17754
+ model.value = hsva;
17755
+ };
17756
+ vue.onBeforeMount(() => {
17757
+ if (!props.modes.includes(mode.value)) mode.value = props.modes[0];
17758
+ });
17759
+ provideDefaults({
17760
+ VSlider: {
17761
+ color: undefined,
17762
+ trackColor: undefined,
17763
+ trackFillColor: undefined
17764
+ }
17765
+ });
17766
+ useRender(() => {
17767
+ const pickerProps = VPicker.filterProps(props);
17768
+ return vue.createVNode(VPicker, vue.mergeProps(pickerProps, {
17769
+ "class": ['v-color-picker', rtlClasses.value, props.class],
17770
+ "style": [{
17771
+ '--v-color-picker-color-hsv': HSVtoCSS({
17772
+ ...(currentColor.value ?? nullColor),
17773
+ a: 1
17774
+ })
17775
+ }, props.style]
17776
+ }), {
17777
+ ...slots,
17778
+ default: () => vue.createVNode(vue.Fragment, null, [!props.hideCanvas && vue.createVNode(VColorPickerCanvas, {
17779
+ "key": "canvas",
17780
+ "color": currentColor.value,
17781
+ "onUpdate:color": updateColor,
17782
+ "disabled": props.disabled,
17783
+ "dotSize": props.dotSize,
17784
+ "width": props.width,
17785
+ "height": props.canvasHeight
17786
+ }, null), (!props.hideSliders || !props.hideInputs) && vue.createVNode("div", {
17787
+ "key": "controls",
17788
+ "class": "v-color-picker__controls"
17789
+ }, [!props.hideSliders && vue.createVNode(VColorPickerPreview, {
17790
+ "key": "preview",
17791
+ "color": currentColor.value,
17792
+ "onUpdate:color": updateColor,
17793
+ "hideAlpha": !mode.value.endsWith('a'),
17794
+ "disabled": props.disabled
17795
+ }, null), !props.hideInputs && vue.createVNode(VColorPickerEdit, {
17796
+ "key": "edit",
17797
+ "modes": props.modes,
17798
+ "mode": mode.value,
17799
+ "onUpdate:mode": m => mode.value = m,
17800
+ "color": currentColor.value,
17801
+ "onUpdate:color": updateColor,
17802
+ "disabled": props.disabled
17803
+ }, null)]), props.showSwatches && vue.createVNode(VColorPickerSwatches, {
17804
+ "key": "swatches",
17805
+ "color": currentColor.value,
17806
+ "onUpdate:color": updateColor,
17807
+ "maxHeight": props.swatchesMaxHeight,
17808
+ "swatches": props.swatches,
17809
+ "disabled": props.disabled
17810
+ }, null)])
17811
+ });
17812
+ });
17813
+ return {};
17814
+ }
17815
+ });
18166
17816
 
18167
- // Composables
18168
- const DateOptionsSymbol = Symbol.for('vuetify:date-options');
18169
- const DateAdapterSymbol = Symbol.for('vuetify:date-adapter');
18170
- function createDate(options, locale) {
18171
- const _options = mergeDeep({
18172
- adapter: VuetifyDateAdapter,
18173
- locale: {
18174
- af: 'af-ZA',
18175
- // ar: '', # not the same value for all variants
18176
- bg: 'bg-BG',
18177
- ca: 'ca-ES',
18178
- ckb: '',
18179
- cs: 'cs-CZ',
18180
- de: 'de-DE',
18181
- el: 'el-GR',
18182
- en: 'en-US',
18183
- // es: '', # not the same value for all variants
18184
- et: 'et-EE',
18185
- fa: 'fa-IR',
18186
- fi: 'fi-FI',
18187
- // fr: '', #not the same value for all variants
18188
- hr: 'hr-HR',
18189
- hu: 'hu-HU',
18190
- he: 'he-IL',
18191
- id: 'id-ID',
18192
- it: 'it-IT',
18193
- ja: 'ja-JP',
18194
- ko: 'ko-KR',
18195
- lv: 'lv-LV',
18196
- lt: 'lt-LT',
18197
- nl: 'nl-NL',
18198
- no: 'no-NO',
18199
- pl: 'pl-PL',
18200
- pt: 'pt-PT',
18201
- ro: 'ro-RO',
18202
- ru: 'ru-RU',
18203
- sk: 'sk-SK',
18204
- sl: 'sl-SI',
18205
- srCyrl: 'sr-SP',
18206
- srLatn: 'sr-SP',
18207
- sv: 'sv-SE',
18208
- th: 'th-TH',
18209
- tr: 'tr-TR',
18210
- az: 'az-AZ',
18211
- uk: 'uk-UA',
18212
- vi: 'vi-VN',
18213
- zhHans: 'zh-CN',
18214
- zhHant: 'zh-TW'
17817
+ // Types
17818
+
17819
+ const makeVComboboxProps = propsFactory({
17820
+ autoSelectFirst: {
17821
+ type: [Boolean, String]
17822
+ },
17823
+ clearOnSelect: {
17824
+ type: Boolean,
17825
+ default: true
17826
+ },
17827
+ delimiters: Array,
17828
+ ...makeFilterProps({
17829
+ filterKeys: ['title']
17830
+ }),
17831
+ ...makeSelectProps({
17832
+ hideNoData: true,
17833
+ returnObject: true
17834
+ }),
17835
+ ...omit(makeVTextFieldProps({
17836
+ modelValue: null,
17837
+ role: 'combobox'
17838
+ }), ['validationValue', 'dirty', 'appendInnerIcon']),
17839
+ ...makeTransitionProps({
17840
+ transition: false
17841
+ })
17842
+ }, 'VCombobox');
17843
+ const VCombobox = genericComponent()({
17844
+ name: 'VCombobox',
17845
+ props: makeVComboboxProps(),
17846
+ emits: {
17847
+ 'update:focused': focused => true,
17848
+ 'update:modelValue': value => true,
17849
+ 'update:search': value => true,
17850
+ 'update:menu': value => true
17851
+ },
17852
+ setup(props, _ref) {
17853
+ let {
17854
+ emit,
17855
+ slots
17856
+ } = _ref;
17857
+ const {
17858
+ t
17859
+ } = useLocale();
17860
+ const vTextFieldRef = vue.ref();
17861
+ const isFocused = vue.shallowRef(false);
17862
+ const isPristine = vue.shallowRef(true);
17863
+ const listHasFocus = vue.shallowRef(false);
17864
+ const vMenuRef = vue.ref();
17865
+ const vVirtualScrollRef = vue.ref();
17866
+ const _menu = useProxiedModel(props, 'menu');
17867
+ const menu = vue.computed({
17868
+ get: () => _menu.value,
17869
+ set: v => {
17870
+ if (_menu.value && !v && vMenuRef.value?.ΨopenChildren.size) return;
17871
+ _menu.value = v;
17872
+ }
17873
+ });
17874
+ const selectionIndex = vue.shallowRef(-1);
17875
+ let cleared = false;
17876
+ const color = vue.computed(() => vTextFieldRef.value?.color);
17877
+ const label = vue.computed(() => menu.value ? props.closeText : props.openText);
17878
+ const {
17879
+ items,
17880
+ transformIn,
17881
+ transformOut
17882
+ } = useItems(props);
17883
+ const {
17884
+ textColorClasses,
17885
+ textColorStyles
17886
+ } = useTextColor(color);
17887
+ const model = useProxiedModel(props, 'modelValue', [], v => transformIn(wrapInArray(v)), v => {
17888
+ const transformed = transformOut(v);
17889
+ return props.multiple ? transformed : transformed[0] ?? null;
17890
+ });
17891
+ const form = useForm(props);
17892
+ const hasChips = vue.computed(() => !!(props.chips || slots.chip));
17893
+ const hasSelectionSlot = vue.computed(() => hasChips.value || !!slots.selection);
17894
+ const _search = vue.shallowRef(!props.multiple && !hasSelectionSlot.value ? model.value[0]?.title ?? '' : '');
17895
+ const search = vue.computed({
17896
+ get: () => {
17897
+ return _search.value;
17898
+ },
17899
+ set: val => {
17900
+ _search.value = val ?? '';
17901
+ if (!props.multiple && !hasSelectionSlot.value) {
17902
+ model.value = [transformItem$3(props, val)];
17903
+ }
17904
+ if (val && props.multiple && props.delimiters?.length) {
17905
+ const values = val.split(new RegExp(`(?:${props.delimiters.join('|')})+`));
17906
+ if (values.length > 1) {
17907
+ values.forEach(v => {
17908
+ v = v.trim();
17909
+ if (v) select(transformItem$3(props, v));
17910
+ });
17911
+ _search.value = '';
17912
+ }
17913
+ }
17914
+ if (!val) selectionIndex.value = -1;
17915
+ isPristine.value = !val;
17916
+ }
17917
+ });
17918
+ const counterValue = vue.computed(() => {
17919
+ return typeof props.counterValue === 'function' ? props.counterValue(model.value) : typeof props.counterValue === 'number' ? props.counterValue : props.multiple ? model.value.length : search.value.length;
17920
+ });
17921
+ vue.watch(_search, value => {
17922
+ if (cleared) {
17923
+ // wait for clear to finish, VTextField sets _search to null
17924
+ // then search computed triggers and updates _search to ''
17925
+ vue.nextTick(() => cleared = false);
17926
+ } else if (isFocused.value && !menu.value) {
17927
+ menu.value = true;
17928
+ }
17929
+ emit('update:search', value);
17930
+ });
17931
+ vue.watch(model, value => {
17932
+ if (!props.multiple && !hasSelectionSlot.value) {
17933
+ _search.value = value[0]?.title ?? '';
17934
+ }
17935
+ });
17936
+ const {
17937
+ filteredItems,
17938
+ getMatches
17939
+ } = useFilter(props, items, () => isPristine.value ? '' : search.value);
17940
+ const displayItems = vue.computed(() => {
17941
+ if (props.hideSelected) {
17942
+ return filteredItems.value.filter(filteredItem => !model.value.some(s => s.value === filteredItem.value));
17943
+ }
17944
+ return filteredItems.value;
17945
+ });
17946
+ const selectedValues = vue.computed(() => model.value.map(selection => selection.value));
17947
+ const highlightFirst = vue.computed(() => {
17948
+ const selectFirst = props.autoSelectFirst === true || props.autoSelectFirst === 'exact' && search.value === displayItems.value[0]?.title;
17949
+ return selectFirst && displayItems.value.length > 0 && !isPristine.value && !listHasFocus.value;
17950
+ });
17951
+ const menuDisabled = vue.computed(() => props.hideNoData && !displayItems.value.length || form.isReadonly.value || form.isDisabled.value);
17952
+ const listRef = vue.ref();
17953
+ const listEvents = useScrolling(listRef, vTextFieldRef);
17954
+ function onClear(e) {
17955
+ cleared = true;
17956
+ if (props.openOnClear) {
17957
+ menu.value = true;
17958
+ }
18215
17959
  }
18216
- }, options);
18217
- return {
18218
- options: _options,
18219
- instance: createInstance(_options, locale)
18220
- };
18221
- }
18222
- function createInstance(options, locale) {
18223
- const instance = vue.reactive(typeof options.adapter === 'function'
18224
- // eslint-disable-next-line new-cap
18225
- ? new options.adapter({
18226
- locale: options.locale[locale.current.value] ?? locale.current.value,
18227
- formats: options.formats
18228
- }) : options.adapter);
18229
- vue.watch(locale.current, value => {
18230
- instance.locale = options.locale[value] ?? value ?? instance.locale;
18231
- });
18232
- return instance;
18233
- }
18234
- function useDate() {
18235
- const options = vue.inject(DateOptionsSymbol);
18236
- if (!options) throw new Error('[Vuetify] Could not find injected date options');
18237
- const locale = useLocale();
18238
- return createInstance(options, locale);
18239
- }
17960
+ function onMousedownControl() {
17961
+ if (menuDisabled.value) return;
17962
+ menu.value = true;
17963
+ }
17964
+ function onMousedownMenuIcon(e) {
17965
+ if (menuDisabled.value) return;
17966
+ if (isFocused.value) {
17967
+ e.preventDefault();
17968
+ e.stopPropagation();
17969
+ }
17970
+ menu.value = !menu.value;
17971
+ }
17972
+ function onListKeydown(e) {
17973
+ if (e.key !== ' ' && checkPrintable(e)) {
17974
+ vTextFieldRef.value?.focus();
17975
+ }
17976
+ }
17977
+ // eslint-disable-next-line complexity
17978
+ function onKeydown(e) {
17979
+ if (isComposingIgnoreKey(e) || form.isReadonly.value) return;
17980
+ const selectionStart = vTextFieldRef.value.selectionStart;
17981
+ const length = model.value.length;
17982
+ if (['Enter', 'ArrowDown', 'ArrowUp'].includes(e.key)) {
17983
+ e.preventDefault();
17984
+ }
17985
+ if (['Enter', 'ArrowDown'].includes(e.key)) {
17986
+ menu.value = true;
17987
+ }
17988
+ if (['Escape'].includes(e.key)) {
17989
+ menu.value = false;
17990
+ }
17991
+ if (['Enter', 'Escape', 'Tab'].includes(e.key)) {
17992
+ if (highlightFirst.value && ['Enter', 'Tab'].includes(e.key) && !model.value.some(_ref2 => {
17993
+ let {
17994
+ value
17995
+ } = _ref2;
17996
+ return value === displayItems.value[0].value;
17997
+ })) {
17998
+ select(filteredItems.value[0]);
17999
+ }
18000
+ isPristine.value = true;
18001
+ }
18002
+ if (e.key === 'ArrowDown' && highlightFirst.value) {
18003
+ listRef.value?.focus('next');
18004
+ }
18005
+ if (e.key === 'Enter' && search.value) {
18006
+ select(transformItem$3(props, search.value));
18007
+ if (hasSelectionSlot.value) _search.value = '';
18008
+ }
18009
+ if (['Backspace', 'Delete'].includes(e.key)) {
18010
+ if (!props.multiple && hasSelectionSlot.value && model.value.length > 0 && !search.value) return select(model.value[0], false);
18011
+ if (~selectionIndex.value) {
18012
+ e.preventDefault();
18013
+ const originalSelectionIndex = selectionIndex.value;
18014
+ select(model.value[selectionIndex.value], false);
18015
+ selectionIndex.value = originalSelectionIndex >= length - 1 ? length - 2 : originalSelectionIndex;
18016
+ } else if (e.key === 'Backspace' && !search.value) {
18017
+ selectionIndex.value = length - 1;
18018
+ }
18019
+ return;
18020
+ }
18021
+ if (!props.multiple) return;
18022
+ if (e.key === 'ArrowLeft') {
18023
+ if (selectionIndex.value < 0 && selectionStart > 0) return;
18024
+ const prev = selectionIndex.value > -1 ? selectionIndex.value - 1 : length - 1;
18025
+ if (model.value[prev]) {
18026
+ selectionIndex.value = prev;
18027
+ } else {
18028
+ selectionIndex.value = -1;
18029
+ vTextFieldRef.value.setSelectionRange(search.value.length, search.value.length);
18030
+ }
18031
+ } else if (e.key === 'ArrowRight') {
18032
+ if (selectionIndex.value < 0) return;
18033
+ const next = selectionIndex.value + 1;
18034
+ if (model.value[next]) {
18035
+ selectionIndex.value = next;
18036
+ } else {
18037
+ selectionIndex.value = -1;
18038
+ vTextFieldRef.value.setSelectionRange(0, 0);
18039
+ }
18040
+ } else if (~selectionIndex.value && checkPrintable(e)) {
18041
+ selectionIndex.value = -1;
18042
+ }
18043
+ }
18044
+ function onAfterEnter() {
18045
+ if (props.eager) {
18046
+ vVirtualScrollRef.value?.calculateVisibleItems();
18047
+ }
18048
+ }
18049
+ function onAfterLeave() {
18050
+ if (isFocused.value) {
18051
+ isPristine.value = true;
18052
+ vTextFieldRef.value?.focus();
18053
+ }
18054
+ }
18055
+ /** @param set - null means toggle */
18056
+ function select(item) {
18057
+ let set = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
18058
+ if (!item || item.props.disabled) return;
18059
+ if (props.multiple) {
18060
+ const index = model.value.findIndex(selection => (props.valueComparator || deepEqual)(selection.value, item.value));
18061
+ const add = set == null ? !~index : set;
18062
+ if (~index) {
18063
+ const value = add ? [...model.value, item] : [...model.value];
18064
+ value.splice(index, 1);
18065
+ model.value = value;
18066
+ } else if (add) {
18067
+ model.value = [...model.value, item];
18068
+ }
18069
+ if (props.clearOnSelect) {
18070
+ search.value = '';
18071
+ }
18072
+ } else {
18073
+ const add = set !== false;
18074
+ model.value = add ? [item] : [];
18075
+ _search.value = add && !hasSelectionSlot.value ? item.title : '';
18240
18076
 
18241
- // https://stackoverflow.com/questions/274861/how-do-i-calculate-the-week-number-given-a-date/275024#275024
18242
- function getWeek(adapter, value) {
18243
- const date = adapter.toJsDate(value);
18244
- let year = date.getFullYear();
18245
- let d1w1 = new Date(year, 0, 1);
18246
- if (date < d1w1) {
18247
- year = year - 1;
18248
- d1w1 = new Date(year, 0, 1);
18249
- } else {
18250
- const tv = new Date(year + 1, 0, 1);
18251
- if (date >= tv) {
18252
- year = year + 1;
18253
- d1w1 = tv;
18077
+ // watch for search watcher to trigger
18078
+ vue.nextTick(() => {
18079
+ menu.value = false;
18080
+ isPristine.value = true;
18081
+ });
18082
+ }
18083
+ }
18084
+ function onFocusin(e) {
18085
+ isFocused.value = true;
18086
+ setTimeout(() => {
18087
+ listHasFocus.value = true;
18088
+ });
18089
+ }
18090
+ function onFocusout(e) {
18091
+ listHasFocus.value = false;
18092
+ }
18093
+ function onUpdateModelValue(v) {
18094
+ if (v == null || v === '' && !props.multiple && !hasSelectionSlot.value) model.value = [];
18254
18095
  }
18096
+ vue.watch(isFocused, (val, oldVal) => {
18097
+ if (val || val === oldVal) return;
18098
+ selectionIndex.value = -1;
18099
+ menu.value = false;
18100
+ if (search.value) {
18101
+ if (props.multiple) {
18102
+ select(transformItem$3(props, search.value));
18103
+ return;
18104
+ }
18105
+ if (!hasSelectionSlot.value) return;
18106
+ if (model.value.some(_ref3 => {
18107
+ let {
18108
+ title
18109
+ } = _ref3;
18110
+ return title === search.value;
18111
+ })) {
18112
+ _search.value = '';
18113
+ } else {
18114
+ select(transformItem$3(props, search.value));
18115
+ }
18116
+ }
18117
+ });
18118
+ vue.watch(menu, () => {
18119
+ if (!props.hideSelected && menu.value && model.value.length) {
18120
+ const index = displayItems.value.findIndex(item => model.value.some(s => (props.valueComparator || deepEqual)(s.value, item.value)));
18121
+ IN_BROWSER && window.requestAnimationFrame(() => {
18122
+ index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index);
18123
+ });
18124
+ }
18125
+ });
18126
+ vue.watch(() => props.items, (newVal, oldVal) => {
18127
+ if (menu.value) return;
18128
+ if (isFocused.value && !oldVal.length && newVal.length) {
18129
+ menu.value = true;
18130
+ }
18131
+ });
18132
+ useRender(() => {
18133
+ const hasList = !!(!props.hideNoData || displayItems.value.length || slots['prepend-item'] || slots['append-item'] || slots['no-data']);
18134
+ const isDirty = model.value.length > 0;
18135
+ const textFieldProps = VTextField.filterProps(props);
18136
+ return vue.createVNode(VTextField, vue.mergeProps({
18137
+ "ref": vTextFieldRef
18138
+ }, textFieldProps, {
18139
+ "modelValue": search.value,
18140
+ "onUpdate:modelValue": [$event => search.value = $event, onUpdateModelValue],
18141
+ "focused": isFocused.value,
18142
+ "onUpdate:focused": $event => isFocused.value = $event,
18143
+ "validationValue": model.externalValue,
18144
+ "counterValue": counterValue.value,
18145
+ "dirty": isDirty,
18146
+ "class": ['v-combobox', {
18147
+ 'v-combobox--active-menu': menu.value,
18148
+ 'v-combobox--chips': !!props.chips,
18149
+ 'v-combobox--selection-slot': !!hasSelectionSlot.value,
18150
+ 'v-combobox--selecting-index': selectionIndex.value > -1,
18151
+ [`v-combobox--${props.multiple ? 'multiple' : 'single'}`]: true
18152
+ }, props.class],
18153
+ "style": props.style,
18154
+ "readonly": form.isReadonly.value,
18155
+ "placeholder": isDirty ? undefined : props.placeholder,
18156
+ "onClick:clear": onClear,
18157
+ "onMousedown:control": onMousedownControl,
18158
+ "onKeydown": onKeydown
18159
+ }), {
18160
+ ...slots,
18161
+ default: () => vue.createVNode(vue.Fragment, null, [vue.createVNode(VMenu, vue.mergeProps({
18162
+ "ref": vMenuRef,
18163
+ "modelValue": menu.value,
18164
+ "onUpdate:modelValue": $event => menu.value = $event,
18165
+ "activator": "parent",
18166
+ "contentClass": "v-combobox__content",
18167
+ "disabled": menuDisabled.value,
18168
+ "eager": props.eager,
18169
+ "maxHeight": 310,
18170
+ "openOnClick": false,
18171
+ "closeOnContentClick": false,
18172
+ "transition": props.transition,
18173
+ "onAfterEnter": onAfterEnter,
18174
+ "onAfterLeave": onAfterLeave
18175
+ }, props.menuProps), {
18176
+ default: () => [hasList && vue.createVNode(VList, vue.mergeProps({
18177
+ "ref": listRef,
18178
+ "selected": selectedValues.value,
18179
+ "selectStrategy": props.multiple ? 'independent' : 'single-independent',
18180
+ "onMousedown": e => e.preventDefault(),
18181
+ "onKeydown": onListKeydown,
18182
+ "onFocusin": onFocusin,
18183
+ "onFocusout": onFocusout,
18184
+ "tabindex": "-1",
18185
+ "aria-live": "polite",
18186
+ "color": props.itemColor ?? props.color
18187
+ }, listEvents, props.listProps), {
18188
+ default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? vue.createVNode(VListItem, {
18189
+ "key": "no-data",
18190
+ "title": t(props.noDataText)
18191
+ }, null)), vue.createVNode(VVirtualScroll, {
18192
+ "ref": vVirtualScrollRef,
18193
+ "renderless": true,
18194
+ "items": displayItems.value,
18195
+ "itemKey": "value"
18196
+ }, {
18197
+ default: _ref4 => {
18198
+ let {
18199
+ item,
18200
+ index,
18201
+ itemRef
18202
+ } = _ref4;
18203
+ const itemProps = vue.mergeProps(item.props, {
18204
+ ref: itemRef,
18205
+ key: item.value,
18206
+ active: highlightFirst.value && index === 0 ? true : undefined,
18207
+ onClick: () => select(item, null)
18208
+ });
18209
+ return slots.item?.({
18210
+ item,
18211
+ index,
18212
+ props: itemProps
18213
+ }) ?? vue.createVNode(VListItem, vue.mergeProps(itemProps, {
18214
+ "role": "option"
18215
+ }), {
18216
+ prepend: _ref5 => {
18217
+ let {
18218
+ isSelected
18219
+ } = _ref5;
18220
+ return vue.createVNode(vue.Fragment, null, [props.multiple && !props.hideSelected ? vue.createVNode(VCheckboxBtn, {
18221
+ "key": item.value,
18222
+ "modelValue": isSelected,
18223
+ "ripple": false,
18224
+ "tabindex": "-1"
18225
+ }, null) : undefined, item.props.prependAvatar && vue.createVNode(VAvatar, {
18226
+ "image": item.props.prependAvatar
18227
+ }, null), item.props.prependIcon && vue.createVNode(VIcon, {
18228
+ "icon": item.props.prependIcon
18229
+ }, null)]);
18230
+ },
18231
+ title: () => {
18232
+ return isPristine.value ? item.title : highlightResult('v-combobox', item.title, getMatches(item)?.title);
18233
+ }
18234
+ });
18235
+ }
18236
+ }), slots['append-item']?.()]
18237
+ })]
18238
+ }), model.value.map((item, index) => {
18239
+ function onChipClose(e) {
18240
+ e.stopPropagation();
18241
+ e.preventDefault();
18242
+ select(item, false);
18243
+ }
18244
+ const slotProps = {
18245
+ 'onClick:close': onChipClose,
18246
+ onKeydown(e) {
18247
+ if (e.key !== 'Enter' && e.key !== ' ') return;
18248
+ e.preventDefault();
18249
+ e.stopPropagation();
18250
+ onChipClose(e);
18251
+ },
18252
+ onMousedown(e) {
18253
+ e.preventDefault();
18254
+ e.stopPropagation();
18255
+ },
18256
+ modelValue: true,
18257
+ 'onUpdate:modelValue': undefined
18258
+ };
18259
+ const hasSlot = hasChips.value ? !!slots.chip : !!slots.selection;
18260
+ const slotContent = hasSlot ? ensureValidVNode(hasChips.value ? slots.chip({
18261
+ item,
18262
+ index,
18263
+ props: slotProps
18264
+ }) : slots.selection({
18265
+ item,
18266
+ index
18267
+ })) : undefined;
18268
+ if (hasSlot && !slotContent) return undefined;
18269
+ return vue.createVNode("div", {
18270
+ "key": item.value,
18271
+ "class": ['v-combobox__selection', index === selectionIndex.value && ['v-combobox__selection--selected', textColorClasses.value]],
18272
+ "style": index === selectionIndex.value ? textColorStyles.value : {}
18273
+ }, [hasChips.value ? !slots.chip ? vue.createVNode(VChip, vue.mergeProps({
18274
+ "key": "chip",
18275
+ "closable": props.closableChips,
18276
+ "size": "small",
18277
+ "text": item.title,
18278
+ "disabled": item.props.disabled
18279
+ }, slotProps), null) : vue.createVNode(VDefaultsProvider, {
18280
+ "key": "chip-defaults",
18281
+ "defaults": {
18282
+ VChip: {
18283
+ closable: props.closableChips,
18284
+ size: 'small',
18285
+ text: item.title
18286
+ }
18287
+ }
18288
+ }, {
18289
+ default: () => [slotContent]
18290
+ }) : slotContent ?? vue.createVNode("span", {
18291
+ "class": "v-combobox__selection-text"
18292
+ }, [item.title, props.multiple && index < model.value.length - 1 && vue.createVNode("span", {
18293
+ "class": "v-combobox__selection-comma"
18294
+ }, [vue.createTextVNode(",")])])]);
18295
+ })]),
18296
+ 'append-inner': function () {
18297
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
18298
+ args[_key] = arguments[_key];
18299
+ }
18300
+ return vue.createVNode(vue.Fragment, null, [slots['append-inner']?.(...args), (!props.hideNoData || props.items.length) && props.menuIcon ? vue.createVNode(VIcon, {
18301
+ "class": "v-combobox__menu-icon",
18302
+ "icon": props.menuIcon,
18303
+ "onMousedown": onMousedownMenuIcon,
18304
+ "onClick": noop,
18305
+ "aria-label": t(label.value),
18306
+ "title": t(label.value),
18307
+ "tabindex": "-1"
18308
+ }, null) : undefined]);
18309
+ }
18310
+ });
18311
+ });
18312
+ return forwardRefs({
18313
+ isFocused,
18314
+ isPristine,
18315
+ menu,
18316
+ search,
18317
+ selectionIndex,
18318
+ filteredItems,
18319
+ select
18320
+ }, vTextFieldRef);
18255
18321
  }
18256
- const diffTime = Math.abs(date.getTime() - d1w1.getTime());
18257
- const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
18258
- return Math.floor(diffDays / 7) + 1;
18259
- }
18322
+ });
18260
18323
 
18261
18324
  // Types
18262
18325
 
@@ -22205,70 +22268,6 @@
22205
22268
  }
22206
22269
  });
22207
22270
 
22208
- // Utilities
22209
- const VPickerTitle = createSimpleFunctional('v-picker-title');
22210
-
22211
- // Types
22212
-
22213
- const makeVPickerProps = propsFactory({
22214
- bgColor: String,
22215
- landscape: Boolean,
22216
- title: String,
22217
- hideHeader: Boolean,
22218
- ...makeVSheetProps()
22219
- }, 'VPicker');
22220
- const VPicker = genericComponent()({
22221
- name: 'VPicker',
22222
- props: makeVPickerProps(),
22223
- setup(props, _ref) {
22224
- let {
22225
- slots
22226
- } = _ref;
22227
- const {
22228
- backgroundColorClasses,
22229
- backgroundColorStyles
22230
- } = useBackgroundColor(vue.toRef(props, 'color'));
22231
- useRender(() => {
22232
- const sheetProps = VSheet.filterProps(props);
22233
- const hasTitle = !!(props.title || slots.title);
22234
- return vue.createVNode(VSheet, vue.mergeProps(sheetProps, {
22235
- "color": props.bgColor,
22236
- "class": ['v-picker', {
22237
- 'v-picker--landscape': props.landscape,
22238
- 'v-picker--with-actions': !!slots.actions
22239
- }, props.class],
22240
- "style": props.style
22241
- }), {
22242
- default: () => [!props.hideHeader && vue.createVNode("div", {
22243
- "key": "header",
22244
- "class": [backgroundColorClasses.value],
22245
- "style": [backgroundColorStyles.value]
22246
- }, [hasTitle && vue.createVNode(VPickerTitle, {
22247
- "key": "picker-title"
22248
- }, {
22249
- default: () => [slots.title?.() ?? props.title]
22250
- }), slots.header && vue.createVNode("div", {
22251
- "class": "v-picker__header"
22252
- }, [slots.header()])]), vue.createVNode("div", {
22253
- "class": "v-picker__body"
22254
- }, [slots.default?.()]), slots.actions && vue.createVNode(VDefaultsProvider, {
22255
- "defaults": {
22256
- VBtn: {
22257
- slim: true,
22258
- variant: 'text'
22259
- }
22260
- }
22261
- }, {
22262
- default: () => [vue.createVNode("div", {
22263
- "class": "v-picker__actions"
22264
- }, [slots.actions()])]
22265
- })]
22266
- });
22267
- });
22268
- return {};
22269
- }
22270
- });
22271
-
22272
22271
  // Types
22273
22272
 
22274
22273
  // Types
@@ -22329,6 +22328,9 @@
22329
22328
  const {
22330
22329
  t
22331
22330
  } = useLocale();
22331
+ const {
22332
+ rtlClasses
22333
+ } = useRtl();
22332
22334
  const model = useProxiedModel(props, 'modelValue', undefined, v => wrapInArray(v), v => props.multiple ? v : v[0]);
22333
22335
  const viewMode = useProxiedModel(props, 'viewMode');
22334
22336
  // const inputMode = useProxiedModel(props, 'inputMode')
@@ -22466,7 +22468,7 @@
22466
22468
  return vue.createVNode(VPicker, vue.mergeProps(pickerProps, {
22467
22469
  "class": ['v-date-picker', `v-date-picker--${viewMode.value}`, {
22468
22470
  'v-date-picker--show-week': props.showWeek
22469
- }, props.class],
22471
+ }, rtlClasses.value, props.class],
22470
22472
  "style": props.style
22471
22473
  }), {
22472
22474
  title: () => slots.title?.() ?? vue.createVNode("div", {
@@ -31161,7 +31163,7 @@
31161
31163
  };
31162
31164
  });
31163
31165
  }
31164
- const version$1 = "3.7.15-dev.2025-03-07";
31166
+ const version$1 = "3.7.15-dev.2025-03-08";
31165
31167
  createVuetify$1.version = version$1;
31166
31168
 
31167
31169
  // Vue's inject() can only be used in setup
@@ -31414,7 +31416,7 @@
31414
31416
 
31415
31417
  /* eslint-disable local-rules/sort-imports */
31416
31418
 
31417
- const version = "3.7.15-dev.2025-03-07";
31419
+ const version = "3.7.15-dev.2025-03-08";
31418
31420
 
31419
31421
  /* eslint-disable local-rules/sort-imports */
31420
31422