@mozaic-ds/vue 2.9.0 → 2.11.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 (44) hide show
  1. package/README.md +4 -6
  2. package/dist/mozaic-vue.css +1 -1
  3. package/dist/mozaic-vue.d.ts +424 -249
  4. package/dist/mozaic-vue.js +1545 -1063
  5. package/dist/mozaic-vue.js.map +1 -1
  6. package/dist/mozaic-vue.umd.cjs +5 -5
  7. package/dist/mozaic-vue.umd.cjs.map +1 -1
  8. package/package.json +14 -13
  9. package/src/components/carousel/MCarousel.spec.ts +138 -0
  10. package/src/components/carousel/MCarousel.stories.ts +94 -0
  11. package/src/components/carousel/MCarousel.vue +154 -0
  12. package/src/components/carousel/README.md +18 -0
  13. package/src/components/flag/MFlag.stories.ts +1 -1
  14. package/src/components/kpiitem/MKpiItem.spec.ts +71 -0
  15. package/src/components/kpiitem/MKpiItem.stories.ts +69 -0
  16. package/src/components/kpiitem/MKpiItem.vue +89 -0
  17. package/src/components/kpiitem/README.md +15 -0
  18. package/src/components/loader/MLoader.spec.ts +2 -2
  19. package/src/components/loader/MLoader.vue +2 -2
  20. package/src/components/phonenumber/MPhoneNumber.spec.ts +110 -1
  21. package/src/components/phonenumber/MPhoneNumber.stories.ts +14 -0
  22. package/src/components/phonenumber/MPhoneNumber.vue +16 -6
  23. package/src/components/phonenumber/README.md +2 -0
  24. package/src/components/starrating/MStarRating.spec.ts +203 -0
  25. package/src/components/starrating/MStarRating.stories.ts +82 -0
  26. package/src/components/starrating/MStarRating.vue +187 -0
  27. package/src/components/starrating/README.md +31 -0
  28. package/src/components/statusbadge/README.md +1 -1
  29. package/src/components/statusdot/README.md +1 -1
  30. package/src/components/statusmessage/MStatusMessage.spec.ts +76 -0
  31. package/src/components/statusmessage/MStatusMessage.stories.ts +52 -0
  32. package/src/components/statusmessage/MStatusMessage.vue +70 -0
  33. package/src/components/statusmessage/README.md +11 -0
  34. package/src/components/statusnotification/README.md +1 -1
  35. package/src/components/steppercompact/MStepperCompact.spec.ts +98 -0
  36. package/src/components/steppercompact/MStepperCompact.stories.ts +43 -0
  37. package/src/components/steppercompact/MStepperCompact.vue +105 -0
  38. package/src/components/steppercompact/README.md +13 -0
  39. package/src/components/tag/MTag.vue +2 -1
  40. package/src/components/tag/README.md +1 -1
  41. package/src/components/textinput/MTextInput.stories.ts +1 -1
  42. package/src/components/toaster/README.md +1 -1
  43. package/src/components/usingPresets.mdx +1 -1
  44. package/src/main.ts +4 -0
