@vuetify/nightly 4.0.0-dev-20230419.0 → 4.0.0-dev-20230422.0

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 (121) hide show
  1. package/CHANGELOG.md +7 -2
  2. package/dist/json/attributes.json +172 -108
  3. package/dist/json/importMap.json +58 -58
  4. package/dist/json/tags.json +16 -0
  5. package/dist/json/web-types.json +522 -220
  6. package/dist/vuetify-labs.css +335 -172
  7. package/dist/vuetify-labs.d.ts +620 -171
  8. package/dist/vuetify-labs.esm.js +864 -182
  9. package/dist/vuetify-labs.esm.js.map +1 -1
  10. package/dist/vuetify-labs.js +864 -181
  11. package/dist/vuetify-labs.min.css +2 -2
  12. package/dist/vuetify.css +166 -3
  13. package/dist/vuetify.d.ts +584 -167
  14. package/dist/vuetify.esm.js +806 -134
  15. package/dist/vuetify.esm.js.map +1 -1
  16. package/dist/vuetify.js +806 -133
  17. package/dist/vuetify.js.map +1 -1
  18. package/dist/vuetify.min.css +2 -2
  19. package/dist/vuetify.min.js +748 -682
  20. package/dist/vuetify.min.js.map +1 -1
  21. package/lib/adapters/date-adapter.mjs +2 -0
  22. package/lib/adapters/date-adapter.mjs.map +1 -0
  23. package/lib/adapters/vuetify.mjs +399 -0
  24. package/lib/adapters/vuetify.mjs.map +1 -0
  25. package/lib/blueprints/index.d.ts +34 -0
  26. package/lib/blueprints/md1.d.ts +34 -0
  27. package/lib/blueprints/md2.d.ts +34 -0
  28. package/lib/blueprints/md3.d.ts +34 -0
  29. package/lib/components/VAppBar/VAppBar.mjs +62 -10
  30. package/lib/components/VAppBar/VAppBar.mjs.map +1 -1
  31. package/lib/components/VAppBar/index.d.ts +26 -0
  32. package/lib/components/VAutocomplete/VAutocomplete.css +9 -0
  33. package/lib/components/VAutocomplete/VAutocomplete.mjs +50 -6
  34. package/lib/components/VAutocomplete/VAutocomplete.mjs.map +1 -1
  35. package/lib/components/VAutocomplete/VAutocomplete.sass +10 -0
  36. package/lib/components/VAutocomplete/index.d.ts +29 -17
  37. package/lib/components/VBtn/_mixins.scss +1 -1
  38. package/lib/components/VCard/VCard.mjs.map +1 -1
  39. package/lib/components/VCard/index.d.ts +21 -16
  40. package/lib/components/VCheckbox/VCheckbox.mjs +2 -2
  41. package/lib/components/VCheckbox/VCheckbox.mjs.map +1 -1
  42. package/lib/components/VCheckbox/index.d.ts +22 -1
  43. package/lib/components/VCombobox/VCombobox.css +1 -1
  44. package/lib/components/VCombobox/VCombobox.mjs +6 -4
  45. package/lib/components/VCombobox/VCombobox.mjs.map +1 -1
  46. package/lib/components/VCombobox/VCombobox.sass +1 -1
  47. package/lib/components/VCombobox/index.d.ts +29 -17
  48. package/lib/components/VField/index.d.ts +6 -0
  49. package/lib/components/VFileInput/VFileInput.mjs +13 -17
  50. package/lib/components/VFileInput/VFileInput.mjs.map +1 -1
  51. package/lib/components/VFileInput/index.d.ts +68 -23
  52. package/lib/components/VInput/VInput.mjs +14 -7
  53. package/lib/components/VInput/VInput.mjs.map +1 -1
  54. package/lib/components/VInput/index.d.ts +22 -1
  55. package/lib/components/VOverlay/locationStrategies.mjs +9 -4
  56. package/lib/components/VOverlay/locationStrategies.mjs.map +1 -1
  57. package/lib/components/VRadioGroup/VRadioGroup.mjs +2 -2
  58. package/lib/components/VRadioGroup/VRadioGroup.mjs.map +1 -1
  59. package/lib/components/VRadioGroup/index.d.ts +22 -1
  60. package/lib/components/VRangeSlider/VRangeSlider.mjs +33 -22
  61. package/lib/components/VRangeSlider/VRangeSlider.mjs.map +1 -1
  62. package/lib/components/VRangeSlider/index.d.ts +39 -6
  63. package/lib/components/VSelect/VSelect.mjs +6 -0
  64. package/lib/components/VSelect/VSelect.mjs.map +1 -1
  65. package/lib/components/VSelect/index.d.ts +32 -17
  66. package/lib/components/VSlider/VSlider.mjs +33 -15
  67. package/lib/components/VSlider/VSlider.mjs.map +1 -1
  68. package/lib/components/VSlider/index.d.ts +39 -6
  69. package/lib/components/VSlider/slider.mjs +43 -23
  70. package/lib/components/VSlider/slider.mjs.map +1 -1
  71. package/lib/components/VSwitch/VSwitch.mjs +5 -3
  72. package/lib/components/VSwitch/VSwitch.mjs.map +1 -1
  73. package/lib/components/VSwitch/index.d.ts +43 -1
  74. package/lib/components/VTextField/VTextField.mjs +4 -12
  75. package/lib/components/VTextField/VTextField.mjs.map +1 -1
  76. package/lib/components/VTextField/index.d.ts +70 -22
  77. package/lib/components/VTextarea/VTextarea.mjs +4 -12
  78. package/lib/components/VTextarea/VTextarea.mjs.map +1 -1
  79. package/lib/components/VTextarea/index.d.ts +61 -22
  80. package/lib/components/VToolbar/VToolbar.css +3 -1
  81. package/lib/components/VToolbar/VToolbar.sass +3 -1
  82. package/lib/components/VValidation/index.d.ts +10 -1
  83. package/lib/components/index.d.ts +525 -150
  84. package/lib/composables/date.mjs +39 -0
  85. package/lib/composables/date.mjs.map +1 -0
  86. package/lib/composables/focus.mjs +3 -2
  87. package/lib/composables/focus.mjs.map +1 -1
  88. package/lib/composables/index.mjs +1 -0
  89. package/lib/composables/index.mjs.map +1 -1
  90. package/lib/composables/items.mjs +7 -2
  91. package/lib/composables/items.mjs.map +1 -1
  92. package/lib/composables/scroll.mjs +3 -0
  93. package/lib/composables/scroll.mjs.map +1 -1
  94. package/lib/entry-bundler.mjs +1 -1
  95. package/lib/framework.mjs +8 -3
  96. package/lib/framework.mjs.map +1 -1
  97. package/lib/iconsets/mdi-svg.mjs +2 -2
  98. package/lib/iconsets/mdi-svg.mjs.map +1 -1
  99. package/lib/index.d.ts +59 -17
  100. package/lib/labs/VDataTable/VDataTable.mjs +2 -2
  101. package/lib/labs/VDataTable/VDataTable.mjs.map +1 -1
  102. package/lib/labs/VDataTable/VDataTableFooter.mjs.map +1 -1
  103. package/lib/labs/VDataTable/VDataTableHeaders.mjs.map +1 -1
  104. package/lib/labs/VDataTable/VDataTableRows.mjs +52 -44
  105. package/lib/labs/VDataTable/VDataTableRows.mjs.map +1 -1
  106. package/lib/labs/VDataTable/VDataTableServer.mjs +2 -1
  107. package/lib/labs/VDataTable/VDataTableServer.mjs.map +1 -1
  108. package/lib/labs/VDataTable/VDataTableVirtual.mjs +0 -1
  109. package/lib/labs/VDataTable/VDataTableVirtual.mjs.map +1 -1
  110. package/lib/labs/VDataTable/composables/options.mjs +2 -1
  111. package/lib/labs/VDataTable/composables/options.mjs.map +1 -1
  112. package/lib/labs/VDataTable/index.d.ts +44 -11
  113. package/lib/labs/VSkeletonLoader/VSkeletonLoader.mjs +1 -0
  114. package/lib/labs/VSkeletonLoader/VSkeletonLoader.mjs.map +1 -1
  115. package/lib/labs/VSkeletonLoader/index.d.ts +9 -9
  116. package/lib/labs/components.d.ts +53 -20
  117. package/lib/styles/main.css +152 -0
  118. package/lib/styles/settings/_utilities.scss +11 -1
  119. package/lib/util/helpers.mjs +4 -0
  120. package/lib/util/helpers.mjs.map +1 -1
  121. package/package.json +2 -2
package/dist/vuetify.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v4.0.0-dev-20230419.0
2
+ * Vuetify v4.0.0-dev-20230422.0
3
3
  * Forged by John Leider
4
4
  * Released under the MIT License.
5
5
  */
@@ -3253,6 +3253,98 @@
3253
3253
 
3254
3254
  // Utilities
3255
3255
 
