@mozaic-ds/vue 1.0.0-beta.3 → 1.0.0-beta.5

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 (191) hide show
  1. package/LICENSE +51 -0
  2. package/README.md +224 -82
  3. package/dist/mozaic-vue.css +1 -1
  4. package/dist/mozaic-vue.d.ts +1202 -0
  5. package/dist/mozaic-vue.js +1220 -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 +81 -50
  11. package/src/components/Contributing.mdx +118 -0
  12. package/src/components/GettingStarted.mdx +50 -0
  13. package/src/components/Introduction.mdx +54 -0
  14. package/src/components/Support.mdx +18 -0
  15. package/src/components/badge/MBadge.spec.ts +16 -0
  16. package/src/components/badge/MBadge.stories.ts +50 -0
  17. package/src/components/badge/MBadge.vue +36 -34
  18. package/src/components/breadcrumb/MBreadcrumb.spec.ts +105 -0
  19. package/src/components/breadcrumb/MBreadcrumb.stories.ts +57 -0
  20. package/src/components/breadcrumb/MBreadcrumb.vue +52 -55
  21. package/src/components/button/MButton.spec.ts +191 -0
  22. package/src/components/button/MButton.stories.ts +66 -0
  23. package/src/components/button/MButton.vue +98 -154
  24. package/src/components/checkbox/MCheckbox.spec.ts +104 -0
  25. package/src/components/checkbox/MCheckbox.stories.ts +83 -0
  26. package/src/components/checkbox/MCheckbox.vue +60 -101
  27. package/src/components/checkboxgroup/MCheckboxGroup.spec.ts +78 -0
  28. package/src/components/checkboxgroup/MCheckboxGroup.stories.ts +61 -0
  29. package/src/components/checkboxgroup/MCheckboxGroup.vue +97 -0
  30. package/src/components/field/MField.spec.ts +166 -0
  31. package/src/components/field/MField.stories.ts +376 -0
  32. package/src/components/field/MField.vue +78 -61
  33. package/src/components/fieldgroup/MFieldGroup.spec.ts +165 -0
  34. package/src/components/fieldgroup/MFieldGroup.stories.ts +423 -0
  35. package/src/components/fieldgroup/MFieldGroup.vue +79 -0
  36. package/src/components/iconbutton/MIconButton.spec.ts +108 -0
  37. package/src/components/iconbutton/MIconButton.stories.ts +66 -0
  38. package/src/components/iconbutton/MIconButton.vue +73 -0
  39. package/src/components/link/MLink.spec.ts +154 -0
  40. package/src/components/link/MLink.stories.ts +98 -0
  41. package/src/components/link/MLink.vue +86 -109
  42. package/src/components/loader/MLoader.spec.ts +104 -0
  43. package/src/components/loader/MLoader.stories.ts +45 -0
  44. package/src/components/loader/MLoader.vue +65 -55
  45. package/src/components/overlay/MOverlay.spec.ts +51 -0
  46. package/src/components/overlay/MOverlay.stories.ts +40 -0
  47. package/src/components/overlay/MOverlay.vue +27 -19
  48. package/src/components/passwordinput/MPasswordInput.spec.ts +104 -0
  49. package/src/components/passwordinput/MPasswordInput.stories.ts +75 -0
  50. package/src/components/passwordinput/MPasswordInput.vue +129 -76
  51. package/src/components/quantityselector/MQuantitySelector.spec.ts +262 -0
  52. package/src/components/quantityselector/MQuantitySelector.stories.ts +89 -0
  53. package/src/components/quantityselector/MQuantitySelector.vue +160 -136
  54. package/src/components/radio/MRadio.spec.ts +104 -0
  55. package/src/components/radio/MRadio.stories.ts +68 -0
  56. package/src/components/radio/MRadio.vue +56 -39
  57. package/src/components/radiogroup/MRadioGroup.spec.ts +54 -0
  58. package/src/components/radiogroup/MRadioGroup.stories.ts +61 -0
  59. package/src/components/radiogroup/MRadioGroup.vue +79 -0
  60. package/src/components/select/MSelect.spec.ts +114 -0
  61. package/src/components/select/MSelect.stories.ts +101 -0
  62. package/src/components/select/MSelect.vue +77 -119
  63. package/src/components/statusbadge/MStatusBadge.stories.ts +45 -0
  64. package/src/components/statusbadge/MStatusBadge.vue +40 -0
  65. package/src/components/statusbadge/MstatusBadge.spec.ts +16 -0
  66. package/src/components/statusdot/MStatusDot.spec.ts +51 -0
  67. package/src/components/statusdot/MStatusDot.stories.ts +48 -0
  68. package/src/components/statusdot/MStatusDot.vue +36 -0
  69. package/src/components/statusnotification/MStatusNotification.spec.ts +99 -0
  70. package/src/components/statusnotification/MStatusNotification.stories.ts +96 -0
  71. package/src/components/statusnotification/MStatusNotification.vue +106 -0
  72. package/src/components/textarea/MTextArea.spec.ts +112 -0
  73. package/src/components/textarea/MTextArea.stories.ts +67 -0
  74. package/src/components/textarea/MTextArea.vue +81 -42
  75. package/src/components/textinput/MTextInput.spec.ts +121 -0
  76. package/src/components/textinput/MTextInput.stories.ts +114 -0
  77. package/src/components/textinput/MTextInput.vue +127 -47
  78. package/src/components/toggle/MToggle.spec.ts +99 -0
  79. package/src/components/toggle/MToggle.stories.ts +68 -0
  80. package/src/components/toggle/MToggle.vue +63 -103
  81. package/src/components/togglegroup/MToggleGroup.spec.ts +78 -0
  82. package/src/components/togglegroup/MToggleGroup.stories.ts +61 -0
  83. package/src/components/togglegroup/MToggleGroup.vue +97 -0
  84. package/src/components/usingIcons.mdx +43 -0
  85. package/src/components/usingPresets.mdx +125 -0
  86. package/src/main.ts +47 -0
  87. package/dist/demo.html +0 -1
  88. package/dist/mozaic-vue.adeo.css +0 -45
  89. package/dist/mozaic-vue.adeo.umd.js +0 -41775
  90. package/dist/mozaic-vue.common.js +0 -41765
  91. package/dist/mozaic-vue.common.js.map +0 -1
  92. package/dist/mozaic-vue.umd.js +0 -41776
  93. package/dist/mozaic-vue.umd.js.map +0 -1
  94. package/dist/mozaic-vue.umd.min.js +0 -4
  95. package/dist/mozaic-vue.umd.min.js.map +0 -1
  96. package/postinstall.js +0 -3
  97. package/src/components/accordion/MAccordion.vue +0 -128
  98. package/src/components/accordion/index.js +0 -7
  99. package/src/components/autocomplete/MAutocomplete.vue +0 -198
  100. package/src/components/autocomplete/index.js +0 -7
  101. package/src/components/badge/index.js +0 -7
  102. package/src/components/breadcrumb/index.js +0 -7
  103. package/src/components/button/index.js +0 -7
  104. package/src/components/card/MCard.vue +0 -78
  105. package/src/components/card/index.js +0 -7
  106. package/src/components/checkbox/MCheckboxGroup.vue +0 -155
  107. package/src/components/checkbox/index.js +0 -12
  108. package/src/components/container/MContainer.vue +0 -33
  109. package/src/components/container/index.js +0 -7
  110. package/src/components/datatable/MDataTable.vue +0 -651
  111. package/src/components/datatable/MDataTableHeader.vue +0 -55
  112. package/src/components/datatable/MDataTableTop.vue +0 -35
  113. package/src/components/datatable/helpers.js +0 -132
  114. package/src/components/datatable/index.js +0 -12
  115. package/src/components/field/index.js +0 -7
  116. package/src/components/fileuploader/MFileResult.vue +0 -149
  117. package/src/components/fileuploader/MFileUploader.vue +0 -142
  118. package/src/components/fileuploader/index.js +0 -7
  119. package/src/components/flag/MFlag.vue +0 -46
  120. package/src/components/flag/index.js +0 -7
  121. package/src/components/heading/MHeading.vue +0 -75
  122. package/src/components/heading/index.js +0 -7
  123. package/src/components/hero/MHero.vue +0 -93
  124. package/src/components/hero/index.js +0 -7
  125. package/src/components/icon/MIcon.vue +0 -120
  126. package/src/components/icon/index.js +0 -7
  127. package/src/components/index.js +0 -43
  128. package/src/components/layer/MLayer.vue +0 -208
  129. package/src/components/layer/index.js +0 -7
  130. package/src/components/link/index.js +0 -7
  131. package/src/components/listbox/MListBox.vue +0 -106
  132. package/src/components/listbox/index.js +0 -7
  133. package/src/components/loader/index.js +0 -7
  134. package/src/components/modal/MModal.vue +0 -179
  135. package/src/components/modal/index.js +0 -7
  136. package/src/components/notification/MNotification.vue +0 -110
  137. package/src/components/notification/index.js +0 -7
  138. package/src/components/optionbutton/MOptionButton.vue +0 -67
  139. package/src/components/optionbutton/index.js +0 -7
  140. package/src/components/optioncard/MOptionCard.vue +0 -132
  141. package/src/components/optioncard/index.js +0 -7
  142. package/src/components/optiongroup/MOptionGroup.vue +0 -18
  143. package/src/components/optiongroup/index.js +0 -7
  144. package/src/components/overlay/MOverlayLoader.vue +0 -43
  145. package/src/components/overlay/index.js +0 -12
  146. package/src/components/pagination/MPagination.vue +0 -162
  147. package/src/components/pagination/index.js +0 -7
  148. package/src/components/passwordinput/index.js +0 -7
  149. package/src/components/phonenumber/MPhoneNumber.vue +0 -390
  150. package/src/components/phonenumber/index.js +0 -7
  151. package/src/components/progressbar/MProgress.vue +0 -102
  152. package/src/components/progressbar/index.js +0 -7
  153. package/src/components/quantityselector/index.js +0 -7
  154. package/src/components/radio/MRadioGroup.vue +0 -111
  155. package/src/components/radio/index.js +0 -12
  156. package/src/components/ratingstars/MStarsInput.vue +0 -118
  157. package/src/components/ratingstars/MStarsResult.vue +0 -89
  158. package/src/components/ratingstars/index.js +0 -12
  159. package/src/components/select/index.js +0 -7
  160. package/src/components/stepper/MStepper.vue +0 -70
  161. package/src/components/stepper/index.js +0 -7
  162. package/src/components/tabs/MTab.vue +0 -184
  163. package/src/components/tabs/index.js +0 -7
  164. package/src/components/tags/MTag.vue +0 -173
  165. package/src/components/tags/index.js +0 -7
  166. package/src/components/textarea/index.js +0 -7
  167. package/src/components/textinput/MTextInputField.vue +0 -105
  168. package/src/components/textinput/MTextInputIcon.vue +0 -42
  169. package/src/components/textinput/index.js +0 -7
  170. package/src/components/toggle/index.js +0 -7
  171. package/src/components/tooltip/MTooltip.vue +0 -42
  172. package/src/components/tooltip/index.js +0 -7
  173. package/src/index.js +0 -62
  174. package/src/shims-tsx.d.ts +0 -13
  175. package/src/shims.vue.d.ts +0 -4
  176. package/src/tokens/adeo/android/colors.xml +0 -391
  177. package/src/tokens/adeo/android/font_dimens.xml +0 -18
  178. package/src/tokens/adeo/css/_variables.scss +0 -385
  179. package/src/tokens/adeo/css/root.scss +0 -387
  180. package/src/tokens/adeo/ios/StyleDictionaryColor.h +0 -399
  181. package/src/tokens/adeo/ios/StyleDictionaryColor.m +0 -411
  182. package/src/tokens/adeo/ios/StyleDictionaryColor.swift +0 -394
  183. package/src/tokens/adeo/ios/StyleDictionarySize.h +0 -69
  184. package/src/tokens/adeo/ios/StyleDictionarySize.m +0 -70
  185. package/src/tokens/adeo/ios/StyleDictionarySize.swift +0 -71
  186. package/src/tokens/adeo/js/tokens.js +0 -483
  187. package/src/tokens/adeo/js/tokensObject.js +0 -10354
  188. package/src/tokens/adeo/scss/_tokens.scss +0 -1300
  189. package/src/utils/mozaicClasses.js +0 -16
  190. package/src/utils/theme.validator.js +0 -19
  191. package/types/index.d.ts +0 -100
