@mozaic-ds/vue 2.11.0 → 2.13.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 +1 -1
  2. package/dist/mozaic-vue.d.ts +791 -353
  3. package/dist/mozaic-vue.js +2945 -2404
  4. package/dist/mozaic-vue.js.map +1 -1
  5. package/dist/mozaic-vue.umd.cjs +5 -5
  6. package/dist/mozaic-vue.umd.cjs.map +1 -1
  7. package/package.json +7 -6
  8. package/src/components/{usingPresets.mdx → BrandPresets.mdx} +2 -2
  9. package/src/components/Changelog.mdx +19 -0
  10. package/src/components/Color.mdx +226 -0
  11. package/src/components/Contributing.mdx +12 -6
  12. package/src/components/GettingStarted.mdx +1 -1
  13. package/src/components/Icon.stories.ts +134 -0
  14. package/src/components/Welcome.mdx +49 -0
  15. package/src/components/accordionlist/MAccordionList.spec.ts +136 -0
  16. package/src/components/accordionlist/MAccordionList.stories.ts +123 -0
  17. package/src/components/accordionlist/MAccordionList.vue +91 -0
  18. package/src/components/accordionlist/README.md +24 -0
  19. package/src/components/accordionlist/m-accordion-list.const.ts +9 -0
  20. package/src/components/accordionlistitem/MAccordionListItem.spec.ts +123 -0
  21. package/src/components/accordionlistitem/MAccordionListItem.vue +95 -0
  22. package/src/components/accordionlistitem/README.md +23 -0
  23. package/src/components/actionbottombar/MActionBottomBar.spec.ts +52 -0
  24. package/src/components/actionbottombar/MActionBottomBar.stories.ts +162 -0
  25. package/src/components/actionbottombar/MActionBottomBar.vue +45 -0
  26. package/src/components/actionbottombar/README.md +31 -0
  27. package/src/components/actionlistbox/MActionListbox.spec.ts +134 -0
  28. package/src/components/actionlistbox/MActionListbox.stories.ts +74 -0
  29. package/src/components/actionlistbox/MActionListbox.vue +89 -0
  30. package/src/components/actionlistbox/README.md +25 -0
  31. package/src/components/avatar/MAvatar.stories.ts +1 -1
  32. package/src/components/breadcrumb/README.md +14 -0
  33. package/src/components/builtinmenu/MBuiltInMenu.spec.ts +111 -0
  34. package/src/components/builtinmenu/MBuiltInMenu.stories.ts +59 -0
  35. package/src/components/builtinmenu/MBuiltInMenu.vue +110 -0
  36. package/src/components/builtinmenu/README.md +32 -0
  37. package/src/components/button/MButton.spec.ts +1 -1
  38. package/src/components/button/MButton.stories.ts +165 -5
  39. package/src/components/button/README.md +33 -1
  40. package/src/components/callout/MCallout.spec.ts +7 -6
  41. package/src/components/callout/MCallout.stories.ts +1 -2
  42. package/src/components/carousel/MCarousel.spec.ts +1 -2
  43. package/src/components/carousel/MCarousel.stories.ts +2 -1
  44. package/src/components/carousel/MCarousel.vue +1 -2
  45. package/src/components/carousel/README.md +14 -0
  46. package/src/components/checkbox/README.md +14 -0
  47. package/src/components/checkboxgroup/README.md +14 -0
  48. package/src/components/checklistmenu/MCheckListMenu.spec.ts +77 -0
  49. package/src/components/checklistmenu/MCheckListMenu.stories.ts +47 -0
  50. package/src/components/checklistmenu/MCheckListMenu.vue +61 -0
  51. package/src/components/checklistmenu/README.md +32 -0
  52. package/src/components/circularprogressbar/README.md +15 -1
  53. package/src/components/datepicker/MDatepicker.vue +1 -1
  54. package/src/components/divider/README.md +22 -0
  55. package/src/components/drawer/MDrawer.vue +1 -2
  56. package/src/components/drawer/README.md +16 -0
  57. package/src/components/field/README.md +14 -0
  58. package/src/components/fileuploader/MFileUploader.spec.ts +304 -0
  59. package/src/components/fileuploader/MFileUploader.stories.ts +123 -0
  60. package/src/components/fileuploader/MFileUploader.vue +314 -0
  61. package/src/components/fileuploader/README.md +58 -0
  62. package/src/components/fileuploaderitem/MFileUploaderItem.spec.ts +91 -0
  63. package/src/components/fileuploaderitem/MFileUploaderItem.vue +180 -0
  64. package/src/components/fileuploaderitem/README.md +58 -0
  65. package/src/components/flag/README.md +1 -1
  66. package/src/components/iconbutton/MIconButton.spec.ts +1 -1
  67. package/src/components/iconbutton/MIconButton.stories.ts +116 -7
  68. package/src/components/iconbutton/README.md +25 -1
  69. package/src/components/kpiitem/MKpiItem.vue +5 -3
  70. package/src/components/linearprogressbarbuffer/README.md +14 -0
  71. package/src/components/link/MLink.stories.ts +1 -2
  72. package/src/components/link/README.md +14 -0
  73. package/src/components/loader/README.md +20 -0
  74. package/src/components/loadingoverlay/README.md +14 -0
  75. package/src/components/modal/MModal.stories.ts +1 -2
  76. package/src/components/modal/MModal.vue +1 -1
  77. package/src/components/modal/README.md +16 -0
  78. package/src/components/numberbadge/README.md +17 -1
  79. package/src/components/overlay/README.md +16 -0
  80. package/src/components/pagination/MPagination.vue +1 -2
  81. package/src/components/pagination/README.md +18 -0
  82. package/src/components/passwordinput/MPasswordInput.vue +1 -1
  83. package/src/components/passwordinput/README.md +14 -0
  84. package/src/components/phonenumber/MPhoneNumber.spec.ts +7 -6
  85. package/src/components/phonenumber/MPhoneNumber.vue +1 -1
  86. package/src/components/quantityselector/MQuantitySelector.vue +1 -2
  87. package/src/components/radio/README.md +14 -0
  88. package/src/components/radiogroup/README.md +14 -0
  89. package/src/components/select/README.md +14 -0
  90. package/src/components/starrating/MStarRating.spec.ts +1 -2
  91. package/src/components/starrating/MStarRating.vue +1 -3
  92. package/src/components/statusbadge/README.md +14 -0
  93. package/src/components/statusdot/README.md +14 -0
  94. package/src/components/statusmessage/MStatusMessage.spec.ts +6 -4
  95. package/src/components/statusmessage/MStatusMessage.vue +6 -4
  96. package/src/components/statusmessage/README.md +14 -0
  97. package/src/components/statusnotification/MStatusNotification.spec.ts +6 -4
  98. package/src/components/statusnotification/MStatusNotification.stories.ts +1 -1
  99. package/src/components/statusnotification/MStatusNotification.vue +7 -5
  100. package/src/components/statusnotification/README.md +14 -0
  101. package/src/components/stepperbottombar/MStepperBottomBar.spec.ts +134 -0
  102. package/src/components/stepperbottombar/MStepperBottomBar.stories.ts +72 -0
  103. package/src/components/stepperbottombar/MStepperBottomBar.vue +131 -0
  104. package/src/components/stepperbottombar/README.md +40 -0
  105. package/src/components/steppercompact/README.md +14 -0
  106. package/src/components/stepperinline/MStepperInline.spec.ts +78 -0
  107. package/src/components/stepperinline/MStepperInline.stories.ts +49 -0
  108. package/src/components/stepperinline/MStepperInline.vue +93 -0
  109. package/src/components/stepperinline/README.md +11 -0
  110. package/src/components/tabs/MTabs.stories.ts +1 -1
  111. package/src/components/tabs/README.md +16 -0
  112. package/src/components/tag/MTag.vue +1 -1
  113. package/src/components/tag/README.md +14 -0
  114. package/src/components/textinput/MTextInput.spec.ts +1 -1
  115. package/src/components/textinput/MTextInput.stories.ts +1 -1
  116. package/src/components/textinput/MTextInput.vue +1 -1
  117. package/src/components/toaster/MToaster.spec.ts +6 -4
  118. package/src/components/toaster/MToaster.vue +7 -5
  119. package/src/components/toaster/README.md +16 -0
  120. package/src/components/toggle/README.md +14 -0
  121. package/src/components/togglegroup/README.md +14 -0
  122. package/src/main.ts +8 -0
  123. package/src/components/Introduction.mdx +0 -100
  124. package/src/components/Support.mdx +0 -18
  125. package/src/components/usingIcons.mdx +0 -35