3256
+ // Types
3257
+
3258
+ // Composables
3259
+ const makeScrollProps = propsFactory({
3260
+ scrollTarget: {
3261
+ type: String
3262
+ },
3263
+ scrollThreshold: {
3264
+ type: [String, Number]
3265
+ }
3266
+ }, 'scroll');
3267
+ function useScroll(props) {
3268
+ let args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
3269
+ const {
3270
+ thresholdMetCallback,
3271
+ scrollThreshold,
3272
+ canScroll
3273
+ } = args;
3274
+ let previousScroll = 0;
3275
+ const target = vue.ref(null);
3276
+ const currentScroll = vue.ref(0);
3277
+ const savedScroll = vue.ref(0);
3278
+ const currentThreshold = vue.ref(0);
3279
+ const isScrollActive = vue.ref(false);
3280
+ const isScrollingUp = vue.ref(false);
3281
+ const computedScrollThreshold = vue.computed(() => {
3282
+ return Number(props.scrollThreshold ?? scrollThreshold ?? 300);
3283
+ });
3284
+ const onScroll = () => {
3285
+ const targetEl = target.value;
3286
+ if (!targetEl || canScroll && !canScroll.value) return;
3287
+ previousScroll = currentScroll.value;
3288
+ currentScroll.value = 'window' in targetEl ? targetEl.pageYOffset : targetEl.scrollTop;
3289
+ isScrollingUp.value = currentScroll.value < previousScroll;
3290
+ currentThreshold.value = Math.abs(currentScroll.value - computedScrollThreshold.value);
3291
+ };
3292
+ vue.watch(isScrollingUp, () => {
3293
+ savedScroll.value = savedScroll.value || currentScroll.value;
3294
+ });
3295
+ vue.watch(isScrollActive, () => {
3296
+ savedScroll.value = 0;
3297
+ });
3298
+ vue.onMounted(() => {
3299
+ vue.watch(() => props.scrollTarget, scrollTarget => {
3300
+ const newTarget = scrollTarget ? document.querySelector(scrollTarget) : window;
3301
+ if (!newTarget) {
3302
+ consoleWarn(`Unable to locate element with identifier ${scrollTarget}`, vue.getCurrentInstance());
3303
+ return;
3304
+ }
3305
+ if (newTarget === target.value) return;
3306
+ target.value?.removeEventListener('scroll', onScroll);
3307
+ target.value = newTarget;
3308
+ target.value.addEventListener('scroll', onScroll, {
3309
+ passive: true
3310
+ });
3311
+ }, {
3312
+ immediate: true
3313
+ });
3314
+ });
3315
+ vue.onBeforeUnmount(() => {
3316
+ target.value?.removeEventListener('scroll', onScroll);
3317
+ });
3318
+ thresholdMetCallback && vue.watch(() => Math.abs(currentScroll.value - savedScroll.value) > computedScrollThreshold.value, thresholdMet => {
3319
+ thresholdMet && thresholdMetCallback({
3320
+ currentThreshold: currentThreshold.value,
3321
+ isScrollingUp: isScrollingUp.value,
3322
+ savedScroll
3323
+ });
3324
+ }, {
3325
+ immediate: true
3326
+ });
3327
+
3328
+ // Do we need this? If yes - seems that
3329
+ // there's no need to expose onScroll
3330
+ canScroll && vue.watch(canScroll, onScroll, {
3331
+ immediate: true
3332
+ });
3333
+ return {
3334
+ computedScrollThreshold,
3335
+ currentScroll,
3336
+ currentThreshold,
3337
+ isScrollActive,
3338
+ // required only for testing
3339
+ // probably can be removed
3340
+ // later (2 chars chlng)
3341
+ isScrollingUp,
3342
+ savedScroll
3343
+ };
3344
+ }
3345
+
3346
+ // Utilities
3347
+
3256
3348
  // Composables
3257
3349
  function useSsrBoot() {
3258
3350
  const isBooted = vue.ref(false);
@@ -3275,13 +3367,7 @@
3275
3367
  const VAppBar = genericComponent()({
3276
3368
  name: 'VAppBar',
3277
3369
  props: {
3278
- // TODO: Implement scrolling techniques
3279
- // hideOnScroll: Boolean
3280
- // invertedScroll: Boolean
3281
- // collapseOnScroll: Boolean
3282
- // elevateOnScroll: Boolean
3283
- // shrinkOnScroll: Boolean
3284
- // fadeImageOnScroll: Boolean
3370
+ scrollBehavior: String,
3285
3371
  modelValue: {
3286
3372
  type: Boolean,
3287
3373
  default: true
@@ -3293,6 +3379,7 @@
3293
3379
  },
3294
3380
  ...makeVToolbarProps(),
3295
3381
  ...makeLayoutItemProps(),
3382
+ ...makeScrollProps(),
3296
3383
  height: {
3297
3384
  type: [Number, String],
3298
3385
  default: 64
@@ -3307,11 +3394,63 @@
3307
3394
  } = _ref;
3308
3395
  const vToolbarRef = vue.ref();
3309
3396
  const isActive = useProxiedModel(props, 'modelValue');
3397
+ const scrollBehavior = vue.computed(() => {
3398
+ const behavior = new Set(props.scrollBehavior?.split(' ') ?? []);
3399
+ return {
3400
+ hide: behavior.has('hide'),
3401
+ // fullyHide: behavior.has('fully-hide'),
3402
+ inverted: behavior.has('inverted'),
3403
+ collapse: behavior.has('collapse'),
3404
+ elevate: behavior.has('elevate'),
3405
+ fadeImage: behavior.has('fade-image')
3406
+ // shrink: behavior.has('shrink'),
3407
+ };
3408
+ });
3409
+
3410
+ const canScroll = vue.computed(() => {
3411
+ const behavior = scrollBehavior.value;
3412
+ return behavior.hide ||
3413
+ // behavior.fullyHide ||
3414
+ behavior.inverted || behavior.collapse || behavior.elevate || behavior.fadeImage ||
3415
+ // behavior.shrink ||
3416
+ !isActive.value;
3417
+ });
3418
+ const {
3419
+ currentScroll,
3420
+ currentThreshold,
3421
+ computedScrollThreshold,
3422
+ isScrollingUp
3423
+ } = useScroll(props, {
3424
+ canScroll
3425
+ });
3426
+ const isCollapsed = vue.computed(() => props.collapse || scrollBehavior.value.collapse && (scrollBehavior.value.inverted ? currentScroll.value < 1 : currentScroll.value > 0));
3427
+ const isFlat = vue.computed(() => props.flat || scrollBehavior.value.elevate && currentScroll.value === (scrollBehavior.value.inverted ? 1 : 0));
3428
+ const scrollRatio = vue.computed(() => Math.min((currentThreshold.value - currentScroll.value) / currentThreshold.value || 1, 1));
3429
+ const opacity = vue.computed(() => scrollBehavior.value.fadeImage ? scrollBehavior.value.inverted ? 1 - scrollRatio.value : scrollRatio.value : undefined);
3310
3430
  const height = vue.computed(() => {
3431
+ if (scrollBehavior.value.hide && scrollBehavior.value.inverted) return 0;
3311
3432
  const height = vToolbarRef.value?.contentHeight ?? 0;
3312
3433
  const extensionHeight = vToolbarRef.value?.extensionHeight ?? 0;
3313
3434
  return height + extensionHeight;
3314
3435
  });
3436
+ function setActive() {
3437
+ const val = currentScroll.value;
3438
+ if (scrollBehavior.value.hide) {
3439
+ if (scrollBehavior.value.inverted) {
3440
+ isActive.value = val > computedScrollThreshold.value;
3441
+ } else {
3442
+ isActive.value = isScrollingUp.value || val < computedScrollThreshold.value;
3443
+ }
3444
+ } else if (scrollBehavior.value.inverted) {
3445
+ isActive.value = currentScroll.value === 0;
3446
+ } else {
3447
+ isActive.value = true;
3448
+ }
3449
+ }
3450
+ vue.watch(currentScroll, setActive, {
3451
+ immediate: true
3452
+ });
3453
+ vue.watch(scrollBehavior, setActive);
3315
3454
  const {
3316
3455
  ssrBootStyles
3317
3456
  } = useSsrBoot();
@@ -3322,7 +3461,7 @@
3322
3461
  order: vue.computed(() => parseInt(props.order, 10)),
3323
3462
  position: vue.toRef(props, 'location'),
3324
3463
  layoutSize: height,
3325
- elementSize: height,
3464
+ elementSize: vue.ref(undefined),
3326
3465
  active: isActive,
3327
3466
  absolute: vue.toRef(props, 'absolute')
3328
3467
  });
@@ -3335,10 +3474,14 @@
3335
3474
  }],
3336
3475
  "style": {
3337
3476
  ...layoutItemStyles.value,
3477
+ '--v-toolbar-image-opacity': opacity.value,
3338
3478
  height: undefined,
3339
3479
  ...ssrBootStyles.value
3340
3480
  }
3341
- }, toolbarProps), slots);
3481
+ }, toolbarProps, {
3482
+ "collapse": isCollapsed.value,
3483
+ "flat": isFlat.value
3484
+ }), slots);
3342
3485
  });
3343
3486
  return {};
3344
3487
  }
@@ -5296,7 +5439,8 @@
5296
5439
 
5297
5440
  // Composables
5298
5441
  const makeFocusProps = propsFactory({
5299
- focused: Boolean
5442
+ focused: Boolean,
5443
+ 'onUpdate:focused': EventProp()
5300
5444
  }, 'focus');
