@volverjs/ui-vue 0.0.10-beta.20 → 0.0.10-beta.22
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/dist/components/VvAccordion/VvAccordion.vue.d.ts +1 -1
- package/dist/components/VvAccordionGroup/VvAccordionGroup.vue.d.ts +1 -1
- package/dist/components/VvAction/VvAction.vue.d.ts +1 -1
- package/dist/components/VvAlert/VvAlert.vue.d.ts +1 -1
- package/dist/components/VvAlertGroup/VvAlertGroup.vue.d.ts +1 -1
- package/dist/components/VvAvatar/VvAvatar.vue.d.ts +1 -1
- package/dist/components/VvAvatarGroup/VvAvatarGroup.vue.d.ts +1 -1
- package/dist/components/VvBadge/VvBadge.vue.d.ts +1 -1
- package/dist/components/VvBreadcrumb/VvBreadcrumb.vue.d.ts +1 -1
- package/dist/components/VvButton/VvButton.vue.d.ts +1 -1
- package/dist/components/VvButtonGroup/VvButtonGroup.vue.d.ts +1 -1
- package/dist/components/VvCard/VvCard.vue.d.ts +1 -1
- package/dist/components/VvCheckbox/VvCheckbox.vue.d.ts +1 -1
- package/dist/components/VvCheckboxGroup/VvCheckboxGroup.vue.d.ts +1 -1
- package/dist/components/VvCombobox/VvCombobox.vue.d.ts +67 -67
- package/dist/components/VvCombobox/index.d.ts +8 -8
- package/dist/components/VvDialog/VvDialog.vue.d.ts +1 -1
- package/dist/components/VvDropdown/VvDropdown.vue.d.ts +70 -70
- package/dist/components/VvDropdown/VvDropdownAction.vue.d.ts +1 -1
- package/dist/components/VvDropdown/VvDropdownItem.vue.d.ts +1 -1
- package/dist/components/VvDropdown/VvDropdownOptgroup.vue.d.ts +1 -1
- package/dist/components/VvDropdown/VvDropdownOption.vue.d.ts +1 -1
- package/dist/components/VvDropdown/index.d.ts +8 -8
- package/dist/components/VvIcon/VvIcon.vue.d.ts +1 -1
- package/dist/components/VvIcon/index.d.ts +12 -0
- package/dist/components/VvInputFile/VvInputFile.es.js +231 -67
- package/dist/components/VvInputFile/VvInputFile.umd.js +1 -1
- package/dist/components/VvInputFile/VvInputFile.vue.d.ts +152 -29
- package/dist/components/VvInputFile/index.d.ts +119 -14
- package/dist/components/VvInputText/VvInputClearAction.d.ts +6 -4
- package/dist/components/VvInputText/VvInputPasswordAction.d.ts +10 -8
- package/dist/components/VvInputText/VvInputStepAction.d.ts +1 -1
- package/dist/components/VvInputText/VvInputText.es.js +73 -65
- package/dist/components/VvInputText/VvInputText.umd.js +1 -1
- package/dist/components/VvInputText/VvInputText.vue.d.ts +10 -10
- package/dist/components/VvInputText/index.d.ts +6 -15
- package/dist/components/VvNav/VvNav.vue.d.ts +1 -1
- package/dist/components/VvNav/VvNavItem.vue.d.ts +1 -1
- package/dist/components/VvNav/VvNavSeparator.vue.d.ts +1 -1
- package/dist/components/VvProgress/VvProgress.vue.d.ts +1 -1
- package/dist/components/VvRadio/VvRadio.vue.d.ts +1 -1
- package/dist/components/VvRadioGroup/VvRadioGroup.vue.d.ts +1 -1
- package/dist/components/VvSelect/VvSelect.vue.d.ts +1 -1
- package/dist/components/VvTab/VvTab.vue.d.ts +1 -1
- package/dist/components/VvTextarea/VvTextarea.vue.d.ts +1 -1
- package/dist/components/VvTooltip/VvTooltip.vue.d.ts +1 -1
- package/dist/components/common/HintSlot.d.ts +1 -1
- package/dist/components/index.es.js +247 -96
- package/dist/components/index.umd.js +1 -1
- package/dist/composables/alert/useAlert.d.ts +1 -1
- package/dist/composables/dropdown/useProvideDropdown.d.ts +1 -1
- package/dist/icons.es.js +210 -210
- package/dist/icons.umd.js +1 -1
- package/dist/index.es.js +20 -12
- package/dist/index.umd.js +1 -1
- package/dist/props/index.d.ts +8 -14
- package/dist/resolvers/unplugin.es.js +20 -12
- package/dist/resolvers/unplugin.umd.js +1 -1
- package/dist/stories/InputFile/InputFile.stories.d.ts +1 -2
- package/dist/stories/InputFile/{InputFileModifiers.stories.d.ts → InputFileDropArea.stories.d.ts} +4 -4
- package/dist/stories/InputFile/InputFileIconPosition.stories.d.ts +8 -0
- package/dist/stories/InputFile/InputFileSlots.stories.d.ts +1 -0
- package/dist/types/input-file.d.ts +2 -0
- package/package.json +49 -49
- package/src/assets/icons/detailed.json +1 -1
- package/src/assets/icons/normal.json +1 -1
- package/src/assets/icons/simple.json +1 -1
- package/src/components/VvIcon/index.ts +13 -0
- package/src/components/VvInputFile/VvInputFile.vue +108 -40
- package/src/components/VvInputFile/index.ts +88 -10
- package/src/components/VvInputText/VvInputClearAction.ts +10 -6
- package/src/components/VvInputText/VvInputPasswordAction.ts +13 -9
- package/src/components/VvInputText/VvInputText.vue +6 -6
- package/src/components/VvInputText/index.ts +7 -15
- package/src/stories/InputFile/InputFile.settings.ts +1 -1
- package/src/stories/InputFile/InputFile.stories.ts +7 -16
- package/src/stories/InputFile/{InputFileModifiers.stories.ts → InputFileDropArea.stories.ts} +18 -13
- package/src/stories/InputFile/InputFileIconPosition.stories.ts +43 -0
- package/src/stories/InputFile/InputFileSlots.stories.ts +11 -3
- package/src/types/input-file.ts +4 -2
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import type { IconifyIconOnLoad, IconifyRenderMode } from '@iconify/vue'
|
|
2
2
|
|
|
3
|
+
export const ACTION_ICONS = {
|
|
4
|
+
showPassword: 'eye-on',
|
|
5
|
+
hidePassword: 'eye-off',
|
|
6
|
+
showDatePicker: 'calendar',
|
|
7
|
+
showTimePicker: 'time',
|
|
8
|
+
showColorPicker: 'color',
|
|
9
|
+
clear: 'close',
|
|
10
|
+
add: 'add',
|
|
11
|
+
remove: 'trash',
|
|
12
|
+
edit: 'edit',
|
|
13
|
+
download: 'download',
|
|
14
|
+
} as const
|
|
15
|
+
|
|
3
16
|
export enum IconPrefix {
|
|
4
17
|
simple = 'simple',
|
|
5
18
|
normal = 'normal',
|
|
@@ -24,23 +24,37 @@
|
|
|
24
24
|
VvInputFileProps,
|
|
25
25
|
props,
|
|
26
26
|
)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
const { modifiers, id, readonly, icon, iconPosition, iconDownload } =
|
|
28
|
+
toRefs(props)
|
|
30
29
|
const hasId = useUniqueId(id)
|
|
31
30
|
const hasHintId = computed(() => `${hasId.value}-hint`)
|
|
32
31
|
|
|
32
|
+
const hasProgress = computed(() => {
|
|
33
|
+
if (!props.progress) {
|
|
34
|
+
return false
|
|
35
|
+
}
|
|
36
|
+
const progress =
|
|
37
|
+
typeof props.progress === 'string'
|
|
38
|
+
? parseInt(props.progress)
|
|
39
|
+
: props.progress
|
|
40
|
+
return progress > 0 && progress < 100
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
const { hasIconBefore, hasIconAfter } = useComponentIcon(icon, iconPosition)
|
|
44
|
+
const { hasIcon: hasIconDownload } = useComponentIcon(iconDownload)
|
|
45
|
+
|
|
33
46
|
// styles
|
|
34
47
|
const bemCssClasses = useModifiers(
|
|
35
48
|
'vv-input-file',
|
|
36
49
|
modifiers,
|
|
37
50
|
computed(() => ({
|
|
38
51
|
dragging: isDragging.value,
|
|
39
|
-
loading: props.loading,
|
|
52
|
+
loading: props.loading && !hasProgress.value,
|
|
40
53
|
valid: props.valid === true,
|
|
41
54
|
invalid: props.invalid === true,
|
|
42
|
-
'icon-before': !!
|
|
43
|
-
'icon-after': !!
|
|
55
|
+
'icon-before': !!hasIconBefore.value,
|
|
56
|
+
'icon-after': !!hasIconAfter.value,
|
|
57
|
+
'drop-area': hasDropArea.value,
|
|
44
58
|
})),
|
|
45
59
|
)
|
|
46
60
|
|
|
@@ -70,7 +84,7 @@
|
|
|
70
84
|
})
|
|
71
85
|
|
|
72
86
|
const hasDropArea = computed(() => {
|
|
73
|
-
return
|
|
87
|
+
return props.dropArea && !readonly.value
|
|
74
88
|
})
|
|
75
89
|
|
|
76
90
|
const isMultiple = computed(() => {
|
|
@@ -134,11 +148,11 @@
|
|
|
134
148
|
}
|
|
135
149
|
toReturn.push(file)
|
|
136
150
|
}
|
|
137
|
-
|
|
138
151
|
localModelValue.value = toReturn
|
|
152
|
+
selectedFileIndex.value = toReturn.length - 1
|
|
139
153
|
}
|
|
140
154
|
|
|
141
|
-
const
|
|
155
|
+
const onClickDropArea = () => {
|
|
142
156
|
if (!inputEl.value) {
|
|
143
157
|
return
|
|
144
158
|
}
|
|
@@ -152,22 +166,44 @@
|
|
|
152
166
|
localModelValue.value = undefined
|
|
153
167
|
return
|
|
154
168
|
}
|
|
169
|
+
if (selectedFileIndex.value === index) {
|
|
170
|
+
selectedFileIndex.value = 0
|
|
171
|
+
}
|
|
155
172
|
const toReturn = [...localModelValue.value]
|
|
156
173
|
toReturn.splice(index, 1)
|
|
157
174
|
localModelValue.value = toReturn
|
|
158
175
|
}
|
|
159
176
|
|
|
160
|
-
const
|
|
177
|
+
const selectedFileIndex = ref(0)
|
|
178
|
+
const PREVIEW_MIME_TYPES = ['image/jpeg', 'image/png']
|
|
161
179
|
const previewSrc = computed(() => {
|
|
162
180
|
if (files.value.length === 0) {
|
|
163
181
|
return
|
|
164
182
|
}
|
|
165
|
-
if (files.value[
|
|
166
|
-
return
|
|
167
|
-
|
|
168
|
-
|
|
183
|
+
if (!files.value[selectedFileIndex.value]) {
|
|
184
|
+
return undefined
|
|
185
|
+
}
|
|
186
|
+
if (files.value[selectedFileIndex.value] instanceof File) {
|
|
187
|
+
const currentFile = files.value[selectedFileIndex.value] as File
|
|
188
|
+
if (!PREVIEW_MIME_TYPES.includes(currentFile.type)) {
|
|
189
|
+
return undefined
|
|
190
|
+
}
|
|
191
|
+
return URL.createObjectURL(currentFile)
|
|
192
|
+
}
|
|
193
|
+
const currentFile = files.value[selectedFileIndex.value] as UploadedFile
|
|
194
|
+
if (currentFile.thumbnailUrl) {
|
|
195
|
+
return currentFile.thumbnailUrl
|
|
196
|
+
}
|
|
197
|
+
if (!PREVIEW_MIME_TYPES.includes(currentFile.type)) {
|
|
198
|
+
return undefined
|
|
199
|
+
}
|
|
200
|
+
return currentFile.url
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
watch(previewSrc, (_newValue, oldValue) => {
|
|
204
|
+
if (oldValue) {
|
|
205
|
+
URL.revokeObjectURL(oldValue)
|
|
169
206
|
}
|
|
170
|
-
return (files.value[currentFileIndex.value] as UploadedFile).url
|
|
171
207
|
})
|
|
172
208
|
|
|
173
209
|
onBeforeUnmount(() => {
|
|
@@ -193,7 +229,27 @@
|
|
|
193
229
|
link.setAttribute('download', file.name)
|
|
194
230
|
document.body.appendChild(link)
|
|
195
231
|
link.click()
|
|
232
|
+
document.body.removeChild(link)
|
|
233
|
+
URL.revokeObjectURL(link.href)
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const onClickSelectFile = (index: number) => {
|
|
237
|
+
selectedFileIndex.value = index
|
|
196
238
|
}
|
|
239
|
+
|
|
240
|
+
const dropdAreaActionLabel = computed(() => {
|
|
241
|
+
if (files.value.length === 0 || isMultiple.value) {
|
|
242
|
+
return props.labelAdd
|
|
243
|
+
}
|
|
244
|
+
return props.labelReplace
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
const dropAreaActionIcon = computed(() => {
|
|
248
|
+
if (files.value.length === 0 || isMultiple.value) {
|
|
249
|
+
return props.iconAdd
|
|
250
|
+
}
|
|
251
|
+
return props.iconReplace
|
|
252
|
+
})
|
|
197
253
|
</script>
|
|
198
254
|
|
|
199
255
|
<template>
|
|
@@ -208,35 +264,35 @@
|
|
|
208
264
|
@dragleave.prevent.stop="onDragleave"
|
|
209
265
|
@drop.prevent.stop="onDrop"
|
|
210
266
|
@dragover.prevent.stop
|
|
211
|
-
@click.stop="
|
|
267
|
+
@click.stop="onClickDropArea"
|
|
212
268
|
>
|
|
213
269
|
<slot name="drop-area">
|
|
214
|
-
<VvButton
|
|
215
|
-
v-if="!readonly"
|
|
216
|
-
modifiers="action"
|
|
217
|
-
aria-label="upload"
|
|
218
|
-
:label="!previewSrc ? labelButton : undefined"
|
|
219
|
-
:class="{
|
|
220
|
-
'absolute top-8 right-8': previewSrc,
|
|
221
|
-
}"
|
|
222
|
-
:icon="!previewSrc ? 'image' : isMultiple ? 'add' : 'edit'"
|
|
223
|
-
class="z-1"
|
|
224
|
-
@click.stop="onClick"
|
|
225
|
-
/>
|
|
226
270
|
<picture class="vv-input-file__preview">
|
|
227
271
|
<img
|
|
228
272
|
v-if="previewSrc"
|
|
229
273
|
:src="previewSrc"
|
|
230
|
-
:alt="files[
|
|
274
|
+
:alt="files[selectedFileIndex].name"
|
|
231
275
|
/>
|
|
232
276
|
</picture>
|
|
277
|
+
<VvButton
|
|
278
|
+
v-if="!readonly"
|
|
279
|
+
modifiers="action"
|
|
280
|
+
:label="!previewSrc ? dropdAreaActionLabel : undefined"
|
|
281
|
+
:title="previewSrc ? dropdAreaActionLabel : undefined"
|
|
282
|
+
:class="{
|
|
283
|
+
'vv-input-file__drop-area-action': previewSrc,
|
|
284
|
+
}"
|
|
285
|
+
:icon="dropAreaActionIcon"
|
|
286
|
+
@click.stop="onClickDropArea"
|
|
287
|
+
/>
|
|
233
288
|
</slot>
|
|
234
289
|
</div>
|
|
235
290
|
<div class="vv-input-file__wrapper">
|
|
236
|
-
<VvIcon v-if="
|
|
291
|
+
<VvIcon v-if="hasIconBefore" v-bind="hasIconBefore" />
|
|
237
292
|
<input
|
|
238
293
|
:id="hasId"
|
|
239
294
|
ref="inputEl"
|
|
295
|
+
type="file"
|
|
240
296
|
:readonly="readonly"
|
|
241
297
|
:placeholder="placeholder"
|
|
242
298
|
:aria-describedby="hasHintLabelOrSlot ? hasHintId : undefined"
|
|
@@ -246,29 +302,42 @@
|
|
|
246
302
|
"
|
|
247
303
|
:multiple="isMultiple"
|
|
248
304
|
:accept="accept"
|
|
249
|
-
type="file"
|
|
250
305
|
:name="name"
|
|
251
306
|
@change="onChange"
|
|
252
307
|
/>
|
|
253
|
-
<
|
|
308
|
+
<progress
|
|
309
|
+
v-if="hasProgress"
|
|
310
|
+
class="vv-input-file__progress"
|
|
311
|
+
:value="progress"
|
|
312
|
+
max="100"
|
|
313
|
+
>
|
|
314
|
+
{{ progress }}%
|
|
315
|
+
</progress>
|
|
316
|
+
<VvIcon v-if="hasIconAfter" v-bind="hasIconAfter" />
|
|
254
317
|
</div>
|
|
255
318
|
<ul class="vv-input-file__list">
|
|
256
319
|
<li
|
|
257
320
|
v-for="(file, index) in files"
|
|
258
321
|
:key="index"
|
|
259
322
|
class="vv-input-file__item"
|
|
260
|
-
|
|
323
|
+
:class="{
|
|
324
|
+
active:
|
|
325
|
+
index === selectedFileIndex &&
|
|
326
|
+
hasDropArea &&
|
|
327
|
+
files.length > 1,
|
|
328
|
+
}"
|
|
329
|
+
@click.stop="onClickSelectFile(index)"
|
|
261
330
|
>
|
|
262
331
|
<button
|
|
332
|
+
v-if="hasIconDownload"
|
|
263
333
|
type="button"
|
|
264
|
-
class="vv-input-file__item-
|
|
265
|
-
title="
|
|
266
|
-
aria-label="download-file"
|
|
334
|
+
class="vv-input-file__item-action"
|
|
335
|
+
:title="labelDownload"
|
|
267
336
|
@click.stop="onClickDownloadFile(file)"
|
|
268
337
|
>
|
|
269
|
-
<VvIcon
|
|
338
|
+
<VvIcon v-bind="hasIconDownload" />
|
|
270
339
|
</button>
|
|
271
|
-
<div class="vv-input-file__item-name
|
|
340
|
+
<div class="vv-input-file__item-name">
|
|
272
341
|
{{ file.name }}
|
|
273
342
|
</div>
|
|
274
343
|
<small class="vv-input-file__item-info">
|
|
@@ -278,8 +347,7 @@
|
|
|
278
347
|
v-if="!readonly"
|
|
279
348
|
type="button"
|
|
280
349
|
class="vv-input-file__item-remove"
|
|
281
|
-
title="
|
|
282
|
-
aria-label="remove-file"
|
|
350
|
+
:title="labelRemove"
|
|
283
351
|
@click.stop="onClickRemoveFile(index)"
|
|
284
352
|
/>
|
|
285
353
|
</li>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { UploadedFile } from '@/types'
|
|
2
2
|
import {
|
|
3
|
+
IdNameProps,
|
|
3
4
|
ModifiersProps,
|
|
4
5
|
ValidProps,
|
|
5
6
|
InvalidProps,
|
|
@@ -7,13 +8,16 @@ import {
|
|
|
7
8
|
LabelProps,
|
|
8
9
|
LoadingProps,
|
|
9
10
|
ReadonlyProps,
|
|
11
|
+
IconProps,
|
|
10
12
|
} from '../../props'
|
|
13
|
+
import { type VvIconProps, ACTION_ICONS } from '../VvIcon'
|
|
11
14
|
|
|
12
15
|
export type VvInputFileEvents = {
|
|
13
16
|
'update:modelValue': [File | undefined]
|
|
14
17
|
}
|
|
15
18
|
|
|
16
19
|
export const VvInputFileProps = {
|
|
20
|
+
...IdNameProps,
|
|
17
21
|
...ModifiersProps,
|
|
18
22
|
...ValidProps,
|
|
19
23
|
...InvalidProps,
|
|
@@ -21,18 +25,92 @@ export const VvInputFileProps = {
|
|
|
21
25
|
...LabelProps,
|
|
22
26
|
...LoadingProps,
|
|
23
27
|
...ReadonlyProps,
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
...IconProps,
|
|
29
|
+
/**
|
|
30
|
+
* Input value
|
|
31
|
+
*/
|
|
26
32
|
modelValue: {
|
|
27
33
|
type: Object as PropType<File | (File | UploadedFile)[] | UploadedFile>,
|
|
28
34
|
required: true,
|
|
29
35
|
},
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Whether to show progress bar
|
|
38
|
+
*/
|
|
39
|
+
progress: { type: [Number, String], default: undefined },
|
|
40
|
+
/**
|
|
41
|
+
* Input
|
|
42
|
+
* Text that appears in the form control when it has no value set
|
|
43
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#placeholder
|
|
44
|
+
*/
|
|
45
|
+
placeholder: { type: String, default: undefined },
|
|
46
|
+
/**
|
|
47
|
+
* File types to accept
|
|
48
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/accept
|
|
49
|
+
*/
|
|
50
|
+
accept: { type: String, default: '*' },
|
|
51
|
+
/**
|
|
52
|
+
* Whether to allow multiple values
|
|
53
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#multiple
|
|
54
|
+
*/
|
|
55
|
+
multiple: { type: Boolean, default: false },
|
|
56
|
+
/**
|
|
57
|
+
* Max number of files
|
|
58
|
+
*/
|
|
59
|
+
max: { type: [Number, String], default: undefined },
|
|
60
|
+
/**
|
|
61
|
+
* Show drop area
|
|
62
|
+
*/
|
|
63
|
+
dropArea: { type: Boolean, default: false },
|
|
64
|
+
/**
|
|
65
|
+
* Label for add button
|
|
66
|
+
*/
|
|
67
|
+
labelAdd: {
|
|
68
|
+
type: String,
|
|
69
|
+
default: 'Add file',
|
|
70
|
+
},
|
|
71
|
+
/**
|
|
72
|
+
* VvIcon name for add button
|
|
73
|
+
* @see VVIcon
|
|
74
|
+
*/
|
|
75
|
+
iconAdd: {
|
|
76
|
+
type: [String, Object] as PropType<string | VvIconProps>,
|
|
77
|
+
default: ACTION_ICONS.add,
|
|
78
|
+
},
|
|
79
|
+
/**
|
|
80
|
+
* Label for replace button
|
|
81
|
+
*/
|
|
82
|
+
labelReplace: {
|
|
83
|
+
type: String,
|
|
84
|
+
default: 'Replace file',
|
|
85
|
+
},
|
|
86
|
+
/**
|
|
87
|
+
* VvIcon name for replace button
|
|
88
|
+
* @see VVIcon
|
|
89
|
+
*/
|
|
90
|
+
iconReplace: {
|
|
91
|
+
type: [String, Object] as PropType<string | VvIconProps>,
|
|
92
|
+
default: ACTION_ICONS.edit,
|
|
93
|
+
},
|
|
94
|
+
/**
|
|
95
|
+
* Label for download button
|
|
96
|
+
*/
|
|
97
|
+
labelDownload: {
|
|
98
|
+
type: String,
|
|
99
|
+
default: 'Downlaod file',
|
|
100
|
+
},
|
|
101
|
+
/**
|
|
102
|
+
* VvIcon name for download button
|
|
103
|
+
* @see VVIcon
|
|
104
|
+
*/
|
|
105
|
+
iconDownload: {
|
|
106
|
+
type: [String, Object] as PropType<string | VvIconProps>,
|
|
107
|
+
default: ACTION_ICONS.download,
|
|
108
|
+
},
|
|
109
|
+
/**
|
|
110
|
+
* Label for remove button
|
|
111
|
+
*/
|
|
112
|
+
labelRemove: {
|
|
113
|
+
type: String,
|
|
114
|
+
default: 'Remove file',
|
|
115
|
+
},
|
|
38
116
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { VvIconProps } from '../VvIcon'
|
|
1
2
|
import VvIcon from '../VvIcon/VvIcon.vue'
|
|
2
3
|
|
|
3
4
|
export default defineComponent({
|
|
@@ -14,28 +15,31 @@ export default defineComponent({
|
|
|
14
15
|
default: 'Clear',
|
|
15
16
|
},
|
|
16
17
|
icon: {
|
|
17
|
-
type: String,
|
|
18
|
+
type: [String, Object] as PropType<string | VvIconProps>,
|
|
18
19
|
default: 'close',
|
|
19
20
|
},
|
|
20
21
|
},
|
|
21
22
|
emits: ['clear'],
|
|
22
23
|
setup(props, { emit }) {
|
|
24
|
+
const { hasIcon } = useComponentIcon(computed(() => props.icon))
|
|
23
25
|
function onClick(e: Event) {
|
|
24
26
|
e?.stopPropagation()
|
|
25
27
|
if (!props.disabled) {
|
|
26
28
|
emit('clear')
|
|
27
29
|
}
|
|
28
30
|
}
|
|
29
|
-
|
|
30
31
|
return {
|
|
32
|
+
hasIcon,
|
|
31
33
|
onClick,
|
|
32
34
|
}
|
|
33
35
|
},
|
|
34
36
|
render() {
|
|
35
|
-
const icon =
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
const icon = this.hasIcon
|
|
38
|
+
? h(VvIcon, {
|
|
39
|
+
...this.hasIcon,
|
|
40
|
+
class: 'vv-input-text__icon',
|
|
41
|
+
})
|
|
42
|
+
: undefined
|
|
39
43
|
|
|
40
44
|
return h(
|
|
41
45
|
'button',
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { TYPES_ICON } from '../VvInputText'
|
|
2
1
|
import VvIcon from '../VvIcon/VvIcon.vue'
|
|
2
|
+
import { type VvIconProps, ACTION_ICONS } from '../VvIcon'
|
|
3
3
|
|
|
4
4
|
export default defineComponent({
|
|
5
5
|
components: {
|
|
@@ -19,12 +19,12 @@ export default defineComponent({
|
|
|
19
19
|
default: 'Hide password',
|
|
20
20
|
},
|
|
21
21
|
iconShow: {
|
|
22
|
-
type: String,
|
|
23
|
-
default:
|
|
22
|
+
type: [String, Object] as PropType<string | VvIconProps>,
|
|
23
|
+
default: ACTION_ICONS.showPassword,
|
|
24
24
|
},
|
|
25
25
|
iconHide: {
|
|
26
|
-
type: String,
|
|
27
|
-
default:
|
|
26
|
+
type: [String, Object] as PropType<string | VvIconProps>,
|
|
27
|
+
default: ACTION_ICONS.hidePassword,
|
|
28
28
|
},
|
|
29
29
|
},
|
|
30
30
|
emits: ['toggle-password'],
|
|
@@ -33,6 +33,7 @@ export default defineComponent({
|
|
|
33
33
|
const activeIcon = computed(() =>
|
|
34
34
|
active.value ? props.iconHide : props.iconShow,
|
|
35
35
|
)
|
|
36
|
+
const { hasIcon } = useComponentIcon(activeIcon)
|
|
36
37
|
|
|
37
38
|
function onClick(e: Event) {
|
|
38
39
|
e?.stopPropagation()
|
|
@@ -45,14 +46,17 @@ export default defineComponent({
|
|
|
45
46
|
return {
|
|
46
47
|
active,
|
|
47
48
|
activeIcon,
|
|
49
|
+
hasIcon,
|
|
48
50
|
onClick,
|
|
49
51
|
}
|
|
50
52
|
},
|
|
51
53
|
render() {
|
|
52
|
-
const icon =
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
const icon = this.hasIcon
|
|
55
|
+
? h(VvIcon, {
|
|
56
|
+
...this.hasIcon,
|
|
57
|
+
class: 'vv-input-text__icon',
|
|
58
|
+
})
|
|
59
|
+
: undefined
|
|
56
60
|
return h(
|
|
57
61
|
'button',
|
|
58
62
|
{
|
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
import { useIMask } from 'vue-imask'
|
|
10
10
|
import HintSlotFactory from '../common/HintSlot'
|
|
11
11
|
import VvIcon from '../VvIcon/VvIcon.vue'
|
|
12
|
+
import { ACTION_ICONS } from '../VvIcon'
|
|
12
13
|
import VvInputTextActionsFactory from '../VvInputText/VvInputTextActions'
|
|
13
14
|
import {
|
|
14
15
|
VvInputTextEvents,
|
|
15
16
|
VvInputTextProps,
|
|
16
17
|
INPUT_TYPES,
|
|
17
|
-
TYPES_ICON,
|
|
18
18
|
} from '../VvInputText'
|
|
19
19
|
|
|
20
20
|
// props, emit, slots and attrs
|
|
@@ -256,14 +256,14 @@
|
|
|
256
256
|
}
|
|
257
257
|
switch (props.type) {
|
|
258
258
|
case INPUT_TYPES.COLOR:
|
|
259
|
-
return { name:
|
|
259
|
+
return { name: ACTION_ICONS.showColorPicker }
|
|
260
260
|
case INPUT_TYPES.DATE:
|
|
261
261
|
case INPUT_TYPES.DATETIME_LOCAL:
|
|
262
262
|
case INPUT_TYPES.WEEK:
|
|
263
263
|
case INPUT_TYPES.MONTH:
|
|
264
|
-
return { name:
|
|
264
|
+
return { name: ACTION_ICONS.showDatePicker }
|
|
265
265
|
case INPUT_TYPES.TIME:
|
|
266
|
-
return { name:
|
|
266
|
+
return { name: ACTION_ICONS.showTimePicker }
|
|
267
267
|
}
|
|
268
268
|
return undefined
|
|
269
269
|
})
|
|
@@ -306,8 +306,8 @@
|
|
|
306
306
|
loading: loading.value,
|
|
307
307
|
disabled: props.disabled,
|
|
308
308
|
readonly: props.readonly,
|
|
309
|
-
'icon-before': hasIconBefore.value
|
|
310
|
-
'icon-after': iconAfter.value
|
|
309
|
+
'icon-before': !!hasIconBefore.value,
|
|
310
|
+
'icon-after': !!iconAfter.value,
|
|
311
311
|
floating: props.floating && !isEmpty(props.label),
|
|
312
312
|
dirty: isDirty.value,
|
|
313
313
|
focus: isFocused.value,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ExtractPropTypes, PropType } from 'vue'
|
|
2
2
|
import type { FactoryOpts } from 'imask'
|
|
3
3
|
import { InputTextareaProps } from '../../props'
|
|
4
|
+
import { type VvIconProps, ACTION_ICONS } from '../VvIcon'
|
|
4
5
|
|
|
5
6
|
export const INPUT_TYPES = {
|
|
6
7
|
TEXT: 'text',
|
|
@@ -19,15 +20,6 @@ export const INPUT_TYPES = {
|
|
|
19
20
|
} as const
|
|
20
21
|
export type InputType = ValueOf<typeof INPUT_TYPES>
|
|
21
22
|
|
|
22
|
-
export const TYPES_ICON = {
|
|
23
|
-
PASSWORD_SHOW: 'eye-on',
|
|
24
|
-
PASSWORD_HIDE: 'eye-off',
|
|
25
|
-
DATE: 'calendar',
|
|
26
|
-
TIME: 'time',
|
|
27
|
-
COLOR: 'color',
|
|
28
|
-
SEARCH: 'close',
|
|
29
|
-
} as const
|
|
30
|
-
|
|
31
23
|
export const VvInputTextEvents = [
|
|
32
24
|
'update:modelValue',
|
|
33
25
|
'update:masked',
|
|
@@ -98,24 +90,24 @@ export const VvInputTextProps = {
|
|
|
98
90
|
* @see VVIcon
|
|
99
91
|
*/
|
|
100
92
|
iconShowPassword: {
|
|
101
|
-
type: String,
|
|
102
|
-
default:
|
|
93
|
+
type: [String, Object] as PropType<string | VvIconProps>,
|
|
94
|
+
default: ACTION_ICONS.showPassword,
|
|
103
95
|
},
|
|
104
96
|
/**
|
|
105
97
|
* VvIcon name for hide password button
|
|
106
98
|
* @see VVIcon
|
|
107
99
|
*/
|
|
108
100
|
iconHidePassword: {
|
|
109
|
-
type: String,
|
|
110
|
-
default:
|
|
101
|
+
type: [String, Object] as PropType<string | VvIconProps>,
|
|
102
|
+
default: ACTION_ICONS.hidePassword,
|
|
111
103
|
},
|
|
112
104
|
/**
|
|
113
105
|
* VvIcon name for clear button
|
|
114
106
|
* @see VVIcon
|
|
115
107
|
*/
|
|
116
108
|
iconClear: {
|
|
117
|
-
type: String,
|
|
118
|
-
default:
|
|
109
|
+
type: [String, Object] as PropType<string | VvIconProps>,
|
|
110
|
+
default: ACTION_ICONS.clear,
|
|
119
111
|
},
|
|
120
112
|
/**
|
|
121
113
|
* Label for step up button
|
|
@@ -28,12 +28,10 @@ export const Default: Story = {
|
|
|
28
28
|
}
|
|
29
29
|
},
|
|
30
30
|
template: /* html */ `
|
|
31
|
-
<
|
|
32
|
-
<
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
</vv-input-file>
|
|
36
|
-
</div>
|
|
31
|
+
<vv-input-file v-bind="args" v-model="files">
|
|
32
|
+
<template #drop-area v-if="args['drop-area']"><div v-html="args['drop-area']"></div></template>
|
|
33
|
+
<template #hint v-if="args['hint']"><div v-html="args['hint']"></div></template>
|
|
34
|
+
</vv-input-file>
|
|
37
35
|
`,
|
|
38
36
|
}),
|
|
39
37
|
}
|
|
@@ -81,18 +79,11 @@ export const Loading: Story = {
|
|
|
81
79
|
},
|
|
82
80
|
}
|
|
83
81
|
|
|
84
|
-
export const
|
|
82
|
+
export const Progress: Story = {
|
|
85
83
|
...Default,
|
|
86
84
|
args: {
|
|
87
85
|
...defaultArgs,
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export const IconRight: Story = {
|
|
93
|
-
...Default,
|
|
94
|
-
args: {
|
|
95
|
-
...defaultArgs,
|
|
96
|
-
iconRight: 'akar-icons:heart',
|
|
86
|
+
progress: 30,
|
|
87
|
+
hintLabel: '30%',
|
|
97
88
|
},
|
|
98
89
|
}
|