@mozaic-ds/vue 1.0.0-rc.2 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +51 -0
- package/README.md +76 -77
- package/dist/mozaic-vue.css +1 -1
- package/dist/mozaic-vue.d.ts +1664 -0
- package/dist/mozaic-vue.js +1943 -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 +78 -51
- package/src/components/Contributing.mdx +118 -0
- package/src/components/GettingStarted.mdx +45 -0
- package/src/components/Introduction.mdx +100 -0
- package/src/components/Support.mdx +18 -0
- package/src/components/breadcrumb/MBreadcrumb.spec.ts +105 -0
- package/src/components/breadcrumb/MBreadcrumb.stories.ts +82 -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 +59 -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/datepicker/MDatepicker.spec.ts +95 -0
- package/src/components/datepicker/MDatepicker.stories.ts +75 -0
- package/src/components/datepicker/MDatepicker.vue +114 -0
- package/src/components/divider/MDivider.spec.ts +57 -0
- package/src/components/divider/MDivider.stories.ts +64 -0
- package/src/components/divider/MDivider.vue +56 -0
- package/src/components/drawer/MDrawer.spec.ts +100 -0
- package/src/components/drawer/MDrawer.stories.ts +128 -0
- package/src/components/drawer/MDrawer.vue +140 -0
- package/src/components/field/MField.spec.ts +166 -0
- package/src/components/field/MField.stories.ts +369 -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 +416 -0
- package/src/components/fieldgroup/MFieldGroup.vue +79 -0
- package/src/components/flag/MFlag.spec.ts +46 -0
- package/src/components/flag/MFlag.stories.ts +46 -0
- package/src/components/flag/MFlag.vue +28 -39
- package/src/components/iconbutton/MIconButton.spec.ts +108 -0
- package/src/components/iconbutton/MIconButton.stories.ts +74 -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 +89 -0
- package/src/components/link/MLink.vue +86 -120
- package/src/components/loader/MLoader.spec.ts +104 -0
- package/src/components/loader/MLoader.stories.ts +43 -0
- package/src/components/loader/MLoader.vue +66 -55
- package/src/components/loadingoverlay/MLoadingOverlay.spec.ts +37 -0
- package/src/components/loadingoverlay/MLoadingOverlay.stories.ts +40 -0
- package/src/components/loadingoverlay/MLoadingOverlay.vue +28 -0
- package/src/components/modal/MModal.spec.ts +103 -0
- package/src/components/modal/MModal.stories.ts +127 -0
- package/src/components/modal/MModal.vue +106 -154
- package/src/components/numberbadge/MNumberBadge.spec.ts +56 -0
- package/src/components/numberbadge/MNumberBadge.stories.ts +48 -0
- package/src/components/numberbadge/MNumberBadge.vue +45 -0
- package/src/components/overlay/MOverlay.spec.ts +51 -0
- package/src/components/overlay/MOverlay.stories.ts +35 -0
- package/src/components/overlay/MOverlay.vue +27 -19
- package/src/components/pagination/MPagination.spec.ts +123 -0
- package/src/components/pagination/MPagination.stories.ts +83 -0
- package/src/components/pagination/MPagination.vue +120 -140
- package/src/components/passwordinput/MPasswordInput.spec.ts +104 -0
- package/src/components/passwordinput/MPasswordInput.stories.ts +75 -0
- package/src/components/passwordinput/MPasswordInput.vue +126 -77
- package/src/components/pincode/MPincode.spec.ts +126 -0
- package/src/components/pincode/MPincode.stories.ts +68 -0
- package/src/components/pincode/MPincode.vue +148 -0
- package/src/components/quantityselector/MQuantitySelector.spec.ts +262 -0
- package/src/components/quantityselector/MQuantitySelector.stories.ts +89 -0
- package/src/components/quantityselector/MQuantitySelector.vue +159 -148
- 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 +103 -0
- package/src/components/statusnotification/MStatusNotification.stories.ts +89 -0
- package/src/components/statusnotification/MStatusNotification.vue +106 -0
- package/src/components/tabs/MTabs.stories.ts +104 -0
- package/src/components/tabs/MTabs.vue +113 -0
- package/src/components/tabs/Mtabs.spec.ts +149 -0
- package/src/components/tag/MTag.spec.ts +107 -0
- package/src/components/tag/MTag.stories.ts +75 -0
- package/src/components/tag/MTag.vue +151 -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 -43
- package/src/components/textinput/MTextInput.spec.ts +121 -0
- package/src/components/textinput/MTextInput.stories.ts +107 -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 +35 -0
- package/src/components/usingPresets.mdx +128 -0
- package/src/main.ts +32 -0
- package/dist/demo.html +0 -1
- package/dist/mozaic-vue.adeo.css +0 -47
- package/dist/mozaic-vue.adeo.umd.js +0 -31109
- package/dist/mozaic-vue.common.js +0 -31099
- package/dist/mozaic-vue.common.js.map +0 -1
- package/dist/mozaic-vue.umd.js +0 -31110
- 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 -381
- package/src/components/autocomplete/index.js +0 -7
- package/src/components/badge/MBadge.vue +0 -43
- 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 -163
- 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/dropdown/MDropdown.vue +0 -317
- package/src/components/dropdown/index.js +0 -7
- 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/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 -136
- package/src/components/icon/index.js +0 -7
- package/src/components/index.js +0 -44
- 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 -146
- package/src/components/listbox/MListBoxActions.vue +0 -251
- package/src/components/listbox/index.js +0 -12
- package/src/components/loader/index.js +0 -7
- 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/index.js +0 -7
- package/src/components/passwordinput/index.js +0 -7
- package/src/components/phonenumber/MPhoneNumber.vue +0 -398
- 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 -119
- 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 -111
- package/src/components/stepper/index.js +0 -7
- package/src/components/tabs/MTab.vue +0 -198
- 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 -63
- package/src/shims-tsx.d.ts +0 -13
- package/src/shims.vue.d.ts +0 -4
- package/src/tokens/adeo/android/colors.xml +0 -448
- package/src/tokens/adeo/android/font_dimens.xml +0 -18
- package/src/tokens/adeo/css/_variables.scss +0 -442
- package/src/tokens/adeo/css/root.scss +0 -444
- package/src/tokens/adeo/ios/StyleDictionaryColor.h +0 -456
- package/src/tokens/adeo/ios/StyleDictionaryColor.m +0 -468
- package/src/tokens/adeo/ios/StyleDictionaryColor.swift +0 -451
- 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 -540
- package/src/tokens/adeo/js/tokensObject.js +0 -11641
- package/src/tokens/adeo/scss/_tokens.scss +0 -1514
- package/src/utils/mozaicClasses.js +0 -16
- package/src/utils/theme.validator.js +0 -19
- package/types/index.d.ts +0 -104
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils';
|
|
2
|
+
import { describe, it, expect } from 'vitest';
|
|
3
|
+
import MStatusDot from './MStatusDot.vue';
|
|
4
|
+
|
|
5
|
+
describe('MStatusDot.vue', () => {
|
|
6
|
+
it('renders with default status and size', () => {
|
|
7
|
+
const wrapper = mount(MStatusDot);
|
|
8
|
+
|
|
9
|
+
expect(wrapper.classes()).toContain('mc-status-dot');
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('renders with custom status', () => {
|
|
13
|
+
const wrapper = mount(MStatusDot, {
|
|
14
|
+
props: {
|
|
15
|
+
status: 'success',
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
expect(wrapper.classes()).toContain('mc-status-dot--success');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('renders with custom size', () => {
|
|
23
|
+
const wrapper = mount(MStatusDot, {
|
|
24
|
+
props: {
|
|
25
|
+
size: 's',
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
expect(wrapper.classes()).toContain('mc-status-dot--s');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('does not render the "info" status when a custom one is passed', () => {
|
|
33
|
+
const wrapper = mount(MStatusDot, {
|
|
34
|
+
props: {
|
|
35
|
+
status: 'warning',
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
expect(wrapper.classes()).not.toContain('mc-status-dot--info');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('does not render the "m" size when a custom one is passed', () => {
|
|
43
|
+
const wrapper = mount(MStatusDot, {
|
|
44
|
+
props: {
|
|
45
|
+
size: 'l',
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
expect(wrapper.classes()).not.toContain('mc-status-dot--m');
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3-vite';
|
|
2
|
+
import MStatusDot from './MStatusDot.vue';
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof MStatusDot> = {
|
|
5
|
+
title: 'Status/Status Dot',
|
|
6
|
+
component: MStatusDot,
|
|
7
|
+
parameters: {
|
|
8
|
+
docs: {
|
|
9
|
+
description: {
|
|
10
|
+
component:
|
|
11
|
+
'A Status dot is a small visual indicator used to represent the state or condition of an element. It is often color-coded to convey different statuses at a glance, such as availability, activity, or urgency. Status Dots are commonly found in user presence indicators, system statuses, or process tracking to provide quick, unobtrusive feedback.',
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
render: (args) => ({
|
|
16
|
+
components: { MStatusDot },
|
|
17
|
+
setup() {
|
|
18
|
+
return { args };
|
|
19
|
+
},
|
|
20
|
+
template: `
|
|
21
|
+
<MStatusDot v-bind="args"></MStatusDot>
|
|
22
|
+
`,
|
|
23
|
+
}),
|
|
24
|
+
};
|
|
25
|
+
export default meta;
|
|
26
|
+
type Story = StoryObj<typeof MStatusDot>;
|
|
27
|
+
|
|
28
|
+
export const Info: Story = {};
|
|
29
|
+
|
|
30
|
+
export const Success: Story = {
|
|
31
|
+
args: { status: 'success' },
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const Warning: Story = {
|
|
35
|
+
args: { status: 'warning' },
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const Error: Story = {
|
|
39
|
+
args: { status: 'error' },
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const Neutral: Story = {
|
|
43
|
+
args: { status: 'neutral' },
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export const Size: Story = {
|
|
47
|
+
args: { size: 'l' },
|
|
48
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<span class="mc-status-dot" :class="classObject"></span>
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script setup lang="ts">
|
|
6
|
+
import { computed } from 'vue';
|
|
7
|
+
/**
|
|
8
|
+
* A badge indicates the status of an entity and can evolve at any time.
|
|
9
|
+
*/
|
|
10
|
+
const props = withDefaults(
|
|
11
|
+
defineProps<{
|
|
12
|
+
/**
|
|
13
|
+
* Allows to define the Status Dot style
|
|
14
|
+
*/
|
|
15
|
+
status?: 'info' | 'success' | 'warning' | 'error' | 'neutral';
|
|
16
|
+
/**
|
|
17
|
+
* Determines the size of the Status Dot.
|
|
18
|
+
*/
|
|
19
|
+
size?: 's' | 'm' | 'l';
|
|
20
|
+
}>(),
|
|
21
|
+
{
|
|
22
|
+
status: 'info',
|
|
23
|
+
},
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
const classObject = computed(() => {
|
|
27
|
+
return {
|
|
28
|
+
[`mc-status-dot--${props.status}`]: props.status && props.status != 'info',
|
|
29
|
+
[`mc-status-dot--${props.size}`]: props.size && props.size != 'm',
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<style lang="scss" scoped>
|
|
35
|
+
@use '@mozaic-ds/styles/components/status-dot';
|
|
36
|
+
</style>
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils';
|
|
2
|
+
import { describe, it, expect } from 'vitest';
|
|
3
|
+
import MStatusNotification from './MStatusNotification.vue';
|
|
4
|
+
import InfoCircleFilled32 from '@mozaic-ds/icons-vue/src/components/InfoCircleFilled32/InfoCircleFilled32.vue';
|
|
5
|
+
import WarningCircleFilled32 from '@mozaic-ds/icons-vue/src/components/WarningCircleFilled32/WarningCircleFilled32.vue';
|
|
6
|
+
import CrossCircleFilled32 from '@mozaic-ds/icons-vue/src/components/CrossCircleFilled32/CrossCircleFilled32.vue';
|
|
7
|
+
import CheckCircleFilled32 from '@mozaic-ds/icons-vue/src/components/CheckCircleFilled32/CheckCircleFilled32.vue';
|
|
8
|
+
|
|
9
|
+
describe('MStatusNotification.vue', () => {
|
|
10
|
+
it('should render correctly with the default props', () => {
|
|
11
|
+
const wrapper = mount(MStatusNotification, {
|
|
12
|
+
props: {
|
|
13
|
+
title: 'Test Title',
|
|
14
|
+
description: 'Test Description',
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
expect(wrapper.text()).toContain('Test Title');
|
|
19
|
+
expect(wrapper.text()).toContain('Test Description');
|
|
20
|
+
expect(wrapper.findComponent(InfoCircleFilled32).exists()).toBe(true); // Default icon is InfoCircle32
|
|
21
|
+
expect(wrapper.classes()).toContain('mc-status-notification');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should display the correct icon based on the status prop', () => {
|
|
25
|
+
const wrapperSuccess = mount(MStatusNotification, {
|
|
26
|
+
props: {
|
|
27
|
+
title: 'Success',
|
|
28
|
+
description: 'Success Description',
|
|
29
|
+
status: 'success',
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
expect(wrapperSuccess.findComponent(CheckCircleFilled32).exists()).toBe(
|
|
33
|
+
true,
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
const wrapperWarning = mount(MStatusNotification, {
|
|
37
|
+
props: {
|
|
38
|
+
title: 'Warning',
|
|
39
|
+
description: 'Warning Description',
|
|
40
|
+
status: 'warning',
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
expect(wrapperWarning.findComponent(WarningCircleFilled32).exists()).toBe(
|
|
44
|
+
true,
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
const wrapperError = mount(MStatusNotification, {
|
|
48
|
+
props: {
|
|
49
|
+
title: 'Error',
|
|
50
|
+
description: 'Error Description',
|
|
51
|
+
status: 'error',
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
expect(wrapperError.findComponent(CrossCircleFilled32).exists()).toBe(true);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('should show the close button if closable prop is true', () => {
|
|
58
|
+
const wrapper = mount(MStatusNotification, {
|
|
59
|
+
props: {
|
|
60
|
+
title: 'Closable Test',
|
|
61
|
+
description: 'Test Description',
|
|
62
|
+
closable: true,
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
expect(
|
|
67
|
+
wrapper.find('button.mc-status-notification-closable__close').exists(),
|
|
68
|
+
).toBe(true);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('should emit a close event when the close button is clicked', async () => {
|
|
72
|
+
const wrapper = mount(MStatusNotification, {
|
|
73
|
+
props: {
|
|
74
|
+
title: 'Closable Test',
|
|
75
|
+
description: 'Test Description',
|
|
76
|
+
closable: true,
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
const closeButton = wrapper.find(
|
|
81
|
+
'button.mc-status-notification-closable__close',
|
|
82
|
+
);
|
|
83
|
+
await closeButton.trigger('click');
|
|
84
|
+
|
|
85
|
+
// Check if the "close" event was emitted
|
|
86
|
+
expect(wrapper.emitted()).toHaveProperty('close');
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('should render footer slot if provided', () => {
|
|
90
|
+
const footerSlotContent = '<button>Footer Button</button>';
|
|
91
|
+
const wrapper = mount(MStatusNotification, {
|
|
92
|
+
props: {
|
|
93
|
+
title: 'With Footer',
|
|
94
|
+
description: 'Description with footer',
|
|
95
|
+
},
|
|
96
|
+
slots: {
|
|
97
|
+
footer: footerSlotContent,
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
expect(wrapper.html()).toContain(footerSlotContent);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3-vite';
|
|
2
|
+
import MStatusNotification from './MStatusNotification.vue';
|
|
3
|
+
import { action } from 'storybook/actions';
|
|
4
|
+
import MButton from '../button/MButton.vue';
|
|
5
|
+
import MLink from '../link/MLink.vue';
|
|
6
|
+
import ArrowNext20 from '@mozaic-ds/icons-vue/src/components/ArrowNext20/ArrowNext20.vue';
|
|
7
|
+
|
|
8
|
+
const meta: Meta<typeof MStatusNotification> = {
|
|
9
|
+
title: 'Status/Status Notification',
|
|
10
|
+
component: MStatusNotification,
|
|
11
|
+
parameters: {
|
|
12
|
+
docs: {
|
|
13
|
+
description: {
|
|
14
|
+
component:
|
|
15
|
+
'A Status Notification is used to draw the user’s attention to important information that needs to be acknowledged. It often provides feedback on a process, highlights a status update, or alerts users about an issue. Notifications are typically triggered by user actions or system events and are designed to be easily noticeable while maintaining a non-intrusive experience.',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
args: {
|
|
20
|
+
title:
|
|
21
|
+
'This is a title, be concise and use the description message to give details.',
|
|
22
|
+
description: 'Description message.',
|
|
23
|
+
},
|
|
24
|
+
render: (args) => ({
|
|
25
|
+
components: { MStatusNotification, MButton, MLink, ArrowNext20 },
|
|
26
|
+
setup() {
|
|
27
|
+
const handleClick = action('close');
|
|
28
|
+
|
|
29
|
+
return { args, handleClick };
|
|
30
|
+
},
|
|
31
|
+
template: `
|
|
32
|
+
<MStatusNotification
|
|
33
|
+
v-bind="args"
|
|
34
|
+
@click="handleClick"
|
|
35
|
+
>
|
|
36
|
+
<template v-if="${'footer' in args}" v-slot:footer>${args.footer}</template>
|
|
37
|
+
</MStatusNotification>
|
|
38
|
+
`,
|
|
39
|
+
}),
|
|
40
|
+
};
|
|
41
|
+
export default meta;
|
|
42
|
+
type Story = StoryObj<typeof MStatusNotification>;
|
|
43
|
+
|
|
44
|
+
export const Info: Story = {};
|
|
45
|
+
|
|
46
|
+
export const Success: Story = {
|
|
47
|
+
args: { status: 'success' },
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export const Warning: Story = {
|
|
51
|
+
args: { status: 'warning' },
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const Error: Story = {
|
|
55
|
+
args: { status: 'error' },
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const Closable: Story = {
|
|
59
|
+
args: { closable: true },
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export const WithButton = {
|
|
63
|
+
args: {
|
|
64
|
+
footer: `
|
|
65
|
+
<MButton outlined>Button Label</MButton>
|
|
66
|
+
`,
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export const WithLink = {
|
|
71
|
+
args: {
|
|
72
|
+
footer: `
|
|
73
|
+
<MLink href="#" iconPosition="right">
|
|
74
|
+
Stand-alone link
|
|
75
|
+
|
|
76
|
+
<template #icon><ArrowNext20 /></template>
|
|
77
|
+
</MLink>
|
|
78
|
+
`,
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export const WithButtons = {
|
|
83
|
+
args: {
|
|
84
|
+
footer: `
|
|
85
|
+
<MButton>Button Label</MButton>
|
|
86
|
+
<MButton outlined>Button Label</MButton>
|
|
87
|
+
`,
|
|
88
|
+
},
|
|
89
|
+
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<section class="mc-status-notification" role="status" :class="classObject">
|
|
3
|
+
<component
|
|
4
|
+
:is="iconComponent"
|
|
5
|
+
class="mc-status-notification__icon"
|
|
6
|
+
aria-hidden="true"
|
|
7
|
+
/>
|
|
8
|
+
<div class="mc-status-notification__content">
|
|
9
|
+
<h2 class="mc-status-notification__title">{{ title }}</h2>
|
|
10
|
+
|
|
11
|
+
<p class="mc-status-notification__message">
|
|
12
|
+
{{ description }}
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
<div v-if="$slots.footer" class="mc-status-notification__footer">
|
|
16
|
+
<slot name="footer" />
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<button
|
|
21
|
+
v-if="closable"
|
|
22
|
+
class="mc-status-notification-closable__close"
|
|
23
|
+
@click="emit('close')"
|
|
24
|
+
>
|
|
25
|
+
<Cross20
|
|
26
|
+
class="mc-status-notification-closable__icon"
|
|
27
|
+
aria-hidden="true"
|
|
28
|
+
/>
|
|
29
|
+
<span class="mc-status-notification-closable__text">Close</span>
|
|
30
|
+
</button>
|
|
31
|
+
</section>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<script setup lang="ts">
|
|
35
|
+
import { computed, type VNode } from 'vue';
|
|
36
|
+
import Cross20 from '@mozaic-ds/icons-vue/src/components/Cross20/Cross20.vue';
|
|
37
|
+
import InfoCircleFilled32 from '@mozaic-ds/icons-vue/src/components/InfoCircleFilled32/InfoCircleFilled32.vue';
|
|
38
|
+
import WarningCircleFilled32 from '@mozaic-ds/icons-vue/src/components/WarningCircleFilled32/WarningCircleFilled32.vue';
|
|
39
|
+
import CrossCircleFilled32 from '@mozaic-ds/icons-vue/src/components/CrossCircleFilled32/CrossCircleFilled32.vue';
|
|
40
|
+
import CheckCircleFilled32 from '@mozaic-ds/icons-vue/src/components/CheckCircleFilled32/CheckCircleFilled32.vue';
|
|
41
|
+
/**
|
|
42
|
+
* A Status Notification is used to draw the user’s attention to important information that needs to be acknowledged. It often provides feedback on a process, highlights a status update, or alerts users about an issue. Notifications are typically triggered by user actions or system events and are designed to be easily noticeable while maintaining a non-intrusive experience.
|
|
43
|
+
*/
|
|
44
|
+
const props = withDefaults(
|
|
45
|
+
defineProps<{
|
|
46
|
+
/**
|
|
47
|
+
* Title of the Status Notification
|
|
48
|
+
*/
|
|
49
|
+
title: string;
|
|
50
|
+
/**
|
|
51
|
+
* Description of the Status Notification
|
|
52
|
+
*/
|
|
53
|
+
description: string;
|
|
54
|
+
/**
|
|
55
|
+
* Allows to define the Status Notification style
|
|
56
|
+
*/
|
|
57
|
+
status?: 'info' | 'success' | 'warning' | 'error';
|
|
58
|
+
/**
|
|
59
|
+
* if `true`, display the close button.
|
|
60
|
+
*/
|
|
61
|
+
closable?: boolean;
|
|
62
|
+
}>(),
|
|
63
|
+
{
|
|
64
|
+
status: 'info',
|
|
65
|
+
},
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
defineSlots<{
|
|
69
|
+
/**
|
|
70
|
+
* Use this slot to insert a button or a link in the footer
|
|
71
|
+
*/
|
|
72
|
+
footer?: VNode;
|
|
73
|
+
}>();
|
|
74
|
+
|
|
75
|
+
const classObject = computed(() => {
|
|
76
|
+
return {
|
|
77
|
+
[`mc-status-notification--${props.status}`]:
|
|
78
|
+
props.status && props.status != 'info',
|
|
79
|
+
};
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
const iconComponent = computed(() => {
|
|
83
|
+
switch (props.status) {
|
|
84
|
+
case 'success':
|
|
85
|
+
return CheckCircleFilled32;
|
|
86
|
+
case 'warning':
|
|
87
|
+
return WarningCircleFilled32;
|
|
88
|
+
case 'error':
|
|
89
|
+
return CrossCircleFilled32;
|
|
90
|
+
case 'info':
|
|
91
|
+
default:
|
|
92
|
+
return InfoCircleFilled32;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const emit = defineEmits<{
|
|
97
|
+
/**
|
|
98
|
+
* Emits when closing the notification.
|
|
99
|
+
*/
|
|
100
|
+
(on: 'close'): void;
|
|
101
|
+
}>();
|
|
102
|
+
</script>
|
|
103
|
+
|
|
104
|
+
<style lang="scss" scoped>
|
|
105
|
+
@use '@mozaic-ds/styles/components/status-notification';
|
|
106
|
+
</style>
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3-vite';
|
|
2
|
+
import { action } from 'storybook/actions';
|
|
3
|
+
|
|
4
|
+
import Mtabs from './MTabs.vue';
|
|
5
|
+
import ChevronRight24 from '@mozaic-ds/icons-vue/src/components/ChevronRight24/ChevronRight24.vue';
|
|
6
|
+
|
|
7
|
+
const meta: Meta<typeof Mtabs> = {
|
|
8
|
+
title: 'Navigation/Tabs',
|
|
9
|
+
component: Mtabs,
|
|
10
|
+
parameters: {
|
|
11
|
+
docs: {
|
|
12
|
+
description: {
|
|
13
|
+
component:
|
|
14
|
+
'Tabs are a navigation component that allows users to switch between different sections within the same context. They help organize content efficiently by displaying only one section at a time, reducing clutter and improving accessibility. Tabs can include icons, labels, and notification badges to provide additional context. They are commonly used in dashboards, product management, and settings interfaces.',
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
args: {
|
|
19
|
+
tabs: [
|
|
20
|
+
{
|
|
21
|
+
label: 'Label',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
label: 'Label',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
label: 'Label',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
label: 'Label',
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
render: (args) => ({
|
|
35
|
+
components: { Mtabs, ChevronRight24 },
|
|
36
|
+
setup() {
|
|
37
|
+
const handleUpdate = action('update:modelValue');
|
|
38
|
+
|
|
39
|
+
return { args, handleUpdate };
|
|
40
|
+
},
|
|
41
|
+
template: `
|
|
42
|
+
<Mtabs
|
|
43
|
+
v-bind="args"
|
|
44
|
+
@update:modelValue="handleUpdate"
|
|
45
|
+
></Mtabs>
|
|
46
|
+
`,
|
|
47
|
+
}),
|
|
48
|
+
};
|
|
49
|
+
export default meta;
|
|
50
|
+
type Story = StoryObj<typeof Mtabs>;
|
|
51
|
+
|
|
52
|
+
export const Default: Story = {};
|
|
53
|
+
|
|
54
|
+
export const Icons: Story = {
|
|
55
|
+
args: {
|
|
56
|
+
tabs: [
|
|
57
|
+
{
|
|
58
|
+
label: 'Label',
|
|
59
|
+
icon: ChevronRight24,
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
label: 'Label',
|
|
63
|
+
icon: ChevronRight24,
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
label: 'Label',
|
|
67
|
+
icon: ChevronRight24,
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
label: 'Label',
|
|
71
|
+
icon: ChevronRight24,
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export const Centered: Story = {
|
|
78
|
+
args: { centered: true },
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export const NoDivider: Story = {
|
|
82
|
+
args: { divider: false },
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const Disabled: Story = {
|
|
86
|
+
args: {
|
|
87
|
+
tabs: [
|
|
88
|
+
{
|
|
89
|
+
label: 'Label',
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
label: 'Label',
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
label: 'Label',
|
|
96
|
+
disabled: true,
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
label: 'Label',
|
|
100
|
+
disabled: true,
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
},
|
|
104
|
+
};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<nav class="mc-tabs" :class="classObject">
|
|
3
|
+
<ul role="tablist" class="mc-tabs__list" :aria-label="description">
|
|
4
|
+
<li
|
|
5
|
+
v-for="(tab, index) in tabs"
|
|
6
|
+
:key="`tab-${index}`"
|
|
7
|
+
role="presentation"
|
|
8
|
+
class="mc-tabs__item"
|
|
9
|
+
>
|
|
10
|
+
<button
|
|
11
|
+
ref="tab"
|
|
12
|
+
role="tab"
|
|
13
|
+
class="mc-tabs__tab"
|
|
14
|
+
:class="{
|
|
15
|
+
'mc-tabs__tab--selected': isTabSelected(index),
|
|
16
|
+
'mc-tabs__tab--disabled': tab.disabled,
|
|
17
|
+
}"
|
|
18
|
+
:aria-selected="isTabSelected(index)"
|
|
19
|
+
type="button"
|
|
20
|
+
@click="onClickTab(index)"
|
|
21
|
+
>
|
|
22
|
+
<span v-if="tab.icon" class="mc-tabs__icon">
|
|
23
|
+
<component :is="tab.icon" />
|
|
24
|
+
</span>
|
|
25
|
+
<div class="mc-tabs__label">
|
|
26
|
+
<span>{{ tab.label }}</span>
|
|
27
|
+
</div>
|
|
28
|
+
</button>
|
|
29
|
+
</li>
|
|
30
|
+
</ul>
|
|
31
|
+
<MDivider v-if="divider"></MDivider>
|
|
32
|
+
</nav>
|
|
33
|
+
</template>
|
|
34
|
+
|
|
35
|
+
<script setup lang="ts">
|
|
36
|
+
import { computed, ref, type Component } from 'vue';
|
|
37
|
+
import MDivider from '../divider/MDivider.vue';
|
|
38
|
+
/**
|
|
39
|
+
* Tabs are a navigation component that allows users to switch between different sections within the same context. They help organize content efficiently by displaying only one section at a time, reducing clutter and improving accessibility. Tabs can include icons, labels, and notification badges to provide additional context. They are commonly used in dashboards, product management, and settings interfaces.
|
|
40
|
+
*/
|
|
41
|
+
const props = withDefaults(
|
|
42
|
+
defineProps<{
|
|
43
|
+
/**
|
|
44
|
+
* A description indicating the purpose of the set of tabs. Useful for improving the accessibility of the component.
|
|
45
|
+
*/
|
|
46
|
+
description?: string;
|
|
47
|
+
/**
|
|
48
|
+
* If `true`, the divider will appear.
|
|
49
|
+
*/
|
|
50
|
+
divider?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* If `true`, the tabs of the component will be centered.
|
|
53
|
+
*/
|
|
54
|
+
centered?: boolean;
|
|
55
|
+
/**
|
|
56
|
+
* The selected tab index, bound via v-model.
|
|
57
|
+
*/
|
|
58
|
+
modelValue?: number;
|
|
59
|
+
/**
|
|
60
|
+
* An array of objects that allows you to provide all the data needed to generate the content for each tab.
|
|
61
|
+
*/
|
|
62
|
+
tabs: Array<{
|
|
63
|
+
/**
|
|
64
|
+
* The icon displayed for the tab from Mozaic-icon-vue.
|
|
65
|
+
*/
|
|
66
|
+
icon?: Component;
|
|
67
|
+
/**
|
|
68
|
+
* The label displayed for the tab.
|
|
69
|
+
*/
|
|
70
|
+
label: string;
|
|
71
|
+
/**
|
|
72
|
+
* If `true`, the tab will be disabled.
|
|
73
|
+
*/
|
|
74
|
+
disabled?: boolean;
|
|
75
|
+
}>;
|
|
76
|
+
}>(),
|
|
77
|
+
{
|
|
78
|
+
modelValue: 0,
|
|
79
|
+
divider: true,
|
|
80
|
+
},
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
const classObject = computed(() => {
|
|
84
|
+
return {
|
|
85
|
+
'mc-tabs--centered': props.centered,
|
|
86
|
+
};
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const modelValue = ref(props.modelValue);
|
|
90
|
+
|
|
91
|
+
const onClickTab = (index: number) => {
|
|
92
|
+
if (props.tabs[index].disabled) return;
|
|
93
|
+
if (index !== modelValue.value) {
|
|
94
|
+
modelValue.value = index;
|
|
95
|
+
emit('update:modelValue', index);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const isTabSelected = (index: number) => {
|
|
100
|
+
return modelValue.value === index;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const emit = defineEmits<{
|
|
104
|
+
/**
|
|
105
|
+
* Emits when the selected tab changes, updating the modelValue prop.
|
|
106
|
+
*/
|
|
107
|
+
(on: 'update:modelValue', value: number): void;
|
|
108
|
+
}>();
|
|
109
|
+
</script>
|
|
110
|
+
|
|
111
|
+
<style lang="scss" scoped>
|
|
112
|
+
@use '@mozaic-ds/styles/components/tabs';
|
|
113
|
+
</style>
|