5301
5445
  function useFocus(props) {
5302
5446
  let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
@@ -5891,6 +6035,8 @@
5891
6035
  appendIcon: IconValue,
5892
6036
  prependIcon: IconValue,
5893
6037
  hideDetails: [Boolean, String],
6038
+ hint: String,
6039
+ persistentHint: Boolean,
5894
6040
  messages: {
5895
6041
  type: [Array, String],
5896
6042
  default: () => []
@@ -5954,10 +6100,19 @@
5954
6100
  resetValidation,
5955
6101
  validate
5956
6102
  }));
6103
+ const messages = vue.computed(() => {
6104
+ if (errorMessages.value.length > 0) {
6105
+ return errorMessages.value;
6106
+ } else if (props.hint && (props.persistentHint || props.focused)) {
6107
+ return props.hint;
6108
+ } else {
6109
+ return props.messages;
6110
+ }
6111
+ });
5957
6112
  useRender(() => {
5958
6113
  const hasPrepend = !!(slots.prepend || props.prependIcon);
5959
6114
  const hasAppend = !!(slots.append || props.appendIcon);
5960
- const hasMessages = !!(props.messages?.length || errorMessages.value.length);
6115
+ const hasMessages = messages.value.length > 0;
5961
6116
  const hasDetails = !props.hideDetails || props.hideDetails === 'auto' && (hasMessages || !!slots.details);
5962
6117
  return vue.createVNode("div", {
5963
6118
  "class": ['v-input', `v-input--${props.direction}`, densityClasses.value, validationClasses.value]
@@ -5980,7 +6135,7 @@
5980
6135
  }, [vue.createVNode(VMessages, {
5981
6136
  "id": messagesId.value,
5982
6137
  "active": hasMessages,
5983
- "messages": errorMessages.value.length > 0 ? errorMessages.value : props.messages
6138
+ "messages": messages.value
5984
6139
  }, {
5985
6140
  message: slots.message
5986
6141
  }), slots.details?.(slotProps.value)])]);
@@ -5992,10 +6147,6 @@
5992
6147
  };
5993
6148
  }
5994
6149
  });
5995
- function filterInputProps(props) {
5996
- const keys = Object.keys(VInput.props).filter(k => !isOn(k));
5997
- return pick(props, keys);
5998
- }
5999
6150
 
