@mozaic-ds/vue 1.0.0-rc.3 → 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 +111 -159
  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 -31341
  120. package/dist/mozaic-vue.common.js +0 -31331
  121. package/dist/mozaic-vue.common.js.map +0 -1
  122. package/dist/mozaic-vue.umd.js +0 -31342
  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 -380
  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 -204
  194. package/src/components/tabs/index.js +0 -7
  195. package/src/components/tags/MTag.vue +0 -175
  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 -452
  208. package/src/tokens/adeo/android/font_dimens.xml +0 -18
  209. package/src/tokens/adeo/css/_variables.scss +0 -446
  210. package/src/tokens/adeo/css/root.scss +0 -448
  211. package/src/tokens/adeo/ios/StyleDictionaryColor.h +0 -460
  212. package/src/tokens/adeo/ios/StyleDictionaryColor.m +0 -472
  213. package/src/tokens/adeo/ios/StyleDictionaryColor.swift +0 -455
  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 -544
  218. package/src/tokens/adeo/js/tokensObject.js +0 -11733
  219. package/src/tokens/adeo/scss/_tokens.scss +0 -1522
  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,61 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3-vite';
2
+ import { action } from 'storybook/actions';
3
+
4
+ import MRadioGroup from './MRadioGroup.vue';
5
+
6
+ const meta: Meta<typeof MRadioGroup> = {
7
+ title: 'Form Elements/Radio Group',
8
+ component: MRadioGroup,
9
+ parameters: {
10
+ docs: {
11
+ description: {
12
+ component:
13
+ 'A radio button is a selection control that allows users to choose a single option from a list of mutually exclusive choices. Unlike checkboxes, only one option can be selected at a time within the same group. Radio Buttons are commonly used in forms, surveys, and settings where a single choice must be made.<br><br> To put a label, requierement text, help text or to apply a valid or invalid message, the examples are available in the [Field Group section](/docs/form-elements-field-group--docs#radio-group).',
14
+ },
15
+ },
16
+ },
17
+ args: {
18
+ name: 'radioGroupName',
19
+ modelValue: 'radio2',
20
+ options: [
21
+ {
22
+ id: 'radio-01',
23
+ label: 'Radio button Label',
24
+ value: 'radio1',
25
+ },
26
+ {
27
+ id: 'radio-02',
28
+ label: 'Radio button Label',
29
+ value: 'radio2',
30
+ },
31
+ {
32
+ id: 'radio-03',
33
+ label: 'Radio button Label',
34
+ value: 'radio3',
35
+ },
36
+ {
37
+ id: 'radio-04',
38
+ label: 'Radio button Label',
39
+ value: 'radio4',
40
+ },
41
+ ],
42
+ },
43
+ render: (args) => ({
44
+ components: { MRadioGroup },
45
+ setup() {
46
+ const handleUpdate = action('update:modelValue');
47
+
48
+ return { args, handleUpdate };
49
+ },
50
+ template: `
51
+ <MRadioGroup
52
+ v-bind="args"
53
+ @update:modelValue="handleUpdate"
54
+ />
55
+ `,
56
+ }),
57
+ };
58
+ export default meta;
59
+ type Story = StoryObj<typeof MRadioGroup>;
60
+
61
+ export const Default: Story = {};
@@ -0,0 +1,79 @@
1
+ <template>
2
+ <div class="mc-field__container" :class="classObjectContainer">
3
+ <MRadio
4
+ v-for="option in options"
5
+ :id="option.id"
6
+ :key="option.id"
7
+ :label="option.label"
8
+ :is-invalid="isInvalid"
9
+ :name="name"
10
+ class="mc-field__item"
11
+ :class="classObjectItem"
12
+ :model-value="modelValue === option.value"
13
+ :disabled="option.disabled"
14
+ @update:model-value="
15
+ (v: boolean) => (v ? emit('update:modelValue', option.value) : null)
16
+ "
17
+ />
18
+ </div>
19
+ </template>
20
+
21
+ <script setup lang="ts">
22
+ import { computed } from 'vue';
23
+ import MRadio from '../radio/MRadio.vue';
24
+
25
+ /**
26
+ * A radio button is used to offer a unique choice to your user in a form. Unlike checkboxes, it can not be used alone.
27
+ */
28
+ const props = defineProps<{
29
+ /**
30
+ * The name attribute for the radio element, typically used for form submission.
31
+ */
32
+ name: string;
33
+ /**
34
+ * Property used to manage the values checked by v-model
35
+ * (Do not use directly)
36
+ */
37
+ modelValue?: string;
38
+ /**
39
+ * list of properties of each radio button of the radio group
40
+ */
41
+ options: Array<{
42
+ id: string;
43
+ label: string;
44
+ value: string;
45
+ disabled?: boolean;
46
+ }>;
47
+ /**
48
+ * If `true`, applies an invalid state to the radio group.
49
+ */
50
+ isInvalid?: boolean;
51
+ /**
52
+ * If `true`, make the form element of the group inline.
53
+ */
54
+ inline?: boolean;
55
+ }>();
56
+
57
+ const classObjectContainer = computed(() => {
58
+ return {
59
+ 'mc-field__container--inline': props.inline,
60
+ };
61
+ });
62
+
63
+ const classObjectItem = computed(() => {
64
+ return {
65
+ 'mc-field__container--inline__item': props.inline,
66
+ };
67
+ });
68
+
69
+ const emit = defineEmits<{
70
+ /**
71
+ * Emits when the radio group value changes, updating the modelValue prop.
72
+ */
73
+ (on: 'update:modelValue', value: string): void;
74
+ }>();
75
+ </script>
76
+
77
+ <style lang="scss" scoped>
78
+ @use '@mozaic-ds/styles/components/field';
79
+ </style>
@@ -0,0 +1,114 @@
1
+ import { mount } from '@vue/test-utils';
2
+ import { describe, it, expect } from 'vitest';
3
+ import MSelect from './MSelect.vue';
4
+
5
+ describe('Select.vue', () => {
6
+ it('renders options correctly', () => {
7
+ const options = [
8
+ { text: 'Option 1', value: '1' },
9
+ { text: 'Option 2', value: '2' },
10
+ { text: 'Option 3', value: '3' },
11
+ ];
12
+
13
+ const wrapper = mount(MSelect, {
14
+ props: {
15
+ id: 'test-select',
16
+ modelValue: '1',
17
+ options,
18
+ },
19
+ });
20
+
21
+ const optionElements = wrapper.findAll('option');
22
+ expect(optionElements.length).toBe(options.length);
23
+ expect(optionElements[0].text()).toBe('Option 1');
24
+ expect(optionElements[1].text()).toBe('Option 2');
25
+ expect(optionElements[2].text()).toBe('Option 3');
26
+ });
27
+
28
+ it('renders placeholder when provided', () => {
29
+ const options = [
30
+ { text: 'Option 1', value: '1' },
31
+ { text: 'Option 2', value: '2' },
32
+ ];
33
+
34
+ const wrapper = mount(MSelect, {
35
+ props: {
36
+ id: 'test-select',
37
+ modelValue: '',
38
+ options,
39
+ placeholder: 'Select an option',
40
+ },
41
+ });
42
+
43
+ const placeholderOption = wrapper.find('option[disabled]');
44
+ expect(placeholderOption.exists()).toBe(true);
45
+ expect(placeholderOption.text()).toBe('-- Select an option --');
46
+ });
47
+
48
+ it('binds and updates the modelValue correctly', async () => {
49
+ const options = [
50
+ { text: 'Option 1', value: '1' },
51
+ { text: 'Option 2', value: '2' },
52
+ ];
53
+
54
+ const wrapper = mount(MSelect, {
55
+ props: {
56
+ id: 'test-select',
57
+ modelValue: '1',
58
+ options,
59
+ },
60
+ });
61
+
62
+ await wrapper.find('select').setValue('2');
63
+
64
+ const emitted = wrapper.emitted('update:modelValue');
65
+ expect(emitted).toBeDefined();
66
+ expect(emitted!.length).toBe(1);
67
+ expect(emitted![0]).toEqual(['2']);
68
+ });
69
+
70
+ it('disables the select when the disabled prop is true', () => {
71
+ const wrapper = mount(MSelect, {
72
+ props: {
73
+ id: 'test-select',
74
+ modelValue: '1',
75
+ options: [{ text: 'Option 1', value: '1' }],
76
+ disabled: true,
77
+ },
78
+ });
79
+
80
+ const select = wrapper.find('select');
81
+ expect(select.attributes('disabled')).toBeDefined();
82
+ });
83
+
84
+ it('applies the correct classes based on props', () => {
85
+ const wrapper = mount(MSelect, {
86
+ props: {
87
+ id: 'test-select',
88
+ modelValue: '1',
89
+ options: [{ text: 'Option 1', value: '1' }],
90
+ size: 's',
91
+ isInvalid: true,
92
+ },
93
+ });
94
+
95
+ const select = wrapper.find('select');
96
+
97
+ expect(select.classes()).toContain('mc-select--s');
98
+
99
+ expect(select.classes()).toContain('is-invalid');
100
+ });
101
+
102
+ it('does not apply invalid class if isInvalid is not set', () => {
103
+ const wrapper = mount(MSelect, {
104
+ props: {
105
+ id: 'test-select',
106
+ modelValue: '1',
107
+ options: [{ text: 'Option 1', value: '1' }],
108
+ },
109
+ });
110
+
111
+ const select = wrapper.find('select');
112
+ expect(select.classes()).not.toContain('is-invalid');
113
+ });
114
+ });
@@ -0,0 +1,101 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3-vite';
2
+ import { action } from 'storybook/actions';
3
+
4
+ import MSelect from './MSelect.vue';
5
+
6
+ const meta: Meta<typeof MSelect> = {
7
+ title: 'Form Elements/Select',
8
+ component: MSelect,
9
+ parameters: {
10
+ docs: {
11
+ description: {
12
+ component:
13
+ 'A select component allows users to choose a single option from a predefined list within a native dropdown menu. It helps simplify input by displaying only relevant choices, reducing the need for manual text entry. Select components are commonly used in forms, settings, and filters where structured selection is required.<br><br> To put a label, requierement text, help text or to apply a valid or invalid message, the examples are available in the [Field section](/docs/form-elements-field--docs#select).',
14
+ },
15
+ },
16
+ },
17
+ argTypes: {
18
+ ariaLabel: {
19
+ table: {
20
+ disable: true,
21
+ },
22
+ },
23
+ },
24
+ args: {
25
+ id: 'selectId',
26
+ placeholder: 'Choose an option',
27
+ options: [
28
+ {
29
+ text: 'Option 1',
30
+ value: 'option1',
31
+ },
32
+ {
33
+ text: 'Option 2',
34
+ value: 'option2',
35
+ disabled: true,
36
+ },
37
+ {
38
+ text: 'Option 3',
39
+ value: 'option3',
40
+ },
41
+ {
42
+ text: 'Option 4',
43
+ value: 'option4',
44
+ },
45
+ ],
46
+ ariaLabel: 'Choose an option',
47
+ },
48
+ render: (args) => ({
49
+ components: { MSelect },
50
+ setup() {
51
+ const handleUpdate = action('update:modelValue');
52
+
53
+ return { args, handleUpdate };
54
+ },
55
+ template: `
56
+ <MSelect
57
+ v-bind="args"
58
+ @update:modelValue="handleUpdate"
59
+ />
60
+ `,
61
+ }),
62
+ };
63
+ export default meta;
64
+ type Story = StoryObj<typeof MSelect>;
65
+
66
+ export const WithValue: Story = {
67
+ args: {
68
+ id: 'withValueId',
69
+ modelValue: 'option1',
70
+ },
71
+ };
72
+
73
+ export const Default: Story = {};
74
+
75
+ export const Small: Story = {
76
+ args: {
77
+ id: 'smallId',
78
+ size: 's',
79
+ },
80
+ };
81
+
82
+ export const Disabled: Story = {
83
+ args: {
84
+ id: 'disabledId',
85
+ disabled: true,
86
+ },
87
+ };
88
+
89
+ export const ReadOnly: Story = {
90
+ args: {
91
+ id: 'readonlyId',
92
+ readonly: true,
93
+ },
94
+ };
95
+
96
+ export const Invalid: Story = {
97
+ args: {
98
+ id: 'invalidId',
99
+ isInvalid: true,
100
+ },
101
+ };
@@ -1,15 +1,17 @@
1
1
  <template>
