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

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 (179) hide show
  1. package/LICENSE +51 -0
  2. package/README.md +218 -84
  3. package/dist/mozaic-vue.css +1 -1
  4. package/dist/mozaic-vue.d.ts +920 -0
  5. package/dist/mozaic-vue.js +877 -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 +80 -50
  11. package/src/components/Contributing.mdx +118 -0
  12. package/src/components/GettingStarted.mdx +39 -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/button/MButton.spec.ts +191 -0
  19. package/src/components/button/MButton.stories.ts +66 -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/field/MField.spec.ts +166 -0
  28. package/src/components/field/MField.stories.ts +376 -0
  29. package/src/components/field/MField.vue +78 -61
  30. package/src/components/fieldgroup/MFieldGroup.spec.ts +165 -0
  31. package/src/components/fieldgroup/MFieldGroup.stories.ts +274 -0
  32. package/src/components/fieldgroup/MFieldGroup.vue +79 -0
  33. package/src/components/iconbutton/MIconButton.spec.ts +108 -0
  34. package/src/components/iconbutton/MIconButton.stories.ts +66 -0
  35. package/src/components/iconbutton/MIconButton.vue +73 -0
  36. package/src/components/link/MLink.spec.ts +154 -0
  37. package/src/components/link/MLink.stories.ts +98 -0
  38. package/src/components/link/MLink.vue +86 -109
  39. package/src/components/loader/MLoader.spec.ts +104 -0
  40. package/src/components/loader/MLoader.stories.ts +45 -0
  41. package/src/components/loader/MLoader.vue +65 -55
  42. package/src/components/overlay/MOverlay.spec.ts +51 -0
  43. package/src/components/overlay/MOverlay.stories.ts +40 -0
  44. package/src/components/overlay/MOverlay.vue +27 -19
  45. package/src/components/quantityselector/MQuantitySelector.spec.ts +262 -0
  46. package/src/components/quantityselector/MQuantitySelector.stories.ts +89 -0
  47. package/src/components/quantityselector/MQuantitySelector.vue +160 -136
  48. package/src/components/radio/MRadio.spec.ts +104 -0
  49. package/src/components/radio/MRadio.stories.ts +68 -0
  50. package/src/components/radio/MRadio.vue +56 -39
  51. package/src/components/radiogroup/MRadioGroup.spec.ts +54 -0
  52. package/src/components/radiogroup/MRadioGroup.stories.ts +61 -0
  53. package/src/components/radiogroup/MRadioGroup.vue +79 -0
  54. package/src/components/select/MSelect.spec.ts +114 -0
  55. package/src/components/select/MSelect.stories.ts +101 -0
  56. package/src/components/select/MSelect.vue +77 -119
  57. package/src/components/statusbadge/MStatusBadge.stories.ts +45 -0
  58. package/src/components/statusbadge/MStatusBadge.vue +40 -0
  59. package/src/components/statusbadge/MStatusDot.vue +32 -0
  60. package/src/components/statusbadge/MstatusBadge.spec.ts +16 -0
  61. package/src/components/textarea/MTextArea.spec.ts +112 -0
  62. package/src/components/textarea/MTextArea.stories.ts +67 -0
  63. package/src/components/textarea/MTextArea.vue +81 -42
  64. package/src/components/textinput/MTextInput.spec.ts +121 -0
  65. package/src/components/textinput/MTextInput.stories.ts +114 -0
  66. package/src/components/textinput/MTextInput.vue +127 -47
  67. package/src/components/toggle/MToggle.spec.ts +99 -0
  68. package/src/components/toggle/MToggle.stories.ts +68 -0
  69. package/src/components/toggle/MToggle.vue +63 -103
  70. package/src/components/usingIcons.mdx +43 -0
  71. package/src/components/usingPresets.mdx +125 -0
  72. package/src/main.ts +39 -0
  73. package/dist/demo.html +0 -1
  74. package/dist/mozaic-vue.adeo.css +0 -45
  75. package/dist/mozaic-vue.adeo.umd.js +0 -41775
  76. package/dist/mozaic-vue.common.js +0 -41765
  77. package/dist/mozaic-vue.common.js.map +0 -1
  78. package/dist/mozaic-vue.umd.js +0 -41776
  79. package/dist/mozaic-vue.umd.js.map +0 -1
  80. package/dist/mozaic-vue.umd.min.js +0 -4
  81. package/dist/mozaic-vue.umd.min.js.map +0 -1
  82. package/postinstall.js +0 -3
  83. package/src/components/accordion/MAccordion.vue +0 -128
  84. package/src/components/accordion/index.js +0 -7
  85. package/src/components/autocomplete/MAutocomplete.vue +0 -198
  86. package/src/components/autocomplete/index.js +0 -7
  87. package/src/components/badge/index.js +0 -7
  88. package/src/components/breadcrumb/MBreadcrumb.vue +0 -73
  89. package/src/components/breadcrumb/index.js +0 -7
  90. package/src/components/button/index.js +0 -7
  91. package/src/components/card/MCard.vue +0 -78
  92. package/src/components/card/index.js +0 -7
  93. package/src/components/checkbox/MCheckboxGroup.vue +0 -155
  94. package/src/components/checkbox/index.js +0 -12
  95. package/src/components/container/MContainer.vue +0 -33
  96. package/src/components/container/index.js +0 -7
  97. package/src/components/datatable/MDataTable.vue +0 -651
  98. package/src/components/datatable/MDataTableHeader.vue +0 -55
  99. package/src/components/datatable/MDataTableTop.vue +0 -35
  100. package/src/components/datatable/helpers.js +0 -132
  101. package/src/components/datatable/index.js +0 -12
  102. package/src/components/field/index.js +0 -7
  103. package/src/components/fileuploader/MFileResult.vue +0 -149
  104. package/src/components/fileuploader/MFileUploader.vue +0 -142
  105. package/src/components/fileuploader/index.js +0 -7
  106. package/src/components/flag/MFlag.vue +0 -46
  107. package/src/components/flag/index.js +0 -7
  108. package/src/components/heading/MHeading.vue +0 -75
  109. package/src/components/heading/index.js +0 -7
  110. package/src/components/hero/MHero.vue +0 -93
  111. package/src/components/hero/index.js +0 -7
  112. package/src/components/icon/MIcon.vue +0 -120
  113. package/src/components/icon/index.js +0 -7
  114. package/src/components/index.js +0 -43
  115. package/src/components/layer/MLayer.vue +0 -208
  116. package/src/components/layer/index.js +0 -7
  117. package/src/components/link/index.js +0 -7
  118. package/src/components/listbox/MListBox.vue +0 -106
  119. package/src/components/listbox/index.js +0 -7
  120. package/src/components/loader/index.js +0 -7
  121. package/src/components/modal/MModal.vue +0 -179
  122. package/src/components/modal/index.js +0 -7
  123. package/src/components/notification/MNotification.vue +0 -110
  124. package/src/components/notification/index.js +0 -7
  125. package/src/components/optionbutton/MOptionButton.vue +0 -67
  126. package/src/components/optionbutton/index.js +0 -7
  127. package/src/components/optioncard/MOptionCard.vue +0 -132
  128. package/src/components/optioncard/index.js +0 -7
  129. package/src/components/optiongroup/MOptionGroup.vue +0 -18
  130. package/src/components/optiongroup/index.js +0 -7
  131. package/src/components/overlay/MOverlayLoader.vue +0 -43
  132. package/src/components/overlay/index.js +0 -12
  133. package/src/components/pagination/MPagination.vue +0 -162
  134. package/src/components/pagination/index.js +0 -7
  135. package/src/components/passwordinput/MPasswordInput.vue +0 -96
  136. package/src/components/passwordinput/index.js +0 -7
  137. package/src/components/phonenumber/MPhoneNumber.vue +0 -390
  138. package/src/components/phonenumber/index.js +0 -7
  139. package/src/components/progressbar/MProgress.vue +0 -102
  140. package/src/components/progressbar/index.js +0 -7
  141. package/src/components/quantityselector/index.js +0 -7
  142. package/src/components/radio/MRadioGroup.vue +0 -111
  143. package/src/components/radio/index.js +0 -12
  144. package/src/components/ratingstars/MStarsInput.vue +0 -118
  145. package/src/components/ratingstars/MStarsResult.vue +0 -89
  146. package/src/components/ratingstars/index.js +0 -12
  147. package/src/components/select/index.js +0 -7
  148. package/src/components/stepper/MStepper.vue +0 -70
  149. package/src/components/stepper/index.js +0 -7
  150. package/src/components/tabs/MTab.vue +0 -184
  151. package/src/components/tabs/index.js +0 -7
  152. package/src/components/tags/MTag.vue +0 -173
  153. package/src/components/tags/index.js +0 -7
  154. package/src/components/textarea/index.js +0 -7
  155. package/src/components/textinput/MTextInputField.vue +0 -105
  156. package/src/components/textinput/MTextInputIcon.vue +0 -42
  157. package/src/components/textinput/index.js +0 -7
  158. package/src/components/toggle/index.js +0 -7
  159. package/src/components/tooltip/MTooltip.vue +0 -42
  160. package/src/components/tooltip/index.js +0 -7
  161. package/src/index.js +0 -62
  162. package/src/shims-tsx.d.ts +0 -13
  163. package/src/shims.vue.d.ts +0 -4
  164. package/src/tokens/adeo/android/colors.xml +0 -391
  165. package/src/tokens/adeo/android/font_dimens.xml +0 -18
  166. package/src/tokens/adeo/css/_variables.scss +0 -385
  167. package/src/tokens/adeo/css/root.scss +0 -387
  168. package/src/tokens/adeo/ios/StyleDictionaryColor.h +0 -399
  169. package/src/tokens/adeo/ios/StyleDictionaryColor.m +0 -411
  170. package/src/tokens/adeo/ios/StyleDictionaryColor.swift +0 -394
  171. package/src/tokens/adeo/ios/StyleDictionarySize.h +0 -69
  172. package/src/tokens/adeo/ios/StyleDictionarySize.m +0 -70
  173. package/src/tokens/adeo/ios/StyleDictionarySize.swift +0 -71
  174. package/src/tokens/adeo/js/tokens.js +0 -483
  175. package/src/tokens/adeo/js/tokensObject.js +0 -10354
  176. package/src/tokens/adeo/scss/_tokens.scss +0 -1300
  177. package/src/utils/mozaicClasses.js +0 -16
  178. package/src/utils/theme.validator.js +0 -19
  179. 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
+ '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.',
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>