@vuetify/nightly 3.9.0-dev.2025-07-08 → 3.9.0-dev.2025-07-16
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.
- package/CHANGELOG.md +14 -3
- package/dist/json/attributes.json +3826 -3806
- package/dist/json/importMap-labs.json +24 -24
- package/dist/json/importMap.json +168 -168
- package/dist/json/tags.json +5 -0
- package/dist/json/web-types.json +6992 -6922
- package/dist/vuetify-labs.cjs +216 -27
- package/dist/vuetify-labs.css +4659 -4657
- package/dist/vuetify-labs.d.ts +119 -57
- package/dist/vuetify-labs.esm.js +216 -27
- package/dist/vuetify-labs.esm.js.map +1 -1
- package/dist/vuetify-labs.js +216 -27
- package/dist/vuetify-labs.min.css +2 -2
- package/dist/vuetify.cjs +178 -18
- package/dist/vuetify.cjs.map +1 -1
- package/dist/vuetify.css +4036 -4034
- package/dist/vuetify.d.ts +109 -57
- package/dist/vuetify.esm.js +178 -18
- package/dist/vuetify.esm.js.map +1 -1
- package/dist/vuetify.js +178 -18
- package/dist/vuetify.js.map +1 -1
- package/dist/vuetify.min.css +2 -2
- package/dist/vuetify.min.js +718 -696
- package/dist/vuetify.min.js.map +1 -1
- package/lib/components/VAutocomplete/VAutocomplete.js +1 -0
- package/lib/components/VAutocomplete/VAutocomplete.js.map +1 -1
- package/lib/components/VCombobox/VCombobox.js +1 -0
- package/lib/components/VCombobox/VCombobox.js.map +1 -1
- package/lib/components/VFileInput/VFileInput.d.ts +15 -0
- package/lib/components/VFileInput/VFileInput.js +38 -9
- package/lib/components/VFileInput/VFileInput.js.map +1 -1
- package/lib/components/VList/VList.js +2 -1
- package/lib/components/VList/VList.js.map +1 -1
- package/lib/components/VList/VListItem.js +7 -1
- package/lib/components/VList/VListItem.js.map +1 -1
- package/lib/components/VProgressLinear/VProgressLinear.css +1 -1
- package/lib/components/VProgressLinear/VProgressLinear.d.ts +75 -0
- package/lib/components/VProgressLinear/VProgressLinear.js +32 -6
- package/lib/components/VProgressLinear/VProgressLinear.js.map +1 -1
- package/lib/components/VProgressLinear/VProgressLinear.sass +2 -2
- package/lib/components/VProgressLinear/chunks.d.ts +55 -0
- package/lib/components/VProgressLinear/chunks.js +62 -0
- package/lib/components/VProgressLinear/chunks.js.map +1 -0
- package/lib/components/VSelect/VSelect.js +1 -0
- package/lib/components/VSelect/VSelect.js.map +1 -1
- package/lib/composables/fileFilter.d.ts +18 -0
- package/lib/composables/fileFilter.js +38 -0
- package/lib/composables/fileFilter.js.map +1 -0
- package/lib/entry-bundler.js +1 -1
- package/lib/framework.d.ts +57 -57
- package/lib/framework.js +1 -1
- package/lib/labs/VFileUpload/VFileUpload.d.ts +15 -0
- package/lib/labs/VFileUpload/VFileUpload.js +39 -9
- package/lib/labs/VFileUpload/VFileUpload.js.map +1 -1
- package/package.json +1 -1
package/dist/vuetify-labs.esm.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/*!
|
2
|
-
* Vuetify v3.9.0-dev.2025-07-
|
2
|
+
* Vuetify v3.9.0-dev.2025-07-16
|
3
3
|
* Forged by John Leider
|
4
4
|
* Released under the MIT License.
|
5
5
|
*/
|
@@ -5186,6 +5186,69 @@ function useLocation(props) {
|
|
5186
5186
|
};
|
5187
5187
|
}
|
5188
5188
|
|
5189
|
+
// Utilities
|
5190
|
+
|
5191
|
+
// Types
|
5192
|
+
|
5193
|
+
// Composables
|
5194
|
+
const makeChunksProps = propsFactory({
|
5195
|
+
chunkCount: {
|
5196
|
+
type: [Number, String],
|
5197
|
+
default: null
|
5198
|
+
},
|
5199
|
+
chunkWidth: {
|
5200
|
+
type: [Number, String],
|
5201
|
+
default: null
|
5202
|
+
},
|
5203
|
+
chunkGap: {
|
5204
|
+
type: [Number, String],
|
5205
|
+
default: 4
|
5206
|
+
}
|
5207
|
+
}, 'chunks');
|
5208
|
+
function useChunks(props, containerWidth) {
|
5209
|
+
const hasChunks = toRef(() => !!props.chunkCount || !!props.chunkWidth);
|
5210
|
+
const chunkWidth = computed(() => {
|
5211
|
+
const containerSize = toValue(containerWidth);
|
5212
|
+
if (!containerSize) {
|
5213
|
+
return 0;
|
5214
|
+
}
|
5215
|
+
if (!props.chunkCount) {
|
5216
|
+
return Number(props.chunkWidth);
|
5217
|
+
}
|
5218
|
+
const count = Number(props.chunkCount);
|
5219
|
+
const availableWidth = containerSize - Number(props.chunkGap) * (count - 1);
|
5220
|
+
return availableWidth / count;
|
5221
|
+
});
|
5222
|
+
const chunkGap = toRef(() => Number(props.chunkGap));
|
5223
|
+
const chunksMaskStyles = computed(() => {
|
5224
|
+
if (!hasChunks.value) {
|
5225
|
+
return {};
|
5226
|
+
}
|
5227
|
+
const chunkGapPx = convertToUnit(chunkGap.value);
|
5228
|
+
const chunkWidthPx = convertToUnit(chunkWidth.value);
|
5229
|
+
return {
|
5230
|
+
maskRepeat: 'repeat-x',
|
5231
|
+
maskImage: `linear-gradient(90deg, #000, #000 ${chunkWidthPx}, transparent ${chunkWidthPx}, transparent)`,
|
5232
|
+
maskSize: `calc(${chunkWidthPx} + ${chunkGapPx}) 100%`
|
5233
|
+
};
|
5234
|
+
});
|
5235
|
+
function snapValueToChunk(val) {
|
5236
|
+
const containerSize = toValue(containerWidth);
|
5237
|
+
if (!containerSize) {
|
5238
|
+
return val;
|
5239
|
+
}
|
5240
|
+
const gapRelativeSize = 100 * chunkGap.value / containerSize;
|
5241
|
+
const chunkRelativeSize = 100 * (chunkWidth.value + chunkGap.value) / containerSize;
|
5242
|
+
const filledChunks = Math.floor((val + gapRelativeSize) / chunkRelativeSize);
|
5243
|
+
return clamp(0, filledChunks * chunkRelativeSize - gapRelativeSize / 2, 100);
|
5244
|
+
}
|
5245
|
+
return {
|
5246
|
+
hasChunks,
|
5247
|
+
chunksMaskStyles,
|
5248
|
+
snapValueToChunk
|
5249
|
+
};
|
5250
|
+
}
|
5251
|
+
|
5189
5252
|
const makeVProgressLinearProps = propsFactory({
|
5190
5253
|
absolute: Boolean,
|
5191
5254
|
active: {
|
@@ -5220,6 +5283,7 @@ const makeVProgressLinearProps = propsFactory({
|
|
5220
5283
|
stream: Boolean,
|
5221
5284
|
striped: Boolean,
|
5222
5285
|
roundedBar: Boolean,
|
5286
|
+
...makeChunksProps(),
|
5223
5287
|
...makeComponentProps(),
|
5224
5288
|
...makeLocationProps({
|
5225
5289
|
location: 'top'
|
@@ -5238,6 +5302,7 @@ const VProgressLinear = genericComponent()({
|
|
5238
5302
|
let {
|
5239
5303
|
slots
|
5240
5304
|
} = _ref;
|
5305
|
+
const root = ref();
|
5241
5306
|
const progress = useProxiedModel(props, 'modelValue');
|
5242
5307
|
const {
|
5243
5308
|
isRtl,
|
@@ -5279,6 +5344,24 @@ const VProgressLinear = genericComponent()({
|
|
5279
5344
|
const isReversed = computed(() => isRtl.value !== props.reverse);
|
5280
5345
|
const transition = computed(() => props.indeterminate ? 'fade-transition' : 'slide-x-transition');
|
5281
5346
|
const isForcedColorsModeActive = IN_BROWSER && window.matchMedia?.('(forced-colors: active)').matches;
|
5347
|
+
const containerWidth = shallowRef(0);
|
5348
|
+
const {
|
5349
|
+
hasChunks,
|
5350
|
+
chunksMaskStyles,
|
5351
|
+
snapValueToChunk
|
5352
|
+
} = useChunks(props, containerWidth);
|
5353
|
+
useToggleScope(hasChunks, () => {
|
5354
|
+
const {
|
5355
|
+
resizeRef
|
5356
|
+
} = useResizeObserver(entries => containerWidth.value = entries[0].contentRect.width);
|
5357
|
+
watchEffect(() => resizeRef.value = root.value);
|
5358
|
+
});
|
5359
|
+
const bufferWidth = computed(() => {
|
5360
|
+
return hasChunks.value ? snapValueToChunk(normalizedBuffer.value) : normalizedBuffer.value;
|
5361
|
+
});
|
5362
|
+
const barWidth = computed(() => {
|
5363
|
+
return hasChunks.value ? snapValueToChunk(normalizedValue.value) : normalizedValue.value;
|
5364
|
+
});
|
5282
5365
|
function handleClick(e) {
|
5283
5366
|
if (!intersectionRef.value) return;
|
5284
5367
|
const {
|
@@ -5289,8 +5372,11 @@ const VProgressLinear = genericComponent()({
|
|
5289
5372
|
const value = isReversed.value ? width - e.clientX + (right - width) : e.clientX - left;
|
5290
5373
|
progress.value = Math.round(value / width * max.value);
|
5291
5374
|
}
|
5375
|
+
watchEffect(() => {
|
5376
|
+
intersectionRef.value = root.value;
|
5377
|
+
});
|
5292
5378
|
useRender(() => createVNode(props.tag, {
|
5293
|
-
"ref":
|
5379
|
+
"ref": root,
|
5294
5380
|
"class": normalizeClass(['v-progress-linear', {
|
5295
5381
|
'v-progress-linear--absolute': props.absolute,
|
5296
5382
|
'v-progress-linear--active': props.active && isIntersecting.value,
|
@@ -5305,7 +5391,7 @@ const VProgressLinear = genericComponent()({
|
|
5305
5391
|
height: props.active ? convertToUnit(height.value) : 0,
|
5306
5392
|
'--v-progress-linear-height': convertToUnit(height.value),
|
5307
5393
|
...(props.absolute ? locationStyles.value : {})
|
5308
|
-
}, props.style]),
|
5394
|
+
}, chunksMaskStyles.value, props.style]),
|
5309
5395
|
"role": "progressbar",
|
5310
5396
|
"aria-hidden": props.active ? 'false' : 'true',
|
5311
5397
|
"aria-valuemin": "0",
|
@@ -5335,7 +5421,7 @@ const VProgressLinear = genericComponent()({
|
|
5335
5421
|
"class": normalizeClass(['v-progress-linear__buffer', !isForcedColorsModeActive ? bufferColorClasses.value : undefined]),
|
5336
5422
|
"style": normalizeStyle([bufferColorStyles.value, {
|
5337
5423
|
opacity: parseFloat(props.bufferOpacity),
|
5338
|
-
width: convertToUnit(
|
5424
|
+
width: convertToUnit(bufferWidth.value, '%')
|
5339
5425
|
}])
|
5340
5426
|
}, null), createVNode(Transition, {
|
5341
5427
|
"name": transition.value
|
@@ -5343,7 +5429,7 @@ const VProgressLinear = genericComponent()({
|
|
5343
5429
|
default: () => [!props.indeterminate ? createElementVNode("div", {
|
5344
5430
|
"class": normalizeClass(['v-progress-linear__determinate', !isForcedColorsModeActive ? barColorClasses.value : undefined]),
|
5345
5431
|
"style": normalizeStyle([barColorStyles.value, {
|
5346
|
-
width: convertToUnit(
|
5432
|
+
width: convertToUnit(barWidth.value, '%')
|
5347
5433
|
}])
|
5348
5434
|
}, null) : createElementVNode("div", {
|
5349
5435
|
"class": "v-progress-linear__indeterminate"
|
@@ -9558,6 +9644,11 @@ const VListItem = genericComponent()({
|
|
9558
9644
|
const isLink = toRef(() => props.link !== false && link.isLink.value);
|
9559
9645
|
const isSelectable = computed(() => !!list && (root.selectable.value || root.activatable.value || props.value != null));
|
9560
9646
|
const isClickable = computed(() => !props.disabled && props.link !== false && (props.link || link.isClickable.value || isSelectable.value));
|
9647
|
+
const role = computed(() => list ? isSelectable.value ? 'option' : 'listitem' : undefined);
|
9648
|
+
const ariaSelected = computed(() => {
|
9649
|
+
if (!isSelectable.value) return undefined;
|
9650
|
+
return root.activatable.value ? isActivated.value : root.selectable.value ? isSelected.value : isActive.value;
|
9651
|
+
});
|
9561
9652
|
const roundedProps = toRef(() => props.rounded || props.nav);
|
9562
9653
|
const color = toRef(() => props.color ?? props.activeColor);
|
9563
9654
|
const variantProps = toRef(() => ({
|
@@ -9661,7 +9752,8 @@ const VListItem = genericComponent()({
|
|
9661
9752
|
}, themeClasses.value, borderClasses.value, colorClasses.value, densityClasses.value, elevationClasses.value, lineClasses.value, roundedClasses.value, variantClasses.value, props.class],
|
9662
9753
|
"style": [colorStyles.value, dimensionStyles.value, props.style],
|
9663
9754
|
"tabindex": isClickable.value ? list ? -2 : 0 : undefined,
|
9664
|
-
"aria-selected":
|
9755
|
+
"aria-selected": ariaSelected.value,
|
9756
|
+
"role": role.value,
|
9665
9757
|
"onClick": onClick,
|
9666
9758
|
"onKeydown": isClickable.value && !isLink.value && onKeyDown
|
9667
9759
|
}, link.linkProps), {
|
@@ -10153,6 +10245,7 @@ const VList = genericComponent()({
|
|
10153
10245
|
const activeColor = toRef(() => props.activeColor);
|
10154
10246
|
const baseColor = toRef(() => props.baseColor);
|
10155
10247
|
const color = toRef(() => props.color);
|
10248
|
+
const isSelectable = toRef(() => props.selectable || props.activatable);
|
10156
10249
|
createList({
|
10157
10250
|
filterable: props.filterable
|
10158
10251
|
});
|
@@ -10222,7 +10315,7 @@ const VList = genericComponent()({
|
|
10222
10315
|
}, themeClasses.value, backgroundColorClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, lineClasses.value, roundedClasses.value, props.class]),
|
10223
10316
|
"style": normalizeStyle([backgroundColorStyles.value, dimensionStyles.value, props.style]),
|
10224
10317
|
"tabindex": props.disabled ? -1 : 0,
|
10225
|
-
"role":
|
10318
|
+
"role": isSelectable.value ? 'listbox' : 'list',
|
10226
10319
|
"aria-activedescendant": undefined,
|
10227
10320
|
"onFocusin": onFocusin,
|
10228
10321
|
"onFocusout": onFocusout,
|
@@ -13287,6 +13380,7 @@ const VSelect = genericComponent()({
|
|
13287
13380
|
"onKeydown": onListKeydown,
|
13288
13381
|
"onFocusin": onFocusin,
|
13289
13382
|
"tabindex": "-1",
|
13383
|
+
"selectable": true,
|
13290
13384
|
"aria-live": "polite",
|
13291
13385
|
"aria-label": `${props.label}-list`,
|
13292
13386
|
"color": props.itemColor ?? props.color
|
@@ -13906,6 +14000,7 @@ const VAutocomplete = genericComponent()({
|
|
13906
14000
|
"onFocusin": onFocusin,
|
13907
14001
|
"onFocusout": onFocusout,
|
13908
14002
|
"tabindex": "-1",
|
14003
|
+
"selectable": true,
|
13909
14004
|
"aria-live": "polite",
|
13910
14005
|
"color": props.itemColor ?? props.color
|
13911
14006
|
}, listEvents, props.listProps), {
|
@@ -18993,6 +19088,7 @@ const VCombobox = genericComponent()({
|
|
18993
19088
|
"selected": selectedValues.value,
|
18994
19089
|
"selectStrategy": props.multiple ? 'independent' : 'single-independent',
|
18995
19090
|
"onMousedown": e => e.preventDefault(),
|
19091
|
+
"selectable": true,
|
18996
19092
|
"onKeydown": onListKeydown,
|
18997
19093
|
"onFocusin": onFocusin,
|
18998
19094
|
"onFocusout": onFocusout,
|
@@ -24091,6 +24187,42 @@ function appendIfDirectory(path, item) {
|
|
24091
24187
|
return item.isDirectory ? `${path}/${item.name}` : path;
|
24092
24188
|
}
|
24093
24189
|
|
24190
|
+
// Utilities
|
24191
|
+
// Composables
|
24192
|
+
const makeFileFilterProps = propsFactory({
|
24193
|
+
filterByType: String
|
24194
|
+
}, 'file-accept');
|
24195
|
+
function useFileFilter(props) {
|
24196
|
+
const fileFilter = computed(() => props.filterByType ? createFilter(props.filterByType) : null);
|
24197
|
+
function filterAccepted(files) {
|
24198
|
+
if (fileFilter.value) {
|
24199
|
+
const accepted = files.filter(fileFilter.value);
|
24200
|
+
return {
|
24201
|
+
accepted,
|
24202
|
+
rejected: files.filter(f => !accepted.includes(f))
|
24203
|
+
};
|
24204
|
+
}
|
24205
|
+
return {
|
24206
|
+
accepted: files,
|
24207
|
+
rejected: []
|
24208
|
+
};
|
24209
|
+
}
|
24210
|
+
return {
|
24211
|
+
filterAccepted
|
24212
|
+
};
|
24213
|
+
}
|
24214
|
+
function createFilter(v) {
|
24215
|
+
const types = v.split(',').map(x => x.trim().toLowerCase());
|
24216
|
+
const extensionsToMatch = types.filter(x => x.startsWith('.'));
|
24217
|
+
const wildcards = types.filter(x => x.endsWith('/*'));
|
24218
|
+
const typesToMatch = types.filter(x => !extensionsToMatch.includes(x) && !wildcards.includes(x));
|
24219
|
+
return file => {
|
24220
|
+
const extension = file.name.split('.').at(-1)?.toLowerCase() ?? '';
|
24221
|
+
const typeGroup = file.type.split('/').at(0)?.toLowerCase() ?? '';
|
24222
|
+
return typesToMatch.includes(file.type) || extensionsToMatch.includes(`.${extension}`) || wildcards.includes(`${typeGroup}/*`);
|
24223
|
+
};
|
24224
|
+
}
|
24225
|
+
|
24094
24226
|
// Types
|
24095
24227
|
|
24096
24228
|
const makeVFileInputProps = propsFactory({
|
@@ -24123,6 +24255,7 @@ const makeVFileInputProps = propsFactory({
|
|
24123
24255
|
return wrapInArray(val).every(v => v != null && typeof v === 'object');
|
24124
24256
|
}
|
24125
24257
|
},
|
24258
|
+
...makeFileFilterProps(),
|
24126
24259
|
...makeVFieldProps({
|
24127
24260
|
clearable: true
|
24128
24261
|
})
|
@@ -24135,7 +24268,8 @@ const VFileInput = genericComponent()({
|
|
24135
24268
|
'click:control': e => true,
|
24136
24269
|
'mousedown:control': e => true,
|
24137
24270
|
'update:focused': focused => true,
|
24138
|
-
'update:modelValue': files => true
|
24271
|
+
'update:modelValue': files => true,
|
24272
|
+
rejected: files => true
|
24139
24273
|
},
|
24140
24274
|
setup(props, _ref) {
|
24141
24275
|
let {
|
@@ -24146,6 +24280,9 @@ const VFileInput = genericComponent()({
|
|
24146
24280
|
const {
|
24147
24281
|
t
|
24148
24282
|
} = useLocale();
|
24283
|
+
const {
|
24284
|
+
filterAccepted
|
24285
|
+
} = useFileFilter(props);
|
24149
24286
|
const model = useProxiedModel(props, 'modelValue', props.modelValue, val => wrapInArray(val), val => !props.multiple && Array.isArray(val) ? val[0] : val);
|
24150
24287
|
const {
|
24151
24288
|
isFocused,
|
@@ -24219,14 +24356,38 @@ const VFileInput = genericComponent()({
|
|
24219
24356
|
e.stopImmediatePropagation();
|
24220
24357
|
isDragging.value = false;
|
24221
24358
|
if (!inputRef.value || !hasFilesOrFolders(e)) return;
|
24359
|
+
const allDroppedFiles = await handleDrop(e);
|
24360
|
+
selectAccepted(allDroppedFiles);
|
24361
|
+
}
|
24362
|
+
function onFileSelection(e) {
|
24363
|
+
if (!e.target || e.repack) return; // prevent loop
|
24364
|
+
|
24365
|
+
if (!props.filterByType) {
|
24366
|
+
const target = e.target;
|
24367
|
+
model.value = [...(target.files ?? [])];
|
24368
|
+
} else {
|
24369
|
+
selectAccepted([...e.target.files]);
|
24370
|
+
}
|
24371
|
+
}
|
24372
|
+
function selectAccepted(files) {
|
24222
24373
|
const dataTransfer = new DataTransfer();
|
24223
|
-
|
24374
|
+
const {
|
24375
|
+
accepted,
|
24376
|
+
rejected
|
24377
|
+
} = filterAccepted(files);
|
24378
|
+
if (rejected.length) {
|
24379
|
+
emit('rejected', rejected);
|
24380
|
+
}
|
24381
|
+
for (const file of accepted) {
|
24224
24382
|
dataTransfer.items.add(file);
|
24225
24383
|
}
|
24226
24384
|
inputRef.value.files = dataTransfer.files;
|
24227
|
-
|
24385
|
+
model.value = [...dataTransfer.files];
|
24386
|
+
const event = new Event('change', {
|
24228
24387
|
bubbles: true
|
24229
|
-
})
|
24388
|
+
});
|
24389
|
+
event.repack = true;
|
24390
|
+
inputRef.value.dispatchEvent(event);
|
24230
24391
|
}
|
24231
24392
|
watch(model, newValue => {
|
24232
24393
|
const hasModelReset = !Array.isArray(newValue) || !newValue.length;
|
@@ -24243,6 +24404,8 @@ const VFileInput = genericComponent()({
|
|
24243
24404
|
...inputProps
|
24244
24405
|
} = VInput.filterProps(props);
|
24245
24406
|
const fieldProps = VField.filterProps(props);
|
24407
|
+
const expectsDirectory = attrs.webkitdirectory !== undefined && attrs.webkitdirectory !== false;
|
24408
|
+
const inputAccept = expectsDirectory ? undefined : props.filterByType ?? String(attrs.accept);
|
24246
24409
|
return createVNode(VInput, mergeProps({
|
24247
24410
|
"ref": vInputRef,
|
24248
24411
|
"modelValue": props.multiple ? model.value : model.value[0],
|
@@ -24296,6 +24459,7 @@ const VFileInput = genericComponent()({
|
|
24296
24459
|
return createElementVNode(Fragment, null, [createElementVNode("input", mergeProps({
|
24297
24460
|
"ref": inputRef,
|
24298
24461
|
"type": "file",
|
24462
|
+
"accept": inputAccept,
|
24299
24463
|
"readonly": isReadonly.value,
|
24300
24464
|
"disabled": isDisabled.value,
|
24301
24465
|
"multiple": props.multiple,
|
@@ -24305,11 +24469,7 @@ const VFileInput = genericComponent()({
|
|
24305
24469
|
if (isReadonly.value) e.preventDefault();
|
24306
24470
|
onFocus();
|
24307
24471
|
},
|
24308
|
-
"onChange":
|
24309
|
-
if (!e.target) return;
|
24310
|
-
const target = e.target;
|
24311
|
-
model.value = [...(target.files ?? [])];
|
24312
|
-
},
|
24472
|
+
"onChange": onFileSelection,
|
24313
24473
|
"onDragleave": onDragleave,
|
24314
24474
|
"onFocus": onFocus,
|
24315
24475
|
"onBlur": blur
|
@@ -31814,6 +31974,7 @@ const makeVFileUploadProps = propsFactory({
|
|
31814
31974
|
},
|
31815
31975
|
showSize: Boolean,
|
31816
31976
|
name: String,
|
31977
|
+
...makeFileFilterProps(),
|
31817
31978
|
...makeDelayProps(),
|
31818
31979
|
...makeDensityProps(),
|
31819
31980
|
...pick(makeVDividerProps({
|
@@ -31826,11 +31987,13 @@ const VFileUpload = genericComponent()({
|
|
31826
31987
|
inheritAttrs: false,
|
31827
31988
|
props: makeVFileUploadProps(),
|
31828
31989
|
emits: {
|
31829
|
-
'update:modelValue': files => true
|
31990
|
+
'update:modelValue': files => true,
|
31991
|
+
rejected: files => true
|
31830
31992
|
},
|
31831
31993
|
setup(props, _ref) {
|
31832
31994
|
let {
|
31833
31995
|
attrs,
|
31996
|
+
emit,
|
31834
31997
|
slots
|
31835
31998
|
} = _ref;
|
31836
31999
|
const {
|
@@ -31839,6 +32002,9 @@ const VFileUpload = genericComponent()({
|
|
31839
32002
|
const {
|
31840
32003
|
densityClasses
|
31841
32004
|
} = useDensity(props);
|
32005
|
+
const {
|
32006
|
+
filterAccepted
|
32007
|
+
} = useFileFilter(props);
|
31842
32008
|
const model = useProxiedModel(props, 'modelValue', props.modelValue, val => wrapInArray(val), val => props.multiple || Array.isArray(props.modelValue) ? val : val[0]);
|
31843
32009
|
const isDragging = shallowRef(false);
|
31844
32010
|
const vSheetRef = ref(null);
|
@@ -31860,14 +32026,38 @@ const VFileUpload = genericComponent()({
|
|
31860
32026
|
e.stopImmediatePropagation();
|
31861
32027
|
isDragging.value = false;
|
31862
32028
|
if (!inputRef.value) return;
|
32029
|
+
const allDroppedFiles = await handleDrop(e);
|
32030
|
+
selectAccepted(allDroppedFiles);
|
32031
|
+
}
|
32032
|
+
function onFileSelection(e) {
|
32033
|
+
if (!e.target || e.repack) return; // prevent loop
|
32034
|
+
|
32035
|
+
if (!props.filterByType) {
|
32036
|
+
const target = e.target;
|
32037
|
+
model.value = [...(target.files ?? [])];
|
32038
|
+
} else {
|
32039
|
+
selectAccepted([...e.target.files]);
|
32040
|
+
}
|
32041
|
+
}
|
32042
|
+
function selectAccepted(files) {
|
31863
32043
|
const dataTransfer = new DataTransfer();
|
31864
|
-
|
32044
|
+
const {
|
32045
|
+
accepted,
|
32046
|
+
rejected
|
32047
|
+
} = filterAccepted(files);
|
32048
|
+
if (rejected.length) {
|
32049
|
+
emit('rejected', rejected);
|
32050
|
+
}
|
32051
|
+
for (const file of accepted) {
|
31865
32052
|
dataTransfer.items.add(file);
|
31866
32053
|
}
|
31867
32054
|
inputRef.value.files = dataTransfer.files;
|
31868
|
-
|
32055
|
+
model.value = [...dataTransfer.files];
|
32056
|
+
const event = new Event('change', {
|
31869
32057
|
bubbles: true
|
31870
|
-
})
|
32058
|
+
});
|
32059
|
+
event.repack = true;
|
32060
|
+
inputRef.value.dispatchEvent(event);
|
31871
32061
|
}
|
31872
32062
|
function onClick() {
|
31873
32063
|
inputRef.value?.click();
|
@@ -31885,17 +32075,16 @@ const VFileUpload = genericComponent()({
|
|
31885
32075
|
const cardProps = VSheet.filterProps(props);
|
31886
32076
|
const dividerProps = VDivider.filterProps(props);
|
31887
32077
|
const [rootAttrs, inputAttrs] = filterInputAttrs(attrs);
|
32078
|
+
const expectsDirectory = attrs.webkitdirectory !== undefined && attrs.webkitdirectory !== false;
|
32079
|
+
const inputAccept = expectsDirectory ? undefined : props.filterByType ?? String(attrs.accept);
|
31888
32080
|
const inputNode = createElementVNode("input", mergeProps({
|
31889
32081
|
"ref": inputRef,
|
31890
32082
|
"type": "file",
|
32083
|
+
"accept": inputAccept,
|
31891
32084
|
"disabled": props.disabled,
|
31892
32085
|
"multiple": props.multiple,
|
31893
32086
|
"name": props.name,
|
31894
|
-
"onChange":
|
31895
|
-
if (!e.target) return;
|
31896
|
-
const target = e.target;
|
31897
|
-
model.value = [...(target.files ?? [])];
|
31898
|
-
}
|
32087
|
+
"onChange": onFileSelection
|
31899
32088
|
}, inputAttrs), null);
|
31900
32089
|
return createElementVNode(Fragment, null, [createVNode(VSheet, mergeProps({
|
31901
32090
|
"ref": vSheetRef
|
@@ -33672,7 +33861,7 @@ function createVuetify$1() {
|
|
33672
33861
|
};
|
33673
33862
|
});
|
33674
33863
|
}
|
33675
|
-
const version$1 = "3.9.0-dev.2025-07-
|
33864
|
+
const version$1 = "3.9.0-dev.2025-07-16";
|
33676
33865
|
createVuetify$1.version = version$1;
|
33677
33866
|
|
33678
33867
|
// Vue's inject() can only be used in setup
|
@@ -33970,7 +34159,7 @@ var index = /*#__PURE__*/Object.freeze({
|
|
33970
34159
|
|
33971
34160
|
/* eslint-disable local-rules/sort-imports */
|
33972
34161
|
|
33973
|
-
const version = "3.9.0-dev.2025-07-
|
34162
|
+
const version = "3.9.0-dev.2025-07-16";
|
33974
34163
|
|
33975
34164
|
/* eslint-disable local-rules/sort-imports */
|
33976
34165
|
|