@@ -13,10 +13,12 @@
13
13
 
14
14
  <script setup lang="ts">
15
15
  import { computed } from 'vue';
16
- import InfoCircleFilled24 from '@mozaic-ds/icons-vue/src/components/InfoCircleFilled24/InfoCircleFilled24.vue';
17
- import WarningCircleFilled24 from '@mozaic-ds/icons-vue/src/components/WarningCircleFilled24/WarningCircleFilled24.vue';
18
- import CrossCircleFilled24 from '@mozaic-ds/icons-vue/src/components/CrossCircleFilled24/CrossCircleFilled24.vue';
19
- import CheckCircleFilled24 from '@mozaic-ds/icons-vue/src/components/CheckCircleFilled24/CheckCircleFilled24.vue';
16
+ import {
17
+ InfoCircleFilled24,
18
+ WarningCircleFilled24,
19
+ CrossCircleFilled24,
20
+ CheckCircleFilled24,
21
+ } from '@mozaic-ds/icons-vue';
20
22
  import MLoader from '../loader/MLoader.vue';
21
23
  /**
22
24
  * A Status Message is a compact component that combines an icon and concise text to communicate system states or user feedback in limited interface space. The icon and message work together as a unified structure to provide clear, immediate understanding of the current status. Status Messages are designed for contexts where space is constrained but clear communication is essential, offering quick recognition through color-coded icons paired with brief, actionable text.
@@ -9,3 +9,17 @@ A Status Message is a compact component that combines an icon and concise text t
9
9
  | --- | --- | --- | --- |
10
10
  | `status` | Allows to define the status message style. | `"info"` `"warning"` `"error"` `"success"` `"neutral"` `"inprogress"` | `"info"` |
11
11
  | `label*` | Label of the status message. | `string` | - |
12
+
13
+ ## Dependencies
14
+
15
+ ### Depends on
16
+
17
+ - [MLoader](../loader)
18
+
19
+ ### Graph
20
+
21
+ ```mermaid
22
+ graph TD;
23
+ MStatusMessage --> MLoader
24
+ style MStatusMessage fill:#008240,stroke:#333,stroke-width:4px
25
+ ```
@@ -1,10 +1,12 @@
1
1
  import { mount } from '@vue/test-utils';
2
2
  import { describe, it, expect } from 'vitest';
3
3
  import MStatusNotification from './MStatusNotification.vue';
4
- import InfoCircleFilled32 from '@mozaic-ds/icons-vue/src/components/InfoCircleFilled32/InfoCircleFilled32.vue';
5
- import WarningCircleFilled32 from '@mozaic-ds/icons-vue/src/components/WarningCircleFilled32/WarningCircleFilled32.vue';
6
- import CrossCircleFilled32 from '@mozaic-ds/icons-vue/src/components/CrossCircleFilled32/CrossCircleFilled32.vue';
7
- import CheckCircleFilled32 from '@mozaic-ds/icons-vue/src/components/CheckCircleFilled32/CheckCircleFilled32.vue';
4
+ import {
5
+ InfoCircleFilled32,
6
+ WarningCircleFilled32,
7
+ CrossCircleFilled32,
8
+ CheckCircleFilled32,
9
+ } from '@mozaic-ds/icons-vue';
8
10
 
9
11
  describe('MStatusNotification.vue', () => {
10
12
  it('should render correctly with the default props', () => {
@@ -3,7 +3,7 @@ import MStatusNotification from './MStatusNotification.vue';
3
3
  import { action } from 'storybook/actions';
4
4
  import MButton from '../button/MButton.vue';
5
5
  import MLink from '../link/MLink.vue';
6
- import ArrowNext20 from '@mozaic-ds/icons-vue/src/components/ArrowNext20/ArrowNext20.vue';
6
+ import { ArrowNext20 } from '@mozaic-ds/icons-vue';
7
7
 
8
8
  const meta: Meta<typeof MStatusNotification> = {
9
9
  title: 'Status/Status Notification',
@@ -34,11 +34,13 @@
34
34
 
35
35
  <script setup lang="ts">
36
36
  import { computed, type VNode } from 'vue';
37
- import Cross20 from '@mozaic-ds/icons-vue/src/components/Cross20/Cross20.vue';
38
- import InfoCircleFilled32 from '@mozaic-ds/icons-vue/src/components/InfoCircleFilled32/InfoCircleFilled32.vue';
39
- import WarningCircleFilled32 from '@mozaic-ds/icons-vue/src/components/WarningCircleFilled32/WarningCircleFilled32.vue';
40
- import CrossCircleFilled32 from '@mozaic-ds/icons-vue/src/components/CrossCircleFilled32/CrossCircleFilled32.vue';
41
- import CheckCircleFilled32 from '@mozaic-ds/icons-vue/src/components/CheckCircleFilled32/CheckCircleFilled32.vue';
37
+ import {
38
+ Cross20,
39
+ InfoCircleFilled32,
40
+ WarningCircleFilled32,
41
+ CrossCircleFilled32,
42
+ CheckCircleFilled32,
43
+ } from '@mozaic-ds/icons-vue';
42
44
  import MIconButton from '../iconbutton/MIconButton.vue';
43
45
  /**
44
46
  * A Status Notification is used to draw the user’s attention to important information that needs to be acknowledged. It often provides feedback on a process, highlights a status update, or alerts users about an issue. Notifications are typically triggered by user actions or system events and are designed to be easily noticeable while maintaining a non-intrusive experience.
@@ -23,3 +23,17 @@ A Status Notification is used to draw the user’s attention to important inform
23
23
  | Name | Description | Type |
24
24
  | --- | --- | --- |
25
25
  | `close` | Emits when closing the notification. | [] |
26
+
27
+ ## Dependencies
28
+
29
+ ### Depends on
30
+
31
+ - [MIconButton](../iconbutton)
32
+
33
+ ### Graph
34
+
35
+ ```mermaid
36
+ graph TD;
37
+ MStatusNotification --> MIconButton
38
+ style MStatusNotification fill:#008240,stroke:#333,stroke-width:4px
39
+ ```
@@ -0,0 +1,134 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { mount } from '@vue/test-utils';
3
+ import MStepperBottomBar from './MStepperBottomBar.vue';
4
+
5
+ const globalStubs = {
6
+ MButton: {
7
+ emits: ['click'],
8
+ template: `<button @click="$emit('click', $event)"><slot /></button>`,
9
+ },
10
+ MDivider: {
11
+ template: `<hr />`,
12
+ },
13
+ };
14
+
15
+ describe('MStepperBottomBar component', () => {
16
+ it('renders cancel button by default', () => {
17
+ const wrapper = mount(MStepperBottomBar, {
18
+ global: { stubs: globalStubs },
19
+ });
20
+
21
+ expect(wrapper.text()).toContain('Cancel');
22
+ });
23
+
24
+ it('does not render cancel button when cancel is false', () => {
25
+ const wrapper = mount(MStepperBottomBar, {
26
+ props: { cancel: false },
27
+ global: { stubs: globalStubs },
28
+ });
29
+
30
+ expect(wrapper.text()).not.toContain('Cancel');
31
+ });
32
+
33
+ it('does not render previous button when step is 0', () => {
34
+ const wrapper = mount(MStepperBottomBar, {
35
+ props: { modelValue: 0 },
36
+ global: { stubs: globalStubs },
37
+ });
38
+
39
+ expect(wrapper.text()).not.toContain('Previous');
40
+ });
41
+
42
+ it('renders previous button when step > 0', () => {
43
+ const wrapper = mount(MStepperBottomBar, {
44
+ props: { modelValue: 1 },
45
+ global: { stubs: globalStubs },
46
+ });
47
+
48
+ expect(wrapper.text()).toContain('Previous');
49
+ });
50
+
51
+ it('emits update:modelValue with decremented value on previous click', async () => {
52
+ const wrapper = mount(MStepperBottomBar, {
53
+ props: { modelValue: 2 },
54
+ global: { stubs: globalStubs },
55
+ });
56
+
57
+ const buttons = wrapper.findAll('button');
58
+ const previousButton = buttons.find((b) => b.text() === 'Previous')!;
59
+
60
+ await previousButton.trigger('click');
61
+
62
+ const emitted = wrapper.emitted('update:modelValue')!;
63
+ expect(emitted.at(-1)).toEqual([1]);
64
+ });
65
+
66
+ it('emits update:modelValue with incremented value on next click', async () => {
67
+ const wrapper = mount(MStepperBottomBar, {
68
+ props: {
69
+ modelValue: 1,
70
+ steps: 3,
71
+ },
72
+ global: { stubs: globalStubs },
73
+ });
74
+
75
+ const nextButton = wrapper
76
+ .findAll('button')
77
+ .find((b) => b.text() === 'Next')!;
78
+
79
+ await nextButton.trigger('click');
80
+
81
+ const emitted = wrapper.emitted('update:modelValue')!;
82
+ expect(emitted.at(-1)).toEqual([2]);
83
+ });
84
+
85
+ it('emits validate when clicking next on last step', async () => {
86
+ const wrapper = mount(MStepperBottomBar, {
87
+ props: {
88
+ modelValue: 3,
89
+ steps: 3,
90
+ },
91
+ global: { stubs: globalStubs },
92
+ });
93
+
94
+ const validateButton = wrapper
95
+ .findAll('button')
96
+ .find((b) => b.text() === 'Validate')!;
97
+
98
+ await validateButton.trigger('click');
99
+
100
+ expect(wrapper.emitted('validate')).toBeTruthy();
101
+ });
102
+
103
+ it('emits cancel when cancel button is clicked', async () => {
104
+ const wrapper = mount(MStepperBottomBar, {
105
+ global: { stubs: globalStubs },
106
+ });
107
+
108
+ const cancelButton = wrapper
109
+ .findAll('button')
110
+ .find((b) => b.text() === 'Cancel')!;
111
+
112
+ await cancelButton.trigger('click');
113
+
114
+ expect(wrapper.emitted('cancel')).toBeTruthy();
115
+ });
116
+
117
+ it('renders custom labels', () => {
118
+ const wrapper = mount(MStepperBottomBar, {
119
+ props: {
120
+ cancelLabel: 'Abort',
121
+ previousLabel: 'Back',
122
+ nextLabel: 'Continue',
123
+ validateLabel: 'Submit',
124
+ modelValue: 1,
125
+ steps: 1,
126
+ },
127
+ global: { stubs: globalStubs },
128
+ });
129
+
130
+ expect(wrapper.text()).toContain('Abort');
131
+ expect(wrapper.text()).toContain('Back');
132
+ expect(wrapper.text()).toContain('Submit');
133
+ });
134
+ });
@@ -0,0 +1,72 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3-vite';
2
+ import { action } from 'storybook/actions';
3
+
4
+ import MStepperBottomBar from './MStepperBottomBar.vue';
5
+
6
+ const meta: Meta<typeof MStepperBottomBar> = {
7
+ title: 'Structure/Stepper Bottom Bar',
8
+ component: MStepperBottomBar,
9
+ tags: ['v2'],
10
+ parameters: {
11
+ layout: 'fullscreen',
12
+ docs: {
13
+ story: { height: '200px' },
14
+ description: {
15
+ component:
16
+ 'A stepper bottom bar is a persistent navigation component used to guide users through a multi-step process. It typically includes “Previous” and “Next” buttons, along with optional actions such as “Cancel” or “Validate”, ensuring a structured flow. This component is commonly used in forms, onboarding sequences, and checkout processes, improving usability by keeping navigation actions always accessible.',
17
+ },
18
+ },
19
+ },
20
+ argTypes: {
21
+ // @ts-expect-error: custom css property
22
+ '--stepper-bottom-bar-z-index': {
23
+ description: 'Customise the z-index of the stepper bottom bar',
24
+ control: false,
25
+ table: {
26
+ category: 'Custom Properties',
27
+ type: { summary: 'number' },
28
+ defaultValue: { summary: '3' },
29
+ },
30
+ },
31
+ },
32
+ args: {
33
+ steps: 3,
34
+ modelValue: 0,
35
+ },
36
+ render: (args) => ({
37
+ components: { MStepperBottomBar },
38
+ setup() {
39
+ const onUpdate = action('update:modelValue');
40
+ const onCancel = action('cancel');
41
+ const onValidate = action('validate');
42
+
43
+ return { args, onUpdate, onCancel, onValidate };
44
+ },
45
+ template: `
46
+ <MStepperBottomBar
47
+ v-bind="args"
48
+ @update:modelValue="onUpdate"
49
+ @cancel="onCancel"
50
+ @validate="onValidate"
51
+ />
52
+ `,
53
+ }),
54
+ };
55
+
56
+ export default meta;
57
+
58
+ type Story = StoryObj<typeof MStepperBottomBar>;
59
+
60
+ export const First: Story = {};
61
+
62
+ export const Middle: Story = {
63
+ args: {
64
+ modelValue: 2,
65
+ },
66
+ };
67
+
68
+ export const Last: Story = {
69
+ args: {
70
+ modelValue: 3,
71
+ },
72
+ };
@@ -0,0 +1,131 @@
1
+ <template>
2
+ <div class="mc-stepper-bottom-bar">
3
+ <MDivider class="mc-stepper-bottom-bar__divider" />
4
+ <div class="mc-stepper-bottom-bar__left">
5
+ <MButton
6
+ v-if="cancel"
7
+ type="button"
8
+ ghost
9
+ size="s"
10
+ @click="emit('cancel')"
11
+ >
12
+ {{ cancelLabel }}
13
+ </MButton>
14
+ </div>
15
+
16
+ <div class="mc-stepper-bottom-bar__right">
17
+ <MButton
18
+ v-if="currentStep > 0"
19
+ type="button"
20
+ outlined
21
+ size="s"
22
+ @click="onPrevious"
23
+ >
24
+ {{ previousLabel }}
25
+ </MButton>
26
+
27
+ <MButton type="button" appearance="accent" size="s" @click="onNext">
28
+ {{ currentStep < steps ? nextLabel : validateLabel }}
29
+ </MButton>
30
+ </div>
31
+ </div>
32
+ </template>
33
+
34
+ <script setup lang="ts">
35
+ import { ref, watch } from 'vue';
36
+ import MButton from '../button/MButton.vue';
37
+ import MDivider from '../divider/MDivider.vue';
38
+ /**
39
+ * A stepper bottom bar is a persistent navigation component used to guide users through a multi-step process. It typically includes “Previous” and “Next” buttons, along with optional actions such as “Cancel” or “Validate”, ensuring a structured flow. This component is commonly used in forms, onboarding sequences, and checkout processes, improving usability by keeping navigation actions always accessible.
40
+ */
41
+ const props = withDefaults(
42
+ defineProps<{
43
+ /**
44
+ * Current step of the stepper compact.
45
+ */
46
+ modelValue?: number;
47
+ /**
48
+ * Total number of steps of the stepper compact.
49
+ */
50
+ steps?: number;
51
+ /**
52
+ * If `true`, display the cancel button.
53
+ */
54
+ cancel?: boolean;
55
+ /**
56
+ * Label for the cancel button.
57
+ */
58
+ cancelLabel?: string;
59
+ /**
60
+ * Label for the previous button.
61
+ */
62
+ previousLabel?: string;
63
+ /**
64
+ * Label for the next button.
65
+ */
66
+ nextLabel?: string;
67
+ /**
68
+ * Label for the validate button.
69
+ */
70
+ validateLabel?: string;
71
+ }>(),
72
+ {
73
+ steps: 0,
74
+ modelValue: 0,
75
+ cancel: true,
76
+ cancelLabel: 'Cancel',
77
+ previousLabel: 'Previous',
78
+ nextLabel: 'Next',
79
+ validateLabel: 'Validate',
80
+ },
81
+ );
82
+
83
+ const emit = defineEmits<{
84
+ /**
85
+ * Emits when the cancel button is clicked.
86
+ */
87
+ (on: 'cancel'): void;
88
+ /**
89
+ * Emits when the step change.
90
+ */
91
+ (on: 'update:modelValue', value: number): void;
92
+ /**
93
+ * Emits when the validate button is clicked.
94
+ */
95
+ (on: 'validate'): void;
96
+ }>();
97
+
98
+ const currentStep = ref(0);
99
+
100
+ watch(
101
+ () => props.modelValue,
102
+ (value) => {
103
+ if (value !== undefined) {
104
+ currentStep.value = value;
105
+ }
106
+ },
107
+ { immediate: true },
108
+ );
109
+
110
+ watch(currentStep, (value) => {
111
+ emit('update:modelValue', value);
112
+ });
113
+
114
+ const onPrevious = () => {
115
+ if (currentStep.value > 0) {
116
+ currentStep.value--;
117
+ }
118
+ };
119
+
120
+ const onNext = () => {
121
+ if (currentStep.value < props.steps) {
122
+ currentStep.value++;
123
+ } else {
124
+ emit('validate');
125
+ }
126
+ };
127
+ </script>
128
+
129
+ <style lang="scss" scoped>
130
+ @use '@mozaic-ds/styles/components/stepper-bottom-bar';
131
+ </style>
@@ -0,0 +1,40 @@
1
+ # MStepperBottomBar
2
+
3
+ A stepper bottom bar is a persistent navigation component used to guide users through a multi-step process. It typically includes “Previous” and “Next” buttons, along with optional actions such as “Cancel” or “Validate”, ensuring a structured flow. This component is commonly used in forms, onboarding sequences, and checkout processes, improving usability by keeping navigation actions always accessible.
4
+
5
+
6
+ ## Props
7
+
8
+ | Name | Description | Type | Default |
9
+ | --- | --- | --- | --- |
10
+ | `modelValue` | Current step of the stepper compact. | `number` | `0` |
11
+ | `steps` | Total number of steps of the stepper compact. | `number` | `0` |
12
+ | `cancel` | If `true`, display the cancel button. | `boolean` | `true` |
13
+ | `cancelLabel` | Label for the cancel button. | `string` | `"Cancel"` |
14
+ | `previousLabel` | Label for the previous button. | `string` | `"Previous"` |
15
+ | `nextLabel` | Label for the next button. | `string` | `"Next"` |
16
+ | `validateLabel` | Label for the validate button. | `string` | `"Validate"` |
17
+
18
+ ## Events
19
+
20
+ | Name | Description | Type |
21
+ | --- | --- | --- |
22
+ | `update:modelValue` | Emits when the step change. | [value: number] |
23
+ | `cancel` | Emits when the cancel button is clicked. | [] |
24
+ | `validate` | Emits when the validate button is clicked. | [] |
25
+
26
+ ## Dependencies
27
+
28
+ ### Depends on
29
+
30
+ - [MButton](../button)
31
+ - [MDivider](../divider)
32
+
33
+ ### Graph
34
+
35
+ ```mermaid
36
+ graph TD;
37
+ MStepperBottomBar --> MButton
38
+ MStepperBottomBar --> MDivider
39
+ style MStepperBottomBar fill:#008240,stroke:#333,stroke-width:4px
40
+ ```
@@ -11,3 +11,17 @@ A stepper is a navigation component that guides users through a sequence of step
11
11
  | `maxSteps` | Maximum number of steps for the stepper compact. | `number` | `4` |