6000
6151
  const VCounter = genericComponent()({
6001
6152
  name: 'VCounter',
@@ -6121,8 +6272,6 @@
6121
6272
  autofocus: Boolean,
6122
6273
  counter: [Boolean, Number, String],
6123
6274
  counterValue: Function,
6124
- hint: String,
6125
- persistentHint: Boolean,
6126
6275
  prefix: String,
6127
6276
  placeholder: String,
6128
6277
  persistentPlaceholder: Boolean,
@@ -6177,9 +6326,6 @@
6177
6326
  const vFieldRef = vue.ref();
6178
6327
  const inputRef = vue.ref();
6179
6328
  const isActive = vue.computed(() => activeTypes.includes(props.type) || props.persistentPlaceholder || isFocused.value);
6180
- const messages = vue.computed(() => {
6181
- return props.messages.length ? props.messages : isFocused.value || props.persistentHint ? props.hint : '';
6182
- });
6183
6329
  function onFocus() {
6184
6330
  if (inputRef.value !== document.activeElement) {
6185
6331
  inputRef.value?.focus();
@@ -6222,7 +6368,7 @@
6222
6368
  const [{
6223
6369
  modelValue: _,
6224
6370
  ...inputProps
6225
- }] = filterInputProps(props);
6371
+ }] = VInput.filterProps(props);
6226
6372
  const [fieldProps] = filterFieldProps(props);
6227
6373
  return vue.createVNode(VInput, vue.mergeProps({
6228
6374
  "ref": vInputRef,
@@ -6232,12 +6378,9 @@
6232
6378
  'v-text-field--prefixed': props.prefix,
6233
6379
  'v-text-field--suffixed': props.suffix,
6234
6380
  'v-text-field--flush-details': ['plain', 'underlined'].includes(props.variant)
6235
- }],
6236
- "onClick:prepend": props['onClick:prepend'],
6237
- "onClick:append": props['onClick:append']
6381
+ }]
6238
6382
  }, rootAttrs, inputProps, {
6239
- "focused": isFocused.value,
6240
- "messages": messages.value
6383
+ "focused": isFocused.value
6241
6384
  }), {
6242
6385
  ...slots,
6243
6386
  default: _ref2 => {
@@ -6646,7 +6789,7 @@
6646
6789
  const id = vue.computed(() => props.id || `checkbox-${uid}`);
6647
6790
  useRender(() => {
6648
6791
  const [inputAttrs, controlAttrs] = filterInputAttrs(attrs);
6649
- const [inputProps, _1] = filterInputProps(props);
6792
+ const [inputProps, _1] = VInput.filterProps(props);
6650
6793
  const [checkboxProps, _2] = VCheckboxBtn.filterProps(props);
6651
6794
  return vue.createVNode(VInput, vue.mergeProps({
6652
6795
  "class": "v-checkbox"
@@ -8058,7 +8201,12 @@
8058
8201
  function useItems(props) {
8059
8202
  const items = vue.computed(() => transformItems$1(props, props.items));
8060
8203
  function transformIn(value) {
8061
- return value.map(item => transformItem$1(props, item));
8204
+ return value.map(v => {
8205
+ const existingItem = items.value.find(item => deepEqual(v, item.value));
8206
+ // Nullish existingItem means value is a custom input value from combobox
8207
+ // In this case, use transformItem to create an InternalItem based on value
8208
+ return existingItem ?? transformItem$1(props, v);
8209
+ });
8062
8210
  }
8063
8211
  function transformOut(value) {
8064
8212
  return value.map(_ref => {
@@ -8736,7 +8884,7 @@
8736
8884
  }
8737
8885
 
8738
8886
  /** Get size of element ignoring max-width/max-height */
8739
- function getIntrinsicSize(el) {
8887
+ function getIntrinsicSize(el, isRtl) {
8740
8888
  // const scrollables = new Map<Element, [number, number]>()
8741
8889
  // el.querySelectorAll('*').forEach(el => {
8742
8890
  // const x = el.scrollLeft
@@ -8753,7 +8901,11 @@
8753
8901
 
8754
8902
  /* eslint-disable-next-line sonarjs/prefer-immediate-return */
8755
8903
  const contentBox = nullifyTransforms(el);
8756
- contentBox.x -= parseFloat(el.style.left || 0);
8904
+ if (isRtl) {
8905
+ contentBox.x += parseFloat(el.style.right || 0);
8906
+ } else {
8907
+ contentBox.x -= parseFloat(el.style.left || 0);
8908
+ }
8757
8909
  contentBox.y -= parseFloat(el.style.top || 0);
8758
8910
 
8759
8911
  // el.style.maxWidth = initialMaxWidth
@@ -8834,7 +8986,7 @@
8834
8986
  });
8835
8987
  if (!data.activatorEl.value || !data.contentEl.value) return;
8836
8988
  const targetBox = data.activatorEl.value.getBoundingClientRect();
8837
- const contentBox = getIntrinsicSize(data.contentEl.value);
8989
+ const contentBox = getIntrinsicSize(data.contentEl.value, data.isRtl.value);
8838
8990
  const scrollParents = getScrollParents(data.contentEl.value);
8839
8991
  const viewportMargin = 12;
8840
8992
  if (!scrollParents.length) {
@@ -9010,7 +9162,8 @@
9010
9162
  transformOrigin: `${placement.origin.side} ${placement.origin.align}`,
9011
9163
  // transform: `translate(${pixelRound(x)}px, ${pixelRound(y)}px)`,
9012
9164
  top: convertToUnit(pixelRound(y)),
9013
- left: convertToUnit(pixelRound(x)),
9165
+ left: data.isRtl.value ? undefined : convertToUnit(pixelRound(x)),
9166
+ right: data.isRtl.value ? convertToUnit(pixelRound(-x)) : undefined,
9014
9167
  minWidth: convertToUnit(axis === 'y' ? Math.min(minWidth.value, targetBox.width) : minWidth.value),
9015
9168
  maxWidth: convertToUnit(pixelCeil(clamp(available.x, minWidth.value === Infinity ? 0 : minWidth.value, maxWidth.value))),
9016
9169
  maxHeight: convertToUnit(pixelCeil(clamp(available.y, minHeight.value === Infinity ? 0 : minHeight.value, maxHeight.value)))
@@ -9905,6 +10058,7 @@
9905
10058
  })
9906
10059
  },
9907
10060
  emits: {
10061
+ 'update:focused': focused => true,
9908
10062
  'update:modelValue': val => true,
9909
10063
  'update:menu': val => true
9910
10064
  },
@@ -10021,6 +10175,9 @@
10021
10175
  menu.value = false;
10022
10176
  }
10023
10177
  }
10178
+ function onFocusin(e) {
10179
+ isFocused.value = true;
10180
+ }
10024
10181
  function onFocusout(e) {
10025
10182
  if (e.relatedTarget == null) {
10026
10183
  vTextFieldRef.value?.focus();
@@ -10075,6 +10232,7 @@
10075
10232
  "selected": selected.value,
10076
10233
  "selectStrategy": props.multiple ? 'independent' : 'single-independent',
10077
10234
  "onMousedown": e => e.preventDefault(),
10235
+ "onFocusin": onFocusin,
10078
10236
  "onFocusout": onFocusout
10079
10237
  }, {
10080
10238
  default: () => [!displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? vue.createVNode(VListItem, {
@@ -10153,6 +10311,7 @@
10153
10311
  });
10154
10312
  });
10155
10313
  return forwardRefs({
10314
+ isFocused,
10156
10315
  menu,
10157
10316
  select
10158
10317
  }, vTextFieldRef);
@@ -10291,6 +10450,7 @@
10291
10450
  })
10292
10451
  },
10293
10452
  emits: {
10453
+ 'update:focused': focused => true,
10294
10454
  'update:search': val => true,
10295
10455
  'update:modelValue': val => true,
10296
10456
  'update:menu': val => true
@@ -10314,11 +10474,17 @@
10314
10474
  _menu.value = v;
10315
10475
  }
10316
10476
  });
10477
+ const selectionIndex = vue.ref(-1);
10478
+ const color = vue.computed(() => vTextFieldRef.value?.color);
10317
10479
  const {
10318
10480
  items,
10319
10481
  transformIn,
10320
10482
  transformOut
10321
10483
  } = useItems(props);
10484
+ const {
10485
+ textColorClasses,
10486
+ textColorStyles
10487
+ } = useTextColor(color);
10322
10488
  const search = useProxiedModel(props, 'search', '');
10323
10489
  const model = useProxiedModel(props, 'modelValue', [], v => transformIn(wrapInArray(v)), v => {
10324
10490
  const transformed = transformOut(v);
@@ -10341,6 +10507,7 @@
10341
10507
  return filteredItems.value;
10342
10508
  });
10343
10509
  const selected = vue.computed(() => selections.value.map(selection => selection.props.value));
10510
+ const selection = vue.computed(() => selections.value[selectionIndex.value]);
10344
10511
  const listRef = vue.ref();
10345
10512
  function onClear(e) {
10346
10513
  if (props.openOnClear) {
@@ -10354,7 +10521,9 @@
10354
10521
  }
10355
10522
  function onKeydown(e) {
10356
10523
  if (props.readonly || form?.isReadonly.value) return;
10357
- if (['Enter', 'ArrowDown', 'ArrowUp'].includes(e.key)) {
10524
+ const selectionStart = vTextFieldRef.value.selectionStart;
10525
+ const length = selected.value.length;
10526
+ if (selectionIndex.value > -1 || ['Enter', 'ArrowDown', 'ArrowUp'].includes(e.key)) {
10358
10527
  e.preventDefault();
10359
10528
  }
10360
10529
  if (['Enter', 'ArrowDown'].includes(e.key)) {
@@ -10371,6 +10540,38 @@
10371
10540
  } else if (e.key === 'ArrowUp') {
10372
10541
  listRef.value?.focus('prev');
10373
10542
  }
10543
+ if (!props.multiple) return;
10544
+ if (['Backspace', 'Delete'].includes(e.key)) {
10545
+ if (selectionIndex.value < 0) {
10546
+ if (e.key === 'Backspace' && !search.value) {
10547
+ selectionIndex.value = length - 1;
10548
+ }
10549
+ return;
10550
+ }
10551
+ const originalSelectionIndex = selectionIndex.value;
10552
+ if (selection.value) select(selection.value);
10553
+ selectionIndex.value = originalSelectionIndex >= length - 1 ? length - 2 : originalSelectionIndex;
10554
+ }
10555
+ if (e.key === 'ArrowLeft') {
10556
+ if (selectionIndex.value < 0 && selectionStart > 0) return;
10557
+ const prev = selectionIndex.value > -1 ? selectionIndex.value - 1 : length - 1;
10558
+ if (selections.value[prev]) {
10559
+ selectionIndex.value = prev;
10560
+ } else {
10561
+ selectionIndex.value = -1;
10562
+ vTextFieldRef.value.setSelectionRange(search.value?.length, search.value?.length);
10563
+ }
10564
+ }
10565
+ if (e.key === 'ArrowRight') {
10566
+ if (selectionIndex.value < 0) return;
10567
+ const next = selectionIndex.value + 1;
10568
+ if (selections.value[next]) {
10569
+ selectionIndex.value = next;
10570
+ } else {
10571
+ selectionIndex.value = -1;
10572
+ vTextFieldRef.value.setSelectionRange(0, 0);
10573
+ }
10574
+ }
10374
10575
  }
10375
10576
  function onInput(e) {
10376
10577
  search.value = e.target.value;
@@ -10392,7 +10593,6 @@
10392
10593
  const index = selected.value.findIndex(selection => props.valueComparator(selection, item.value));
10393
10594
  if (index === -1) {
10394
10595
  model.value = [...model.value, item];
10395
- search.value = '';
10396
10596
  } else {
10397
10597
  const value = [...model.value];
10398
10598
  value.splice(index, 1);
@@ -10437,12 +10637,15 @@
10437
10637
  "onUpdate:modelValue": v => {
10438
10638
  if (v == null) model.value = [];
10439
10639
  },
10640
+ "focused": isFocused.value,
10641
+ "onUpdate:focused": $event => isFocused.value = $event,
10440
10642
  "validationValue": model.externalValue,
10441
10643
  "dirty": isDirty,
10442
10644
  "onInput": onInput,
10443
10645
  "class": ['v-autocomplete', {
10444
10646
  'v-autocomplete--active-menu': menu.value,
10445
10647
  'v-autocomplete--chips': !!props.chips,
10648
+ 'v-autocomplete--selecting-index': selectionIndex.value > -1,
10446
10649
  [`v-autocomplete--${props.multiple ? 'multiple' : 'single'}`]: true,
10447
10650
  'v-autocomplete--selection-slot': !!slots.selection
10448
10651
  }],
@@ -10451,8 +10654,6 @@
10451
10654
  "placeholder": isDirty ? undefined : props.placeholder,
10452
10655
  "onClick:clear": onClear,
10453
10656
  "onMousedown:control": onMousedownControl,
10454
- "onFocus": () => isFocused.value = true,
10455
- "onBlur": () => isFocused.value = false,
10456
10657
  "onKeydown": onKeydown
10457
10658
  }), {
10458
10659
  ...slots,
@@ -10517,7 +10718,8 @@
10517
10718
  };
10518
10719
  return vue.createVNode("div", {
10519
10720
  "key": item.value,
10520
- "class": "v-autocomplete__selection"
10721
+ "class": ['v-autocomplete__selection', index === selectionIndex.value && ['v-autocomplete__selection--selected', textColorClasses.value]],
10722
+ "style": index === selectionIndex.value ? textColorStyles.value : {}
10521
10723
  }, [hasChips ? !slots.chip ? vue.createVNode(VChip, vue.mergeProps({
10522
10724
  "key": "chip",
10523
10725
  "closable": props.closableChips,
@@ -12412,11 +12614,33 @@
12412
12614
  elevation: 2
12413
12615
  })
12414
12616
  }, 'slider');
12617
+ const useSteps = props => {
12618
+ const min = vue.computed(() => parseFloat(props.min));
12619
+ const max = vue.computed(() => parseFloat(props.max));
12620
+ const step = vue.computed(() => +props.step > 0 ? parseFloat(props.step) : 0);
12621
+ const decimals = vue.computed(() => Math.max(getDecimals(step.value), getDecimals(min.value)));
12622
+ function roundValue(value) {
12623
+ if (step.value <= 0) return value;
12624
+ const clamped = clamp(value, min.value, max.value);
12625
+ const offset = min.value % step.value;
12626
+ const newValue = Math.round((clamped - offset) / step.value) * step.value + offset;
12627
+ return parseFloat(Math.min(newValue, max.value).toFixed(decimals.value));
12628
+ }
12629
+ return {
12630
+ min,
12631
+ max,
12632
+ step,
12633
+ decimals,
12634
+ roundValue
12635
+ };
12636
+ };
12415
12637
  const useSlider = _ref => {
12416
12638
  let {
12417
12639
  props,
12418
- handleSliderMouseUp,
12419
- handleMouseMove,
12640
+ steps,
12641
+ onSliderStart,
12642
+ onSliderMove,
12643
+ onSliderEnd,
12420
12644
  getActiveThumb
12421
12645
  } = _ref;
12422
12646
  const {
@@ -12430,10 +12654,13 @@
12430
12654
  }
12431
12655
  return hd;
12432
12656
  });
12433
- const min = vue.computed(() => parseFloat(props.min));
12434
- const max = vue.computed(() => parseFloat(props.max));
12435
- const step = vue.computed(() => +props.step > 0 ? parseFloat(props.step) : 0);
12436
- const decimals = vue.computed(() => Math.max(getDecimals(step.value), getDecimals(min.value)));
12657
+ const {
12658
+ min,
12659
+ max,
12660
+ step,
12661
+ decimals,
12662
+ roundValue
12663
+ } = steps;
12437
12664
  const thumbSize = vue.computed(() => parseInt(props.thumbSize, 10));
12438
12665
  const tickSize = vue.computed(() => parseInt(props.tickSize, 10));
12439
12666
  const trackSize = vue.computed(() => parseInt(props.trackSize, 10));
@@ -12447,13 +12674,6 @@
12447
12674
  const startOffset = vue.ref(0);
12448
12675
  const trackContainerRef = vue.ref();
12449
12676
  const activeThumbRef = vue.ref();
12450
- function roundValue(value) {
12451
- if (step.value <= 0) return value;
12452
- const clamped = clamp(value, min.value, max.value);
12453
- const offset = min.value % step.value;
12454
- const newValue = Math.round((clamped - offset) / step.value) * step.value + offset;
12455
- return parseFloat(Math.min(newValue, max.value).toFixed(decimals.value));
12456
- }
12457
12677
  function parseMouseMove(e) {
12458
12678
  const vertical = props.direction === 'vertical';
12459
12679
  const start = vertical ? 'top' : 'left';
@@ -12470,14 +12690,11 @@
12470
12690
  if (vertical || horizontalDirection.value === 'rtl') clickPos = 1 - clickPos;
12471
12691
  return roundValue(min.value + clickPos * (max.value - min.value));
12472
12692
  }
12473
- let thumbMoved = false;
12474
12693
  const handleStop = e => {
12475
- if (!thumbMoved) {
12476
- startOffset.value = 0;
12477
- handleSliderMouseUp(parseMouseMove(e));
12478
- }
12694
+ onSliderEnd({
12695
+ value: parseMouseMove(e)
12696
+ });
12479
12697
  mousePressed.value = false;
12480
- thumbMoved = false;
12481
12698
  startOffset.value = 0;
12482
12699
  };
12483
12700
  const handleStart = e => {
@@ -12486,20 +12703,25 @@
12486
12703
  activeThumbRef.value.focus();
12487
12704
  mousePressed.value = true;
12488
12705
  if (activeThumbRef.value.contains(e.target)) {
12489
- thumbMoved = true;
12490
12706
  startOffset.value = getOffset(e, activeThumbRef.value, props.direction);
12491
12707
  } else {
12492
12708
  startOffset.value = 0;
12493
- handleMouseMove(parseMouseMove(e));
12709
+ onSliderMove({
12710
+ value: parseMouseMove(e)
12711
+ });
12494
12712
  }
12713
+ onSliderStart({
12714
+ value: parseMouseMove(e)
12715
+ });
12495
12716
  };
12496
12717
  const moveListenerOptions = {
12497
12718
  passive: true,
12498
12719
  capture: true
12499
12720
  };
12500
12721
  function onMouseMove(e) {
12501
- thumbMoved = true;
12502
- handleMouseMove(parseMouseMove(e));
12722
+ onSliderMove({
12723
+ value: parseMouseMove(e)
12724
+ });
12503
12725
  }
12504
12726
  function onSliderMouseUp(e) {
12505
12727
  e.stopPropagation();
@@ -12875,13 +13097,21 @@
12875
13097
  },
12876
13098
  emits: {
12877
13099
  'update:focused': value => true,
12878
- 'update:modelValue': v => true
13100
+ 'update:modelValue': v => true,
13101
+ start: value => true,
13102
+ end: value => true
12879
13103
  },
12880
13104
  setup(props, _ref) {
12881
13105
  let {
12882
- slots
13106
+ slots,
13107
+ emit
12883
13108
  } = _ref;
12884
13109
  const thumbContainerRef = vue.ref();
13110
+ const steps = useSteps(props);
13111
+ const model = useProxiedModel(props, 'modelValue', undefined, v => {
13112
+ const value = typeof v === 'string' ? parseFloat(v) : v == null ? steps.min.value : v;
13113
+ return steps.roundValue(value);
13114
+ });
12885
13115
  const {
12886
13116
  min,
12887
13117
  max,
@@ -12895,16 +13125,26 @@
12895
13125
  readonly
12896
13126
  } = useSlider({
12897
13127
  props,
12898
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
12899
- handleSliderMouseUp: newValue => model.value = roundValue(newValue),
12900
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
12901
- handleMouseMove: newValue => model.value = roundValue(newValue),
13128
+ steps,
13129
+ onSliderStart: () => {
13130
+ emit('start', model.value);
13131
+ },
13132
+ onSliderEnd: _ref2 => {
13133
+ let {
13134
+ value
13135
+ } = _ref2;
13136
+ const roundedValue = roundValue(value);
13137
+ model.value = roundedValue;
13138
+ emit('end', roundedValue);
13139
+ },
13140
+ onSliderMove: _ref3 => {
13141
+ let {
13142
+ value
13143
+ } = _ref3;
13144
+ return model.value = roundValue(value);
13145
+ },
12902
13146
  getActiveThumb: () => thumbContainerRef.value?.$el
12903
13147
  });
12904
- const model = useProxiedModel(props, 'modelValue', undefined, v => {
12905
- const value = typeof v === 'string' ? parseFloat(v) : v == null ? min.value : v;
12906
- return roundValue(value);
12907
- });
12908
13148
  const {
12909
13149
  isFocused,
12910
13150
  focus,
@@ -12912,7 +13152,7 @@
12912
13152
  } = useFocus(props);
12913
13153
  const trackStop = vue.computed(() => position(model.value));
12914
13154
  useRender(() => {
12915
- const [inputProps, _] = filterInputProps(props);
13155
+ const [inputProps, _] = VInput.filterProps(props);
12916
13156
  const hasPrepend = !!(props.label || slots.label || slots.prepend);
12917
13157
  return vue.createVNode(VInput, vue.mergeProps({
12918
13158
  "class": ['v-slider', {
@@ -12930,11 +13170,11 @@
12930
13170
  "class": "v-slider__label",
12931
13171
  "text": props.label
12932
13172
  }, null) : undefined, slots.prepend?.(slotProps)]) : undefined,
12933
- default: _ref2 => {
13173
+ default: _ref4 => {
12934
13174
  let {
12935
13175
  id,
12936
13176
  messagesId
12937
- } = _ref2;
13177
+ } = _ref4;
12938
13178
  return vue.createVNode("div", {
12939
13179
  "class": "v-slider__container",
12940
13180
  "onMousedown": !readonly.value ? onSliderMousedown : undefined,
@@ -13576,6 +13816,7 @@
13576
13816
  })
13577
13817
  },
13578
13818
  emits: {
13819
+ 'update:focused': focused => true,
13579
13820
  'update:modelValue': val => true,
13580
13821
  'update:search': val => true,
13581
13822
  'update:menu': val => true
@@ -13713,8 +13954,9 @@
13713
13954
  }
13714
13955
  return;
13715
13956
  }
13716
- select(selection.value);
13717
- vue.nextTick(() => !selection.value && (selectionIndex.value = length - 2));
13957
+ const originalSelectionIndex = selectionIndex.value;
13958
+ if (selection.value) select(selection.value);
13959
+ selectionIndex.value = originalSelectionIndex >= length - 1 ? length - 2 : originalSelectionIndex;
13718
13960
  }
13719
13961
  if (e.key === 'ArrowLeft') {
13720
13962
  if (selectionIndex.value < 0 && selectionStart > 0) return;
@@ -13799,6 +14041,8 @@
13799
14041
  "onUpdate:modelValue": [$event => search.value = $event, v => {
13800
14042
  if (v == null) model.value = [];
13801
14043
  }],
14044
+ "focused": isFocused.value,
14045
+ "onUpdate:focused": $event => isFocused.value = $event,
13802
14046
  "validationValue": model.externalValue,
13803
14047
  "dirty": isDirty,
13804
14048
  "class": ['v-combobox', {
@@ -13812,8 +14056,6 @@
13812
14056
  "placeholder": isDirty ? undefined : props.placeholder,
13813
14057
  "onClick:clear": onClear,
13814
14058
  "onMousedown:control": onMousedownControl,
13815
- "onFocus": () => isFocused.value = true,
13816
- "onBlur": () => isFocused.value = false,
13817
14059
  "onKeydown": onKeydown
13818
14060
  }), {
13819
14061
  ...slots,
@@ -14265,8 +14507,6 @@
14265
14507
  default: '$vuetify.fileInput.counter'
14266
14508
  },
14267
14509
  multiple: Boolean,
14268
- hint: String,
14269
- persistentHint: Boolean,
14270
14510
  showSize: {
14271
14511
  type: [Boolean, Number],
14272
14512
  default: false,
@@ -14291,6 +14531,7 @@
14291
14531
  emits: {
14292
14532
  'click:control': e => true,
14293
14533
  'mousedown:control': e => true,
14534
+ 'update:focused': focused => true,
14294
14535
  'update:modelValue': files => true
14295
14536
  },
14296
14537
  setup(props, _ref) {
@@ -14303,6 +14544,11 @@
14303
14544
  t
14304
14545
  } = useLocale();
14305
14546
  const model = useProxiedModel(props, 'modelValue');
14547
+ const {
14548
+ isFocused,
14549
+ focus,
14550
+ blur
14551
+ } = useFocus(props);
14306
14552
  const base = vue.computed(() => typeof props.showSize !== 'boolean' ? props.showSize : undefined);
14307
14553
  const totalBytes = vue.computed(() => (model.value ?? []).reduce((bytes, _ref2) => {
14308
14554
  let {
@@ -14324,21 +14570,14 @@
14324
14570
  });
14325
14571
  const vInputRef = vue.ref();
14326
14572
  const vFieldRef = vue.ref();
14327
- const isFocused = vue.ref(false);
14328
14573
  const inputRef = vue.ref();
14329
- const messages = vue.computed(() => {
14330
- return props.messages.length ? props.messages : props.persistentHint ? props.hint : '';
14331
- });
14332
14574
  function onFocus() {
14333
14575
  if (inputRef.value !== document.activeElement) {
14334
14576
  inputRef.value?.focus();
14335
14577
  }
14336
- if (!isFocused.value) {
14337
- isFocused.value = true;
14338
- }
14578
+ if (!isFocused.value) focus();
14339
14579
  }
14340
14580
  function onClickPrepend(e) {
14341
- callEvent(props['onClick:prepend'], e);
14342
14581
  onControlClick(e);
14343
14582
  }
14344
14583
  function onControlMousedown(e) {
@@ -14369,18 +14608,16 @@
14369
14608
  const [{
14370
14609
  modelValue: _,
14371
14610
  ...inputProps
14372
- }] = filterInputProps(props);
14611
+ }] = VInput.filterProps(props);
14373
14612
  const [fieldProps] = filterFieldProps(props);
14374
14613
  return vue.createVNode(VInput, vue.mergeProps({
14375
14614
  "ref": vInputRef,
14376
14615
  "modelValue": model.value,
14377
14616
  "onUpdate:modelValue": $event => model.value = $event,
14378
14617
  "class": "v-file-input",
14379
- "onClick:prepend": onClickPrepend,
14380
- "onClick:append": props['onClick:append']
14618
+ "onClick:prepend": onClickPrepend
14381
14619
  }, rootAttrs, inputProps, {
14382
- "focused": isFocused.value,
14383
- "messages": messages.value
14620
+ "focused": isFocused.value
14384
14621
  }), {
14385
14622
  ...slots,
14386
14623
  default: _ref3 => {
@@ -14432,7 +14669,7 @@
14432
14669
  model.value = [...(target.files ?? [])];
14433
14670
  },
14434
14671
  "onFocus": onFocus,
14435
- "onBlur": () => isFocused.value = false
14672
+ "onBlur": blur
14436
14673
  }, slotProps, inputAttrs), null), vue.createVNode("div", {
14437
14674
  "class": fieldClass
14438
14675
  }, [!!model.value?.length && (slots.selection ? slots.selection({
@@ -15123,6 +15360,432 @@
15123
15360
  }
15124
15361
  });
15125
15362
 
15363
+ // Utilities
15364
+
15365
+ // Types
15366
+
15367
+ function getWeekArray(date) {
15368
+ let currentWeek = [];
15369
+ const weeks = [];
15370
+ const firstDayOfMonth = startOfMonth(date);
15371
+ const lastDayOfMonth = endOfMonth(date);
15372
+ for (let i = 0; i < firstDayOfMonth.getDay(); i++) {
15373
+ currentWeek.push(null);
15374
+ }
15375
+ for (let i = 1; i <= lastDayOfMonth.getDate(); i++) {
15376
+ const day = new Date(date.getFullYear(), date.getMonth(), i);
15377
+
15378
+ // Add the day to the current week
15379
+ currentWeek.push(day);
15380
+
15381
+ // If the current week has 7 days, add it to the weeks array and start a new week
15382
+ if (currentWeek.length === 7) {
15383
+ weeks.push(currentWeek);
15384
+ currentWeek = [];
15385
+ }
15386
+ }
15387
+ for (let i = currentWeek.length; i < 7; i++) {
15388
+ currentWeek.push(null);
15389
+ }
15390
+ weeks.push(currentWeek);
15391
+ return weeks;
15392
+ }
15393
+ function startOfMonth(date) {
15394
+ return new Date(date.getFullYear(), date.getMonth(), 1);
15395
+ }
15396
+ function endOfMonth(date) {
15397
+ return new Date(date.getFullYear(), date.getMonth() + 1, 0);
15398
+ }
15399
+ function date(value) {
15400
+ if (value == null) return null;
15401
+ if (value instanceof Date) return value;
15402
+ if (typeof value === 'string') {
15403
+ const parsed = Date.parse(value);
15404
+ if (!isNaN(parsed)) return new Date(parsed);
15405
+ }
15406
+ return null;
15407
+ }
15408
+ const firstDay = {
15409
+ '001': 1,
15410
+ AD: 1,
15411
+ AE: 6,
15412
+ AF: 6,
15413
+ AG: 0,
15414
+ AI: 1,
15415
+ AL: 1,
15416
+ AM: 1,
15417
+ AN: 1,
15418
+ AR: 1,
15419
+ AS: 0,
15420
+ AT: 1,
15421
+ AU: 0,
15422
+ AX: 1,
15423
+ AZ: 1,
15424
+ BA: 1,
15425
+ BD: 0,
15426
+ BE: 1,
15427
+ BG: 1,
15428
+ BH: 6,
15429
+ BM: 1,
15430
+ BN: 1,
15431
+ BR: 0,
15432
+ BS: 0,
15433
+ BT: 0,
15434
+ BW: 0,
15435
+ BY: 1,
15436
+ BZ: 0,
15437
+ CA: 0,
15438
+ CH: 1,
15439
+ CL: 1,
15440
+ CM: 1,
15441
+ CN: 0,
15442
+ CO: 0,
15443
+ CR: 1,
15444
+ CY: 1,
15445
+ CZ: 1,
15446
+ DE: 1,
15447
+ DJ: 6,
15448
+ DK: 1,
15449
+ DM: 0,
15450
+ DO: 0,
15451
+ DZ: 6,
15452
+ EC: 1,
15453
+ EE: 1,
15454
+ EG: 6,
15455
+ ES: 1,
15456
+ ET: 0,
15457
+ FI: 1,
15458
+ FJ: 1,
15459
+ FO: 1,
15460
+ FR: 1,
15461
+ GB: 1,
15462
+ 'GB-alt-variant': 0,
15463
+ GE: 1,
15464
+ GF: 1,
15465
+ GP: 1,
15466
+ GR: 1,
15467
+ GT: 0,
15468
+ GU: 0,
15469
+ HK: 0,
15470
+ HN: 0,
15471
+ HR: 1,
15472
+ HU: 1,
15473
+ ID: 0,
15474
+ IE: 1,
15475
+ IL: 0,
15476
+ IN: 0,
15477
+ IQ: 6,
15478
+ IR: 6,
15479
+ IS: 1,
15480
+ IT: 1,
15481
+ JM: 0,
15482
+ JO: 6,
15483
+ JP: 0,
15484
+ KE: 0,
15485
+ KG: 1,
15486
+ KH: 0,
15487
+ KR: 0,
15488
+ KW: 6,
15489
+ KZ: 1,
15490
+ LA: 0,
15491
+ LB: 1,
15492
+ LI: 1,
15493
+ LK: 1,
15494
+ LT: 1,
15495
+ LU: 1,
15496
+ LV: 1,
15497
+ LY: 6,
15498
+ MC: 1,
15499
+ MD: 1,
15500
+ ME: 1,
15501
+ MH: 0,
15502
+ MK: 1,
15503
+ MM: 0,
15504
+ MN: 1,
15505
+ MO: 0,
15506
+ MQ: 1,
15507
+ MT: 0,
15508
+ MV: 5,
15509
+ MX: 0,
15510
+ MY: 1,
15511
+ MZ: 0,
15512
+ NI: 0,
15513
+ NL: 1,
15514
+ NO: 1,
15515
+ NP: 0,
15516
+ NZ: 1,
15517
+ OM: 6,
15518
+ PA: 0,
15519
+ PE: 0,
15520
+ PH: 0,
15521
+ PK: 0,
15522
+ PL: 1,
15523
+ PR: 0,
15524
+ PT: 0,
15525
+ PY: 0,
15526
+ QA: 6,
15527
+ RE: 1,
15528
+ RO: 1,
15529
+ RS: 1,
15530
+ RU: 1,
15531
+ SA: 0,
15532
+ SD: 6,
15533
+ SE: 1,
15534
+ SG: 0,
15535
+ SI: 1,
15536
+ SK: 1,
15537
+ SM: 1,
15538
+ SV: 0,
15539
+ SY: 6,
15540
+ TH: 0,
15541
+ TJ: 1,
15542
+ TM: 1,
15543
+ TR: 1,
15544
+ TT: 0,
15545
+ TW: 0,
15546
+ UA: 1,
15547
+ UM: 0,
15548
+ US: 0,
15549
+ UY: 1,
15550
+ UZ: 1,
15551
+ VA: 1,
15552
+ VE: 0,
15553
+ VI: 0,
15554
+ VN: 1,
15555
+ WS: 0,
15556
+ XK: 1,
15557
+ YE: 0,
15558
+ ZA: 0,
15559
+ ZW: 0
15560
+ };
15561
+ const sundayJanuarySecond2000 = new Date(2000, 0, 2);
15562
+ function getWeekdays(locale) {
15563
+ const daysFromSunday = firstDay[locale.slice(-2).toUpperCase()];
15564
+ return createRange(7).map(i => {
15565
+ const weekday = new Date(sundayJanuarySecond2000);
15566
+ weekday.setDate(sundayJanuarySecond2000.getDate() + daysFromSunday + i);
15567
+ return new Intl.DateTimeFormat(locale, {
15568
+ weekday: 'long'
15569
+ }).format(weekday);
15570
+ });
15571
+ }
15572
+ function format(value, formatString, locale) {
15573
+ const date = new Date(value);
15574
+ let options = {};
15575
+ switch (formatString) {
15576
+ case 'fullDateWithWeekday':
15577
+ options = {
15578
+ weekday: 'long',
15579
+ day: 'numeric',
15580
+ month: 'long',
15581
+ year: 'numeric'
15582
+ };
15583
+ break;
15584
+ case 'normalDateWithWeekday':
15585
+ options = {
15586
+ weekday: 'short',
15587
+ day: 'numeric',
15588
+ month: 'short',
15589
+ year: 'numeric'
15590
+ };
15591
+ break;
15592
+ case 'keyboardDate':
15593
+ options = {};
15594
+ break;
15595
+ case 'monthAndDate':
15596
+ options = {
15597
+ month: 'long',
15598
+ day: 'numeric'
15599
+ };
15600
+ break;
15601
+ case 'monthAndYear':
15602
+ options = {
15603
+ month: 'long',
15604
+ year: 'numeric'
15605
+ };
15606
+ break;
15607
+ default:
15608
+ options = {
15609
+ timeZone: 'UTC',
15610
+ timeZoneName: 'short'
15611
+ };
15612
+ }
15613
+ return new Intl.DateTimeFormat(locale, options).format(date);
15614
+ }
15615
+ function addDays(date, amount) {
15616
+ const d = new Date(date);
15617
+ d.setDate(d.getDate() + amount);
15618
+ return d;
15619
+ }
15620
+ function addMonths(date, amount) {
15621
+ const d = new Date(date);
15622
+ d.setMonth(d.getMonth() + amount);
15623
+ return d;
15624
+ }
15625
+ function getYear(date) {
15626
+ return date.getFullYear();
15627
+ }
15628
+ function getMonth(date) {
15629
+ return date.getMonth();
15630
+ }
15631
+ function startOfYear(date) {
15632
+ return new Date(date.getFullYear(), 0, 1);
15633
+ }
15634
+ function endOfYear(date) {
15635
+ return new Date(date.getFullYear(), 11, 31);
15636
+ }
15637
+ function getMondayOfFirstWeekOfYear(year) {
15638
+ return new Date(year, 0, 1);
15639
+ }
15640
+
15641
+ // https://stackoverflow.com/questions/274861/how-do-i-calculate-the-week-number-given-a-date/275024#275024
15642
+ function getWeek(date) {
15643
+ let year = date.getFullYear();
15644
+ let d1w1 = getMondayOfFirstWeekOfYear(year);
15645
+ if (date < d1w1) {
15646
+ year = year - 1;
15647
+ d1w1 = getMondayOfFirstWeekOfYear(year);
15648
+ } else {
15649
+ const tv = getMondayOfFirstWeekOfYear(year + 1);
15650
+ if (date >= tv) {
15651
+ year = year + 1;
15652
+ d1w1 = tv;
15653
+ }
15654
+ }
15655
+ const diffTime = Math.abs(date.getTime() - d1w1.getTime());
15656
+ const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
15657
+ return Math.floor(diffDays / 7) + 1;
15658
+ }
15659
+ function isWithinRange(date, range) {
15660
+ return isAfter(date, range[0]) && isBefore(date, range[1]);
15661
+ }
15662
+ function isValid(date) {
15663
+ const d = new Date(date);
15664
+ return d instanceof Date && !isNaN(d.getTime());
15665
+ }
15666
+ function isAfter(date, comparing) {
15667
+ return date.getTime() > comparing.getTime();
15668
+ }
15669
+ function isBefore(date, comparing) {
15670
+ return date.getTime() < comparing.getTime();
15671
+ }
15672
+ function isEqual(date, comparing) {
15673
+ return date.getTime() === comparing.getTime();
15674
+ }
15675
+ function isSameDay(date, comparing) {
15676
+ return date.getDate() === comparing.getDate() && date.getMonth() === comparing.getMonth() && date.getFullYear() === comparing.getFullYear();
15677
+ }
15678
+ function isSameMonth(date, comparing) {
15679
+ return date.getMonth() === comparing.getMonth() && date.getFullYear() === comparing.getFullYear();
15680
+ }
15681
+ function getDiff(date, comparing, unit) {
15682
+ const d = new Date(date);
15683
+ const c = new Date(comparing);
15684
+ if (unit === 'month') {
15685
+ return d.getMonth() - c.getMonth() + (d.getFullYear() - c.getFullYear()) * 12;
15686
+ }
15687
+ return Math.floor((d.getTime() - c.getTime()) / (1000 * 60 * 60 * 24));
15688
+ }
15689
+ function setYear(date, year) {
15690
+ const d = new Date(date);
15691
+ d.setFullYear(year);
15692
+ return d;
15693
+ }
15694
+ class VuetifyDateAdapter {
15695
+ constructor() {
15696
+ let locale = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'en';
15697
+ this.locale = locale;
15698
+ }
15699
+ date(value) {
15700
+ return date(value);
15701
+ }
15702
+ addDays(date, amount) {
15703
+ return addDays(date, amount);
15704
+ }
15705
+ addMonths(date, amount) {
15706
+ return addMonths(date, amount);
15707
+ }
15708
+ getWeekArray(date) {
15709
+ return getWeekArray(date);
15710
+ }
15711
+ startOfMonth(date) {
15712
+ return startOfMonth(date);
15713
+ }
15714
+ endOfMonth(date) {
15715
+ return endOfMonth(date);
15716
+ }
15717
+ format(date, formatString) {
15718
+ return format(date, formatString, this.locale);
15719
+ }
15720
+ isEqual(date, comparing) {
15721
+ return isEqual(date, comparing);
15722
+ }
15723
+ isValid(date) {
15724
+ return isValid(date);
15725
+ }
15726
+ isWithinRange(date, range) {
15727
+ return isWithinRange(date, range);
15728
+ }
15729
+ isAfter(date, comparing) {
15730
+ return isAfter(date, comparing);
15731
+ }
15732
+ isSameDay(date, comparing) {
15733
+ return isSameDay(date, comparing);
15734
+ }
15735
+ isSameMonth(date, comparing) {
15736
+ return isSameMonth(date, comparing);
15737
+ }
15738
+ setYear(date, year) {
15739
+ return setYear(date, year);
15740
+ }
15741
+ getDiff(date, comparing, unit) {
15742
+ return getDiff(date, comparing, unit);
15743
+ }
15744
+ getWeek(date) {
15745
+ return getWeek(date);
15746
+ }
15747
+ getWeekdays() {
15748
+ return getWeekdays(this.locale);
15749
+ }
15750
+ getYear(date) {
15751
+ return getYear(date);
15752
+ }
15753
+ getMonth(date) {
15754
+ return getMonth(date);
15755
+ }
15756
+ startOfYear(date) {
15757
+ return startOfYear(date);
15758
+ }
15759
+ endOfYear(date) {
15760
+ return endOfYear(date);
15761
+ }
15762
+ }
15763
+
15764
+ // Composables
15765
+
15766
+ // Types
15767
+
15768
+ const DateAdapterSymbol = Symbol.for('vuetify:date-adapter');
15769
+ function createDate(options) {
15770
+ return options ?? {
15771
+ adapter: VuetifyDateAdapter
15772
+ };
15773
+ }
15774
+ function useDate(props) {
15775
+ const date = vue.inject(DateAdapterSymbol);
15776
+ const locale = useLocale();
15777
+ if (!date) throw new Error('[Vuetify] Could not find injected date');
15778
+
15779
+ // eslint-disable-next-line new-cap
15780
+ const instance = new date.adapter(locale.current.value);
15781
+ vue.watch(locale.current, val => {
15782
+ instance.locale = val;
15783
+ }, {
15784
+ immediate: true
15785
+ });
15786
+ return instance;
15787
+ }
15788
+
15126
15789
  function useSticky(_ref) {
15127
15790
  let {
15128
15791
  rootEl,
@@ -16127,7 +16790,7 @@
16127
16790
  const model = useProxiedModel(props, 'modelValue');
16128
16791
  useRender(() => {
16129
16792
  const [inputAttrs, controlAttrs] = filterInputAttrs(attrs);
16130
- const [inputProps, _1] = filterInputProps(props);
16793
+ const [inputProps, _1] = VInput.filterProps(props);
16131
16794
  const [controlProps, _2] = VSelectionControl.filterProps(props);
16132
16795
  const label = slots.label ? slots.label({
16133
16796
  label: props.label,
@@ -16192,11 +16855,14 @@
16192
16855
  },
16193
16856
  emits: {
16194
16857
  'update:focused': value => true,
16195
- 'update:modelValue': value => true
16858
+ 'update:modelValue': value => true,
16859
+ end: value => true,
16860
+ start: value => true
16196
16861
  },
16197
16862
  setup(props, _ref) {
16198
16863
  let {
16199
- slots
16864
+ slots,
16865
+ emit
16200
16866
  } = _ref;
16201
16867
  const startThumbRef = vue.ref();
16202
16868
  const stopThumbRef = vue.ref();
@@ -16209,6 +16875,11 @@
16209
16875
  const b = Math.abs(stopOffset);
16210
16876
  return a < b || a === b && startOffset < 0 ? startThumbRef.value.$el : stopThumbRef.value.$el;
16211
16877
  }
16878
+ const steps = useSteps(props);
16879
+ const model = useProxiedModel(props, 'modelValue', undefined, arr => {
16880
+ if (!arr?.length) return [0, 0];
16881
+ return arr.map(value => steps.roundValue(value));
16882
+ });
16212
16883
  const {
16213
16884
  activeThumbRef,
16214
16885
  hasLabels,
@@ -16218,34 +16889,37 @@
16218
16889
  onSliderMousedown,
16219
16890
  onSliderTouchstart,
16220
16891
  position,
16221
- roundValue,
16222
16892
  trackContainerRef
16223
16893
  } = useSlider({
16224
- /* eslint-disable @typescript-eslint/no-use-before-define */
16225
16894
  props,
16226
- handleSliderMouseUp: newValue => {
16227
- model.value = activeThumbRef.value === startThumbRef.value?.$el ? [newValue, model.value[1]] : [model.value[0], newValue];
16895
+ steps,
16896
+ onSliderStart: () => {
16897
+ emit('start', model.value);
16228
16898
  },
16229
- handleMouseMove: newValue => {
16899
+ onSliderEnd: _ref2 => {
16900
+ let {
16901
+ value
16902
+ } = _ref2;
16903
+ const newValue = activeThumbRef.value === startThumbRef.value?.$el ? [value, model.value[1]] : [model.value[0], value];
16904
+ model.value = newValue;
16905
+ emit('end', newValue);
16906
+ },
16907
+ onSliderMove: _ref3 => {
16908
+ let {
16909
+ value
16910
+ } = _ref3;
16230
16911
  const [start, stop] = model.value;
16231
16912
  if (!props.strict && start === stop && start !== min.value) {
16232
- activeThumbRef.value = newValue > start ? stopThumbRef.value?.$el : startThumbRef.value?.$el;
16913
+ activeThumbRef.value = value > start ? stopThumbRef.value?.$el : startThumbRef.value?.$el;
16233
16914
  activeThumbRef.value?.focus();
16234
16915
  }
16235
16916
  if (activeThumbRef.value === startThumbRef.value?.$el) {
16236
- model.value = [Math.min(newValue, stop), stop];
16917
+ model.value = [Math.min(value, stop), stop];
16237
16918
  } else {
16238
- model.value = [start, Math.max(start, newValue)];
16919
+ model.value = [start, Math.max(start, value)];
16239
16920
  }
16240
16921
  },
16241
16922
  getActiveThumb
16242
- /* eslint-enable @typescript-eslint/no-use-before-define */
16243
- });
16244
-
16245
- const model = useProxiedModel(props, 'modelValue', undefined, arr => {
16246
- // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
16247
- if (!arr || !arr.length) return [0, 0];
16248
- return arr.map(value => roundValue(value));
16249
16923
  });
16250
16924
  const {
16251
16925
  isFocused,
@@ -16255,7 +16929,7 @@
16255
16929
  const trackStart = vue.computed(() => position(model.value[0]));
16256
16930
  const trackStop = vue.computed(() => position(model.value[1]));
16257
16931
  useRender(() => {
16258
- const [inputProps, _] = filterInputProps(props);
16932
+ const [inputProps, _] = VInput.filterProps(props);
16259
16933
  const hasPrepend = !!(props.label || slots.label || slots.prepend);
16260
16934
  return vue.createVNode(VInput, vue.mergeProps({
16261
16935
  "class": ['v-slider', 'v-range-slider', {
@@ -16273,11 +16947,11 @@
16273
16947
  "class": "v-slider__label",
16274
16948
  "text": props.label
16275
16949
  }, null) : undefined, slots.prepend?.(slotProps)]) : undefined,
16276
- default: _ref2 => {
16950
+ default: _ref4 => {
16277
16951
  let {
16278
16952
  id,
16279
16953
  messagesId
16280
- } = _ref2;
16954
+ } = _ref4;
16281
16955
  return vue.createVNode("div", {
16282
16956
  "class": "v-slider__container",
16283
16957
  "onMousedown": onSliderMousedown,
@@ -17100,10 +17774,12 @@
17100
17774
  }
17101
17775
  useRender(() => {
17102
17776
  const [inputAttrs, controlAttrs] = filterInputAttrs(attrs);
17103
- const [inputProps, _1] = filterInputProps(props);
17777
+ const [inputProps, _1] = VInput.filterProps(props);
17104
17778
  const [controlProps, _2] = VSelectionControl.filterProps(props);
17105
17779
  const control = vue.ref();
17106
- function onClick() {
17780
+ function onClick(e) {
17781
+ e.stopPropagation();
17782
+ e.preventDefault();
17107
17783
  control.value?.input?.click();
17108
17784
  }
17109
17785
  return vue.createVNode(VInput, vue.mergeProps({
@@ -17464,8 +18140,6 @@
17464
18140
  autofocus: Boolean,
17465
18141
  counter: [Boolean, Number, String],
17466
18142
  counterValue: Function,
17467
- hint: String,
17468
- persistentHint: Boolean,
17469
18143
  prefix: String,
17470
18144
  placeholder: String,
17471
18145
  persistentPlaceholder: Boolean,
@@ -17520,9 +18194,6 @@
17520
18194
  const controlHeight = vue.ref('');
17521
18195
  const textareaRef = vue.ref();
17522
18196
  const isActive = vue.computed(() => isFocused.value || props.persistentPlaceholder);
17523
- const messages = vue.computed(() => {
17524
- return props.messages.length ? props.messages : isFocused.value || props.persistentHint ? props.hint : '';
17525
- });
17526
18197
  function onFocus() {
17527
18198
  if (textareaRef.value !== document.activeElement) {
17528
18199
  textareaRef.value?.focus();
@@ -17594,7 +18265,7 @@
17594
18265
  const [{
17595
18266
  modelValue: _,
17596
18267
  ...inputProps
17597
- }] = filterInputProps(props);
18268
+ }] = VInput.filterProps(props);
17598
18269
  const [fieldProps] = filterFieldProps(props);
17599
18270
  return vue.createVNode(VInput, vue.mergeProps({
17600
18271
  "ref": vInputRef,
@@ -17608,12 +18279,9 @@
17608
18279
  'v-textarea--auto-grow': props.autoGrow,
17609
18280
  'v-textarea--no-resize': props.noResize || props.autoGrow,
17610
18281
  'v-text-field--flush-details': ['plain', 'underlined'].includes(props.variant)
17611
- }],
17612
- "onClick:prepend": props['onClick:prepend'],
17613
- "onClick:append": props['onClick:append']
18282
+ }]
17614
18283
  }, rootAttrs, inputProps, {
17615
- "focused": isFocused.value,
17616
- "messages": messages.value
18284
+ "focused": isFocused.value
17617
18285
  }), {
17618
18286
  ...slots,
17619
18287
  default: _ref2 => {
@@ -18495,6 +19163,7 @@
18495
19163
  const theme = createTheme(options.theme);
18496
19164
  const icons = createIcons(options.icons);
18497
19165
  const locale = createLocale(options.locale);
19166
+ const date = createDate(options.date);
18498
19167
  const install = app => {
18499
19168
  for (const key in directives) {
18500
19169
  app.directive(key, directives[key]);
@@ -18515,6 +19184,7 @@
18515
19184
  app.provide(ThemeSymbol, theme);
18516
19185
  app.provide(IconSymbol, icons);
18517
19186
  app.provide(LocaleSymbol, locale);
19187
+ app.provide(DateAdapterSymbol, date);
18518
19188
  if (IN_BROWSER && options.ssr) {
18519
19189
  if (app.$nuxt) {
18520
19190
  app.$nuxt.hook('app:suspense:resolve', () => {
@@ -18542,7 +19212,8 @@
18542
19212
  display: inject.call(this, DisplaySymbol),
18543
19213
  theme: inject.call(this, ThemeSymbol),
18544
19214
  icons: inject.call(this, IconSymbol),
18545
- locale: inject.call(this, LocaleSymbol)
19215
+ locale: inject.call(this, LocaleSymbol),
19216
+ date: inject.call(this, DateAdapterSymbol)
18546
19217
  });
18547
19218
  }
18548
19219
  }
@@ -18555,10 +19226,11 @@
18555
19226
  display,
18556
19227
  theme,
18557
19228
  icons,
18558
- locale
19229
+ locale,
19230
+ date
18559
19231
  };
18560
19232
  }
18561
- const version$1 = "4.0.0-dev-20230419.0";
19233
+ const version$1 = "4.0.0-dev-20230422.0";
18562
19234
  createVuetify$1.version = version$1;
18563
19235
 
18564
19236
  // Vue's inject() can only be used in setup
@@ -18578,12 +19250,13 @@
18578
19250
  ...options
18579
19251
  });
18580
19252
  };
18581
- const version = "4.0.0-dev-20230419.0";
19253
+ const version = "4.0.0-dev-20230422.0";
18582
19254
  createVuetify.version = version;
18583
19255
 
18584
19256
  exports.components = components;
18585
19257
  exports.createVuetify = createVuetify;
18586
19258
  exports.directives = directives;
19259
+ exports.useDate = useDate;
18587
19260
  exports.useDisplay = useDisplay;
18588
19261
  exports.useLayout = useLayout;
18589
19262
  exports.useLocale = useLocale;