@@ -0,0 +1,187 @@
1
+ <template>
2
+ <component
3
+ class="mc-star-rating"
4
+ :class="classObject"
5
+ :is="rootTag"
6
+ :href="props.href"
7
+ :to="props.href"
8
+ :target="props.target"
9
+ >
10
+ <div
11
+ class="mc-star-rating__wrapper"
12
+ :tabindex="isReadonly ? -1 : 0"
13
+ :role="isReadonly ? 'img' : 'slider'"
14
+ :aria-label="`Note ${displayValue} sur ${maxValue}`"
15
+ v-bind="
16
+ !isReadonly
17
+ ? {
18
+ 'aria-valuemin': 0,
19
+ 'aria-valuemax': maxValue,
20
+ 'aria-valuenow': rating,
21
+ 'aria-readonly': false,
22
+ }
23
+ : {}
24
+ "
25
+ v-on="
26
+ isReadonly
27
+ ? {}
28
+ : {
29
+ keydown: onKeydown,
30
+ mouseleave: clearHover,
31
+ blur: clearHover,
32
+ }
33
+ "
34
+ >
35
+ <component
36
+ v-for="(_, index) in maxValue"
37
+ :key="index"
38
+ :is="getStarComponent(index)"
39
+ class="mc-star-rating__icon"
40
+ v-on="
41
+ !isReadonly
42
+ ? {
43
+ mousemove: () => onHover(index),
44
+ click: () => onClick(index),
45
+ }
46
+ : {}
47
+ "
48
+ />
49
+ </div>
50
+
51
+ <span v-if="props.text || props.href" class="mc-star-rating__info">
52
+ {{ text || href }}
53
+ </span>
54
+ </component>
55
+ </template>
56
+
57
+ <script setup lang="ts">
58
+ import { computed, ref } from 'vue';
59
+ import Star24 from '@mozaic-ds/icons-vue/src/components/Star24/Star24.vue';
60
+ import StarFilled24 from '@mozaic-ds/icons-vue/src/components/StarFilled24/StarFilled24.vue';
61
+ import StarHalf24 from '@mozaic-ds/icons-vue/src/components/StarHalf24/StarHalf24.vue';
62
+
63
+ /**
64
+ * A Star rating visually represents a score or evaluation and can be used to display a rating or allow users to rate an item, such as a product or service. It serves two main purposes: collecting user feedback by enabling individuals to express their experience and providing social proof by displaying ratings from other users to assist decision-making. Rating Stars are commonly found in e-commerce, review systems, and feedback interfaces, offering a quick and intuitive way to assess quality or satisfaction.
65
+ */
66
+
67
+ const props = withDefaults(
68
+ defineProps<{
69
+ /**
70
+ * Determines whether the rating is interactive or read-only.
71
+ * When true, all user interactions (click, hover, keyboard) are disabled.
72
+ * Automatically set to true when `compact`, `href`, or `information` are provided.
73
+ *
74
+ */
75
+ readonly?: boolean;
76
+ /**
77
+ * Defines the visual size of the star icons and the accompanying text.
78
+ *
79
+ */
80
+ size?: 's' | 'm' | 'l';
81
+ /**
82
+ * Enables a compact display mode that shows only one star instead of five.
83
+ * Typically used for summaries or quick visual cues.
84
+ * When enabled, the component automatically becomes read-only.
85
+ *
86
+ */
87
+ compact?: boolean;
88
+ /**
89
+ * Specifies the color scheme of the stars.
90
+ *
91
+ */
92
+ appearance?: 'standard' | 'accent';
93
+ /**
94
+ * Optional text displayed next to the star rating.
95
+ * If provided, the component automatically becomes read-only.
96
+ */
97
+ text?: string;
98
+ /**
99
+ * URL for the link (for external links or the `to` prop for `router-link`).
100
+ */
101
+ href?: string;
102
+ /**
103
+ * Where to open the link.
104
+ */
105
+ target?: '_self' | '_blank' | '_parent' | '_top';
106
+ /**
107
+ * If `true`, the link will be rendered as a `router-link` for internal navigation (Vue Router).
108
+ */
109
+ router?: boolean;
110
+ }>(),
111
+ {
112
+ readonly: true,
113
+ size: 's',
114
+ compact: false,
115
+ appearance: 'accent',
116
+ },
117
+ );
118
+
119
+ const hover = ref<number | null>(null);
120
+
121
+ /**
122
+ * The current rating value of the component.
123
+ * Used with `v-model` for two-way data binding.
124
+ * When the rating changes (via click or keyboard), an `update:modelValue` event is emitted.
125
+ */
126
+ const rating = defineModel<number>({ required: true });
127
+
128
+ const rootTag = computed(() => {
129
+ if (props.href) return props.router ? 'router-link' : 'a';
130
+ return 'div';
131
+ });
132
+
133
+ const isReadonly = computed(() =>
134
+ [props.readonly, props.compact, props.href, props.text].some(Boolean),
135
+ );
136
+
137
+ const classObject = computed(() => ({
138
+ 'mc-star-rating--link': props.href,
139
+ 'mc-star-rating--slider': !isReadonly.value,
140
+ [`mc-star-rating--${props.size}`]: props.size,
141
+ [`mc-star-rating--${props.appearance}`]: props.appearance,
142
+ }));
143
+
144
+ const displayValue = computed(() => hover.value ?? rating.value);
145
+ const maxValue = computed(() => (props.compact ? 1 : 5));
146
+
147
+ function getStarComponent(index: number) {
148
+ if (props.compact || displayValue.value >= index + 1) {
149
+ return StarFilled24;
150
+ } else if (isReadonly.value && displayValue.value >= index + 0.5) {
151
+ return StarHalf24;
152
+ } else {
153
+ return Star24;
154
+ }
155
+ }
156
+
157
+ function onHover(index: number) {
158
+ hover.value = index + 1;
159
+ }
160
+
161
+ function clearHover() {
162
+ hover.value = null;
163
+ }
164
+
165
+ function onClick(index: number) {
166
+ rating.value = index + 1;
167
+ }
168
+
169
+ function onKeydown(e: KeyboardEvent) {
170
+ const key = e.key;
171
+ let newValue = Math.floor(rating.value);
172
+
173
+ if (key === 'ArrowRight') {
174
+ newValue = Math.min(maxValue.value, newValue + 1);
175
+ } else if (key === 'ArrowLeft') {
176
+ newValue = Math.max(1, newValue - 1);
177
+ } else return;
178
+
179
+ rating.value = newValue;
180
+
181
+ e.preventDefault();
182
+ }
183
+ </script>
184
+
185
+ <style lang="scss" scoped>
186
+ @use '@mozaic-ds/styles/components/star-rating';
187
+ </style>
@@ -0,0 +1,31 @@
1
+ # MStarRating
2
+
3
+ A Star rating visually represents a score or evaluation and can be used to display a rating or allow users to rate an item, such as a product or service. It serves two main purposes: collecting user feedback by enabling individuals to express their experience and providing social proof by displaying ratings from other users to assist decision-making. Rating Stars are commonly found in e-commerce, review systems, and feedback interfaces, offering a quick and intuitive way to assess quality or satisfaction.
4
+
5
+
6
+ ## Props
7
+
8
+ | Name | Description | Type | Default |
9
+ | --- | --- | --- | --- |
10
+ | `readonly` | Determines whether the rating is interactive or read-only.
11
+ When true, all user interactions (click, hover, keyboard) are disabled.
12
+ Automatically set to true when `compact`, `href`, or `information` are provided. | `boolean` | `true` |
13
+ | `size` | Defines the visual size of the star icons and the accompanying text. | `"s"` `"m"` `"l"` | `"s"` |
14
+ | `compact` | Enables a compact display mode that shows only one star instead of five.
15
+ Typically used for summaries or quick visual cues.
16
+ When enabled, the component automatically becomes read-only. | `boolean` | `false` |
17
+ | `appearance` | Specifies the color scheme of the stars. | `"standard"` `"accent"` | `"accent"` |
18
+ | `text` | Optional text displayed next to the star rating.
19
+ If provided, the component automatically becomes read-only. | `string` | - |
20
+ | `href` | URL for the link (for external links or the `to` prop for `router-link`). | `string` | - |
21
+ | `target` | Where to open the link. | `"_self"` `"_blank"` `"_parent"` `"_top"` | - |
22
+ | `router` | If `true`, the link will be rendered as a `router-link` for internal navigation (Vue Router). | `boolean` | - |
23
+ | `modelValue*` | The current rating value of the component.
24
+ Used with `v-model` for two-way data binding.
25
+ When the rating changes (via click or keyboard), an `update:modelValue` event is emitted. | `number` | - |
26
+
27
+ ## Events
28
+
29
+ | Name | Description | Type |
30
+ | --- | --- | --- |
31
+ | `update:modelValue` | - | `[value: number]` |
@@ -8,4 +8,4 @@ A Status Badge is used to indicate the current status of an element, providing a
8
8
  | Name | Description | Type | Default |
