@volverjs/ui-vue 0.0.10-beta.20 → 0.0.10-beta.21

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 (115) hide show
  1. package/dist/components/VvAccordion/VvAccordion.es.js +3 -1
  2. package/dist/components/VvAccordion/VvAccordion.umd.js +1 -1
  3. package/dist/components/VvAccordion/VvAccordion.vue.d.ts +1 -1
  4. package/dist/components/VvAccordionGroup/VvAccordionGroup.es.js +6 -1
  5. package/dist/components/VvAccordionGroup/VvAccordionGroup.umd.js +1 -1
  6. package/dist/components/VvAccordionGroup/VvAccordionGroup.vue.d.ts +1 -1
  7. package/dist/components/VvAction/VvAction.es.js +2 -1
  8. package/dist/components/VvAction/VvAction.umd.js +1 -1
  9. package/dist/components/VvAction/VvAction.vue.d.ts +1 -1
  10. package/dist/components/VvAlert/VvAlert.es.js +7 -0
  11. package/dist/components/VvAlert/VvAlert.umd.js +1 -1
  12. package/dist/components/VvAlert/VvAlert.vue.d.ts +1 -1
  13. package/dist/components/VvAlertGroup/VvAlertGroup.es.js +10 -0
  14. package/dist/components/VvAlertGroup/VvAlertGroup.umd.js +1 -1
  15. package/dist/components/VvAlertGroup/VvAlertGroup.vue.d.ts +1 -1
  16. package/dist/components/VvAvatar/VvAvatar.vue.d.ts +1 -1
  17. package/dist/components/VvAvatarGroup/VvAvatarGroup.vue.d.ts +1 -1
  18. package/dist/components/VvBadge/VvBadge.es.js +2 -1
  19. package/dist/components/VvBadge/VvBadge.umd.js +1 -1
  20. package/dist/components/VvBadge/VvBadge.vue.d.ts +1 -1
  21. package/dist/components/VvBreadcrumb/VvBreadcrumb.es.js +3 -1
  22. package/dist/components/VvBreadcrumb/VvBreadcrumb.umd.js +1 -1
  23. package/dist/components/VvBreadcrumb/VvBreadcrumb.vue.d.ts +1 -1
  24. package/dist/components/VvButton/VvButton.es.js +33 -15
  25. package/dist/components/VvButton/VvButton.umd.js +1 -1
  26. package/dist/components/VvButton/VvButton.vue.d.ts +1 -1
  27. package/dist/components/VvButtonGroup/VvButtonGroup.es.js +2 -1
  28. package/dist/components/VvButtonGroup/VvButtonGroup.umd.js +1 -1
  29. package/dist/components/VvButtonGroup/VvButtonGroup.vue.d.ts +1 -1
  30. package/dist/components/VvCard/VvCard.es.js +5 -1
  31. package/dist/components/VvCard/VvCard.umd.js +1 -1
  32. package/dist/components/VvCard/VvCard.vue.d.ts +1 -1
  33. package/dist/components/VvCheckbox/VvCheckbox.es.js +2 -1
  34. package/dist/components/VvCheckbox/VvCheckbox.umd.js +1 -1
  35. package/dist/components/VvCheckbox/VvCheckbox.vue.d.ts +1 -1
  36. package/dist/components/VvCheckboxGroup/VvCheckboxGroup.es.js +13 -2
  37. package/dist/components/VvCheckboxGroup/VvCheckboxGroup.umd.js +1 -1
  38. package/dist/components/VvCheckboxGroup/VvCheckboxGroup.vue.d.ts +1 -1
  39. package/dist/components/VvCombobox/VvCombobox.es.js +48 -15
  40. package/dist/components/VvCombobox/VvCombobox.umd.js +1 -1
  41. package/dist/components/VvCombobox/VvCombobox.vue.d.ts +42 -42
  42. package/dist/components/VvDialog/VvDialog.es.js +3 -0
  43. package/dist/components/VvDialog/VvDialog.umd.js +1 -1
  44. package/dist/components/VvDialog/VvDialog.vue.d.ts +1 -1
  45. package/dist/components/VvDropdown/VvDropdown.vue.d.ts +42 -42
  46. package/dist/components/VvDropdown/VvDropdownAction.vue.d.ts +1 -1
  47. package/dist/components/VvDropdown/VvDropdownItem.vue.d.ts +1 -1
  48. package/dist/components/VvDropdown/VvDropdownOptgroup.vue.d.ts +1 -1
  49. package/dist/components/VvDropdown/VvDropdownOption.vue.d.ts +1 -1
  50. package/dist/components/VvDropdownAction/VvDropdownAction.es.js +2 -1
  51. package/dist/components/VvDropdownAction/VvDropdownAction.umd.js +1 -1
  52. package/dist/components/VvIcon/VvIcon.vue.d.ts +1 -1
  53. package/dist/components/VvIcon/index.d.ts +12 -0
  54. package/dist/components/VvInputFile/VvInputFile.es.js +258 -82
  55. package/dist/components/VvInputFile/VvInputFile.umd.js +1 -1
  56. package/dist/components/VvInputFile/VvInputFile.vue.d.ts +152 -29
  57. package/dist/components/VvInputFile/index.d.ts +119 -14
  58. package/dist/components/VvInputText/VvInputClearAction.d.ts +6 -4
  59. package/dist/components/VvInputText/VvInputPasswordAction.d.ts +10 -8
  60. package/dist/components/VvInputText/VvInputStepAction.d.ts +1 -1
  61. package/dist/components/VvInputText/VvInputText.es.js +79 -65
  62. package/dist/components/VvInputText/VvInputText.umd.js +1 -1
  63. package/dist/components/VvInputText/VvInputText.vue.d.ts +10 -10
  64. package/dist/components/VvInputText/index.d.ts +6 -15
  65. package/dist/components/VvNav/VvNav.es.js +2 -1
  66. package/dist/components/VvNav/VvNav.umd.js +1 -1
  67. package/dist/components/VvNav/VvNav.vue.d.ts +1 -1
  68. package/dist/components/VvNav/VvNavItem.vue.d.ts +1 -1
  69. package/dist/components/VvNav/VvNavSeparator.vue.d.ts +1 -1
  70. package/dist/components/VvNavItem/VvNavItem.es.js +2 -1
  71. package/dist/components/VvNavItem/VvNavItem.umd.js +1 -1
  72. package/dist/components/VvProgress/VvProgress.vue.d.ts +1 -1
  73. package/dist/components/VvRadio/VvRadio.vue.d.ts +1 -1
  74. package/dist/components/VvRadioGroup/VvRadioGroup.es.js +13 -1
  75. package/dist/components/VvRadioGroup/VvRadioGroup.umd.js +1 -1
  76. package/dist/components/VvRadioGroup/VvRadioGroup.vue.d.ts +1 -1
  77. package/dist/components/VvSelect/VvSelect.es.js +4 -0
  78. package/dist/components/VvSelect/VvSelect.umd.js +1 -1
  79. package/dist/components/VvSelect/VvSelect.vue.d.ts +1 -1
  80. package/dist/components/VvTab/VvTab.es.js +7 -2
  81. package/dist/components/VvTab/VvTab.umd.js +1 -1
  82. package/dist/components/VvTab/VvTab.vue.d.ts +1 -1
  83. package/dist/components/VvTextarea/VvTextarea.es.js +4 -0
  84. package/dist/components/VvTextarea/VvTextarea.umd.js +1 -1
  85. package/dist/components/VvTextarea/VvTextarea.vue.d.ts +1 -1
  86. package/dist/components/VvTooltip/VvTooltip.vue.d.ts +1 -1
  87. package/dist/components/common/HintSlot.d.ts +1 -1
  88. package/dist/components/index.es.js +354 -115
  89. package/dist/components/index.umd.js +1 -1
  90. package/dist/composables/alert/useAlert.d.ts +1 -1
  91. package/dist/composables/dropdown/useProvideDropdown.d.ts +1 -1
  92. package/dist/icons.es.js +210 -210
  93. package/dist/icons.umd.js +1 -1
  94. package/dist/stories/InputFile/InputFile.stories.d.ts +1 -2
  95. package/dist/stories/InputFile/{InputFileModifiers.stories.d.ts → InputFileDropArea.stories.d.ts} +4 -4
  96. package/dist/stories/InputFile/InputFileIconPosition.stories.d.ts +8 -0
  97. package/dist/stories/InputFile/InputFileSlots.stories.d.ts +1 -0
  98. package/dist/types/input-file.d.ts +2 -0
  99. package/package.json +45 -45
  100. package/src/assets/icons/detailed.json +1 -1
  101. package/src/assets/icons/normal.json +1 -1
  102. package/src/assets/icons/simple.json +1 -1
  103. package/src/components/VvIcon/index.ts +13 -0
  104. package/src/components/VvInputFile/VvInputFile.vue +103 -40
  105. package/src/components/VvInputFile/index.ts +88 -10
  106. package/src/components/VvInputText/VvInputClearAction.ts +10 -6
  107. package/src/components/VvInputText/VvInputPasswordAction.ts +13 -9
  108. package/src/components/VvInputText/VvInputText.vue +6 -6
  109. package/src/components/VvInputText/index.ts +7 -15
  110. package/src/stories/InputFile/InputFile.settings.ts +1 -1
  111. package/src/stories/InputFile/InputFile.stories.ts +7 -16
  112. package/src/stories/InputFile/{InputFileModifiers.stories.ts → InputFileDropArea.stories.ts} +18 -13
  113. package/src/stories/InputFile/InputFileIconPosition.stories.ts +43 -0
  114. package/src/stories/InputFile/InputFileSlots.stories.ts +11 -3
  115. 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
