@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
package/dist/vuetify.js CHANGED
@@ -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
  */
@@ -16961,6 +16961,9 @@
16961
16961
  }
16962
16962
  });
16963
16963
 
16964
+ // Utilities
16965
+ const VPickerTitle = createSimpleFunctional('v-picker-title');
16966
+
16964
16967
  const makeVSheetProps = propsFactory({
16965
16968
  color: String,
16966
16969
  ...makeBorderProps(),
@@ -17015,665 +17018,66 @@
17015
17018
 
17016
17019
  // Types
17017
17020
 
17018
- const makeVColorPickerProps = propsFactory({
17019
- canvasHeight: {
17020
- type: [String, Number],
17021
- default: 150
17022
- },
17023
- disabled: Boolean,
17024
- dotSize: {
17025
- type: [Number, String],
17026
- default: 10
17027
- },
17028
- hideCanvas: Boolean,
17029
- hideSliders: Boolean,
17030
- hideInputs: Boolean,
17031
- mode: {
17032
- type: String,
17033
- default: 'rgba',
17034
- validator: v => Object.keys(modes).includes(v)
17035
- },
17036
- modes: {
17037
- type: Array,
17038
- default: () => Object.keys(modes),
17039
- validator: v => Array.isArray(v) && v.every(m => Object.keys(modes).includes(m))
17040
- },
17041
- showSwatches: Boolean,
17042
- swatches: Array,
17043
- swatchesMaxHeight: {
17044
- type: [Number, String],
17045
- default: 150
17046
- },
17047
- modelValue: {
17048
- type: [Object, String]
17049
- },
17050
- ...omit(makeVSheetProps({
17051
- width: 300
17052
- }), ['height', 'location', 'minHeight', 'maxHeight', 'minWidth', 'maxWidth'])
17053
- }, 'VColorPicker');
17054
- const VColorPicker = defineComponent({
17055
- name: 'VColorPicker',
17056
- props: makeVColorPickerProps(),
17057
- emits: {
17058
- 'update:modelValue': color => true,
17059
- 'update:mode': mode => true
17060
- },
17061
- setup(props) {
17062
- const mode = useProxiedModel(props, 'mode');
17063
- const hue = vue.ref(null);
17064
- const model = useProxiedModel(props, 'modelValue', undefined, v => {
17065
- if (v == null || v === '') return null;
17066
- let c;
17067
- try {
17068
- c = RGBtoHSV(parseColor(v));
17069
- } catch (err) {
17070
- consoleWarn(err);
17071
- return null;
17072
- }
17073
- return c;
17074
- }, v => {
17075
- if (!v) return null;
17076
- return extractColor(v, props.modelValue);
17077
- });
17078
- const currentColor = vue.computed(() => {
17079
- return model.value ? {
17080
- ...model.value,
17081
- h: hue.value ?? model.value.h
17082
- } : null;
17083
- });
17021
+ const makeVPickerProps = propsFactory({
17022
+ bgColor: String,
17023
+ landscape: Boolean,
17024
+ title: String,
17025
+ hideHeader: Boolean,
17026
+ ...makeVSheetProps()
17027
+ }, 'VPicker');
17028
+ const VPicker = genericComponent()({
17029
+ name: 'VPicker',
17030
+ props: makeVPickerProps(),
17031
+ setup(props, _ref) {
17032
+ let {
17033
+ slots
17034
+ } = _ref;
17084
17035
  const {
17085
- rtlClasses
17086
- } = useRtl();
17087
- let externalChange = true;
17088
- vue.watch(model, v => {
17089
- if (!externalChange) {
17090
- // prevent hue shift from rgb conversion inaccuracy
17091
- externalChange = true;
17092
- return;
17093
- }
17094
- if (!v) return;
17095
- hue.value = v.h;
17096
- }, {
17097
- immediate: true
17098
- });
17099
- const updateColor = hsva => {
17100
- externalChange = false;
17101
- hue.value = hsva.h;
17102
- model.value = hsva;
17103
- };
17104
- vue.onBeforeMount(() => {
17105
- if (!props.modes.includes(mode.value)) mode.value = props.modes[0];
17106
- });
17107
- provideDefaults({
17108
- VSlider: {
17109
- color: undefined,
17110
- trackColor: undefined,
17111
- trackFillColor: undefined
17112
- }
17113
- });
17036
+ backgroundColorClasses,
17037
+ backgroundColorStyles
17038
+ } = useBackgroundColor(vue.toRef(props, 'color'));
17114
17039
  useRender(() => {
17115
17040
  const sheetProps = VSheet.filterProps(props);
17116
- return vue.createVNode(VSheet, vue.mergeProps({
17117
- "rounded": props.rounded,
17118
- "elevation": props.elevation,
17119
- "theme": props.theme,
17120
- "class": ['v-color-picker', rtlClasses.value, props.class],
17121
- "style": [{
17122
- '--v-color-picker-color-hsv': HSVtoCSS({
17123
- ...(currentColor.value ?? nullColor),
17124
- a: 1
17125
- })
17126
- }, props.style]
17127
- }, sheetProps, {
17128
- "maxWidth": props.width
17041
+ const hasTitle = !!(props.title || slots.title);
17042
+ return vue.createVNode(VSheet, vue.mergeProps(sheetProps, {
17043
+ "color": props.bgColor,
17044
+ "class": ['v-picker', {
17045
+ 'v-picker--landscape': props.landscape,
17046
+ 'v-picker--with-actions': !!slots.actions
17047
+ }, props.class],
17048
+ "style": props.style
17129
17049
  }), {
17130
- default: () => [!props.hideCanvas && vue.createVNode(VColorPickerCanvas, {
17131
- "key": "canvas",
17132
- "color": currentColor.value,
17133
- "onUpdate:color": updateColor,
17134
- "disabled": props.disabled,
17135
- "dotSize": props.dotSize,
17136
- "width": props.width,
17137
- "height": props.canvasHeight
17138
- }, null), (!props.hideSliders || !props.hideInputs) && vue.createVNode("div", {
17139
- "key": "controls",
17140
- "class": "v-color-picker__controls"
17141
- }, [!props.hideSliders && vue.createVNode(VColorPickerPreview, {
17142
- "key": "preview",
17143
- "color": currentColor.value,
17144
- "onUpdate:color": updateColor,
17145
- "hideAlpha": !mode.value.endsWith('a'),
17146
- "disabled": props.disabled
17147
- }, null), !props.hideInputs && vue.createVNode(VColorPickerEdit, {
17148
- "key": "edit",
17149
- "modes": props.modes,
17150
- "mode": mode.value,
17151
- "onUpdate:mode": m => mode.value = m,
17152
- "color": currentColor.value,
17153
- "onUpdate:color": updateColor,
17154
- "disabled": props.disabled
17155
- }, null)]), props.showSwatches && vue.createVNode(VColorPickerSwatches, {
17156
- "key": "swatches",
17157
- "color": currentColor.value,
17158
- "onUpdate:color": updateColor,
17159
- "maxHeight": props.swatchesMaxHeight,
17160
- "swatches": props.swatches,
17161
- "disabled": props.disabled
17162
- }, null)]
17050
+ default: () => [!props.hideHeader && vue.createVNode("div", {
17051
+ "key": "header",
17052
+ "class": [backgroundColorClasses.value],
17053
+ "style": [backgroundColorStyles.value]
17054
+ }, [hasTitle && vue.createVNode(VPickerTitle, {
17055
+ "key": "picker-title"
17056
+ }, {
17057
+ default: () => [slots.title?.() ?? props.title]
17058
+ }), slots.header && vue.createVNode("div", {
17059
+ "class": "v-picker__header"
17060
+ }, [slots.header()])]), vue.createVNode("div", {
17061
+ "class": "v-picker__body"
17062
+ }, [slots.default?.()]), slots.actions && vue.createVNode(VDefaultsProvider, {
17063
+ "defaults": {
17064
+ VBtn: {
17065
+ slim: true,
17066
+ variant: 'text'
17067
+ }
17068
+ }
17069
+ }, {
17070
+ default: () => [vue.createVNode("div", {
17071
+ "class": "v-picker__actions"
17072
+ }, [slots.actions()])]
17073
+ })]
17163
17074
  });
17164
17075
  });
17165
17076
  return {};
17166
17077
  }
17167
17078
  });
17168
-
17169
- // Types
17170
-
17171
- const makeVComboboxProps = propsFactory({
17172
- autoSelectFirst: {
17173
- type: [Boolean, String]
17174
- },
17175
- clearOnSelect: {
17176
- type: Boolean,
17177
- default: true
17178
- },
17179
- delimiters: Array,
17180
- ...makeFilterProps({
17181
- filterKeys: ['title']
17182
- }),
17183
- ...makeSelectProps({
17184
- hideNoData: true,
17185
- returnObject: true
17186
- }),
17187
- ...omit(makeVTextFieldProps({
17188
- modelValue: null,
17189
- role: 'combobox'
17190
- }), ['validationValue', 'dirty', 'appendInnerIcon']),
17191
- ...makeTransitionProps({
17192
- transition: false
17193
- })
17194
- }, 'VCombobox');
17195
- const VCombobox = genericComponent()({
17196
- name: 'VCombobox',
17197
- props: makeVComboboxProps(),
17198
- emits: {
17199
- 'update:focused': focused => true,
17200
- 'update:modelValue': value => true,
17201
- 'update:search': value => true,
17202
- 'update:menu': value => true
17203
- },
17204
- setup(props, _ref) {
17205
- let {
17206
- emit,
17207
- slots
17208
- } = _ref;
17209
- const {
17210
- t
17211
- } = useLocale();
17212
- const vTextFieldRef = vue.ref();
17213
- const isFocused = vue.shallowRef(false);
17214
- const isPristine = vue.shallowRef(true);
17215
- const listHasFocus = vue.shallowRef(false);
17216
- const vMenuRef = vue.ref();
17217
- const vVirtualScrollRef = vue.ref();
17218
- const _menu = useProxiedModel(props, 'menu');
17219
- const menu = vue.computed({
17220
- get: () => _menu.value,
17221
- set: v => {
17222
- if (_menu.value && !v && vMenuRef.value?.ΨopenChildren.size) return;
17223
- _menu.value = v;
17224
- }
17225
- });
17226
- const selectionIndex = vue.shallowRef(-1);
17227
- let cleared = false;
17228
- const color = vue.computed(() => vTextFieldRef.value?.color);
17229
- const label = vue.computed(() => menu.value ? props.closeText : props.openText);
17230
- const {
17231
- items,
17232
- transformIn,
17233
- transformOut
17234
- } = useItems(props);
17235
- const {
17236
- textColorClasses,
17237
- textColorStyles
17238
- } = useTextColor(color);
17239
- const model = useProxiedModel(props, 'modelValue', [], v => transformIn(wrapInArray(v)), v => {
17240
- const transformed = transformOut(v);
17241
- return props.multiple ? transformed : transformed[0] ?? null;
17242
- });
17243
- const form = useForm(props);
17244
- const hasChips = vue.computed(() => !!(props.chips || slots.chip));
17245
- const hasSelectionSlot = vue.computed(() => hasChips.value || !!slots.selection);
17246
- const _search = vue.shallowRef(!props.multiple && !hasSelectionSlot.value ? model.value[0]?.title ?? '' : '');
17247
- const search = vue.computed({
17248
- get: () => {
17249
- return _search.value;
17250
- },
17251
- set: val => {
17252
- _search.value = val ?? '';
17253
- if (!props.multiple && !hasSelectionSlot.value) {
17254
- model.value = [transformItem$3(props, val)];
17255
- }
17256
- if (val && props.multiple && props.delimiters?.length) {
17257
- const values = val.split(new RegExp(`(?:${props.delimiters.join('|')})+`));
17258
- if (values.length > 1) {
17259
- values.forEach(v => {
17260
- v = v.trim();
17261
- if (v) select(transformItem$3(props, v));
17262
- });
17263
- _search.value = '';
17264
- }
17265
- }
17266
- if (!val) selectionIndex.value = -1;
17267
- isPristine.value = !val;
17268
- }
17269
- });
17270
- const counterValue = vue.computed(() => {
17271
- return typeof props.counterValue === 'function' ? props.counterValue(model.value) : typeof props.counterValue === 'number' ? props.counterValue : props.multiple ? model.value.length : search.value.length;
17272
- });
17273
- vue.watch(_search, value => {
17274
- if (cleared) {
17275
- // wait for clear to finish, VTextField sets _search to null
17276
- // then search computed triggers and updates _search to ''
17277
- vue.nextTick(() => cleared = false);
17278
- } else if (isFocused.value && !menu.value) {
17279
- menu.value = true;
17280
- }
17281
- emit('update:search', value);
17282
- });
17283
- vue.watch(model, value => {
17284
- if (!props.multiple && !hasSelectionSlot.value) {
17285
- _search.value = value[0]?.title ?? '';
17286
- }
17287
- });
17288
- const {
17289
- filteredItems,
17290
- getMatches
17291
- } = useFilter(props, items, () => isPristine.value ? '' : search.value);
17292
- const displayItems = vue.computed(() => {
17293
- if (props.hideSelected) {
17294
- return filteredItems.value.filter(filteredItem => !model.value.some(s => s.value === filteredItem.value));
17295
- }
17296
- return filteredItems.value;
17297
- });
17298
- const selectedValues = vue.computed(() => model.value.map(selection => selection.value));
17299
- const highlightFirst = vue.computed(() => {
17300
- const selectFirst = props.autoSelectFirst === true || props.autoSelectFirst === 'exact' && search.value === displayItems.value[0]?.title;
17301
- return selectFirst && displayItems.value.length > 0 && !isPristine.value && !listHasFocus.value;
17302
- });
17303
- const menuDisabled = vue.computed(() => props.hideNoData && !displayItems.value.length || form.isReadonly.value || form.isDisabled.value);
17304
- const listRef = vue.ref();
17305
- const listEvents = useScrolling(listRef, vTextFieldRef);
17306
- function onClear(e) {
17307
- cleared = true;
17308
- if (props.openOnClear) {
17309
- menu.value = true;
17310
- }
17311
- }
17312
- function onMousedownControl() {
17313
- if (menuDisabled.value) return;
17314
- menu.value = true;
17315
- }
17316
- function onMousedownMenuIcon(e) {
17317
- if (menuDisabled.value) return;
17318
- if (isFocused.value) {
17319
- e.preventDefault();
17320
- e.stopPropagation();
17321
- }
17322
- menu.value = !menu.value;
17323
- }
17324
- function onListKeydown(e) {
17325
- if (e.key !== ' ' && checkPrintable(e)) {
17326
- vTextFieldRef.value?.focus();
17327
- }
17328
- }
17329
- // eslint-disable-next-line complexity
17330
- function onKeydown(e) {
17331
- if (isComposingIgnoreKey(e) || form.isReadonly.value) return;
17332
- const selectionStart = vTextFieldRef.value.selectionStart;
17333
- const length = model.value.length;
17334
- if (['Enter', 'ArrowDown', 'ArrowUp'].includes(e.key)) {
17335
- e.preventDefault();
17336
- }
17337
- if (['Enter', 'ArrowDown'].includes(e.key)) {
17338
- menu.value = true;
17339
- }
17340
- if (['Escape'].includes(e.key)) {
17341
- menu.value = false;
17342
- }
17343
- if (['Enter', 'Escape', 'Tab'].includes(e.key)) {
17344
- if (highlightFirst.value && ['Enter', 'Tab'].includes(e.key) && !model.value.some(_ref2 => {
17345
- let {
17346
- value
17347
- } = _ref2;
17348
- return value === displayItems.value[0].value;
17349
- })) {
17350
- select(filteredItems.value[0]);
17351
- }
17352
- isPristine.value = true;
17353
- }
17354
- if (e.key === 'ArrowDown' && highlightFirst.value) {
17355
- listRef.value?.focus('next');
17356
- }
17357
- if (e.key === 'Enter' && search.value) {
17358
- select(transformItem$3(props, search.value));
17359
- if (hasSelectionSlot.value) _search.value = '';
17360
- }
17361
- if (['Backspace', 'Delete'].includes(e.key)) {
17362
- if (!props.multiple && hasSelectionSlot.value && model.value.length > 0 && !search.value) return select(model.value[0], false);
17363
- if (~selectionIndex.value) {
17364
- e.preventDefault();
17365
- const originalSelectionIndex = selectionIndex.value;
17366
- select(model.value[selectionIndex.value], false);
17367
- selectionIndex.value = originalSelectionIndex >= length - 1 ? length - 2 : originalSelectionIndex;
17368
- } else if (e.key === 'Backspace' && !search.value) {
17369
- selectionIndex.value = length - 1;
17370
- }
17371
- return;
17372
- }
17373
- if (!props.multiple) return;
17374
- if (e.key === 'ArrowLeft') {
17375
- if (selectionIndex.value < 0 && selectionStart > 0) return;
17376
- const prev = selectionIndex.value > -1 ? selectionIndex.value - 1 : length - 1;
17377
- if (model.value[prev]) {
17378
- selectionIndex.value = prev;
17379
- } else {
17380
- selectionIndex.value = -1;
17381
- vTextFieldRef.value.setSelectionRange(search.value.length, search.value.length);
17382
- }
17383
- } else if (e.key === 'ArrowRight') {
17384
- if (selectionIndex.value < 0) return;
17385
- const next = selectionIndex.value + 1;
17386
- if (model.value[next]) {
17387
- selectionIndex.value = next;
17388
- } else {
17389
- selectionIndex.value = -1;
17390
- vTextFieldRef.value.setSelectionRange(0, 0);
17391
- }
17392
- } else if (~selectionIndex.value && checkPrintable(e)) {
17393
- selectionIndex.value = -1;
17394
- }
17395
- }
17396
- function onAfterEnter() {
17397
- if (props.eager) {
17398
- vVirtualScrollRef.value?.calculateVisibleItems();
17399
- }
17400
- }
17401
- function onAfterLeave() {
17402
- if (isFocused.value) {
17403
- isPristine.value = true;
17404
- vTextFieldRef.value?.focus();
17405
- }
17406
- }
17407
- /** @param set - null means toggle */
17408
- function select(item) {
17409
- let set = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
17410
- if (!item || item.props.disabled) return;
17411
- if (props.multiple) {
17412
- const index = model.value.findIndex(selection => (props.valueComparator || deepEqual)(selection.value, item.value));
17413
- const add = set == null ? !~index : set;
17414
- if (~index) {
17415
- const value = add ? [...model.value, item] : [...model.value];
17416
- value.splice(index, 1);
17417
- model.value = value;
17418
- } else if (add) {
17419
- model.value = [...model.value, item];
17420
- }
17421
- if (props.clearOnSelect) {
17422
- search.value = '';
17423
- }
17424
- } else {
17425
- const add = set !== false;
17426
- model.value = add ? [item] : [];
17427
- _search.value = add && !hasSelectionSlot.value ? item.title : '';
17428
-
17429
- // watch for search watcher to trigger
17430
- vue.nextTick(() => {
17431
- menu.value = false;
17432
- isPristine.value = true;
17433
- });
17434
- }
17435
- }
17436
- function onFocusin(e) {
17437
- isFocused.value = true;
17438
- setTimeout(() => {
17439
- listHasFocus.value = true;
17440
- });
17441
- }
17442
- function onFocusout(e) {
17443
- listHasFocus.value = false;
17444
- }
17445
- function onUpdateModelValue(v) {
17446
- if (v == null || v === '' && !props.multiple && !hasSelectionSlot.value) model.value = [];
17447
- }
17448
- vue.watch(isFocused, (val, oldVal) => {
17449
- if (val || val === oldVal) return;
17450
- selectionIndex.value = -1;
17451
- menu.value = false;
17452
- if (search.value) {
17453
- if (props.multiple) {
17454
- select(transformItem$3(props, search.value));
17455
- return;
17456
- }
17457
- if (!hasSelectionSlot.value) return;
17458
- if (model.value.some(_ref3 => {
17459
- let {
17460
- title
17461
- } = _ref3;
17462
- return title === search.value;
17463
- })) {
17464
- _search.value = '';
17465
- } else {
17466
- select(transformItem$3(props, search.value));
17467
- }
17468
- }
17469
- });
17470
- vue.watch(menu, () => {
17471
- if (!props.hideSelected && menu.value && model.value.length) {
17472
- const index = displayItems.value.findIndex(item => model.value.some(s => (props.valueComparator || deepEqual)(s.value, item.value)));
17473
- IN_BROWSER && window.requestAnimationFrame(() => {
17474
- index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index);
17475
- });
17476
- }
17477
- });
17478
- vue.watch(() => props.items, (newVal, oldVal) => {
17479
- if (menu.value) return;
17480
- if (isFocused.value && !oldVal.length && newVal.length) {
17481
- menu.value = true;
17482
- }
17483
- });
17484
- useRender(() => {
17485
- const hasList = !!(!props.hideNoData || displayItems.value.length || slots['prepend-item'] || slots['append-item'] || slots['no-data']);
17486
- const isDirty = model.value.length > 0;
17487
- const textFieldProps = VTextField.filterProps(props);
17488
- return vue.createVNode(VTextField, vue.mergeProps({
17489
- "ref": vTextFieldRef
17490
- }, textFieldProps, {
17491
- "modelValue": search.value,
17492
- "onUpdate:modelValue": [$event => search.value = $event, onUpdateModelValue],
17493
- "focused": isFocused.value,
17494
- "onUpdate:focused": $event => isFocused.value = $event,
17495
- "validationValue": model.externalValue,
17496
- "counterValue": counterValue.value,
17497
- "dirty": isDirty,
17498
- "class": ['v-combobox', {
17499
- 'v-combobox--active-menu': menu.value,
17500
- 'v-combobox--chips': !!props.chips,
17501
- 'v-combobox--selection-slot': !!hasSelectionSlot.value,
17502
- 'v-combobox--selecting-index': selectionIndex.value > -1,
17503
- [`v-combobox--${props.multiple ? 'multiple' : 'single'}`]: true
17504
- }, props.class],
17505
- "style": props.style,
17506
- "readonly": form.isReadonly.value,
17507
- "placeholder": isDirty ? undefined : props.placeholder,
17508
- "onClick:clear": onClear,
17509
- "onMousedown:control": onMousedownControl,
17510
- "onKeydown": onKeydown
17511
- }), {
17512
- ...slots,
17513
- default: () => vue.createVNode(vue.Fragment, null, [vue.createVNode(VMenu, vue.mergeProps({
17514
- "ref": vMenuRef,
17515
- "modelValue": menu.value,
17516
- "onUpdate:modelValue": $event => menu.value = $event,
17517
- "activator": "parent",
17518
- "contentClass": "v-combobox__content",
17519
- "disabled": menuDisabled.value,
17520
- "eager": props.eager,
17521
- "maxHeight": 310,
17522
- "openOnClick": false,
17523
- "closeOnContentClick": false,
17524
- "transition": props.transition,
17525
- "onAfterEnter": onAfterEnter,
17526
- "onAfterLeave": onAfterLeave
17527
- }, props.menuProps), {
17528
- default: () => [hasList && vue.createVNode(VList, vue.mergeProps({
17529
- "ref": listRef,
17530
- "selected": selectedValues.value,
17531
- "selectStrategy": props.multiple ? 'independent' : 'single-independent',
17532
- "onMousedown": e => e.preventDefault(),
17533
- "onKeydown": onListKeydown,
17534
- "onFocusin": onFocusin,
17535
- "onFocusout": onFocusout,
17536
- "tabindex": "-1",
17537
- "aria-live": "polite",
17538
- "color": props.itemColor ?? props.color
17539
- }, listEvents, props.listProps), {
17540
- default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? vue.createVNode(VListItem, {
17541
- "key": "no-data",
17542
- "title": t(props.noDataText)
17543
- }, null)), vue.createVNode(VVirtualScroll, {
17544
- "ref": vVirtualScrollRef,
17545
- "renderless": true,
17546
- "items": displayItems.value,
17547
- "itemKey": "value"
17548
- }, {
17549
- default: _ref4 => {
17550
- let {
17551
- item,
17552
- index,
17553
- itemRef
17554
- } = _ref4;
17555
- const itemProps = vue.mergeProps(item.props, {
17556
- ref: itemRef,
17557
- key: item.value,
17558
- active: highlightFirst.value && index === 0 ? true : undefined,
17559
- onClick: () => select(item, null)
17560
- });
17561
- return slots.item?.({
17562
- item,
17563
- index,
17564
- props: itemProps
17565
- }) ?? vue.createVNode(VListItem, vue.mergeProps(itemProps, {
17566
- "role": "option"
17567
- }), {
17568
- prepend: _ref5 => {
17569
- let {
17570
- isSelected
17571
- } = _ref5;
17572
- return vue.createVNode(vue.Fragment, null, [props.multiple && !props.hideSelected ? vue.createVNode(VCheckboxBtn, {
17573
- "key": item.value,
17574
- "modelValue": isSelected,
17575
- "ripple": false,
17576
- "tabindex": "-1"
17577
- }, null) : undefined, item.props.prependAvatar && vue.createVNode(VAvatar, {
17578
- "image": item.props.prependAvatar
17579
- }, null), item.props.prependIcon && vue.createVNode(VIcon, {
17580
- "icon": item.props.prependIcon
17581
- }, null)]);
17582
- },
17583
- title: () => {
17584
- return isPristine.value ? item.title : highlightResult('v-combobox', item.title, getMatches(item)?.title);
17585
- }
17586
- });
17587
- }
17588
- }), slots['append-item']?.()]
17589
- })]
17590
- }), model.value.map((item, index) => {
17591
- function onChipClose(e) {
17592
- e.stopPropagation();
17593
- e.preventDefault();
17594
- select(item, false);
17595
- }
17596
- const slotProps = {
17597
- 'onClick:close': onChipClose,
17598
- onKeydown(e) {
17599
- if (e.key !== 'Enter' && e.key !== ' ') return;
17600
- e.preventDefault();
17601
- e.stopPropagation();
17602
- onChipClose(e);
17603
- },
17604
- onMousedown(e) {
17605
- e.preventDefault();
17606
- e.stopPropagation();
17607
- },
17608
- modelValue: true,
17609
- 'onUpdate:modelValue': undefined
17610
- };
17611
- const hasSlot = hasChips.value ? !!slots.chip : !!slots.selection;
17612
- const slotContent = hasSlot ? ensureValidVNode(hasChips.value ? slots.chip({
17613
- item,
17614
- index,
17615
- props: slotProps
17616
- }) : slots.selection({
17617
- item,
17618
- index
17619
- })) : undefined;
17620
- if (hasSlot && !slotContent) return undefined;
17621
- return vue.createVNode("div", {
17622
- "key": item.value,
17623
- "class": ['v-combobox__selection', index === selectionIndex.value && ['v-combobox__selection--selected', textColorClasses.value]],
17624
- "style": index === selectionIndex.value ? textColorStyles.value : {}
17625
- }, [hasChips.value ? !slots.chip ? vue.createVNode(VChip, vue.mergeProps({
17626
- "key": "chip",
17627
- "closable": props.closableChips,
17628
- "size": "small",
17629
- "text": item.title,
17630
- "disabled": item.props.disabled
17631
- }, slotProps), null) : vue.createVNode(VDefaultsProvider, {
17632
- "key": "chip-defaults",
17633
- "defaults": {
17634
- VChip: {
17635
- closable: props.closableChips,
17636
- size: 'small',
17637
- text: item.title
17638
- }
17639
- }
17640
- }, {
17641
- default: () => [slotContent]
17642
- }) : slotContent ?? vue.createVNode("span", {
17643
- "class": "v-combobox__selection-text"
17644
- }, [item.title, props.multiple && index < model.value.length - 1 && vue.createVNode("span", {
17645
- "class": "v-combobox__selection-comma"
17646
- }, [vue.createTextVNode(",")])])]);
17647
- })]),
17648
- 'append-inner': function () {
17649
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
17650
- args[_key] = arguments[_key];
17651
- }
17652
- return vue.createVNode(vue.Fragment, null, [slots['append-inner']?.(...args), (!props.hideNoData || props.items.length) && props.menuIcon ? vue.createVNode(VIcon, {
17653
- "class": "v-combobox__menu-icon",
17654
- "icon": props.menuIcon,
17655
- "onMousedown": onMousedownMenuIcon,
17656
- "onClick": noop,
17657
- "aria-label": t(label.value),
17658
- "title": t(label.value),
17659
- "tabindex": "-1"
17660
- }, null) : undefined]);
17661
- }
17662
- });
17663
- });
17664
- return forwardRefs({
17665
- isFocused,
17666
- isPristine,
17667
- menu,
17668
- search,
17669
- selectionIndex,
17670
- filteredItems,
17671
- select
17672
- }, vTextFieldRef);
17673
- }
17674
- });
17675
-
17676
- // Utilities
17079
+
17080
+ // Utilities
17677
17081
 
17678
17082
  // Types
17679
17083
 
@@ -18395,101 +17799,760 @@
18395
17799
  endOfYear(date) {
18396
17800
  return endOfYear(date);
18397
17801
  }
18398
- }
17802
+ }
17803
+
17804
+ // Composables
17805
+ const DateOptionsSymbol = Symbol.for('vuetify:date-options');
17806
+ const DateAdapterSymbol = Symbol.for('vuetify:date-adapter');
17807
+ function createDate(options, locale) {
17808
+ const _options = mergeDeep({
17809
+ adapter: VuetifyDateAdapter,
17810
+ locale: {
17811
+ af: 'af-ZA',
17812
+ // ar: '', # not the same value for all variants
17813
+ bg: 'bg-BG',
17814
+ ca: 'ca-ES',
17815
+ ckb: '',
17816
+ cs: 'cs-CZ',
17817
+ de: 'de-DE',
17818
+ el: 'el-GR',
17819
+ en: 'en-US',
17820
+ // es: '', # not the same value for all variants
17821
+ et: 'et-EE',
17822
+ fa: 'fa-IR',
17823
+ fi: 'fi-FI',
17824
+ // fr: '', #not the same value for all variants
17825
+ hr: 'hr-HR',
17826
+ hu: 'hu-HU',
17827
+ he: 'he-IL',
17828
+ id: 'id-ID',
17829
+ it: 'it-IT',
17830
+ ja: 'ja-JP',
17831
+ ko: 'ko-KR',
17832
+ lv: 'lv-LV',
17833
+ lt: 'lt-LT',
17834
+ nl: 'nl-NL',
17835
+ no: 'no-NO',
17836
+ pl: 'pl-PL',
17837
+ pt: 'pt-PT',
17838
+ ro: 'ro-RO',
17839
+ ru: 'ru-RU',
17840
+ sk: 'sk-SK',
17841
+ sl: 'sl-SI',
17842
+ srCyrl: 'sr-SP',
17843
+ srLatn: 'sr-SP',
17844
+ sv: 'sv-SE',
17845
+ th: 'th-TH',
17846
+ tr: 'tr-TR',
17847
+ az: 'az-AZ',
17848
+ uk: 'uk-UA',
17849
+ vi: 'vi-VN',
17850
+ zhHans: 'zh-CN',
17851
+ zhHant: 'zh-TW'
17852
+ }
17853
+ }, options);
17854
+ return {
17855
+ options: _options,
17856
+ instance: createInstance(_options, locale)
17857
+ };
17858
+ }
17859
+ function createInstance(options, locale) {
17860
+ const instance = vue.reactive(typeof options.adapter === 'function'
17861
+ // eslint-disable-next-line new-cap
17862
+ ? new options.adapter({
17863
+ locale: options.locale[locale.current.value] ?? locale.current.value,
17864
+ formats: options.formats
17865
+ }) : options.adapter);
17866
+ vue.watch(locale.current, value => {
17867
+ instance.locale = options.locale[value] ?? value ?? instance.locale;
17868
+ });
17869
+ return instance;
17870
+ }
17871
+ function useDate() {
17872
+ const options = vue.inject(DateOptionsSymbol);
17873
+ if (!options) throw new Error('[Vuetify] Could not find injected date options');
17874
+ const locale = useLocale();
17875
+ return createInstance(options, locale);
17876
+ }
17877
+
17878
+ // https://stackoverflow.com/questions/274861/how-do-i-calculate-the-week-number-given-a-date/275024#275024
17879
+ function getWeek(adapter, value) {
17880
+ const date = adapter.toJsDate(value);
17881
+ let year = date.getFullYear();
17882
+ let d1w1 = new Date(year, 0, 1);
17883
+ if (date < d1w1) {
17884
+ year = year - 1;
17885
+ d1w1 = new Date(year, 0, 1);
17886
+ } else {
17887
+ const tv = new Date(year + 1, 0, 1);
17888
+ if (date >= tv) {
17889
+ year = year + 1;
17890
+ d1w1 = tv;
17891
+ }
17892
+ }
17893
+ const diffTime = Math.abs(date.getTime() - d1w1.getTime());
17894
+ const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
17895
+ return Math.floor(diffDays / 7) + 1;
17896
+ }
17897
+
17898
+ // Types
17899
+
17900
+ const makeVColorPickerProps = propsFactory({
17901
+ canvasHeight: {
17902
+ type: [String, Number],
17903
+ default: 150
17904
+ },
17905
+ disabled: Boolean,
17906
+ dotSize: {
17907
+ type: [Number, String],
17908
+ default: 10
17909
+ },
17910
+ hideCanvas: Boolean,
17911
+ hideSliders: Boolean,
17912
+ hideInputs: Boolean,
17913
+ mode: {
17914
+ type: String,
17915
+ default: 'rgba',
17916
+ validator: v => Object.keys(modes).includes(v)
17917
+ },
17918
+ modes: {
17919
+ type: Array,
17920
+ default: () => Object.keys(modes),
17921
+ validator: v => Array.isArray(v) && v.every(m => Object.keys(modes).includes(m))
17922
+ },
17923
+ showSwatches: Boolean,
17924
+ swatches: Array,
17925
+ swatchesMaxHeight: {
17926
+ type: [Number, String],
17927
+ default: 150
17928
+ },
17929
+ modelValue: {
17930
+ type: [Object, String]
17931
+ },
17932
+ ...makeVPickerProps({
17933
+ hideHeader: true
17934
+ })
17935
+ }, 'VColorPicker');
17936
+ const VColorPicker = defineComponent({
17937
+ name: 'VColorPicker',
17938
+ props: makeVColorPickerProps(),
17939
+ emits: {
17940
+ 'update:modelValue': color => true,
17941
+ 'update:mode': mode => true
17942
+ },
17943
+ setup(props, _ref) {
17944
+ let {
17945
+ slots
17946
+ } = _ref;
17947
+ const mode = useProxiedModel(props, 'mode');
17948
+ const hue = vue.ref(null);
17949
+ const model = useProxiedModel(props, 'modelValue', undefined, v => {
17950
+ if (v == null || v === '') return null;
17951
+ let c;
17952
+ try {
17953
+ c = RGBtoHSV(parseColor(v));
17954
+ } catch (err) {
17955
+ consoleWarn(err);
17956
+ return null;
17957
+ }
17958
+ return c;
17959
+ }, v => {
17960
+ if (!v) return null;
17961
+ return extractColor(v, props.modelValue);
17962
+ });
17963
+ const currentColor = vue.computed(() => {
17964
+ return model.value ? {
17965
+ ...model.value,
17966
+ h: hue.value ?? model.value.h
17967
+ } : null;
17968
+ });
17969
+ const {
17970
+ rtlClasses
17971
+ } = useRtl();
17972
+ let externalChange = true;
17973
+ vue.watch(model, v => {
17974
+ if (!externalChange) {
17975
+ // prevent hue shift from rgb conversion inaccuracy
17976
+ externalChange = true;
17977
+ return;
17978
+ }
17979
+ if (!v) return;
17980
+ hue.value = v.h;
17981
+ }, {
17982
+ immediate: true
17983
+ });
17984
+ const updateColor = hsva => {
17985
+ externalChange = false;
17986
+ hue.value = hsva.h;
17987
+ model.value = hsva;
17988
+ };
17989
+ vue.onBeforeMount(() => {
17990
+ if (!props.modes.includes(mode.value)) mode.value = props.modes[0];
17991
+ });
17992
+ provideDefaults({
17993
+ VSlider: {
17994
+ color: undefined,
17995
+ trackColor: undefined,
17996
+ trackFillColor: undefined
17997
+ }
17998
+ });
17999
+ useRender(() => {
18000
+ const pickerProps = VPicker.filterProps(props);
18001
+ return vue.createVNode(VPicker, vue.mergeProps(pickerProps, {
18002
+ "class": ['v-color-picker', rtlClasses.value, props.class],
18003
+ "style": [{
18004
+ '--v-color-picker-color-hsv': HSVtoCSS({
18005
+ ...(currentColor.value ?? nullColor),
18006
+ a: 1
18007
+ })
18008
+ }, props.style]
18009
+ }), {
18010
+ ...slots,
18011
+ default: () => vue.createVNode(vue.Fragment, null, [!props.hideCanvas && vue.createVNode(VColorPickerCanvas, {
18012
+ "key": "canvas",
18013
+ "color": currentColor.value,
18014
+ "onUpdate:color": updateColor,
18015
+ "disabled": props.disabled,
18016
+ "dotSize": props.dotSize,
18017
+ "width": props.width,
18018
+ "height": props.canvasHeight
18019
+ }, null), (!props.hideSliders || !props.hideInputs) && vue.createVNode("div", {
18020
+ "key": "controls",
18021
+ "class": "v-color-picker__controls"
18022
+ }, [!props.hideSliders && vue.createVNode(VColorPickerPreview, {
18023
+ "key": "preview",
18024
+ "color": currentColor.value,
18025
+ "onUpdate:color": updateColor,
18026
+ "hideAlpha": !mode.value.endsWith('a'),
18027
+ "disabled": props.disabled
18028
+ }, null), !props.hideInputs && vue.createVNode(VColorPickerEdit, {
18029
+ "key": "edit",
18030
+ "modes": props.modes,
18031
+ "mode": mode.value,
18032
+ "onUpdate:mode": m => mode.value = m,
18033
+ "color": currentColor.value,
18034
+ "onUpdate:color": updateColor,
18035
+ "disabled": props.disabled
18036
+ }, null)]), props.showSwatches && vue.createVNode(VColorPickerSwatches, {
18037
+ "key": "swatches",
18038
+ "color": currentColor.value,
18039
+ "onUpdate:color": updateColor,
18040
+ "maxHeight": props.swatchesMaxHeight,
18041
+ "swatches": props.swatches,
18042
+ "disabled": props.disabled
18043
+ }, null)])
18044
+ });
18045
+ });
18046
+ return {};
18047
+ }
18048
+ });
18399
18049
 
18400
- // Composables
18401
- const DateOptionsSymbol = Symbol.for('vuetify:date-options');
18402
- const DateAdapterSymbol = Symbol.for('vuetify:date-adapter');
18403
- function createDate(options, locale) {
18404
- const _options = mergeDeep({
18405
- adapter: VuetifyDateAdapter,
18406
- locale: {
18407
- af: 'af-ZA',
18408
- // ar: '', # not the same value for all variants
18409
- bg: 'bg-BG',
18410
- ca: 'ca-ES',
18411
- ckb: '',
18412
- cs: 'cs-CZ',
18413
- de: 'de-DE',
18414
- el: 'el-GR',
18415
- en: 'en-US',
18416
- // es: '', # not the same value for all variants
18417
- et: 'et-EE',
18418
- fa: 'fa-IR',
18419
- fi: 'fi-FI',
18420
- // fr: '', #not the same value for all variants
18421
- hr: 'hr-HR',
18422
- hu: 'hu-HU',
18423
- he: 'he-IL',
18424
- id: 'id-ID',
18425
- it: 'it-IT',
18426
- ja: 'ja-JP',
18427
- ko: 'ko-KR',
18428
- lv: 'lv-LV',
18429
- lt: 'lt-LT',
18430
- nl: 'nl-NL',
18431
- no: 'no-NO',
18432
- pl: 'pl-PL',
18433
- pt: 'pt-PT',
18434
- ro: 'ro-RO',
18435
- ru: 'ru-RU',
18436
- sk: 'sk-SK',
18437
- sl: 'sl-SI',
18438
- srCyrl: 'sr-SP',
18439
- srLatn: 'sr-SP',
18440
- sv: 'sv-SE',
18441
- th: 'th-TH',
18442
- tr: 'tr-TR',
18443
- az: 'az-AZ',
18444
- uk: 'uk-UA',
18445
- vi: 'vi-VN',
18446
- zhHans: 'zh-CN',
18447
- zhHant: 'zh-TW'
18050
+ // Types
18051
+
18052
+ const makeVComboboxProps = propsFactory({
18053
+ autoSelectFirst: {
18054
+ type: [Boolean, String]
18055
+ },
18056
+ clearOnSelect: {
18057
+ type: Boolean,
18058
+ default: true
18059
+ },
18060
+ delimiters: Array,
18061
+ ...makeFilterProps({
18062
+ filterKeys: ['title']
18063
+ }),
18064
+ ...makeSelectProps({
18065
+ hideNoData: true,
18066
+ returnObject: true
18067
+ }),
18068
+ ...omit(makeVTextFieldProps({
18069
+ modelValue: null,
18070
+ role: 'combobox'
18071
+ }), ['validationValue', 'dirty', 'appendInnerIcon']),
18072
+ ...makeTransitionProps({
18073
+ transition: false
18074
+ })
18075
+ }, 'VCombobox');
18076
+ const VCombobox = genericComponent()({
18077
+ name: 'VCombobox',
18078
+ props: makeVComboboxProps(),
18079
+ emits: {
18080
+ 'update:focused': focused => true,
18081
+ 'update:modelValue': value => true,
18082
+ 'update:search': value => true,
18083
+ 'update:menu': value => true
18084
+ },
18085
+ setup(props, _ref) {
18086
+ let {
18087
+ emit,
18088
+ slots
18089
+ } = _ref;
18090
+ const {
18091
+ t
18092
+ } = useLocale();
18093
+ const vTextFieldRef = vue.ref();
18094
+ const isFocused = vue.shallowRef(false);
18095
+ const isPristine = vue.shallowRef(true);
18096
+ const listHasFocus = vue.shallowRef(false);
18097
+ const vMenuRef = vue.ref();
18098
+ const vVirtualScrollRef = vue.ref();
18099
+ const _menu = useProxiedModel(props, 'menu');
18100
+ const menu = vue.computed({
18101
+ get: () => _menu.value,
18102
+ set: v => {
18103
+ if (_menu.value && !v && vMenuRef.value?.ΨopenChildren.size) return;
18104
+ _menu.value = v;
18105
+ }
18106
+ });
18107
+ const selectionIndex = vue.shallowRef(-1);
18108
+ let cleared = false;
18109
+ const color = vue.computed(() => vTextFieldRef.value?.color);
18110
+ const label = vue.computed(() => menu.value ? props.closeText : props.openText);
18111
+ const {
18112
+ items,
18113
+ transformIn,
18114
+ transformOut
18115
+ } = useItems(props);
18116
+ const {
18117
+ textColorClasses,
18118
+ textColorStyles
18119
+ } = useTextColor(color);
18120
+ const model = useProxiedModel(props, 'modelValue', [], v => transformIn(wrapInArray(v)), v => {
18121
+ const transformed = transformOut(v);
18122
+ return props.multiple ? transformed : transformed[0] ?? null;
18123
+ });
18124
+ const form = useForm(props);
18125
+ const hasChips = vue.computed(() => !!(props.chips || slots.chip));
18126
+ const hasSelectionSlot = vue.computed(() => hasChips.value || !!slots.selection);
18127
+ const _search = vue.shallowRef(!props.multiple && !hasSelectionSlot.value ? model.value[0]?.title ?? '' : '');
18128
+ const search = vue.computed({
18129
+ get: () => {
18130
+ return _search.value;
18131
+ },
18132
+ set: val => {
18133
+ _search.value = val ?? '';
18134
+ if (!props.multiple && !hasSelectionSlot.value) {
18135
+ model.value = [transformItem$3(props, val)];
18136
+ }
18137
+ if (val && props.multiple && props.delimiters?.length) {
18138
+ const values = val.split(new RegExp(`(?:${props.delimiters.join('|')})+`));
18139
+ if (values.length > 1) {
18140
+ values.forEach(v => {
18141
+ v = v.trim();
18142
+ if (v) select(transformItem$3(props, v));
18143
+ });
18144
+ _search.value = '';
18145
+ }
18146
+ }
18147
+ if (!val) selectionIndex.value = -1;
18148
+ isPristine.value = !val;
18149
+ }
18150
+ });
18151
+ const counterValue = vue.computed(() => {
18152
+ return typeof props.counterValue === 'function' ? props.counterValue(model.value) : typeof props.counterValue === 'number' ? props.counterValue : props.multiple ? model.value.length : search.value.length;
18153
+ });
18154
+ vue.watch(_search, value => {
18155
+ if (cleared) {
18156
+ // wait for clear to finish, VTextField sets _search to null
18157
+ // then search computed triggers and updates _search to ''
18158
+ vue.nextTick(() => cleared = false);
18159
+ } else if (isFocused.value && !menu.value) {
18160
+ menu.value = true;
18161
+ }
18162
+ emit('update:search', value);
18163
+ });
18164
+ vue.watch(model, value => {
18165
+ if (!props.multiple && !hasSelectionSlot.value) {
18166
+ _search.value = value[0]?.title ?? '';
18167
+ }
18168
+ });
18169
+ const {
18170
+ filteredItems,
18171
+ getMatches
18172
+ } = useFilter(props, items, () => isPristine.value ? '' : search.value);
18173
+ const displayItems = vue.computed(() => {
18174
+ if (props.hideSelected) {
18175
+ return filteredItems.value.filter(filteredItem => !model.value.some(s => s.value === filteredItem.value));
18176
+ }
18177
+ return filteredItems.value;
18178
+ });
18179
+ const selectedValues = vue.computed(() => model.value.map(selection => selection.value));
18180
+ const highlightFirst = vue.computed(() => {
18181
+ const selectFirst = props.autoSelectFirst === true || props.autoSelectFirst === 'exact' && search.value === displayItems.value[0]?.title;
18182
+ return selectFirst && displayItems.value.length > 0 && !isPristine.value && !listHasFocus.value;
18183
+ });
18184
+ const menuDisabled = vue.computed(() => props.hideNoData && !displayItems.value.length || form.isReadonly.value || form.isDisabled.value);
18185
+ const listRef = vue.ref();
18186
+ const listEvents = useScrolling(listRef, vTextFieldRef);
18187
+ function onClear(e) {
18188
+ cleared = true;
18189
+ if (props.openOnClear) {
18190
+ menu.value = true;
18191
+ }
18448
18192
  }
18449
- }, options);
18450
- return {
18451
- options: _options,
18452
- instance: createInstance(_options, locale)
18453
- };
18454
- }
18455
- function createInstance(options, locale) {
18456
- const instance = vue.reactive(typeof options.adapter === 'function'
18457
- // eslint-disable-next-line new-cap
18458
- ? new options.adapter({
18459
- locale: options.locale[locale.current.value] ?? locale.current.value,
18460
- formats: options.formats
18461
- }) : options.adapter);
18462
- vue.watch(locale.current, value => {
18463
- instance.locale = options.locale[value] ?? value ?? instance.locale;
18464
- });
18465
- return instance;
18466
- }
18467
- function useDate() {
18468
- const options = vue.inject(DateOptionsSymbol);
18469
- if (!options) throw new Error('[Vuetify] Could not find injected date options');
18470
- const locale = useLocale();
18471
- return createInstance(options, locale);
18472
- }
18193
+ function onMousedownControl() {
18194
+ if (menuDisabled.value) return;
18195
+ menu.value = true;
18196
+ }
18197
+ function onMousedownMenuIcon(e) {
18198
+ if (menuDisabled.value) return;
18199
+ if (isFocused.value) {
18200
+ e.preventDefault();
18201
+ e.stopPropagation();
18202
+ }
18203
+ menu.value = !menu.value;
18204
+ }
18205
+ function onListKeydown(e) {
18206
+ if (e.key !== ' ' && checkPrintable(e)) {
18207
+ vTextFieldRef.value?.focus();
18208
+ }
18209
+ }
18210
+ // eslint-disable-next-line complexity
18211
+ function onKeydown(e) {
18212
+ if (isComposingIgnoreKey(e) || form.isReadonly.value) return;
18213
+ const selectionStart = vTextFieldRef.value.selectionStart;
18214
+ const length = model.value.length;
18215
+ if (['Enter', 'ArrowDown', 'ArrowUp'].includes(e.key)) {
18216
+ e.preventDefault();
18217
+ }
18218
+ if (['Enter', 'ArrowDown'].includes(e.key)) {
18219
+ menu.value = true;
18220
+ }
18221
+ if (['Escape'].includes(e.key)) {
18222
+ menu.value = false;
18223
+ }
18224
+ if (['Enter', 'Escape', 'Tab'].includes(e.key)) {
18225
+ if (highlightFirst.value && ['Enter', 'Tab'].includes(e.key) && !model.value.some(_ref2 => {
18226
+ let {
18227
+ value
18228
+ } = _ref2;
18229
+ return value === displayItems.value[0].value;
18230
+ })) {
18231
+ select(filteredItems.value[0]);
18232
+ }
18233
+ isPristine.value = true;
18234
+ }
18235
+ if (e.key === 'ArrowDown' && highlightFirst.value) {
18236
+ listRef.value?.focus('next');
18237
+ }
18238
+ if (e.key === 'Enter' && search.value) {
18239
+ select(transformItem$3(props, search.value));
18240
+ if (hasSelectionSlot.value) _search.value = '';
18241
+ }
18242
+ if (['Backspace', 'Delete'].includes(e.key)) {
18243
+ if (!props.multiple && hasSelectionSlot.value && model.value.length > 0 && !search.value) return select(model.value[0], false);
18244
+ if (~selectionIndex.value) {
18245
+ e.preventDefault();
18246
+ const originalSelectionIndex = selectionIndex.value;
18247
+ select(model.value[selectionIndex.value], false);
18248
+ selectionIndex.value = originalSelectionIndex >= length - 1 ? length - 2 : originalSelectionIndex;
18249
+ } else if (e.key === 'Backspace' && !search.value) {
18250
+ selectionIndex.value = length - 1;
18251
+ }
18252
+ return;
18253
+ }
18254
+ if (!props.multiple) return;
18255
+ if (e.key === 'ArrowLeft') {
18256
+ if (selectionIndex.value < 0 && selectionStart > 0) return;
18257
+ const prev = selectionIndex.value > -1 ? selectionIndex.value - 1 : length - 1;
18258
+ if (model.value[prev]) {
18259
+ selectionIndex.value = prev;
18260
+ } else {
18261
+ selectionIndex.value = -1;
18262
+ vTextFieldRef.value.setSelectionRange(search.value.length, search.value.length);
18263
+ }
18264
+ } else if (e.key === 'ArrowRight') {
18265
+ if (selectionIndex.value < 0) return;
18266
+ const next = selectionIndex.value + 1;
18267
+ if (model.value[next]) {
18268
+ selectionIndex.value = next;
18269
+ } else {
18270
+ selectionIndex.value = -1;
18271
+ vTextFieldRef.value.setSelectionRange(0, 0);
18272
+ }
18273
+ } else if (~selectionIndex.value && checkPrintable(e)) {
18274
+ selectionIndex.value = -1;
18275
+ }
18276
+ }
18277
+ function onAfterEnter() {
18278
+ if (props.eager) {
18279
+ vVirtualScrollRef.value?.calculateVisibleItems();
18280
+ }
18281
+ }
18282
+ function onAfterLeave() {
18283
+ if (isFocused.value) {
18284
+ isPristine.value = true;
18285
+ vTextFieldRef.value?.focus();
18286
+ }
18287
+ }
18288
+ /** @param set - null means toggle */
18289
+ function select(item) {
18290
+ let set = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
18291
+ if (!item || item.props.disabled) return;
18292
+ if (props.multiple) {
18293
+ const index = model.value.findIndex(selection => (props.valueComparator || deepEqual)(selection.value, item.value));
18294
+ const add = set == null ? !~index : set;
18295
+ if (~index) {
18296
+ const value = add ? [...model.value, item] : [...model.value];
18297
+ value.splice(index, 1);
18298
+ model.value = value;
18299
+ } else if (add) {
18300
+ model.value = [...model.value, item];
18301
+ }
18302
+ if (props.clearOnSelect) {
18303
+ search.value = '';
18304
+ }
18305
+ } else {
18306
+ const add = set !== false;
18307
+ model.value = add ? [item] : [];
18308
+ _search.value = add && !hasSelectionSlot.value ? item.title : '';
18473
18309
 
18474
- // https://stackoverflow.com/questions/274861/how-do-i-calculate-the-week-number-given-a-date/275024#275024
18475
- function getWeek(adapter, value) {
18476
- const date = adapter.toJsDate(value);
18477
- let year = date.getFullYear();
18478
- let d1w1 = new Date(year, 0, 1);
18479
- if (date < d1w1) {
18480
- year = year - 1;
18481
- d1w1 = new Date(year, 0, 1);
18482
- } else {
18483
- const tv = new Date(year + 1, 0, 1);
18484
- if (date >= tv) {
18485
- year = year + 1;
18486
- d1w1 = tv;
18310
+ // watch for search watcher to trigger
18311
+ vue.nextTick(() => {
18312
+ menu.value = false;
18313
+ isPristine.value = true;
18314
+ });
18315
+ }
18316
+ }
18317
+ function onFocusin(e) {
18318
+ isFocused.value = true;
18319
+ setTimeout(() => {
18320
+ listHasFocus.value = true;
18321
+ });
18322
+ }
18323
+ function onFocusout(e) {
18324
+ listHasFocus.value = false;
18325
+ }
18326
+ function onUpdateModelValue(v) {
18327
+ if (v == null || v === '' && !props.multiple && !hasSelectionSlot.value) model.value = [];
18487
18328
  }
18329
+ vue.watch(isFocused, (val, oldVal) => {
18330
+ if (val || val === oldVal) return;
18331
+ selectionIndex.value = -1;
18332
+ menu.value = false;
18333
+ if (search.value) {
18334
+ if (props.multiple) {
18335
+ select(transformItem$3(props, search.value));
18336
+ return;
18337
+ }
18338
+ if (!hasSelectionSlot.value) return;
18339
+ if (model.value.some(_ref3 => {
18340
+ let {
18341
+ title
18342
+ } = _ref3;
18343
+ return title === search.value;
18344
+ })) {
18345
+ _search.value = '';
18346
+ } else {
18347
+ select(transformItem$3(props, search.value));
18348
+ }
18349
+ }
18350
+ });
18351
+ vue.watch(menu, () => {
18352
+ if (!props.hideSelected && menu.value && model.value.length) {
18353
+ const index = displayItems.value.findIndex(item => model.value.some(s => (props.valueComparator || deepEqual)(s.value, item.value)));
18354
+ IN_BROWSER && window.requestAnimationFrame(() => {
18355
+ index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index);
18356
+ });
18357
+ }
18358
+ });
18359
+ vue.watch(() => props.items, (newVal, oldVal) => {
18360
+ if (menu.value) return;
18361
+ if (isFocused.value && !oldVal.length && newVal.length) {
18362
+ menu.value = true;
18363
+ }
18364
+ });
18365
+ useRender(() => {
18366
+ const hasList = !!(!props.hideNoData || displayItems.value.length || slots['prepend-item'] || slots['append-item'] || slots['no-data']);
18367
+ const isDirty = model.value.length > 0;
18368
+ const textFieldProps = VTextField.filterProps(props);
18369
+ return vue.createVNode(VTextField, vue.mergeProps({
18370
+ "ref": vTextFieldRef
18371
+ }, textFieldProps, {
18372
+ "modelValue": search.value,
18373
+ "onUpdate:modelValue": [$event => search.value = $event, onUpdateModelValue],
18374
+ "focused": isFocused.value,
18375
+ "onUpdate:focused": $event => isFocused.value = $event,
18376
+ "validationValue": model.externalValue,
18377
+ "counterValue": counterValue.value,
18378
+ "dirty": isDirty,
18379
+ "class": ['v-combobox', {
18380
+ 'v-combobox--active-menu': menu.value,
18381
+ 'v-combobox--chips': !!props.chips,
18382
+ 'v-combobox--selection-slot': !!hasSelectionSlot.value,
18383
+ 'v-combobox--selecting-index': selectionIndex.value > -1,
18384
+ [`v-combobox--${props.multiple ? 'multiple' : 'single'}`]: true
18385
+ }, props.class],
18386
+ "style": props.style,
18387
+ "readonly": form.isReadonly.value,
18388
+ "placeholder": isDirty ? undefined : props.placeholder,
18389
+ "onClick:clear": onClear,
18390
+ "onMousedown:control": onMousedownControl,
18391
+ "onKeydown": onKeydown
18392
+ }), {
18393
+ ...slots,
18394
+ default: () => vue.createVNode(vue.Fragment, null, [vue.createVNode(VMenu, vue.mergeProps({
18395
+ "ref": vMenuRef,
18396
+ "modelValue": menu.value,
18397
+ "onUpdate:modelValue": $event => menu.value = $event,
18398
+ "activator": "parent",
18399
+ "contentClass": "v-combobox__content",
18400
+ "disabled": menuDisabled.value,
18401
+ "eager": props.eager,
18402
+ "maxHeight": 310,
18403
+ "openOnClick": false,
18404
+ "closeOnContentClick": false,
18405
+ "transition": props.transition,
18406
+ "onAfterEnter": onAfterEnter,
18407
+ "onAfterLeave": onAfterLeave
18408
+ }, props.menuProps), {
18409
+ default: () => [hasList && vue.createVNode(VList, vue.mergeProps({
18410
+ "ref": listRef,
18411
+ "selected": selectedValues.value,
18412
+ "selectStrategy": props.multiple ? 'independent' : 'single-independent',
18413
+ "onMousedown": e => e.preventDefault(),
18414
+ "onKeydown": onListKeydown,
18415
+ "onFocusin": onFocusin,
18416
+ "onFocusout": onFocusout,
18417
+ "tabindex": "-1",
18418
+ "aria-live": "polite",
18419
+ "color": props.itemColor ?? props.color
18420
+ }, listEvents, props.listProps), {
18421
+ default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? vue.createVNode(VListItem, {
18422
+ "key": "no-data",
18423
+ "title": t(props.noDataText)
18424
+ }, null)), vue.createVNode(VVirtualScroll, {
18425
+ "ref": vVirtualScrollRef,
18426
+ "renderless": true,
18427
+ "items": displayItems.value,
18428
+ "itemKey": "value"
18429
+ }, {
18430
+ default: _ref4 => {
18431
+ let {
18432
+ item,
18433
+ index,
18434
+ itemRef
18435
+ } = _ref4;
18436
+ const itemProps = vue.mergeProps(item.props, {
18437
+ ref: itemRef,
18438
+ key: item.value,
18439
+ active: highlightFirst.value && index === 0 ? true : undefined,
18440
+ onClick: () => select(item, null)
18441
+ });
18442
+ return slots.item?.({
18443
+ item,
18444
+ index,
18445
+ props: itemProps
18446
+ }) ?? vue.createVNode(VListItem, vue.mergeProps(itemProps, {
18447
+ "role": "option"
18448
+ }), {
18449
+ prepend: _ref5 => {
18450
+ let {
18451
+ isSelected
18452
+ } = _ref5;
18453
+ return vue.createVNode(vue.Fragment, null, [props.multiple && !props.hideSelected ? vue.createVNode(VCheckboxBtn, {
18454
+ "key": item.value,
18455
+ "modelValue": isSelected,
18456
+ "ripple": false,
18457
+ "tabindex": "-1"
18458
+ }, null) : undefined, item.props.prependAvatar && vue.createVNode(VAvatar, {
18459
+ "image": item.props.prependAvatar
18460
+ }, null), item.props.prependIcon && vue.createVNode(VIcon, {
18461
+ "icon": item.props.prependIcon
18462
+ }, null)]);
18463
+ },
18464
+ title: () => {
18465
+ return isPristine.value ? item.title : highlightResult('v-combobox', item.title, getMatches(item)?.title);
18466
+ }
18467
+ });
18468
+ }
18469
+ }), slots['append-item']?.()]
18470
+ })]
18471
+ }), model.value.map((item, index) => {
18472
+ function onChipClose(e) {
18473
+ e.stopPropagation();
18474
+ e.preventDefault();
18475
+ select(item, false);
18476
+ }
18477
+ const slotProps = {
18478
+ 'onClick:close': onChipClose,
18479
+ onKeydown(e) {
18480
+ if (e.key !== 'Enter' && e.key !== ' ') return;
18481
+ e.preventDefault();
18482
+ e.stopPropagation();
18483
+ onChipClose(e);
18484
+ },
18485
+ onMousedown(e) {
18486
+ e.preventDefault();
18487
+ e.stopPropagation();
18488
+ },
18489
+ modelValue: true,
18490
+ 'onUpdate:modelValue': undefined
18491
+ };
18492
+ const hasSlot = hasChips.value ? !!slots.chip : !!slots.selection;
18493
+ const slotContent = hasSlot ? ensureValidVNode(hasChips.value ? slots.chip({
18494
+ item,
18495
+ index,
18496
+ props: slotProps
18497
+ }) : slots.selection({
18498
+ item,
18499
+ index
18500
+ })) : undefined;
18501
+ if (hasSlot && !slotContent) return undefined;
18502
+ return vue.createVNode("div", {
18503
+ "key": item.value,
18504
+ "class": ['v-combobox__selection', index === selectionIndex.value && ['v-combobox__selection--selected', textColorClasses.value]],
18505
+ "style": index === selectionIndex.value ? textColorStyles.value : {}
18506
+ }, [hasChips.value ? !slots.chip ? vue.createVNode(VChip, vue.mergeProps({
18507
+ "key": "chip",
18508
+ "closable": props.closableChips,
18509
+ "size": "small",
18510
+ "text": item.title,
18511
+ "disabled": item.props.disabled
18512
+ }, slotProps), null) : vue.createVNode(VDefaultsProvider, {
18513
+ "key": "chip-defaults",
18514
+ "defaults": {
18515
+ VChip: {
18516
+ closable: props.closableChips,
18517
+ size: 'small',
18518
+ text: item.title
18519
+ }
18520
+ }
18521
+ }, {
18522
+ default: () => [slotContent]
18523
+ }) : slotContent ?? vue.createVNode("span", {
18524
+ "class": "v-combobox__selection-text"
18525
+ }, [item.title, props.multiple && index < model.value.length - 1 && vue.createVNode("span", {
18526
+ "class": "v-combobox__selection-comma"
18527
+ }, [vue.createTextVNode(",")])])]);
18528
+ })]),
18529
+ 'append-inner': function () {
18530
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
18531
+ args[_key] = arguments[_key];
18532
+ }
18533
+ return vue.createVNode(vue.Fragment, null, [slots['append-inner']?.(...args), (!props.hideNoData || props.items.length) && props.menuIcon ? vue.createVNode(VIcon, {
18534
+ "class": "v-combobox__menu-icon",
18535
+ "icon": props.menuIcon,
18536
+ "onMousedown": onMousedownMenuIcon,
18537
+ "onClick": noop,
18538
+ "aria-label": t(label.value),
18539
+ "title": t(label.value),
18540
+ "tabindex": "-1"
18541
+ }, null) : undefined]);
18542
+ }
18543
+ });
18544
+ });
18545
+ return forwardRefs({
18546
+ isFocused,
18547
+ isPristine,
18548
+ menu,
18549
+ search,
18550
+ selectionIndex,
18551
+ filteredItems,
18552
+ select
18553
+ }, vTextFieldRef);
18488
18554
  }
18489
- const diffTime = Math.abs(date.getTime() - d1w1.getTime());
18490
- const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
18491
- return Math.floor(diffDays / 7) + 1;
18492
- }
18555
+ });
18493
18556
 