9
9
  | --- | --- | --- | --- |
10
10
  | `label*` | Content of the status badge | `string` | - |
11
- | `status` | Allows to define the status badge type | `"info"` `"success"` `"warning"` `"error"` `"neutral"` | `"info"` |
11
+ | `status` | Allows to define the status badge type | `"info"` `"warning"` `"error"` `"success"` `"neutral"` | `"info"` |
@@ -7,5 +7,5 @@ A Status dot is a small visual indicator used to represent the state or conditio
7
7
 
8
8
  | Name | Description | Type | Default |
9
9
  | --- | --- | --- | --- |
10
- | `status` | Allows to define the status dot type. | `"info"` `"success"` `"warning"` `"error"` `"neutral"` | `"info"` |
10
+ | `status` | Allows to define the status dot type. | `"info"` `"warning"` `"error"` `"success"` `"neutral"` | `"info"` |
11
11
  | `size` | Determines the size of the status dot. | `"s"` `"m"` `"l"` | - |
@@ -0,0 +1,76 @@
1
+ import { mount } from '@vue/test-utils';
2
+ import { describe, it, expect } from 'vitest';
3
+ import MStatusMessage from './MStatusMessage.vue';
4
+
5
+ import InfoCircleFilled24 from '@mozaic-ds/icons-vue/src/components/InfoCircleFilled24/InfoCircleFilled24.vue';
6
+ import WarningCircleFilled24 from '@mozaic-ds/icons-vue/src/components/WarningCircleFilled24/WarningCircleFilled24.vue';
7
+ import CrossCircleFilled24 from '@mozaic-ds/icons-vue/src/components/CrossCircleFilled24/CrossCircleFilled24.vue';
8
+ import CheckCircleFilled24 from '@mozaic-ds/icons-vue/src/components/CheckCircleFilled24/CheckCircleFilled24.vue';
9
+
10
+ describe('MStatusMessage.vue', () => {
11
+ it('renders the label', () => {
12
+ const wrapper = mount(MStatusMessage, {
13
+ props: { label: 'Hello world' },
14
+ });
15
+
16
+ expect(wrapper.find('.mc-status-message__description').text()).toBe(
17
+ 'Hello world',
18
+ );
19
+ });
20
+
21
+ it('uses the info icon by default', () => {
22
+ const wrapper = mount(MStatusMessage, {
23
+ props: { label: 'Info message' },
24
+ });
25
+
26
+ expect(wrapper.findComponent(InfoCircleFilled24).exists()).toBe(true);
27
+ });
28
+
29
+ it('renders the success icon when status is success', () => {
30
+ const wrapper = mount(MStatusMessage, {
31
+ props: { status: 'success', label: 'Success' },
32
+ });
33
+
34
+ expect(wrapper.findComponent(CheckCircleFilled24).exists()).toBe(true);
35
+ });
36
+
37
+ it('renders the warning icon when status is warning', () => {
38
+ const wrapper = mount(MStatusMessage, {
39
+ props: { status: 'warning', label: 'Warning' },
40
+ });
41
+
42
+ expect(wrapper.findComponent(WarningCircleFilled24).exists()).toBe(true);
43
+ });
44
+
45
+ it('renders the error icon when status is error', () => {
46
+ const wrapper = mount(MStatusMessage, {
47
+ props: { status: 'error', label: 'Error' },
48
+ });
49
+
50
+ expect(wrapper.findComponent(CrossCircleFilled24).exists()).toBe(true);
51
+ });
52
+
53
+ it('adds correct modifier class for non-info statuses', () => {
54
+ const wrapper = mount(MStatusMessage, {
55
+ props: { status: 'warning', label: 'Warn' },
56
+ });
57
+
58
+ expect(wrapper.classes()).toContain('mc-status-message--warning');
59
+ });
60
+
61
+ it('does NOT add modifier class for info', () => {
62
+ const wrapper = mount(MStatusMessage, { props: { label: 'Info' } });
63
+
64
+ expect(wrapper.classes()).not.toContain('mc-status-message--info');
65
+ });
66
+
67
+ it('shows loader instead of icon when status is inprogress', () => {
68
+ const wrapper = mount(MStatusMessage, {
69
+ props: { status: 'inprogress', label: 'Loading' },
70
+ });
71
+
72
+ expect(wrapper.findComponent({ name: 'MLoader' }).exists()).toBe(true);
73
+
74
+ expect(wrapper.find('.mc-status-message__icon').exists()).toBe(false);
75
+ });
76
+ });
@@ -0,0 +1,52 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3-vite';
2
+ import MStatusMessage from './MStatusMessage.vue';
3
+
4
+ const meta: Meta<typeof MStatusMessage> = {
5
+ title: 'Status/Status Message',
6
+ component: MStatusMessage,
7
+ tags: ['v2'],
8
+ parameters: {
9
+ docs: {
10
+ description: {
11
+ component:
12
+ '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.',
13
+ },
14
+ },
15
+ },
16
+ args: {
17
+ label: 'Brief status message',
18
+ },
19
+ render: (args) => ({
20
+ components: { MStatusMessage },
21
+ setup() {
22
+ return { args };
23
+ },
24
+ template: `
25
+ <MStatusMessage v-bind="args"></MStatusMessage>
26
+ `,
27
+ }),
28
+ };
29
+ export default meta;
30
+ type Story = StoryObj<typeof MStatusMessage>;
31
+
32
+ export const Info: Story = {};
33
+
34
+ export const Success: Story = {
35
+ args: { status: 'success' },
36
+ };
37
+
38
+ export const Warning: Story = {
39
+ args: { status: 'warning' },
40
+ };
41
+
42
+ export const Error: Story = {
43
+ args: { status: 'error' },
44
+ };
45
+
46
+ export const Neutral: Story = {
47
+ args: { status: 'neutral' },
48
+ };
49
+
50
+ export const InProgress: Story = {
51
+ args: { status: 'inprogress' },
52
+ };
@@ -0,0 +1,70 @@
1
+ <template>
2
+ <div class="mc-status-message" :class="classObject">
3
+ <component
4
+ v-if="status != 'inprogress'"
5
+ :is="iconComponent"
6
+ class="mc-status-message__icon"
7
+ aria-hidden="true"
8
+ />
9
+ <MLoader v-else size="s" />
10
+ <p class="mc-status-message__description">{{ label }}</p>
11
+ </div>
12
+ </template>
13
+
14
+ <script setup lang="ts">
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';
20
+ import MLoader from '../loader/MLoader.vue';
21
+ /**
22
+ * 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.
23
+ */
24
+ const props = withDefaults(
25
+ defineProps<{
26
+ /**
27
+ * Allows to define the status message style.
28
+ */
29
+ status?:
30
+ | 'info'
31
+ | 'success'
32
+ | 'warning'
33
+ | 'error'
34
+ | 'neutral'
35
+ | 'inprogress';
36
+ /**
37
+ * Label of the status message.
38
+ */
39
+ label: string;
40
+ }>(),
41
+ {
42
+ status: 'info',
43
+ },
44
+ );
45
+
46
+ const classObject = computed(() => {
47
+ return {
48
+ [`mc-status-message--${props.status}`]:
49
+ props.status && props.status != 'info',
50
+ };
51
+ });
52
+
53
+ const iconComponent = computed(() => {
54
+ switch (props.status) {
55
+ case 'success':
56
+ return CheckCircleFilled24;
57
+ case 'warning':
58
+ return WarningCircleFilled24;
59
+ case 'error':
60
+ return CrossCircleFilled24;
61
+ case 'info':
62
+ default:
63
+ return InfoCircleFilled24;
64
+ }
65
+ });
66
+ </script>
67
+
68
+ <style lang="scss" scoped>
69
+ @use '@mozaic-ds/styles/components/status-message';
70
+ </style>
@@ -0,0 +1,11 @@
1
+ # MStatusMessage
2
+
3
+ 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.
4
+
5
+
6
+ ## Props
7
+
8
+ | Name | Description | Type | Default |
9
+ | --- | --- | --- | --- |
10
+ | `status` | Allows to define the status message style. | `"info"` `"warning"` `"error"` `"success"` `"neutral"` `"inprogress"` | `"info"` |
11
+ | `label*` | Label of the status message. | `string` | - |
@@ -9,7 +9,7 @@ A Status Notification is used to draw the user’s attention to important inform
9
9
  | --- | --- | --- | --- |