12
12
  | `label*` | Label of the stepper compact. | `string` | - |
13
13
  | `description` | Description displayed below the label of the stepper compact. | `string` | - |
14
+
15
+ ## Dependencies
16
+
17
+ ### Depends on
18
+
19
+ - [MCircularProgressbar](../circularprogressbar)
20
+
21
+ ### Graph
22
+
23
+ ```mermaid
24
+ graph TD;
25
+ MStepperCompact --> MCircularProgressbar
26
+ style MStepperCompact fill:#008240,stroke:#333,stroke-width:4px
27
+ ```
@@ -0,0 +1,78 @@
1
+ import { mount } from '@vue/test-utils';
2
+ import MStepperInline from './MStepperInline.vue';
3
+ import { describe, it, expect } from 'vitest';
4
+
5
+ describe('MStepperInline', () => {
6
+ const defaultSteps = [
7
+ { label: 'Step 1' },
8
+ { label: 'Step 2' },
9
+ { label: 'Step 3' },
10
+ ];
11
+
12
+ it('renders correctly with default props', () => {
13
+ const wrapper = mount(MStepperInline, {
14
+ props: {
15
+ currentStep: 1,
16
+ steps: defaultSteps,
17
+ },
18
+ });
19
+
20
+ expect(wrapper.exists()).toBe(true);
21
+ expect(wrapper.findAll('.mc-stepper-inline__item').length).toBe(
22
+ defaultSteps.length,
23
+ );
24
+ expect(wrapper.find('.mc-stepper-inline__label').text()).toContain(
25
+ 'Step 1',
26
+ );
27
+ });
28
+
29
+ it('displays additional information when provided', () => {
30
+ const stepsWithInfo = [
31
+ { label: 'Step 1', additionalInfo: 'Info 1' },
32
+ { label: 'Step 2', additionalInfo: 'Info 2' },
33
+ ];
34
+ const wrapper = mount(MStepperInline, {
35
+ props: {
36
+ currentStep: 1,
37
+ steps: stepsWithInfo,
38
+ },
39
+ });
40
+
41
+ expect(wrapper.findAll('.mc-stepper-inline__additional').length).toBe(
42
+ stepsWithInfo.length,
43
+ );
44
+ expect(wrapper.find('.mc-stepper-inline__additional').text()).toBe(
45
+ 'Info 1',
46
+ );
47
+ });
48
+
49
+ it('marks the correct step as active', async () => {
50
+ const wrapper = mount(MStepperInline, {
51
+ props: {
52
+ currentStep: 2,
53
+ steps: defaultSteps,
54
+ },
55
+ });
56
+
57
+ const labels = wrapper.findAll('.mc-stepper-inline__label');
58
+ expect(labels[1].classes()).toContain('is-current');
59
+ expect(labels[0].classes()).not.toContain('is-current');
60
+
61
+ await wrapper.setProps({ currentStep: 3 });
62
+ expect(labels[2].classes()).toContain('is-current');
63
+ });
64
+
65
+ it('marks completed steps', () => {
66
+ const wrapper = mount(MStepperInline, {
67
+ props: {
68
+ currentStep: 3,
69
+ steps: defaultSteps,
70
+ },
71
+ });
72
+
73
+ const items = wrapper.findAll('.mc-stepper-inline__item');
74
+ expect(items[0].classes()).toContain('is-completed');
75
+ expect(items[1].classes()).toContain('is-completed');
76
+ expect(items[2].classes()).not.toContain('is-completed');
77
+ });
78
+ });
@@ -0,0 +1,49 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3-vite';
2
+ import MStepperInline from './MStepperInline.vue';
3
+
4
+ const meta: Meta<typeof MStepperInline> = {
5
+ title: 'Indicators/Stepper Inline',
6
+ component: MStepperInline,
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
+ { label: 'Cart' },
20
+ { label: 'Delivery address' },
21
+ { label: 'Payment' },
22
+ { label: 'Order confirmation' },
23
+ ],
24
+ },
25
+ render: (args) => ({
26
+ components: { MStepperInline },
27
+ setup() {
28
+ return { args };
29
+ },
30
+ template: `<MStepperInline v-bind="args" />`,
31
+ }),
32
+ };
33
+
34
+ export default meta;
35
+ type Story = StoryObj<typeof MStepperInline>;
36
+
37
+ export const Default: Story = {};
38
+
39
+ export const AditionnalInfo: Story = {
40
+ args: {
41
+ currentStep: 2,
42
+ steps: [
43
+ { label: 'Cart', additionalInfo: 'Additional information' },
44
+ { label: 'Delivery address', additionalInfo: 'Additional information' },
45
+ { label: 'Payment', additionalInfo: 'Additional information' },
46
+ { label: 'Order confirmation', additionalInfo: 'Additional information' },
47
+ ],
48
+ },
49
+ };