@@ -1,169 +1,113 @@
1
1
  <template>
2
- <a v-if="href" :href="href" class="mc-button" :class="setClasses" :aria-label="ariaLabel">
3
- <m-icon
4
- v-if="icon && iconPosition === 'left'"
5
- :id="`mc-button__${iconPosition}-icon-${id}`"
6
- :class="`mc-button__icon mc-button__icon--${iconPosition}`"
7
- :name="icon"
8
- />
9
- <span v-if="label" class="mc-button__label">
10
- {{ label }}
11
- </span>
12
- <m-icon
13
- v-if="icon && iconPosition === 'right'"
14
- :id="`mc-button__${iconPosition}-icon-${id}`"
15
- :class="`mc-button__icon mc-button__icon--${iconPosition}`"
16
- :name="icon"
17
- />
18
- </a>
19
2
  <button
20
- v-else
21
3
  class="mc-button"
4
+ :class="classObject"
22
5
  :disabled="disabled"
23
- :class="setClasses"
24
- :aria-label="ariaLabel"
25
- @click="$emit('click', $event)"
6
+ :type="type"
26
7
  >
27
- <m-icon
28
- v-if="icon && iconPosition === 'left'"
29
- :id="`mc-button__${iconPosition}-icon-${id}`"
30
- :class="`mc-button__icon mc-button__icon--${iconPosition}`"
31
- :name="icon"
32
- />
33
- <span v-if="label" class="mc-button__label">
34
- {{ label }}
8
+ <span
9
+ v-if="$slots.icon && iconPosition == 'left' && !isLoading"
10
+ class="mc-button__icon"
11
+ >
12
+ <slot name="icon" />
13
+ </span>
14
+ <span
15
+ v-if="isLoading"
16
+ class="mc-button__icon"
17
+ :style="{ position: 'absolute' }"
18
+ >
19
+ <MLoader :style="{ color: 'currentColor' }" size="s" />
20
+ </span>
21
+ <span v-if="$slots.icon && iconPosition == 'only'" class="mc-button__icon">
22
+ <slot name="icon" />
23
+ </span>
24
+ <span
25
+ v-else
26
+ class="mc-button__label"
27
+ :style="{ visibility: isLoading ? 'hidden' : 'visible' }"
28
+ >
29
+ <slot>Button Label</slot>
30
+ </span>
31
+ <span
32
+ v-if="$slots.icon && iconPosition == 'right' && !isLoading"
33
+ class="mc-button__icon"
34
+ >
35
+ <slot name="icon" />
35
36
  </span>