2
2
  <select
3
3
  :id="id"
4
- ref="select"
5
4
  class="mc-select"
6
- :class="[setClasses, cssFieldElementClass]"
7
- :value="getSelectValue"
5
+ :name="name"
6
+ :value="modelValue"
7
+ :class="classObject"
8
8
  :disabled="disabled"
9
- @change="onChange($event.target.value)"
10
- v-on="inputListeners"
9
+ v-bind="$attrs"
10
+ @change="
11
+ emit('update:modelValue', ($event.target as HTMLSelectElement).value)
12
+ "
11
13
  >
12
- <option v-if="placeholder" value="" disabled="disabled">
14
+ <option v-if="placeholder" value="" disabled>
13
15
  -- {{ placeholder }} --
14
16
  </option>
15
17
  <option
@@ -19,127 +21,83 @@
19
21
  v-bind="option.attributes"
20
22
  :disabled="option.disabled"
21
23
  >
22
- <slot name="text" :option="option">
23
- {{ option.text }}
24
- </slot>
24
+ {{ option.text }}
25
25
  </option>
26
- <slot name="options" />
27
26
  </select>
28
27
  </template>
29
28
 
30
- <script>
31
- export default {
32
- name: 'MSelect',
33
- inject: {
34
- cssFieldElementClass: {
35
- default: '',
36
- },
37
- },
38
-
39
- model: {
40
- prop: 'value',
41
- event: 'change',
42
- },
29
+ <script setup lang="ts">
30
+ import { computed } from 'vue';
43
31
 
44
- props: {
45
- id: {
46
- type: String,
47
- required: true,
48
- },
49
- options: {
50
- type: Array,
51
- required: true,
52
- },
53
- value: {
54
- type: [String, Number],
55
- default: null,
56
- },
57
- size: {
58
- type: String,
59
- default: 'm',
60
- validator: (value) => ['s', 'm'].includes(value),
61
- },
62
- placeholder: {
63
- type: String,
64
- default: null,
65
- },
66
- isValid: {
67
- type: Boolean,
68
- default: false,
69
- },
70
- isInvalid: {
71
- type: Boolean,
72
- default: false,
73
- },
74
- disabled: {
75
- type: Boolean,
76
- default: false,
77
- },
32
+ /**
33
+ * A select is a form element for multi-line text input, ideal for longer content like comments or descriptions.
34
+ */
35
+ const props = withDefaults(
36
+ defineProps<{
37
+ /**
38
+ * A unique identifier for the select, used to associate the label with the form element.
39
+ */
40
+ id: string;
41
+ /**
42
+ * The name attribute for the select element, used for form submission.
43
+ */
44
+ name?: string;
45
+ /**
46
+ * Define the available choices for the select element.
47
+ */
48
+ options: Array<{
49
+ id?: string;
50
+ text: string;
51
+ value: string | number;
52
+ attributes?: Record<string, string | boolean | number>;
53
+ disabled?: boolean;
54
+ }>;
55
+ /**
56
+ * The current value of the select.
57
+ */
58
+ modelValue?: string | number;
59
+ /**
60
+ * Text displayed when the select has no selected value.
61
+ */
62
+ placeholder?: string;
63
+ /**
64
+ * If `true`, the select is marked as invalid.
65
+ */
66
+ isInvalid?: boolean;
67
+ /**
68
+ * If `true`, the select is disabled and non-interactive.
69
+ */
70
+ disabled?: boolean;
71
+ /**
72
+ * Determines the size of the select
73
+ */
74
+ size?: 's' | 'm';
75
+ /**
76
+ * If `true`, the select is read-only (cannot be edited).
77
+ */
78
+ readonly?: boolean;
79
+ }>(),
80
+ {
81
+ size: 'm',
78
82
  },
83
+ );
79
84
 
80
- data() {
81
- return {
82
- optionValue: null,
83
- };
84
- },
85
-
86
- computed: {
87
- getSelectValue() {
88
- return this.optionValue ? this.optionValue : this.value;
89
- },
90
-
91
- setClasses() {
92
- const classes = [
93
- {
94
- 'is-valid': this.isValid,
95
- 'is-invalid': this.isInvalid,
96
- },
97
- ];
98
-
99
- if (this.size) {
100
- classes.push(`mc-select--${this.size}`);
101
- }
85
+ const classObject = computed(() => {
86
+ return {
87
+ [`mc-select--${props.size}`]: props.size && props.size != 'm',
88
+ 'mc-select--readonly': props.readonly,
89
+ 'is-invalid': props.isInvalid,
90
+ };
91
+ });
102
92
 
103
- return classes;
104
- },
105
- inputListeners: function () {
106
- // see => https://vuejs.org/v2/guide/components-custom-events.html#Binding-Native-Events-to-Components
107
- var vm = this;
108
- return Object.assign({}, this.$listeners, {
109
- change: function (event) {
110
- vm.$emit('change', event.target.value);
111
- },
112
- });
113
- },
114
- },
115
-
116
- mounted() {
117
- this.getOptionValue();
118
- },
119
-
120
- methods: {
121
- getOptionValue() {
122
- if (!this.value) {
123
- const firstOption = this.$el.querySelector('option');
124
- this.optionValue = firstOption.value;
125
- }
126
- },
127
- onChange(value) {
128
- const optionText = this.$refs.select
129
- .querySelector(`option[value="${value}"]`)
130
- .textContent.trim();
131
- const optionData = {
132
- text: optionText,
133
- value: value,
134
- };
135
-
136
- this.$emit('change', value, optionData);
137
- },
138
- },
139
- };
93
+ const emit = defineEmits<{
94
+ /**
95
+ * Emits when the select value changes, updating the modelValue prop.
96
+ */
97
+ (on: 'update:modelValue', value: string | number): void;
98
+ }>();
140
99
  </script>
141
100
 
142
- <style lang="scss">
143
- @import 'settings-tools/_all-settings';
144
- @import 'components/_c.select';
101
+ <style lang="scss" scoped>
102
+ @use '@mozaic-ds/styles/components/select';
145
103
  </style>
@@ -0,0 +1,45 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3-vite';
2
+ import MStatusBadge from './MStatusBadge.vue';
3
+
4
+ const meta: Meta<typeof MStatusBadge> = {
5
+ title: 'Status/Status Badge',
6
+ component: MStatusBadge,
7
+ parameters: {
8
+ docs: {
9
+ description: {
10
+ component:
11
+ 'A status badge indicates the status of an entity and can evolve at any time.',
12
+ },
13
+ },
14
+ },
15
+ args: { label: 'Badge label' },
16
+ render: (args) => ({
17
+ components: { MStatusBadge },
18
+ setup() {
19
+ return { args };
20
+ },
21
+ template: `
22
+ <MStatusBadge v-bind="args"></MStatusBadge>
23
+ `,
24
+ }),
25
+ };
26
+ export default meta;
27
+ type Story = StoryObj<typeof MStatusBadge>;
28
+
29
+ export const Info: Story = {};
30
+
31
+ export const Success: Story = {
32
+ args: { status: 'success' },
33
+ };
34
+
35
+ export const Warning: Story = {
36
+ args: { status: 'warning' },
37
+ };
38
+
39
+ export const Error: Story = {
40
+ args: { status: 'error' },
41
+ };
42
+
43
+ export const Neutral: Story = {
44
+ args: { status: 'neutral' },
45
+ };
@@ -0,0 +1,40 @@
1
+ <template>
2
+ <div class="mc-status-badge" :class="classObject">
3
+ <MStatusDot :status="status" />
4
+ <span class="mc-status-badge__label">{{ label }}</span>
5
+ </div>
6
+ </template>
7
+
8
+ <script setup lang="ts">
9
+ import { computed } from 'vue';
10
+ import MStatusDot from '../statusdot/MStatusDot.vue';
11
+ /**
12
+ * A status badge indicates the status of an entity and can evolve at any time.
13
+ */
14
+ const props = withDefaults(
15
+ defineProps<{
16
+ /**
17
+ * Content of the Status Badge
18
+ */
19
+ label: string;
20
+ /**
21
+ * Allows to define the Status Badge style
22
+ */
23
+ status?: 'info' | 'success' | 'warning' | 'error' | 'neutral';
24
+ }>(),
25
+ {
26
+ status: 'info',
27
+ },
28
+ );
29
+
30
+ const classObject = computed(() => {
31
+ return {
32
+ [`mc-status-badge--${props.status}`]:
33
+ props.status && props.status != 'info',
34
+ };
35
+ });
36
+ </script>
37
+
38
+ <style lang="scss" scoped>
39
+ @use '@mozaic-ds/styles/components/status-badge';
40
+ </style>
@@ -0,0 +1,16 @@
1
+ import { describe, it, expect } from 'vitest';
2
+
3
+ import { mount } from '@vue/test-utils';
4
+ import MStatusBadge from './MStatusBadge.vue';
5
+
6
+ describe('MStatusBadge component', () => {
7
+ it('renders properly', () => {
8
+ const wrapper = mount(MStatusBadge, {
9
+ props: {
10
+ label: 'Badge Label',
11
+ },
12
+ });
13
+
14
+ expect(wrapper.text()).toContain('Badge Label');
15
+ });
16
+ });