@mozaic-ds/vue 2.16.0 → 2.18.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/dist/mozaic-vue.css +2 -1
- package/dist/mozaic-vue.d.ts +258 -137
- package/dist/mozaic-vue.js +14054 -10878
- package/dist/mozaic-vue.js.map +1 -1
- package/dist/mozaic-vue.umd.cjs +7 -25
- package/dist/mozaic-vue.umd.cjs.map +1 -1
- package/package.json +22 -11
- package/src/components/BrandPresets.mdx +2 -2
- package/src/components/Migration.mdx +651 -0
- package/src/components/accordionlist/MAccordionList.figma.ts +43 -0
- package/src/components/accordionlistitem/MAccordionListItem.figma.ts +27 -0
- package/src/components/accordionlistitem/MAccordionListItem.spec.ts +22 -3
- package/src/components/accordionlistitem/MAccordionListItem.vue +38 -28
- package/src/components/actionbottombar/MActionBottomBar.figma.ts +24 -0
- package/src/components/actionlistbox/MActionListbox.figma.ts +30 -0
- package/src/components/avatar/MAvatar.figma.ts +31 -0
- package/src/components/breadcrumb/MBreadcrumb.figma.ts +31 -0
- package/src/components/builtinmenu/MBuiltInMenu.figma.ts +23 -0
- package/src/components/builtinmenu/MBuiltInMenu.spec.ts +30 -1
- package/src/components/builtinmenu/MBuiltInMenu.vue +26 -17
- package/src/components/builtinmenu/README.md +2 -0
- package/src/components/button/MButton.figma.ts +41 -0
- package/src/components/callout/MCallout.figma.ts +29 -0
- package/src/components/callout/MCallout.spec.ts +35 -0
- package/src/components/callout/MCallout.vue +22 -4
- package/src/components/callout/README.md +2 -0
- package/src/components/carousel/MCarousel.figma.ts +32 -0
- package/src/components/checkbox/MCheckbox.figma.ts +45 -0
- package/src/components/checkboxgroup/MCheckboxGroup.figma.ts +30 -0
- package/src/components/checklistmenu/MCheckListMenu.figma.ts +29 -0
- package/src/components/checklistmenu/MCheckListMenu.spec.ts +12 -1
- package/src/components/checklistmenu/MCheckListMenu.vue +6 -0
- package/src/components/checklistmenu/README.md +2 -0
- package/src/components/circularprogressbar/MCircularProgressbar.figma.ts +31 -0
- package/src/components/combobox/MCombobox.figma.ts +48 -0
- package/src/components/combobox/MCombobox.spec.ts +1 -1
- package/src/components/combobox/MCombobox.vue +18 -9
- package/src/components/combobox/README.md +2 -2
- package/src/components/container/MContainer.figma.ts +30 -0
- package/src/components/datatable/DataTable.stories.ts +277 -0
- package/src/components/datatable/DataTableCells.stories.ts +251 -0
- package/src/components/datatable/DataTableEmpty.stories.ts +102 -0
- package/src/components/datatable/DataTableExpandable.stories.ts +95 -0
- package/src/components/datatable/DataTableNested.stories.ts +96 -0
- package/src/components/datatable/DataTableSelectable.stories.ts +124 -0
- package/src/components/datatable/DataTableSortable.stories.ts +164 -0
- package/src/components/datatable/MDataTable.types.ts +54 -0
- package/src/components/datatable/assets/styles.scss +10 -0
- package/src/components/datatable/datatable.mdx +63 -0
- package/src/components/datatable/tools/data.js +8 -0
- package/src/components/datatable/tools/data.json +2018 -0
- package/src/components/datatable/utils.js +19 -0
- package/src/components/datepicker/MDatepicker.figma.ts +20 -0
- package/src/components/divider/MDivider.figma.ts +30 -0
- package/src/components/drawer/MDrawer.figma.ts +37 -0
- package/src/components/drawer/README.md +1 -1
- package/src/components/field/MField.figma.ts +30 -0
- package/src/components/fileuploader/MFileUploader.figma.ts +23 -0
- package/src/components/fileuploaderitem/MFileUploaderItem.figma.ts +27 -0
- package/src/components/flag/MFlag.figma.ts +26 -0
- package/src/components/iconbutton/MIconButton.figma.ts +54 -0
- package/src/components/kpiitem/MKpiItem.figma.ts +33 -0
- package/src/components/linearprogressbarbuffer/MLinearProgressbarBuffer.figma.ts +31 -0
- package/src/components/linearprogressbarpercentage/MLinearProgressbarPercentage.figma.ts +26 -0
- package/src/components/link/MLink.figma.ts +32 -0
- package/src/components/loader/MLoader.figma.ts +30 -0
- package/src/components/loadingoverlay/MLoadingOverlay.figma.ts +18 -0
- package/src/components/modal/MModal.figma.ts +27 -0
- package/src/components/navigationindicator/MNavigationIndicator.figma.ts +24 -0
- package/src/components/navigationindicator/MNavigationIndicator.spec.ts +75 -18
- package/src/components/navigationindicator/MNavigationIndicator.vue +10 -12
- package/src/components/numberbadge/MNumberBadge.figma.ts +31 -0
- package/src/components/optionListbox/MOptionListbox.figma.ts +36 -0
- package/src/components/optionListbox/MOptionListbox.vue +34 -19
- package/src/components/optionListbox/README.md +1 -1
- package/src/components/overlay/MOverlay.figma.ts +20 -0
- package/src/components/pageheader/MPageHeader.figma.ts +21 -0
- package/src/components/pagination/MPagination.figma.ts +34 -0
- package/src/components/passwordinput/MPasswordInput.figma.ts +30 -0
- package/src/components/phonenumber/MPhoneNumber.figma.ts +47 -0
- package/src/components/pincode/MPincode.figma.ts +41 -0
- package/src/components/pincode/MPincode.spec.ts +1 -4
- package/src/components/pincode/MPincode.vue +11 -15
- package/src/components/popover/MPopover.figma.ts +42 -0
- package/src/components/popover/MPopover.spec.ts +126 -0
- package/src/components/popover/MPopover.vue +36 -1
- package/src/components/quantityselector/MQuantitySelector.figma.ts +50 -0
- package/src/components/radio/MRadio.figma.ts +40 -0
- package/src/components/radiogroup/MRadioGroup.figma.ts +30 -0
- package/src/components/segmentedcontrol/MSegmentedControl.figma.ts +33 -0
- package/src/components/segmentedcontrol/MSegmentedControl.spec.ts +92 -0
- package/src/components/segmentedcontrol/MSegmentedControl.vue +61 -2
- package/src/components/select/MSelect.figma.ts +49 -0
- package/src/components/sidebar/MSidebar.figma.ts +28 -0
- package/src/components/sidebarexpandableitem/MSidebarExpandableItem.figma.ts +19 -0
- package/src/components/sidebarfooter/MSidebarFooter.figma.ts +21 -0
- package/src/components/sidebarheader/MSidebarHeader.figma.ts +18 -0
- package/src/components/sidebarnavitem/MSidebarNavItem.figma.ts +23 -0
- package/src/components/sidebarshortcutitem/MSidebarShortcutItem.figma.ts +20 -0
- package/src/components/starrating/MStarRating.figma.ts +35 -0
- package/src/components/starrating/MStarRating.spec.ts +19 -22
- package/src/components/starrating/MStarRating.vue +3 -2
- package/src/components/statusbadge/MStatusBadge.figma.ts +27 -0
- package/src/components/statusdot/MStatusDot.figma.ts +31 -0
- package/src/components/statusmessage/MStatusMessage.figma.ts +28 -0
- package/src/components/statusmessage/MStatusMessage.spec.ts +15 -0
- package/src/components/statusmessage/MStatusMessage.stories.ts +4 -0
- package/src/components/statusmessage/MStatusMessage.vue +7 -0
- package/src/components/statusmessage/README.md +2 -0
- package/src/components/statusnotification/MStatusNotification.figma.ts +29 -0
- package/src/components/stepperbottombar/MStepperBottomBar.figma.ts +20 -0
- package/src/components/steppercompact/MStepperCompact.figma.ts +21 -0
- package/src/components/stepperinline/MStepperInline.figma.ts +23 -0
- package/src/components/stepperstacked/MStepperStacked.figma.ts +23 -0
- package/src/components/tabs/MTabs.figma.ts +33 -0
- package/src/components/tabs/MTabs.vue +90 -4
- package/src/components/tabs/Mtabs.spec.ts +162 -0
- package/src/components/tag/MTag.figma.ts +26 -0
- package/src/components/tag/MTag.stories.ts +13 -3
- package/src/components/tag/MTag.vue +11 -1
- package/src/components/tag/README.md +6 -0
- package/src/components/textarea/MTextArea.figma.ts +28 -0
- package/src/components/textinput/MTextInput.figma.ts +51 -0
- package/src/components/tile/MTile.figma.ts +31 -0
- package/src/components/tileclickable/MTileClickable.figma.ts +31 -0
- package/src/components/tileexpandable/MTileExpandable.figma.ts +31 -0
- package/src/components/tileselectable/MTileSelectable.figma.ts +29 -0
- package/src/components/toaster/MToaster.figma.ts +25 -0
- package/src/components/toggle/MToggle.figma.ts +39 -0
- package/src/components/togglegroup/MToggleGroup.figma.ts +30 -0
- package/src/components/tooltip/MTooltip.figma.ts +29 -0
- package/src/main.ts +1 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Connect mapping for MAccordionList
|
|
3
|
+
* Links Figma Accordion List to @mozaic-ds/vue
|
|
4
|
+
*/
|
|
5
|
+
import figma, { html } from '@figma/code-connect/html';
|
|
6
|
+
|
|
7
|
+
figma.connect(
|
|
8
|
+
'https://www.figma.com/design/Zyh9RyabNaqkjbuFWP9Aqj/%E2%9C%A8-Components--ADS2---Stable-version-?node-id=1647%3A16440',
|
|
9
|
+
{
|
|
10
|
+
props: {
|
|
11
|
+
appearance: figma.enum('Appareance', {
|
|
12
|
+
Standard: 'standard',
|
|
13
|
+
Ghost: 'ghost',
|
|
14
|
+
}),
|
|
15
|
+
showItem02: figma.boolean('Show Item 02'),
|
|
16
|
+
showItem03: figma.boolean('Show Item 03'),
|
|
17
|
+
showItem04: figma.boolean('Show Item 04'),
|
|
18
|
+
showItem05: figma.boolean('Show Item 05'),
|
|
19
|
+
showItem06: figma.boolean('Show Item 06'),
|
|
20
|
+
showItem07: figma.boolean('Show Item 07'),
|
|
21
|
+
showItem08: figma.boolean('Show Item 08'),
|
|
22
|
+
},
|
|
23
|
+
example: ({ appearance }) =>
|
|
24
|
+
html`<script setup>
|
|
25
|
+
import { MAccordionList, MAccordionListItem } from '@mozaic-ds/vue';
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<MAccordionList appearance=${appearance}>
|
|
29
|
+
<MAccordionListItem id="1" title="Content title">
|
|
30
|
+
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>
|
|
31
|
+
</MAccordionListItem>
|
|
32
|
+
<MAccordionListItem id="2" title="Content title">
|
|
33
|
+
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>
|
|
34
|
+
</MAccordionListItem>
|
|
35
|
+
<MAccordionListItem id="3" title="Content title">
|
|
36
|
+
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>
|
|
37
|
+
</MAccordionListItem>
|
|
38
|
+
<MAccordionListItem id="4" title="Content title">
|
|
39
|
+
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>
|
|
40
|
+
</MAccordionListItem>
|
|
41
|
+
</MAccordionList>`,
|
|
42
|
+
},
|
|
43
|
+
);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Connect mapping for MAccordionListItem
|
|
3
|
+
* Links Figma Accordion List Item to @mozaic-ds/vue
|
|
4
|
+
*/
|
|
5
|
+
import figma, { html } from '@figma/code-connect/html';
|
|
6
|
+
|
|
7
|
+
figma.connect(
|
|
8
|
+
'https://www.figma.com/design/Zyh9RyabNaqkjbuFWP9Aqj/branch/tOAc8mV1PF5g0tjBfSbUXA/%E2%9C%A8-Components--ADS2---Stable-version-?node-id=1647%3A16442',
|
|
9
|
+
{
|
|
10
|
+
props: {
|
|
11
|
+
title: figma.string('Title'),
|
|
12
|
+
subtitle: figma.boolean('Has subtitle', {
|
|
13
|
+
true: figma.string('Subtitle'),
|
|
14
|
+
false: undefined,
|
|
15
|
+
}),
|
|
16
|
+
},
|
|
17
|
+
example: ({ title, subtitle }) =>
|
|
18
|
+
html`<script setup>
|
|
19
|
+
import { MAccordionListItem } from '@mozaic-ds/vue';
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<MAccordionListItem id="accordion-1" title=${title} subtitle=${subtitle}>
|
|
23
|
+
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>
|
|
24
|
+
</MAccordionListItem>`,
|
|
25
|
+
imports: ["import { MAccordionListItem } from '@mozaic-ds/vue'"],
|
|
26
|
+
},
|
|
27
|
+
);
|
|
@@ -82,15 +82,34 @@ describe('MAccordionListItem', () => {
|
|
|
82
82
|
expect(button.attributes('aria-expanded')).toBe('true');
|
|
83
83
|
});
|
|
84
84
|
|
|
85
|
-
it('sets
|
|
85
|
+
it('sets inert correctly for content', async () => {
|
|
86
86
|
const { wrapper, state } = mountItem({ id: 'item-1', title: 'Title' }, []);
|
|
87
87
|
|
|
88
88
|
const content = wrapper.find('.mc-accordion__content');
|
|
89
|
-
expect(content.attributes('
|
|
89
|
+
expect(content.attributes('inert')).not.toBeUndefined();
|
|
90
90
|
|
|
91
91
|
state.value.push('item-1');
|
|
92
92
|
await wrapper.vm.$nextTick();
|
|
93
|
-
expect(content.attributes('
|
|
93
|
+
expect(content.attributes('inert')).toBeUndefined();
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('renders heading with default level h2', () => {
|
|
97
|
+
const { wrapper } = mountItem({ id: '1', title: 'Title' });
|
|
98
|
+
expect(wrapper.find('h2.mc-accordion__title').exists()).toBe(true);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('renders heading with custom headingLevel prop', () => {
|
|
102
|
+
const wrapper = mount(MAccordionListItem, {
|
|
103
|
+
props: { id: '1', title: 'Title', tag: 'h3' },
|
|
104
|
+
global: {
|
|
105
|
+
provide: {
|
|
106
|
+
[AccordionStateKey as symbol]: ref([]),
|
|
107
|
+
[AccordionToggleFnKey as symbol]: vi.fn(),
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
expect(wrapper.find('h3.mc-accordion__title').exists()).toBe(true);
|
|
112
|
+
expect(wrapper.find('h2').exists()).toBe(false);
|
|
94
113
|
});
|
|
95
114
|
|
|
96
115
|
it('calls toggleItem when button is clicked', async () => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="mc-accordion__item">
|
|
3
3
|
<div class="mc-accordion__header">
|
|
4
|
-
<
|
|
4
|
+
<component :is="tag" class="mc-accordion__title">
|
|
5
5
|
<button
|
|
6
6
|
:id="`accordion-${id}`"
|
|
7
7
|
class="mc-accordion__trigger"
|
|
@@ -19,12 +19,12 @@
|
|
|
19
19
|
</span>
|
|
20
20
|
</div>
|
|
21
21
|
</button>
|
|
22
|
-
</
|
|
22
|
+
</component>
|
|
23
23
|
</div>
|
|
24
24
|
<div
|
|
25
25
|
:id="`content-${id}`"
|
|
26
26
|
class="mc-accordion__content"
|
|
27
|
-
:
|
|
27
|
+
:inert="!open || undefined"
|
|
28
28
|
:aria-labelledby="`accordion-${id}`"
|
|
29
29
|
role="region"
|
|
30
30
|
>
|
|
@@ -49,31 +49,41 @@ import {
|
|
|
49
49
|
AccordionToggleFnKey,
|
|
50
50
|
} from '../accordionlist/m-accordion-list.const';
|
|
51
51
|
|
|
52
|
-
const props =
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
52
|
+
const props = withDefaults(
|
|
53
|
+
defineProps<{
|
|
54
|
+
/**
|
|
55
|
+
* A unique identifier for the accordion item.
|
|
56
|
+
* It links the trigger button (`aria-controls`) to its associated content (`aria-labelledby`),
|
|
57
|
+
* ensuring accessibility and tracking the open/closed state.
|
|
58
|
+
* If no ID is provided, a unique one is generated automatically.
|
|
59
|
+
*/
|
|
60
|
+
id: string;
|
|
61
|
+
/**
|
|
62
|
+
* The main heading of the accordion item. This is the primary text visible to users in the collapsed state and acts as the trigger for expanding or collapsing the content.
|
|
63
|
+
*/
|
|
64
|
+
title: string;
|
|
65
|
+
/**
|
|
66
|
+
* An optional secondary heading displayed below the title. It provides additional context or detail about the content of the accordion item.
|
|
67
|
+
*/
|
|
68
|
+
subtitle?: string;
|
|
69
|
+
/**
|
|
70
|
+
* The main content of the accordion item. This is the information revealed when the accordion is expanded, typically containing text, HTML, or other elements.
|
|
71
|
+
*/
|
|
72
|
+
content?: string;
|
|
73
|
+
/**
|
|
74
|
+
* Icon component to display before the item title.
|
|
75
|
+
*/
|
|
76
|
+
icon?: Component;
|
|
77
|
+
/**
|
|
78
|
+
* Heading level for the accordion trigger (h2–h6). Adjust to match the
|
|
79
|
+
* heading hierarchy of the page where the accordion is used.
|
|
80
|
+
*/
|
|
81
|
+
tag?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
|
82
|
+
}>(),
|
|
83
|
+
{
|
|
84
|
+
tag: 'h2',
|
|
85
|
+
},
|
|
86
|
+
);
|
|
77
87
|
|
|
78
88
|
defineSlots<{
|
|
79
89
|
/**
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Connect mapping for MActionBottomBar
|
|
3
|
+
* Links Figma Action bottom bar (ADS2) to @mozaic-ds/vue
|
|
4
|
+
*/
|
|
5
|
+
import figma, { html } from '@figma/code-connect/html';
|
|
6
|
+
|
|
7
|
+
figma.connect(
|
|
8
|
+
'https://www.figma.com/design/Zyh9RyabNaqkjbuFWP9Aqj/%E2%9C%A8-Components--ADS2---Stable-version-?node-id=10709-6937',
|
|
9
|
+
{
|
|
10
|
+
props: {
|
|
11
|
+
shadow: figma.boolean('Has shadow'),
|
|
12
|
+
},
|
|
13
|
+
example: ({ shadow }) =>
|
|
14
|
+
html`<script setup>
|
|
15
|
+
import { MActionBottomBar, MButton } from '@mozaic-ds/vue';
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<MActionBottomBar shadow=${shadow}>
|
|
19
|
+
<template #right>
|
|
20
|
+
<MButton size="s" appearance="accent">Save</MButton>
|
|
21
|
+
</template>
|
|
22
|
+
</MActionBottomBar>`,
|
|
23
|
+
},
|
|
24
|
+
);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Connect mapping for MActionListbox
|
|
3
|
+
* Links Figma Action listbox (ADS2) to @mozaic-ds/vue
|
|
4
|
+
*/
|
|
5
|
+
import figma, { html } from '@figma/code-connect/html';
|
|
6
|
+
|
|
7
|
+
figma.connect(
|
|
8
|
+
'https://www.figma.com/design/Zyh9RyabNaqkjbuFWP9Aqj/%E2%9C%A8-Components--ADS2---Stable-version-?node-id=6-29046',
|
|
9
|
+
{
|
|
10
|
+
props: {},
|
|
11
|
+
example: () =>
|
|
12
|
+
html`<script setup>
|
|
13
|
+
import { MActionListbox, MButton } from '@mozaic-ds/vue';
|
|
14
|
+
import { Copy20, Download20, Trash20 } from '@mozaic-ds/icons-vue';
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<MActionListbox
|
|
18
|
+
title="Listbox title"
|
|
19
|
+
:items="[
|
|
20
|
+
{ id: '1', label: 'Duplicate', icon: Copy20 },
|
|
21
|
+
{ id: '2', label: 'Download', icon: Download20 },
|
|
22
|
+
{ id: '3', label: 'Delete', icon: Trash20, appearance: 'danger', divider: true },
|
|
23
|
+
]"
|
|
24
|
+
>
|
|
25
|
+
<template #activator="{ id }">
|
|
26
|
+
<MButton :popovertarget="id">Open menu</MButton>
|
|
27
|
+
</template>
|
|
28
|
+
</MActionListbox>`,
|
|
29
|
+
},
|
|
30
|
+
);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Connect mapping for MAvatar
|
|
3
|
+
* Links Figma Avatar (ADS2) to @mozaic-ds/vue
|
|
4
|
+
*/
|
|
5
|
+
import figma, { html } from '@figma/code-connect/html';
|
|
6
|
+
|
|
7
|
+
figma.connect(
|
|
8
|
+
'https://www.figma.com/design/Zyh9RyabNaqkjbuFWP9Aqj/%E2%9C%A8-Components--ADS2---Stable-version-?node-id=5-6412',
|
|
9
|
+
{
|
|
10
|
+
props: {
|
|
11
|
+
size: figma.enum('Size', {
|
|
12
|
+
'S (32px)': 's',
|
|
13
|
+
'M (48px)': 'm',
|
|
14
|
+
'L (64px)': 'l',
|
|
15
|
+
}),
|
|
16
|
+
type: figma.enum('Type', {
|
|
17
|
+
Picture: 'picture',
|
|
18
|
+
Initials: 'initials',
|
|
19
|
+
Icon: 'icon',
|
|
20
|
+
}),
|
|
21
|
+
},
|
|
22
|
+
example: ({ size }) =>
|
|
23
|
+
html`<script setup>
|
|
24
|
+
import { MAvatar } from '@mozaic-ds/vue';
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<MAvatar size=${size}>
|
|
28
|
+
<img src="/placeholder.png" alt="Avatar" />
|
|
29
|
+
</MAvatar>`,
|
|
30
|
+
},
|
|
31
|
+
);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Connect mapping for MBreadcrumb
|
|
3
|
+
* Links Figma Breadcrumb (ADS2) to @mozaic-ds/vue
|
|
4
|
+
*/
|
|
5
|
+
import figma, { html } from '@figma/code-connect/html';
|
|
6
|
+
|
|
7
|
+
figma.connect(
|
|
8
|
+
'https://www.figma.com/design/Zyh9RyabNaqkjbuFWP9Aqj/%E2%9C%A8-Components--ADS2---Stable-version-?node-id=6-11237',
|
|
9
|
+
{
|
|
10
|
+
props: {
|
|
11
|
+
appearance: figma.enum('Appearance', {
|
|
12
|
+
Standard: 'standard',
|
|
13
|
+
'Inverse (only on dark background)': 'inverse',
|
|
14
|
+
}),
|
|
15
|
+
},
|
|
16
|
+
example: ({ appearance }) =>
|
|
17
|
+
html`<script setup>
|
|
18
|
+
import { MBreadcrumb } from '@mozaic-ds/vue';
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<MBreadcrumb
|
|
22
|
+
appearance=${appearance}
|
|
23
|
+
:links="[
|
|
24
|
+
{ label: 'Home', href: '#' },
|
|
25
|
+
{ label: 'Level 01', href: '#' },
|
|
26
|
+
{ label: 'Current Page', href: '#' },
|
|
27
|
+
]"
|
|
28
|
+
aria-label="breadcrumb"
|
|
29
|
+
></MBreadcrumb>`,
|
|
30
|
+
},
|
|
31
|
+
);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Connect mapping for MBuiltInMenu
|
|
3
|
+
* Links Figma Built-in menu (ADS2) to @mozaic-ds/vue
|
|
4
|
+
*/
|
|
5
|
+
import figma, { html } from '@figma/code-connect/html';
|
|
6
|
+
|
|
7
|
+
figma.connect(
|
|
8
|
+
'https://www.figma.com/design/Zyh9RyabNaqkjbuFWP9Aqj/%E2%9C%A8-Components--ADS2---Stable-version-?node-id=6-11260',
|
|
9
|
+
{
|
|
10
|
+
props: {
|
|
11
|
+
outlined: figma.enum('is outlined', {
|
|
12
|
+
'true': true,
|
|
13
|
+
'false': false,
|
|
14
|
+
}),
|
|
15
|
+
},
|
|
16
|
+
example: ({ outlined }) =>
|
|
17
|
+
html`<script setup>
|
|
18
|
+
import { MBuiltInMenu } from '@mozaic-ds/vue';
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<MBuiltInMenu :items="[{ label: 'Label' }, { label: 'Label' }]" outlined=${outlined} />`,
|
|
22
|
+
},
|
|
23
|
+
);
|
|
@@ -86,7 +86,9 @@ describe('MBuiltInMenu', () => {
|
|
|
86
86
|
});
|
|
87
87
|
const lis = wrapper.findAll('li');
|
|
88
88
|
const selectedItem = lis[2];
|
|
89
|
-
|
|
89
|
+
// aria-current is on the interactive element, not the <li> container
|
|
90
|
+
const interactiveEl = selectedItem.find('button, a');
|
|
91
|
+
expect(interactiveEl.attributes('aria-current')).toBe('true');
|
|
90
92
|
expect(selectedItem.classes()).toContain(
|
|
91
93
|
'mc-built-in-menu__item--selected',
|
|
92
94
|
);
|
|
@@ -108,4 +110,31 @@ describe('MBuiltInMenu', () => {
|
|
|
108
110
|
'mc-built-in-menu--outlined',
|
|
109
111
|
);
|
|
110
112
|
});
|
|
113
|
+
|
|
114
|
+
it('uses default aria-label "Menu" on nav when label prop is not provided', () => {
|
|
115
|
+
const wrapper = mount(MBuiltInMenu, { props: { items } });
|
|
116
|
+
expect(wrapper.find('nav').attributes('aria-label')).toBe('Menu');
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it('uses custom label prop as aria-label on nav', () => {
|
|
120
|
+
const wrapper = mount(MBuiltInMenu, {
|
|
121
|
+
props: { items, label: 'Settings navigation' },
|
|
122
|
+
});
|
|
123
|
+
expect(wrapper.find('nav').attributes('aria-label')).toBe('Settings navigation');
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('sets aria-hidden on ChevronRight and item icons', () => {
|
|
127
|
+
const wrapper = mount(MBuiltInMenu, { props: { items } });
|
|
128
|
+
// All SVG icons inside items should be aria-hidden
|
|
129
|
+
const ariaHiddenIcons = wrapper.findAll('[aria-hidden="true"]');
|
|
130
|
+
expect(ariaHiddenIcons.length).toBeGreaterThan(0);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it('does not put aria-current on the <li>, only on the interactive element', () => {
|
|
134
|
+
const wrapper = mount(MBuiltInMenu, { props: { items, modelValue: 0 } });
|
|
135
|
+
const li = wrapper.findAll('li')[0];
|
|
136
|
+
expect(li.attributes('aria-current')).toBeUndefined();
|
|
137
|
+
const interactive = li.find('button, a');
|
|
138
|
+
expect(interactive.attributes('aria-current')).toBe('true');
|
|
139
|
+
});
|
|
111
140
|
});
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
'mc-built-in-menu': true,
|
|
5
5
|
'mc-built-in-menu--outlined': props.outlined,
|
|
6
6
|
}"
|
|
7
|
-
aria-label="
|
|
7
|
+
:aria-label="props.label"
|
|
8
8
|
>
|
|
9
9
|
<ul class="mc-built-in-menu__list">
|
|
10
10
|
<li
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
'mc-built-in-menu__item': true,
|
|
15
15
|
'mc-built-in-menu__item--selected': currentMenuItem === index,
|
|
16
16
|
}"
|
|
17
|
-
v-bind="currentMenuItem === index ? { 'aria-current': true } : {}"
|
|
18
17
|
>
|
|
19
18
|
<component
|
|
20
19
|
:is="getItemTag(item)"
|
|
@@ -23,17 +22,19 @@
|
|
|
23
22
|
'mc-built-in-menu__link': isLink(item),
|
|
24
23
|
}"
|
|
25
24
|
v-bind="isLink(item) ? getLinkAttrs(item) : {}"
|
|
25
|
+
:aria-current="currentMenuItem === index ? true : undefined"
|
|
26
26
|
@click="currentMenuItem = index"
|
|
27
27
|
>
|
|
28
28
|
<component
|
|
29
29
|
v-if="item.icon"
|
|
30
30
|
:is="item.icon"
|
|
31
31
|
class="mc-built-in-menu__icon"
|
|
32
|
+
aria-hidden="true"
|
|
32
33
|
/>
|
|
33
34
|
|
|
34
35
|
<span class="mc-built-in-menu__label">{{ item.label }}</span>
|
|
35
36
|
|
|
36
|
-
<ChevronRight20 class="mc-built-in-menu__icon" />
|
|
37
|
+
<ChevronRight20 class="mc-built-in-menu__icon" aria-hidden="true" />
|
|
37
38
|
</component>
|
|
38
39
|
</li>
|
|
39
40
|
</ul>
|
|
@@ -56,20 +57,28 @@ export type MenuItem = {
|
|
|
56
57
|
target?: '_self' | '_blank' | '_parent' | '_top';
|
|
57
58
|
};
|
|
58
59
|
|
|
59
|
-
const props =
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
60
|
+
const props = withDefaults(
|
|
61
|
+
defineProps<{
|
|
62
|
+
/**
|
|
63
|
+
* Specifies the key of the currently selected menu item. It allows the component to highlight or style the corresponding item to indicate it is selected or currently in use.
|
|
64
|
+
*/
|
|
65
|
+
modelValue?: number;
|
|
66
|
+
/**
|
|
67
|
+
* Defines the menu items, each of which can include an icon and act as a button, link, or router-link.
|
|
68
|
+
*/
|
|
69
|
+
items: MenuItem[];
|
|
70
|
+
/**
|
|
71
|
+
* When enabled, adds a visible border around the wrapper to highlight or separate its content.
|
|
72
|
+
*/
|
|
73
|
+
outlined?: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Accessible label for the navigation landmark. Should describe the purpose
|
|
76
|
+
* of this menu to distinguish it from other navigations on the page.
|
|
77
|
+
*/
|
|
78
|
+
label?: string;
|
|
79
|
+
}>(),
|
|
80
|
+
{ label: 'Menu' },
|
|
81
|
+
);
|
|
73
82
|
|
|
74
83
|
const emit = defineEmits<{
|
|
75
84
|
/**
|
|
@@ -10,6 +10,8 @@ A built-in menu is a structured list of navigational or interactive options, typ
|
|
|
10
10
|
| `modelValue` | Specifies the key of the currently selected menu item. It allows the component to highlight or style the corresponding item to indicate it is selected or currently in use. | `number` | - |
|
|
11
11
|
| `items*` | Defines the menu items, each of which can include an icon and act as a button, link, or router-link. | `MenuItem[]` | - |
|
|
12
12
|
| `outlined` | When enabled, adds a visible border around the wrapper to highlight or separate its content. | `boolean` | - |
|
|
13
|
+
| `label` | Accessible label for the navigation landmark. Should describe the purpose
|
|
14
|
+
of this menu to distinguish it from other navigations on the page. | `string` | `"Menu"` |
|
|
13
15
|
|
|
14
16
|
## Events
|
|
15
17
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Connect mapping for MButton
|
|
3
|
+
* Links Figma Button to @mozaic-ds/vue
|
|
4
|
+
* Props discovered via Figma MCP get_code_connect_suggestions
|
|
5
|
+
*/
|
|
6
|
+
import figma, { html } from '@figma/code-connect/html';
|
|
7
|
+
|
|
8
|
+
figma.connect(
|
|
9
|
+
'https://www.figma.com/design/Zyh9RyabNaqkjbuFWP9Aqj/%E2%9C%A8-Components--ADS2---Stable-version-?node-id=1%3A609',
|
|
10
|
+
{
|
|
11
|
+
props: {
|
|
12
|
+
label: figma.string('Label'),
|
|
13
|
+
appearance: figma.enum('Appearance', {
|
|
14
|
+
Standard: 'standard',
|
|
15
|
+
Accent: 'accent',
|
|
16
|
+
Danger: 'danger',
|
|
17
|
+
'Inverse (only on dark background)': 'inverse',
|
|
18
|
+
}),
|
|
19
|
+
size: figma.enum('Size', {
|
|
20
|
+
S: 's',
|
|
21
|
+
'M (default)': 'm',
|
|
22
|
+
L: 'l',
|
|
23
|
+
}),
|
|
24
|
+
iconLeft: figma.boolean('Icon left'),
|
|
25
|
+
iconRight: figma.boolean('Icon right'),
|
|
26
|
+
iconOnly: figma.boolean('Icon only'),
|
|
27
|
+
disabled: figma.boolean('Is disabled'),
|
|
28
|
+
isLoading: figma.boolean('Is loading'),
|
|
29
|
+
outlined: figma.enum('Type', { Outlined: true }),
|
|
30
|
+
ghost: figma.enum('Type', { Ghost: true }),
|
|
31
|
+
},
|
|
32
|
+
example: ({ label, appearance, size, disabled, isLoading, outlined, ghost }) =>
|
|
33
|
+
html`<script setup>
|
|
34
|
+
import { MButton } from '@mozaic-ds/vue';
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<MButton appearance=${appearance} size=${size} disabled=${disabled} :is-loading=${isLoading} outlined=${outlined} ghost=${ghost}>
|
|
38
|
+
${label}
|
|
39
|
+
</MButton>`,
|
|
40
|
+
},
|
|
41
|
+
);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Connect mapping for MCallout
|
|
3
|
+
* Links Figma Callout (ADS2) to @mozaic-ds/vue
|
|
4
|
+
*/
|
|
5
|
+
import figma, { html } from '@figma/code-connect/html';
|
|
6
|
+
|
|
7
|
+
figma.connect(
|
|
8
|
+
'https://www.figma.com/design/Zyh9RyabNaqkjbuFWP9Aqj/%E2%9C%A8-Components--ADS2---Stable-version-?node-id=5-6504',
|
|
9
|
+
{
|
|
10
|
+
props: {
|
|
11
|
+
appearance: figma.enum('Appearance', {
|
|
12
|
+
Standard: 'standard',
|
|
13
|
+
Accent: 'accent',
|
|
14
|
+
Tips: 'tips',
|
|
15
|
+
Inverse: 'inverse',
|
|
16
|
+
}),
|
|
17
|
+
},
|
|
18
|
+
example: ({ appearance }) =>
|
|
19
|
+
html`<script setup>
|
|
20
|
+
import { MCallout } from '@mozaic-ds/vue';
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<MCallout
|
|
24
|
+
title="This is a title, be concise and use the description message to give details."
|
|
25
|
+
description="Description message."
|
|
26
|
+
appearance=${appearance}
|
|
27
|
+
></MCallout>`,
|
|
28
|
+
},
|
|
29
|
+
);
|
|
@@ -97,4 +97,39 @@ describe('MCallout.vue', () => {
|
|
|
97
97
|
|
|
98
98
|
expect(wrapper.find('.mc-callout__footer').exists()).toBe(false);
|
|
99
99
|
});
|
|
100
|
+
|
|
101
|
+
it('renders title with default tag prop (h2)', () => {
|
|
102
|
+
const wrapper = mount(MCallout, {
|
|
103
|
+
props: { title: 'Title', description: 'Desc' },
|
|
104
|
+
});
|
|
105
|
+
expect(wrapper.find('h2.mc-callout__title').exists()).toBe(true);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('renders title with custom tag prop', () => {
|
|
109
|
+
const wrapper = mount(MCallout, {
|
|
110
|
+
props: { title: 'Title', description: 'Desc', tag: 'h3' },
|
|
111
|
+
});
|
|
112
|
+
expect(wrapper.find('h3.mc-callout__title').exists()).toBe(true);
|
|
113
|
+
expect(wrapper.find('h2').exists()).toBe(false);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('has aria-labelledby pointing to the title', () => {
|
|
117
|
+
const wrapper = mount(MCallout, {
|
|
118
|
+
props: { title: 'Title', description: 'Desc' },
|
|
119
|
+
});
|
|
120
|
+
const section = wrapper.find('section');
|
|
121
|
+
const titleId = wrapper.find('.mc-callout__title').attributes('id');
|
|
122
|
+
expect(titleId).toBeDefined();
|
|
123
|
+
expect(section.attributes('aria-labelledby')).toBe(titleId);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('sets aria-hidden on the icon wrapper', () => {
|
|
127
|
+
const wrapper = mount(MCallout, {
|
|
128
|
+
props: { title: 'Title', description: 'Desc' },
|
|
129
|
+
slots: { icon: '<svg class="icon" />' },
|
|
130
|
+
});
|
|
131
|
+
expect(wrapper.find('.mc-callout__icon').attributes('aria-hidden')).toBe(
|
|
132
|
+
'true',
|
|
133
|
+
);
|
|
134
|
+
});
|
|
100
135
|
});
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<section
|
|
3
|
-
|
|
2
|
+
<section
|
|
3
|
+
class="mc-callout"
|
|
4
|
+
role="status"
|
|
5
|
+
:class="classObject"
|
|
6
|
+
:aria-labelledby="`callout-title-${id}`"
|
|
7
|
+
>
|
|
8
|
+
<div class="mc-callout__icon" aria-hidden="true">
|
|
4
9
|
<slot name="icon" />
|
|
5
10
|
</div>
|
|
6
11
|
<div class="mc-callout__content">
|
|
7
|
-
<
|
|
12
|
+
<component
|
|
13
|
+
:is="props.tag"
|
|
14
|
+
:id="`callout-title-${id}`"
|
|
15
|
+
class="mc-callout__title"
|
|
16
|
+
>{{ title }}</component
|
|
17
|
+
>
|
|
8
18
|
|
|
9
19
|
<p class="mc-callout__message">
|
|
10
20
|
{{ description }}
|
|
@@ -18,7 +28,7 @@
|
|
|
18
28
|
</template>
|
|
19
29
|
|
|
20
30
|
<script setup lang="ts">
|
|
21
|
-
import { computed, type VNode } from 'vue';
|
|
31
|
+
import { computed, useId, type VNode } from 'vue';
|
|
22
32
|
/**
|
|
23
33
|
* A callout is used to highlight additional information that can assist users with tips, extra details, or helpful guidance, without signaling a critical status or alert. Unlike notifications, callouts are not triggered by user actions and do not correspond to specific system states. They are designed to enhance the user experience by providing contextually relevant information that supports comprehension and usability.
|
|
24
34
|
*/
|
|
@@ -36,12 +46,20 @@ const props = withDefaults(
|
|
|
36
46
|
* Allows to define the callout appearance.
|
|
37
47
|
*/
|
|
38
48
|
appearance?: 'standard' | 'accent' | 'tips' | 'inverse';
|
|
49
|
+
/**
|
|
50
|
+
* Heading level for the callout title (h2–h6). Adjust to match the
|
|
51
|
+
* heading hierarchy of the page where the callout is used.
|
|
52
|
+
*/
|
|
53
|
+
tag?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
|
39
54
|
}>(),
|
|
40
55
|
{
|
|
41
56
|
appearance: 'standard',
|
|
57
|
+
tag: 'h2',
|
|
42
58
|
},
|
|
43
59
|
);
|
|
44
60
|
|
|
61
|
+
const id = useId();
|
|
62
|
+
|
|
45
63
|
defineSlots<{
|
|
46
64
|
/**
|
|
47
65
|
* Use this slot to insert an icon.
|
|
@@ -10,6 +10,8 @@ A callout is used to highlight additional information that can assist users with
|
|
|
10
10
|
| `title*` | Title of the callout. | `string` | - |
|
|
11
11
|
| `description*` | Description of the callout. | `string` | - |
|
|
12
12
|
| `appearance` | Allows to define the callout appearance. | `"standard"` `"inverse"` `"accent"` `"tips"` | `"standard"` |
|
|
13
|
+
| `tag` | Heading level for the callout title (h2–h6). Adjust to match the
|
|
14
|
+
heading hierarchy of the page where the callout is used. | `"h2"` `"h1"` `"h3"` `"h4"` `"h5"` `"h6"` | `"h2"` |
|
|
13
15
|
|
|
14
16
|
## Slots
|
|
15
17
|
|