@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.
- package/LICENSE +51 -0
- package/README.md +224 -82
- package/dist/mozaic-vue.css +1 -1
- package/dist/mozaic-vue.d.ts +1202 -0
- package/dist/mozaic-vue.js +1220 -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 +81 -50
- package/src/components/Contributing.mdx +118 -0
- package/src/components/GettingStarted.mdx +50 -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/breadcrumb/MBreadcrumb.spec.ts +105 -0
- package/src/components/breadcrumb/MBreadcrumb.stories.ts +57 -0
- package/src/components/breadcrumb/MBreadcrumb.vue +52 -55
- 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 +423 -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/passwordinput/MPasswordInput.spec.ts +104 -0
- package/src/components/passwordinput/MPasswordInput.stories.ts +75 -0
- package/src/components/passwordinput/MPasswordInput.vue +129 -76
- 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/MstatusBadge.spec.ts +16 -0
- package/src/components/statusdot/MStatusDot.spec.ts +51 -0
- package/src/components/statusdot/MStatusDot.stories.ts +48 -0
- package/src/components/statusdot/MStatusDot.vue +36 -0
- package/src/components/statusnotification/MStatusNotification.spec.ts +99 -0
- package/src/components/statusnotification/MStatusNotification.stories.ts +96 -0
- package/src/components/statusnotification/MStatusNotification.vue +106 -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/togglegroup/MToggleGroup.spec.ts +78 -0
- package/src/components/togglegroup/MToggleGroup.stories.ts +61 -0
- package/src/components/togglegroup/MToggleGroup.vue +97 -0
- package/src/components/usingIcons.mdx +43 -0
- package/src/components/usingPresets.mdx +125 -0
- package/src/main.ts +47 -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/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/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,84 +1,94 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="mc-loader" :class="
|
|
2
|
+
<div class="mc-loader" :class="classObject">
|
|
3
3
|
<span class="mc-loader__spinner">
|
|
4
4
|
<svg
|
|
5
5
|
class="mc-loader__icon"
|
|
6
6
|
xmlns="http://www.w3.org/2000/svg"
|
|
7
|
-
:viewBox="
|
|
7
|
+
:viewBox="setViewBox"
|
|
8
|
+
aria-hidden="true"
|
|
8
9
|
>
|
|
9
|
-
<circle
|
|
10
|
+
<circle
|
|
11
|
+
class="mc-loader__path"
|
|
12
|
+
cx="50%"
|
|
13
|
+
cy="50%"
|
|
14
|
+
:r="setCircleRadius"
|
|
15
|
+
></circle>
|
|
10
16
|
</svg>
|
|
11
17
|
</span>
|
|
12
|
-
|
|
13
|
-
<span v-if="text" class="mc-loader__text">{{ text }}</span>
|
|
18
|
+
<p v-if="text" class="mc-loader__text" role="status">{{ text }}</p>
|
|
14
19
|
</div>
|
|
15
20
|
</template>
|
|
16
21
|
|
|
17
|
-
<script>
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
<script setup lang="ts">
|
|
23
|
+
import { computed } from 'vue';
|
|
24
|
+
/**
|
|
25
|
+
* A loader indicates that content or data is being loaded or processed, providing visual feedback to users during wait times.
|
|
26
|
+
*/
|
|
27
|
+
const props = withDefaults(
|
|
28
|
+
defineProps<{
|
|
22
29
|
/**
|
|
23
|
-
*
|
|
24
|
-
* @values s, m , l
|
|
30
|
+
* Specifies the visual appearance of the loader.
|
|
25
31
|
*/
|
|
26
|
-
|
|
27
|
-
type: String,
|
|
28
|
-
default: 'm',
|
|
29
|
-
validator: (value) => ['s', 'm', 'l'].includes(value),
|
|
30
|
-
},
|
|
32
|
+
appearance?: 'standard' | 'accent' | 'inverse';
|
|
31
33
|
|
|
32
34
|
/**
|
|
33
|
-
*
|
|
34
|
-
* @values dark, light, primary
|
|
35
|
+
* Defines the size of the loader.
|
|
35
36
|
*/
|
|
36
|
-
|
|
37
|
-
type: String,
|
|
38
|
-
default: 'primary',
|
|
39
|
-
validator: (value) => ['dark', 'light', 'primary'].includes(value),
|
|
40
|
-
},
|
|
37
|
+
size?: 's' | 'm' | 'l';
|
|
41
38
|
|
|
42
39
|
/**
|
|
43
|
-
*
|
|
40
|
+
* Text to display alongside the loader when using the loader inside an `Overlay`.
|
|
44
41
|
*/
|
|
45
|
-
text
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
42
|
+
text?: string;
|
|
43
|
+
}>(),
|
|
44
|
+
{
|
|
45
|
+
appearance: 'standard',
|
|
46
|
+
size: 'm',
|
|
49
47
|
},
|
|
48
|
+
);
|
|
50
49
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
const classObject = computed(() => {
|
|
51
|
+
return {
|
|
52
|
+
[`mc-loader--${props.size}`]: props.size && props.size !== 'm',
|
|
53
|
+
[`mc-loader--${props.appearance}`]:
|
|
54
|
+
props.appearance && props.appearance !== 'standard',
|
|
55
|
+
};
|
|
56
|
+
});
|
|
54
57
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
+
const setViewBox = computed(() => {
|
|
59
|
+
let viewBox: string;
|
|
58
60
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
switch (props.size) {
|
|
62
|
+
case 's':
|
|
63
|
+
viewBox = '0 0 24 24';
|
|
64
|
+
break;
|
|
65
|
+
case 'l':
|
|
66
|
+
viewBox = '0 0 64 64';
|
|
67
|
+
break;
|
|
68
|
+
default:
|
|
69
|
+
viewBox = '0 0 32 32';
|
|
70
|
+
}
|
|
71
|
+
return viewBox;
|
|
72
|
+
});
|
|
62
73
|
|
|
63
|
-
|
|
64
|
-
|
|
74
|
+
const setCircleRadius = computed(() => {
|
|
75
|
+
let circleRadius: number;
|
|
65
76
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
77
|
+
switch (props.size) {
|
|
78
|
+
case 's':
|
|
79
|
+
circleRadius = 6;
|
|
80
|
+
break;
|
|
81
|
+
case 'l':
|
|
82
|
+
circleRadius = 19;
|
|
83
|
+
break;
|
|
84
|
+
default:
|
|
85
|
+
circleRadius = 9;
|
|
86
|
+
}
|
|
73
87
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
},
|
|
77
|
-
},
|
|
78
|
-
};
|
|
88
|
+
return circleRadius;
|
|
89
|
+
});
|
|
79
90
|
</script>
|
|
80
91
|
|
|
81
|
-
<style lang="scss">
|
|
82
|
-
@
|
|
83
|
-
@import 'components/c.loader';
|
|
92
|
+
<style lang="scss" scoped>
|
|
93
|
+
@use '@mozaic-ds/styles/components/loader';
|
|
84
94
|
</style>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils';
|
|
2
|
+
import { describe, it, expect } from 'vitest';
|
|
3
|
+
import MOverlay from './MOverlay.vue';
|
|
4
|
+
|
|
5
|
+
describe('MOverlay.vue', () => {
|
|
6
|
+
it('should be visible when isVisible is true', () => {
|
|
7
|
+
const wrapper = mount(MOverlay, {
|
|
8
|
+
props: {
|
|
9
|
+
isVisible: true,
|
|
10
|
+
},
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
expect(wrapper.classes()).toContain('is-visible');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('should not be visible when isVisible is false', () => {
|
|
17
|
+
const wrapper = mount(MOverlay, {
|
|
18
|
+
props: {
|
|
19
|
+
isVisible: false,
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
expect(wrapper.classes()).not.toContain('is-visible');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should apply the dialog label for accessibility', () => {
|
|
27
|
+
const label = 'Overlay Dialog';
|
|
28
|
+
const wrapper = mount(MOverlay, {
|
|
29
|
+
props: {
|
|
30
|
+
dialogLabel: label,
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
expect(
|
|
35
|
+
wrapper.find('div[role="dialog"]').attributes('aria-labelledby'),
|
|
36
|
+
).toBe(label);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('should render the content inside the overlay', () => {
|
|
40
|
+
const wrapper = mount(MOverlay, {
|
|
41
|
+
props: {
|
|
42
|
+
isVisible: true,
|
|
43
|
+
},
|
|
44
|
+
slots: {
|
|
45
|
+
default: 'Overlay Content',
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
expect(wrapper.text()).toContain('Overlay Content');
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3';
|
|
2
|
+
import MOverlay from './MOverlay.vue';
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof MOverlay> = {
|
|
5
|
+
title: 'Overlay/Overlay',
|
|
6
|
+
component: MOverlay,
|
|
7
|
+
parameters: {
|
|
8
|
+
docs: {
|
|
9
|
+
description: {
|
|
10
|
+
component:
|
|
11
|
+
'An overlay component is a UI element that appears above the main content to display additional information or interactions, often blocking or dimming the background.',
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
args: {
|
|
16
|
+
isVisible: true,
|
|
17
|
+
},
|
|
18
|
+
argTypes: {
|
|
19
|
+
$slots: {
|
|
20
|
+
table: {
|
|
21
|
+
disable: true,
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
render: (args) => ({
|
|
26
|
+
components: { MOverlay },
|
|
27
|
+
setup() {
|
|
28
|
+
return { args };
|
|
29
|
+
},
|
|
30
|
+
template: `
|
|
31
|
+
<MOverlay v-bind="args">
|
|
32
|
+
<template v-if="${'default' in args}" v-slot>${args.default}</template>
|
|
33
|
+
</MOverlay>
|
|
34
|
+
`,
|
|
35
|
+
}),
|
|
36
|
+
};
|
|
37
|
+
export default meta;
|
|
38
|
+
type Story = StoryObj<typeof MOverlay>;
|
|
39
|
+
|
|
40
|
+
export const Default: Story = {};
|
|
@@ -1,28 +1,36 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="mc-overlay" :class="{ 'is-visible': isVisible }">
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
<div role="dialog" tabindex="-1" :aria-labelledby="dialogLabel">
|
|
4
|
+
<slot />
|
|
5
|
+
</div>
|
|
5
6
|
</div>
|
|
6
7
|
</template>
|
|
7
8
|
|
|
8
|
-
<script>
|
|
9
|
-
|
|
10
|
-
name: 'MOverlay',
|
|
9
|
+
<script setup lang="ts">
|
|
10
|
+
import type { VNode } from 'vue';
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
12
|
+
/**
|
|
13
|
+
* An overlay component is a UI element that appears above the main content to display additional information or interactions, often blocking or dimming the background.
|
|
14
|
+
*/
|
|
15
|
+
defineProps<{
|
|
16
|
+
/**
|
|
17
|
+
* Controls the visibility of the overlay.
|
|
18
|
+
*/
|
|
19
|
+
isVisible?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Accessible label for the overlay dialog.
|
|
22
|
+
*/
|
|
23
|
+
dialogLabel?: string;
|
|
24
|
+
}>();
|
|
25
|
+
|
|
26
|
+
defineSlots<{
|
|
27
|
+
/**
|
|
28
|
+
* Use this slot to insert a centered content inside the overlay
|
|
29
|
+
*/
|
|
30
|
+
default?: VNode;
|
|
31
|
+
}>();
|
|
23
32
|
</script>
|
|
24
33
|
|
|
25
|
-
<style lang="scss">
|
|
26
|
-
@
|
|
27
|
-
@import 'components/c.overlay';
|
|
34
|
+
<style lang="scss" scoped>
|
|
35
|
+
@use '@mozaic-ds/styles/components/overlay';
|
|
28
36
|
</style>
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils';
|
|
2
|
+
import { describe, it, expect } from 'vitest';
|
|
3
|
+
import MPasswordInput from './MPasswordInput.vue';
|
|
4
|
+
|
|
5
|
+
describe('MPasswordInput.vue', () => {
|
|
6
|
+
it('renders correctly with default props', () => {
|
|
7
|
+
const wrapper = mount(MPasswordInput, {
|
|
8
|
+
props: {
|
|
9
|
+
id: 'password-input',
|
|
10
|
+
},
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const input = wrapper.find('input');
|
|
14
|
+
const toggleButton = wrapper.find('button[role="switch"]');
|
|
15
|
+
|
|
16
|
+
expect(input.exists()).toBe(true);
|
|
17
|
+
expect(input.attributes('type')).toBe('password');
|
|
18
|
+
|
|
19
|
+
expect(toggleButton.exists()).toBe(true);
|
|
20
|
+
expect(toggleButton.text()).toBe('Show');
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('toggles password visibility on button click', async () => {
|
|
24
|
+
const wrapper = mount(MPasswordInput, {
|
|
25
|
+
props: {
|
|
26
|
+
id: 'password-input',
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const toggleButton = wrapper.find('button[role="switch"]');
|
|
31
|
+
const input = wrapper.find('input');
|
|
32
|
+
|
|
33
|
+
expect(input.attributes('type')).toBe('password');
|
|
34
|
+
|
|
35
|
+
await toggleButton.trigger('click');
|
|
36
|
+
|
|
37
|
+
expect(input.attributes('type')).toBe('text');
|
|
38
|
+
expect(toggleButton.text()).toBe('Hide');
|
|
39
|
+
|
|
40
|
+
await toggleButton.trigger('click');
|
|
41
|
+
|
|
42
|
+
expect(input.attributes('type')).toBe('password');
|
|
43
|
+
expect(toggleButton.text()).toBe('Show');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('should update modelValue when input value changes', async () => {
|
|
47
|
+
const wrapper = mount(MPasswordInput, {
|
|
48
|
+
props: {
|
|
49
|
+
id: 'password-input',
|
|
50
|
+
modelValue: '',
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const input = wrapper.find('input');
|
|
55
|
+
await input.setValue('newPassword123');
|
|
56
|
+
|
|
57
|
+
expect(wrapper.emitted()['update:modelValue']).toBeTruthy();
|
|
58
|
+
expect(wrapper.emitted()['update:modelValue'][0]).toEqual([
|
|
59
|
+
'newPassword123',
|
|
60
|
+
]);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('clears the input when the clear button is clicked', async () => {
|
|
64
|
+
const wrapper = mount(MPasswordInput, {
|
|
65
|
+
props: {
|
|
66
|
+
id: 'password-input',
|
|
67
|
+
modelValue: 'somePassword',
|
|
68
|
+
isClearable: true,
|
|
69
|
+
clearLabel: 'Clear content',
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const clearButton = wrapper.find('.mc-controls-options__button');
|
|
74
|
+
|
|
75
|
+
await clearButton.trigger('click');
|
|
76
|
+
|
|
77
|
+
expect(wrapper.emitted()['update:modelValue']).toBeTruthy();
|
|
78
|
+
expect(wrapper.emitted()['update:modelValue'][0]).toEqual(['']);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('disables the input when disabled prop is passed', () => {
|
|
82
|
+
const wrapper = mount(MPasswordInput, {
|
|
83
|
+
props: {
|
|
84
|
+
id: 'password-input',
|
|
85
|
+
disabled: true,
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const input = wrapper.find('input');
|
|
90
|
+
|
|
91
|
+
expect(input.attributes('disabled')).toBeDefined();
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('applies invalid state when isInvalid prop is true', () => {
|
|
95
|
+
const wrapper = mount(MPasswordInput, {
|
|
96
|
+
props: {
|
|
97
|
+
id: 'password-input',
|
|
98
|
+
isInvalid: true,
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
expect(wrapper.classes()).toContain('is-invalid');
|
|
103
|
+
});
|
|
104
|
+
});
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3';
|
|
2
|
+
import { action } from '@storybook/addon-actions';
|
|
3
|
+
|
|
4
|
+
import MPasswordInput from './MPasswordInput.vue';
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof MPasswordInput> = {
|
|
7
|
+
title: 'Form Elements/PasswordInput',
|
|
8
|
+
component: MPasswordInput,
|
|
9
|
+
parameters: {
|
|
10
|
+
docs: {
|
|
11
|
+
description: {
|
|
12
|
+
component:
|
|
13
|
+
'A password input is a specialized input field used to securely enter and manage passwords. It typically masks the characters entered to protect sensitive information from being seen. It includes a toggle button to show or hide the password, improving usability while maintaining security. Password inputs are commonly used in login forms, account creation, and authentication flows.<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#input).',
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
args: {
|
|
18
|
+
id: 'passwordInputId',
|
|
19
|
+
placeholder: 'Enter your password',
|
|
20
|
+
},
|
|
21
|
+
render: (args) => ({
|
|
22
|
+
components: { MPasswordInput },
|
|
23
|
+
setup() {
|
|
24
|
+
const handleUpdate = action('update:modelValue');
|
|
25
|
+
|
|
26
|
+
return { args, handleUpdate };
|
|
27
|
+
},
|
|
28
|
+
template: `
|
|
29
|
+
<MPasswordInput
|
|
30
|
+
v-bind="args"
|
|
31
|
+
@update:modelValue="handleUpdate"
|
|
32
|
+
/>
|
|
33
|
+
`,
|
|
34
|
+
}),
|
|
35
|
+
};
|
|
36
|
+
export default meta;
|
|
37
|
+
type Story = StoryObj<typeof MPasswordInput>;
|
|
38
|
+
|
|
39
|
+
export const WithValue: Story = {
|
|
40
|
+
args: {
|
|
41
|
+
id: 'withValueId',
|
|
42
|
+
modelValue: 'Magic-word-123',
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export const Default: Story = {};
|
|
47
|
+
|
|
48
|
+
export const Clearable: Story = {
|
|
49
|
+
args: {
|
|
50
|
+
id: 'clearableId',
|
|
51
|
+
modelValue: 'Magic-word-123',
|
|
52
|
+
isClearable: true,
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export const Disabled: Story = {
|
|
57
|
+
args: {
|
|
58
|
+
id: 'disableId',
|
|
59
|
+
disabled: true,
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export const ReadOnly: Story = {
|
|
64
|
+
args: {
|
|
65
|
+
id: 'readonlyId',
|
|
66
|
+
readonly: true,
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export const Invalid: Story = {
|
|
71
|
+
args: {
|
|
72
|
+
id: 'invalidId',
|
|
73
|
+
isInvalid: true,
|
|
74
|
+
},
|
|
75
|
+
};
|