Skip to content

Commit a8e2e56

Browse files
authored
fix(b-form-file): fix prop type checking for value prop (#4168)
1 parent 152fefc commit a8e2e56

File tree

5 files changed

+24
-7
lines changed

5 files changed

+24
-7
lines changed

src/components/form-file/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ assistive technologies.
253253

254254
With inputs of type file, normally the `v-model` is uni-directional (meaning you cannot pre-set the
255255
selected files). However, you can clear the file input's selected files by setting the `v-model` to
256-
either `null`, an empty string `''`, or an empty array `[]`).
256+
either `null` (for single mode) or an empty array `[]` (for multiple/directory mode).
257257

258258
Alternatively, `<b-form-file>` provides a `reset()` method that can be called to clear the file
259259
input. To take advantage of the `reset()` method, you will need to obtain a reference to the

src/components/form-file/form-file.js

+17-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import Vue from '../../utils/vue'
22
import { from as arrayFrom, isArray, concat } from '../../utils/array'
33
import { getComponentConfig } from '../../utils/config'
4-
import { isFunction } from '../../utils/inspect'
4+
import { isFile, isFunction, isUndefinedOrNull } from '../../utils/inspect'
55
import { File } from '../../utils/safe-types'
6+
import { warn } from '../../utils/warn'
67
import formCustomMixin from '../../mixins/form-custom'
78
import formMixin from '../../mixins/form'
89
import formStateMixin from '../../mixins/form-state'
@@ -27,7 +28,21 @@ export const BFormFile = /*#__PURE__*/ Vue.extend({
2728
},
2829
value: {
2930
type: [File, Array],
30-
default: null
31+
default: null,
32+
validator: val => {
33+
/* istanbul ignore next */
34+
if (val === '') {
35+
warn(
36+
`${NAME} - setting value/v-model to an empty string for reset is deprecated. Set to 'null' instead`
37+
)
38+
return true
39+
}
40+
return (
41+
isUndefinedOrNull(val) ||
42+
isFile(val) ||
43+
(isArray(val) && (val.length === 0 || val.every(isFile)))
44+
)
45+
}
3146
},
3247
accept: {
3348
type: String,

src/components/form-file/form-file.spec.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ describe('form-file', () => {
340340
const wrapper = mount(BFormFile, {
341341
propsData: {
342342
id: 'foo',
343-
value: ''
343+
value: null
344344
}
345345
})
346346
const file1 = new File(['foo'], 'foo.txt', {
@@ -358,8 +358,7 @@ describe('form-file', () => {
358358
wrapper.setProps({ value: null })
359359
await waitNT(wrapper.vm)
360360

361-
expect(wrapper.emitted('input').length).toEqual(2)
362-
expect(wrapper.emitted('input')[1][0]).toEqual(null)
361+
expect(wrapper.emitted('input').length).toEqual(1)
363362

364363
wrapper.destroy()
365364
})

src/components/form-file/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"props": [
1414
{
1515
"prop": "value",
16-
"description": "The current value of the file input. Will be an array if multiple or directory is set. Can be set to null or empty array to reset the file input"
16+
"description": "The current value of the file input. Will be a single File object or an array of File objects (if multiple or directory is set). Can be set to null, or an empty array to reset the file input"
1717
},
1818
{
1919
"prop": "accept",

src/utils/inspect.js

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { isArray } from './array'
22
import { isObject, isPlainObject } from './object'
3+
import { File } from './safe-types'
34

45
// --- Convenience inspection utilities ---
56

@@ -29,6 +30,8 @@ export const isDate = val => val instanceof Date
2930

3031
export const isEvent = val => val instanceof Event
3132

33+
export const isFile = val => val instanceof File
34+
3235
export const isRegExp = val => toRawType(val) === 'RegExp'
3336

3437
export const isPromise = val =>

0 commit comments

Comments
 (0)