@mozaic-ds/vue 1.0.0-beta.1 → 1.0.0-beta.4
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/LICENSE +51 -0
- package/README.md +218 -84
- package/dist/mozaic-vue.css +1 -1
- package/dist/mozaic-vue.d.ts +920 -0
- package/dist/mozaic-vue.js +877 -0
- package/dist/mozaic-vue.js.map +1 -0
- package/dist/mozaic-vue.umd.cjs +2 -0
- package/dist/mozaic-vue.umd.cjs.map +1 -0
- package/env.d.ts +1 -0
- package/package.json +80 -50
- package/src/components/Contributing.mdx +118 -0
- package/src/components/GettingStarted.mdx +39 -0
- package/src/components/Introduction.mdx +54 -0
- package/src/components/Support.mdx +18 -0
- package/src/components/badge/MBadge.spec.ts +16 -0
- package/src/components/badge/MBadge.stories.ts +50 -0
- package/src/components/badge/MBadge.vue +36 -34
- package/src/components/button/MButton.spec.ts +191 -0
- package/src/components/button/MButton.stories.ts +66 -0
- package/src/components/button/MButton.vue +98 -154
- package/src/components/checkbox/MCheckbox.spec.ts +104 -0
- package/src/components/checkbox/MCheckbox.stories.ts +83 -0
- package/src/components/checkbox/MCheckbox.vue +60 -101
- package/src/components/checkboxgroup/MCheckboxGroup.spec.ts +78 -0
- package/src/components/checkboxgroup/MCheckboxGroup.stories.ts +61 -0
- package/src/components/checkboxgroup/MCheckboxGroup.vue +97 -0
- package/src/components/field/MField.spec.ts +166 -0
- package/src/components/field/MField.stories.ts +376 -0
- package/src/components/field/MField.vue +78 -61
- package/src/components/fieldgroup/MFieldGroup.spec.ts +165 -0
- package/src/components/fieldgroup/MFieldGroup.stories.ts +274 -0
- package/src/components/fieldgroup/MFieldGroup.vue +79 -0
- package/src/components/iconbutton/MIconButton.spec.ts +108 -0
- package/src/components/iconbutton/MIconButton.stories.ts +66 -0
- package/src/components/iconbutton/MIconButton.vue +73 -0
- package/src/components/link/MLink.spec.ts +154 -0
- package/src/components/link/MLink.stories.ts +98 -0
- package/src/components/link/MLink.vue +86 -109
- package/src/components/loader/MLoader.spec.ts +104 -0
- package/src/components/loader/MLoader.stories.ts +45 -0
- package/src/components/loader/MLoader.vue +65 -55
- package/src/components/overlay/MOverlay.spec.ts +51 -0
- package/src/components/overlay/MOverlay.stories.ts +40 -0
- package/src/components/overlay/MOverlay.vue +27 -19
- package/src/components/quantityselector/MQuantitySelector.spec.ts +262 -0
- package/src/components/quantityselector/MQuantitySelector.stories.ts +89 -0
- package/src/components/quantityselector/MQuantitySelector.vue +160 -136
- package/src/components/radio/MRadio.spec.ts +104 -0
- package/src/components/radio/MRadio.stories.ts +68 -0
- package/src/components/radio/MRadio.vue +56 -39
- package/src/components/radiogroup/MRadioGroup.spec.ts +54 -0
- package/src/components/radiogroup/MRadioGroup.stories.ts +61 -0
- package/src/components/radiogroup/MRadioGroup.vue +79 -0
- package/src/components/select/MSelect.spec.ts +114 -0
- package/src/components/select/MSelect.stories.ts +101 -0
- package/src/components/select/MSelect.vue +77 -119
- package/src/components/statusbadge/MStatusBadge.stories.ts +45 -0
- package/src/components/statusbadge/MStatusBadge.vue +40 -0
- package/src/components/statusbadge/MStatusDot.vue +32 -0
- package/src/components/statusbadge/MstatusBadge.spec.ts +16 -0
- package/src/components/textarea/MTextArea.spec.ts +112 -0
- package/src/components/textarea/MTextArea.stories.ts +67 -0
- package/src/components/textarea/MTextArea.vue +81 -42
- package/src/components/textinput/MTextInput.spec.ts +121 -0
- package/src/components/textinput/MTextInput.stories.ts +114 -0
- package/src/components/textinput/MTextInput.vue +127 -47
- package/src/components/toggle/MToggle.spec.ts +99 -0
- package/src/components/toggle/MToggle.stories.ts +68 -0
- package/src/components/toggle/MToggle.vue +63 -103
- package/src/components/usingIcons.mdx +43 -0
- package/src/components/usingPresets.mdx +125 -0
- package/src/main.ts +39 -0
- package/dist/demo.html +0 -1
- package/dist/mozaic-vue.adeo.css +0 -45
- package/dist/mozaic-vue.adeo.umd.js +0 -41775
- package/dist/mozaic-vue.common.js +0 -41765
- package/dist/mozaic-vue.common.js.map +0 -1
- package/dist/mozaic-vue.umd.js +0 -41776
- package/dist/mozaic-vue.umd.js.map +0 -1
- package/dist/mozaic-vue.umd.min.js +0 -4
- package/dist/mozaic-vue.umd.min.js.map +0 -1
- package/postinstall.js +0 -3
- package/src/components/accordion/MAccordion.vue +0 -128
- package/src/components/accordion/index.js +0 -7
- package/src/components/autocomplete/MAutocomplete.vue +0 -198
- package/src/components/autocomplete/index.js +0 -7
- package/src/components/badge/index.js +0 -7
- package/src/components/breadcrumb/MBreadcrumb.vue +0 -73
- package/src/components/breadcrumb/index.js +0 -7
- package/src/components/button/index.js +0 -7
- package/src/components/card/MCard.vue +0 -78
- package/src/components/card/index.js +0 -7
- package/src/components/checkbox/MCheckboxGroup.vue +0 -155
- package/src/components/checkbox/index.js +0 -12
- package/src/components/container/MContainer.vue +0 -33
- package/src/components/container/index.js +0 -7
- package/src/components/datatable/MDataTable.vue +0 -651
- package/src/components/datatable/MDataTableHeader.vue +0 -55
- package/src/components/datatable/MDataTableTop.vue +0 -35
- package/src/components/datatable/helpers.js +0 -132
- package/src/components/datatable/index.js +0 -12
- package/src/components/field/index.js +0 -7
- package/src/components/fileuploader/MFileResult.vue +0 -149
- package/src/components/fileuploader/MFileUploader.vue +0 -142
- package/src/components/fileuploader/index.js +0 -7
- package/src/components/flag/MFlag.vue +0 -46
- package/src/components/flag/index.js +0 -7
- package/src/components/heading/MHeading.vue +0 -75
- package/src/components/heading/index.js +0 -7
- package/src/components/hero/MHero.vue +0 -93
- package/src/components/hero/index.js +0 -7
- package/src/components/icon/MIcon.vue +0 -120
- package/src/components/icon/index.js +0 -7
- package/src/components/index.js +0 -43
- package/src/components/layer/MLayer.vue +0 -208
- package/src/components/layer/index.js +0 -7
- package/src/components/link/index.js +0 -7
- package/src/components/listbox/MListBox.vue +0 -106
- package/src/components/listbox/index.js +0 -7
- package/src/components/loader/index.js +0 -7
- package/src/components/modal/MModal.vue +0 -179
- package/src/components/modal/index.js +0 -7
- package/src/components/notification/MNotification.vue +0 -110
- package/src/components/notification/index.js +0 -7
- package/src/components/optionbutton/MOptionButton.vue +0 -67
- package/src/components/optionbutton/index.js +0 -7
- package/src/components/optioncard/MOptionCard.vue +0 -132
- package/src/components/optioncard/index.js +0 -7
- package/src/components/optiongroup/MOptionGroup.vue +0 -18
- package/src/components/optiongroup/index.js +0 -7
- package/src/components/overlay/MOverlayLoader.vue +0 -43
- package/src/components/overlay/index.js +0 -12
- package/src/components/pagination/MPagination.vue +0 -162
- package/src/components/pagination/index.js +0 -7
- package/src/components/passwordinput/MPasswordInput.vue +0 -96
- package/src/components/passwordinput/index.js +0 -7
- package/src/components/phonenumber/MPhoneNumber.vue +0 -390
- package/src/components/phonenumber/index.js +0 -7
- package/src/components/progressbar/MProgress.vue +0 -102
- package/src/components/progressbar/index.js +0 -7
- package/src/components/quantityselector/index.js +0 -7
- package/src/components/radio/MRadioGroup.vue +0 -111
- package/src/components/radio/index.js +0 -12
- package/src/components/ratingstars/MStarsInput.vue +0 -118
- package/src/components/ratingstars/MStarsResult.vue +0 -89
- package/src/components/ratingstars/index.js +0 -12
- package/src/components/select/index.js +0 -7
- package/src/components/stepper/MStepper.vue +0 -70
- package/src/components/stepper/index.js +0 -7
- package/src/components/tabs/MTab.vue +0 -184
- package/src/components/tabs/index.js +0 -7
- package/src/components/tags/MTag.vue +0 -173
- package/src/components/tags/index.js +0 -7
- package/src/components/textarea/index.js +0 -7
- package/src/components/textinput/MTextInputField.vue +0 -105
- package/src/components/textinput/MTextInputIcon.vue +0 -42
- package/src/components/textinput/index.js +0 -7
- package/src/components/toggle/index.js +0 -7
- package/src/components/tooltip/MTooltip.vue +0 -42
- package/src/components/tooltip/index.js +0 -7
- package/src/index.js +0 -62
- package/src/shims-tsx.d.ts +0 -13
- package/src/shims.vue.d.ts +0 -4
- package/src/tokens/adeo/android/colors.xml +0 -391
- package/src/tokens/adeo/android/font_dimens.xml +0 -18
- package/src/tokens/adeo/css/_variables.scss +0 -385
- package/src/tokens/adeo/css/root.scss +0 -387
- package/src/tokens/adeo/ios/StyleDictionaryColor.h +0 -399
- package/src/tokens/adeo/ios/StyleDictionaryColor.m +0 -411
- package/src/tokens/adeo/ios/StyleDictionaryColor.swift +0 -394
- package/src/tokens/adeo/ios/StyleDictionarySize.h +0 -69
- package/src/tokens/adeo/ios/StyleDictionarySize.m +0 -70
- package/src/tokens/adeo/ios/StyleDictionarySize.swift +0 -71
- package/src/tokens/adeo/js/tokens.js +0 -483
- package/src/tokens/adeo/js/tokensObject.js +0 -10354
- package/src/tokens/adeo/scss/_tokens.scss +0 -1300
- package/src/utils/mozaicClasses.js +0 -16
- package/src/utils/theme.validator.js +0 -19
- package/types/index.d.ts +0 -100
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3';
|
|
2
|
+
import { action } from '@storybook/addon-actions';
|
|
3
|
+
|
|
4
|
+
import MFieldGroup from './MFieldGroup.vue';
|
|
5
|
+
import MCheckboxGroup from '../checkboxgroup/MCheckboxGroup.vue';
|
|
6
|
+
import MRadioGroup from '../radiogroup/MRadioGroup.vue';
|
|
7
|
+
|
|
8
|
+
const meta: Meta<typeof MFieldGroup> = {
|
|
9
|
+
title: 'Form Elements/Field Group',
|
|
10
|
+
component: MFieldGroup,
|
|
11
|
+
parameters: {
|
|
12
|
+
docs: {
|
|
13
|
+
description: {
|
|
14
|
+
component:
|
|
15
|
+
'the Field Group component creates a structured form field for group field such as Radio Group, Checkbox Group or Toggle Group with a label, optional help text, error and validation message handling.',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
args: {
|
|
20
|
+
legend: 'Label',
|
|
21
|
+
id: 'ReplaceByInputId',
|
|
22
|
+
requirementText: 'required',
|
|
23
|
+
helpText: 'Help text',
|
|
24
|
+
default: `
|
|
25
|
+
<MCheckboxGroup
|
|
26
|
+
name="checkboxGroupName"
|
|
27
|
+
:options="
|
|
28
|
+
[
|
|
29
|
+
{
|
|
30
|
+
id: 'checkbox-01',
|
|
31
|
+
label: 'checkbox Label',
|
|
32
|
+
value: 'checkbox1',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: 'checkbox-02',
|
|
36
|
+
label: 'checkbox Label',
|
|
37
|
+
value: 'checkbox2',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
id: 'checkbox-03',
|
|
41
|
+
label: 'checkbox Label',
|
|
42
|
+
value: 'checkbox3',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: 'checkbox-04',
|
|
46
|
+
label: 'checkbox Label',
|
|
47
|
+
value: 'checkbox4',
|
|
48
|
+
},
|
|
49
|
+
]
|
|
50
|
+
"
|
|
51
|
+
@update:modelValue="handleUpdate"
|
|
52
|
+
/>
|
|
53
|
+
`,
|
|
54
|
+
},
|
|
55
|
+
argTypes: {
|
|
56
|
+
$slots: {
|
|
57
|
+
table: {
|
|
58
|
+
disable: true,
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
render: (args) => ({
|
|
63
|
+
components: { MFieldGroup, MCheckboxGroup, MRadioGroup },
|
|
64
|
+
setup() {
|
|
65
|
+
const handleUpdate = action('update:modelValue');
|
|
66
|
+
|
|
67
|
+
return { args, handleUpdate };
|
|
68
|
+
},
|
|
69
|
+
template: `
|
|
70
|
+
<MFieldGroup v-bind="args">
|
|
71
|
+
${args.default}
|
|
72
|
+
</MFieldGroup>
|
|
73
|
+
`,
|
|
74
|
+
}),
|
|
75
|
+
};
|
|
76
|
+
export default meta;
|
|
77
|
+
type Story = StoryObj<typeof MFieldGroup>;
|
|
78
|
+
|
|
79
|
+
export const Default: Story = {
|
|
80
|
+
args: {
|
|
81
|
+
legend: 'Label',
|
|
82
|
+
id: 'ReplaceByInputId',
|
|
83
|
+
helpText: 'Help text',
|
|
84
|
+
requirementText: 'optional',
|
|
85
|
+
default: `
|
|
86
|
+
<!-- All the code below must be replaced by a form element. -->
|
|
87
|
+
<div class="content-slot">
|
|
88
|
+
Insert a form element here to replace this slot.
|
|
89
|
+
</div>
|
|
90
|
+
`,
|
|
91
|
+
},
|
|
92
|
+
render: (args) => ({
|
|
93
|
+
components: { MFieldGroup },
|
|
94
|
+
setup() {
|
|
95
|
+
return { args };
|
|
96
|
+
},
|
|
97
|
+
template: `
|
|
98
|
+
<MFieldGroup v-bind="args">
|
|
99
|
+
${args.default}
|
|
100
|
+
</MFieldGroup>
|
|
101
|
+
`,
|
|
102
|
+
}),
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
export const CheckboxGroup: Story = {};
|
|
106
|
+
|
|
107
|
+
export const CheckboxGroupValid: Story = {
|
|
108
|
+
args: {
|
|
109
|
+
legend: 'Label',
|
|
110
|
+
id: 'ReplaceByInputId',
|
|
111
|
+
requirementText: 'required',
|
|
112
|
+
isValid: true,
|
|
113
|
+
message: 'Validation message (Be concise and use comprehensive words).',
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
export const CheckboxGroupInvalid: Story = {
|
|
118
|
+
args: {
|
|
119
|
+
legend: 'Label',
|
|
120
|
+
id: 'ReplaceByInputId',
|
|
121
|
+
requirementText: 'required',
|
|
122
|
+
isInvalid: true,
|
|
123
|
+
message: 'Error message (Be concise and use comprehensive words)',
|
|
124
|
+
default: `
|
|
125
|
+
<MCheckboxGroup
|
|
126
|
+
name="checkboxGroupName"
|
|
127
|
+
isInvalid
|
|
128
|
+
:options="
|
|
129
|
+
[
|
|
130
|
+
{
|
|
131
|
+
id: 'checkbox-01',
|
|
132
|
+
label: 'checkbox Label',
|
|
133
|
+
value: 'checkbox1',
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
id: 'checkbox-02',
|
|
137
|
+
label: 'checkbox Label',
|
|
138
|
+
value: 'checkbox2',
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
id: 'checkbox-03',
|
|
142
|
+
label: 'checkbox Label',
|
|
143
|
+
value: 'checkbox3',
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
id: 'checkbox-04',
|
|
147
|
+
label: 'checkbox Label',
|
|
148
|
+
value: 'checkbox4',
|
|
149
|
+
},
|
|
150
|
+
]
|
|
151
|
+
"
|
|
152
|
+
@update:modelValue="handleUpdate"
|
|
153
|
+
/>
|
|
154
|
+
`,
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
export const RadioGroup: Story = {
|
|
159
|
+
args: {
|
|
160
|
+
legend: 'Label',
|
|
161
|
+
id: 'ReplaceByInputId',
|
|
162
|
+
default: `
|
|
163
|
+
<MRadioGroup
|
|
164
|
+
name="radioGroupName"
|
|
165
|
+
:options="
|
|
166
|
+
[
|
|
167
|
+
{
|
|
168
|
+
id: 'radio-01',
|
|
169
|
+
label: 'Radio button Label',
|
|
170
|
+
value: 'radio1'
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
id: 'radio-02',
|
|
174
|
+
label: 'Radio button Label',
|
|
175
|
+
value: 'radio2'
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
id: 'radio-03',
|
|
179
|
+
label: 'Radio button Label',
|
|
180
|
+
value: 'radio3'
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
id: 'radio-04',
|
|
184
|
+
label: 'Radio button Label',
|
|
185
|
+
value: 'radio4'
|
|
186
|
+
}
|
|
187
|
+
]
|
|
188
|
+
"
|
|
189
|
+
@update:modelValue="handleUpdate"
|
|
190
|
+
/>
|
|
191
|
+
`,
|
|
192
|
+
},
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
export const RadioGroupValid: Story = {
|
|
196
|
+
args: {
|
|
197
|
+
legend: 'Label',
|
|
198
|
+
id: 'ReplaceByInputId',
|
|
199
|
+
requirementText: 'required',
|
|
200
|
+
isValid: true,
|
|
201
|
+
message: 'Validation message (Be concise and use comprehensive words).',
|
|
202
|
+
default: `
|
|
203
|
+
<MRadioGroup
|
|
204
|
+
name="radioGroupValidName"
|
|
205
|
+
:options="
|
|
206
|
+
[
|
|
207
|
+
{
|
|
208
|
+
id: 'radio01',
|
|
209
|
+
label: 'Radio button Label',
|
|
210
|
+
value: 'radio1'
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
id: 'radio02',
|
|
214
|
+
label: 'Radio button Label',
|
|
215
|
+
value: 'radio2'
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
id: 'radio03',
|
|
219
|
+
label: 'Radio button Label',
|
|
220
|
+
value: 'radio3'
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
id: 'radio04',
|
|
224
|
+
label: 'Radio button Label',
|
|
225
|
+
value: 'radio4'
|
|
226
|
+
}
|
|
227
|
+
]
|
|
228
|
+
"
|
|
229
|
+
@update:modelValue="handleUpdate"
|
|
230
|
+
/>
|
|
231
|
+
`,
|
|
232
|
+
},
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
export const RadioGroupInvalid: Story = {
|
|
236
|
+
args: {
|
|
237
|
+
legend: 'Label',
|
|
238
|
+
id: 'ReplaceByInputId',
|
|
239
|
+
requirementText: 'required',
|
|
240
|
+
isInvalid: true,
|
|
241
|
+
message: 'Error message (Be concise and use comprehensive words)',
|
|
242
|
+
default: `
|
|
243
|
+
<MRadioGroup
|
|
244
|
+
name="radioGroupInvalidName"
|
|
245
|
+
isInvalid
|
|
246
|
+
:options="
|
|
247
|
+
[
|
|
248
|
+
{
|
|
249
|
+
id: 'radio-1',
|
|
250
|
+
label: 'Radio button Label',
|
|
251
|
+
value: 'radio1'
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
id: 'radio-2',
|
|
255
|
+
label: 'Radio button Label',
|
|
256
|
+
value: 'radio2'
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
id: 'radio-3',
|
|
260
|
+
label: 'Radio button Label',
|
|
261
|
+
value: 'radio3'
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
id: 'radio-4',
|
|
265
|
+
label: 'Radio button Label',
|
|
266
|
+
value: 'radio4'
|
|
267
|
+
}
|
|
268
|
+
]
|
|
269
|
+
"
|
|
270
|
+
@update:modelValue="handleUpdate"
|
|
271
|
+
/>
|
|
272
|
+
`,
|
|
273
|
+
},
|
|
274
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<fieldset class="mc-field--group">
|
|
3
|
+
<legend class="mc-field__legend" :for="id">
|
|
4
|
+
{{ legend }}
|
|
5
|
+
<span v-if="requirementText" class="mc-field__requirement"
|
|
6
|
+
>({{ requirementText }})</span
|
|
7
|
+
>
|
|
8
|
+
</legend>
|
|
9
|
+
|
|
10
|
+
<span v-if="helpText" class="mc-field__help">{{ helpText }}</span>
|
|
11
|
+
|
|
12
|
+
<div class="mc-field__content">
|
|
13
|
+
<slot />
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<span
|
|
17
|
+
v-if="(isValid || isInvalid) && message"
|
|
18
|
+
class="mc-field__validation-message"
|
|
19
|
+
:class="classObjectValidation"
|
|
20
|
+
>
|
|
21
|
+
{{ message }}
|
|
22
|
+
</span>
|
|
23
|
+
</fieldset>
|
|
24
|
+
</template>
|
|
25
|
+
|
|
26
|
+
<script setup lang="ts">
|
|
27
|
+
import { computed, type VNode } from 'vue';
|
|
28
|
+
/**
|
|
29
|
+
* This component creates a structured form field for group field such as Radio Group, Checkbox Group or Toggle Group with a label, optional help text, error and validation message handling.
|
|
30
|
+
*/
|
|
31
|
+
const props = defineProps<{
|
|
32
|
+
/**
|
|
33
|
+
* A unique identifier for the form field, used to associate the label with the form element.
|
|
34
|
+
*/
|
|
35
|
+
id: string;
|
|
36
|
+
/**
|
|
37
|
+
* The text displayed as the legend for the form fieldset.
|
|
38
|
+
*/
|
|
39
|
+
legend: string;
|
|
40
|
+
/**
|
|
41
|
+
* Additional text displayed alongside the label, typically used to indicate if the form field is required or optional
|
|
42
|
+
*/
|
|
43
|
+
requirementText?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Text shown below the form field to provide additional context or instructions for the user.
|
|
46
|
+
*/
|
|
47
|
+
helpText?: string;
|
|
48
|
+
/**
|
|
49
|
+
* If `true`, applies a valid state to the form field.
|
|
50
|
+
*/
|
|
51
|
+
isValid?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* If `true`, applies an invalid state to the form field.
|
|
54
|
+
*/
|
|
55
|
+
isInvalid?: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* message displayed when the form field has a valid or invalid state, usually indicating validation or errors.
|
|
58
|
+
*/
|
|
59
|
+
message?: string;
|
|
60
|
+
}>();
|
|
61
|
+
|
|
62
|
+
defineSlots<{
|
|
63
|
+
/**
|
|
64
|
+
* Use this slot to insert the form element of your choice
|
|
65
|
+
*/
|
|
66
|
+
default: VNode;
|
|
67
|
+
}>();
|
|
68
|
+
|
|
69
|
+
const classObjectValidation = computed(() => {
|
|
70
|
+
return {
|
|
71
|
+
'is-valid': props.isValid,
|
|
72
|
+
'is-invalid': props.isInvalid,
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
</script>
|
|
76
|
+
|
|
77
|
+
<style lang="scss" scoped>
|
|
78
|
+
@use '@mozaic-ds/styles/components/field';
|
|
79
|
+
</style>
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils';
|
|
2
|
+
import { describe, it, expect } from 'vitest';
|
|
3
|
+
import MIconButton from './MIconButton.vue';
|
|
4
|
+
import ChevronRight24 from '@mozaic-ds/icons-vue/src/components/ChevronRight24/ChevronRight24.vue';
|
|
5
|
+
|
|
6
|
+
describe('MButton component', () => {
|
|
7
|
+
it('renders with an icon', () => {
|
|
8
|
+
const wrapper = mount(MIconButton, {
|
|
9
|
+
slots: {
|
|
10
|
+
icon: [ChevronRight24],
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
const icon = wrapper.findComponent(ChevronRight24);
|
|
15
|
+
expect(icon.exists()).toBe(true);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('applies the correct appearance class based on the appearance prop', () => {
|
|
19
|
+
const wrapper = mount(MIconButton, {
|
|
20
|
+
props: {
|
|
21
|
+
appearance: 'accent',
|
|
22
|
+
},
|
|
23
|
+
slots: {
|
|
24
|
+
icon: [ChevronRight24],
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
expect(wrapper.classes()).toContain('mc-button--accent');
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('applies the correct size class based on the size prop', () => {
|
|
32
|
+
const wrapper = mount(MIconButton, {
|
|
33
|
+
props: {
|
|
34
|
+
size: 'l',
|
|
35
|
+
},
|
|
36
|
+
slots: {
|
|
37
|
+
icon: [ChevronRight24],
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
expect(wrapper.classes()).toContain('mc-button--l');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('disables the button when the disabled prop is true', async () => {
|
|
45
|
+
const wrapper = mount(MIconButton, {
|
|
46
|
+
props: {
|
|
47
|
+
disabled: true,
|
|
48
|
+
},
|
|
49
|
+
slots: {
|
|
50
|
+
icon: [ChevronRight24],
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const button = wrapper.find('button');
|
|
55
|
+
expect(button.attributes('disabled')).toBeDefined();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('applies the correct ghost class when ghost prop is true', () => {
|
|
59
|
+
const wrapper = mount(MIconButton, {
|
|
60
|
+
props: {
|
|
61
|
+
ghost: true,
|
|
62
|
+
},
|
|
63
|
+
slots: {
|
|
64
|
+
icon: [ChevronRight24],
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
expect(wrapper.classes()).toContain('mc-button--ghost');
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('applies the outlined class when outlined prop is true', () => {
|
|
72
|
+
const wrapper = mount(MIconButton, {
|
|
73
|
+
props: {
|
|
74
|
+
outlined: true,
|
|
75
|
+
},
|
|
76
|
+
slots: {
|
|
77
|
+
icon: [ChevronRight24],
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
expect(wrapper.classes()).toContain('mc-button--outlined');
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('has type="button" by default', () => {
|
|
85
|
+
const wrapper = mount(MIconButton, {
|
|
86
|
+
slots: {
|
|
87
|
+
icon: [ChevronRight24],
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const button = wrapper.find('button');
|
|
92
|
+
expect(button.attributes('type')).toBe('button');
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('can have type="submit" when the type prop is "submit"', () => {
|
|
96
|
+
const wrapper = mount(MIconButton, {
|
|
97
|
+
props: {
|
|
98
|
+
type: 'submit',
|
|
99
|
+
},
|
|
100
|
+
slots: {
|
|
101
|
+
icon: [ChevronRight24],
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
const button = wrapper.find('button');
|
|
106
|
+
expect(button.attributes('type')).toBe('submit');
|
|
107
|
+
});
|
|
108
|
+
});
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3';
|
|
2
|
+
|
|
3
|
+
import MIconButton from './MIconButton.vue';
|
|
4
|
+
import ChevronRight24 from '@mozaic-ds/icons-vue/src/components/ChevronRight24/ChevronRight24.vue';
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof MIconButton> = {
|
|
7
|
+
title: 'Action/Icon Button',
|
|
8
|
+
component: MIconButton,
|
|
9
|
+
parameters: {
|
|
10
|
+
docs: {
|
|
11
|
+
description: {
|
|
12
|
+
component:
|
|
13
|
+
'Icon Buttons are used to trigger actions. Their appearance is depending on the type of action required from the user, or the context.',
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
args: {
|
|
18
|
+
icon: '<ChevronRight24/>',
|
|
19
|
+
ariaLabel: 'Go to next page',
|
|
20
|
+
},
|
|
21
|
+
argTypes: {
|
|
22
|
+
ariaLabel: {
|
|
23
|
+
table: {
|
|
24
|
+
disable: true,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
$slots: {
|
|
28
|
+
table: {
|
|
29
|
+
disable: true,
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
render: (args) => ({
|
|
34
|
+
components: { MIconButton, ChevronRight24 },
|
|
35
|
+
setup() {
|
|
36
|
+
return { args };
|
|
37
|
+
},
|
|
38
|
+
template: `
|
|
39
|
+
<MIconButton
|
|
40
|
+
v-bind="args"
|
|
41
|
+
>
|
|
42
|
+
<template v-if="${'icon' in args}" v-slot:icon>${args.icon}</template>
|
|
43
|
+
</MIconButton>
|
|
44
|
+
`,
|
|
45
|
+
}),
|
|
46
|
+
};
|
|
47
|
+
export default meta;
|
|
48
|
+
type Story = StoryObj<typeof MIconButton>;
|
|
49
|
+
|
|
50
|
+
export const Standard: Story = {};
|
|
51
|
+
|
|
52
|
+
export const Outline: Story = {
|
|
53
|
+
args: { outlined: true },
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export const Ghost: Story = {
|
|
57
|
+
args: { ghost: true },
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export const SizeS: Story = {
|
|
61
|
+
args: { size: 's' },
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export const SizeL: Story = {
|
|
65
|
+
args: { size: 'l' },
|
|
66
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<button
|
|
3
|
+
class="mc-button mc-button--icon-button"
|
|
4
|
+
:class="classObject"
|
|
5
|
+
:disabled="disabled"
|
|
6
|
+
:type="type"
|
|
7
|
+
>
|
|
8
|
+
<span class="mc-button__icon">
|
|
9
|
+
<slot name="icon" />
|
|
10
|
+
</span>
|
|
11
|
+
</button>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script setup lang="ts">
|
|
15
|
+
import { computed, type VNode } from 'vue';
|
|
16
|
+
/**
|
|
17
|
+
* Icon Buttons are used to trigger actions. Their appearance is depending on the type of action required from the user, or the context.
|
|
18
|
+
*/
|
|
19
|
+
const props = withDefaults(
|
|
20
|
+
defineProps<{
|
|
21
|
+
/**
|
|
22
|
+
* Defines the visual style of the icon button.
|
|
23
|
+
*/
|
|
24
|
+
appearance?: 'standard' | 'accent' | 'danger' | 'inverse';
|
|
25
|
+
/**
|
|
26
|
+
* Determines the size of the icon button.
|
|
27
|
+
*/
|
|
28
|
+
size?: 's' | 'm' | 'l';
|
|
29
|
+
/**
|
|
30
|
+
* If `true`, disables the icon button, making it non-interactive.
|
|
31
|
+
*/
|
|
32
|
+
disabled?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* If `true`, applies a "ghost" style to the icon button.
|
|
35
|
+
*/
|
|
36
|
+
ghost?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* If `true`, the icon button gets an outlined style.
|
|
39
|
+
*/
|
|
40
|
+
outlined?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Specifies the button's HTML `type` attribute.
|
|
43
|
+
*/
|
|
44
|
+
type?: 'button' | 'reset' | 'submit';
|
|
45
|
+
}>(),
|
|
46
|
+
{
|
|
47
|
+
appearance: 'standard',
|
|
48
|
+
size: 'm',
|
|
49
|
+
type: 'button',
|
|
50
|
+
},
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
defineSlots<{
|
|
54
|
+
/**
|
|
55
|
+
* Use this slot to insert the form element of your choice
|
|
56
|
+
*/
|
|
57
|
+
icon: VNode;
|
|
58
|
+
}>();
|
|
59
|
+
|
|
60
|
+
const classObject = computed(() => {
|
|
61
|
+
return {
|
|
62
|
+
[`mc-button--${props.appearance}`]:
|
|
63
|
+
props.appearance && props.appearance != 'standard',
|
|
64
|
+
[`mc-button--${props.size}`]: props.size && props.size != 'm',
|
|
65
|
+
'mc-button--ghost': props.ghost,
|
|
66
|
+
'mc-button--outlined': props.outlined,
|
|
67
|
+
};
|
|
68
|
+
});
|
|
69
|
+
</script>
|
|
70
|
+
|
|
71
|
+
<style lang="scss" scoped>
|
|
72
|
+
@use '@mozaic-ds/styles/components/button';
|
|
73
|
+
</style>
|