18494
18557
  // Types
18495
18558
 
@@ -22438,70 +22501,6 @@
22438
22501
  }
22439
22502
  });
22440
22503
 
22441
- // Utilities
22442
- const VPickerTitle = createSimpleFunctional('v-picker-title');
22443
-
22444
- // Types
22445
-
22446
- const makeVPickerProps = propsFactory({
22447
- bgColor: String,
22448
- landscape: Boolean,
22449
- title: String,
22450
- hideHeader: Boolean,
22451
- ...makeVSheetProps()
22452
- }, 'VPicker');
22453
- const VPicker = genericComponent()({
22454
- name: 'VPicker',
22455
- props: makeVPickerProps(),
22456
- setup(props, _ref) {
22457
- let {
22458
- slots
22459
- } = _ref;
22460
- const {
22461
- backgroundColorClasses,
22462
- backgroundColorStyles
22463
- } = useBackgroundColor(vue.toRef(props, 'color'));
22464
- useRender(() => {
22465
- const sheetProps = VSheet.filterProps(props);
22466
- const hasTitle = !!(props.title || slots.title);
22467
- return vue.createVNode(VSheet, vue.mergeProps(sheetProps, {
22468
- "color": props.bgColor,
22469
- "class": ['v-picker', {
22470
- 'v-picker--landscape': props.landscape,
22471
- 'v-picker--with-actions': !!slots.actions
22472
- }, props.class],
22473
- "style": props.style
22474
- }), {
22475
- default: () => [!props.hideHeader && vue.createVNode("div", {
22476
- "key": "header",
22477
- "class": [backgroundColorClasses.value],
22478
- "style": [backgroundColorStyles.value]
22479
- }, [hasTitle && vue.createVNode(VPickerTitle, {
22480
- "key": "picker-title"
22481
- }, {
22482
- default: () => [slots.title?.() ?? props.title]
22483
- }), slots.header && vue.createVNode("div", {
22484
- "class": "v-picker__header"
22485
- }, [slots.header()])]), vue.createVNode("div", {
22486
- "class": "v-picker__body"
22487
- }, [slots.default?.()]), slots.actions && vue.createVNode(VDefaultsProvider, {
22488
- "defaults": {
22489
- VBtn: {
22490
- slim: true,
22491
- variant: 'text'
22492
- }
22493
- }
22494
- }, {
22495
- default: () => [vue.createVNode("div", {
22496
- "class": "v-picker__actions"
22497
- }, [slots.actions()])]
22498
- })]
22499
- });
22500
- });
22501
- return {};
22502
- }
22503
- });
22504
-
22505
22504
  // Types