36
- <m-icon
37
- v-if="icon && iconPosition === 'right'"
38
- :id="`mc-button__${iconPosition}-icon-${id}`"
39
- :class="`mc-button__icon mc-button__icon--${iconPosition}`"
40
- :name="icon"
41
- />
42
37
  </button>
43
38
  </template>
44
39
 
45
- <script>
46
- import {
47
- responsiveModifiers,
48
- responsiveModifierValidators,
49
- } from '../../utils/mozaicClasses';
50
- import MIcon from '../icon/MIcon.vue';
51
-
52
- export default {
53
- name: 'MButton',
54
-
55
- components: {
56
- MIcon,
57
- },
58
-
59
- props: {
60
- label: {
61
- type: String,
62
- default: null,
63
- },
64
- href: {
65
- type: String,
66
- default: null,
67
- },
68
- theme: {
69
- type: String,
70
- default: null,
71
- },
72
- size: {
73
- type: String,
74
- default: 'm',
75
- validator: (value) =>
76
- responsiveModifierValidators(value, [
77
- 's',
78
- 's@from-m',
79
- 's@from-l',
80
- 's@from-xl',
81
- 's@from-xxl',
82
- 'm',
83
- 'm@from-m',
84
- 'm@from-l',
85
- 'm@from-xl',
86
- 'm@from-xxl',
87
- 'l',
88
- 'l@from-m',
89
- 'l@from-l',
90
- 'l@from-xl',
91
- 'l@from-xxl',
92
- ]),
93
- },
94
- width: {
95
- type: String,
96
- default: null,
97
- validator: (value) =>
98
- responsiveModifierValidators(value, [
99
- 'fit',
100
- 'fit@from-m',
101
- 'fit@from-l',
102
- 'fit@from-xl',
103
- 'fit@from-xxl',
104
- 'full',
105
- 'full@from-m',
106
- 'full@from-l',
107
- 'full@from-xl',
108
- 'full@from-xxl',
109
- ]),
110
- },
111
- disabled: {
112
- type: Boolean,
113
- default: false,
114
- },
115
- icon: {
116
- type: String,
117
- default: null,
118
- },
119
- iconPosition: {
120
- type: String,
121
- default: 'left',
122
- validator: (value) => ['left', 'right'].includes(value),
123
- },
124
- ariaLabel: {
125
- type: String,
126
- default: null,
127
- },
40
+ <script setup lang="ts">
41
+ import { computed, type VNode } from 'vue';
42
+ import MLoader from '../loader/MLoader.vue';
43
+ /**
44
+ * Buttons are used to trigger actions. Their appearance is depending on the type of action required from the user, or the context.
45
+ */
46
+ const props = withDefaults(
47
+ defineProps<{
48
+ /**
49
+ * Defines the visual style of the button.
50
+ */
51
+ appearance?: 'standard' | 'accent' | 'danger' | 'inverse';
52
+ /**
53
+ * Determines the size of the button.
54
+ */
55
+ size?: 's' | 'm' | 'l';
56
+ /**
57
+ * If `true`, disables the button, making it non-interactive.
58
+ */
59
+ disabled?: boolean;
60
+ /**
61
+ * If `true`, applies a "ghost" style to the button, typically a transparent background with a border.
62
+ */
63
+ ghost?: boolean;
64
+ /**
65
+ * If `true`, the button gets an outlined style, usually with just the border and no solid background.
66
+ */
67
+ outlined?: boolean;
68
+ /**
69
+ * Controls the positioning of an icon in the button.
70
+ */
71
+ iconPosition?: 'left' | 'right' | 'only';
72
+ /**
73
+ * Specifies the button's HTML `type` attribute.
74
+ */
75
+ type?: 'button' | 'reset' | 'submit';
76
+ /**
77
+ * If `true`, a loading state is displayed.
78
+ */
79
+ isLoading?: boolean;
80
+ }>(),
81
+ {
82
+ appearance: 'standard',
83
+ size: 'm',
84
+ type: 'button',
128
85
  },
86
+ );
129
87
 
130
- data() {
131
- return {
132
- id: null,
133
- };
134
- },
135
-
136
- computed: {
137
- setClasses() {
138
- const classes = [];
139
-
140
- if (this.theme) {
141
- classes.push(`mc-button--${this.theme}`);
142
- }
143
-
144
- if (this.size) {
145
- responsiveModifiers('mc-button', this.size, classes);
146
- }
147
-
148
- if (this.width) {
149
- responsiveModifiers('mc-button', this.width, classes);
150
- }
88
+ defineSlots<{
89
+ /**
90
+ * The content displayed in the button.
91
+ */
92
+ default: string;
93
+ /**
94
+ * Use this slot to insert an icon for the Button
95
+ */
96
+ icon?: VNode;
97
+ }>();
151
98
 
152
- if (!this.label) {
153
- classes.push('mc-button--square');
154
- }
155
-
156
- return classes;
157
- },
158
- },
159
-
160
- created() {
161
- this.id = this._uid;
162
- },
163
- };
99
+ const classObject = computed(() => {
100
+ return {
101
+ [`mc-button--${props.appearance}`]:
102
+ props.appearance && props.appearance != 'standard',
103
+ [`mc-button--${props.size}`]: props.size && props.size != 'm',
104
+ 'mc-button--ghost': props.ghost,
105
+ 'mc-button--outlined': props.outlined,
106
+ 'mc-button--icon-only': props.iconPosition == 'only',
107
+ };
108
+ });
164
109
  </script>
165
110
 
166
- <style lang="scss">
167
- @import 'settings-tools/_all-settings';
168
- @import 'components/c.button';
111
+ <style lang="scss" scoped>
112
+ @use '@mozaic-ds/styles/components/button';
169
113
  </style>
@@ -0,0 +1,104 @@
1
+ import { mount } from '@vue/test-utils';
2
+ import MCheckbox from './MCheckbox.vue';
3
+ import { describe, it, expect } from 'vitest';
4
+
5
+ describe('MCheckbox', () => {
6
+ it('renders with label', () => {
7
+ const wrapper = mount(MCheckbox, {
8
+ props: {
9
+ id: 'test-checkbox',
10
+ label: 'Accept terms',
11
+ modelValue: false,
12
+ },
13
+ });
14
+
15
+ expect(wrapper.find('label').text()).toBe('Accept terms');
16
+ });
17
+
18
+ it('renders the checkbox as checked when modelValue is true', () => {
19
+ const wrapper = mount(MCheckbox, {
20
+ props: {
21
+ id: 'test-checkbox',
22
+ modelValue: true,
23
+ },
24
+ });
25
+
26
+ const checkbox = wrapper.find('input');
27
+ expect(checkbox.element.checked).toBe(true);
28
+ });
29
+
30
+ it('renders the checkbox as unchecked when modelValue is false', () => {
31
+ const wrapper = mount(MCheckbox, {
32
+ props: {
33
+ id: 'test-checkbox',
34
+ modelValue: false,
35
+ },
36
+ });
37
+
38
+ const checkbox = wrapper.find('input');
39
+ expect(checkbox.element.checked).toBe(false);
40
+ });
41
+
42
+ it('emits update:modelValue when clicked', async () => {
43
+ const wrapper = mount(MCheckbox, {
44
+ props: {
45
+ id: 'test-checkbox',
46
+ modelValue: false,
47
+ },
48
+ });
49
+
50
+ const checkbox = wrapper.find('input');
51
+ await checkbox.setChecked(true);
52
+
53
+ expect(wrapper.emitted()['update:modelValue'][0]).toEqual([true]);
54
+ });
55
+
56
+ it('emits update:modelValue when unchecked', async () => {
57
+ const wrapper = mount(MCheckbox, {
58
+ props: {
59
+ id: 'test-checkbox',
60
+ modelValue: true,
61
+ },
62
+ });
63
+
64
+ const checkbox = wrapper.find('input');
65
+ await checkbox.setChecked(false);
66
+
67
+ expect(wrapper.emitted()['update:modelValue'][0]).toEqual([false]);
68
+ });
69
+
70
+ it('is disabled when the disabled prop is true', () => {
71
+ const wrapper = mount(MCheckbox, {
72
+ props: {
73
+ id: 'test-checkbox',
74
+ disabled: true,
75
+ },
76
+ });
77
+
78
+ const checkbox = wrapper.find('input');
79
+ expect(checkbox.element.disabled).toBe(true);
80
+ });
81
+
82
+ it('sets the indeterminate state correctly', () => {
83
+ const wrapper = mount(MCheckbox, {
84
+ props: {
85
+ id: 'test-checkbox',
86
+ indeterminate: true,
87
+ },
88
+ });
89
+
90
+ const checkbox = wrapper.find('input');
91
+ expect(checkbox.element.indeterminate).toBe(true);
92
+ });
93
+
94
+ it('applies is-invalid class when isInvalid is true', () => {
95
+ const wrapper = mount(MCheckbox, {
96
+ props: {
97
+ id: 'test-checkbox',
98
+ isInvalid: true,
99
+ },
100
+ });
101
+
102
+ expect(wrapper.find('input').classes()).toContain('is-invalid');
103
+ });
104
+ });
@@ -0,0 +1,83 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3';
2
+ import { action } from '@storybook/addon-actions';
3
+
4
+ import MCheckbox from './MCheckbox.vue';
5
+
6
+ const meta: Meta<typeof MCheckbox> = {
7
+ title: 'Form Elements/Checkbox',
8
+ component: MCheckbox,
9
+ parameters: {
10
+ docs: {
11
+ description: {
12
+ component:
13
+ 'A checkbox is an interactive component used to select or deselect an option, typically within a list of choices. It allows users to make multiple selections independently and is often accompanied by a label for clarity. Checkboxes are commonly used in forms, filters, settings, and preference selections to provide a simple and intuitive way to enable or disable specific options.',
14
+ },
15
+ },
16
+ },
17
+ args: {
18
+ label: 'Label',
19
+ id: 'checkboxId',
20
+ },
21
+ render: (args) => ({
22
+ components: { MCheckbox },
23
+ setup() {
24
+ const handleUpdate = action('update:modelValue');
25
+
26
+ return { args, handleUpdate };
27
+ },
28
+ template: `
29
+ <MCheckbox
30
+ v-bind="args"
31
+ @update:modelValue="handleUpdate"
32
+ />
33
+ `,
34
+ }),
35
+ };
36
+ export default meta;
37
+ type Story = StoryObj<typeof MCheckbox>;
38
+
39
+ export const Default: Story = {};
40
+
41
+ export const Checked: Story = {
42
+ args: {
43
+ modelValue: true,
44
+ id: 'checkedId',
45
+ },
46
+ };
47
+
48
+ export const Indeterminate: Story = {
49
+ args: {
50
+ indeterminate: true,
51
+ id: 'IndeterminateId',
52
+ },
53
+ };
54
+
55
+ export const Disabled: Story = {
56
+ args: {
57
+ disabled: true,
58
+ id: 'disabledId',
59
+ },
60
+ };
61
+
62
+ export const Invalid: Story = {
63
+ args: {
64
+ isInvalid: true,
65
+ id: 'invalidId',
66
+ },
67
+ };
68
+
69
+ export const IndeterminateDisabled: Story = {
70
+ args: {
71
+ indeterminate: true,
72
+ disabled: true,
73
+ id: 'checkedIndeterminateId',
74
+ },
75
+ };
76
+
77
+ export const CheckedDisabled: Story = {
78
+ args: {
79
+ modelValue: true,
80
+ disabled: true,
81
+ id: 'checkedDisabledId',
82
+ },
83
+ };
@@ -1,118 +1,77 @@
1
1
  <template>
2
- <div v-if="hasLabel" class="mc-checkbox">
2
+ <div class="mc-checkbox">
3
3
  <input
4
- v-bind="$attrs"
5
4
  :id="id"
6
- ref="input"
7
- :name="name"
8
5
  type="checkbox"
9
6
  class="mc-checkbox__input"
10
- :class="setInputClasses"
11
- :checked="checked"
12
- :required="required"
7
+ :class="classObject"
8
+ :name="name"
9
+ :checked="modelValue"
10
+ :indeterminate="indeterminate"
13
11
  :disabled="disabled"
14
- @change="$emit('change', $event.target.checked)"
12
+ :aria-invalid="isInvalid"
13
+ v-bind="$attrs"
14
+ @change="
15
+ emit('update:modelValue', ($event.target as HTMLInputElement).checked)
16
+ "
15
17
  />
16
- <label :for="id" class="mc-checkbox__label">
17
- <slot name="label">
18
- {{ label }}
19
- </slot>
18
+ <label v-if="label" :for="id" class="mc-checkbox__label">
19
+ {{ label }}
20
20
  </label>
21
21
  </div>
22
-
23
- <input
24
- v-else
25
- v-bind="$attrs"
26
- :id="id"
27
- ref="input"
28
- :name="name"
29
- type="checkbox"
30
- class="mc-checkbox__input"
31
- :class="setInputClasses"
32
- :checked="checked"
33
- :required="required"
34
- :disabled="disabled"
35
- @change="$emit('change', $event.target.checked)"
36
- />
37
22
  </template>
38
23
 
39
- <script>
40
- export default {
41
- name: 'MCheckbox',
42
-
43
- inheritAttrs: false,
44
-
45
- model: {
46
- prop: 'checked',
47
- event: 'change',
48
- },
49
-
50
- props: {
51
- id: {
52
- type: String,
53
- required: true,
54
- },
55
- name: {
56
- type: String,
57
- default: null,
58
- },
59
- label: {
60
- type: String,
61
- default: null,
62
- },
63
- checked: {
64
- type: Boolean,
65
- default: false,
66
- },
67
- disabled: {
68
- type: Boolean,
69
- default: false,
70
- },
71
- required: {
72
- type: Boolean,
73
- default: false,
74
- },
75
- indeterminate: {
76
- type: Boolean,
77
- default: false,
78
- },
79
- isInvalid: {
80
- type: Boolean,
81
- default: false,
82
- },
83
- },
84
-
85
- computed: {
86
- hasLabel() {
87
- return this.label != null || this.$slots.label != null;
88
- },
89
-
90
- setInputClasses() {
91
- return {
92
- 'is-invalid': this.isInvalid,
93
- };
94
- },
95
- },
24
+ <script setup lang="ts">
25
+ import { computed } from 'vue';
96
26
 
97
- watch: {
98
- indeterminate() {
99
- this.setIndeterminate();
100
- },
101
- },
27
+ /**
28
+ * Checkboxes are used to select one or multiple options in a list. They usually find their place in forms and are also used to accept some mentions.
29
+ */
30
+ const props = defineProps<{
31
+ /**
32
+ * A unique identifier for the checkbox, used to associate the label with the form element.
33
+ */
34
+ id: string;
35
+ /**
36
+ * The name attribute for the checkbox element, typically used for form submission.
37
+ */
38
+ name?: string;
39
+ /**
40
+ * The text label displayed next to the checkbox.
41
+ */
42
+ label?: string;
43
+ /**
44
+ * The checkbox's checked state, bound via v-model.
45
+ */
46
+ modelValue?: boolean;
47
+ /**
48
+ * Sets the checkbox to an indeterminate state (partially selected).
49
+ */
50
+ indeterminate?: boolean;
51
+ /**
52
+ * If `true`, applies an invalid state to the checkbox.
53
+ */
54
+ isInvalid?: boolean;
55
+ /**
56
+ * If `true`, disables the checkbox, making it non-interactive.
57
+ */
58
+ disabled?: boolean;
59
+ }>();
102
60
 
103
- mounted() {
104
- this.setIndeterminate();
105
- },
61
+ const classObject = computed(() => {
62
+ return {
63
+ 'is-invalid': props.isInvalid,
64
+ };
65
+ });
106
66
 
107
- methods: {
108
- setIndeterminate() {
109
- this.$refs.input.indeterminate = this.indeterminate;
110
- },
111
- },
112
- };
67
+ const emit = defineEmits<{
68
+ /**
69
+ * Emits when the checkbox value changes, updating the modelValue prop.
70
+ */
71
+ (on: 'update:modelValue', value: boolean): void;
72
+ }>();
113
73
  </script>
114
74
 
115
- <style lang="scss">
116
- @import 'settings-tools/_all-settings';
117
- @import 'components/c.checkbox';
75
+ <style lang="scss" scoped>
76
+ @use '@mozaic-ds/styles/components/checkbox';
118
77
  </style>