@mozaic-ds/vue 1.0.0-rc.2 → 2.1.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 (222) hide show
  1. package/LICENSE +51 -0
  2. package/README.md +76 -77
  3. package/dist/mozaic-vue.css +1 -1
  4. package/dist/mozaic-vue.d.ts +1664 -0
  5. package/dist/mozaic-vue.js +1943 -0
  6. package/dist/mozaic-vue.js.map +1 -0
  7. package/dist/mozaic-vue.umd.cjs +2 -0
  8. package/dist/mozaic-vue.umd.cjs.map +1 -0
  9. package/env.d.ts +1 -0
  10. package/package.json +78 -51
  11. package/src/components/Contributing.mdx +118 -0
  12. package/src/components/GettingStarted.mdx +45 -0
  13. package/src/components/Introduction.mdx +100 -0
  14. package/src/components/Support.mdx +18 -0
  15. package/src/components/breadcrumb/MBreadcrumb.spec.ts +105 -0
  16. package/src/components/breadcrumb/MBreadcrumb.stories.ts +82 -0
  17. package/src/components/breadcrumb/MBreadcrumb.vue +52 -55
  18. package/src/components/button/MButton.spec.ts +191 -0
  19. package/src/components/button/MButton.stories.ts +59 -0
  20. package/src/components/button/MButton.vue +98 -154
  21. package/src/components/checkbox/MCheckbox.spec.ts +104 -0
  22. package/src/components/checkbox/MCheckbox.stories.ts +83 -0
  23. package/src/components/checkbox/MCheckbox.vue +60 -101
  24. package/src/components/checkboxgroup/MCheckboxGroup.spec.ts +78 -0
  25. package/src/components/checkboxgroup/MCheckboxGroup.stories.ts +61 -0
  26. package/src/components/checkboxgroup/MCheckboxGroup.vue +97 -0
  27. package/src/components/datepicker/MDatepicker.spec.ts +95 -0
  28. package/src/components/datepicker/MDatepicker.stories.ts +75 -0
  29. package/src/components/datepicker/MDatepicker.vue +114 -0
  30. package/src/components/divider/MDivider.spec.ts +57 -0
  31. package/src/components/divider/MDivider.stories.ts +64 -0
  32. package/src/components/divider/MDivider.vue +56 -0
  33. package/src/components/drawer/MDrawer.spec.ts +100 -0
  34. package/src/components/drawer/MDrawer.stories.ts +128 -0
  35. package/src/components/drawer/MDrawer.vue +140 -0
  36. package/src/components/field/MField.spec.ts +166 -0
  37. package/src/components/field/MField.stories.ts +369 -0
  38. package/src/components/field/MField.vue +78 -61
  39. package/src/components/fieldgroup/MFieldGroup.spec.ts +165 -0
  40. package/src/components/fieldgroup/MFieldGroup.stories.ts +416 -0
  41. package/src/components/fieldgroup/MFieldGroup.vue +79 -0
  42. package/src/components/flag/MFlag.spec.ts +46 -0
  43. package/src/components/flag/MFlag.stories.ts +46 -0
  44. package/src/components/flag/MFlag.vue +28 -39
  45. package/src/components/iconbutton/MIconButton.spec.ts +108 -0
  46. package/src/components/iconbutton/MIconButton.stories.ts +74 -0
  47. package/src/components/iconbutton/MIconButton.vue +73 -0
  48. package/src/components/link/MLink.spec.ts +154 -0
  49. package/src/components/link/MLink.stories.ts +89 -0
  50. package/src/components/link/MLink.vue +86 -120
  51. package/src/components/loader/MLoader.spec.ts +104 -0
  52. package/src/components/loader/MLoader.stories.ts +43 -0
  53. package/src/components/loader/MLoader.vue +66 -55
  54. package/src/components/loadingoverlay/MLoadingOverlay.spec.ts +37 -0
  55. package/src/components/loadingoverlay/MLoadingOverlay.stories.ts +40 -0
  56. package/src/components/loadingoverlay/MLoadingOverlay.vue +28 -0
  57. package/src/components/modal/MModal.spec.ts +103 -0
  58. package/src/components/modal/MModal.stories.ts +127 -0
  59. package/src/components/modal/MModal.vue +106 -154
  60. package/src/components/numberbadge/MNumberBadge.spec.ts +56 -0
  61. package/src/components/numberbadge/MNumberBadge.stories.ts +48 -0
  62. package/src/components/numberbadge/MNumberBadge.vue +45 -0
  63. package/src/components/overlay/MOverlay.spec.ts +51 -0
  64. package/src/components/overlay/MOverlay.stories.ts +35 -0
  65. package/src/components/overlay/MOverlay.vue +27 -19
  66. package/src/components/pagination/MPagination.spec.ts +123 -0
  67. package/src/components/pagination/MPagination.stories.ts +83 -0
  68. package/src/components/pagination/MPagination.vue +120 -140
  69. package/src/components/passwordinput/MPasswordInput.spec.ts +104 -0
  70. package/src/components/passwordinput/MPasswordInput.stories.ts +75 -0
  71. package/src/components/passwordinput/MPasswordInput.vue +126 -77
  72. package/src/components/pincode/MPincode.spec.ts +126 -0
  73. package/src/components/pincode/MPincode.stories.ts +68 -0
  74. package/src/components/pincode/MPincode.vue +148 -0
  75. package/src/components/quantityselector/MQuantitySelector.spec.ts +262 -0
  76. package/src/components/quantityselector/MQuantitySelector.stories.ts +89 -0
  77. package/src/components/quantityselector/MQuantitySelector.vue +159 -148
  78. package/src/components/radio/MRadio.spec.ts +104 -0
  79. package/src/components/radio/MRadio.stories.ts +68 -0
  80. package/src/components/radio/MRadio.vue +56 -39
  81. package/src/components/radiogroup/MRadioGroup.spec.ts +54 -0
  82. package/src/components/radiogroup/MRadioGroup.stories.ts +61 -0
  83. package/src/components/radiogroup/MRadioGroup.vue +79 -0
  84. package/src/components/select/MSelect.spec.ts +114 -0
  85. package/src/components/select/MSelect.stories.ts +101 -0
  86. package/src/components/select/MSelect.vue +77 -119
  87. package/src/components/statusbadge/MStatusBadge.stories.ts +45 -0
  88. package/src/components/statusbadge/MStatusBadge.vue +40 -0
  89. package/src/components/statusbadge/MstatusBadge.spec.ts +16 -0
  90. package/src/components/statusdot/MStatusDot.spec.ts +51 -0
  91. package/src/components/statusdot/MStatusDot.stories.ts +48 -0
  92. package/src/components/statusdot/MStatusDot.vue +36 -0
  93. package/src/components/statusnotification/MStatusNotification.spec.ts +103 -0
  94. package/src/components/statusnotification/MStatusNotification.stories.ts +89 -0
  95. package/src/components/statusnotification/MStatusNotification.vue +106 -0
  96. package/src/components/tabs/MTabs.stories.ts +104 -0
  97. package/src/components/tabs/MTabs.vue +113 -0
  98. package/src/components/tabs/Mtabs.spec.ts +149 -0
  99. package/src/components/tag/MTag.spec.ts +107 -0
  100. package/src/components/tag/MTag.stories.ts +75 -0
  101. package/src/components/tag/MTag.vue +151 -0
  102. package/src/components/textarea/MTextArea.spec.ts +112 -0
  103. package/src/components/textarea/MTextArea.stories.ts +67 -0
  104. package/src/components/textarea/MTextArea.vue +81 -43
  105. package/src/components/textinput/MTextInput.spec.ts +121 -0
  106. package/src/components/textinput/MTextInput.stories.ts +107 -0
  107. package/src/components/textinput/MTextInput.vue +127 -47
  108. package/src/components/toggle/MToggle.spec.ts +99 -0
  109. package/src/components/toggle/MToggle.stories.ts +68 -0
  110. package/src/components/toggle/MToggle.vue +63 -103
  111. package/src/components/togglegroup/MToggleGroup.spec.ts +78 -0
  112. package/src/components/togglegroup/MToggleGroup.stories.ts +61 -0
  113. package/src/components/togglegroup/MToggleGroup.vue +97 -0
  114. package/src/components/usingIcons.mdx +35 -0
  115. package/src/components/usingPresets.mdx +128 -0
  116. package/src/main.ts +32 -0
  117. package/dist/demo.html +0 -1
  118. package/dist/mozaic-vue.adeo.css +0 -47
  119. package/dist/mozaic-vue.adeo.umd.js +0 -31109
  120. package/dist/mozaic-vue.common.js +0 -31099
  121. package/dist/mozaic-vue.common.js.map +0 -1
  122. package/dist/mozaic-vue.umd.js +0 -31110
  123. package/dist/mozaic-vue.umd.js.map +0 -1
  124. package/dist/mozaic-vue.umd.min.js +0 -4
  125. package/dist/mozaic-vue.umd.min.js.map +0 -1
  126. package/postinstall.js +0 -3
  127. package/src/components/accordion/MAccordion.vue +0 -128
  128. package/src/components/accordion/index.js +0 -7
  129. package/src/components/autocomplete/MAutocomplete.vue +0 -381
  130. package/src/components/autocomplete/index.js +0 -7
  131. package/src/components/badge/MBadge.vue +0 -43
  132. package/src/components/badge/index.js +0 -7
  133. package/src/components/breadcrumb/index.js +0 -7
  134. package/src/components/button/index.js +0 -7
  135. package/src/components/card/MCard.vue +0 -78
  136. package/src/components/card/index.js +0 -7
  137. package/src/components/checkbox/MCheckboxGroup.vue +0 -163
  138. package/src/components/checkbox/index.js +0 -12
  139. package/src/components/container/MContainer.vue +0 -33
  140. package/src/components/container/index.js +0 -7
  141. package/src/components/datatable/MDataTable.vue +0 -651
  142. package/src/components/datatable/MDataTableHeader.vue +0 -55
  143. package/src/components/datatable/MDataTableTop.vue +0 -35
  144. package/src/components/datatable/helpers.js +0 -132
  145. package/src/components/datatable/index.js +0 -12
  146. package/src/components/dropdown/MDropdown.vue +0 -317
  147. package/src/components/dropdown/index.js +0 -7
  148. package/src/components/field/index.js +0 -7
  149. package/src/components/fileuploader/MFileResult.vue +0 -149
  150. package/src/components/fileuploader/MFileUploader.vue +0 -142
  151. package/src/components/fileuploader/index.js +0 -7
  152. package/src/components/flag/index.js +0 -7
  153. package/src/components/heading/MHeading.vue +0 -75
  154. package/src/components/heading/index.js +0 -7
  155. package/src/components/hero/MHero.vue +0 -93
  156. package/src/components/hero/index.js +0 -7
  157. package/src/components/icon/MIcon.vue +0 -136
  158. package/src/components/icon/index.js +0 -7
  159. package/src/components/index.js +0 -44
  160. package/src/components/layer/MLayer.vue +0 -208
  161. package/src/components/layer/index.js +0 -7
  162. package/src/components/link/index.js +0 -7
  163. package/src/components/listbox/MListBox.vue +0 -146
  164. package/src/components/listbox/MListBoxActions.vue +0 -251
  165. package/src/components/listbox/index.js +0 -12
  166. package/src/components/loader/index.js +0 -7
  167. package/src/components/modal/index.js +0 -7
  168. package/src/components/notification/MNotification.vue +0 -110
  169. package/src/components/notification/index.js +0 -7
  170. package/src/components/optionbutton/MOptionButton.vue +0 -67
  171. package/src/components/optionbutton/index.js +0 -7
  172. package/src/components/optioncard/MOptionCard.vue +0 -132
  173. package/src/components/optioncard/index.js +0 -7
  174. package/src/components/optiongroup/MOptionGroup.vue +0 -18
  175. package/src/components/optiongroup/index.js +0 -7
  176. package/src/components/overlay/MOverlayLoader.vue +0 -43
  177. package/src/components/overlay/index.js +0 -12
  178. package/src/components/pagination/index.js +0 -7
  179. package/src/components/passwordinput/index.js +0 -7
  180. package/src/components/phonenumber/MPhoneNumber.vue +0 -398
  181. package/src/components/phonenumber/index.js +0 -7
  182. package/src/components/progressbar/MProgress.vue +0 -102
  183. package/src/components/progressbar/index.js +0 -7
  184. package/src/components/quantityselector/index.js +0 -7
  185. package/src/components/radio/MRadioGroup.vue +0 -111
  186. package/src/components/radio/index.js +0 -12
  187. package/src/components/ratingstars/MStarsInput.vue +0 -119
  188. package/src/components/ratingstars/MStarsResult.vue +0 -89
  189. package/src/components/ratingstars/index.js +0 -12
  190. package/src/components/select/index.js +0 -7
  191. package/src/components/stepper/MStepper.vue +0 -111
  192. package/src/components/stepper/index.js +0 -7
  193. package/src/components/tabs/MTab.vue +0 -198
  194. package/src/components/tabs/index.js +0 -7
  195. package/src/components/tags/MTag.vue +0 -173
  196. package/src/components/tags/index.js +0 -7
  197. package/src/components/textarea/index.js +0 -7
  198. package/src/components/textinput/MTextInputField.vue +0 -105
  199. package/src/components/textinput/MTextInputIcon.vue +0 -42
  200. package/src/components/textinput/index.js +0 -7
  201. package/src/components/toggle/index.js +0 -7
  202. package/src/components/tooltip/MTooltip.vue +0 -42
  203. package/src/components/tooltip/index.js +0 -7
  204. package/src/index.js +0 -63
  205. package/src/shims-tsx.d.ts +0 -13
  206. package/src/shims.vue.d.ts +0 -4
  207. package/src/tokens/adeo/android/colors.xml +0 -448
  208. package/src/tokens/adeo/android/font_dimens.xml +0 -18
  209. package/src/tokens/adeo/css/_variables.scss +0 -442
  210. package/src/tokens/adeo/css/root.scss +0 -444
  211. package/src/tokens/adeo/ios/StyleDictionaryColor.h +0 -456
  212. package/src/tokens/adeo/ios/StyleDictionaryColor.m +0 -468
  213. package/src/tokens/adeo/ios/StyleDictionaryColor.swift +0 -451
  214. package/src/tokens/adeo/ios/StyleDictionarySize.h +0 -69
  215. package/src/tokens/adeo/ios/StyleDictionarySize.m +0 -70
  216. package/src/tokens/adeo/ios/StyleDictionarySize.swift +0 -71
  217. package/src/tokens/adeo/js/tokens.js +0 -540
  218. package/src/tokens/adeo/js/tokensObject.js +0 -11641
  219. package/src/tokens/adeo/scss/_tokens.scss +0 -1514
  220. package/src/utils/mozaicClasses.js +0 -16
  221. package/src/utils/theme.validator.js +0 -19
  222. package/types/index.d.ts +0 -104
