@mozaic-ds/vue 2.15.0 → 2.17.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/mozaic-vue.css +2 -1
- package/dist/mozaic-vue.d.ts +1040 -408
- package/dist/mozaic-vue.js +17183 -6742
- package/dist/mozaic-vue.js.map +1 -1
- package/dist/mozaic-vue.umd.cjs +26 -6
- package/dist/mozaic-vue.umd.cjs.map +1 -1
- package/package.json +11 -5
- package/src/components/BrandPresets.mdx +2 -2
- package/src/components/ComponentsMapping.mdx +98 -0
- package/src/components/accordionlist/MAccordionList.figma.ts +43 -0
- package/src/components/accordionlistitem/MAccordionListItem.figma.ts +27 -0
- package/src/components/actionbottombar/MActionBottomBar.figma.ts +24 -0
- package/src/components/actionlistbox/MActionListbox.figma.ts +30 -0
- package/src/components/actionlistbox/MActionListbox.spec.ts +14 -0
- package/src/components/actionlistbox/MActionListbox.stories.ts +15 -8
- package/src/components/actionlistbox/MActionListbox.vue +13 -1
- package/src/components/actionlistbox/README.md +2 -1
- package/src/components/avatar/MAvatar.figma.ts +31 -0
- package/src/components/breadcrumb/MBreadcrumb.figma.ts +31 -0
- package/src/components/builtinmenu/MBuiltInMenu.figma.ts +23 -0
- package/src/components/button/MButton.figma.ts +41 -0
- package/src/components/button/README.md +2 -0
- package/src/components/callout/MCallout.figma.ts +29 -0
- package/src/components/carousel/MCarousel.figma.ts +32 -0
- package/src/components/checkbox/MCheckbox.figma.ts +45 -0
- package/src/components/checkboxgroup/MCheckboxGroup.figma.ts +30 -0
- package/src/components/checklistmenu/MCheckListMenu.figma.ts +29 -0
- package/src/components/circularprogressbar/MCircularProgressbar.figma.ts +31 -0
- package/src/components/combobox/MCombobox.figma.ts +48 -0
- package/src/components/combobox/MCombobox.spec.ts +246 -0
- package/src/components/combobox/MCombobox.stories.ts +190 -0
- package/src/components/combobox/MCombobox.vue +286 -0
- package/src/components/combobox/README.md +52 -0
- package/src/components/container/MContainer.figma.ts +30 -0
- package/src/components/datatable/DataTable.stories.ts +277 -0
- package/src/components/datatable/DataTableCells.stories.ts +251 -0
- package/src/components/datatable/DataTableEmpty.stories.ts +102 -0
- package/src/components/datatable/DataTableExpandable.stories.ts +95 -0
- package/src/components/datatable/DataTableNested.stories.ts +96 -0
- package/src/components/datatable/DataTableSelectable.stories.ts +124 -0
- package/src/components/datatable/DataTableSortable.stories.ts +164 -0
- package/src/components/datatable/MDataTable.types.ts +54 -0
- package/src/components/datatable/assets/styles.scss +10 -0
- package/src/components/datatable/datatable.mdx +62 -0
- package/src/components/datatable/tools/data.js +8 -0
- package/src/components/datatable/tools/data.json +2018 -0
- package/src/components/datatable/utils.js +19 -0
- package/src/components/datepicker/MDatepicker.figma.ts +20 -0
- package/src/components/divider/MDivider.figma.ts +30 -0
- package/src/components/drawer/MDrawer.figma.ts +37 -0
- package/src/components/drawer/README.md +1 -1
- package/src/components/field/MField.figma.ts +30 -0
- package/src/components/field/MField.stories.ts +105 -0
- package/src/components/fileuploader/MFileUploader.figma.ts +23 -0
- package/src/components/fileuploaderitem/MFileUploaderItem.figma.ts +27 -0
- package/src/components/flag/MFlag.figma.ts +26 -0
- package/src/components/iconbutton/MIconButton.figma.ts +54 -0
- package/src/components/kpiitem/MKpiItem.figma.ts +33 -0
- package/src/components/linearprogressbarbuffer/MLinearProgressbarBuffer.figma.ts +31 -0
- package/src/components/linearprogressbarpercentage/MLinearProgressbarPercentage.figma.ts +26 -0
- package/src/components/link/MLink.figma.ts +32 -0
- package/src/components/loader/MLoader.figma.ts +30 -0
- package/src/components/loadingoverlay/MLoadingOverlay.figma.ts +18 -0
- package/src/components/modal/MModal.figma.ts +27 -0
- package/src/components/navigationindicator/MNavigationIndicator.figma.ts +24 -0
- package/src/components/numberbadge/MNumberBadge.figma.ts +31 -0
- package/src/components/optionListbox/MOptionListbox.figma.ts +36 -0
- package/src/components/optionListbox/MOptionListbox.spec.ts +527 -0
- package/src/components/optionListbox/MOptionListbox.vue +470 -0
- package/src/components/optionListbox/README.md +63 -0
- package/src/components/overlay/MOverlay.figma.ts +20 -0
- package/src/components/pageheader/MPageHeader.figma.ts +21 -0
- package/src/components/pagination/MPagination.figma.ts +34 -0
- package/src/components/passwordinput/MPasswordInput.figma.ts +30 -0
- package/src/components/phonenumber/MPhoneNumber.figma.ts +47 -0
- package/src/components/pincode/MPincode.figma.ts +41 -0
- package/src/components/pincode/MPincode.spec.ts +1 -4
- package/src/components/pincode/MPincode.vue +11 -15
- package/src/components/popover/MPopover.figma.ts +42 -0
- package/src/components/quantityselector/MQuantitySelector.figma.ts +50 -0
- package/src/components/radio/MRadio.figma.ts +40 -0
- package/src/components/radiogroup/MRadioGroup.figma.ts +30 -0
- package/src/components/segmentedcontrol/MSegmentedControl.figma.ts +33 -0
- package/src/components/select/MSelect.figma.ts +49 -0
- package/src/components/sidebar/MSidebar.figma.ts +28 -0
- package/src/components/sidebarexpandableitem/MSidebarExpandableItem.figma.ts +19 -0
- package/src/components/sidebarfooter/MSidebarFooter.figma.ts +21 -0
- package/src/components/sidebarheader/MSidebarHeader.figma.ts +18 -0
- package/src/components/sidebarnavitem/MSidebarNavItem.figma.ts +23 -0
- package/src/components/sidebarshortcutitem/MSidebarShortcutItem.figma.ts +20 -0
- package/src/components/starrating/MStarRating.figma.ts +35 -0
- package/src/components/statusbadge/MStatusBadge.figma.ts +27 -0
- package/src/components/statusdot/MStatusDot.figma.ts +31 -0
- package/src/components/statusmessage/MStatusMessage.figma.ts +28 -0
- package/src/components/statusmessage/MStatusMessage.spec.ts +15 -0
- package/src/components/statusmessage/MStatusMessage.stories.ts +4 -0
- package/src/components/statusmessage/MStatusMessage.vue +7 -0
- package/src/components/statusmessage/README.md +2 -0
- package/src/components/statusnotification/MStatusNotification.figma.ts +29 -0
- package/src/components/stepperbottombar/MStepperBottomBar.figma.ts +20 -0
- package/src/components/steppercompact/MStepperCompact.figma.ts +21 -0
- package/src/components/stepperinline/MStepperInline.figma.ts +23 -0
- package/src/components/stepperstacked/MStepperStacked.figma.ts +23 -0
- package/src/components/stepperstacked/MStepperStacked.spec.ts +162 -0
- package/src/components/stepperstacked/MStepperStacked.stories.ts +57 -0
- package/src/components/stepperstacked/MStepperStacked.vue +106 -0
- package/src/components/stepperstacked/README.md +15 -0
- package/src/components/tabs/MTabs.figma.ts +33 -0
- package/src/components/tag/MTag.figma.ts +26 -0
- package/src/components/tag/MTag.stories.ts +13 -3
- package/src/components/tag/MTag.vue +11 -1
- package/src/components/tag/README.md +6 -0
- package/src/components/textarea/MTextArea.figma.ts +28 -0
- package/src/components/textinput/MTextInput.figma.ts +51 -0
- package/src/components/textinput/MTextInput.vue +13 -1
- package/src/components/textinput/README.md +15 -1
- package/src/components/tile/MTile.figma.ts +31 -0
- package/src/components/tileclickable/MTileClickable.figma.ts +31 -0
- package/src/components/tileexpandable/MTileExpandable.figma.ts +31 -0
- package/src/components/tileselectable/MTileSelectable.figma.ts +29 -0
- package/src/components/toaster/MToaster.figma.ts +25 -0
- package/src/components/toggle/MToggle.figma.ts +39 -0
- package/src/components/togglegroup/MToggleGroup.figma.ts +30 -0
- package/src/components/tooltip/MTooltip.figma.ts +29 -0
- package/src/main.ts +1 -0
|
@@ -8,6 +8,8 @@ A Status Message is a compact component that combines an icon and concise text t
|
|
|
8
8
|
| Name | Description | Type | Default |
|
|
9
9
|
| --- | --- | --- | --- |
|
|
10
10
|
| `status` | Allows to define the status message style. | `"info"` `"warning"` `"error"` `"success"` `"neutral"` `"inprogress"` | `"info"` |
|
|
11
|
+
| `appearance` | Allows to define the status message appearance.
|
|
12
|
+
The accent status is used to highlight a specific message. | `"standard"` `"accent"` | `"standard"` |
|
|
11
13
|
| `label*` | Label of the status message. | `string` | - |
|
|
12
14
|
|
|
13
15
|
## Dependencies
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Connect mapping for MStatusNotification
|
|
3
|
+
* Links Figma Status notification (ADS2) to @mozaic-ds/vue
|
|
4
|
+
*/
|
|
5
|
+
import figma, { html } from '@figma/code-connect/html';
|
|
6
|
+
|
|
7
|
+
figma.connect(
|
|
8
|
+
'https://www.figma.com/design/Zyh9RyabNaqkjbuFWP9Aqj/%E2%9C%A8-Components--ADS2---Stable-version-?node-id=6-21600',
|
|
9
|
+
{
|
|
10
|
+
props: {
|
|
11
|
+
status: figma.enum('Status', {
|
|
12
|
+
Information: 'info',
|
|
13
|
+
Success: 'success',
|
|
14
|
+
Warning: 'warning',
|
|
15
|
+
Error: 'error',
|
|
16
|
+
}),
|
|
17
|
+
},
|
|
18
|
+
example: ({ status }) =>
|
|
19
|
+
html`<script setup>
|
|
20
|
+
import { MStatusNotification } from '@mozaic-ds/vue';
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<MStatusNotification
|
|
24
|
+
title="Notification title"
|
|
25
|
+
description="Notification description"
|
|
26
|
+
status=${status}
|
|
27
|
+
></MStatusNotification>`,
|
|
28
|
+
},
|
|
29
|
+
);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Connect mapping for MStepperBottomBar
|
|
3
|
+
* Links Figma Stepper bottom bar (ADS2) to @mozaic-ds/vue
|
|
4
|
+
*/
|
|
5
|
+
import figma, { html } from '@figma/code-connect/html';
|
|
6
|
+
|
|
7
|
+
figma.connect(
|
|
8
|
+
'https://www.figma.com/design/Zyh9RyabNaqkjbuFWP9Aqj/%E2%9C%A8-Components--ADS2---Stable-version-?node-id=10726-18528',
|
|
9
|
+
{
|
|
10
|
+
props: {
|
|
11
|
+
cancel: figma.boolean('Has cancel action'),
|
|
12
|
+
},
|
|
13
|
+
example: ({ cancel }) =>
|
|
14
|
+
html`<script setup>
|
|
15
|
+
import { MStepperBottomBar } from '@mozaic-ds/vue';
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<MStepperBottomBar cancel=${cancel} :steps="3" />`,
|
|
19
|
+
},
|
|
20
|
+
);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Connect mapping for MStepperCompact
|
|
3
|
+
* Links Figma Stepper (Compact) (ADS2) to @mozaic-ds/vue
|
|
4
|
+
*/
|
|
5
|
+
import figma, { html } from '@figma/code-connect/html';
|
|
6
|
+
|
|
7
|
+
figma.connect(
|
|
8
|
+
'https://www.figma.com/design/Zyh9RyabNaqkjbuFWP9Aqj/%E2%9C%A8-Components--ADS2---Stable-version-?node-id=13297-24864',
|
|
9
|
+
{
|
|
10
|
+
props: {
|
|
11
|
+
label: figma.string('Step label'),
|
|
12
|
+
description: figma.string('Next step label'),
|
|
13
|
+
},
|
|
14
|
+
example: ({ label, description }) =>
|
|
15
|
+
html`<script setup>
|
|
16
|
+
import { MStepperCompact } from '@mozaic-ds/vue';
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<MStepperCompact label=${label} :description=${description} :value="1" :max-steps="4"></MStepperCompact>`,
|
|
20
|
+
},
|
|
21
|
+
);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Connect mapping for MStepperInline
|
|
3
|
+
* Links Figma Stepper (Inline) to @mozaic-ds/vue
|
|
4
|
+
*/
|
|
5
|
+
import figma, { html } from '@figma/code-connect/html';
|
|
6
|
+
|
|
7
|
+
figma.connect(
|
|
8
|
+
'https://www.figma.com/design/Zyh9RyabNaqkjbuFWP9Aqj/%E2%9C%A8-Components--ADS2---Stable-version-?node-id=13050-10371',
|
|
9
|
+
{
|
|
10
|
+
props: {
|
|
11
|
+
showStep03: figma.boolean('Show Step 03'),
|
|
12
|
+
showStep04: figma.boolean('Show Step 04'),
|
|
13
|
+
showStep05: figma.boolean('Show Step 05'),
|
|
14
|
+
showStep06: figma.boolean('Show Step 06'),
|
|
15
|
+
},
|
|
16
|
+
example: () =>
|
|
17
|
+
html`<script setup>
|
|
18
|
+
import { MStepperInline } from '@mozaic-ds/vue';
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<MStepperInline :current-step="1" :steps="[{ label: 'Step label', additionalInfo: 'Additional information' }, { label: 'Step label', additionalInfo: 'Additional information' }, { label: 'Step label', additionalInfo: 'Additional information' }]"></MStepperInline>`,
|
|
22
|
+
},
|
|
23
|
+
);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Connect mapping for MStepperStacked
|
|
3
|
+
* Links Figma Stepper (Stacked) (ADS2) to @mozaic-ds/vue
|
|
4
|
+
*/
|
|
5
|
+
import figma, { html } from '@figma/code-connect/html';
|
|
6
|
+
|
|
7
|
+
figma.connect(
|
|
8
|
+
'https://www.figma.com/design/Zyh9RyabNaqkjbuFWP9Aqj/%E2%9C%A8-Components--ADS2---Stable-version-?node-id=13179-6447',
|
|
9
|
+
{
|
|
10
|
+
props: {
|
|
11
|
+
showStep03: figma.boolean('Show Step 03'),
|
|
12
|
+
showStep04: figma.boolean('Show Step 04'),
|
|
13
|
+
showStep05: figma.boolean('Show Step 05'),
|
|
14
|
+
showStep06: figma.boolean('Show Step 06'),
|
|
15
|
+
},
|
|
16
|
+
example: () =>
|
|
17
|
+
html`<script setup>
|
|
18
|
+
import { MStepperStacked } from '@mozaic-ds/vue';
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<MStepperStacked :current-step="1" :steps="[{ label: 'Step label', additionalInfo: 'Additional information' }, { label: 'Step label', additionalInfo: 'Additional information' }, { label: 'Step label', additionalInfo: 'Additional information' }]"></MStepperStacked>`,
|
|
22
|
+
},
|
|
23
|
+
);
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { mount } from '@vue/test-utils';
|
|
3
|
+
import MStepperStacked from './MStepperStacked.vue';
|
|
4
|
+
|
|
5
|
+
const defaultSteps = [
|
|
6
|
+
{ id: '1', label: 'Step 1' },
|
|
7
|
+
{ id: '2', label: 'Step 2', additionalInfo: 'Additional info' },
|
|
8
|
+
{ id: '3', label: 'Step 3' },
|
|
9
|
+
];
|
|
10
|
+
|
|
11
|
+
describe('MStepperStacked', () => {
|
|
12
|
+
describe('Basic rendering', () => {
|
|
13
|
+
it('renders as many li elements as there are steps', () => {
|
|
14
|
+
const wrapper = mount(MStepperStacked, {
|
|
15
|
+
props: { steps: defaultSteps },
|
|
16
|
+
});
|
|
17
|
+
const items = wrapper.findAll('.mc-stepper-stacked__item');
|
|
18
|
+
expect(items).toHaveLength(defaultSteps.length);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('renders the label of each step', () => {
|
|
22
|
+
const wrapper = mount(MStepperStacked, {
|
|
23
|
+
props: { steps: defaultSteps },
|
|
24
|
+
});
|
|
25
|
+
defaultSteps.forEach((step) => {
|
|
26
|
+
expect(wrapper.text()).toContain(step.label);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('renders step numbers (1, 2, 3...)', () => {
|
|
31
|
+
const wrapper = mount(MStepperStacked, {
|
|
32
|
+
props: { steps: defaultSteps, currentStep: '1' },
|
|
33
|
+
});
|
|
34
|
+
expect(wrapper.text()).toContain('2');
|
|
35
|
+
expect(wrapper.text()).toContain('3');
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('renders additionalInfo when provided', () => {
|
|
39
|
+
const wrapper = mount(MStepperStacked, {
|
|
40
|
+
props: { steps: defaultSteps },
|
|
41
|
+
});
|
|
42
|
+
expect(wrapper.text()).toContain('Additional info');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('adds the has-additional class on items with additionalInfo', () => {
|
|
46
|
+
const wrapper = mount(MStepperStacked, {
|
|
47
|
+
props: { steps: defaultSteps },
|
|
48
|
+
});
|
|
49
|
+
const items = wrapper.findAll('.mc-stepper-stacked__item');
|
|
50
|
+
expect(items[1].classes()).toContain('has-additional');
|
|
51
|
+
expect(items[0].classes()).not.toContain('has-additional');
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
describe('Step states', () => {
|
|
56
|
+
it('marks the current step circle with the is-current class', () => {
|
|
57
|
+
const wrapper = mount(MStepperStacked, {
|
|
58
|
+
props: { steps: defaultSteps, currentStep: '2' },
|
|
59
|
+
});
|
|
60
|
+
const circles = wrapper.findAll('.mc-stepper-stacked__circle');
|
|
61
|
+
const currentCircle = circles.find((c) => c.classes('is-current'));
|
|
62
|
+
expect(currentCircle).toBeTruthy();
|
|
63
|
+
expect(currentCircle?.text()).toBe('2');
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('marks the current step label with the is-current class', () => {
|
|
67
|
+
const wrapper = mount(MStepperStacked, {
|
|
68
|
+
props: { steps: defaultSteps, currentStep: '2' },
|
|
69
|
+
});
|
|
70
|
+
const labels = wrapper.findAll('.mc-stepper-stacked__label');
|
|
71
|
+
expect(labels[1].classes()).toContain('is-current');
|
|
72
|
+
expect(labels[0].classes()).not.toContain('is-current');
|
|
73
|
+
expect(labels[2].classes()).not.toContain('is-current');
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('renders the Check icon for completed steps', () => {
|
|
77
|
+
const wrapper = mount(MStepperStacked, {
|
|
78
|
+
props: { steps: defaultSteps, currentStep: '3' },
|
|
79
|
+
});
|
|
80
|
+
const checkIcons = wrapper.findAll('.mc-stepper-stacked__icon--check');
|
|
81
|
+
expect(checkIcons).toHaveLength(2);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('does not render the Check icon for the current step', () => {
|
|
85
|
+
const wrapper = mount(MStepperStacked, {
|
|
86
|
+
props: { steps: defaultSteps, currentStep: '1' },
|
|
87
|
+
});
|
|
88
|
+
const checkIcons = wrapper.findAll('.mc-stepper-stacked__icon--check');
|
|
89
|
+
expect(checkIcons).toHaveLength(0);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('renders a numbered circle for non-completed steps', () => {
|
|
93
|
+
const wrapper = mount(MStepperStacked, {
|
|
94
|
+
props: { steps: defaultSteps, currentStep: '1' },
|
|
95
|
+
});
|
|
96
|
+
const circles = wrapper.findAll('.mc-stepper-stacked__circle');
|
|
97
|
+
expect(circles).toHaveLength(3);
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
describe('active step — string type', () => {
|
|
102
|
+
it('falls back to step 1 if currentStep is less than 1', () => {
|
|
103
|
+
const wrapper = mount(MStepperStacked, {
|
|
104
|
+
props: { steps: defaultSteps, currentStep: 'unknown id' },
|
|
105
|
+
});
|
|
106
|
+
const labels = wrapper.findAll('.mc-stepper-stacked__label');
|
|
107
|
+
expect(labels[0].classes()).toContain('is-current');
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('works with no steps (default value)', () => {
|
|
111
|
+
const wrapper = mount(MStepperStacked);
|
|
112
|
+
expect(wrapper.findAll('.mc-stepper-stacked__item')).toHaveLength(0);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
describe('active step — number type', () => {
|
|
117
|
+
it('clamps to step 1 when currentStep is 0 or less', () => {
|
|
118
|
+
const wrapper = mount(MStepperStacked, {
|
|
119
|
+
props: { steps: defaultSteps, currentStep: 0 },
|
|
120
|
+
});
|
|
121
|
+
const labels = wrapper.findAll('.mc-stepper-stacked__label');
|
|
122
|
+
expect(labels[0].classes()).toContain('is-current');
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('clamps to the last step when currentStep exceeds steps length', () => {
|
|
126
|
+
const wrapper = mount(MStepperStacked, {
|
|
127
|
+
props: { steps: defaultSteps, currentStep: 99 },
|
|
128
|
+
});
|
|
129
|
+
const labels = wrapper.findAll('.mc-stepper-stacked__label');
|
|
130
|
+
expect(labels[defaultSteps.length - 1].classes()).toContain('is-current');
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
describe('Default currentStep', () => {
|
|
135
|
+
it('defaults to currentStep=1', () => {
|
|
136
|
+
const wrapper = mount(MStepperStacked, {
|
|
137
|
+
props: { steps: defaultSteps },
|
|
138
|
+
});
|
|
139
|
+
const labels = wrapper.findAll('.mc-stepper-stacked__label');
|
|
140
|
+
expect(labels[0].classes()).toContain('is-current');
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
describe('First and last step', () => {
|
|
145
|
+
it('has no completed steps when currentStep=1', () => {
|
|
146
|
+
const wrapper = mount(MStepperStacked, {
|
|
147
|
+
props: { steps: defaultSteps, currentStep: '1' },
|
|
148
|
+
});
|
|
149
|
+
expect(wrapper.findAll('.mc-stepper-stacked__icon--check')).toHaveLength(
|
|
150
|
+
0,
|
|
151
|
+
);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('marks all previous steps as completed when on the last step', () => {
|
|
155
|
+
const wrapper = mount(MStepperStacked, {
|
|
156
|
+
props: { steps: defaultSteps, currentStep: '3' },
|
|
157
|
+
});
|
|
158
|
+
const checkIcons = wrapper.findAll('.mc-stepper-stacked__icon--check');
|
|
159
|
+
expect(checkIcons).toHaveLength(defaultSteps.length - 1);
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3-vite';
|
|
2
|
+
import MStepperStacked from './MStepperStacked.vue';
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof MStepperStacked> = {
|
|
5
|
+
title: 'Indicators/Stepper Stacked',
|
|
6
|
+
component: MStepperStacked,
|
|
7
|
+
tags: ['v2'],
|
|
8
|
+
parameters: {
|
|
9
|
+
docs: {
|
|
10
|
+
description: {
|
|
11
|
+
component:
|
|
12
|
+
'A stepper is a navigation component that guides users through a sequence of steps in a structured process. It visually represents progress, completed steps, and upcoming steps, helping users understand their position within a workflow. Steppers are commonly used in multi-step forms, onboarding flows, checkout processes, and task completion sequences to improve clarity and reduce cognitive load.',
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
args: {
|
|
17
|
+
currentStep: 1,
|
|
18
|
+
steps: [
|
|
19
|
+
{ id: '1', label: 'Cart' },
|
|
20
|
+
{ id: '2', label: 'Delivery address' },
|
|
21
|
+
{ id: '3', label: 'Payment' },
|
|
22
|
+
{ id: '4', label: 'Order confirmation' },
|
|
23
|
+
],
|
|
24
|
+
},
|
|
25
|
+
render: (args) => ({
|
|
26
|
+
components: { MStepperStacked },
|
|
27
|
+
setup() {
|
|
28
|
+
return { args };
|
|
29
|
+
},
|
|
30
|
+
template: `<MStepperStacked v-bind="args" />`,
|
|
31
|
+
}),
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default meta;
|
|
35
|
+
type Story = StoryObj<typeof MStepperStacked>;
|
|
36
|
+
|
|
37
|
+
export const Default: Story = {};
|
|
38
|
+
|
|
39
|
+
export const AditionnalInfo: Story = {
|
|
40
|
+
args: {
|
|
41
|
+
currentStep: 2,
|
|
42
|
+
steps: [
|
|
43
|
+
{ id: '1', label: 'Cart', additionalInfo: 'Additional information' },
|
|
44
|
+
{
|
|
45
|
+
id: '2',
|
|
46
|
+
label: 'Delivery address',
|
|
47
|
+
additionalInfo: 'Additional information',
|
|
48
|
+
},
|
|
49
|
+
{ id: '3', label: 'Payment', additionalInfo: 'Additional information' },
|
|
50
|
+
{
|
|
51
|
+
id: '4',
|
|
52
|
+
label: 'Order confirmation',
|
|
53
|
+
additionalInfo: 'Additional information',
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<nav class="mc-stepper-stacked" aria-label="Stepper">
|
|
3
|
+
<ol class="mc-stepper-stacked__container">
|
|
4
|
+
<li
|
|
5
|
+
v-for="(step, index) in steps"
|
|
6
|
+
:key="index"
|
|
7
|
+
:class="{
|
|
8
|
+
'mc-stepper-stacked__item': true,
|
|
9
|
+
'has-additional': step.additionalInfo,
|
|
10
|
+
}"
|
|
11
|
+
>
|
|
12
|
+
<div class="mc-stepper-stacked__indicator">
|
|
13
|
+
<Check24
|
|
14
|
+
v-if="stepStates[index].completed"
|
|
15
|
+
class="mc-stepper-stacked__icon mc-stepper-stacked__icon--check"
|
|
16
|
+
/>
|
|
17
|
+
<span
|
|
18
|
+
v-else
|
|
19
|
+
:class="{
|
|
20
|
+
'mc-stepper-stacked__circle': true,
|
|
21
|
+
'is-current': stepStates[index].current,
|
|
22
|
+
}"
|
|
23
|
+
>
|
|
24
|
+
{{ index + 1 }}
|
|
25
|
+
</span>
|
|
26
|
+
</div>
|
|
27
|
+
<div class="mc-stepper-stacked__content">
|
|
28
|
+
<span
|
|
29
|
+
:class="{
|
|
30
|
+
'mc-stepper-stacked__label': true,
|
|
31
|
+
'is-current': stepStates[index].current,
|
|
32
|
+
}"
|
|
33
|
+
>
|
|
34
|
+
{{ step.label }}
|
|
35
|
+
</span>
|
|
36
|
+
<span class="mc-stepper-stacked__additional">
|
|
37
|
+
{{ step.additionalInfo }}
|
|
38
|
+
</span>
|
|
39
|
+
</div>
|
|
40
|
+
</li>
|
|
41
|
+
</ol>
|
|
42
|
+
</nav>
|
|
43
|
+
</template>
|
|
44
|
+
|
|
45
|
+
<script setup lang="ts">
|
|
46
|
+
import { computed } from 'vue';
|
|
47
|
+
import { Check24 } from '@mozaic-ds/icons-vue';
|
|
48
|
+
/**
|
|
49
|
+
* A stepper is a navigation component that guides users through a sequence of steps in a structured process. It visually represents progress, completed steps, and upcoming steps, helping users understand their position within a workflow. Steppers are commonly used in multi-step forms, onboarding flows, checkout processes, and task completion sequences to improve clarity and reduce cognitive load.
|
|
50
|
+
*/
|
|
51
|
+
const props = withDefaults(
|
|
52
|
+
defineProps<{
|
|
53
|
+
/**
|
|
54
|
+
* Defines the currently active step.
|
|
55
|
+
*
|
|
56
|
+
* - If a `number` is provided, it represents the 1-based position of the step
|
|
57
|
+
* in the `steps` array (e.g. `1` for the first step).
|
|
58
|
+
* - If a `string` is provided, it must match the `id` of one of the steps.
|
|
59
|
+
*/
|
|
60
|
+
currentStep?: string | number;
|
|
61
|
+
/**
|
|
62
|
+
* Steps of the stepper inline.
|
|
63
|
+
*/
|
|
64
|
+
steps?: Array<{
|
|
65
|
+
/**
|
|
66
|
+
* Unique identifier for the step.
|
|
67
|
+
*/
|
|
68
|
+
id?: string;
|
|
69
|
+
/**
|
|
70
|
+
* Label of the step.
|
|
71
|
+
*/
|
|
72
|
+
label: string;
|
|
73
|
+
/**
|
|
74
|
+
* Optional additional information under the label.
|
|
75
|
+
*/
|
|
76
|
+
additionalInfo?: string;
|
|
77
|
+
}>;
|
|
78
|
+
}>(),
|
|
79
|
+
{
|
|
80
|
+
currentStep: '1',
|
|
81
|
+
steps: () => [],
|
|
82
|
+
},
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
const activeStep = computed(() => {
|
|
86
|
+
if (typeof props.currentStep === 'number') {
|
|
87
|
+
return Math.min(Math.max(props.currentStep, 1), props.steps.length) - 1;
|
|
88
|
+
} else {
|
|
89
|
+
const activeIndex = props.steps.findIndex(
|
|
90
|
+
(step) => step.id === props.currentStep,
|
|
91
|
+
);
|
|
92
|
+
return activeIndex === -1 ? 0 : activeIndex;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const stepStates = computed(() =>
|
|
97
|
+
props.steps.map((_, i) => ({
|
|
98
|
+
completed: i < activeStep.value,
|
|
99
|
+
current: i === activeStep.value,
|
|
100
|
+
})),
|
|
101
|
+
);
|
|
102
|
+
</script>
|
|
103
|
+
|
|
104
|
+
<style scoped lang="scss">
|
|
105
|
+
@use '@mozaic-ds/styles/components/stepper-stacked';
|
|
106
|
+
</style>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# MStepperStacked
|
|
2
|
+
|
|
3
|
+
A stepper is a navigation component that guides users through a sequence of steps in a structured process. It visually represents progress, completed steps, and upcoming steps, helping users understand their position within a workflow. Steppers are commonly used in multi-step forms, onboarding flows, checkout processes, and task completion sequences to improve clarity and reduce cognitive load.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## Props
|
|
7
|
+
|
|
8
|
+
| Name | Description | Type | Default |
|
|
9
|
+
| --- | --- | --- | --- |
|
|
10
|
+
| `currentStep` | Defines the currently active step.
|
|
11
|
+
|
|
12
|
+
- If a `number` is provided, it represents the 1-based position of the step
|
|
13
|
+
in the `steps` array (e.g. `1` for the first step).
|
|
14
|
+
- If a `string` is provided, it must match the `id` of one of the steps. | `string` `number` | `"1"` |
|
|
15
|
+
| `steps` | Steps of the stepper inline. | `{ id?: string` `undefined; label: string; additionalInfo?: string` `undefined; }[]` | `[]` |
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Connect mapping for MTabs
|
|
3
|
+
* Links Figma Tabs (ADS2) to @mozaic-ds/vue
|
|
4
|
+
*/
|
|
5
|
+
import figma, { html } from '@figma/code-connect/html';
|
|
6
|
+
|
|
7
|
+
figma.connect(
|
|
8
|
+
'https://www.figma.com/design/Zyh9RyabNaqkjbuFWP9Aqj/%E2%9C%A8-Components--ADS2---Stable-version-?node-id=6-11474',
|
|
9
|
+
{
|
|
10
|
+
props: {
|
|
11
|
+
divider: figma.boolean('Show divider'),
|
|
12
|
+
centered: figma.enum('Centered', {
|
|
13
|
+
True: true,
|
|
14
|
+
False: false,
|
|
15
|
+
}),
|
|
16
|
+
},
|
|
17
|
+
example: ({ divider, centered }) =>
|
|
18
|
+
html`<script setup>
|
|
19
|
+
import { MTabs } from '@mozaic-ds/vue';
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<MTabs
|
|
23
|
+
:divider=${divider}
|
|
24
|
+
centered=${centered}
|
|
25
|
+
model-value="label1"
|
|
26
|
+
:tabs="[
|
|
27
|
+
{ id: 'label1', label: 'Label' },
|
|
28
|
+
{ id: 'label2', label: 'Label' },
|
|
29
|
+
{ id: 'label3', label: 'Label' },
|
|
30
|
+
]"
|
|
31
|
+
></MTabs>`,
|
|
32
|
+
},
|
|
33
|
+
);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Connect mapping for MTag
|
|
3
|
+
* Links Figma Tag to @mozaic-ds/vue
|
|
4
|
+
*/
|
|
5
|
+
import figma, { html } from '@figma/code-connect/html';
|
|
6
|
+
|
|
7
|
+
figma.connect(
|
|
8
|
+
'https://www.figma.com/design/Zyh9RyabNaqkjbuFWP9Aqj/%E2%9C%A8-Components--ADS2---Stable-version-?node-id=5730-15694',
|
|
9
|
+
{
|
|
10
|
+
props: {
|
|
11
|
+
type: figma.enum('Type', {
|
|
12
|
+
'Informative (Read-only)': 'informative',
|
|
13
|
+
'Interactive (as link or button)': 'interactive',
|
|
14
|
+
Contextualised: 'contextualised',
|
|
15
|
+
Removable: 'removable',
|
|
16
|
+
Selectable: 'selectable',
|
|
17
|
+
}),
|
|
18
|
+
},
|
|
19
|
+
example: ({ type }) =>
|
|
20
|
+
html`<script setup>
|
|
21
|
+
import { MTag } from '@mozaic-ds/vue';
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<MTag type=${type} label="Tag label"></MTag>`,
|
|
25
|
+
},
|
|
26
|
+
);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/vue3-vite';
|
|
2
2
|
import { action } from 'storybook/actions';
|
|
3
|
+
import { FeelingSatisfied20 } from '@mozaic-ds/icons-vue';
|
|
3
4
|
import MTag from './MTag.vue';
|
|
4
5
|
|
|
5
6
|
const meta: Meta<typeof MTag> = {
|
|
@@ -17,7 +18,7 @@ const meta: Meta<typeof MTag> = {
|
|
|
17
18
|
label: 'Tag label',
|
|
18
19
|
},
|
|
19
20
|
render: (args) => ({
|
|
20
|
-
components: { MTag },
|
|
21
|
+
components: { MTag, FeelingSatisfied20 },
|
|
21
22
|
setup() {
|
|
22
23
|
const handleUpdate = action('update:modelValue');
|
|
23
24
|
const handleRemoveTag = action('remove-tag');
|
|
@@ -25,11 +26,14 @@ const meta: Meta<typeof MTag> = {
|
|
|
25
26
|
return { args, handleUpdate, handleRemoveTag };
|
|
26
27
|
},
|
|
27
28
|
template: `
|
|
28
|
-
<MTag
|
|
29
|
+
<MTag
|
|
29
30
|
v-bind="args"
|
|
30
31
|
@update:modelValue="handleUpdate"
|
|
31
32
|
@remove-tag="handleRemoveTag"
|
|
32
|
-
|
|
33
|
+
v-model="args.modelValue"
|
|
34
|
+
>
|
|
35
|
+
<template v-if="${'icon' in args}" v-slot:icon>${args.icon}</template>
|
|
36
|
+
</MTag>
|
|
33
37
|
`,
|
|
34
38
|
}),
|
|
35
39
|
};
|
|
@@ -42,6 +46,12 @@ export const Size: Story = {
|
|
|
42
46
|
args: { size: 's' },
|
|
43
47
|
};
|
|
44
48
|
|
|
49
|
+
export const Icon: Story = {
|
|
50
|
+
args: {
|
|
51
|
+
icon: '<FeelingSatisfied20/>',
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
|
|
45
55
|
export const Interactive: Story = {
|
|
46
56
|
args: { type: 'interactive' },
|
|
47
57
|
};
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"
|
|
18
18
|
v-bind="$attrs"
|
|
19
19
|
/>
|
|
20
|
+
<slot v-if="!modelValue" name="icon" />
|
|
20
21
|
<span class="mc-tag__label">{{ label }}</span>
|
|
21
22
|
</label>
|
|
22
23
|
|
|
@@ -28,6 +29,7 @@
|
|
|
28
29
|
:disabled="disabled"
|
|
29
30
|
v-bind="$attrs"
|
|
30
31
|
>
|
|
32
|
+
<slot name="icon" />
|
|
31
33
|
<span class="mc-tag__label">{{ label }}</span>
|
|
32
34
|
</button>
|
|
33
35
|
|
|
@@ -66,12 +68,13 @@
|
|
|
66
68
|
|
|
67
69
|
<!-- informative -->
|
|
68
70
|
<span v-else class="mc-tag" :class="classObject" v-bind="$attrs">
|
|
71
|
+
<slot name="icon" />
|
|
69
72
|
<span class="mc-tag__label">{{ label }}</span>
|
|
70
73
|
</span>
|
|
71
74
|
</template>
|
|
72
75
|
|
|
73
76
|
<script setup lang="ts">
|
|
74
|
-
import { computed } from 'vue';
|
|
77
|
+
import { computed, type VNode } from 'vue';
|
|
75
78
|
import { CrossCircleFilled24 } from '@mozaic-ds/icons-vue';
|
|
76
79
|
import MNumberBadge from '../numberbadge/MNumberBadge.vue';
|
|
77
80
|
/**
|
|
@@ -128,6 +131,13 @@ const props = withDefaults(
|
|
|
128
131
|
},
|
|
129
132
|
);
|
|
130
133
|
|
|
134
|
+
defineSlots<{
|
|
135
|
+
/**
|
|
136
|
+
* Use this slot to insert an icon in the tag.
|
|
137
|
+
*/
|
|
138
|
+
icon?: VNode;
|
|
139
|
+
}>();
|
|
140
|
+
|
|
131
141
|
const classObject = computed(() => {
|
|
132
142
|
return {
|
|
133
143
|
[`mc-tag-${props.type}`]: props.type && props.type != 'informative',
|
|
@@ -17,6 +17,12 @@ A Tag is a UI element used to filter data, categorize, select or deselect an opt
|
|
|
17
17
|
| `contextualisedNumber` | A number displayed in the badge when the tag is contextualised. | `number` | `99` |
|
|
18
18
|
| `removableLabel` | Accessible label text for the remove button in removable tags. | `string` | `"Remove"` |
|
|
19
19
|
|
|
20
|
+
## Slots
|
|
21
|
+
|
|
22
|
+
| Name | Description |
|
|
23
|
+
| --- | --- |
|
|
24
|
+
| `icon` | Use this slot to insert an icon in the tag. |
|
|
25
|
+
|
|
20
26
|
## Events
|
|
21
27
|
|
|
22
28
|
| Name | Description | Type |
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Connect mapping for MTextArea
|
|
3
|
+
* Links Figma _text area / base to @mozaic-ds/vue
|
|
4
|
+
*/
|
|
5
|
+
import figma, { html } from '@figma/code-connect/html';
|
|
6
|
+
|
|
7
|
+
figma.connect(
|
|
8
|
+
'https://www.figma.com/design/Zyh9RyabNaqkjbuFWP9Aqj/%E2%9C%A8-Components--ADS2---Stable-version-?node-id=4544-28487',
|
|
9
|
+
{
|
|
10
|
+
props: {
|
|
11
|
+
isInvalid: figma.enum('Is invalid', {
|
|
12
|
+
True: true,
|
|
13
|
+
False: false,
|
|
14
|
+
}),
|
|
15
|
+
},
|
|
16
|
+
example: ({ isInvalid }) =>
|
|
17
|
+
html`<script setup>
|
|
18
|
+
import { MTextArea } from '@mozaic-ds/vue';
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<MTextArea
|
|
22
|
+
id="textarea-id"
|
|
23
|
+
:is-invalid=${isInvalid}
|
|
24
|
+
placeholder="Placeholder"
|
|
25
|
+
model-value=""
|
|
26
|
+
></MTextArea>`,
|
|
27
|
+
},
|
|
28
|
+
);
|