- const { modifiers, id, readonly } = toRefs(props)
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': !!props.iconLeft,
43
- 'icon-after': !!props.iconRight,
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 modifiers?.value?.includes('drop-area')
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 onClick = () => {
155
+ const onClickDropArea = () => {
142
156
  if (!inputEl.value) {
143
157
  return
144
158
  }
@@ -157,17 +171,34 @@
157
171
  localModelValue.value = toReturn
158
172
  }
159
173
 
160
- const currentFileIndex = ref(0)
174
+ const selectedFileIndex = ref(0)
175
+ const PREVIEW_MIME_TYPES = ['image/jpeg', 'image/png']
161
176
  const previewSrc = computed(() => {
162
177
  if (files.value.length === 0) {
163
178
  return
164
179
  }
165
- if (files.value[currentFileIndex.value] instanceof File) {
166
- return URL.createObjectURL(
167
- files.value[currentFileIndex.value] as File,
168
- )
180
+
181
+ if (files.value[selectedFileIndex.value] instanceof File) {
182
+ const currentFile = files.value[selectedFileIndex.value] as File
183
+ if (!PREVIEW_MIME_TYPES.includes(currentFile.type)) {
184
+ return undefined
185
+ }
186
+ return URL.createObjectURL(currentFile)
187
+ }
188
+ const currentFile = files.value[selectedFileIndex.value] as UploadedFile
189
+ if (currentFile.thumbnailUrl) {
190
+ return currentFile.thumbnailUrl
191
+ }
192
+ if (!PREVIEW_MIME_TYPES.includes(currentFile.type)) {
193
+ return undefined
194
+ }
195
+ return currentFile.url
196
+ })
197
+
198
+ watch(previewSrc, (_newValue, oldValue) => {
199
+ if (oldValue) {
200
+ URL.revokeObjectURL(oldValue)
169
201
  }
170
- return (files.value[currentFileIndex.value] as UploadedFile).url
171
202
  })
172
203
 
173
204
  onBeforeUnmount(() => {
@@ -193,7 +224,27 @@
193
224
  link.setAttribute('download', file.name)
194
225
  document.body.appendChild(link)
195
226
  link.click()
227
+ document.body.removeChild(link)
228
+ URL.revokeObjectURL(link.href)
196
229
  }
230
+
231
+ const onClickSelectFile = (index: number) => {
232
+ selectedFileIndex.value = index
233
+ }
234
+
235
+ const dropdAreaActionLabel = computed(() => {
236
+ if (files.value.length === 0 || isMultiple.value) {
237
+ return props.labelAdd
238
+ }
239
+ return props.labelReplace
240
+ })
241
+
242
+ const dropAreaActionIcon = computed(() => {
243
+ if (files.value.length === 0 || isMultiple.value) {
244
+ return props.iconAdd
245
+ }
246
+ return props.iconReplace
247
+ })
197
248
  </script>
198
249
 
199
250
  <template>
@@ -208,35 +259,35 @@
208
259
  @dragleave.prevent.stop="onDragleave"
209
260
  @drop.prevent.stop="onDrop"
210
261
  @dragover.prevent.stop
211
- @click.stop="onClick"
262
+ @click.stop="onClickDropArea"
212
263
  >
213
264
  <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
265
  <picture class="vv-input-file__preview">
227
266
  <img
228
267
  v-if="previewSrc"
229
268
  :src="previewSrc"
230
- :alt="files[currentFileIndex].name"
269
+ :alt="files[selectedFileIndex].name"
231
270
  />
232
271
  </picture>
272
+ <VvButton
273
+ v-if="!readonly"
274
+ modifiers="action"
275
+ :label="!previewSrc ? dropdAreaActionLabel : undefined"
276
+ :title="previewSrc ? dropdAreaActionLabel : undefined"
277
+ :class="{
278
+ 'vv-input-file__drop-area-action': previewSrc,
279
+ }"
280
+ :icon="dropAreaActionIcon"
281
+ @click.stop="onClickDropArea"
282
+ />
233
283
  </slot>
234
284
  </div>
235
285
  <div class="vv-input-file__wrapper">
236
- <VvIcon v-if="iconLeft" :name="iconLeft" />
286
+ <VvIcon v-if="hasIconBefore" v-bind="hasIconBefore" />
237
287
  <input
238
288
  :id="hasId"
239
289
  ref="inputEl"
290
+ type="file"
240
291
  :readonly="readonly"
241
292
  :placeholder="placeholder"
242
293
  :aria-describedby="hasHintLabelOrSlot ? hasHintId : undefined"
@@ -246,29 +297,42 @@
246
297
  "
247
298
  :multiple="isMultiple"
248
299
  :accept="accept"
249
- type="file"
250
300
  :name="name"
251
301
  @change="onChange"
252
302
  />
253
- <VvIcon v-if="iconRight" :name="iconRight" />
303
+ <progress
304
+ v-if="hasProgress"
305
+ class="vv-input-file__progress"
306
+ :value="progress"
307
+ max="100"
308
+ >
309
+ {{ progress }}%
310
+ </progress>
311
+ <VvIcon v-if="hasIconAfter" v-bind="hasIconAfter" />
254
312
  </div>
255
313
  <ul class="vv-input-file__list">
256
314
  <li
257
315
  v-for="(file, index) in files"
258
316
  :key="index"
259
317
  class="vv-input-file__item"
260
- @click.stop="currentFileIndex = index"
318
+ :class="{
319
+ active:
320
+ index === selectedFileIndex &&
321
+ hasDropArea &&
322
+ files.length > 1,
323
+ }"
324
+ @click.stop="onClickSelectFile(index)"
261
325
  >
262
326
  <button
327
+ v-if="hasIconDownload"
263
328
  type="button"
264
- class="vv-input-file__item-icon cursor-pointer"
265
- title="Download"
266
- aria-label="download-file"
329
+ class="vv-input-file__item-action"
330
+ :title="labelDownload"
267
331
  @click.stop="onClickDownloadFile(file)"
268
332
  >
269
- <VvIcon name="download" />
333
+ <VvIcon v-bind="hasIconDownload" />
270
334
  </button>
271
- <div class="vv-input-file__item-name cursor-pointer">
335
+ <div class="vv-input-file__item-name">
272
336
  {{ file.name }}
273
337
  </div>
274
338
  <small class="vv-input-file__item-info">
@@ -278,8 +342,7 @@
278
342
  v-if="!readonly"
279
343
  type="button"
280
344
  class="vv-input-file__item-remove"
281
- title="Remove"
282
- aria-label="remove-file"
345
+ :title="labelRemove"
283
346
  @click.stop="onClickRemoveFile(index)"
284
347
  />
285
348
  </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
- name: { type: String },
25
- id: { type: String },
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
- max: [Number, String],
31
- labelButton: { type: String, default: 'Image' },
32
- loading: Boolean,
33
- accept: String,
34
- placeholder: String,
35
- multiple: Boolean,
36
- iconLeft: String,
37
- iconRight: String,
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 = h(VvIcon, {
36
- name: this.icon,
37
- class: 'vv-input-text__icon',
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: TYPES_ICON.PASSWORD_SHOW,
22
+ type: [String, Object] as PropType<string | VvIconProps>,
23
+ default: ACTION_ICONS.showPassword,
24
24
  },
25
25
  iconHide: {
26
- type: String,
27
- default: TYPES_ICON.PASSWORD_HIDE,
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 = h(VvIcon, {
53
- name: this.activeIcon,
54
- class: 'vv-input-text__icon',
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: TYPES_ICON.COLOR }
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: TYPES_ICON.DATE }
264
+ return { name: ACTION_ICONS.showDatePicker }
265
265
  case INPUT_TYPES.TIME:
266
- return { name: TYPES_ICON.TIME }
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 !== undefined,
310
- 'icon-after': iconAfter.value !== undefined,
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: TYPES_ICON.PASSWORD_SHOW,
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: TYPES_ICON.PASSWORD_HIDE,
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: TYPES_ICON.SEARCH,
109
+ type: [String, Object] as PropType<string | VvIconProps>,
110
+ default: ACTION_ICONS.clear,
119
111
  },
120
112
  /**
121
113
  * Label for step up button
@@ -11,7 +11,7 @@ export const argTypes = {
11
11
  ...HintArgTypes,
12
12
  modifiers: {
13
13
  ...ModifiersArgTypes.modifiers,
14
- options: ['drop-area', 'hidden', 'square', 'circle'],
14
+ options: ['hidden', 'square', 'circle'],
15
15
  },
16
16
  'drop-area': {
17
17
  description: 'Drop area slot',
@@ -28,12 +28,10 @@ export const Default: Story = {
28
28
  }
29
29
  },
30
30
  template: /* html */ `
31
- <div class="w-1/4">
32
- <vv-input-file v-bind="args" v-model="files">
33
- <template #drop-area v-if="args['drop-area']"><div v-html="args['drop-area']"></div></template>
34
- <template #hint v-if="args['hint']"><div v-html="args['hint']"></div></template>
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 IconLeft: Story = {
82
+ export const Progress: Story = {
85
83
  ...Default,
86
84
  args: {
87
85
  ...defaultArgs,
88
- iconLeft: 'material-symbols:cloud-outline',
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
  }