10
10
  | `title*` | Title of the status notification. | `string` | - |
11
11
  | `description*` | Description of the status notification. | `string` | - |
12
- | `status` | Allows to define the status notification type. | `"info"` `"success"` `"warning"` `"error"` | `"info"` |
12
+ | `status` | Allows to define the status notification type. | `"info"` `"warning"` `"error"` `"success"` | `"info"` |
13
13
  | `closable` | if `true`, display the close button. | `boolean` | - |
14
14
 
15
15
  ## Slots
@@ -0,0 +1,98 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { mount } from '@vue/test-utils';
3
+ import MStepperCompact from './MStepperCompact.vue';
4
+
5
+ describe('MStepperCompact component', () => {
6
+ it('renders with required label and optional description', () => {
7
+ const wrapper = mount(MStepperCompact, {
8
+ props: {
9
+ label: 'Current Step',
10
+ },
11
+ });
12
+
13
+ expect(wrapper.find('.mc-stepper-compact').exists()).toBe(true);
14
+ expect(wrapper.find('.mc-stepper-compact__progress').exists()).toBe(true);
15
+ expect(wrapper.find('.mc-stepper-compact__label').text()).toBe(
16
+ 'Current Step',
17
+ );
18
+
19
+ // description should NOT be rendered by default
20
+ expect(wrapper.find('.mc-stepper-compact__description').exists()).toBe(
21
+ false,
22
+ );
23
+ });
24
+
25
+ it('calculates progress value correctly', () => {
26
+ const wrapper = mount(MStepperCompact, {
27
+ props: {
28
+ label: 'Current Step',
29
+ value: 2,
30
+ maxSteps: 5,
31
+ },
32
+ });
33
+
34
+ const progressbar = wrapper.findComponent({ name: 'MCircularProgressbar' });
35
+
36
+ expect(progressbar.props('value')).toBe(40); // (2/5) * 100
37
+ });
38
+
39
+ it('displays correct content value (current step / total)', () => {
40
+ const wrapper = mount(MStepperCompact, {
41
+ props: {
42
+ label: 'Current Step',
43
+ value: 3,
44
+ maxSteps: 7,
45
+ },
46
+ });
47
+
48
+ const progressbar = wrapper.findComponent({ name: 'MCircularProgressbar' });
49
+
50
+ expect(progressbar.props('contentValue')).toBe('3 / 7');
51
+ });
52
+
53
+ it('passes correct props to MCircularProgressbar', () => {
54
+ const wrapper = mount(MStepperCompact, {
55
+ props: {
56
+ label: 'Current Step',
57
+ value: 2,
58
+ maxSteps: 4,
59
+ },
60
+ });
61
+
62
+ const progressbar = wrapper.findComponent({ name: 'MCircularProgressbar' });
63
+
64
+ expect(progressbar.props('type')).toBe('content');
65
+ expect(progressbar.props('size')).toBe('m');
66
+ expect(progressbar.props('value')).toBe(50); // (2/4) * 100
67
+ expect(progressbar.props('contentValue')).toBe('2 / 4');
68
+ });
69
+
70
+ it('renders custom label and description when provided', () => {
71
+ const wrapper = mount(MStepperCompact, {
72
+ props: {
73
+ label: 'Custom Label',
74
+ description: 'Custom Description',
75
+ },
76
+ });
77
+
78
+ expect(wrapper.find('.mc-stepper-compact__label').text()).toBe(
79
+ 'Custom Label',
80
+ );
81
+ expect(wrapper.find('.mc-stepper-compact__description').text()).toBe(
82
+ 'Custom Description',
83
+ );
84
+ });
85
+
86
+ it('does not render description element when description is empty', () => {
87
+ const wrapper = mount(MStepperCompact, {
88
+ props: {
89
+ label: 'Label Only',
90
+ description: undefined,
91
+ },
92
+ });
93
+
94
+ expect(wrapper.find('.mc-stepper-compact__description').exists()).toBe(
95
+ false,
96
+ );
97
+ });
98
+ });
@@ -0,0 +1,43 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3-vite';
2
+ import MStepperCompact from './MStepperCompact.vue';
3
+
4
+ const meta: Meta<typeof MStepperCompact> = {
5
+ title: 'Indicators/Stepper Compact',
6
+ component: MStepperCompact,
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
+ argTypes: {
17
+ value: {
18
+ control: { type: 'number', min: 1, max: 10 },
19
+ },
20
+ maxSteps: {
21
+ control: { type: 'number', min: 2, max: 10 },
22
+ },
23
+ },
24
+ args: {
25
+ value: 1,
26
+ maxSteps: 4,
27
+ label: 'Current Step',
28
+ description: 'Next: Step label',
29
+ },
30
+ render: (args) => ({
31
+ components: { MStepperCompact },
32
+ setup() {
33
+ return { args };
34
+ },
35
+ template: `
36
+ <MStepperCompact v-bind="args"></MStepperCompact>
37
+ `,
38
+ }),
39
+ };
40
+ export default meta;
41
+ type Story = StoryObj<typeof MStepperCompact>;
42
+
43
+ export const Default: Story = {};