@@ -0,0 +1,51 @@
1
+ import { mount } from '@vue/test-utils';
2
+ import { describe, it, expect } from 'vitest';
3
+ import MStatusDot from './MStatusDot.vue';
4
+
5
+ describe('MStatusDot.vue', () => {
6
+ it('renders with default status and size', () => {
7
+ const wrapper = mount(MStatusDot);
8
+
9
+ expect(wrapper.classes()).toContain('mc-status-dot');
10
+ });
11
+
12
+ it('renders with custom status', () => {
13
+ const wrapper = mount(MStatusDot, {
14
+ props: {
15
+ status: 'success',
16
+ },
17
+ });
18
+
19
+ expect(wrapper.classes()).toContain('mc-status-dot--success');
20
+ });
21
+
22
+ it('renders with custom size', () => {
23
+ const wrapper = mount(MStatusDot, {
24
+ props: {
25
+ size: 's',
26
+ },
27
+ });
28
+
29
+ expect(wrapper.classes()).toContain('mc-status-dot--s');
30
+ });
31
+
32
+ it('does not render the "info" status when a custom one is passed', () => {
33
+ const wrapper = mount(MStatusDot, {
34
+ props: {
35
+ status: 'warning',
36
+ },
37
+ });
38
+
39
+ expect(wrapper.classes()).not.toContain('mc-status-dot--info');
40
+ });
41
+
42
+ it('does not render the "m" size when a custom one is passed', () => {
43
+ const wrapper = mount(MStatusDot, {
44
+ props: {
45
+ size: 'l',
46
+ },
47
+ });
48
+
49
+ expect(wrapper.classes()).not.toContain('mc-status-dot--m');
50
+ });
51
+ });
@@ -0,0 +1,48 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3-vite';
2
+ import MStatusDot from './MStatusDot.vue';
3
+
4
+ const meta: Meta<typeof MStatusDot> = {
5
+ title: 'Status/Status Dot',
6
+ component: MStatusDot,
7
+ parameters: {
8
+ docs: {
9
+ description: {
10
+ component:
11
+ 'A Status dot is a small visual indicator used to represent the state or condition of an element. It is often color-coded to convey different statuses at a glance, such as availability, activity, or urgency. Status Dots are commonly found in user presence indicators, system statuses, or process tracking to provide quick, unobtrusive feedback.',
12
+ },
13
+ },
14
+ },
15
+ render: (args) => ({
16
+ components: { MStatusDot },
17
+ setup() {
18
+ return { args };
19
+ },
20
+ template: `
21
+ <MStatusDot v-bind="args"></MStatusDot>
22
+ `,
23
+ }),
24
+ };
25
+ export default meta;
26
+ type Story = StoryObj<typeof MStatusDot>;
27
+
28
+ export const Info: Story = {};
29
+
30
+ export const Success: Story = {
31
+ args: { status: 'success' },
32
+ };
33
+
34
+ export const Warning: Story = {
35
+ args: { status: 'warning' },
36
+ };
37
+
38
+ export const Error: Story = {
39
+ args: { status: 'error' },
40
+ };
41
+
42
+ export const Neutral: Story = {
43
+ args: { status: 'neutral' },
44
+ };
45
+
46
+ export const Size: Story = {
47
+ args: { size: 'l' },
48
+ };
@@ -0,0 +1,36 @@
1
+ <template>
2
+ <span class="mc-status-dot" :class="classObject"></span>
3
+ </template>
4
+
5
+ <script setup lang="ts">
6
+ import { computed } from 'vue';
7
+ /**
8
+ * A badge indicates the status of an entity and can evolve at any time.
9
+ */
10
+ const props = withDefaults(
11
+ defineProps<{
12
+ /**
13
+ * Allows to define the Status Dot style
14
+ */
15
+ status?: 'info' | 'success' | 'warning' | 'error' | 'neutral';
16
+ /**
17
+ * Determines the size of the Status Dot.
18
+ */
19
+ size?: 's' | 'm' | 'l';
20
+ }>(),
21
+ {
22
+ status: 'info',
23
+ },
24
+ );
25
+
26
+ const classObject = computed(() => {
27
+ return {
28
+ [`mc-status-dot--${props.status}`]: props.status && props.status != 'info',
29
+ [`mc-status-dot--${props.size}`]: props.size && props.size != 'm',
30
+ };
31
+ });
32
+ </script>
33
+
34
+ <style lang="scss" scoped>
35
+ @use '@mozaic-ds/styles/components/status-dot';
36
+ </style>
@@ -0,0 +1,103 @@
1
+ import { mount } from '@vue/test-utils';
2
+ import { describe, it, expect } from 'vitest';
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';
8
+
9
+ describe('MStatusNotification.vue', () => {
10
+ it('should render correctly with the default props', () => {
11
+ const wrapper = mount(MStatusNotification, {
12
+ props: {
13
+ title: 'Test Title',
14
+ description: 'Test Description',
15
+ },
16
+ });
17
+
18
+ expect(wrapper.text()).toContain('Test Title');
19
+ expect(wrapper.text()).toContain('Test Description');
20
+ expect(wrapper.findComponent(InfoCircleFilled32).exists()).toBe(true); // Default icon is InfoCircle32
21
+ expect(wrapper.classes()).toContain('mc-status-notification');
22
+ });
23
+
24
+ it('should display the correct icon based on the status prop', () => {
25
+ const wrapperSuccess = mount(MStatusNotification, {
26
+ props: {
27
+ title: 'Success',
28
+ description: 'Success Description',
29
+ status: 'success',
30
+ },
31
+ });
32
+ expect(wrapperSuccess.findComponent(CheckCircleFilled32).exists()).toBe(
33
+ true,
34
+ );
35
+
36
+ const wrapperWarning = mount(MStatusNotification, {
37
+ props: {
38
+ title: 'Warning',
39
+ description: 'Warning Description',
40
+ status: 'warning',
41
+ },
42
+ });
43
+ expect(wrapperWarning.findComponent(WarningCircleFilled32).exists()).toBe(
44
+ true,
45
+ );
46
+
47
+ const wrapperError = mount(MStatusNotification, {
48
+ props: {
49
+ title: 'Error',
50
+ description: 'Error Description',
51
+ status: 'error',
52
+ },
53
+ });
54
+ expect(wrapperError.findComponent(CrossCircleFilled32).exists()).toBe(true);
55
+ });
56
+
57
+ it('should show the close button if closable prop is true', () => {
58
+ const wrapper = mount(MStatusNotification, {
59
+ props: {
60
+ title: 'Closable Test',
61
+ description: 'Test Description',
62
+ closable: true,
63
+ },
64
+ });
65
+
66
+ expect(
67
+ wrapper.find('button.mc-status-notification-closable__close').exists(),
68
+ ).toBe(true);
69
+ });
70
+
71
+ it('should emit a close event when the close button is clicked', async () => {
72
+ const wrapper = mount(MStatusNotification, {
73
+ props: {
74
+ title: 'Closable Test',
75
+ description: 'Test Description',
76
+ closable: true,
77
+ },
78
+ });
79
+
80
+ const closeButton = wrapper.find(
81
+ 'button.mc-status-notification-closable__close',
82
+ );
83
+ await closeButton.trigger('click');
84
+
85
+ // Check if the "close" event was emitted
86
+ expect(wrapper.emitted()).toHaveProperty('close');
87
+ });
88
+
89
+ it('should render footer slot if provided', () => {
90
+ const footerSlotContent = '<button>Footer Button</button>';
91
+ const wrapper = mount(MStatusNotification, {
92
+ props: {
93
+ title: 'With Footer',
94
+ description: 'Description with footer',
95
+ },
96
+ slots: {
97
+ footer: footerSlotContent,
98
+ },
99
+ });
100
+
101
+ expect(wrapper.html()).toContain(footerSlotContent);
102
+ });
103
+ });
@@ -0,0 +1,89 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3-vite';
2
+ import MStatusNotification from './MStatusNotification.vue';
3
+ import { action } from 'storybook/actions';
4
+ import MButton from '../button/MButton.vue';
5
+ import MLink from '../link/MLink.vue';
6
+ import ArrowNext20 from '@mozaic-ds/icons-vue/src/components/ArrowNext20/ArrowNext20.vue';
7
+
8
+ const meta: Meta<typeof MStatusNotification> = {
9
+ title: 'Status/Status Notification',
10
+ component: MStatusNotification,
11
+ parameters: {
12
+ docs: {
13
+ description: {
14
+ component:
15
+ '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.',
16
+ },
17
+ },
18
+ },
19
+ args: {
20
+ title:
21
+ 'This is a title, be concise and use the description message to give details.',
22
+ description: 'Description message.',
23
+ },
24
+ render: (args) => ({
25
+ components: { MStatusNotification, MButton, MLink, ArrowNext20 },
26
+ setup() {
27
+ const handleClick = action('close');
28
+
29
+ return { args, handleClick };
30
+ },
31
+ template: `
32
+ <MStatusNotification
33
+ v-bind="args"
34
+ @click="handleClick"
35
+ >
36
+ <template v-if="${'footer' in args}" v-slot:footer>${args.footer}</template>
37
+ </MStatusNotification>
38
+ `,
39
+ }),
40
+ };
41
+ export default meta;
42
+ type Story = StoryObj<typeof MStatusNotification>;
43
+
44
+ export const Info: Story = {};
45
+
46
+ export const Success: Story = {
47
+ args: { status: 'success' },
48
+ };
49
+
50
+ export const Warning: Story = {
51
+ args: { status: 'warning' },
52
+ };
53
+
54
+ export const Error: Story = {
55
+ args: { status: 'error' },
56
+ };
57
+
58
+ export const Closable: Story = {
59
+ args: { closable: true },
60
+ };
61
+
62
+ export const WithButton = {
63
+ args: {
64
+ footer: `
65
+ <MButton outlined>Button Label</MButton>
66
+ `,
67
+ },
68
+ };
69
+
70
+ export const WithLink = {
71
+ args: {
72
+ footer: `
73
+ <MLink href="#" iconPosition="right">
74
+ Stand-alone link
75
+
76
+ <template #icon><ArrowNext20 /></template>
77
+ </MLink>
78
+ `,
79
+ },
80
+ };
81
+
82
+ export const WithButtons = {
83
+ args: {
84
+ footer: `
85
+ <MButton>Button Label</MButton>
86
+ <MButton outlined>Button Label</MButton>
87
+ `,
88
+ },
89
+ };
@@ -0,0 +1,106 @@
1
+ <template>
2
+ <section class="mc-status-notification" role="status" :class="classObject">
3
+ <component
4
+ :is="iconComponent"
5
+ class="mc-status-notification__icon"
6
+ aria-hidden="true"
7
+ />
8
+ <div class="mc-status-notification__content">
9
+ <h2 class="mc-status-notification__title">{{ title }}</h2>
10
+
11
+ <p class="mc-status-notification__message">
12
+ {{ description }}
13
+ </p>
14
+
15
+ <div v-if="$slots.footer" class="mc-status-notification__footer">
16
+ <slot name="footer" />
17
+ </div>
18
+ </div>
19
+
20
+ <button
21
+ v-if="closable"
22
+ class="mc-status-notification-closable__close"
23
+ @click="emit('close')"
24
+ >
25
+ <Cross20
26
+ class="mc-status-notification-closable__icon"
27
+ aria-hidden="true"
28
+ />
29
+ <span class="mc-status-notification-closable__text">Close</span>
30
+ </button>
31
+ </section>
32
+ </template>
33
+
34
+ <script setup lang="ts">
35
+ import { computed, type VNode } from 'vue';
36
+ import Cross20 from '@mozaic-ds/icons-vue/src/components/Cross20/Cross20.vue';
37
+ import InfoCircleFilled32 from '@mozaic-ds/icons-vue/src/components/InfoCircleFilled32/InfoCircleFilled32.vue';
38
+ import WarningCircleFilled32 from '@mozaic-ds/icons-vue/src/components/WarningCircleFilled32/WarningCircleFilled32.vue';
39
+ import CrossCircleFilled32 from '@mozaic-ds/icons-vue/src/components/CrossCircleFilled32/CrossCircleFilled32.vue';
40
+ import CheckCircleFilled32 from '@mozaic-ds/icons-vue/src/components/CheckCircleFilled32/CheckCircleFilled32.vue';
41
+ /**
42
+ * 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.
43
+ */
44
+ const props = withDefaults(
45
+ defineProps<{
46
+ /**
47
+ * Title of the Status Notification
48
+ */
49
+ title: string;
50
+ /**
51
+ * Description of the Status Notification
52
+ */
53
+ description: string;
54
+ /**
55
+ * Allows to define the Status Notification style
56
+ */
57
+ status?: 'info' | 'success' | 'warning' | 'error';
58
+ /**
59
+ * if `true`, display the close button.
60
+ */
61
+ closable?: boolean;
62
+ }>(),
63
+ {
64
+ status: 'info',
65
+ },
66
+ );
67
+
68
+ defineSlots<{
69
+ /**
70
+ * Use this slot to insert a button or a link in the footer
71
+ */
72
+ footer?: VNode;
73
+ }>();
74
+
75
+ const classObject = computed(() => {
76
+ return {
77
+ [`mc-status-notification--${props.status}`]:
78
+ props.status && props.status != 'info',
79
+ };
80
+ });
81
+
82
+ const iconComponent = computed(() => {
83
+ switch (props.status) {
84
+ case 'success':
85
+ return CheckCircleFilled32;
86
+ case 'warning':
87
+ return WarningCircleFilled32;
88
+ case 'error':
89
+ return CrossCircleFilled32;
90
+ case 'info':
91
+ default:
92
+ return InfoCircleFilled32;
93
+ }
94
+ });
95
+
96
+ const emit = defineEmits<{
97
+ /**
98
+ * Emits when closing the notification.
99
+ */
100
+ (on: 'close'): void;
101
+ }>();
102
+ </script>
103
+
104
+ <style lang="scss" scoped>
105
+ @use '@mozaic-ds/styles/components/status-notification';
106
+ </style>
@@ -0,0 +1,104 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3-vite';
2
+ import { action } from 'storybook/actions';
3
+
4
+ import Mtabs from './MTabs.vue';
5
+ import ChevronRight24 from '@mozaic-ds/icons-vue/src/components/ChevronRight24/ChevronRight24.vue';
6
+
7
+ const meta: Meta<typeof Mtabs> = {
8
+ title: 'Navigation/Tabs',
9
+ component: Mtabs,
10
+ parameters: {
11
+ docs: {
12
+ description: {
13
+ component:
14
+ 'Tabs are a navigation component that allows users to switch between different sections within the same context. They help organize content efficiently by displaying only one section at a time, reducing clutter and improving accessibility. Tabs can include icons, labels, and notification badges to provide additional context. They are commonly used in dashboards, product management, and settings interfaces.',
15
+ },
16
+ },
17
+ },
18
+ args: {
19
+ tabs: [
20
+ {
21
+ label: 'Label',
22
+ },
23
+ {
24
+ label: 'Label',
25
+ },
26
+ {
27
+ label: 'Label',
28
+ },
29
+ {
30
+ label: 'Label',
31
+ },
32
+ ],
33
+ },
34
+ render: (args) => ({
35
+ components: { Mtabs, ChevronRight24 },
36
+ setup() {
37
+ const handleUpdate = action('update:modelValue');
38
+
39
+ return { args, handleUpdate };
40
+ },
41
+ template: `
42
+ <Mtabs
43
+ v-bind="args"
44
+ @update:modelValue="handleUpdate"
45
+ ></Mtabs>
46
+ `,
47
+ }),
48
+ };
49
+ export default meta;
50
+ type Story = StoryObj<typeof Mtabs>;
51
+
52
+ export const Default: Story = {};
53
+
54
+ export const Icons: Story = {
55
+ args: {
56
+ tabs: [
57
+ {
58
+ label: 'Label',
59
+ icon: ChevronRight24,
60
+ },
61
+ {
62
+ label: 'Label',
63
+ icon: ChevronRight24,
64
+ },
65
+ {
66
+ label: 'Label',
67
+ icon: ChevronRight24,
68
+ },
69
+ {
70
+ label: 'Label',
71
+ icon: ChevronRight24,
72
+ },
73
+ ],
74
+ },
75
+ };
76
+
77
+ export const Centered: Story = {
78
+ args: { centered: true },
79
+ };
80
+
81
+ export const NoDivider: Story = {
82
+ args: { divider: false },
83
+ };
84
+
85
+ export const Disabled: Story = {
86
+ args: {
87
+ tabs: [
88
+ {
89
+ label: 'Label',
90
+ },
91
+ {
92
+ label: 'Label',
93
+ },
94
+ {
95
+ label: 'Label',
96
+ disabled: true,
97
+ },
98
+ {
99
+ label: 'Label',
100
+ disabled: true,
101
+ },
102
+ ],
103
+ },
104
+ };
@@ -0,0 +1,113 @@
1
+ <template>
2
+ <nav class="mc-tabs" :class="classObject">
3
+ <ul role="tablist" class="mc-tabs__list" :aria-label="description">
4
+ <li
5
+ v-for="(tab, index) in tabs"
6
+ :key="`tab-${index}`"
7
+ role="presentation"
8
+ class="mc-tabs__item"
9
+ >
10
+ <button
11
+ ref="tab"
12
+ role="tab"
13
+ class="mc-tabs__tab"
14
+ :class="{
15
+ 'mc-tabs__tab--selected': isTabSelected(index),
16
+ 'mc-tabs__tab--disabled': tab.disabled,
17
+ }"
18
+ :aria-selected="isTabSelected(index)"
19
+ type="button"
20
+ @click="onClickTab(index)"
21
+ >
22
+ <span v-if="tab.icon" class="mc-tabs__icon">
23
+ <component :is="tab.icon" />
24
+ </span>
25
+ <div class="mc-tabs__label">
26
+ <span>{{ tab.label }}</span>
27
+ </div>
28
+ </button>
29
+ </li>
30
+ </ul>
31
+ <MDivider v-if="divider"></MDivider>
32
+ </nav>
33
+ </template>
34
+
35
+ <script setup lang="ts">
36
+ import { computed, ref, type Component } from 'vue';
37
+ import MDivider from '../divider/MDivider.vue';
38
+ /**
39
+ * Tabs are a navigation component that allows users to switch between different sections within the same context. They help organize content efficiently by displaying only one section at a time, reducing clutter and improving accessibility. Tabs can include icons, labels, and notification badges to provide additional context. They are commonly used in dashboards, product management, and settings interfaces.
40
+ */
41
+ const props = withDefaults(
42
+ defineProps<{
43
+ /**
44
+ * A description indicating the purpose of the set of tabs. Useful for improving the accessibility of the component.
45
+ */
46
+ description?: string;
47
+ /**
48
+ * If `true`, the divider will appear.
49
+ */
50
+ divider?: boolean;
51
+ /**
52
+ * If `true`, the tabs of the component will be centered.
53
+ */
54
+ centered?: boolean;
55
+ /**
56
+ * The selected tab index, bound via v-model.
57
+ */
58
+ modelValue?: number;
59
+ /**
60
+ * An array of objects that allows you to provide all the data needed to generate the content for each tab.
61
+ */
62
+ tabs: Array<{
63
+ /**
64
+ * The icon displayed for the tab from Mozaic-icon-vue.
65
+ */
66
+ icon?: Component;
67
+ /**
68
+ * The label displayed for the tab.
69
+ */
70
+ label: string;
71
+ /**
72
+ * If `true`, the tab will be disabled.
73
+ */
74
+ disabled?: boolean;
75
+ }>;
76
+ }>(),
77
+ {
78
+ modelValue: 0,
79
+ divider: true,
80
+ },
81
+ );
82
+
83
+ const classObject = computed(() => {
84
+ return {
85
+ 'mc-tabs--centered': props.centered,
86
+ };
87
+ });
88
+
89
+ const modelValue = ref(props.modelValue);
90
+
91
+ const onClickTab = (index: number) => {
92
+ if (props.tabs[index].disabled) return;
93
+ if (index !== modelValue.value) {
94
+ modelValue.value = index;
95
+ emit('update:modelValue', index);
96
+ }
97
+ };
98
+
99
+ const isTabSelected = (index: number) => {
100
+ return modelValue.value === index;
101
+ };
102
+
103
+ const emit = defineEmits<{
104
+ /**
105
+ * Emits when the selected tab changes, updating the modelValue prop.
106
+ */
107
+ (on: 'update:modelValue', value: number): void;
108
+ }>();
109
+ </script>
110
+
111
+ <style lang="scss" scoped>
112
+ @use '@mozaic-ds/styles/components/tabs';
113
+ </style>