@fastkit/vui 1.2.0 → 1.3.1
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/vui.css +38 -0
- package/dist/vui.d.ts +321 -2
- package/dist/vui.mjs +455 -334
- package/dist/vui.mjs.map +1 -1
- package/package.json +15 -15
- package/src/components/VControlField/VControlField.scss +1 -0
- package/src/components/VFileInput/VFileInput.scss +42 -0
- package/src/components/VFileInput/VFileInput.tsx +178 -0
- package/src/components/VFileInput/index.ts +1 -0
- package/src/components/index.ts +1 -0
- package/src/injections.ts +1 -0
- package/src/service.tsx +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fastkit/vui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "A simple, extensible UI kit for Vue applications.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fastkit",
|
|
@@ -44,32 +44,32 @@
|
|
|
44
44
|
"src"
|
|
45
45
|
],
|
|
46
46
|
"dependencies": {
|
|
47
|
+
"@fastkit/color-scheme-gen": "^1.1.0",
|
|
47
48
|
"@fastkit/color-scheme": "^2.1.0",
|
|
48
|
-
"@fastkit/helpers": "^0.15.0",
|
|
49
49
|
"@fastkit/icon-font": "^2.1.0",
|
|
50
|
-
"@fastkit/
|
|
50
|
+
"@fastkit/helpers": "^0.15.0",
|
|
51
51
|
"@fastkit/media-match": "^2.1.0",
|
|
52
|
+
"@fastkit/media-match-gen": "^1.1.0",
|
|
53
|
+
"@fastkit/stylebase": "^0.13.1",
|
|
54
|
+
"@fastkit/rules": "^0.15.0",
|
|
52
55
|
"@fastkit/dom": "^0.3.0",
|
|
53
56
|
"@fastkit/vue-app-layout": "^0.18.0",
|
|
54
57
|
"@fastkit/tiny-logger": "^0.15.0",
|
|
55
|
-
"@fastkit/vue-action": "^0.5.0",
|
|
56
|
-
"@fastkit/vue-disabled-reason": "^0.2.0",
|
|
57
58
|
"@fastkit/vue-body-scroll-lock": "^0.4.0",
|
|
58
|
-
"@fastkit/vue-
|
|
59
|
+
"@fastkit/vue-action": "^0.5.0",
|
|
59
60
|
"@fastkit/vue-color-scheme": "^0.17.0",
|
|
60
|
-
"@fastkit/vue-
|
|
61
|
+
"@fastkit/vue-click-outside": "^0.4.0",
|
|
62
|
+
"@fastkit/vue-disabled-reason": "^0.2.0",
|
|
63
|
+
"@fastkit/vue-form-control": "^0.24.2",
|
|
61
64
|
"@fastkit/vue-location": "^0.6.0",
|
|
65
|
+
"@fastkit/vue-keyboard": "^0.4.0",
|
|
66
|
+
"@fastkit/vue-media-match": "^0.16.0",
|
|
62
67
|
"@fastkit/vue-loading": "^0.17.0",
|
|
63
68
|
"@fastkit/vue-resize": "^0.4.0",
|
|
64
|
-
"@fastkit/vue-stack": "^0.19.
|
|
65
|
-
"@fastkit/vue-form-control": "^0.23.0",
|
|
66
|
-
"@fastkit/vue-media-match": "^0.16.0",
|
|
67
|
-
"@fastkit/vue-scroller": "^0.17.0",
|
|
68
|
-
"@fastkit/media-match-gen": "^1.1.0",
|
|
69
|
-
"@fastkit/rules": "^0.15.0",
|
|
70
|
-
"@fastkit/stylebase": "^0.13.1",
|
|
69
|
+
"@fastkit/vue-stack": "^0.19.2",
|
|
71
70
|
"@fastkit/vue-transitions": "^0.4.0",
|
|
72
|
-
"@fastkit/vue-utils": "^0.17.0"
|
|
71
|
+
"@fastkit/vue-utils": "^0.17.0",
|
|
72
|
+
"@fastkit/vue-scroller": "^0.17.0"
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
75
|
"vue": "^3.5.22",
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
@use '../../styles/core';
|
|
2
|
+
|
|
3
|
+
@layer vui {
|
|
4
|
+
.v-file-input {
|
|
5
|
+
&__inner {
|
|
6
|
+
display: flex;
|
|
7
|
+
align-items: stretch;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
&__button {
|
|
11
|
+
flex: 0 0 auto;
|
|
12
|
+
height: auto;
|
|
13
|
+
margin: 0 !important; // @TODO remove important and apply layer order
|
|
14
|
+
margin-bottom: 1px;
|
|
15
|
+
border-top-right-radius: 0;
|
|
16
|
+
border-bottom-right-radius: 0;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
&__selections {
|
|
20
|
+
display: flex;
|
|
21
|
+
flex-wrap: wrap;
|
|
22
|
+
align-items: center;
|
|
23
|
+
align-self: stretch;
|
|
24
|
+
padding: 4px 6px;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
&__placeholder {
|
|
28
|
+
color: var(--control-disabled-color);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
&__input {
|
|
32
|
+
flex: 1 1 100%;
|
|
33
|
+
cursor: text;
|
|
34
|
+
border-top-left-radius: 0;
|
|
35
|
+
border-bottom-left-radius: 0;
|
|
36
|
+
|
|
37
|
+
&__element {
|
|
38
|
+
@include core.hidden-input-element;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import './VFileInput.scss';
|
|
2
|
+
import { defineComponent, computed } from 'vue';
|
|
3
|
+
import {
|
|
4
|
+
createFileInputNodeSettings,
|
|
5
|
+
useFileInputNodeControl,
|
|
6
|
+
createFormNodeWrapperProps,
|
|
7
|
+
FormNodeWrapperSlots,
|
|
8
|
+
FileInputNodeEmits,
|
|
9
|
+
type FileInputNodeControl,
|
|
10
|
+
} from '@fastkit/vue-form-control';
|
|
11
|
+
import { defineSlots, ExtractPropInput, withCtx } from '@fastkit/vue-utils';
|
|
12
|
+
import { VFormControl } from '../VFormControl';
|
|
13
|
+
import {
|
|
14
|
+
VControlField,
|
|
15
|
+
createControlFieldProps,
|
|
16
|
+
InputBoxSlots,
|
|
17
|
+
} from '../VControlField';
|
|
18
|
+
import {
|
|
19
|
+
createControlProps,
|
|
20
|
+
useControl,
|
|
21
|
+
createControlFieldProviderProps,
|
|
22
|
+
useControlField,
|
|
23
|
+
} from '../../composables';
|
|
24
|
+
import { colorSchemeProps } from '@fastkit/vue-color-scheme';
|
|
25
|
+
import { VUI_FILE_INPUT_SYMBOL, useVui } from '../../injections';
|
|
26
|
+
import { VButton } from '../VButton';
|
|
27
|
+
|
|
28
|
+
const { props, emits } = createFileInputNodeSettings();
|
|
29
|
+
|
|
30
|
+
const slots = defineSlots<
|
|
31
|
+
FormNodeWrapperSlots &
|
|
32
|
+
InputBoxSlots & {
|
|
33
|
+
selections?: (control: FileInputNodeControl) => any;
|
|
34
|
+
}
|
|
35
|
+
>();
|
|
36
|
+
|
|
37
|
+
function createFileInputProps() {
|
|
38
|
+
return {
|
|
39
|
+
...props,
|
|
40
|
+
...colorSchemeProps(),
|
|
41
|
+
...createFormNodeWrapperProps(),
|
|
42
|
+
...createControlFieldProps(),
|
|
43
|
+
...createControlFieldProviderProps(),
|
|
44
|
+
...createControlProps(),
|
|
45
|
+
...slots(),
|
|
46
|
+
buttonText: {
|
|
47
|
+
type: String,
|
|
48
|
+
default: 'Choose File',
|
|
49
|
+
},
|
|
50
|
+
truncateLength: {
|
|
51
|
+
type: [Number, String],
|
|
52
|
+
default: 22,
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export type FileInputPropsOptions = ReturnType<typeof createFileInputProps>;
|
|
58
|
+
|
|
59
|
+
export type FileInputEmits = FileInputNodeEmits;
|
|
60
|
+
|
|
61
|
+
export type FileInputInput = ExtractPropInput<
|
|
62
|
+
ReturnType<typeof createFileInputProps>
|
|
63
|
+
>;
|
|
64
|
+
|
|
65
|
+
export const VFileInput = defineComponent({
|
|
66
|
+
name: 'VFileInput',
|
|
67
|
+
props: createFileInputProps(),
|
|
68
|
+
emits,
|
|
69
|
+
slots,
|
|
70
|
+
setup(props, ctx) {
|
|
71
|
+
const vui = useVui();
|
|
72
|
+
const inputControl = useFileInputNodeControl(props, ctx, {
|
|
73
|
+
nodeType: VUI_FILE_INPUT_SYMBOL,
|
|
74
|
+
});
|
|
75
|
+
const control = useControl(props);
|
|
76
|
+
useControlField(props);
|
|
77
|
+
|
|
78
|
+
const classes = computed(() => ['v-file-input', control.classes.value]);
|
|
79
|
+
|
|
80
|
+
const handleClickLabel = (ev: PointerEvent) => {
|
|
81
|
+
inputControl.focus();
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const endAdornmentSlot = () => {
|
|
85
|
+
// }
|
|
86
|
+
if (props.clearable && inputControl.value.length) {
|
|
87
|
+
return (
|
|
88
|
+
<VButton
|
|
89
|
+
key="clear"
|
|
90
|
+
icon={vui.icon('clear')}
|
|
91
|
+
rounded
|
|
92
|
+
onClick={(ev) => {
|
|
93
|
+
ev.stopPropagation();
|
|
94
|
+
inputControl.clear();
|
|
95
|
+
}}
|
|
96
|
+
/>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const showDialog = () => {
|
|
102
|
+
if (inputControl.canOperation) {
|
|
103
|
+
inputControl.inputElement?.click();
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const renderSelections = () => {
|
|
108
|
+
if (ctx.slots.selections) {
|
|
109
|
+
return ctx.slots.selections(inputControl);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const { files } = inputControl.selectionContext;
|
|
113
|
+
if (!files.length)
|
|
114
|
+
return (
|
|
115
|
+
<span class="v-file-input__placeholder">
|
|
116
|
+
{inputControl.placeholder || 'No file chosen'}
|
|
117
|
+
</span>
|
|
118
|
+
);
|
|
119
|
+
return files.map((file) => file.truncatedName).join(', ');
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const defaultSlot = () => (
|
|
123
|
+
<div class="v-file-input__inner">
|
|
124
|
+
<VButton
|
|
125
|
+
key="open"
|
|
126
|
+
class="v-file-input__button"
|
|
127
|
+
color={'base' as any}
|
|
128
|
+
size={props.size}
|
|
129
|
+
startIcon={vui.icon('fileUpload')}
|
|
130
|
+
variant={vui.setting('containedVariant')}
|
|
131
|
+
onClick={showDialog}>
|
|
132
|
+
{props.buttonText}
|
|
133
|
+
</VButton>
|
|
134
|
+
<VControlField
|
|
135
|
+
class="v-file-input__input"
|
|
136
|
+
startAdornment={props.startAdornment}
|
|
137
|
+
endAdornment={props.endAdornment}
|
|
138
|
+
size={control.size.value}
|
|
139
|
+
onClick={showDialog}
|
|
140
|
+
autoHeight
|
|
141
|
+
v-slots={{
|
|
142
|
+
...ctx.slots,
|
|
143
|
+
default: withCtx(() => [
|
|
144
|
+
inputControl.createInputElement({
|
|
145
|
+
class: 'v-file-input__input__element',
|
|
146
|
+
}),
|
|
147
|
+
<div class="v-file-input__selections">{renderSelections()}</div>,
|
|
148
|
+
]),
|
|
149
|
+
endAdornment: withCtx(endAdornmentSlot),
|
|
150
|
+
}}
|
|
151
|
+
/>
|
|
152
|
+
</div>
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
ctx.expose({
|
|
156
|
+
control: inputControl,
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
return () => (
|
|
160
|
+
<VFormControl
|
|
161
|
+
nodeControl={inputControl}
|
|
162
|
+
// focused={inputControl.focused}
|
|
163
|
+
hiddenInfo={props.hiddenInfo}
|
|
164
|
+
class={classes.value}
|
|
165
|
+
label={props.label}
|
|
166
|
+
hint={props.hint}
|
|
167
|
+
hinttip={props.hinttip}
|
|
168
|
+
requiredChip={props.requiredChip}
|
|
169
|
+
onClickLabel={handleClickLabel}
|
|
170
|
+
v-slots={{
|
|
171
|
+
...ctx.slots,
|
|
172
|
+
default: withCtx(defaultSlot),
|
|
173
|
+
// infoAppends: withCtx(infoAppendsSlot),
|
|
174
|
+
}}
|
|
175
|
+
/>
|
|
176
|
+
);
|
|
177
|
+
},
|
|
178
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './VFileInput';
|
package/src/components/index.ts
CHANGED
package/src/injections.ts
CHANGED
|
@@ -27,6 +27,7 @@ export const VUI_RADIO_GROUP_SYMBOL = 'vui-radio-group';
|
|
|
27
27
|
export const VUI_RADIO_SYMBOL = 'vui-radio';
|
|
28
28
|
export const VUI_SWITCH_GROUP_SYMBOL = 'vui-switch-group';
|
|
29
29
|
export const VUI_SWITCH_SYMBOL = 'vui-switch';
|
|
30
|
+
export const VUI_FILE_INPUT_SYMBOL = 'vui-file-input';
|
|
30
31
|
export const VUI_FORM_GROUP_SYMBOL = 'vui-form-group';
|
|
31
32
|
export const VUI_FORM_SYMBOL = 'vui-form';
|
|
32
33
|
|