@mozaic-ds/vue 1.0.0-beta.1 → 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.
- package/LICENSE +51 -0
- package/README.md +218 -84
- package/dist/mozaic-vue.css +1 -1
- package/dist/mozaic-vue.d.ts +920 -0
- package/dist/mozaic-vue.js +877 -0
- package/dist/mozaic-vue.js.map +1 -0
- package/dist/mozaic-vue.umd.cjs +2 -0
- package/dist/mozaic-vue.umd.cjs.map +1 -0
- package/env.d.ts +1 -0
- package/package.json +80 -50
- package/src/components/Contributing.mdx +118 -0
- package/src/components/GettingStarted.mdx +39 -0
- package/src/components/Introduction.mdx +54 -0
- package/src/components/Support.mdx +18 -0
- package/src/components/badge/MBadge.spec.ts +16 -0
- package/src/components/badge/MBadge.stories.ts +50 -0
- package/src/components/badge/MBadge.vue +36 -34
- package/src/components/button/MButton.spec.ts +191 -0
- package/src/components/button/MButton.stories.ts +66 -0
- package/src/components/button/MButton.vue +98 -154
- package/src/components/checkbox/MCheckbox.spec.ts +104 -0
- package/src/components/checkbox/MCheckbox.stories.ts +83 -0
- package/src/components/checkbox/MCheckbox.vue +60 -101
- package/src/components/checkboxgroup/MCheckboxGroup.spec.ts +78 -0
- package/src/components/checkboxgroup/MCheckboxGroup.stories.ts +61 -0
- package/src/components/checkboxgroup/MCheckboxGroup.vue +97 -0
- package/src/components/field/MField.spec.ts +166 -0
- package/src/components/field/MField.stories.ts +376 -0
- package/src/components/field/MField.vue +78 -61
- package/src/components/fieldgroup/MFieldGroup.spec.ts +165 -0
- package/src/components/fieldgroup/MFieldGroup.stories.ts +274 -0
- package/src/components/fieldgroup/MFieldGroup.vue +79 -0
- package/src/components/iconbutton/MIconButton.spec.ts +108 -0
- package/src/components/iconbutton/MIconButton.stories.ts +66 -0
- package/src/components/iconbutton/MIconButton.vue +73 -0
- package/src/components/link/MLink.spec.ts +154 -0
- package/src/components/link/MLink.stories.ts +98 -0
- package/src/components/link/MLink.vue +86 -109
- package/src/components/loader/MLoader.spec.ts +104 -0
- package/src/components/loader/MLoader.stories.ts +45 -0
- package/src/components/loader/MLoader.vue +65 -55
- package/src/components/overlay/MOverlay.spec.ts +51 -0
- package/src/components/overlay/MOverlay.stories.ts +40 -0
- package/src/components/overlay/MOverlay.vue +27 -19
- package/src/components/quantityselector/MQuantitySelector.spec.ts +262 -0
- package/src/components/quantityselector/MQuantitySelector.stories.ts +89 -0
- package/src/components/quantityselector/MQuantitySelector.vue +160 -136
- package/src/components/radio/MRadio.spec.ts +104 -0
- package/src/components/radio/MRadio.stories.ts +68 -0
- package/src/components/radio/MRadio.vue +56 -39
- package/src/components/radiogroup/MRadioGroup.spec.ts +54 -0
- package/src/components/radiogroup/MRadioGroup.stories.ts +61 -0
- package/src/components/radiogroup/MRadioGroup.vue +79 -0
- package/src/components/select/MSelect.spec.ts +114 -0
- package/src/components/select/MSelect.stories.ts +101 -0
- package/src/components/select/MSelect.vue +77 -119
- package/src/components/statusbadge/MStatusBadge.stories.ts +45 -0
- package/src/components/statusbadge/MStatusBadge.vue +40 -0
- package/src/components/statusbadge/MStatusDot.vue +32 -0
- package/src/components/statusbadge/MstatusBadge.spec.ts +16 -0
- package/src/components/textarea/MTextArea.spec.ts +112 -0
- package/src/components/textarea/MTextArea.stories.ts +67 -0
- package/src/components/textarea/MTextArea.vue +81 -42
- package/src/components/textinput/MTextInput.spec.ts +121 -0
- package/src/components/textinput/MTextInput.stories.ts +114 -0
- package/src/components/textinput/MTextInput.vue +127 -47
- package/src/components/toggle/MToggle.spec.ts +99 -0
- package/src/components/toggle/MToggle.stories.ts +68 -0
- package/src/components/toggle/MToggle.vue +63 -103
- package/src/components/usingIcons.mdx +43 -0
- package/src/components/usingPresets.mdx +125 -0
- package/src/main.ts +39 -0
- package/dist/demo.html +0 -1
- package/dist/mozaic-vue.adeo.css +0 -45
- package/dist/mozaic-vue.adeo.umd.js +0 -41775
- package/dist/mozaic-vue.common.js +0 -41765
- package/dist/mozaic-vue.common.js.map +0 -1
- package/dist/mozaic-vue.umd.js +0 -41776
- package/dist/mozaic-vue.umd.js.map +0 -1
- package/dist/mozaic-vue.umd.min.js +0 -4
- package/dist/mozaic-vue.umd.min.js.map +0 -1
- package/postinstall.js +0 -3
- package/src/components/accordion/MAccordion.vue +0 -128
- package/src/components/accordion/index.js +0 -7
- package/src/components/autocomplete/MAutocomplete.vue +0 -198
- package/src/components/autocomplete/index.js +0 -7
- package/src/components/badge/index.js +0 -7
- package/src/components/breadcrumb/MBreadcrumb.vue +0 -73
- package/src/components/breadcrumb/index.js +0 -7
- package/src/components/button/index.js +0 -7
- package/src/components/card/MCard.vue +0 -78
- package/src/components/card/index.js +0 -7
- package/src/components/checkbox/MCheckboxGroup.vue +0 -155
- package/src/components/checkbox/index.js +0 -12
- package/src/components/container/MContainer.vue +0 -33
- package/src/components/container/index.js +0 -7
- package/src/components/datatable/MDataTable.vue +0 -651
- package/src/components/datatable/MDataTableHeader.vue +0 -55
- package/src/components/datatable/MDataTableTop.vue +0 -35
- package/src/components/datatable/helpers.js +0 -132
- package/src/components/datatable/index.js +0 -12
- package/src/components/field/index.js +0 -7
- package/src/components/fileuploader/MFileResult.vue +0 -149
- package/src/components/fileuploader/MFileUploader.vue +0 -142
- package/src/components/fileuploader/index.js +0 -7
- package/src/components/flag/MFlag.vue +0 -46
- package/src/components/flag/index.js +0 -7
- package/src/components/heading/MHeading.vue +0 -75
- package/src/components/heading/index.js +0 -7
- package/src/components/hero/MHero.vue +0 -93
- package/src/components/hero/index.js +0 -7
- package/src/components/icon/MIcon.vue +0 -120
- package/src/components/icon/index.js +0 -7
- package/src/components/index.js +0 -43
- package/src/components/layer/MLayer.vue +0 -208
- package/src/components/layer/index.js +0 -7
- package/src/components/link/index.js +0 -7
- package/src/components/listbox/MListBox.vue +0 -106
- package/src/components/listbox/index.js +0 -7
- package/src/components/loader/index.js +0 -7
- package/src/components/modal/MModal.vue +0 -179
- package/src/components/modal/index.js +0 -7
- package/src/components/notification/MNotification.vue +0 -110
- package/src/components/notification/index.js +0 -7
- package/src/components/optionbutton/MOptionButton.vue +0 -67
- package/src/components/optionbutton/index.js +0 -7
- package/src/components/optioncard/MOptionCard.vue +0 -132
- package/src/components/optioncard/index.js +0 -7
- package/src/components/optiongroup/MOptionGroup.vue +0 -18
- package/src/components/optiongroup/index.js +0 -7
- package/src/components/overlay/MOverlayLoader.vue +0 -43
- package/src/components/overlay/index.js +0 -12
- package/src/components/pagination/MPagination.vue +0 -162
- package/src/components/pagination/index.js +0 -7
- package/src/components/passwordinput/MPasswordInput.vue +0 -96
- package/src/components/passwordinput/index.js +0 -7
- package/src/components/phonenumber/MPhoneNumber.vue +0 -390
- package/src/components/phonenumber/index.js +0 -7
- package/src/components/progressbar/MProgress.vue +0 -102
- package/src/components/progressbar/index.js +0 -7
- package/src/components/quantityselector/index.js +0 -7
- package/src/components/radio/MRadioGroup.vue +0 -111
- package/src/components/radio/index.js +0 -12
- package/src/components/ratingstars/MStarsInput.vue +0 -118
- package/src/components/ratingstars/MStarsResult.vue +0 -89
- package/src/components/ratingstars/index.js +0 -12
- package/src/components/select/index.js +0 -7
- package/src/components/stepper/MStepper.vue +0 -70
- package/src/components/stepper/index.js +0 -7
- package/src/components/tabs/MTab.vue +0 -184
- package/src/components/tabs/index.js +0 -7
- package/src/components/tags/MTag.vue +0 -173
- package/src/components/tags/index.js +0 -7
- package/src/components/textarea/index.js +0 -7
- package/src/components/textinput/MTextInputField.vue +0 -105
- package/src/components/textinput/MTextInputIcon.vue +0 -42
- package/src/components/textinput/index.js +0 -7
- package/src/components/toggle/index.js +0 -7
- package/src/components/tooltip/MTooltip.vue +0 -42
- package/src/components/tooltip/index.js +0 -7
- package/src/index.js +0 -62
- package/src/shims-tsx.d.ts +0 -13
- package/src/shims.vue.d.ts +0 -4
- package/src/tokens/adeo/android/colors.xml +0 -391
- package/src/tokens/adeo/android/font_dimens.xml +0 -18
- package/src/tokens/adeo/css/_variables.scss +0 -385
- package/src/tokens/adeo/css/root.scss +0 -387
- package/src/tokens/adeo/ios/StyleDictionaryColor.h +0 -399
- package/src/tokens/adeo/ios/StyleDictionaryColor.m +0 -411
- package/src/tokens/adeo/ios/StyleDictionaryColor.swift +0 -394
- package/src/tokens/adeo/ios/StyleDictionarySize.h +0 -69
- package/src/tokens/adeo/ios/StyleDictionarySize.m +0 -70
- package/src/tokens/adeo/ios/StyleDictionarySize.swift +0 -71
- package/src/tokens/adeo/js/tokens.js +0 -483
- package/src/tokens/adeo/js/tokensObject.js +0 -10354
- package/src/tokens/adeo/scss/_tokens.scss +0 -1300
- package/src/utils/mozaicClasses.js +0 -16
- package/src/utils/theme.validator.js +0 -19
- 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
|
-
:
|
|
24
|
-
:aria-label="ariaLabel"
|
|
25
|
-
@click="$emit('click', $event)"
|
|
6
|
+
:type="type"
|
|
26
7
|
>
|
|
27
|
-
<
|
|
28
|
-
v-if="icon && iconPosition
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
<span
|
|
34
|
-
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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
|
-
@
|
|
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
|
|
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="
|
|
11
|
-
:
|
|
12
|
-
:
|
|
7
|
+
:class="classObject"
|
|
8
|
+
:name="name"
|
|
9
|
+
:checked="modelValue"
|
|
10
|
+
:indeterminate="indeterminate"
|
|
13
11
|
:disabled="disabled"
|
|
14
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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
|
-
|
|
104
|
-
|
|
105
|
-
|
|
61
|
+
const classObject = computed(() => {
|
|
62
|
+
return {
|
|
63
|
+
'is-invalid': props.isInvalid,
|
|
64
|
+
};
|
|
65
|
+
});
|
|
106
66
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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
|
-
@
|
|
117
|
-
@import 'components/c.checkbox';
|
|
75
|
+
<style lang="scss" scoped>
|
|
76
|
+
@use '@mozaic-ds/styles/components/checkbox';
|
|
118
77
|
</style>
|