22506
22505
 
22507
22506
  // Types
@@ -22562,6 +22561,9 @@
22562
22561
  const {
22563
22562
  t
22564
22563
  } = useLocale();
22564
+ const {
22565
+ rtlClasses
22566
+ } = useRtl();
22565
22567
  const model = useProxiedModel(props, 'modelValue', undefined, v => wrapInArray(v), v => props.multiple ? v : v[0]);
22566
22568
  const viewMode = useProxiedModel(props, 'viewMode');
22567
22569
  // const inputMode = useProxiedModel(props, 'inputMode')
@@ -22699,7 +22701,7 @@
22699
22701
  return vue.createVNode(VPicker, vue.mergeProps(pickerProps, {
22700
22702
  "class": ['v-date-picker', `v-date-picker--${viewMode.value}`, {
22701
22703
  'v-date-picker--show-week': props.showWeek
22702
- }, props.class],
22704
+ }, rtlClasses.value, props.class],
22703
22705
  "style": props.style
22704
22706
  }), {
22705
22707
  title: () => slots.title?.() ?? vue.createVNode("div", {
@@ -28530,7 +28532,7 @@
28530
28532
  };
28531
28533
  });
28532
28534
  }
28533
- const version$1 = "3.7.15-dev.2025-03-07";
28535
+ const version$1 = "3.7.15-dev.2025-03-08";
28534
28536
  createVuetify$1.version = version$1;
28535
28537
 
28536
28538
  // Vue's inject() can only be used in setup
@@ -28555,7 +28557,7 @@
28555
28557
  ...options
28556
28558
  });
28557
28559
  };
28558
- const version = "3.7.15-dev.2025-03-07";
28560
+ const version = "3.7.15-dev.2025-03-08";
28559
28561
  createVuetify.version = version;
28560
28562
 
28561
28563
  exports.blueprints = index;