@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.
Files changed (125) hide show
  1. package/dist/mozaic-vue.css +2 -1
  2. package/dist/mozaic-vue.d.ts +1040 -408
  3. package/dist/mozaic-vue.js +17183 -6742
  4. package/dist/mozaic-vue.js.map +1 -1
  5. package/dist/mozaic-vue.umd.cjs +26 -6
  6. package/dist/mozaic-vue.umd.cjs.map +1 -1
  7. package/package.json +11 -5
  8. package/src/components/BrandPresets.mdx +2 -2
  9. package/src/components/ComponentsMapping.mdx +98 -0
  10. package/src/components/accordionlist/MAccordionList.figma.ts +43 -0
  11. package/src/components/accordionlistitem/MAccordionListItem.figma.ts +27 -0
  12. package/src/components/actionbottombar/MActionBottomBar.figma.ts +24 -0
  13. package/src/components/actionlistbox/MActionListbox.figma.ts +30 -0
  14. package/src/components/actionlistbox/MActionListbox.spec.ts +14 -0
  15. package/src/components/actionlistbox/MActionListbox.stories.ts +15 -8
  16. package/src/components/actionlistbox/MActionListbox.vue +13 -1
  17. package/src/components/actionlistbox/README.md +2 -1
  18. package/src/components/avatar/MAvatar.figma.ts +31 -0
  19. package/src/components/breadcrumb/MBreadcrumb.figma.ts +31 -0
  20. package/src/components/builtinmenu/MBuiltInMenu.figma.ts +23 -0
  21. package/src/components/button/MButton.figma.ts +41 -0
  22. package/src/components/button/README.md +2 -0
  23. package/src/components/callout/MCallout.figma.ts +29 -0
  24. package/src/components/carousel/MCarousel.figma.ts +32 -0
  25. package/src/components/checkbox/MCheckbox.figma.ts +45 -0
  26. package/src/components/checkboxgroup/MCheckboxGroup.figma.ts +30 -0
  27. package/src/components/checklistmenu/MCheckListMenu.figma.ts +29 -0
  28. package/src/components/circularprogressbar/MCircularProgressbar.figma.ts +31 -0
  29. package/src/components/combobox/MCombobox.figma.ts +48 -0
  30. package/src/components/combobox/MCombobox.spec.ts +246 -0
  31. package/src/components/combobox/MCombobox.stories.ts +190 -0
  32. package/src/components/combobox/MCombobox.vue +286 -0
  33. package/src/components/combobox/README.md +52 -0
  34. package/src/components/container/MContainer.figma.ts +30 -0
  35. package/src/components/datatable/DataTable.stories.ts +277 -0
  36. package/src/components/datatable/DataTableCells.stories.ts +251 -0
  37. package/src/components/datatable/DataTableEmpty.stories.ts +102 -0
  38. package/src/components/datatable/DataTableExpandable.stories.ts +95 -0
  39. package/src/components/datatable/DataTableNested.stories.ts +96 -0
  40. package/src/components/datatable/DataTableSelectable.stories.ts +124 -0
  41. package/src/components/datatable/DataTableSortable.stories.ts +164 -0
  42. package/src/components/datatable/MDataTable.types.ts +54 -0
  43. package/src/components/datatable/assets/styles.scss +10 -0
  44. package/src/components/datatable/datatable.mdx +62 -0
  45. package/src/components/datatable/tools/data.js +8 -0
  46. package/src/components/datatable/tools/data.json +2018 -0
  47. package/src/components/datatable/utils.js +19 -0
  48. package/src/components/datepicker/MDatepicker.figma.ts +20 -0
  49. package/src/components/divider/MDivider.figma.ts +30 -0
  50. package/src/components/drawer/MDrawer.figma.ts +37 -0
  51. package/src/components/drawer/README.md +1 -1
  52. package/src/components/field/MField.figma.ts +30 -0
  53. package/src/components/field/MField.stories.ts +105 -0
  54. package/src/components/fileuploader/MFileUploader.figma.ts +23 -0
  55. package/src/components/fileuploaderitem/MFileUploaderItem.figma.ts +27 -0
  56. package/src/components/flag/MFlag.figma.ts +26 -0
  57. package/src/components/iconbutton/MIconButton.figma.ts +54 -0
  58. package/src/components/kpiitem/MKpiItem.figma.ts +33 -0
  59. package/src/components/linearprogressbarbuffer/MLinearProgressbarBuffer.figma.ts +31 -0
  60. package/src/components/linearprogressbarpercentage/MLinearProgressbarPercentage.figma.ts +26 -0
  61. package/src/components/link/MLink.figma.ts +32 -0
  62. package/src/components/loader/MLoader.figma.ts +30 -0
  63. package/src/components/loadingoverlay/MLoadingOverlay.figma.ts +18 -0
  64. package/src/components/modal/MModal.figma.ts +27 -0
  65. package/src/components/navigationindicator/MNavigationIndicator.figma.ts +24 -0
  66. package/src/components/numberbadge/MNumberBadge.figma.ts +31 -0
  67. package/src/components/optionListbox/MOptionListbox.figma.ts +36 -0
  68. package/src/components/optionListbox/MOptionListbox.spec.ts +527 -0
  69. package/src/components/optionListbox/MOptionListbox.vue +470 -0
  70. package/src/components/optionListbox/README.md +63 -0
  71. package/src/components/overlay/MOverlay.figma.ts +20 -0
  72. package/src/components/pageheader/MPageHeader.figma.ts +21 -0
  73. package/src/components/pagination/MPagination.figma.ts +34 -0
  74. package/src/components/passwordinput/MPasswordInput.figma.ts +30 -0
  75. package/src/components/phonenumber/MPhoneNumber.figma.ts +47 -0
  76. package/src/components/pincode/MPincode.figma.ts +41 -0
  77. package/src/components/pincode/MPincode.spec.ts +1 -4
  78. package/src/components/pincode/MPincode.vue +11 -15
  79. package/src/components/popover/MPopover.figma.ts +42 -0
  80. package/src/components/quantityselector/MQuantitySelector.figma.ts +50 -0
  81. package/src/components/radio/MRadio.figma.ts +40 -0
  82. package/src/components/radiogroup/MRadioGroup.figma.ts +30 -0
  83. package/src/components/segmentedcontrol/MSegmentedControl.figma.ts +33 -0
  84. package/src/components/select/MSelect.figma.ts +49 -0
  85. package/src/components/sidebar/MSidebar.figma.ts +28 -0
  86. package/src/components/sidebarexpandableitem/MSidebarExpandableItem.figma.ts +19 -0
  87. package/src/components/sidebarfooter/MSidebarFooter.figma.ts +21 -0
  88. package/src/components/sidebarheader/MSidebarHeader.figma.ts +18 -0
  89. package/src/components/sidebarnavitem/MSidebarNavItem.figma.ts +23 -0
  90. package/src/components/sidebarshortcutitem/MSidebarShortcutItem.figma.ts +20 -0
  91. package/src/components/starrating/MStarRating.figma.ts +35 -0
  92. package/src/components/statusbadge/MStatusBadge.figma.ts +27 -0
  93. package/src/components/statusdot/MStatusDot.figma.ts +31 -0
  94. package/src/components/statusmessage/MStatusMessage.figma.ts +28 -0
  95. package/src/components/statusmessage/MStatusMessage.spec.ts +15 -0
  96. package/src/components/statusmessage/MStatusMessage.stories.ts +4 -0
  97. package/src/components/statusmessage/MStatusMessage.vue +7 -0
  98. package/src/components/statusmessage/README.md +2 -0
  99. package/src/components/statusnotification/MStatusNotification.figma.ts +29 -0
  100. package/src/components/stepperbottombar/MStepperBottomBar.figma.ts +20 -0
  101. package/src/components/steppercompact/MStepperCompact.figma.ts +21 -0
  102. package/src/components/stepperinline/MStepperInline.figma.ts +23 -0
  103. package/src/components/stepperstacked/MStepperStacked.figma.ts +23 -0
  104. package/src/components/stepperstacked/MStepperStacked.spec.ts +162 -0
  105. package/src/components/stepperstacked/MStepperStacked.stories.ts +57 -0
  106. package/src/components/stepperstacked/MStepperStacked.vue +106 -0
  107. package/src/components/stepperstacked/README.md +15 -0
  108. package/src/components/tabs/MTabs.figma.ts +33 -0
  109. package/src/components/tag/MTag.figma.ts +26 -0
  110. package/src/components/tag/MTag.stories.ts +13 -3
  111. package/src/components/tag/MTag.vue +11 -1
  112. package/src/components/tag/README.md +6 -0
  113. package/src/components/textarea/MTextArea.figma.ts +28 -0
  114. package/src/components/textinput/MTextInput.figma.ts +51 -0
  115. package/src/components/textinput/MTextInput.vue +13 -1
  116. package/src/components/textinput/README.md +15 -1
  117. package/src/components/tile/MTile.figma.ts +31 -0
  118. package/src/components/tileclickable/MTileClickable.figma.ts +31 -0
  119. package/src/components/tileexpandable/MTileExpandable.figma.ts +31 -0
  120. package/src/components/tileselectable/MTileSelectable.figma.ts +29 -0
  121. package/src/components/toaster/MToaster.figma.ts +25 -0
  122. package/src/components/toggle/MToggle.figma.ts +39 -0
  123. package/src/components/togglegroup/MToggleGroup.figma.ts +30 -0
  124. package/src/components/tooltip/MTooltip.figma.ts +29 -0
  125. 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
- ></MTag>
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
+ );