vueless 0.0.102 → 0.0.104

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vueless",
3
- "version": "0.0.102",
3
+ "version": "0.0.104",
4
4
  "license": "MIT",
5
5
  "description": "Vue Styleless Component Framework.",
6
6
  "homepage": "https://vueless.com",
@@ -169,7 +169,8 @@ const isShownModal = computed({
169
169
  set: (value) => emit("update:modelValue", value),
170
170
  });
171
171
 
172
- const currentLocale = computed(() => merge(tm("UModalConfirm"), props.config.i18n));
172
+ const i18nGlobal = tm(UModalConfirm);
173
+ const currentLocale = computed(() => merge(defaultConfig.i18n, i18nGlobal, props.config.i18n));
173
174
 
174
175
  function closeModal() {
175
176
  isShownModal.value = false;
@@ -218,7 +218,8 @@ const {
218
218
  } = useAttrs(props);
219
219
  const { tm } = useLocale();
220
220
 
221
- const currentLocale = computed(() => merge(tm("UDataList"), props.config.i18n));
221
+ const i18nGlobal = tm(UDataListName);
222
+ const currentLocale = computed(() => merge(defaultConfig.i18n, i18nGlobal, props.config.i18n));
222
223
 
223
224
  function onDragMove(event) {
224
225
  const isDisabledNestingItem = event.draggedContext.element.isDisabledNesting;
@@ -427,7 +427,8 @@ const isFooterSticky = computed(
427
427
  isCheckedMoreOneTableItems.value,
428
428
  );
429
429
 
430
- const currentLocale = computed(() => merge(tm("UTable"), props.config.i18n));
430
+ const i18nGlobal = tm(UTable);
431
+ const currentLocale = computed(() => merge(defaultConfig.i18n, i18nGlobal, props.config.i18n));
431
432
 
432
433
  const normalizedColumns = computed(() => TableService.normalizeColumns(props.columns));
433
434
 
@@ -242,7 +242,8 @@ const { tm } = useLocale();
242
242
 
243
243
  defineExpose({ pointerSet, pointerBackward, pointerForward, pointerReset, addPointerElement });
244
244
 
245
- const currentLocale = computed(() => merge(tm("UDropdownList"), props.config.i18n));
245
+ const i18nGlobal = tm(UDropdownList);
246
+ const currentLocale = computed(() => merge(defaultConfig.i18n, i18nGlobal, props.config.i18n));
246
247
 
247
248
  const addOptionKeyCombination = computed(() => {
248
249
  return isMac ? "(⌘ + Enter)" : "(Ctrl + Enter)";
@@ -348,7 +348,8 @@ const isCurrentView = computed(() => ({
348
348
  year: currentView.value === VIEW.year,
349
349
  }));
350
350
 
351
- const currentLocale = computed(() => merge(tm("UCalendar"), props.config.i18n));
351
+ const i18nGlobal = tm(UCalendar);
352
+ const currentLocale = computed(() => merge(defaultConfig.i18n, i18nGlobal, props.config.i18n));
352
353
 
353
354
  const locale = computed(() => {
354
355
  const { months, weekdays } = currentLocale.value;
@@ -370,13 +371,15 @@ const locale = computed(() => {
370
371
  const userFormatLocale = computed(() => {
371
372
  const { months, weekdays } = currentLocale.value;
372
373
 
373
- const monthsLonghand = props.config.i18n?.months?.userFormat
374
- ? months.userFormat
375
- : months.longhand;
374
+ const monthsLonghand =
375
+ Boolean(props.config.i18n?.months?.userFormat) || Boolean(i18nGlobal?.months?.userFormat)
376
+ ? months.userFormat
377
+ : months.longhand;
376
378
 
377
- const weekdaysLonghand = props.config.i18n?.weekdays?.userFormat
378
- ? weekdays.userFormat
379
- : weekdays.longhand;
379
+ const weekdaysLonghand =
380
+ Boolean(props.config.i18n?.weekdays?.userFormat) || Boolean(i18nGlobal?.weekdays?.userFormat)
381
+ ? weekdays.userFormat
382
+ : weekdays.longhand;
380
383
 
381
384
  // formatted locale
382
385
  return {
@@ -259,7 +259,8 @@ function onBlur(event) {
259
259
  function formatUserDate(data) {
260
260
  if (props.dateFormat !== STANDARD_USER_FORMAT) return data;
261
261
 
262
- const currentLocale = merge(tm("UDatePicker"), props.config.i18n);
262
+ const i18nGlobal = tm(UDatePicker);
263
+ const currentLocale = computed(() => merge(defaultConfig.i18n, i18nGlobal, props.config.i18n));
263
264
 
264
265
  let prefix = "";
265
266
  const formattedDate = data.charAt(0).toUpperCase() + data.toLowerCase().slice(1);
@@ -273,15 +274,15 @@ function formatUserDate(data) {
273
274
  const isTomorrow = isSameDay(addDays(today, 1), selectedDate);
274
275
 
275
276
  if (isToday) {
276
- prefix = currentLocale.today;
277
+ prefix = currentLocale.value.today;
277
278
  }
278
279
 
279
280
  if (isYesterday) {
280
- prefix = currentLocale.yesterday;
281
+ prefix = currentLocale.value.yesterday;
281
282
  }
282
283
 
283
284
  if (isTomorrow) {
284
- prefix = currentLocale.tomorrow;
285
+ prefix = currentLocale.value.tomorrow;
285
286
  }
286
287
 
287
288
  return prefix ? `${prefix}, ${formattedDateWithoutDay}` : formattedDate;
@@ -432,8 +432,10 @@ const localValue = computed({
432
432
  });
433
433
 
434
434
  const { isMobileBreakpoint } = useBreakpoint();
435
+ const i18nGlobal = tm(UDatePickerRange);
436
+
435
437
  const rangeInputName = computed(() => `rangeInput-${props.id}`);
436
- const currentLocale = computed(() => merge(tm("UDatePickerRange"), props.config.i18n));
438
+ const currentLocale = computed(() => merge(defaultConfig.i18n, i18nGlobal, props.config.i18n));
437
439
 
438
440
  const locale = computed(() => {
439
441
  const { months, weekdays } = currentLocale.value;
@@ -455,13 +457,15 @@ const locale = computed(() => {
455
457
  const userFormatLocale = computed(() => {
456
458
  const { months, weekdays } = currentLocale.value;
457
459
 
458
- const monthsLonghand = props.config.i18n?.months?.userFormat
459
- ? months.userFormat
460
- : months.longhand;
460
+ const monthsLonghand =
461
+ Boolean(props.config.i18n?.months?.userFormat) || Boolean(i18nGlobal?.months?.userFormat)
462
+ ? months.userFormat
463
+ : months.longhand;
461
464
 
462
- const weekdaysLonghand = props.config.i18n?.weekdays?.userFormat
463
- ? weekdays.userFormat
464
- : weekdays.longhand;
465
+ const weekdaysLonghand =
466
+ Boolean(props.config.i18n?.weekdays?.userFormat) || Boolean(i18nGlobal?.weekdays?.userFormat)
467
+ ? weekdays.userFormat
468
+ : weekdays.longhand;
465
469
 
466
470
  // formatted locale
467
471
  return {
@@ -6,7 +6,7 @@ import defaultConfig from "../configs/default.config";
6
6
 
7
7
  export function useAttrs(props) {
8
8
  const { config, getAttrs } = useUI(defaultConfig, () => props.config);
9
- const { dropzoneWrapper, placeholder } = config.value;
9
+ const { dropzoneWrapper, placeholder, selectedItem } = config.value;
10
10
 
11
11
  const cvaDropzoneWrapper = cva({
12
12
  base: dropzoneWrapper.base,
@@ -20,6 +20,12 @@ export function useAttrs(props) {
20
20
  compoundVariants: placeholder.compoundVariants,
21
21
  });
22
22
 
23
+ const cvaSelectedItem = cva({
24
+ base: selectedItem.base,
25
+ variants: selectedItem.variants,
26
+ compoundVariants: selectedItem.compoundVariants,
27
+ });
28
+
23
29
  const dropzoneWrapperClasses = computed(() =>
24
30
  cvaDropzoneWrapper({
25
31
  error: Boolean(props.error),
@@ -35,20 +41,25 @@ export function useAttrs(props) {
35
41
  }),
36
42
  );
37
43
 
44
+ const selectedItemClasses = computed(() =>
45
+ cvaSelectedItem({
46
+ size: props.size,
47
+ }),
48
+ );
49
+
38
50
  const labelAttrs = getAttrs("label", { isComponent: true });
39
51
  const buttonAttrs = getAttrs("button", { isComponent: true });
40
52
  const dropzoneWrapperAttrs = getAttrs("dropzoneWrapper", { classes: dropzoneWrapperClasses });
41
53
  const descriptionAttrs = getAttrs("description", { isComponent: true });
54
+ const contentWrapperAttrs = getAttrs("contentWrapper");
42
55
  const buttonWrapperAttrs = getAttrs("buttonWrapper");
43
- const placeholderWrapperAttrs = getAttrs("placeholderWrapper");
44
- const placeholderAttrs = getAttrs("placeholder", {
45
- classes: placeholderClasses,
46
- isComponent: true,
47
- });
48
- const placeholderIconAttrs = getAttrs("placeholderIcon", { isComponent: true });
56
+ const placeholderAttrs = getAttrs("placeholder", { classes: placeholderClasses });
49
57
  const clearIconAttrs = getAttrs("clearIcon", { isComponent: true });
58
+ const chooseFileIconAttrs = getAttrs("chooseFileIcon", { isComponent: true });
50
59
  const chooseFileIconNameAttrs = getAttrs("chooseFileIconName", { isComponent: true });
51
60
  const inputAttrs = getAttrs("input");
61
+ const fileListAttrs = getAttrs("fileList");
62
+ const selectedItemAttrs = getAttrs("selectedItem", { classes: selectedItemClasses });
52
63
 
53
64
  return {
54
65
  config,
@@ -57,11 +68,13 @@ export function useAttrs(props) {
57
68
  buttonAttrs,
58
69
  dropzoneWrapperAttrs,
59
70
  descriptionAttrs,
60
- buttonWrapperAttrs,
61
- placeholderWrapperAttrs,
62
- placeholderIconAttrs,
71
+ contentWrapperAttrs,
63
72
  clearIconAttrs,
64
73
  chooseFileIconNameAttrs,
65
74
  placeholderAttrs,
75
+ fileListAttrs,
76
+ buttonWrapperAttrs,
77
+ selectedItemAttrs,
78
+ chooseFileIconAttrs,
66
79
  };
67
80
  }
@@ -26,10 +26,20 @@ export default /*tw*/ {
26
26
  ],
27
27
  },
28
28
  description: "text-gray-700",
29
- buttonWrapper: "relative mt-3 flex w-full gap-52 justify-between rounded bg-brand-50 p-4",
30
- placeholderWrapper: "flex items-center gap-2",
29
+ contentWrapper: "relative mt-3 flex w-full gap-6 justify-between items-start rounded bg-brand-50 p-4",
30
+ fileList: "pr-4 shrink-0 text-gray-700 flex-grow flex flex-col gap-4",
31
31
  placeholder: {
32
- base: "pr-4 shrink-0 text-ellipsis overflow-hidden text-gray-700 text-nowrap",
32
+ base: "pr-4 shrink-0 text-gray-700 flex-grow",
33
+ variants: {
34
+ size: {
35
+ sm: "text-sm",
36
+ md: "text-base",
37
+ lg: "text-lg",
38
+ },
39
+ },
40
+ },
41
+ selectedItem: {
42
+ base: "pr-4 shrink-0 text-gray-700 flex-grow",
33
43
  variants: {
34
44
  size: {
35
45
  sm: "text-sm",
@@ -39,25 +49,25 @@ export default /*tw*/ {
39
49
  },
40
50
  },
41
51
  button: "hover:cursor-pointer",
42
- placeholderIcon: "-rotate-45",
43
- placeholderIconName: "attach_file",
44
52
  chooseFileIcon: "",
45
- chooseFileIconName: "upload_file",
53
+ chooseFileIconName: "attach_file",
46
54
  clearIcon: "",
47
55
  clearIconName: "close",
48
- dropzoneWrapperHover: "border-gray-400 bg-gray-50",
56
+ dropzoneWrapperHover: "border-gray-400",
49
57
  dropzoneWrapperError: "hover:border-red-400 border-red-300",
50
58
  input: "sr-only pointer-events-none size-0 opacity-0",
59
+ buttonWrapper: "flex gap-4 items-center",
51
60
  i18n: {
52
61
  sizeError: "File size is too big.",
53
62
  formatError: "Format is not supported.",
54
63
  noFile: "No file selected",
55
- uploadFile: "Upload file",
64
+ uploadFile: "Choose file",
56
65
  },
57
66
  defaultVariants: {
58
67
  size: "md",
59
68
  labelAlign: "topInside",
60
69
  allowedFileTypes: [],
61
- maxFileSize: 100,
70
+ multiple: false,
71
+ maxFileSize: 0,
62
72
  },
63
73
  };
@@ -3,58 +3,64 @@
3
3
  <div ref="dropZoneRef" :ondrop="onDrop" v-bind="dropzoneWrapperAttrs">
4
4
  <UText :size="nestedComponentSize" v-bind="descriptionAttrs" :html="description" />
5
5
 
6
- <div v-bind="buttonWrapperAttrs">
7
- <div v-bind="placeholderWrapperAttrs">
6
+ <div v-bind="contentWrapperAttrs">
7
+ <slot name="left" />
8
+ <span v-if="!isValue" v-bind="placeholderAttrs" v-text="currentLocale.noFile" />
9
+ <div v-else v-bind="fileListAttrs">
10
+ <template v-if="props.multiple">
11
+ <span
12
+ v-for="(file, idx) in currentFiles"
13
+ v-bind="selectedItemAttrs"
14
+ :key="idx"
15
+ v-text="file.name"
16
+ />
17
+ </template>
18
+ <span v-else v-bind="selectedItemAttrs" v-text="currentFiles.name" />
19
+ </div>
20
+
21
+ <div v-bind="buttonWrapperAttrs">
22
+ <template v-if="Array.isArray(currentFiles) || !currentFiles">
23
+ <UButton
24
+ class="hover:cursor-pointer"
25
+ :label="currentLocale.uploadFile"
26
+ variant="thirdary"
27
+ filled
28
+ :size="nestedComponentSize"
29
+ v-bind="buttonAttrs"
30
+ tag="label"
31
+ :for="id"
32
+ >
33
+ <template #right>
34
+ <UIcon
35
+ internal
36
+ :size="nestedComponentSize"
37
+ :name="config.chooseFileIconName"
38
+ v-bind="chooseFileIconAttrs"
39
+ />
40
+ </template>
41
+ </UButton>
42
+
43
+ <input
44
+ :id="id"
45
+ ref="fileInputRef"
46
+ :multiple="multiple"
47
+ type="file"
48
+ :accept="accept"
49
+ v-bind="inputAttrs"
50
+ @change="onChangeFile"
51
+ />
52
+ </template>
8
53
  <UIcon
9
- pill
54
+ v-if="isValue"
55
+ interactive
10
56
  internal
11
57
  :size="nestedComponentSize"
12
- :name="config.placeholderIconName"
13
- v-bind="placeholderIconAttrs"
58
+ :name="config.clearIconName"
59
+ pill
60
+ v-bind="clearIconAttrs"
61
+ @click="onClickResetFiles"
14
62
  />
15
- <span v-bind="placeholderAttrs" v-text="placeholder" />
16
63
  </div>
17
-
18
- <template v-if="!currentFiles.length">
19
- <UButton
20
- class="hover:cursor-pointer"
21
- :label="currentLocale.uploadFile"
22
- variant="thirdary"
23
- filled
24
- :size="nestedComponentSize"
25
- v-bind="buttonAttrs"
26
- tag="label"
27
- :for="id"
28
- >
29
- <template #right>
30
- <UIcon
31
- internal
32
- :size="nestedComponentSize"
33
- :name="config.chooseFileIconName"
34
- v-bind="chooseFileIconAttrs"
35
- />
36
- </template>
37
- </UButton>
38
-
39
- <input
40
- :id="id"
41
- ref="fileInputRef"
42
- type="file"
43
- :accept="accept"
44
- v-bind="inputAttrs"
45
- @change="onChangeFile"
46
- />
47
- </template>
48
- <UIcon
49
- v-else
50
- interactive
51
- internal
52
- :size="nestedComponentSize"
53
- :name="config.clearIconName"
54
- pill
55
- v-bind="clearIconAttrs"
56
- @click="onClickResetFiles"
57
- />
58
64
  </div>
59
65
  </div>
60
66
  </ULabel>
@@ -87,7 +93,7 @@ const props = defineProps({
87
93
  */
88
94
  label: {
89
95
  type: String,
90
- default: "Label",
96
+ default: "",
91
97
  },
92
98
 
93
99
  /**
@@ -95,7 +101,7 @@ const props = defineProps({
95
101
  */
96
102
  description: {
97
103
  type: String,
98
- default: "Some description here",
104
+ default: "",
99
105
  },
100
106
 
101
107
  /**
@@ -108,8 +114,16 @@ const props = defineProps({
108
114
  },
109
115
 
110
116
  modelValue: {
111
- type: Array,
112
- default: () => [],
117
+ type: [Array, File],
118
+ default: null,
119
+ },
120
+
121
+ /**
122
+ * Allow select multiple files.
123
+ */
124
+ multiple: {
125
+ type: Boolean,
126
+ default: UIService.get(defaultConfig, UInputFile).default.multiple,
113
127
  },
114
128
 
115
129
  /**
@@ -175,20 +189,26 @@ const {
175
189
  buttonAttrs,
176
190
  dropzoneWrapperAttrs,
177
191
  descriptionAttrs,
178
- buttonWrapperAttrs,
179
- placeholderWrapperAttrs,
180
- placeholderIconAttrs,
192
+ contentWrapperAttrs,
181
193
  clearIconAttrs,
182
194
  chooseFileIconAttrs,
183
195
  placeholderAttrs,
184
196
  inputAttrs,
197
+ fileListAttrs,
198
+ buttonWrapperAttrs,
199
+ selectedItemAttrs,
185
200
  } = useAttrs(props);
186
201
 
187
- const currentLocale = computed(() => merge(tm("UInputFile"), props.config.i18n));
202
+ const i18nGlobal = tm(UInputFile);
203
+ const currentLocale = computed(() => merge(defaultConfig.i18n, i18nGlobal, props.config.i18n));
188
204
 
189
205
  const currentFiles = computed({
190
206
  get: () => props.modelValue,
191
- set: (newValue) => emit("update:modelValue", newValue),
207
+ set: (newValue) => {
208
+ const fallbackValue = props.multiple ? [] : null;
209
+
210
+ emit("update:modelValue", newValue || fallbackValue);
211
+ },
192
212
  });
193
213
 
194
214
  const currentError = computed({
@@ -196,16 +216,23 @@ const currentError = computed({
196
216
  set: (newValue) => emit("update:error", newValue),
197
217
  });
198
218
 
199
- const accept = computed(() => {
200
- return props.allowedFileTypes.join(",");
201
- });
202
-
203
219
  const extensionNames = computed(() => {
204
220
  return props.allowedFileTypes.map((type) => type.replace(".", ""));
205
221
  });
206
222
 
207
- const placeholder = computed(() => {
208
- return currentFiles.value.length ? currentFiles.value[0].name : currentLocale.value.noFile;
223
+ const allowedFileTypeFormats = computed(() => {
224
+ return props.allowedFileTypes.map((type) => (type.startsWith(".") ? type : `.${type}`));
225
+ });
226
+
227
+ const accept = computed(() => {
228
+ return allowedFileTypeFormats.value.join(",");
229
+ });
230
+
231
+ const isValue = computed(() => {
232
+ return (
233
+ (Array.isArray(currentFiles.value) && currentFiles.value.length) ||
234
+ (!Array.isArray(currentFiles.value) && currentFiles.value)
235
+ );
209
236
  });
210
237
 
211
238
  const nestedComponentSize = computed(() => {
@@ -237,7 +264,7 @@ function validate(file) {
237
264
 
238
265
  const isValidSize = targetFileSize <= props.maxFileSize;
239
266
 
240
- if (!isValidSize) {
267
+ if (!isValidSize && props.maxFileSize) {
241
268
  currentError.value = currentLocale.value.sizeError;
242
269
  }
243
270
 
@@ -255,11 +282,15 @@ function onChangeFile(event) {
255
282
  return;
256
283
  }
257
284
 
258
- currentFiles.value = Array.from(event.target.files);
285
+ currentFiles.value = props.multiple
286
+ ? [...currentFiles.value, Array.from(event.target.files).at(0)]
287
+ : Array.from(event.target.files).at(0);
288
+
289
+ if (fileInputRef.value) fileInputRef.value.value = "";
259
290
  }
260
291
 
261
292
  function onClickResetFiles() {
262
- currentFiles.value = [];
293
+ currentFiles.value = null;
263
294
 
264
295
  if (fileInputRef.value) fileInputRef.value.value = "";
265
296
  }
@@ -267,13 +298,13 @@ function onClickResetFiles() {
267
298
  function onDragOver(event) {
268
299
  event.preventDefault();
269
300
 
270
- dropZoneRef.value.classList.add(config.value.dropzoneWrapperHover.split(" "));
301
+ dropZoneRef.value.classList.add(...config.value.dropzoneWrapperHover.split(" "));
271
302
  }
272
303
 
273
304
  function onDragLeave(event) {
274
305
  event.preventDefault();
275
306
 
276
- dropZoneRef.value.classList.remove(config.value.dropzoneWrapperHover.split(" "));
307
+ dropZoneRef.value.classList.remove(...config.value.dropzoneWrapperHover.split(" "));
277
308
  }
278
309
 
279
310
  function onDrop(event) {
@@ -296,7 +327,7 @@ function onDrop(event) {
296
327
  return;
297
328
  }
298
329
 
299
- currentFiles.value = [targetFile];
330
+ currentFiles.value = props.multiple ? [...currentFiles.value, targetFile] : targetFile;
300
331
  });
301
332
  }
302
333
  </script>
@@ -500,7 +500,8 @@ const {
500
500
  dropdownListAttrs,
501
501
  } = useAttrs(props, { isTop, isOpen, selectedLabel });
502
502
 
503
- const currentLocale = computed(() => merge(tm("USelect"), props.config.i18n));
503
+ const i18nGlobal = tm(USelect);
504
+ const currentLocale = computed(() => merge(defaultConfig.i18n, i18nGlobal, props.config.i18n));
504
505
 
505
506
  const inputPlaceholder = computed(() => {
506
507
  const message = currentLocale.value.addMore;
@@ -158,7 +158,8 @@ const emit = defineEmits(["update:modelValue"]);
158
158
 
159
159
  const { tm } = useLocale();
160
160
 
161
- const currentLocale = computed(() => merge(tm("USwitch"), props.config.i18n));
161
+ const i18nGlobal = tm(USwitch);
162
+ const currentLocale = computed(() => merge(defaultConfig.i18n, i18nGlobal, props.config.i18n));
162
163
 
163
164
  const checkedValue = computed({
164
165
  get: () => props.modelValue,
@@ -142,7 +142,8 @@ const notifyPositionStyles = ref({});
142
142
 
143
143
  const notificationsWrapperRef = ref(null);
144
144
 
145
- const currentLocale = computed(() => merge(tm("UNotify"), props.config.i18n));
145
+ const i18nGlobal = tm(UNotify);
146
+ const currentLocale = computed(() => merge(defaultConfig.i18n, i18nGlobal, props.config.i18n));
146
147
 
147
148
  onMounted(() => {
148
149
  window.addEventListener("resize", setPosition, { passive: true });
package/web-types.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "framework": "vue",
3
3
  "name": "vueless",
4
- "version": "0.0.102",
4
+ "version": "0.0.104",
5
5
  "contributions": {
6
6
  "html": {
7
7
  "description-markup": "markdown",
@@ -3448,7 +3448,7 @@
3448
3448
  "kind": "expression",
3449
3449
  "type": "string"
3450
3450
  },
3451
- "default": "\"Label\""
3451
+ "default": "\"\""
3452
3452
  },
3453
3453
  {
3454
3454
  "name": "description",
@@ -3457,7 +3457,7 @@
3457
3457
  "kind": "expression",
3458
3458
  "type": "string"
3459
3459
  },
3460
- "default": "\"Some description here\""
3460
+ "default": "\"\""
3461
3461
  },
3462
3462
  {
3463
3463
  "name": "labelAlign",
@@ -3472,9 +3472,18 @@
3472
3472
  "name": "modelValue",
3473
3473
  "value": {
3474
3474
  "kind": "expression",
3475
- "type": "array"
3475
+ "type": "array|File"
3476
3476
  },
3477
- "default": "[]"
3477
+ "default": "null"
3478
+ },
3479
+ {
3480
+ "name": "multiple",
3481
+ "description": "Allow select multiple files.",
3482
+ "value": {
3483
+ "kind": "expression",
3484
+ "type": "boolean"
3485
+ },
3486
+ "default": "false"
3478
3487
  },
3479
3488
  {
3480
3489
  "name": "maxFileSize",
@@ -3483,7 +3492,7 @@
3483
3492
  "kind": "expression",
3484
3493
  "type": "number"
3485
3494
  },
3486
- "default": "100"
3495
+ "default": "0"
3487
3496
  },
3488
3497
  {
3489
3498
  "name": "allowedFileTypes",
@@ -3539,6 +3548,11 @@
3539
3548
  "name": "update:error"
3540
3549
  }
3541
3550
  ],
3551
+ "slots": [
3552
+ {
3553
+ "name": "left"
3554
+ }
3555
+ ],
3542
3556
  "source": {
3543
3557
  "module": "vueless/ui.form-input-file/index.vue",
3544
3558
  "symbol": "default"
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M452-203.43h60v-201.96l82.48 82.48 42-42L480-517.15 325.76-362.91l42 42L452-405.39v201.96ZM222.15-74.02q-27.6 0-47.86-20.27-20.27-20.26-20.27-47.86v-675.7q0-27.7 20.27-48.03 20.26-20.34 47.86-20.34h361.48l222.59 222.59v521.48q0 27.6-20.34 47.86-20.33 20.27-48.03 20.27h-515.7Zm326.7-557.83v-186h-326.7v675.7h515.7v-489.7h-189Zm-326.7-186v186-186 675.7-675.7Z"/></svg>