@ouestfrance/sipa-bms-ui 8.19.0 → 8.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/form/BmsFilePicker.vue.d.ts +4 -0
- package/dist/components/form/BmsInputText.vue.d.ts +1 -0
- package/dist/components/form/BmsMultiSelect.vue.d.ts +4 -0
- package/dist/components/form/BmsSearch.vue.d.ts +3 -1
- package/dist/components/form/RawAutocomplete.vue.d.ts +8 -0
- package/dist/components/layout/BmsSplitWindow.vue.d.ts +1 -0
- package/dist/components/navigation/UiTenantSwitcher.vue.d.ts +3 -1
- package/dist/components/table/BmsTableFilters.vue.d.ts +3 -1
- package/dist/mockServiceWorker.js +1 -1
- package/dist/sipa-bms-ui.css +54 -368
- package/dist/sipa-bms-ui.es.js +118 -47
- package/dist/sipa-bms-ui.es.js.map +1 -1
- package/dist/sipa-bms-ui.umd.js +117 -46
- package/dist/sipa-bms-ui.umd.js.map +1 -1
- package/package.json +13 -12
- package/src/assets/scss/_conf.scss +0 -1
- package/src/assets/scss/app.scss +0 -1
- package/src/components/button/BmsAllButtons.stories.js +50 -23
- package/src/components/button/BmsButton.stories.js +151 -65
- package/src/components/button/BmsIconButton.stories.js +14 -8
- package/src/components/button/UiButton.stories.js +31 -0
- package/src/components/feedback/BmsCircularProgress.stories.js +0 -7
- package/src/components/feedback/BmsLoader.stories.js +0 -6
- package/src/components/feedback/BmsTooltip.stories.js +1 -0
- package/src/components/feedback/UiTooltip.stories.js +1 -0
- package/src/components/form/BmsAutocomplete.stories.js +11 -1
- package/src/components/form/BmsBetweenInput.stories.js +17 -1
- package/src/components/form/BmsFilePicker.stories.js +8 -1
- package/src/components/form/BmsFilePicker.vue +10 -5
- package/src/components/form/BmsInputBooleanCheckbox.stories.js +9 -0
- package/src/components/form/BmsInputCheckboxCaption.stories.js +16 -0
- package/src/components/form/BmsInputCheckboxCaptionGroup.stories.js +21 -1
- package/src/components/form/BmsInputText.vue +1 -0
- package/src/components/form/BmsMultiSelect.vue +32 -25
- package/src/components/form/BmsSelect.vue +18 -16
- package/src/components/form/RawAutocomplete.vue +16 -4
- package/src/components/form/RawInputText.vue +1 -0
- package/src/components/form/UiBmsInputCheckbox.stories.js +1 -0
- package/src/components/form/UiBmsSwitch.stories.js +1 -5
- package/src/components/layout/BmsForm_retrocompat.stories.js +1 -0
- package/src/components/layout/BmsModal.stories.js +2 -1
- package/src/components/layout/BmsSplitWindow.vue +4 -3
- package/src/components/navigation/BmsBreadcrumb.stories.js +0 -18
- package/src/components/navigation/BmsMenu.stories.js +4 -4
- package/src/components/navigation/BmsMenuNav.stories.js +4 -3
- package/src/components/navigation/UiMenuItem.stories.js +53 -2
- package/src/components/navigation/UiTab.stories.js +1 -0
- package/src/components/navigation/UiTenantSwitcher.stories.js +1 -0
- package/src/components/table/BmsEmptyScreen.stories.js +0 -7
- package/src/components/table/BmsTableFilters.vue +1 -1
- package/src/components/table/UiBmsTable.stories.js +1 -0
- package/src/components/table/UiFilterButton.stories.js +3 -8
- package/src/components/utils/BmsRelativeTime.stories.js +0 -6
- package/src/documentation/button/primaryButton.mdx +142 -0
- package/src/documentation/{secondaryButton.mdx → button/secondaryButton.mdx} +2 -2
- package/src/documentation/foundation/contributing.mdx +72 -0
- package/src/documentation/foundation/gettingstarted.mdx +7 -0
- package/src/documentation/{principles.mdx → foundation/principles.mdx} +9 -9
- package/src/documentation/icons.mdx +43 -0
- package/src/showroom/pages/forms.vue +10 -1
- package/src/assets/scss/_formkit.scss +0 -353
- package/src/components/feedback/Notification.stories.js +0 -37
- package/src/components/form/Form.stories.js +0 -35
- package/src/components/navigation/UiMenuItemStatus.stories.js +0 -64
- package/src/documentation/primaryButton.mdx +0 -20
- /package/src/documentation/{button.mdx → button/button.mdx} +0 -0
|
@@ -2,6 +2,7 @@ import BmsAutocomplete from '@/components/form/BmsAutocomplete.vue';
|
|
|
2
2
|
import { Cat, Heart, Wheat } from 'lucide-vue-next';
|
|
3
3
|
|
|
4
4
|
import template from '@/documentation/template_field_dependency.mdx';
|
|
5
|
+
import { DEFAULT_FIELD_INPUT } from '../../../.storybook/constants';
|
|
5
6
|
|
|
6
7
|
export default {
|
|
7
8
|
parameters: {
|
|
@@ -9,7 +10,8 @@ export default {
|
|
|
9
10
|
page: template,
|
|
10
11
|
},
|
|
11
12
|
},
|
|
12
|
-
|
|
13
|
+
tags: ['with_useable_code'],
|
|
14
|
+
title: 'Composants/form/Autocomplete',
|
|
13
15
|
component: BmsAutocomplete,
|
|
14
16
|
argTypes: {},
|
|
15
17
|
};
|
|
@@ -31,6 +33,7 @@ const Template = (args) => ({
|
|
|
31
33
|
|
|
32
34
|
export const Default = Template.bind({});
|
|
33
35
|
Default.args = {
|
|
36
|
+
...DEFAULT_FIELD_INPUT,
|
|
34
37
|
label: 'My autocomplete field',
|
|
35
38
|
options: [
|
|
36
39
|
{ label: 'titi', value: 'i' },
|
|
@@ -42,6 +45,7 @@ Default.args = {
|
|
|
42
45
|
|
|
43
46
|
export const Disabled = Template.bind({});
|
|
44
47
|
Disabled.args = {
|
|
48
|
+
...DEFAULT_FIELD_INPUT,
|
|
45
49
|
label: 'My autocomplete field',
|
|
46
50
|
options: [
|
|
47
51
|
{ label: 'titi', value: 'i' },
|
|
@@ -54,6 +58,7 @@ Disabled.args = {
|
|
|
54
58
|
|
|
55
59
|
export const Loading = Template.bind({});
|
|
56
60
|
Loading.args = {
|
|
61
|
+
...DEFAULT_FIELD_INPUT,
|
|
57
62
|
label: 'My autocomplete field',
|
|
58
63
|
loading: true,
|
|
59
64
|
options: [
|
|
@@ -66,6 +71,7 @@ Loading.args = {
|
|
|
66
71
|
|
|
67
72
|
export const WithStringArray = Template.bind({});
|
|
68
73
|
WithStringArray.args = {
|
|
74
|
+
...DEFAULT_FIELD_INPUT,
|
|
69
75
|
label: 'My autocomplete field',
|
|
70
76
|
options: ['titi', 'toto', 'tutu'],
|
|
71
77
|
modelValue: '',
|
|
@@ -74,6 +80,7 @@ WithStringArray.args = {
|
|
|
74
80
|
|
|
75
81
|
export const WithValue = Template.bind({});
|
|
76
82
|
WithValue.args = {
|
|
83
|
+
...DEFAULT_FIELD_INPUT,
|
|
77
84
|
label: 'My autocomplete field',
|
|
78
85
|
options: [
|
|
79
86
|
{ label: 'titi', value: 'i' },
|
|
@@ -86,6 +93,7 @@ WithValue.args = {
|
|
|
86
93
|
export const Opened = Template.bind({});
|
|
87
94
|
Opened.parameters = { pseudo: { focus: 'input' } };
|
|
88
95
|
Opened.args = {
|
|
96
|
+
...DEFAULT_FIELD_INPUT,
|
|
89
97
|
label: 'My autocomplete field',
|
|
90
98
|
options: [
|
|
91
99
|
{ label: 'titi', value: 'i' },
|
|
@@ -97,6 +105,7 @@ Opened.args = {
|
|
|
97
105
|
};
|
|
98
106
|
export const IconsWithValue = Template.bind({});
|
|
99
107
|
IconsWithValue.args = {
|
|
108
|
+
...DEFAULT_FIELD_INPUT,
|
|
100
109
|
label: 'My autocomplete field',
|
|
101
110
|
options: [
|
|
102
111
|
{ label: 'titi', value: 'i', icon: Heart },
|
|
@@ -109,6 +118,7 @@ IconsWithValue.args = {
|
|
|
109
118
|
export const IconsOpened = Template.bind({});
|
|
110
119
|
IconsOpened.parameters = { pseudo: { focus: 'input' } };
|
|
111
120
|
IconsOpened.args = {
|
|
121
|
+
...DEFAULT_FIELD_INPUT,
|
|
112
122
|
label: 'My autocomplete field',
|
|
113
123
|
options: [
|
|
114
124
|
{ label: 'titi', value: 'i', icon: Heart },
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BookOpen, CloudLightning } from 'lucide-vue-next';
|
|
2
2
|
import BmsBetweenInput from './BmsBetweenInput.vue';
|
|
3
|
-
import {
|
|
3
|
+
import { InputType, StatusType } from '../../models';
|
|
4
4
|
|
|
5
5
|
import template from '@/documentation/template_field_dependency.mdx';
|
|
6
6
|
|
|
@@ -11,6 +11,7 @@ export default {
|
|
|
11
11
|
},
|
|
12
12
|
},
|
|
13
13
|
title: 'Composants/form/BetweenInput',
|
|
14
|
+
tags: ['with_useable_code'],
|
|
14
15
|
component: BmsBetweenInput,
|
|
15
16
|
};
|
|
16
17
|
|
|
@@ -32,8 +33,20 @@ const Template = (args) => ({
|
|
|
32
33
|
`,
|
|
33
34
|
});
|
|
34
35
|
|
|
36
|
+
const DEFAULT_BEETWEEN_INPUT = {
|
|
37
|
+
inputType: InputType.NUMBER,
|
|
38
|
+
label: 'My label',
|
|
39
|
+
required: false,
|
|
40
|
+
optional: false,
|
|
41
|
+
disabled: false,
|
|
42
|
+
helperText: 'help me !',
|
|
43
|
+
captions: [],
|
|
44
|
+
errors: [],
|
|
45
|
+
};
|
|
46
|
+
|
|
35
47
|
export const Default = Template.bind({});
|
|
36
48
|
Default.args = {
|
|
49
|
+
...DEFAULT_BEETWEEN_INPUT,
|
|
37
50
|
label: 'My label',
|
|
38
51
|
placeholderFrom: 'Placeholder From',
|
|
39
52
|
placeholderTo: 'Placeholder To',
|
|
@@ -42,6 +55,7 @@ Default.args = {
|
|
|
42
55
|
|
|
43
56
|
export const WithDate = Template.bind({});
|
|
44
57
|
WithDate.args = {
|
|
58
|
+
...DEFAULT_BEETWEEN_INPUT,
|
|
45
59
|
inputType: InputType.DATETIME,
|
|
46
60
|
label: 'My label',
|
|
47
61
|
placeholderFrom: 'Placeholder From',
|
|
@@ -51,6 +65,7 @@ WithDate.args = {
|
|
|
51
65
|
|
|
52
66
|
export const WithBadPresetValueDate = Template.bind({});
|
|
53
67
|
WithBadPresetValueDate.args = {
|
|
68
|
+
...DEFAULT_BEETWEEN_INPUT,
|
|
54
69
|
inputType: InputType.DATETIME,
|
|
55
70
|
label: 'My label',
|
|
56
71
|
placeholderFrom: 'Placeholder From',
|
|
@@ -62,6 +77,7 @@ WithBadPresetValueDate.args = {
|
|
|
62
77
|
|
|
63
78
|
export const WithErrors = Template.bind({});
|
|
64
79
|
WithErrors.args = {
|
|
80
|
+
...DEFAULT_BEETWEEN_INPUT,
|
|
65
81
|
label: 'My label',
|
|
66
82
|
placeholderFrom: 'Placeholder From',
|
|
67
83
|
placeholderTo: 'Placeholder To',
|
|
@@ -9,6 +9,7 @@ export default {
|
|
|
9
9
|
},
|
|
10
10
|
},
|
|
11
11
|
title: 'Composants/form/FilePicker',
|
|
12
|
+
tags: ['with_useable_code'],
|
|
12
13
|
component: BmsFilePicker,
|
|
13
14
|
argTypes: {
|
|
14
15
|
limit: {
|
|
@@ -31,10 +32,16 @@ const Template = (args) => ({
|
|
|
31
32
|
});
|
|
32
33
|
|
|
33
34
|
export const Empty = Template.bind({});
|
|
34
|
-
Empty.args = {
|
|
35
|
+
Empty.args = {
|
|
36
|
+
modelValue: [],
|
|
37
|
+
limit: 5,
|
|
38
|
+
dragOverMessage: 'Déposer vos fichiers ici',
|
|
39
|
+
dragOffMessage: 'Glissez votre fichier ici ou cliquez pour parcourir',
|
|
40
|
+
};
|
|
35
41
|
|
|
36
42
|
export const WithFiles = Template.bind({});
|
|
37
43
|
WithFiles.args = {
|
|
44
|
+
limit: 5,
|
|
38
45
|
modelValue: [
|
|
39
46
|
{
|
|
40
47
|
name: 'Name of a file',
|
|
@@ -7,9 +7,16 @@ const files: Ref<File[] | undefined> = ref();
|
|
|
7
7
|
const isDragOver = ref(false);
|
|
8
8
|
|
|
9
9
|
const props = withDefaults(
|
|
10
|
-
defineProps<{
|
|
10
|
+
defineProps<{
|
|
11
|
+
dragOverMessage?: string;
|
|
12
|
+
dragOffMessage?: string;
|
|
13
|
+
modelValue?: File[];
|
|
14
|
+
limit: number;
|
|
15
|
+
}>(),
|
|
11
16
|
{
|
|
12
17
|
limit: 10,
|
|
18
|
+
dragOverMessage: 'Déposer votre image ici',
|
|
19
|
+
dragOffMessage: 'Glissez votre image ici ou cliquez pour parcourir',
|
|
13
20
|
},
|
|
14
21
|
);
|
|
15
22
|
|
|
@@ -101,10 +108,8 @@ function onDeleteFile(file: File) {
|
|
|
101
108
|
@dragover.prevent
|
|
102
109
|
>
|
|
103
110
|
<label class="file-upload__label">
|
|
104
|
-
<template v-if="isDragOver">
|
|
105
|
-
<template v-else
|
|
106
|
-
>Glissez votre image ici ou cliquez pour parcourir</template
|
|
107
|
-
>
|
|
111
|
+
<template v-if="isDragOver">{{ dragOverMessage }}</template>
|
|
112
|
+
<template v-else>{{ dragOffMessage }}</template>
|
|
108
113
|
<input
|
|
109
114
|
data-testid="file-upload-input-file"
|
|
110
115
|
type="file"
|
|
@@ -3,6 +3,7 @@ import { ref } from 'vue';
|
|
|
3
3
|
import { StatusType } from '@/models';
|
|
4
4
|
|
|
5
5
|
import template from '@/documentation/template_field_dependency.mdx';
|
|
6
|
+
import { DEFAULT_FIELD_INPUT } from '../../../.storybook/constants';
|
|
6
7
|
|
|
7
8
|
export default {
|
|
8
9
|
parameters: {
|
|
@@ -10,6 +11,7 @@ export default {
|
|
|
10
11
|
page: template,
|
|
11
12
|
},
|
|
12
13
|
},
|
|
14
|
+
tags: ['with_useable_code'],
|
|
13
15
|
title: 'Composants/form/InputBooleanCheckbox',
|
|
14
16
|
component: BmsInputBooleanCheckbox,
|
|
15
17
|
};
|
|
@@ -42,12 +44,14 @@ const Template = (args) => ({
|
|
|
42
44
|
|
|
43
45
|
export const Default = Template.bind({});
|
|
44
46
|
Default.args = {
|
|
47
|
+
...DEFAULT_FIELD_INPUT,
|
|
45
48
|
labelValue: 'check me !',
|
|
46
49
|
name: 'myCheckboxName',
|
|
47
50
|
};
|
|
48
51
|
|
|
49
52
|
export const WithNotBooleanModelValue = Template.bind({});
|
|
50
53
|
WithNotBooleanModelValue.args = {
|
|
54
|
+
...DEFAULT_FIELD_INPUT,
|
|
51
55
|
modelValue: 'COCHEEEEEEEE',
|
|
52
56
|
labelValue: 'check me !',
|
|
53
57
|
name: 'myCheckboxName',
|
|
@@ -55,6 +59,7 @@ WithNotBooleanModelValue.args = {
|
|
|
55
59
|
|
|
56
60
|
export const DefaultWithCheckedValue = Template.bind({});
|
|
57
61
|
DefaultWithCheckedValue.args = {
|
|
62
|
+
...DEFAULT_FIELD_INPUT,
|
|
58
63
|
modelValue: true,
|
|
59
64
|
labelValue: 'check me !',
|
|
60
65
|
name: 'myCheckboxName',
|
|
@@ -62,6 +67,7 @@ DefaultWithCheckedValue.args = {
|
|
|
62
67
|
|
|
63
68
|
export const WithLabel = Template.bind({});
|
|
64
69
|
WithLabel.args = {
|
|
70
|
+
...DEFAULT_FIELD_INPUT,
|
|
65
71
|
label: 'My label',
|
|
66
72
|
labelValue: 'check me !',
|
|
67
73
|
modelValue: false,
|
|
@@ -70,6 +76,7 @@ WithLabel.args = {
|
|
|
70
76
|
|
|
71
77
|
export const WithLabelAsSlot = Template.bind({});
|
|
72
78
|
WithLabelAsSlot.args = {
|
|
79
|
+
...DEFAULT_FIELD_INPUT,
|
|
73
80
|
name: 'myCheckboxName',
|
|
74
81
|
labelValue: 'check me !',
|
|
75
82
|
modelValue: false,
|
|
@@ -78,6 +85,7 @@ WithLabelAsSlot.args = {
|
|
|
78
85
|
|
|
79
86
|
export const Disabled = Template.bind({});
|
|
80
87
|
Disabled.args = {
|
|
88
|
+
...DEFAULT_FIELD_INPUT,
|
|
81
89
|
name: 'myCheckboxName',
|
|
82
90
|
labelValue: 'check me !',
|
|
83
91
|
label: 'My label',
|
|
@@ -87,6 +95,7 @@ Disabled.args = {
|
|
|
87
95
|
|
|
88
96
|
export const Error = Template.bind({});
|
|
89
97
|
Error.args = {
|
|
98
|
+
...DEFAULT_FIELD_INPUT,
|
|
90
99
|
name: 'myCheckboxName',
|
|
91
100
|
labelValue: 'check me !',
|
|
92
101
|
label: 'My label',
|
|
@@ -9,6 +9,7 @@ export default {
|
|
|
9
9
|
page: template,
|
|
10
10
|
},
|
|
11
11
|
},
|
|
12
|
+
tags: ['with_useable_code'],
|
|
12
13
|
title: 'Composants/form/InputCheckboxCaption',
|
|
13
14
|
component: BmsInputCheckboxCaption,
|
|
14
15
|
};
|
|
@@ -38,8 +39,18 @@ const Template = (args) => ({
|
|
|
38
39
|
`,
|
|
39
40
|
});
|
|
40
41
|
|
|
42
|
+
const DEFAULT_CHECKBOXCAPTION_INPUT = {
|
|
43
|
+
label: 'Mon texte',
|
|
44
|
+
options: [],
|
|
45
|
+
required: false,
|
|
46
|
+
disabled: false,
|
|
47
|
+
captions: [],
|
|
48
|
+
errors: [],
|
|
49
|
+
};
|
|
50
|
+
|
|
41
51
|
export const Default = Template.bind({});
|
|
42
52
|
Default.args = {
|
|
53
|
+
...DEFAULT_CHECKBOXCAPTION_INPUT,
|
|
43
54
|
modelValue: null,
|
|
44
55
|
label: 'MyLabel',
|
|
45
56
|
name: 'myInput',
|
|
@@ -47,6 +58,7 @@ Default.args = {
|
|
|
47
58
|
|
|
48
59
|
export const WithLabelAsSlot = Template.bind({});
|
|
49
60
|
WithLabelAsSlot.args = {
|
|
61
|
+
...DEFAULT_CHECKBOXCAPTION_INPUT,
|
|
50
62
|
modelValue: null,
|
|
51
63
|
labelSlot: 'This is a slotted value',
|
|
52
64
|
name: 'myInput',
|
|
@@ -54,6 +66,7 @@ WithLabelAsSlot.args = {
|
|
|
54
66
|
|
|
55
67
|
export const WithCaptions = Template.bind({});
|
|
56
68
|
WithCaptions.args = {
|
|
69
|
+
...DEFAULT_CHECKBOXCAPTION_INPUT,
|
|
57
70
|
label: 'My label',
|
|
58
71
|
modelValue: null,
|
|
59
72
|
captions: ['Caption form my label 1', 'Caption form my label 2'],
|
|
@@ -62,6 +75,7 @@ WithCaptions.args = {
|
|
|
62
75
|
|
|
63
76
|
export const WithCaptionMode = Template.bind({});
|
|
64
77
|
WithCaptionMode.args = {
|
|
78
|
+
...DEFAULT_CHECKBOXCAPTION_INPUT,
|
|
65
79
|
label: 'My label',
|
|
66
80
|
modelValue: null,
|
|
67
81
|
captions: [
|
|
@@ -75,6 +89,7 @@ WithCaptionMode.args = {
|
|
|
75
89
|
|
|
76
90
|
export const Disabled = Template.bind({});
|
|
77
91
|
Disabled.args = {
|
|
92
|
+
...DEFAULT_CHECKBOXCAPTION_INPUT,
|
|
78
93
|
label: 'My label',
|
|
79
94
|
modelValue: null,
|
|
80
95
|
disabled: true,
|
|
@@ -84,6 +99,7 @@ Disabled.args = {
|
|
|
84
99
|
|
|
85
100
|
export const Error = Template.bind({});
|
|
86
101
|
Error.args = {
|
|
102
|
+
...DEFAULT_CHECKBOXCAPTION_INPUT,
|
|
87
103
|
label: 'My label',
|
|
88
104
|
modelValue: null,
|
|
89
105
|
errors: ['Error 1', 'Error 2'],
|
|
@@ -11,6 +11,7 @@ export default {
|
|
|
11
11
|
page: template,
|
|
12
12
|
},
|
|
13
13
|
},
|
|
14
|
+
tags: ['with_useable_code'],
|
|
14
15
|
title: 'Composants/form/InputCheckboxCaptionGroup',
|
|
15
16
|
component: BmsInputCheckboxCaptionGroup,
|
|
16
17
|
};
|
|
@@ -30,8 +31,21 @@ const Template = (args) => ({
|
|
|
30
31
|
`,
|
|
31
32
|
});
|
|
32
33
|
|
|
34
|
+
const DEFAULT_CHECKBOXCAPTION_INPUT = {
|
|
35
|
+
options: [],
|
|
36
|
+
required: false,
|
|
37
|
+
optional: false,
|
|
38
|
+
disabled: false,
|
|
39
|
+
helperText: 'help me !',
|
|
40
|
+
captions: [],
|
|
41
|
+
errors: [],
|
|
42
|
+
align: 'right',
|
|
43
|
+
};
|
|
44
|
+
|
|
33
45
|
export const DefaultRow = Template.bind({});
|
|
34
46
|
DefaultRow.args = {
|
|
47
|
+
...DEFAULT_CHECKBOXCAPTION_INPUT,
|
|
48
|
+
label: 'This is a field label',
|
|
35
49
|
options: [
|
|
36
50
|
{ value: 'tata', label: 'Tata', captions: ['Caption for tata'] },
|
|
37
51
|
{ value: 'titi', label: 'Titi', captions: ['Caption for titi'] },
|
|
@@ -43,11 +57,11 @@ DefaultRow.args = {
|
|
|
43
57
|
{ label: 'Caption for group', mode: StatusType.Success },
|
|
44
58
|
],
|
|
45
59
|
modelValue: [],
|
|
46
|
-
label: 'This is a field label',
|
|
47
60
|
};
|
|
48
61
|
|
|
49
62
|
export const DefaultColumn = Template.bind({});
|
|
50
63
|
DefaultColumn.args = {
|
|
64
|
+
...DEFAULT_CHECKBOXCAPTION_INPUT,
|
|
51
65
|
options: [
|
|
52
66
|
{ value: 'tata', captions: ['Caption for tata'] },
|
|
53
67
|
{ value: 'titi', captions: ['Caption for titi'] },
|
|
@@ -61,6 +75,7 @@ DefaultColumn.args = {
|
|
|
61
75
|
|
|
62
76
|
export const WithCaptionMode = Template.bind({});
|
|
63
77
|
WithCaptionMode.args = {
|
|
78
|
+
...DEFAULT_CHECKBOXCAPTION_INPUT,
|
|
64
79
|
options: [
|
|
65
80
|
{
|
|
66
81
|
value: 'tata',
|
|
@@ -89,6 +104,7 @@ WithCaptionMode.args = {
|
|
|
89
104
|
|
|
90
105
|
export const DefaultSelected = Template.bind({});
|
|
91
106
|
DefaultSelected.args = {
|
|
107
|
+
...DEFAULT_CHECKBOXCAPTION_INPUT,
|
|
92
108
|
options: [
|
|
93
109
|
{ value: 'tata', captions: ['Caption for tata'] },
|
|
94
110
|
{ value: 'titi', captions: ['Caption for titi'] },
|
|
@@ -101,6 +117,7 @@ DefaultSelected.args = {
|
|
|
101
117
|
|
|
102
118
|
export const FullHelp = Template.bind({});
|
|
103
119
|
FullHelp.args = {
|
|
120
|
+
...DEFAULT_CHECKBOXCAPTION_INPUT,
|
|
104
121
|
options: [
|
|
105
122
|
{ value: 'tata', captions: ['Caption for tata'] },
|
|
106
123
|
{ value: 'titi', captions: ['Caption for titi'] },
|
|
@@ -115,6 +132,7 @@ FullHelp.args = {
|
|
|
115
132
|
|
|
116
133
|
export const Disabled = Template.bind({});
|
|
117
134
|
Disabled.args = {
|
|
135
|
+
...DEFAULT_CHECKBOXCAPTION_INPUT,
|
|
118
136
|
options: [
|
|
119
137
|
{ value: 'tata', captions: ['Caption for tata'] },
|
|
120
138
|
{ value: 'titi', captions: ['Caption for titi'] },
|
|
@@ -128,6 +146,7 @@ Disabled.args = {
|
|
|
128
146
|
|
|
129
147
|
export const Required = Template.bind({});
|
|
130
148
|
Required.args = {
|
|
149
|
+
...DEFAULT_CHECKBOXCAPTION_INPUT,
|
|
131
150
|
options: [
|
|
132
151
|
{ value: 'tata', captions: ['Caption for tata'] },
|
|
133
152
|
{ value: 'titi', captions: ['Caption for titi'] },
|
|
@@ -141,6 +160,7 @@ Required.args = {
|
|
|
141
160
|
|
|
142
161
|
export const Errors = Template.bind({});
|
|
143
162
|
Errors.args = {
|
|
163
|
+
...DEFAULT_CHECKBOXCAPTION_INPUT,
|
|
144
164
|
options: [
|
|
145
165
|
{ value: 'tata', captions: ['Caption for tata'] },
|
|
146
166
|
{ value: 'titi', captions: ['Caption for titi'] },
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
:model-value="modelValue"
|
|
6
6
|
:open="isDatalistOpen"
|
|
7
7
|
@select="onSelect"
|
|
8
|
-
@click="
|
|
8
|
+
@click="onSelectClick"
|
|
9
9
|
>
|
|
10
10
|
<template #input>
|
|
11
11
|
<div class="tags">
|
|
@@ -24,11 +24,8 @@
|
|
|
24
24
|
v-model="searching"
|
|
25
25
|
class="search"
|
|
26
26
|
:disabled="disabled"
|
|
27
|
-
@
|
|
28
|
-
@click="openDatalist"
|
|
27
|
+
@input="onInput"
|
|
29
28
|
@keyup.down="openDatalist"
|
|
30
|
-
@input="openDatalist"
|
|
31
|
-
@keyup.backspace="onBackspace"
|
|
32
29
|
/>
|
|
33
30
|
</div>
|
|
34
31
|
|
|
@@ -37,16 +34,8 @@
|
|
|
37
34
|
<X class="icon icon-clear" @click.stop="clearInput" />
|
|
38
35
|
</template>
|
|
39
36
|
<template v-else>
|
|
40
|
-
<ChevronUp
|
|
41
|
-
|
|
42
|
-
class="icon icon-toggle-button"
|
|
43
|
-
@click="closeDatalist"
|
|
44
|
-
/>
|
|
45
|
-
<ChevronDown
|
|
46
|
-
v-else
|
|
47
|
-
class="icon icon-toggle-button"
|
|
48
|
-
@click="openDatalist"
|
|
49
|
-
/>
|
|
37
|
+
<ChevronUp v-if="isDatalistOpen" class="icon icon-toggle-button" />
|
|
38
|
+
<ChevronDown v-else class="icon icon-toggle-button" />
|
|
50
39
|
</template>
|
|
51
40
|
</span>
|
|
52
41
|
</template>
|
|
@@ -67,7 +56,7 @@ import { InputOption } from '@/models';
|
|
|
67
56
|
import { searchString } from '@/helpers';
|
|
68
57
|
import { FieldComponentProps } from '@/plugins/field/field-component.model';
|
|
69
58
|
import RawSelect from './RawSelect.vue';
|
|
70
|
-
import { onClickOutside } from '@vueuse/core';
|
|
59
|
+
import { onClickOutside, onKeyDown, onKeyUp } from '@vueuse/core';
|
|
71
60
|
|
|
72
61
|
export interface Props extends FieldComponentProps {
|
|
73
62
|
options: InputOption[] | string[];
|
|
@@ -80,9 +69,16 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
80
69
|
required: false,
|
|
81
70
|
});
|
|
82
71
|
|
|
83
|
-
const
|
|
72
|
+
const emits = defineEmits<{
|
|
73
|
+
select: [option: InputOption | string];
|
|
74
|
+
input: [e: InputEvent];
|
|
75
|
+
}>();
|
|
76
|
+
|
|
77
|
+
const modelValue = defineModel<string[] | null>('modelValue', { default: [] });
|
|
84
78
|
|
|
79
|
+
const inputElement: Ref<HTMLElement | null> = ref(null);
|
|
85
80
|
const isDatalistOpen = ref(false);
|
|
81
|
+
const searching = ref('');
|
|
86
82
|
|
|
87
83
|
const closeDatalist = () => (isDatalistOpen.value = false);
|
|
88
84
|
const openDatalist = () => {
|
|
@@ -91,13 +87,9 @@ const openDatalist = () => {
|
|
|
91
87
|
}
|
|
92
88
|
};
|
|
93
89
|
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
onClickOutside(inputElement, closeDatalist, {
|
|
99
|
-
ignore: ['.datalist-option', '.icon-toggle-button'],
|
|
100
|
-
});
|
|
90
|
+
const onBlur = () => {
|
|
91
|
+
closeDatalist();
|
|
92
|
+
};
|
|
101
93
|
|
|
102
94
|
const onBackspace = () => {
|
|
103
95
|
if (
|
|
@@ -107,6 +99,21 @@ const onBackspace = () => {
|
|
|
107
99
|
)
|
|
108
100
|
modelValue.value.splice(-1);
|
|
109
101
|
};
|
|
102
|
+
onClickOutside(inputElement, closeDatalist, {
|
|
103
|
+
ignore: ['.datalist-option', '.icon-toggle-button'],
|
|
104
|
+
});
|
|
105
|
+
onKeyUp('Escape', closeDatalist);
|
|
106
|
+
onKeyUp('Tab', closeDatalist);
|
|
107
|
+
|
|
108
|
+
onKeyDown('Backspace', onBackspace);
|
|
109
|
+
|
|
110
|
+
const onSelectClick = () => {
|
|
111
|
+
isDatalistOpen.value = !isDatalistOpen.value;
|
|
112
|
+
};
|
|
113
|
+
const onInput = (e: InputEvent) => {
|
|
114
|
+
emits('input', e);
|
|
115
|
+
openDatalist();
|
|
116
|
+
};
|
|
110
117
|
|
|
111
118
|
const setFocus = () => {
|
|
112
119
|
if (inputElement.value) {
|
|
@@ -122,8 +129,8 @@ const onSelect = (option: InputOption | string) => {
|
|
|
122
129
|
}
|
|
123
130
|
|
|
124
131
|
searching.value = '';
|
|
132
|
+
emits('select', option);
|
|
125
133
|
setFocus();
|
|
126
|
-
closeDatalist();
|
|
127
134
|
};
|
|
128
135
|
|
|
129
136
|
const removeOption = (value: string) => {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
v-bind="$props"
|
|
4
4
|
:open="isDatalistOpen"
|
|
5
5
|
@select="onSelect"
|
|
6
|
-
@click="
|
|
6
|
+
@click="onSelectClick"
|
|
7
7
|
>
|
|
8
8
|
<template #input>
|
|
9
9
|
<input
|
|
@@ -15,17 +15,11 @@
|
|
|
15
15
|
:placeholder="placeholder"
|
|
16
16
|
:required="required"
|
|
17
17
|
:disabled="disabled"
|
|
18
|
-
@focus="openDatalist"
|
|
19
|
-
@click="openDatalist"
|
|
20
18
|
@keyup.down="openDatalist"
|
|
21
19
|
/>
|
|
22
20
|
<span class="icon-toggle-container">
|
|
23
|
-
<ChevronUp
|
|
24
|
-
|
|
25
|
-
class="icon-toggle-button"
|
|
26
|
-
@click="closeDatalist"
|
|
27
|
-
/>
|
|
28
|
-
<ChevronDown v-else class="icon-toggle-button" @click="openDatalist" />
|
|
21
|
+
<ChevronUp v-if="isDatalistOpen" class="icon-toggle-button" />
|
|
22
|
+
<ChevronDown v-else class="icon-toggle-button" />
|
|
29
23
|
</span>
|
|
30
24
|
</template>
|
|
31
25
|
</RawSelect>
|
|
@@ -33,12 +27,12 @@
|
|
|
33
27
|
|
|
34
28
|
<script lang="ts" setup>
|
|
35
29
|
import { ChevronDown, ChevronUp } from 'lucide-vue-next';
|
|
36
|
-
import { computed, Ref, ref } from 'vue';
|
|
30
|
+
import { computed, Ref, ref, watch } from 'vue';
|
|
37
31
|
import _ from 'lodash';
|
|
38
32
|
import { InputOption } from '@/models';
|
|
39
33
|
import { FieldComponentProps } from '@/plugins/field/field-component.model';
|
|
40
34
|
import RawSelect from './RawSelect.vue';
|
|
41
|
-
import { onClickOutside } from '@vueuse/core';
|
|
35
|
+
import { onClickOutside, onKeyUp } from '@vueuse/core';
|
|
42
36
|
|
|
43
37
|
export interface Props extends FieldComponentProps {
|
|
44
38
|
options: InputOption[];
|
|
@@ -55,10 +49,13 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
55
49
|
open: false,
|
|
56
50
|
});
|
|
57
51
|
|
|
52
|
+
const emits = defineEmits<{
|
|
53
|
+
select: [value: any];
|
|
54
|
+
}>();
|
|
55
|
+
|
|
58
56
|
const modelValue = defineModel<any>('modelValue', { required: true });
|
|
59
57
|
|
|
60
58
|
const inputElement: Ref<HTMLElement | null> = ref(null);
|
|
61
|
-
|
|
62
59
|
const isDatalistOpen = ref(props.open);
|
|
63
60
|
|
|
64
61
|
const closeDatalist = () => {
|
|
@@ -71,13 +68,11 @@ const openDatalist = () => {
|
|
|
71
68
|
}
|
|
72
69
|
};
|
|
73
70
|
|
|
74
|
-
const emits = defineEmits<{
|
|
75
|
-
select: [value: any];
|
|
76
|
-
}>();
|
|
77
|
-
|
|
78
71
|
onClickOutside(inputElement, closeDatalist, {
|
|
79
72
|
ignore: ['.datalist-option', '.icon-toggle-button'],
|
|
80
73
|
});
|
|
74
|
+
onKeyUp('Escape', closeDatalist);
|
|
75
|
+
onKeyUp('Tab', closeDatalist);
|
|
81
76
|
|
|
82
77
|
const displayValue = computed(() => {
|
|
83
78
|
const option = props.options.find((o) =>
|
|
@@ -100,6 +95,13 @@ const onSelect = (option: any) => {
|
|
|
100
95
|
closeDatalist();
|
|
101
96
|
};
|
|
102
97
|
|
|
98
|
+
const onSelectClick = () => {
|
|
99
|
+
isDatalistOpen.value = !isDatalistOpen.value;
|
|
100
|
+
if (isDatalistOpen) {
|
|
101
|
+
setFocus();
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
103
105
|
defineExpose({
|
|
104
106
|
setFocus,
|
|
105
107
|
});
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
:required="required"
|
|
11
11
|
:small="small"
|
|
12
12
|
@input="onInput"
|
|
13
|
-
@
|
|
13
|
+
@click="onClick"
|
|
14
|
+
@keyup.down="openDatalist"
|
|
14
15
|
>
|
|
15
16
|
<template #icon-start>
|
|
16
17
|
<slot name="icon-start"></slot>
|
|
@@ -58,7 +59,7 @@ import RawInputText from '@/components/form/RawInputText.vue';
|
|
|
58
59
|
import { InputOption, InputType } from '@/models';
|
|
59
60
|
import { ChevronDown, ChevronUp, X } from 'lucide-vue-next';
|
|
60
61
|
import { FieldComponentProps } from '@/plugins/field/field-component.model';
|
|
61
|
-
import { MaybeElementRef, onClickOutside } from '@vueuse/core';
|
|
62
|
+
import { MaybeElementRef, onClickOutside, onKeyUp } from '@vueuse/core';
|
|
62
63
|
|
|
63
64
|
export interface Props extends FieldComponentProps {
|
|
64
65
|
options: InputOption[];
|
|
@@ -82,6 +83,10 @@ const rawInput: Ref<HTMLElement | null> = ref(null);
|
|
|
82
83
|
const emits = defineEmits<{
|
|
83
84
|
addNewOption: [newOption: string];
|
|
84
85
|
select: [option: InputOption];
|
|
86
|
+
blur: [];
|
|
87
|
+
focus: [];
|
|
88
|
+
click: [];
|
|
89
|
+
input: [e: InputEvent];
|
|
85
90
|
}>();
|
|
86
91
|
|
|
87
92
|
const getValidOptionByLabel = (label: string) =>
|
|
@@ -102,6 +107,13 @@ onClickOutside(rawInput as MaybeElementRef, closeDatalist, {
|
|
|
102
107
|
ignore: ['.datalist-option', '.icon-toggle-button', '.icon-clear'],
|
|
103
108
|
});
|
|
104
109
|
|
|
110
|
+
const onBlur = () => {
|
|
111
|
+
emits('blur');
|
|
112
|
+
closeDatalist();
|
|
113
|
+
};
|
|
114
|
+
onKeyUp('Escape', onBlur);
|
|
115
|
+
onKeyUp('Tab', onBlur);
|
|
116
|
+
|
|
105
117
|
const classes = computed(() => {
|
|
106
118
|
return { 'is-error': props.errors?.length, 'is-disabled': props.disabled };
|
|
107
119
|
});
|
|
@@ -148,8 +160,8 @@ watch(
|
|
|
148
160
|
},
|
|
149
161
|
);
|
|
150
162
|
|
|
151
|
-
const
|
|
152
|
-
|
|
163
|
+
const onClick = () => {
|
|
164
|
+
isDatalistOpen.value = !isDatalistOpen.value;
|
|
153
165
|
};
|
|
154
166
|
|
|
155
167
|
const onInput = () => {
|