@ouestfrance/sipa-bms-ui 8.10.1 → 8.12.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/button/BmsButton.vue.d.ts +2 -1
- package/dist/components/button/BmsIconButton.vue.d.ts +3 -1
- package/dist/components/button/UiButton.vue.d.ts +4 -2
- package/dist/components/button/UiButtonLink.vue.d.ts +1 -0
- package/dist/components/feedback/BmsTooltip.vue.d.ts +1 -1
- package/dist/components/feedback/UiTooltip.vue.d.ts +1 -1
- package/dist/components/form/BmsInputText.vue.d.ts +2 -0
- package/dist/components/form/BmsSearch.vue.d.ts +4 -0
- package/dist/components/form/RawAutocomplete.vue.d.ts +2 -0
- package/dist/components/layout/BmsHeaderTitle.vue.d.ts +1 -1
- package/dist/components/layout/UiPopoverMenu.vue.d.ts +1 -1
- package/dist/components/navigation/BmsBreadcrumb.vue.d.ts +1 -1
- package/dist/components/navigation/BmsShortLinkMenu.vue.d.ts +2 -2
- package/dist/components/navigation/UiTenantSwitcher.vue.d.ts +4 -0
- package/dist/components/table/BmsTableFilters.vue.d.ts +4 -0
- package/dist/components/utils/BmsCocarde.vue.d.ts +1 -1
- package/dist/mockServiceWorker.js +2 -1
- package/dist/plugins/field/FieldComponent.vue.d.ts +3 -0
- package/dist/plugins/field/SkeletonField.vue.d.ts +2 -0
- package/dist/plugins/field/field-component.model.d.ts +2 -0
- package/dist/plugins/router-history/router-history.composable.d.ts +1 -1
- package/dist/sipa-bms-ui.css +95 -100
- package/dist/sipa-bms-ui.es.js +4099 -4009
- package/dist/sipa-bms-ui.es.js.map +1 -1
- package/dist/sipa-bms-ui.umd.js +4106 -4016
- package/dist/sipa-bms-ui.umd.js.map +1 -1
- package/package.json +19 -18
- package/src/components/button/BmsButton.stories.js +26 -0
- package/src/components/button/BmsButton.vue +2 -0
- package/src/components/button/BmsIconButton.stories.js +4 -0
- package/src/components/button/BmsIconButton.vue +10 -1
- package/src/components/button/UiButton.vue +2 -0
- package/src/components/button/UiButtonLink.vue +13 -6
- package/src/components/feedback/UiTooltip.vue +1 -0
- package/src/components/form/BmsAutocomplete.stories.js +12 -0
- package/src/components/form/BmsAutocomplete.vue +1 -0
- package/src/components/form/BmsInputText.stories.js +8 -0
- package/src/components/form/BmsInputToggle.stories.js +27 -0
- package/src/components/form/BmsInputToggle.vue +16 -2
- package/src/components/form/BmsMultiSelect.vue +6 -1
- package/src/components/form/BmsSelect.stories.js +9 -0
- package/src/components/form/BmsSelect.vue +31 -65
- package/src/components/form/BmsServerAutocomplete.stories.js +25 -2
- package/src/components/form/BmsServerAutocomplete.vue +1 -0
- package/src/components/form/RawSelect.vue +1 -18
- package/src/components/layout/BmsModal.stories.js +1 -1
- package/src/components/table/BmsServerTable.vue +2 -4
- package/src/plugins/field/FieldComponent.spec.ts +2 -1
- package/src/plugins/field/FieldComponent.stories.js +18 -1
- package/src/plugins/field/FieldComponent.vue +26 -6
- package/src/plugins/field/SkeletonField.stories.js +21 -0
- package/src/plugins/field/SkeletonField.vue +27 -0
- package/src/plugins/field/field-component.model.ts +2 -0
- package/src/showroom/App.vue +5 -0
- package/src/showroom/pages/loading-form.vue +78 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ouestfrance/sipa-bms-ui",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.12.0",
|
|
4
4
|
"author": "Ouest-France BMS",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"scripts": {
|
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
"test:e2e:headless": "START_SERVER_AND_TEST_INSECURE=1 start-server-and-test serve http://localhost:8080 'cypress run'",
|
|
16
16
|
"test:e2e:open": "START_SERVER_AND_TEST_INSECURE=1 start-server-and-test dev:showroom https://localhost:1234 'cypress open'",
|
|
17
17
|
"storybook:dev": "storybook dev -p 6006 --no-open",
|
|
18
|
-
"storybook:build": "storybook build --loglevel warn --quiet",
|
|
18
|
+
"storybook:build": "storybook build --loglevel warn --quiet --stats-json",
|
|
19
|
+
"chromatic:turbosnap": "CHROMATIC_PROJECT_TOKEN=chpt_4854db5bc2ca640 chromatic --allow-console-errors --storybook-build-dir=storybook-static --only-changed",
|
|
19
20
|
"chromatic": "CHROMATIC_PROJECT_TOKEN=chpt_4854db5bc2ca640 chromatic --allow-console-errors --storybook-build-dir=storybook-static",
|
|
20
21
|
"chromatic:dev": "npm run storybook:build && npm run chromatic",
|
|
21
22
|
"chromatic:accept": "npm run chromatic -- --auto-accept-changes",
|
|
@@ -30,15 +31,15 @@
|
|
|
30
31
|
},
|
|
31
32
|
"devDependencies": {
|
|
32
33
|
"@chromatic-com/storybook": "^4.0.0",
|
|
33
|
-
"@codemirror/lang-html": "6.4.
|
|
34
|
+
"@codemirror/lang-html": "6.4.11",
|
|
34
35
|
"@codemirror/lang-json": "6.0.2",
|
|
35
36
|
"@commitlint/cli": "19.8.1",
|
|
36
37
|
"@commitlint/config-conventional": "19.8.1",
|
|
37
38
|
"@formkit/vue": "1.6.9",
|
|
38
39
|
"@mdx-js/react": "3.1.1",
|
|
39
|
-
"@storybook/addon-docs": "9.1.
|
|
40
|
-
"@storybook/addon-links": "9.1.
|
|
41
|
-
"@storybook/vue3-vite": "9.1.
|
|
40
|
+
"@storybook/addon-docs": "9.1.10",
|
|
41
|
+
"@storybook/addon-links": "9.1.10",
|
|
42
|
+
"@storybook/vue3-vite": "9.1.10",
|
|
42
43
|
"@types/lodash": "4.17.20",
|
|
43
44
|
"@types/uuid": "11.0.0",
|
|
44
45
|
"@vitejs/plugin-vue": "6.0.1",
|
|
@@ -47,42 +48,42 @@
|
|
|
47
48
|
"@vueuse/motion": "^3.0.0",
|
|
48
49
|
"axios": "1.12.2",
|
|
49
50
|
"blob-util": "^2.0.2",
|
|
50
|
-
"chromatic": "13.
|
|
51
|
+
"chromatic": "13.3.0",
|
|
51
52
|
"codemirror": "6.0.2",
|
|
52
53
|
"cors": "^2.8.5",
|
|
53
54
|
"cross-env": "^10.0.0",
|
|
54
55
|
"cy2": "^4.0.0",
|
|
55
|
-
"cypress": "15.
|
|
56
|
+
"cypress": "15.4.0",
|
|
56
57
|
"express": "^5.0.0",
|
|
57
58
|
"husky": "9.1.7",
|
|
58
59
|
"jsdom": "27.0.0",
|
|
59
60
|
"keycloak-js": "26.1.2",
|
|
60
|
-
"lint-staged": "16.
|
|
61
|
+
"lint-staged": "16.2.4",
|
|
61
62
|
"lodash": "4.17.21",
|
|
62
|
-
"lucide-vue-next": "0.
|
|
63
|
+
"lucide-vue-next": "0.545.0",
|
|
63
64
|
"msw-storybook-addon": "^2.0.3",
|
|
64
65
|
"normalize.css": "8.0.1",
|
|
65
66
|
"path": "0.12.7",
|
|
66
67
|
"prettier": "3.6.2",
|
|
67
|
-
"sass": "1.93.
|
|
68
|
+
"sass": "1.93.2",
|
|
68
69
|
"semantic-release": "24.2.9",
|
|
69
70
|
"start-server-and-test": "2.1.2",
|
|
70
|
-
"storybook": "9.1.
|
|
71
|
-
"storybook-addon-pseudo-states": "9.1.
|
|
71
|
+
"storybook": "9.1.10",
|
|
72
|
+
"storybook-addon-pseudo-states": "9.1.10",
|
|
72
73
|
"storybook-vue3-router": "^6.0.2",
|
|
73
74
|
"typescript": "5.2.2",
|
|
74
75
|
"uuid": "13.0.0",
|
|
75
|
-
"vite": "7.1.
|
|
76
|
+
"vite": "7.1.10",
|
|
76
77
|
"vite-plugin-dts": "^4.1.0",
|
|
77
|
-
"vite-plugin-mkcert": "1.17.
|
|
78
|
+
"vite-plugin-mkcert": "1.17.9",
|
|
78
79
|
"vite-plugin-pages": "0.33.1",
|
|
79
80
|
"vite-svg-loader": "5.1.0",
|
|
80
81
|
"vitest": "3.2.4",
|
|
81
|
-
"vue": "3.5.
|
|
82
|
+
"vue": "3.5.22",
|
|
82
83
|
"vue-codemirror": "6.1.1",
|
|
83
84
|
"vue-loader": "17.4.2",
|
|
84
|
-
"vue-router": "4.
|
|
85
|
-
"vue-tsc": "3.
|
|
85
|
+
"vue-router": "4.6.0",
|
|
86
|
+
"vue-tsc": "3.1.1"
|
|
86
87
|
},
|
|
87
88
|
"files": [
|
|
88
89
|
"dist",
|
|
@@ -82,3 +82,29 @@ export const Tertiary = Template.bind({});
|
|
|
82
82
|
Tertiary.args = {
|
|
83
83
|
type: 'tertiary',
|
|
84
84
|
};
|
|
85
|
+
|
|
86
|
+
const TemplateSmall = (args) => ({
|
|
87
|
+
components: {
|
|
88
|
+
BmsButton,
|
|
89
|
+
ArrowRight,
|
|
90
|
+
ArrowLeft,
|
|
91
|
+
Camera,
|
|
92
|
+
Heart,
|
|
93
|
+
Wand,
|
|
94
|
+
},
|
|
95
|
+
setup() {
|
|
96
|
+
return { args };
|
|
97
|
+
},
|
|
98
|
+
template: `
|
|
99
|
+
<BmsButton v-bind="args">Save me</BmsButton>
|
|
100
|
+
<br/>
|
|
101
|
+
<br/>
|
|
102
|
+
<BmsButton v-bind="args" small>Save me</BmsButton>
|
|
103
|
+
|
|
104
|
+
`,
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
export const Small = TemplateSmall.bind({});
|
|
108
|
+
Small.args = {
|
|
109
|
+
type: 'primary',
|
|
110
|
+
};
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
:mode="uiMode"
|
|
4
4
|
:color="mode"
|
|
5
5
|
:to="to"
|
|
6
|
+
:small="small"
|
|
6
7
|
:type="submit ? 'submit' : 'button'"
|
|
7
8
|
>
|
|
8
9
|
<template #start>
|
|
@@ -26,6 +27,7 @@ interface Props {
|
|
|
26
27
|
to?: RouteLocationRaw | null;
|
|
27
28
|
mode?: StatusType.Danger | StatusType.Default;
|
|
28
29
|
submit?: boolean;
|
|
30
|
+
small?: boolean;
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
const props = withDefaults(defineProps<Props>(), {
|
|
@@ -38,6 +38,10 @@ const Template = (args) => ({
|
|
|
38
38
|
<br> <b>:hover</b>
|
|
39
39
|
<BmsIconButton v-bind="args" class="_hover"><Heart/></BmsIconButton>
|
|
40
40
|
|
|
41
|
+
<br>
|
|
42
|
+
<br> <b>Small</b>
|
|
43
|
+
<BmsIconButton v-bind="args" small><Heart/></BmsIconButton>
|
|
44
|
+
|
|
41
45
|
|
|
42
46
|
<br> <b>BmsIconButton must be on same alignment (using BmsLink and native button html tag)</b>
|
|
43
47
|
<BmsIconButton
|
|
@@ -4,7 +4,14 @@
|
|
|
4
4
|
:tooltip-text="tooltipText"
|
|
5
5
|
:direction="tooltipDirection"
|
|
6
6
|
>
|
|
7
|
-
<UiButton
|
|
7
|
+
<UiButton
|
|
8
|
+
v-bind="$attrs"
|
|
9
|
+
icon
|
|
10
|
+
:to="to"
|
|
11
|
+
:target="target"
|
|
12
|
+
:color="mode"
|
|
13
|
+
:small="small"
|
|
14
|
+
>
|
|
8
15
|
<slot></slot>
|
|
9
16
|
</UiButton>
|
|
10
17
|
</BmsTooltip>
|
|
@@ -23,11 +30,13 @@ interface Props {
|
|
|
23
30
|
mode?: StatusType.Danger | StatusType.Information;
|
|
24
31
|
tooltipText?: string;
|
|
25
32
|
tooltipDirection?: TooltipDirection;
|
|
33
|
+
small?: boolean;
|
|
26
34
|
}
|
|
27
35
|
const props = withDefaults(defineProps<Props>(), {
|
|
28
36
|
mode: StatusType.Information,
|
|
29
37
|
to: null,
|
|
30
38
|
tooltipText: '',
|
|
39
|
+
small: false,
|
|
31
40
|
});
|
|
32
41
|
|
|
33
42
|
const activated: ComputedRef<boolean> = computed(() => !!props.tooltipText);
|
|
@@ -25,6 +25,7 @@ interface Props {
|
|
|
25
25
|
color?: StatusType;
|
|
26
26
|
mode?: 'fill' | 'ghost' | 'outline';
|
|
27
27
|
icon?: boolean;
|
|
28
|
+
small?: boolean;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
const props = withDefaults(defineProps<Props>(), {
|
|
@@ -33,5 +34,6 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
33
34
|
color: StatusType.Default,
|
|
34
35
|
mode: 'fill',
|
|
35
36
|
icon: false,
|
|
37
|
+
small: false,
|
|
36
38
|
});
|
|
37
39
|
</script>
|
|
@@ -23,6 +23,7 @@ interface Props {
|
|
|
23
23
|
target?: string;
|
|
24
24
|
color: StatusType;
|
|
25
25
|
mode: 'fill' | 'ghost' | 'outline';
|
|
26
|
+
small: boolean;
|
|
26
27
|
icon: boolean;
|
|
27
28
|
}
|
|
28
29
|
|
|
@@ -33,7 +34,7 @@ const classes = computed(() => {
|
|
|
33
34
|
const disabled = attrs && (!!attrs.disabled || attrs.disabled === '');
|
|
34
35
|
return `bms-button is-${props.color}${
|
|
35
36
|
props.icon ? ' is-icon' : ` bms-button--${props.mode}`
|
|
36
|
-
} ${disabled ? ' bms-button--disabled' : ''} `;
|
|
37
|
+
} ${disabled ? ' bms-button--disabled' : ''} ${props.small ? 'bms-button--small' : ''}`;
|
|
37
38
|
});
|
|
38
39
|
</script>
|
|
39
40
|
|
|
@@ -44,8 +45,6 @@ const classes = computed(() => {
|
|
|
44
45
|
|
|
45
46
|
@mixin selectColorsToApply($colorName) {
|
|
46
47
|
&.is-icon {
|
|
47
|
-
padding: 0.5em 0;
|
|
48
|
-
|
|
49
48
|
--bms-button-background-color: transparent;
|
|
50
49
|
--bms-button-border-color: transparent;
|
|
51
50
|
--bms-button-text-color: var(--bms-grey-100);
|
|
@@ -127,14 +126,15 @@ const classes = computed(() => {
|
|
|
127
126
|
}
|
|
128
127
|
|
|
129
128
|
.bms-button {
|
|
130
|
-
height: 2em;
|
|
131
129
|
font-size: 1em;
|
|
132
130
|
|
|
131
|
+
--button-padding: 0.5em;
|
|
132
|
+
|
|
133
133
|
box-sizing: border-box;
|
|
134
134
|
display: inline-flex;
|
|
135
135
|
align-items: center;
|
|
136
136
|
margin: 0;
|
|
137
|
-
padding:
|
|
137
|
+
padding: var(--button-padding);
|
|
138
138
|
appearance: none;
|
|
139
139
|
cursor: pointer;
|
|
140
140
|
border-radius: var(--bms-border-radius);
|
|
@@ -152,7 +152,7 @@ const classes = computed(() => {
|
|
|
152
152
|
@include selectColorsToApply('grey');
|
|
153
153
|
|
|
154
154
|
.content {
|
|
155
|
-
margin: 0
|
|
155
|
+
margin: 0 var(--button-padding);
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
> span {
|
|
@@ -166,6 +166,13 @@ const classes = computed(() => {
|
|
|
166
166
|
width: 1em;
|
|
167
167
|
height: 1em;
|
|
168
168
|
}
|
|
169
|
+
&--small {
|
|
170
|
+
--button-padding: 0.25em;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
&.is-icon {
|
|
174
|
+
padding: var(--button-padding) 0;
|
|
175
|
+
}
|
|
169
176
|
|
|
170
177
|
&.is-default {
|
|
171
178
|
@include selectColorsToApply('main');
|
|
@@ -40,6 +40,18 @@ Default.args = {
|
|
|
40
40
|
modelValue: '',
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
+
export const Loading = Template.bind({});
|
|
44
|
+
Loading.args = {
|
|
45
|
+
label: 'My autocomplete field',
|
|
46
|
+
loading: true,
|
|
47
|
+
options: [
|
|
48
|
+
{ label: 'titi', value: 'i' },
|
|
49
|
+
{ label: 'toto', value: 'o' },
|
|
50
|
+
{ label: 'tutu', value: 'u' },
|
|
51
|
+
],
|
|
52
|
+
modelValue: '',
|
|
53
|
+
};
|
|
54
|
+
|
|
43
55
|
export const WithStringArray = Template.bind({});
|
|
44
56
|
WithStringArray.args = {
|
|
45
57
|
label: 'My autocomplete field',
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
:placeholder="placeholder"
|
|
14
14
|
:can-add-new-option="canAddNewOption"
|
|
15
15
|
:small="small"
|
|
16
|
+
:loading="loading"
|
|
16
17
|
@select="(option: any) => emits('select', option)"
|
|
17
18
|
@add-new-option="(newOption: string) => emits('addNewOption', newOption)"
|
|
18
19
|
@input="(e: InputEvent) => emits('input', e)"
|
|
@@ -45,6 +45,14 @@ Default.args = {
|
|
|
45
45
|
captions: ['There is more information'],
|
|
46
46
|
};
|
|
47
47
|
|
|
48
|
+
export const Loading = Template.bind({});
|
|
49
|
+
Loading.args = {
|
|
50
|
+
label: 'My label',
|
|
51
|
+
placeholder: 'Placeholder',
|
|
52
|
+
captions: ['There is more information'],
|
|
53
|
+
loading: true,
|
|
54
|
+
};
|
|
55
|
+
|
|
48
56
|
export const WithValue = Template.bind({});
|
|
49
57
|
WithValue.args = {
|
|
50
58
|
label: 'My label',
|
|
@@ -38,3 +38,30 @@ On.args = { label: 'Label', modelValue: true, name: 'my-input' };
|
|
|
38
38
|
|
|
39
39
|
export const Off = Template.bind({});
|
|
40
40
|
Off.args = { label: 'Label', modelValue: false, name: 'my-input' };
|
|
41
|
+
|
|
42
|
+
const TemplateOverflow = (args) => ({
|
|
43
|
+
setup() {
|
|
44
|
+
const curentValue = ref(args.modelValue);
|
|
45
|
+
return { args, curentValue };
|
|
46
|
+
},
|
|
47
|
+
components: {
|
|
48
|
+
BmsInputToggle,
|
|
49
|
+
},
|
|
50
|
+
template: `
|
|
51
|
+
<div style="width: 200px; border: 1px solid black;">
|
|
52
|
+
<BmsInputToggle v-bind="{...args}" v-model="curentValue"/>
|
|
53
|
+
</div>
|
|
54
|
+
`,
|
|
55
|
+
});
|
|
56
|
+
export const Overflow = TemplateOverflow.bind({});
|
|
57
|
+
Overflow.args = {
|
|
58
|
+
label: 'with a very long label that overflows',
|
|
59
|
+
name: 'my-input',
|
|
60
|
+
ellipsisLabel: true,
|
|
61
|
+
};
|
|
62
|
+
export const NoOverflow = TemplateOverflow.bind({});
|
|
63
|
+
NoOverflow.args = {
|
|
64
|
+
label: 'with a very long label that overflows',
|
|
65
|
+
name: 'my-input',
|
|
66
|
+
ellipsisLabel: false,
|
|
67
|
+
};
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<field :disabled="disabled" :small="small">
|
|
3
|
-
<label
|
|
2
|
+
<field :disabled="disabled" :small="small" :ellipsisLabel="ellipsisLabel">
|
|
3
|
+
<label
|
|
4
|
+
class="input-toggle"
|
|
5
|
+
:class="{ isOn: modelValue, disabled, overflow: ellipsisLabel }"
|
|
6
|
+
>
|
|
4
7
|
<span class="input-switch-info">{{ label }}</span>
|
|
5
8
|
<UiBmsSwitch
|
|
6
9
|
:modelValue="modelValue"
|
|
@@ -43,6 +46,17 @@ defineEmits<{
|
|
|
43
46
|
align-items: center;
|
|
44
47
|
gap: 0.5em;
|
|
45
48
|
|
|
49
|
+
&.overflow {
|
|
50
|
+
width: 100%;
|
|
51
|
+
.input-switch-info {
|
|
52
|
+
width: 100%;
|
|
53
|
+
white-space: nowrap;
|
|
54
|
+
overflow: hidden;
|
|
55
|
+
word-break: break-all;
|
|
56
|
+
text-overflow: ellipsis;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
46
60
|
.input-switch-info {
|
|
47
61
|
color: var(--label-color);
|
|
48
62
|
transition: 0.2s;
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
ref="inputElement"
|
|
24
24
|
v-model="searching"
|
|
25
25
|
class="search"
|
|
26
|
+
:disabled="disabled"
|
|
26
27
|
@focus="openDatalist"
|
|
27
28
|
@click="openDatalist"
|
|
28
29
|
@keyup.down="openDatalist"
|
|
@@ -84,7 +85,11 @@ const inputElement: Ref<HTMLElement | null> = ref(null);
|
|
|
84
85
|
const isDatalistOpen = ref(false);
|
|
85
86
|
|
|
86
87
|
const closeDatalist = () => (isDatalistOpen.value = false);
|
|
87
|
-
const openDatalist = () =>
|
|
88
|
+
const openDatalist = () => {
|
|
89
|
+
if (!props.disabled) {
|
|
90
|
+
isDatalistOpen.value = true;
|
|
91
|
+
}
|
|
92
|
+
};
|
|
88
93
|
|
|
89
94
|
const searching = ref('');
|
|
90
95
|
|
|
@@ -39,6 +39,15 @@ Default.args = {
|
|
|
39
39
|
],
|
|
40
40
|
};
|
|
41
41
|
|
|
42
|
+
export const Loading = Template.bind({});
|
|
43
|
+
Loading.args = {
|
|
44
|
+
label: 'My label',
|
|
45
|
+
captions: ['Helping text'],
|
|
46
|
+
loading: true,
|
|
47
|
+
modelValue: '',
|
|
48
|
+
options: [],
|
|
49
|
+
};
|
|
50
|
+
|
|
42
51
|
export const WithPlaceholder = Template.bind({});
|
|
43
52
|
WithPlaceholder.args = {
|
|
44
53
|
label: 'My label',
|
|
@@ -64,8 +64,10 @@ const closeDatalist = () => {
|
|
|
64
64
|
isDatalistOpen.value = false;
|
|
65
65
|
};
|
|
66
66
|
const openDatalist = () => {
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
if (!props.disabled) {
|
|
68
|
+
isDatalistOpen.value = true;
|
|
69
|
+
setFocus();
|
|
70
|
+
}
|
|
69
71
|
};
|
|
70
72
|
|
|
71
73
|
const emits = defineEmits<{
|
|
@@ -104,74 +106,38 @@ defineExpose({
|
|
|
104
106
|
|
|
105
107
|
<style lang="scss" scoped>
|
|
106
108
|
.field__input {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
109
|
+
.icon-toggle {
|
|
110
|
+
&-container {
|
|
111
|
+
height: 100%;
|
|
112
|
+
display: flex;
|
|
113
|
+
align-items: center;
|
|
110
114
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
padding: 0 0 0 1em;
|
|
114
|
-
border-radius: var(--bms-border-radius);
|
|
115
|
-
border: 1px solid var(--field-border-color);
|
|
116
|
-
background-color: var(--input-background-color);
|
|
117
|
-
min-height: var(--field-height);
|
|
118
|
-
|
|
119
|
-
display: flex;
|
|
120
|
-
align-items: center;
|
|
121
|
-
justify-content: space-between;
|
|
122
|
-
|
|
123
|
-
.icon-toggle {
|
|
124
|
-
&-container {
|
|
125
|
-
height: 100%;
|
|
126
|
-
display: flex;
|
|
127
|
-
align-items: center;
|
|
128
|
-
|
|
129
|
-
&:hover {
|
|
130
|
-
cursor: pointer;
|
|
131
|
-
}
|
|
115
|
+
&:hover {
|
|
116
|
+
cursor: pointer;
|
|
132
117
|
}
|
|
133
|
-
&-button {
|
|
134
|
-
width: 1em;
|
|
135
|
-
margin: 0 var(--field-padding);
|
|
136
|
-
display: block;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
&:hover {
|
|
141
|
-
--field-border-color: var(--bms-grey-100);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
&:has(input:focus) {
|
|
145
|
-
--field-border-color: var(--field-border-color-active);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
&.is-error {
|
|
149
|
-
--field-border-color: var(--bms-red-100);
|
|
150
|
-
--input-background-color: var(--bms-red-25);
|
|
151
118
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
pointer-events: none;
|
|
119
|
+
&-button {
|
|
120
|
+
width: 1em;
|
|
121
|
+
margin: 0 var(--field-padding);
|
|
122
|
+
display: block;
|
|
157
123
|
}
|
|
124
|
+
}
|
|
158
125
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
126
|
+
input {
|
|
127
|
+
border: none;
|
|
128
|
+
background-color: transparent;
|
|
129
|
+
caret-color: transparent;
|
|
130
|
+
cursor: pointer;
|
|
131
|
+
outline: none;
|
|
132
|
+
appearance: none;
|
|
133
|
+
margin: 0;
|
|
134
|
+
padding: 0;
|
|
135
|
+
font: inherit;
|
|
136
|
+
color: inherit;
|
|
137
|
+
height: 24px;
|
|
138
|
+
line-height: 1;
|
|
139
|
+
width: 100%;
|
|
140
|
+
height: 100%;
|
|
175
141
|
}
|
|
176
142
|
}
|
|
177
143
|
</style>
|
|
@@ -34,8 +34,8 @@ const Template = (args) => ({
|
|
|
34
34
|
return { args };
|
|
35
35
|
},
|
|
36
36
|
template: `
|
|
37
|
-
<BmsServerAutocomplete v-bind="args"
|
|
38
|
-
|
|
37
|
+
<BmsServerAutocomplete v-bind="args"/>
|
|
38
|
+
<BmsServerAutocomplete v-bind="args" small/>
|
|
39
39
|
`,
|
|
40
40
|
});
|
|
41
41
|
|
|
@@ -51,6 +51,29 @@ Default.args = {
|
|
|
51
51
|
url: 'https://fakeapi.com/items',
|
|
52
52
|
};
|
|
53
53
|
|
|
54
|
+
export const Disabled = Template.bind({});
|
|
55
|
+
Disabled.args = {
|
|
56
|
+
label: 'My autocomplete field',
|
|
57
|
+
modelValue: '',
|
|
58
|
+
disabled: true,
|
|
59
|
+
request: Promise.resolve([]),
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export const Loading = Template.bind({});
|
|
63
|
+
Loading.args = {
|
|
64
|
+
label: 'My autocomplete field',
|
|
65
|
+
modelValue: '',
|
|
66
|
+
request: () => {
|
|
67
|
+
return new Promise((resolve) =>
|
|
68
|
+
setTimeout(() => {
|
|
69
|
+
resolve({
|
|
70
|
+
data: [],
|
|
71
|
+
});
|
|
72
|
+
}, 10000),
|
|
73
|
+
);
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
|
|
54
77
|
export const WithRequest = Template.bind({});
|
|
55
78
|
WithRequest.args = {
|
|
56
79
|
label: 'My autocomplete field',
|
|
@@ -61,7 +61,7 @@ const selectItem = (option: any) => {
|
|
|
61
61
|
|
|
62
62
|
.select-wrapper {
|
|
63
63
|
width: 100%;
|
|
64
|
-
padding: 0 0 0
|
|
64
|
+
padding: 0 0 0 var(--field-padding);
|
|
65
65
|
border-radius: var(--bms-border-radius);
|
|
66
66
|
border: 1px solid var(--field-border-color);
|
|
67
67
|
background-color: var(--input-background-color);
|
|
@@ -71,23 +71,6 @@ const selectItem = (option: any) => {
|
|
|
71
71
|
align-items: center;
|
|
72
72
|
justify-content: space-between;
|
|
73
73
|
|
|
74
|
-
.icon-down {
|
|
75
|
-
&-container {
|
|
76
|
-
height: 100%;
|
|
77
|
-
display: flex;
|
|
78
|
-
align-items: center;
|
|
79
|
-
|
|
80
|
-
&:hover {
|
|
81
|
-
cursor: pointer;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
&-button {
|
|
85
|
-
width: 1em;
|
|
86
|
-
margin: 0 var(--field-padding);
|
|
87
|
-
display: block;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
74
|
&:hover {
|
|
92
75
|
--field-border-color: var(--bms-grey-100);
|
|
93
76
|
}
|
|
@@ -246,7 +246,6 @@ async function fetchData() {
|
|
|
246
246
|
}
|
|
247
247
|
controller.value = new AbortController();
|
|
248
248
|
loading.value = true;
|
|
249
|
-
|
|
250
249
|
try {
|
|
251
250
|
const { data, total: totalItems } = await props.request(
|
|
252
251
|
{
|
|
@@ -260,11 +259,8 @@ async function fetchData() {
|
|
|
260
259
|
controller.value,
|
|
261
260
|
props.url,
|
|
262
261
|
);
|
|
263
|
-
|
|
264
262
|
items.value = data;
|
|
265
263
|
total.value = totalItems;
|
|
266
|
-
|
|
267
|
-
loading.value = false;
|
|
268
264
|
} catch (error) {
|
|
269
265
|
if (
|
|
270
266
|
!(error instanceof CanceledError) &&
|
|
@@ -272,6 +268,8 @@ async function fetchData() {
|
|
|
272
268
|
) {
|
|
273
269
|
throw error;
|
|
274
270
|
}
|
|
271
|
+
} finally {
|
|
272
|
+
loading.value = false;
|
|
275
273
|
}
|
|
276
274
|
}
|
|
277
275
|
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import FieldComponent from '@/plugins/field/FieldComponent.vue';
|
|
2
2
|
import { mount, shallowMount } from '@vue/test-utils';
|
|
3
3
|
import { BmsCaption } from '@/index';
|
|
4
|
+
import { nextTick } from 'vue';
|
|
4
5
|
|
|
5
6
|
describe('FieldComponent', () => {
|
|
6
7
|
it('should display label', async () => {
|
|
7
|
-
const wrapper =
|
|
8
|
+
const wrapper = mount(FieldComponent, {
|
|
8
9
|
slots: {
|
|
9
10
|
default: '<input type="text" />',
|
|
10
11
|
},
|