vueless 0.0.98 → 0.0.100
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/assets/icons/attach_file.svg +1 -0
- package/composable.ui/index.js +2 -2
- package/package.json +1 -4
- package/ui.button/configs/default.config.js +1 -0
- package/ui.button/index.vue +8 -2
- package/ui.container-page/configs/default.config.js +1 -1
- package/ui.form-input/index.vue +1 -1
- package/ui.form-input-file/composables/attrs.composable.js +40 -55
- package/ui.form-input-file/configs/default.config.js +44 -40
- package/ui.form-input-file/index.stories.js +11 -33
- package/ui.form-input-file/index.vue +149 -246
- package/ui.form-input-file/services/fileForm.service.js +5 -0
- package/ui.form-input-money/configs/default.config.js +1 -1
- package/ui.form-input-money/index.stories.js +27 -26
- package/ui.form-input-money/index.vue +6 -5
- package/ui.form-input-search/configs/default.config.js +1 -1
- package/ui.form-input-search/index.vue +6 -5
- package/ui.form-select/index.vue +1 -1
- package/web-types.json +35 -60
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M737.33-324.39q0 105.46-74.69 177.91-74.69 72.46-180.26 72.46-105.58 0-180.35-72.46-74.77-72.45-74.77-177.85v-383.82q0-74.63 53.41-126.35 53.42-51.72 127.75-51.72 74.34 0 127.69 51.72 53.35 51.72 53.35 126.35v363.82q0 43.66-31.56 74.62-31.55 30.97-75.81 30.97-44.26 0-75.61-30.64t-31.35-74.95v-370h66.46v370q0 16.05 11.97 27.59t29.2 11.54q17.24 0 28.74-11.5 11.5-11.51 11.5-27.63v-363.58q.24-47.35-33.38-79.6-33.62-32.25-81.35-32.25-47.74 0-81.14 32.19-33.41 32.19-33.41 79.42v383.82q.24 77.83 55.57 130.96 55.33 53.13 133.62 53.13 77.86 0 133.03-53.16 55.17-53.17 54.93-130.93v-396.93h66.46v396.87Z"/></svg>
|
package/composable.ui/index.js
CHANGED
|
@@ -176,10 +176,10 @@ function mergeConfigs({
|
|
|
176
176
|
if (isGlobalConfig || isPropsConfig) {
|
|
177
177
|
if (key === "strategy") {
|
|
178
178
|
config[key] = propsConfig[key] || globalConfig[key] || defaultConfig[key];
|
|
179
|
-
} else if (key === "safelist") {
|
|
179
|
+
} else if (key === "safelist" || key === "safelistColors") {
|
|
180
180
|
if (propsConfig[key]) {
|
|
181
181
|
// eslint-disable-next-line no-console
|
|
182
|
-
console.warn(
|
|
182
|
+
console.warn(`Passing '${key}' key by 'config' prop is not allowed.`);
|
|
183
183
|
}
|
|
184
184
|
} else if (key === "defaultVariants") {
|
|
185
185
|
config[key] = { ...defaultConfig[key], ...globalConfig[key], ...propsConfig[key] };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vueless",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.100",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Vue Styleless Component Framework.",
|
|
6
6
|
"homepage": "https://vueless.com",
|
|
@@ -25,9 +25,6 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@tailwindcss/forms": "^0.5.7",
|
|
28
|
-
"@uppy/core": "^3.10.1",
|
|
29
|
-
"@uppy/drag-drop": "^3.1.0",
|
|
30
|
-
"@uppy/vue": "^1.1.2",
|
|
31
28
|
"cva": "^1.0.0-beta.1",
|
|
32
29
|
"lodash-es": "^4.17.21",
|
|
33
30
|
"tailwind-merge": "^2.3.0",
|
package/ui.button/index.vue
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
2
|
+
<component
|
|
3
|
+
:is="tag"
|
|
3
4
|
:id="id"
|
|
4
5
|
ref="buttonRef"
|
|
5
6
|
:disabled="disabled"
|
|
@@ -19,7 +20,7 @@
|
|
|
19
20
|
|
|
20
21
|
<!-- @slot Use it to add something after text. -->
|
|
21
22
|
<slot v-if="!loading" name="right" />
|
|
22
|
-
</
|
|
23
|
+
</component>
|
|
23
24
|
</template>
|
|
24
25
|
|
|
25
26
|
<script setup>
|
|
@@ -136,6 +137,11 @@ const props = defineProps({
|
|
|
136
137
|
default: () => ({}),
|
|
137
138
|
},
|
|
138
139
|
|
|
140
|
+
tag: {
|
|
141
|
+
type: String,
|
|
142
|
+
default: UIService.get(defaultConfig, UButton).default.tag,
|
|
143
|
+
},
|
|
144
|
+
|
|
139
145
|
/**
|
|
140
146
|
* Data-cy attribute for automated testing.
|
|
141
147
|
*/
|
|
@@ -2,7 +2,7 @@ export default /*tw*/ {
|
|
|
2
2
|
htmlBody: "bg-gray-50 group/body-gray",
|
|
3
3
|
wrapperMobile: "overflow-x-hidden mb-[theme('spacing.mobile-menu-height')]",
|
|
4
4
|
wrapper: {
|
|
5
|
-
base: "min-h-screen
|
|
5
|
+
base: "min-h-screen UNotifyPage",
|
|
6
6
|
variants: {
|
|
7
7
|
width: {
|
|
8
8
|
xs: "md:w-[25rem] md:max-[500px]:!w-full",
|
package/ui.form-input/index.vue
CHANGED
|
@@ -360,7 +360,7 @@ function transformValue(value, exp) {
|
|
|
360
360
|
}
|
|
361
361
|
|
|
362
362
|
function setLabelPosition() {
|
|
363
|
-
if (props.
|
|
363
|
+
if (props.labelAlign === "top" || !hasSlotContent(slots["left"])) return;
|
|
364
364
|
|
|
365
365
|
const leftSlotWidth = leftSlotWrapper.value.getBoundingClientRect().width;
|
|
366
366
|
|
|
@@ -1,82 +1,67 @@
|
|
|
1
1
|
import { computed } from "vue";
|
|
2
2
|
import useUI from "../../composable.ui";
|
|
3
|
-
import { cva
|
|
3
|
+
import { cva } from "../../service.ui";
|
|
4
4
|
|
|
5
5
|
import defaultConfig from "../configs/default.config";
|
|
6
6
|
|
|
7
|
-
export function useAttrs(props
|
|
8
|
-
const { config, getAttrs
|
|
9
|
-
const {
|
|
7
|
+
export function useAttrs(props) {
|
|
8
|
+
const { config, getAttrs } = useUI(defaultConfig, () => props.config);
|
|
9
|
+
const { dropzoneWrapper, placeholder } = config.value;
|
|
10
10
|
|
|
11
|
-
const
|
|
12
|
-
base:
|
|
13
|
-
variants:
|
|
14
|
-
compoundVariants:
|
|
11
|
+
const cvaDropzoneWrapper = cva({
|
|
12
|
+
base: dropzoneWrapper.base,
|
|
13
|
+
variants: dropzoneWrapper.variants,
|
|
14
|
+
compoundVariants: dropzoneWrapper.compoundVariants,
|
|
15
15
|
});
|
|
16
16
|
|
|
17
|
-
const
|
|
18
|
-
base:
|
|
19
|
-
variants:
|
|
20
|
-
compoundVariants:
|
|
17
|
+
const cvaPlaceholder = cva({
|
|
18
|
+
base: placeholder.base,
|
|
19
|
+
variants: placeholder.variants,
|
|
20
|
+
compoundVariants: placeholder.compoundVariants,
|
|
21
21
|
});
|
|
22
22
|
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
const dropzoneWrapperClasses = computed(() =>
|
|
24
|
+
cvaDropzoneWrapper({
|
|
25
|
+
error: Boolean(props.error),
|
|
26
26
|
label: Boolean(props.label),
|
|
27
|
-
|
|
27
|
+
labelAlign: props.labelAlign,
|
|
28
|
+
size: props.size,
|
|
28
29
|
}),
|
|
29
30
|
);
|
|
30
31
|
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
const placeholderClasses = computed(() =>
|
|
33
|
+
cvaPlaceholder({
|
|
34
|
+
size: props.size,
|
|
34
35
|
}),
|
|
35
36
|
);
|
|
36
37
|
|
|
37
|
-
const uploadAttrs = getAttrs("upload", { classes: uploadClasses });
|
|
38
|
-
const buttonAttrs = getAttrs("button", { isComponent: true });
|
|
39
|
-
const iconUploadFileAttrs = getAttrs("iconUploadFile", { isComponent: true });
|
|
40
|
-
const wrapperAttrs = getAttrs("wrapper");
|
|
41
38
|
const labelAttrs = getAttrs("label", { isComponent: true });
|
|
42
|
-
const
|
|
43
|
-
const
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
const
|
|
47
|
-
|
|
39
|
+
const buttonAttrs = getAttrs("button", { isComponent: true });
|
|
40
|
+
const dropzoneWrapperAttrs = getAttrs("dropzoneWrapper", { classes: dropzoneWrapperClasses });
|
|
41
|
+
const descriptionAttrs = getAttrs("description", { isComponent: true });
|
|
42
|
+
const buttonWrapperAttrs = getAttrs("buttonWrapper");
|
|
43
|
+
const placeholderWrapperAttrs = getAttrs("placeholderWrapper");
|
|
44
|
+
const placeholderAttrs = getAttrs("placeholder", {
|
|
45
|
+
classes: placeholderClasses,
|
|
48
46
|
isComponent: true,
|
|
49
47
|
});
|
|
50
|
-
|
|
51
|
-
const iconCloseAttrs =
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}));
|
|
55
|
-
|
|
56
|
-
const uppyUploadRaw = getAttrs("uppyUpload");
|
|
57
|
-
|
|
58
|
-
const uppyUploadAttrs = computed(() => ({
|
|
59
|
-
...uppyUploadRaw.value,
|
|
60
|
-
class: cx([uppyUploadRaw.value.class, dragOver.value && config.dragOver]),
|
|
61
|
-
}));
|
|
62
|
-
|
|
63
|
-
const uploadSlotAttrs = getAttrs("uploadSlot");
|
|
64
|
-
const filesAttrs = getAttrs("files", { isComponent: true });
|
|
48
|
+
const iconPlaceholderAttrs = getAttrs("iconPlaceholder", { isComponent: true });
|
|
49
|
+
const iconCloseAttrs = getAttrs("iconClose", { isComponent: true });
|
|
50
|
+
const iconUploadFileAttrs = getAttrs("iconUploadFile", { isComponent: true });
|
|
51
|
+
const inputAttrs = getAttrs("input");
|
|
65
52
|
|
|
66
53
|
return {
|
|
67
54
|
config,
|
|
68
|
-
|
|
69
|
-
buttonAttrs,
|
|
70
|
-
iconUploadFileAttrs,
|
|
71
|
-
iconCloseAttrs,
|
|
72
|
-
wrapperAttrs,
|
|
55
|
+
inputAttrs,
|
|
73
56
|
labelAttrs,
|
|
74
|
-
|
|
57
|
+
buttonAttrs,
|
|
58
|
+
dropzoneWrapperAttrs,
|
|
75
59
|
descriptionAttrs,
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
60
|
+
buttonWrapperAttrs,
|
|
61
|
+
placeholderWrapperAttrs,
|
|
62
|
+
iconPlaceholderAttrs,
|
|
63
|
+
iconCloseAttrs,
|
|
64
|
+
iconUploadFileAttrs,
|
|
65
|
+
placeholderAttrs,
|
|
81
66
|
};
|
|
82
67
|
}
|
|
@@ -1,59 +1,63 @@
|
|
|
1
1
|
export default /*tw*/ {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
label: {
|
|
3
|
+
wrapper: "relative w-full",
|
|
4
|
+
label: {
|
|
5
|
+
compoundVariants: [
|
|
6
|
+
{ align: "topInside", size: "sm", class: "left-5 top-4" },
|
|
7
|
+
{ align: "topInside", size: "md", class: "left-5 top-5" },
|
|
8
|
+
{ align: "topInside", size: "lg", class: "left-5 top-6" },
|
|
9
|
+
],
|
|
10
10
|
},
|
|
11
11
|
},
|
|
12
|
-
|
|
13
|
-
list: "mb-4 space-y-4",
|
|
14
|
-
button: "w-full",
|
|
15
|
-
iconUploadFileName: "upload_file",
|
|
16
|
-
iconDescriptionName: "description",
|
|
17
|
-
iconCloseName: "close",
|
|
18
|
-
iconClose: "ml-1.5",
|
|
19
|
-
iconUploadFile: "",
|
|
20
|
-
itemClose: "z-20",
|
|
21
|
-
uploadSlot: "w-fit",
|
|
22
|
-
files: "mt-4",
|
|
23
|
-
fileUploadHover: "border-gray-400 bg-gray-50",
|
|
24
|
-
dragOver: "h-full w-full",
|
|
25
|
-
uppyUpload: "opacity-0 absolute left-0 top-0 h-0 w-0 [&_.uppy-Root]:h-full [&_.uppy-Root]:w-full",
|
|
26
|
-
errorFileUpload: "hover:border-red-400 border-red-300",
|
|
27
|
-
upload: {
|
|
12
|
+
dropzoneWrapper: {
|
|
28
13
|
base: `
|
|
29
|
-
|
|
30
|
-
|
|
14
|
+
size-auto w-full rounded border border-dashed border-gray-300 bg-white
|
|
15
|
+
p-4 px-5 py-6 hover:border-gray-400
|
|
31
16
|
`,
|
|
32
17
|
variants: {
|
|
33
|
-
size: {
|
|
34
|
-
sm: "group/label:text-xs group/description:text-xs group/image:h-8 group/image:w-8 group/title:text-sm",
|
|
35
|
-
md: "group/text-sm group/description:text-sm group/image:h-10 group/image:w-10 group/title:text-base",
|
|
36
|
-
ld: "group/label:text-base group/description:text-base group/image:h-12 group/image:w-12 group/title:text-lg",
|
|
37
|
-
},
|
|
38
18
|
error: {
|
|
39
19
|
true: "border-red-300 hover:border-red-400",
|
|
40
20
|
},
|
|
41
21
|
},
|
|
22
|
+
compoundVariants: [
|
|
23
|
+
{ labelAlign: "topInside", label: true, size: "sm", class: "pt-8" },
|
|
24
|
+
{ labelAlign: "topInside", label: true, size: "md", class: "py-10" },
|
|
25
|
+
{ labelAlign: "topInside", label: true, size: "lg", class: "pt-12" },
|
|
26
|
+
],
|
|
42
27
|
},
|
|
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",
|
|
31
|
+
placeholder: {
|
|
32
|
+
base: "pr-4 shrink-0 text-ellipsis overflow-hidden text-gray-700 text-nowrap",
|
|
33
|
+
variants: {
|
|
34
|
+
size: {
|
|
35
|
+
sm: "text-sm",
|
|
36
|
+
md: "text-base",
|
|
37
|
+
lg: "text-lg",
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
iconPlaceholderName: "attach_file",
|
|
42
|
+
iconPlaceholder: "-rotate-45",
|
|
43
|
+
button: "hover:cursor-pointer",
|
|
44
|
+
iconUploadFileName: "upload_file",
|
|
45
|
+
iconCloseName: "close",
|
|
46
|
+
iconClose: "",
|
|
47
|
+
iconUploadFile: "",
|
|
48
|
+
dropzoneWrapperHover: "border-gray-400 bg-gray-50",
|
|
49
|
+
dropzoneWrapperError: "hover:border-red-400 border-red-300",
|
|
50
|
+
input: "sr-only pointer-events-none size-0 opacity-0",
|
|
43
51
|
i18n: {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
selectFile: "Select file",
|
|
52
|
+
sizeError: "File size is too big.",
|
|
53
|
+
formatError: "Format is not supported.",
|
|
54
|
+
noFile: "No file selected",
|
|
55
|
+
uploadFile: "Upload file",
|
|
49
56
|
},
|
|
50
57
|
defaultVariants: {
|
|
51
58
|
size: "md",
|
|
52
59
|
labelAlign: "topInside",
|
|
53
60
|
allowedFileTypes: [".png", ".jpg", ".jpeg", ".pdf", ".txt", ".doc", ".docx", "xls", ".xlsx"],
|
|
54
|
-
maxFileSize:
|
|
55
|
-
maxFiles: 3,
|
|
56
|
-
local: false,
|
|
57
|
-
multiple: false,
|
|
61
|
+
maxFileSize: 100,
|
|
58
62
|
},
|
|
59
63
|
};
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { getArgTypes } from "../service.storybook";
|
|
2
2
|
|
|
3
3
|
import UInputFile from "../ui.form-input-file";
|
|
4
|
-
import UButton from "../ui.button";
|
|
5
4
|
import URow from "../ui.container-row";
|
|
6
5
|
|
|
7
6
|
export default {
|
|
8
|
-
id: "
|
|
7
|
+
id: "30232",
|
|
9
8
|
title: "Form Inputs & Controls / Input File",
|
|
10
9
|
component: UInputFile,
|
|
11
10
|
argTypes: {
|
|
@@ -18,29 +17,23 @@ const DefaultTemplate = (args) => ({
|
|
|
18
17
|
setup() {
|
|
19
18
|
return { args };
|
|
20
19
|
},
|
|
20
|
+
data() {
|
|
21
|
+
return {
|
|
22
|
+
files: [],
|
|
23
|
+
error: args.error || "",
|
|
24
|
+
};
|
|
25
|
+
},
|
|
21
26
|
template: `
|
|
22
27
|
<URow>
|
|
23
28
|
<UInputFile
|
|
24
29
|
v-bind="args"
|
|
30
|
+
v-model="files"
|
|
31
|
+
v-model:error="error"
|
|
25
32
|
/>
|
|
26
33
|
</URow>
|
|
27
34
|
`,
|
|
28
35
|
});
|
|
29
36
|
|
|
30
|
-
const SlotTemplate = (args) => ({
|
|
31
|
-
components: { UInputFile, UButton },
|
|
32
|
-
setup() {
|
|
33
|
-
return { args };
|
|
34
|
-
},
|
|
35
|
-
template: `
|
|
36
|
-
<UInputFile
|
|
37
|
-
v-bind="args"
|
|
38
|
-
>
|
|
39
|
-
${args.slotTemplate}
|
|
40
|
-
</UInputFile>
|
|
41
|
-
`,
|
|
42
|
-
});
|
|
43
|
-
|
|
44
37
|
const SizesTemplate = (args, { argTypes } = {}) => ({
|
|
45
38
|
components: { UInputFile, URow },
|
|
46
39
|
setup() {
|
|
@@ -64,23 +57,8 @@ const SizesTemplate = (args, { argTypes } = {}) => ({
|
|
|
64
57
|
export const Default = DefaultTemplate.bind({});
|
|
65
58
|
Default.args = {};
|
|
66
59
|
|
|
67
|
-
export const allowedSomeFileType = DefaultTemplate.bind({});
|
|
68
|
-
allowedSomeFileType.args = { allowedFileTypes: [".png", ".jpg", ".jpeg"] };
|
|
69
|
-
|
|
70
|
-
export const sizes = SizesTemplate.bind({});
|
|
71
|
-
sizes.args = {};
|
|
72
|
-
|
|
73
|
-
export const multiple = DefaultTemplate.bind({});
|
|
74
|
-
multiple.args = { multiple: true };
|
|
75
|
-
|
|
76
60
|
export const error = DefaultTemplate.bind({});
|
|
77
61
|
error.args = { error: "some error" };
|
|
78
62
|
|
|
79
|
-
export const
|
|
80
|
-
|
|
81
|
-
slotTemplate: `
|
|
82
|
-
<template #default>
|
|
83
|
-
<UButton class="w-[40rem]" label="Select file" color="red" />
|
|
84
|
-
</template>
|
|
85
|
-
`,
|
|
86
|
-
};
|
|
63
|
+
export const sizes = SizesTemplate.bind({});
|
|
64
|
+
sizes.args = {};
|
|
@@ -1,84 +1,78 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<div v-
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
:name="config.iconUploadFileName"
|
|
18
|
-
v-bind="iconUploadFileAttrs"
|
|
19
|
-
/>
|
|
20
|
-
|
|
21
|
-
<div v-bind="descriptionAttrs" v-text="descriptionText" />
|
|
22
|
-
</div>
|
|
23
|
-
|
|
24
|
-
<div v-bind="listAttrs">
|
|
25
|
-
<UFiles :options="filesList" v-bind="filesAttrs">
|
|
26
|
-
<template #right="file">
|
|
27
|
-
<UIcon
|
|
28
|
-
internal
|
|
29
|
-
interactive
|
|
30
|
-
color="gray"
|
|
31
|
-
:size="componentSize"
|
|
32
|
-
:name="config.iconCloseName"
|
|
33
|
-
v-bind="iconCloseAttrs"
|
|
34
|
-
@click="onClickDeleteFile(file)"
|
|
35
|
-
/>
|
|
36
|
-
</template>
|
|
37
|
-
</UFiles>
|
|
38
|
-
</div>
|
|
2
|
+
<ULabel :error="error" :align="labelAlign" :label="label" :size="size" v-bind="labelAttrs">
|
|
3
|
+
<div ref="dropZoneRef" :ondrop="onDrop" v-bind="dropzoneWrapperAttrs">
|
|
4
|
+
<UText :size="nestedComponentSize" v-bind="descriptionAttrs" :html="description" />
|
|
5
|
+
|
|
6
|
+
<div v-bind="buttonWrapperAttrs">
|
|
7
|
+
<div v-bind="placeholderWrapperAttrs">
|
|
8
|
+
<UIcon
|
|
9
|
+
pill
|
|
10
|
+
internal
|
|
11
|
+
:size="nestedComponentSize"
|
|
12
|
+
:name="config.iconPlaceholderName"
|
|
13
|
+
v-bind="iconPlaceholderAttrs"
|
|
14
|
+
/>
|
|
15
|
+
<span v-bind="placeholderAttrs" v-text="placeholder" />
|
|
16
|
+
</div>
|
|
39
17
|
|
|
18
|
+
<template v-if="!currentFiles.length">
|
|
40
19
|
<UButton
|
|
41
|
-
|
|
42
|
-
:
|
|
20
|
+
class="hover:cursor-pointer"
|
|
21
|
+
:label="currentLocale.uploadFile"
|
|
43
22
|
variant="thirdary"
|
|
44
23
|
filled
|
|
45
|
-
:
|
|
24
|
+
:size="nestedComponentSize"
|
|
46
25
|
v-bind="buttonAttrs"
|
|
47
|
-
|
|
26
|
+
tag="label"
|
|
27
|
+
:for="id"
|
|
28
|
+
>
|
|
29
|
+
<template #right>
|
|
30
|
+
<UIcon
|
|
31
|
+
internal
|
|
32
|
+
:size="nestedComponentSize"
|
|
33
|
+
:name="config.iconUploadFileName"
|
|
34
|
+
v-bind="iconUploadFileAttrs"
|
|
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"
|
|
48
46
|
/>
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
</template>
|
|
48
|
+
<UIcon
|
|
49
|
+
v-else
|
|
50
|
+
interactive
|
|
51
|
+
internal
|
|
52
|
+
:size="nestedComponentSize"
|
|
53
|
+
:name="config.iconCloseName"
|
|
54
|
+
pill
|
|
55
|
+
v-bind="iconCloseAttrs"
|
|
56
|
+
@click="onClickResetFiles"
|
|
57
|
+
/>
|
|
58
|
+
</div>
|
|
53
59
|
</div>
|
|
54
|
-
|
|
55
|
-
<div v-else :id="fileId" :data-cy="dataCy" v-bind="uploadSlotAttrs" @click="onClickUploadFile">
|
|
56
|
-
<slot />
|
|
57
|
-
|
|
58
|
-
<DragDrop :id="uppyId" :uppy="uppy" v-bind="uppyUploadAttrs" />
|
|
59
|
-
</div>
|
|
60
|
-
</div>
|
|
60
|
+
</ULabel>
|
|
61
61
|
</template>
|
|
62
62
|
|
|
63
63
|
<script setup>
|
|
64
|
-
import
|
|
65
|
-
import DragDrop from "@uppy/vue/src/drag-drop";
|
|
64
|
+
import { computed, nextTick, onBeforeUnmount, onMounted, ref } from "vue";
|
|
66
65
|
import { merge } from "lodash-es";
|
|
67
66
|
|
|
68
|
-
import { computed, onBeforeUnmount, onMounted, ref, watch } from "vue";
|
|
69
|
-
|
|
70
|
-
import UIcon from "../ui.image-icon";
|
|
71
|
-
import ULabel from "../ui.form-label";
|
|
72
|
-
import UButton from "../ui.button";
|
|
73
|
-
import UFiles from "../ui.text-files";
|
|
74
|
-
|
|
75
67
|
import UIService, { getRandomId } from "../service.ui";
|
|
68
|
+
import { getFileMbSize } from "./services/fileForm.service";
|
|
76
69
|
|
|
77
|
-
import { UInputFile } from "./constants";
|
|
78
|
-
import defaultConfig from "./configs/default.config";
|
|
79
70
|
import { useAttrs } from "./composables/attrs.composable";
|
|
80
71
|
import { useLocale } from "../composable.locale";
|
|
81
72
|
|
|
73
|
+
import { UInputFile } from "./constants";
|
|
74
|
+
import defaultConfig from "./configs/default.config";
|
|
75
|
+
|
|
82
76
|
/* Should be a string for correct web-types gen */
|
|
83
77
|
defineOptions({ name: "UInputFile" });
|
|
84
78
|
|
|
@@ -88,7 +82,7 @@ const props = defineProps({
|
|
|
88
82
|
*/
|
|
89
83
|
label: {
|
|
90
84
|
type: String,
|
|
91
|
-
default: "",
|
|
85
|
+
default: "Label",
|
|
92
86
|
},
|
|
93
87
|
|
|
94
88
|
/**
|
|
@@ -96,7 +90,7 @@ const props = defineProps({
|
|
|
96
90
|
*/
|
|
97
91
|
description: {
|
|
98
92
|
type: String,
|
|
99
|
-
default: "",
|
|
93
|
+
default: "Some description here",
|
|
100
94
|
},
|
|
101
95
|
|
|
102
96
|
/**
|
|
@@ -108,22 +102,11 @@ const props = defineProps({
|
|
|
108
102
|
default: UIService.get(defaultConfig, UInputFile).default.labelAlign,
|
|
109
103
|
},
|
|
110
104
|
|
|
111
|
-
|
|
112
|
-
* Set files data.
|
|
113
|
-
*/
|
|
114
|
-
files: {
|
|
105
|
+
modelValue: {
|
|
115
106
|
type: Array,
|
|
116
107
|
default: () => [],
|
|
117
108
|
},
|
|
118
109
|
|
|
119
|
-
/**
|
|
120
|
-
* Selected files will be imported when a form will be submitted
|
|
121
|
-
*/
|
|
122
|
-
local: {
|
|
123
|
-
type: Boolean,
|
|
124
|
-
default: UIService.get(defaultConfig, UInputFile).default.local,
|
|
125
|
-
},
|
|
126
|
-
|
|
127
110
|
/**
|
|
128
111
|
* Set max file size in megabytes.
|
|
129
112
|
*/
|
|
@@ -132,22 +115,6 @@ const props = defineProps({
|
|
|
132
115
|
default: UIService.get(defaultConfig, UInputFile).default.maxFileSize,
|
|
133
116
|
},
|
|
134
117
|
|
|
135
|
-
/**
|
|
136
|
-
* Allow to select multiple files.
|
|
137
|
-
*/
|
|
138
|
-
multiple: {
|
|
139
|
-
type: Boolean,
|
|
140
|
-
default: UIService.get(defaultConfig, UInputFile).default.multiple,
|
|
141
|
-
},
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Set max number files for upload
|
|
145
|
-
*/
|
|
146
|
-
maxFiles: {
|
|
147
|
-
type: Number,
|
|
148
|
-
default: UIService.get(defaultConfig, UInputFile).default.maxFiles,
|
|
149
|
-
},
|
|
150
|
-
|
|
151
118
|
/**
|
|
152
119
|
* Set allowed file types.
|
|
153
120
|
*/
|
|
@@ -157,20 +124,20 @@ const props = defineProps({
|
|
|
157
124
|
},
|
|
158
125
|
|
|
159
126
|
/**
|
|
160
|
-
* Set
|
|
127
|
+
* Set size.
|
|
128
|
+
* @values sm, md, lg
|
|
161
129
|
*/
|
|
162
|
-
|
|
130
|
+
size: {
|
|
163
131
|
type: String,
|
|
164
|
-
default:
|
|
132
|
+
default: UIService.get(defaultConfig, UInputFile).default.size,
|
|
165
133
|
},
|
|
166
134
|
|
|
167
135
|
/**
|
|
168
|
-
* Set
|
|
169
|
-
* @values sm, md, lg
|
|
136
|
+
* Set error text for component.
|
|
170
137
|
*/
|
|
171
|
-
|
|
138
|
+
error: {
|
|
172
139
|
type: String,
|
|
173
|
-
default:
|
|
140
|
+
default: "",
|
|
174
141
|
},
|
|
175
142
|
|
|
176
143
|
/**
|
|
@@ -181,211 +148,147 @@ const props = defineProps({
|
|
|
181
148
|
type: String,
|
|
182
149
|
default: () => getRandomId(),
|
|
183
150
|
},
|
|
184
|
-
|
|
185
151
|
/**
|
|
186
|
-
* Sets
|
|
152
|
+
* Sets component ui config object.
|
|
187
153
|
*/
|
|
188
|
-
|
|
189
|
-
type:
|
|
190
|
-
default:
|
|
154
|
+
config: {
|
|
155
|
+
type: Object,
|
|
156
|
+
default: () => ({}),
|
|
191
157
|
},
|
|
192
158
|
});
|
|
193
159
|
|
|
194
|
-
const emit = defineEmits(["
|
|
160
|
+
const emit = defineEmits(["update:modelValue", "update:error"]);
|
|
195
161
|
|
|
196
162
|
const { tm } = useLocale();
|
|
197
163
|
|
|
198
|
-
const
|
|
199
|
-
const
|
|
200
|
-
const errorMessage = ref("");
|
|
201
|
-
const dragOver = ref(false);
|
|
202
|
-
const errorFilesTypes = ref([]);
|
|
164
|
+
const dropZoneRef = ref(null);
|
|
165
|
+
const fileInputRef = ref(null);
|
|
203
166
|
|
|
204
167
|
const {
|
|
205
168
|
config,
|
|
206
|
-
uploadAttrs,
|
|
207
|
-
buttonAttrs,
|
|
208
|
-
iconUploadFileAttrs,
|
|
209
|
-
iconCloseAttrs,
|
|
210
|
-
wrapperAttrs,
|
|
211
169
|
labelAttrs,
|
|
212
|
-
|
|
170
|
+
buttonAttrs,
|
|
171
|
+
dropzoneWrapperAttrs,
|
|
213
172
|
descriptionAttrs,
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
173
|
+
buttonWrapperAttrs,
|
|
174
|
+
placeholderWrapperAttrs,
|
|
175
|
+
iconPlaceholderAttrs,
|
|
176
|
+
iconCloseAttrs,
|
|
177
|
+
iconUploadFileAttrs,
|
|
178
|
+
placeholderAttrs,
|
|
179
|
+
inputAttrs,
|
|
180
|
+
} = useAttrs(props);
|
|
220
181
|
|
|
221
182
|
const currentLocale = computed(() => merge(tm("UInputFile"), props.config.i18n));
|
|
222
183
|
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
text: file.name,
|
|
227
|
-
id: file.id,
|
|
228
|
-
};
|
|
229
|
-
});
|
|
184
|
+
const currentFiles = computed({
|
|
185
|
+
get: () => props.modelValue,
|
|
186
|
+
set: (newValue) => emit("update:modelValue", newValue),
|
|
230
187
|
});
|
|
231
188
|
|
|
232
|
-
const
|
|
233
|
-
|
|
189
|
+
const currentError = computed({
|
|
190
|
+
get: () => props.error,
|
|
191
|
+
set: (newValue) => emit("update:error", newValue),
|
|
234
192
|
});
|
|
235
193
|
|
|
236
|
-
const
|
|
237
|
-
return
|
|
194
|
+
const accept = computed(() => {
|
|
195
|
+
return props.allowedFileTypes.join(",");
|
|
238
196
|
});
|
|
239
197
|
|
|
240
|
-
const
|
|
241
|
-
return
|
|
198
|
+
const extensionNames = computed(() => {
|
|
199
|
+
return props.allowedFileTypes.map((type) => type.replace(".", ""));
|
|
242
200
|
});
|
|
243
201
|
|
|
244
|
-
const
|
|
245
|
-
return
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
const allowedFilesForUpload = computed(() => {
|
|
249
|
-
const allowedFormat = props.allowedFileTypes.join(", ");
|
|
250
|
-
|
|
251
|
-
return `${currentLocale.value.canAttachFilesFormat} ${allowedFormat}`;
|
|
202
|
+
const placeholder = computed(() => {
|
|
203
|
+
return currentFiles.value.length ? currentFiles.value[0].name : currentLocale.value.noFile;
|
|
252
204
|
});
|
|
253
205
|
|
|
254
|
-
const
|
|
255
|
-
|
|
256
|
-
});
|
|
206
|
+
const nestedComponentSize = computed(() => {
|
|
207
|
+
let size = "sm";
|
|
257
208
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
md: "sm",
|
|
262
|
-
lg: "md",
|
|
263
|
-
};
|
|
209
|
+
if (props.size === "sm") size = "xs";
|
|
210
|
+
if (props.size === "md") size = "sm";
|
|
211
|
+
if (props.size === "lg") size = "md";
|
|
264
212
|
|
|
265
|
-
return size
|
|
213
|
+
return size;
|
|
266
214
|
});
|
|
267
215
|
|
|
268
|
-
|
|
269
|
-
|
|
216
|
+
onMounted(() => {
|
|
217
|
+
dropZoneRef.value.addEventListener("dragover", onDragOver);
|
|
218
|
+
dropZoneRef.value.addEventListener("dragleave", onDragLeave);
|
|
270
219
|
});
|
|
271
220
|
|
|
272
|
-
|
|
273
|
-
|
|
221
|
+
onBeforeUnmount(() => {
|
|
222
|
+
dropZoneRef.value.removeEventListener("dragover", onDragOver);
|
|
223
|
+
dropZoneRef.value.removeEventListener("dragleave", onDragLeave);
|
|
274
224
|
});
|
|
275
225
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
id: uppyId.value,
|
|
279
|
-
restrictions: {
|
|
280
|
-
maxFileSize: maxFileSizeInBytes,
|
|
281
|
-
maxNumberOfFiles: maxFilesNumber,
|
|
282
|
-
allowedFileTypes: props.allowedFileTypes,
|
|
283
|
-
},
|
|
284
|
-
}).on("restriction-failed", (file, error) => {
|
|
285
|
-
const isFile = errorFilesTypes.value.find((item) => item === file.extension);
|
|
286
|
-
|
|
287
|
-
if (error && !isFile) errorFilesTypes.value.push(`.${file.extension}`);
|
|
288
|
-
}),
|
|
289
|
-
);
|
|
290
|
-
|
|
291
|
-
watch(selectedFiles, onChangeSelectedFiles, { deep: true });
|
|
292
|
-
watch(() => props.files, onChangeFiles, { deep: true });
|
|
293
|
-
watch(errorFilesTypes, onChangeErrorFilesTypes, { deep: true });
|
|
294
|
-
watch(() => props.error, onChangeError, { deep: true, immediate: true });
|
|
295
|
-
|
|
296
|
-
onMounted(() => {
|
|
297
|
-
uppy.value.on("file-added", () => {
|
|
298
|
-
uploadFiles();
|
|
299
|
-
});
|
|
226
|
+
function validate(file) {
|
|
227
|
+
const targetFileSize = getFileMbSize(file);
|
|
300
228
|
|
|
301
|
-
|
|
229
|
+
const isValidType = extensionNames.value.some((item) => file.type.includes(item));
|
|
230
|
+
const isValidSize = targetFileSize <= props.maxFileSize;
|
|
302
231
|
|
|
303
|
-
if (
|
|
304
|
-
|
|
305
|
-
uppyUpload.value.addEventListener("dragleave", onDragLeave, true);
|
|
232
|
+
if (!isValidSize) {
|
|
233
|
+
currentError.value = currentLocale.value.sizeError;
|
|
306
234
|
}
|
|
307
|
-
});
|
|
308
|
-
|
|
309
|
-
onBeforeUnmount(() => {
|
|
310
|
-
removeEventListener("dragover", () => (dragOver.value = true));
|
|
311
|
-
uppyUpload.value.removeEventListener("dragover", onDragOver, true);
|
|
312
|
-
uppyUpload.value.removeEventListener("dragleave", onDragLeave, true);
|
|
313
|
-
});
|
|
314
235
|
|
|
315
|
-
|
|
316
|
-
|
|
236
|
+
if (!isValidType) {
|
|
237
|
+
currentError.value = currentLocale.value.formatError;
|
|
238
|
+
}
|
|
317
239
|
}
|
|
318
240
|
|
|
319
|
-
function
|
|
320
|
-
|
|
241
|
+
function onChangeFile(event) {
|
|
242
|
+
validate(event.target.files[0]);
|
|
321
243
|
|
|
322
|
-
|
|
323
|
-
|
|
244
|
+
if (currentError.value) {
|
|
245
|
+
onClickResetFiles();
|
|
324
246
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
}
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
328
249
|
|
|
329
|
-
|
|
330
|
-
fileUpload.value.classList.remove(config.fileUploadHover);
|
|
331
|
-
dragOver.value = false;
|
|
250
|
+
currentFiles.value = Array.from(event.target.files);
|
|
332
251
|
}
|
|
333
252
|
|
|
334
|
-
function
|
|
335
|
-
|
|
253
|
+
function onClickResetFiles() {
|
|
254
|
+
currentFiles.value = [];
|
|
336
255
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
return file.data;
|
|
341
|
-
});
|
|
342
|
-
|
|
343
|
-
if (!props.error && errorMessage.value) {
|
|
344
|
-
errorMessage.value = "";
|
|
345
|
-
errorFilesTypes.value = [];
|
|
346
|
-
}
|
|
256
|
+
if (fileInputRef.value) fileInputRef.value.value = "";
|
|
257
|
+
}
|
|
347
258
|
|
|
348
|
-
|
|
259
|
+
function onDragOver(event) {
|
|
260
|
+
event.preventDefault();
|
|
349
261
|
|
|
350
|
-
|
|
262
|
+
dropZoneRef.value.classList.add(config.value.dropzoneWrapperHover.split(" "));
|
|
351
263
|
}
|
|
352
264
|
|
|
353
|
-
function
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
if (!props.error && errorMessage.value) {
|
|
357
|
-
errorMessage.value = "";
|
|
358
|
-
errorFilesTypes.value = [];
|
|
359
|
-
}
|
|
265
|
+
function onDragLeave(event) {
|
|
266
|
+
event.preventDefault();
|
|
360
267
|
|
|
361
|
-
|
|
268
|
+
dropZoneRef.value.classList.remove(config.value.dropzoneWrapperHover.split(" "));
|
|
362
269
|
}
|
|
363
270
|
|
|
364
|
-
function
|
|
365
|
-
|
|
366
|
-
}
|
|
271
|
+
function onDrop(event) {
|
|
272
|
+
event.preventDefault();
|
|
367
273
|
|
|
368
|
-
|
|
369
|
-
if (errorFilesTypes.value.length) {
|
|
370
|
-
const error = errorFilesTypes.value.join(", ");
|
|
371
|
-
const cannotAttachFilesStart = currentLocale.value.cannotAttachFilesStart;
|
|
372
|
-
const cannotAttachFilesEnd = currentLocale.value.cannotAttachFilesEnd;
|
|
274
|
+
let targetFile = null;
|
|
373
275
|
|
|
374
|
-
|
|
276
|
+
if (event.dataTransfer.items) {
|
|
277
|
+
targetFile = [...event.dataTransfer.items].find((item) => item.kind === "file")?.getAsFile();
|
|
278
|
+
} else {
|
|
279
|
+
targetFile = [...event.dataTransfer.files].at(0);
|
|
375
280
|
}
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
function onClickDeleteFile(data) {
|
|
379
|
-
const index = filesData.value.findIndex((file) => file.id === data.file.id);
|
|
380
281
|
|
|
381
|
-
if (
|
|
382
|
-
filesData.value.splice(index, 1);
|
|
282
|
+
if (targetFile) validate(targetFile);
|
|
383
283
|
|
|
384
|
-
|
|
284
|
+
nextTick(() => {
|
|
285
|
+
if (currentError.value || !targetFile) {
|
|
286
|
+
onClickResetFiles();
|
|
385
287
|
|
|
386
|
-
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
387
290
|
|
|
388
|
-
|
|
389
|
-
}
|
|
291
|
+
currentFiles.value = [targetFile];
|
|
292
|
+
});
|
|
390
293
|
}
|
|
391
294
|
</script>
|
|
@@ -2,7 +2,7 @@ import { getArgTypes, getSlotNames } from "../service.storybook";
|
|
|
2
2
|
|
|
3
3
|
import UInputMoney from "../ui.form-input-money";
|
|
4
4
|
import URow from "../ui.container-row";
|
|
5
|
-
import UGroup from "../ui.container-group";
|
|
5
|
+
// import UGroup from "../ui.container-group";
|
|
6
6
|
|
|
7
7
|
export default {
|
|
8
8
|
id: "3030",
|
|
@@ -56,29 +56,30 @@ const SizesTemplate = (args, { argTypes } = {}) => ({
|
|
|
56
56
|
`,
|
|
57
57
|
});
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
59
|
+
// TODO: Rewrite to labelAlign
|
|
60
|
+
// const LabelPlacementTemplate = (args) => ({
|
|
61
|
+
// components: { UInputMoney, UGroup },
|
|
62
|
+
// setup() {
|
|
63
|
+
// return {
|
|
64
|
+
// args,
|
|
65
|
+
// };
|
|
66
|
+
// },
|
|
67
|
+
// template: `
|
|
68
|
+
// <UGroup size="lg">
|
|
69
|
+
// <UInputMoney
|
|
70
|
+
// v-bind="args"
|
|
71
|
+
// :label-outside="true"
|
|
72
|
+
// label="top"
|
|
73
|
+
// />
|
|
74
|
+
//
|
|
75
|
+
// <UInputMoney
|
|
76
|
+
// v-bind="args"
|
|
77
|
+
// :label-outside="false"
|
|
78
|
+
// label="topInside"
|
|
79
|
+
// />
|
|
80
|
+
// </UGroup>
|
|
81
|
+
// `,
|
|
82
|
+
// });
|
|
82
83
|
|
|
83
84
|
export const Default = DefaultTemplate.bind({});
|
|
84
85
|
Default.args = {};
|
|
@@ -89,8 +90,8 @@ sizes.args = {};
|
|
|
89
90
|
export const symbol = DefaultTemplate.bind({});
|
|
90
91
|
symbol.args = { symbol: "€" };
|
|
91
92
|
|
|
92
|
-
export const labelOutside = LabelPlacementTemplate.bind({});
|
|
93
|
-
labelOutside.args = {};
|
|
93
|
+
// export const labelOutside = LabelPlacementTemplate.bind({});
|
|
94
|
+
// labelOutside.args = {};
|
|
94
95
|
|
|
95
96
|
export const placeholder = DefaultTemplate.bind({});
|
|
96
97
|
placeholder.args = { placeholder: "Placeholder" };
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
v-model="formattedValue"
|
|
6
6
|
:size="size"
|
|
7
7
|
:label="localLabel"
|
|
8
|
-
:label-
|
|
8
|
+
:label-align="labelAlign"
|
|
9
9
|
:placeholder="placeholder"
|
|
10
10
|
:description="description"
|
|
11
11
|
:error="error"
|
|
@@ -67,11 +67,12 @@ const props = defineProps({
|
|
|
67
67
|
},
|
|
68
68
|
|
|
69
69
|
/**
|
|
70
|
-
*
|
|
70
|
+
* Set label placement related from the default slot.
|
|
71
|
+
* @values top, topInside, topWithDesc, bottom, left, right
|
|
71
72
|
*/
|
|
72
|
-
|
|
73
|
-
type:
|
|
74
|
-
default: UIService.get(defaultConfig, UInputMoney).default.
|
|
73
|
+
labelAlign: {
|
|
74
|
+
type: String,
|
|
75
|
+
default: UIService.get(defaultConfig, UInputMoney).default.labelAlign,
|
|
75
76
|
},
|
|
76
77
|
|
|
77
78
|
/**
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
:type="search"
|
|
13
13
|
:input-mode="search"
|
|
14
14
|
:data-cy="dataCy"
|
|
15
|
-
:label-
|
|
15
|
+
:label-align="labelAlign"
|
|
16
16
|
v-bind="inputAttrs"
|
|
17
17
|
@keyup.enter="onClickSearch"
|
|
18
18
|
>
|
|
@@ -136,11 +136,12 @@ const props = defineProps({
|
|
|
136
136
|
},
|
|
137
137
|
|
|
138
138
|
/**
|
|
139
|
-
*
|
|
139
|
+
* Set label placement related from the default slot.
|
|
140
|
+
* @values top, topInside, topWithDesc, bottom, left, right
|
|
140
141
|
*/
|
|
141
|
-
|
|
142
|
-
type:
|
|
143
|
-
default: UIService.get(defaultConfig, UInputSearch).default.
|
|
142
|
+
labelAlign: {
|
|
143
|
+
type: String,
|
|
144
|
+
default: UIService.get(defaultConfig, UInputSearch).default.labelAlign,
|
|
144
145
|
},
|
|
145
146
|
|
|
146
147
|
/**
|
package/ui.form-select/index.vue
CHANGED
|
@@ -713,7 +713,7 @@ function removeElement(option, shouldClose = true) {
|
|
|
713
713
|
}
|
|
714
714
|
|
|
715
715
|
function setLabelPosition() {
|
|
716
|
-
if (props.
|
|
716
|
+
if (props.labelAlign === "top" || !hasSlotContent(slots["left"])) return;
|
|
717
717
|
|
|
718
718
|
const leftSlotWidth = leftSlotWrapperRef.value.getBoundingClientRect().width;
|
|
719
719
|
const innerWrapperPaddingLeft = parseInt(
|
package/web-types.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"framework": "vue",
|
|
3
3
|
"name": "vueless",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.100",
|
|
5
5
|
"contributions": {
|
|
6
6
|
"html": {
|
|
7
7
|
"description-markup": "markdown",
|
|
@@ -635,6 +635,14 @@
|
|
|
635
635
|
},
|
|
636
636
|
"default": "{}"
|
|
637
637
|
},
|
|
638
|
+
{
|
|
639
|
+
"name": "tag",
|
|
640
|
+
"value": {
|
|
641
|
+
"kind": "expression",
|
|
642
|
+
"type": "string"
|
|
643
|
+
},
|
|
644
|
+
"default": "button"
|
|
645
|
+
},
|
|
638
646
|
{
|
|
639
647
|
"name": "dataCy",
|
|
640
648
|
"description": "Data-cy attribute for automated testing.",
|
|
@@ -3440,7 +3448,7 @@
|
|
|
3440
3448
|
"kind": "expression",
|
|
3441
3449
|
"type": "string"
|
|
3442
3450
|
},
|
|
3443
|
-
"default": "\"\""
|
|
3451
|
+
"default": "\"Label\""
|
|
3444
3452
|
},
|
|
3445
3453
|
{
|
|
3446
3454
|
"name": "description",
|
|
@@ -3449,7 +3457,7 @@
|
|
|
3449
3457
|
"kind": "expression",
|
|
3450
3458
|
"type": "string"
|
|
3451
3459
|
},
|
|
3452
|
-
"default": "\"\""
|
|
3460
|
+
"default": "\"Some description here\""
|
|
3453
3461
|
},
|
|
3454
3462
|
{
|
|
3455
3463
|
"name": "labelAlign",
|
|
@@ -3461,23 +3469,13 @@
|
|
|
3461
3469
|
"default": "topInside"
|
|
3462
3470
|
},
|
|
3463
3471
|
{
|
|
3464
|
-
"name": "
|
|
3465
|
-
"description": "Set files data.",
|
|
3472
|
+
"name": "modelValue",
|
|
3466
3473
|
"value": {
|
|
3467
3474
|
"kind": "expression",
|
|
3468
3475
|
"type": "array"
|
|
3469
3476
|
},
|
|
3470
3477
|
"default": "[]"
|
|
3471
3478
|
},
|
|
3472
|
-
{
|
|
3473
|
-
"name": "local",
|
|
3474
|
-
"description": "Selected files will be imported when a form will be submitted",
|
|
3475
|
-
"value": {
|
|
3476
|
-
"kind": "expression",
|
|
3477
|
-
"type": "boolean"
|
|
3478
|
-
},
|
|
3479
|
-
"default": "false"
|
|
3480
|
-
},
|
|
3481
3479
|
{
|
|
3482
3480
|
"name": "maxFileSize",
|
|
3483
3481
|
"description": "Set max file size in megabytes.",
|
|
@@ -3485,25 +3483,7 @@
|
|
|
3485
3483
|
"kind": "expression",
|
|
3486
3484
|
"type": "number"
|
|
3487
3485
|
},
|
|
3488
|
-
"default": "
|
|
3489
|
-
},
|
|
3490
|
-
{
|
|
3491
|
-
"name": "multiple",
|
|
3492
|
-
"description": "Allow to select multiple files.",
|
|
3493
|
-
"value": {
|
|
3494
|
-
"kind": "expression",
|
|
3495
|
-
"type": "boolean"
|
|
3496
|
-
},
|
|
3497
|
-
"default": "false"
|
|
3498
|
-
},
|
|
3499
|
-
{
|
|
3500
|
-
"name": "maxFiles",
|
|
3501
|
-
"description": "Set max number files for upload",
|
|
3502
|
-
"value": {
|
|
3503
|
-
"kind": "expression",
|
|
3504
|
-
"type": "number"
|
|
3505
|
-
},
|
|
3506
|
-
"default": "3"
|
|
3486
|
+
"default": "100"
|
|
3507
3487
|
},
|
|
3508
3488
|
{
|
|
3509
3489
|
"name": "allowedFileTypes",
|
|
@@ -3515,22 +3495,22 @@
|
|
|
3515
3495
|
"default": ".png,.jpg,.jpeg,.pdf,.txt,.doc,.docx,xls,.xlsx"
|
|
3516
3496
|
},
|
|
3517
3497
|
{
|
|
3518
|
-
"name": "
|
|
3519
|
-
"description": "Set
|
|
3498
|
+
"name": "size",
|
|
3499
|
+
"description": "Set size.",
|
|
3520
3500
|
"value": {
|
|
3521
3501
|
"kind": "expression",
|
|
3522
|
-
"type": "
|
|
3502
|
+
"type": "'sm' | 'md' | 'lg'"
|
|
3523
3503
|
},
|
|
3524
|
-
"default": "
|
|
3504
|
+
"default": "md"
|
|
3525
3505
|
},
|
|
3526
3506
|
{
|
|
3527
|
-
"name": "
|
|
3528
|
-
"description": "Set
|
|
3507
|
+
"name": "error",
|
|
3508
|
+
"description": "Set error text for component.",
|
|
3529
3509
|
"value": {
|
|
3530
3510
|
"kind": "expression",
|
|
3531
|
-
"type": "
|
|
3511
|
+
"type": "string"
|
|
3532
3512
|
},
|
|
3533
|
-
"default": "
|
|
3513
|
+
"default": "\"\""
|
|
3534
3514
|
},
|
|
3535
3515
|
{
|
|
3536
3516
|
"name": "id",
|
|
@@ -3542,26 +3522,21 @@
|
|
|
3542
3522
|
"default": "() => getRandomId()"
|
|
3543
3523
|
},
|
|
3544
3524
|
{
|
|
3545
|
-
"name": "
|
|
3546
|
-
"description": "Sets
|
|
3525
|
+
"name": "config",
|
|
3526
|
+
"description": "Sets component ui config object.",
|
|
3547
3527
|
"value": {
|
|
3548
3528
|
"kind": "expression",
|
|
3549
|
-
"type": "
|
|
3529
|
+
"type": "object"
|
|
3550
3530
|
},
|
|
3551
|
-
"default": "
|
|
3531
|
+
"default": "{}"
|
|
3552
3532
|
}
|
|
3553
3533
|
],
|
|
3554
3534
|
"events": [
|
|
3555
3535
|
{
|
|
3556
|
-
"name": "
|
|
3536
|
+
"name": "update:modelValue"
|
|
3557
3537
|
},
|
|
3558
3538
|
{
|
|
3559
|
-
"name": "
|
|
3560
|
-
}
|
|
3561
|
-
],
|
|
3562
|
-
"slots": [
|
|
3563
|
-
{
|
|
3564
|
-
"name": "default"
|
|
3539
|
+
"name": "update:error"
|
|
3565
3540
|
}
|
|
3566
3541
|
],
|
|
3567
3542
|
"source": {
|
|
@@ -3592,13 +3567,13 @@
|
|
|
3592
3567
|
"default": "\"\""
|
|
3593
3568
|
},
|
|
3594
3569
|
{
|
|
3595
|
-
"name": "
|
|
3596
|
-
"description": "
|
|
3570
|
+
"name": "labelAlign",
|
|
3571
|
+
"description": "Set label placement related from the default slot.",
|
|
3597
3572
|
"value": {
|
|
3598
3573
|
"kind": "expression",
|
|
3599
|
-
"type": "
|
|
3574
|
+
"type": "'top' | 'topInside' | 'topWithDesc' | 'bottom' | 'left' | 'right'"
|
|
3600
3575
|
},
|
|
3601
|
-
"default": "
|
|
3576
|
+
"default": "topInside"
|
|
3602
3577
|
},
|
|
3603
3578
|
{
|
|
3604
3579
|
"name": "symbol",
|
|
@@ -4057,13 +4032,13 @@
|
|
|
4057
4032
|
"default": "\"\""
|
|
4058
4033
|
},
|
|
4059
4034
|
{
|
|
4060
|
-
"name": "
|
|
4061
|
-
"description": "
|
|
4035
|
+
"name": "labelAlign",
|
|
4036
|
+
"description": "Set label placement related from the default slot.",
|
|
4062
4037
|
"value": {
|
|
4063
4038
|
"kind": "expression",
|
|
4064
|
-
"type": "
|
|
4039
|
+
"type": "'top' | 'topInside' | 'topWithDesc' | 'bottom' | 'left' | 'right'"
|
|
4065
4040
|
},
|
|
4066
|
-
"default": "
|
|
4041
|
+
"default": "topInside"
|
|
4067
4042
|
},
|
|
4068
4043
|
{
|
|
4069
4044
|
"name": "placeholder",
|