@mozaic-ds/vue 2.13.0 → 2.14.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 +1 -1
- package/dist/mozaic-vue.d.ts +1088 -378
- package/dist/mozaic-vue.js +2662 -1854
- package/dist/mozaic-vue.js.map +1 -1
- package/dist/mozaic-vue.umd.cjs +5 -5
- package/dist/mozaic-vue.umd.cjs.map +1 -1
- package/package.json +4 -4
- package/src/components/actionlistbox/MActionListbox.spec.ts +53 -59
- package/src/components/actionlistbox/MActionListbox.stories.ts +22 -1
- package/src/components/actionlistbox/MActionListbox.vue +91 -28
- package/src/components/actionlistbox/README.md +15 -0
- package/src/components/breadcrumb/MBreadcrumb.vue +5 -0
- package/src/components/button/README.md +4 -0
- package/src/components/checkbox/README.md +2 -0
- package/src/components/divider/README.md +4 -0
- package/src/components/iconbutton/MIconButton.stories.ts +12 -0
- package/src/components/iconbutton/MIconButton.vue +13 -1
- package/src/components/iconbutton/README.md +27 -0
- package/src/components/loader/README.md +2 -0
- package/src/components/navigationindicator/MNavigationIndicator.spec.ts +152 -0
- package/src/components/navigationindicator/MNavigationIndicator.stories.ts +41 -0
- package/src/components/navigationindicator/MNavigationIndicator.vue +132 -0
- package/src/components/navigationindicator/README.md +37 -0
- package/src/components/pageheader/MPageHeader.spec.ts +142 -0
- package/src/components/pageheader/MPageHeader.stories.ts +125 -0
- package/src/components/pageheader/MPageHeader.vue +133 -0
- package/src/components/pageheader/README.md +46 -0
- package/src/components/popover/MPopover.spec.ts +106 -0
- package/src/components/popover/MPopover.stories.ts +126 -0
- package/src/components/popover/MPopover.vue +131 -0
- package/src/components/popover/README.md +42 -0
- package/src/components/radio/README.md +2 -0
- package/src/components/select/MSelect.spec.ts +2 -1
- package/src/components/select/MSelect.vue +30 -25
- package/src/components/sidebar/MSidebar.const.ts +6 -0
- package/src/components/sidebar/MSidebar.spec.ts +110 -0
- package/src/components/sidebar/MSidebar.stories.ts +108 -0
- package/src/components/sidebar/MSidebar.vue +124 -0
- package/src/components/sidebar/README.md +59 -0
- package/src/components/sidebar/stories/DefaultCase.stories.vue +120 -0
- package/src/components/sidebar/stories/README.md +27 -0
- package/src/components/sidebar/stories/WithExpandOnly.stories.vue +112 -0
- package/src/components/sidebar/stories/WithProfileInfoOnly.stories.vue +119 -0
- package/src/components/sidebar/stories/WithSingleLevel.stories.vue +98 -0
- package/src/components/sidebar/use-floating-item.composable.ts +135 -0
- package/src/components/sidebar/use-floating-item.spec.ts +251 -0
- package/src/components/sidebarexpandableitem/MSidebarExpandableItem.spec.ts +151 -0
- package/src/components/sidebarexpandableitem/MSidebarExpandableItem.vue +113 -0
- package/src/components/sidebarexpandableitem/README.md +36 -0
- package/src/components/sidebarfooter/MSidebarFooter.spec.ts +276 -0
- package/src/components/sidebarfooter/MSidebarFooter.vue +201 -0
- package/src/components/sidebarfooter/README.md +52 -0
- package/src/components/sidebarfooter/_MSidebarFooterMenu.vue +64 -0
- package/src/components/sidebarheader/MSidebarHeader.vue +36 -0
- package/src/components/sidebarheader/README.md +31 -0
- package/src/components/sidebarnavitem/MSidebarNavItem.spec.ts +127 -0
- package/src/components/sidebarnavitem/MSidebarNavItem.vue +113 -0
- package/src/components/sidebarnavitem/README.md +56 -0
- package/src/components/sidebarshortcutitem/MSidebarShortcutItem.spec.ts +59 -0
- package/src/components/sidebarshortcutitem/MSidebarShortcutItem.vue +52 -0
- package/src/components/sidebarshortcutitem/README.md +32 -0
- package/src/components/sidebarshortcuts/MSidebarShortcuts.spec.ts +87 -0
- package/src/components/sidebarshortcuts/MSidebarShortcuts.vue +101 -0
- package/src/components/sidebarshortcuts/README.md +36 -0
- package/src/components/statusbadge/README.md +12 -0
- package/src/components/textinput/MTextInput.stories.ts +13 -1
- package/src/components/textinput/MTextInput.vue +12 -0
- package/src/components/textinput/README.md +3 -1
- package/src/components/tile/MTile.spec.ts +61 -0
- package/src/components/tile/MTile.stories.ts +102 -0
- package/src/components/tile/MTile.vue +68 -0
- package/src/components/tile/README.md +19 -0
- package/src/components/tileclickable/MTileClickable.spec.ts +130 -0
- package/src/components/tileclickable/MTileClickable.stories.ts +60 -0
- package/src/components/tileclickable/MTileClickable.vue +106 -0
- package/src/components/tileclickable/README.md +30 -0
- package/src/components/tileexpandable/MTileExpandable.spec.ts +121 -0
- package/src/components/tileexpandable/MTileExpandable.stories.ts +50 -0
- package/src/components/tileexpandable/MTileExpandable.vue +131 -0
- package/src/components/tileexpandable/README.md +36 -0
- package/src/components/tileselectable/MTileSelectable.spec.ts +177 -0
- package/src/components/tileselectable/MTileSelectable.stories.ts +55 -0
- package/src/components/tileselectable/MTileSelectable.vue +142 -0
- package/src/components/tileselectable/README.md +44 -0
- package/src/components/toaster/README.md +1 -1
- package/src/components/tooltip/MTooltip.vue +5 -0
- package/src/components/tooltip/README.md +16 -1
- package/src/main.ts +12 -2
- package/src/utils/use-is-mobile.composable.ts +20 -0
- package/src/utils/use-is-mobile.spec.ts +70 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
:class="{
|
|
4
|
+
'mc-tile mc-tile--expandable': true,
|
|
5
|
+
[`mc-tile--${appearance}`]: props.appearance !== 'primary',
|
|
6
|
+
'mc-tile--bordered': props.bordered,
|
|
7
|
+
[`mc-tile--trigger-${props.trigger}`]: props.trigger !== 'container',
|
|
8
|
+
}"
|
|
9
|
+
>
|
|
10
|
+
<component
|
|
11
|
+
:is="isContainerTriggered ? 'button' : 'div'"
|
|
12
|
+
class="mc-tile__header"
|
|
13
|
+
v-bind="
|
|
14
|
+
isContainerTriggered
|
|
15
|
+
? {
|
|
16
|
+
type: 'button',
|
|
17
|
+
['aria-controls']: `content-${id}`,
|
|
18
|
+
['aria-expanded']: open,
|
|
19
|
+
onclick: toggle,
|
|
20
|
+
}
|
|
21
|
+
: {}
|
|
22
|
+
"
|
|
23
|
+
>
|
|
24
|
+
<div class="mc-tile__body">
|
|
25
|
+
<slot />
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
<div class="mc-tile__action">
|
|
29
|
+
<MIconButton
|
|
30
|
+
v-if="props.trigger === 'icon'"
|
|
31
|
+
class="mc-tile__action-button"
|
|
32
|
+
ghost
|
|
33
|
+
:aria-controls="`content-${id}`"
|
|
34
|
+
:aria-expanded="open"
|
|
35
|
+
aria-label="Expansion trigger button"
|
|
36
|
+
@click="toggle"
|
|
37
|
+
>
|
|
38
|
+
<template #icon>
|
|
39
|
+
<ChevronDown24 />
|
|
40
|
+
</template>
|
|
41
|
+
</MIconButton>
|
|
42
|
+
|
|
43
|
+
<MButton
|
|
44
|
+
v-else-if="props.trigger === 'button'"
|
|
45
|
+
class="mc-tile__action-button"
|
|
46
|
+
ghost
|
|
47
|
+
icon-position="right"
|
|
48
|
+
:aria-controls="`content-${id}`"
|
|
49
|
+
:aria-expanded="open"
|
|
50
|
+
aria-label="Expansion trigger button"
|
|
51
|
+
@click="toggle"
|
|
52
|
+
>
|
|
53
|
+
<span class="mc-tile__action-label">
|
|
54
|
+
{{ props.label }}
|
|
55
|
+
</span>
|
|
56
|
+
|
|
57
|
+
<template #icon>
|
|
58
|
+
<ChevronDown24 />
|
|
59
|
+
</template>
|
|
60
|
+
</MButton>
|
|
61
|
+
</div>
|
|
62
|
+
</component>
|
|
63
|
+
|
|
64
|
+
<div class="mc-tile__content" :id="`content-${id}`" :aria-hidden="!open">
|
|
65
|
+
<slot name="details" />
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
</template>
|
|
69
|
+
|
|
70
|
+
<script setup lang="ts">
|
|
71
|
+
import { computed, ref, useId, type VNode } from 'vue';
|
|
72
|
+
import MButton from '../button/MButton.vue';
|
|
73
|
+
import MIconButton from '../iconbutton/MIconButton.vue';
|
|
74
|
+
import { ChevronDown24 } from '@mozaic-ds/icons-vue';
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* A tile is a container component used to group related content and actions within a structured layout. It provides a clickable or static area that can display text, images, icons, or interactive elements. Tiles are commonly used to present key information, navigate to detailed views, or trigger specific actions in dashboards, cards, and grid-based layouts. Their adaptable design allows them to accommodate various content types while maintaining a consistent and organized interface.
|
|
78
|
+
*/
|
|
79
|
+
|
|
80
|
+
const props = withDefaults(
|
|
81
|
+
defineProps<{
|
|
82
|
+
/**
|
|
83
|
+
* Defines the visual style of the tile.
|
|
84
|
+
*/
|
|
85
|
+
appearance?: 'primary' | 'secondary';
|
|
86
|
+
/**
|
|
87
|
+
* Adds a border around the tile.
|
|
88
|
+
*/
|
|
89
|
+
bordered?: boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Determines how the tile expansion is triggered.
|
|
92
|
+
*/
|
|
93
|
+
trigger?: 'container' | 'icon' | 'button';
|
|
94
|
+
/**
|
|
95
|
+
* Label for the action button (only used when trigger is 'button').
|
|
96
|
+
*/
|
|
97
|
+
label?: string;
|
|
98
|
+
}>(),
|
|
99
|
+
{
|
|
100
|
+
appearance: 'primary',
|
|
101
|
+
label: 'See more',
|
|
102
|
+
trigger: 'icon',
|
|
103
|
+
bordered: true,
|
|
104
|
+
},
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
defineSlots<{
|
|
108
|
+
/**
|
|
109
|
+
* Default slot for the main content of the tile.
|
|
110
|
+
*/
|
|
111
|
+
default?: VNode[];
|
|
112
|
+
/**
|
|
113
|
+
* Named slot for expandable content shown when the tile is opened.
|
|
114
|
+
*/
|
|
115
|
+
details?: VNode[];
|
|
116
|
+
}>();
|
|
117
|
+
|
|
118
|
+
const id = useId();
|
|
119
|
+
|
|
120
|
+
const open = ref(false);
|
|
121
|
+
|
|
122
|
+
const isContainerTriggered = computed(() => props.trigger === 'container');
|
|
123
|
+
|
|
124
|
+
function toggle() {
|
|
125
|
+
open.value = !open.value;
|
|
126
|
+
}
|
|
127
|
+
</script>
|
|
128
|
+
|
|
129
|
+
<style lang="scss" scoped>
|
|
130
|
+
@use '@mozaic-ds/styles/components/tile';
|
|
131
|
+
</style>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# MTileExpandable
|
|
2
|
+
|
|
3
|
+
A tile is a container component used to group related content and actions within a structured layout. It provides a clickable or static area that can display text, images, icons, or interactive elements. Tiles are commonly used to present key information, navigate to detailed views, or trigger specific actions in dashboards, cards, and grid-based layouts. Their adaptable design allows them to accommodate various content types while maintaining a consistent and organized interface.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## Props
|
|
7
|
+
|
|
8
|
+
| Name | Description | Type | Default |
|
|
9
|
+
| --- | --- | --- | --- |
|
|
10
|
+
| `appearance` | Defines the visual style of the tile. | `"primary"` `"secondary"` | `"primary"` |
|
|
11
|
+
| `bordered` | Adds a border around the tile. | `boolean` | `true` |
|
|
12
|
+
| `trigger` | Determines how the tile expansion is triggered. | `"icon"` `"button"` `"container"` | `"icon"` |
|
|
13
|
+
| `label` | Label for the action button (only used when trigger is 'button'). | `string` | `"See more"` |
|
|
14
|
+
|
|
15
|
+
## Slots
|
|
16
|
+
|
|
17
|
+
| Name | Description |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| `default` | Default slot for the main content of the tile. |
|
|
20
|
+
| `details` | Named slot for expandable content shown when the tile is opened. |
|
|
21
|
+
|
|
22
|
+
## Dependencies
|
|
23
|
+
|
|
24
|
+
### Depends on
|
|
25
|
+
|
|
26
|
+
- [MButton](../button)
|
|
27
|
+
- [MIconButton](../iconbutton)
|
|
28
|
+
|
|
29
|
+
### Graph
|
|
30
|
+
|
|
31
|
+
```mermaid
|
|
32
|
+
graph TD;
|
|
33
|
+
MTileExpandable --> MButton
|
|
34
|
+
MTileExpandable --> MIconButton
|
|
35
|
+
style MTileExpandable fill:#008240,stroke:#333,stroke-width:4px
|
|
36
|
+
```
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
+
import { mount } from '@vue/test-utils';
|
|
3
|
+
import MTileSelectable from './MTileSelectable.vue';
|
|
4
|
+
|
|
5
|
+
vi.mock('../checkbox/MCheckbox.vue', () => ({
|
|
6
|
+
default: {
|
|
7
|
+
name: 'MCheckbox',
|
|
8
|
+
props: ['modelValue', 'id', 'name'],
|
|
9
|
+
emits: ['update:modelValue'],
|
|
10
|
+
template: `
|
|
11
|
+
<input
|
|
12
|
+
type="checkbox"
|
|
13
|
+
:id="id"
|
|
14
|
+
:checked="modelValue"
|
|
15
|
+
@change="$emit('update:modelValue', !$props.modelValue)"
|
|
16
|
+
/>
|
|
17
|
+
`,
|
|
18
|
+
},
|
|
19
|
+
}));
|
|
20
|
+
|
|
21
|
+
vi.mock('../radio/MRadio.vue', () => ({
|
|
22
|
+
default: {
|
|
23
|
+
name: 'MRadio',
|
|
24
|
+
props: ['modelValue', 'id', 'name'],
|
|
25
|
+
emits: ['update:modelValue'],
|
|
26
|
+
template: `
|
|
27
|
+
<input
|
|
28
|
+
type="radio"
|
|
29
|
+
:id="id"
|
|
30
|
+
:checked="modelValue"
|
|
31
|
+
@change="$emit('update:modelValue', true)"
|
|
32
|
+
/>
|
|
33
|
+
`,
|
|
34
|
+
},
|
|
35
|
+
}));
|
|
36
|
+
|
|
37
|
+
describe('MTileSelectable', () => {
|
|
38
|
+
it('applies bordered class when bordered is true', () => {
|
|
39
|
+
const wrapper = mount(MTileSelectable, {
|
|
40
|
+
props: {
|
|
41
|
+
modelValue: false,
|
|
42
|
+
bordered: true,
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
expect(wrapper.classes()).toContain('mc-tile--bordered');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('does not apply bordered class when bordered is false', () => {
|
|
50
|
+
const wrapper = mount(MTileSelectable, {
|
|
51
|
+
props: {
|
|
52
|
+
modelValue: false,
|
|
53
|
+
bordered: false,
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
expect(wrapper.classes()).not.toContain('mc-tile--bordered');
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('applies selected class when modelValue is true', () => {
|
|
61
|
+
const wrapper = mount(MTileSelectable, {
|
|
62
|
+
props: {
|
|
63
|
+
modelValue: true,
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
expect(wrapper.classes()).toContain('mc-tile--selected');
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('does not apply selected class when modelValue is false', () => {
|
|
71
|
+
const wrapper = mount(MTileSelectable, {
|
|
72
|
+
props: {
|
|
73
|
+
modelValue: false,
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
expect(wrapper.classes()).not.toContain('mc-tile--selected');
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('applies input left class when inputPosition is left', () => {
|
|
81
|
+
const wrapper = mount(MTileSelectable, {
|
|
82
|
+
props: {
|
|
83
|
+
modelValue: false,
|
|
84
|
+
inputPosition: 'left',
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
expect(wrapper.classes()).toContain('mc-tile--input-left');
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('applies input center class when centered is true', () => {
|
|
92
|
+
const wrapper = mount(MTileSelectable, {
|
|
93
|
+
props: {
|
|
94
|
+
modelValue: false,
|
|
95
|
+
centered: true,
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
expect(wrapper.classes()).toContain('mc-tile--input-center');
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('renders checkbox by default', () => {
|
|
103
|
+
const wrapper = mount(MTileSelectable, {
|
|
104
|
+
props: {
|
|
105
|
+
modelValue: false,
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
expect(wrapper.find('input[type="checkbox"]').exists()).toBe(true);
|
|
110
|
+
expect(wrapper.find('input[type="radio"]').exists()).toBe(false);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it('renders radio when inputType is radio', () => {
|
|
114
|
+
const wrapper = mount(MTileSelectable, {
|
|
115
|
+
props: {
|
|
116
|
+
modelValue: false,
|
|
117
|
+
inputType: 'radio',
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
expect(wrapper.find('input[type="radio"]').exists()).toBe(true);
|
|
122
|
+
expect(wrapper.find('input[type="checkbox"]').exists()).toBe(false);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('emits update:modelValue when checkbox value changes', async () => {
|
|
126
|
+
const wrapper = mount(MTileSelectable, {
|
|
127
|
+
props: {
|
|
128
|
+
modelValue: false,
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
await wrapper.find('input[type="checkbox"]').trigger('change');
|
|
133
|
+
|
|
134
|
+
expect(wrapper.emitted('update:modelValue')).toBeTruthy();
|
|
135
|
+
expect(wrapper.emitted('update:modelValue')![0]).toEqual([true]);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('emits update:modelValue when radio button value changes', async () => {
|
|
139
|
+
const wrapper = mount(MTileSelectable, {
|
|
140
|
+
props: {
|
|
141
|
+
inputType: 'radio',
|
|
142
|
+
modelValue: false,
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
await wrapper.find('input[type="radio"]').trigger('change');
|
|
147
|
+
|
|
148
|
+
expect(wrapper.emitted('update:modelValue')).toBeTruthy();
|
|
149
|
+
expect(wrapper.emitted('update:modelValue')![0]).toEqual([true]);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it('renders header and content when details slot is provided', () => {
|
|
153
|
+
const wrapper = mount(MTileSelectable, {
|
|
154
|
+
props: {
|
|
155
|
+
modelValue: false,
|
|
156
|
+
},
|
|
157
|
+
slots: {
|
|
158
|
+
default: 'Main content',
|
|
159
|
+
details: 'Details content',
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
expect(wrapper.find('.mc-tile__header').exists()).toBe(true);
|
|
164
|
+
expect(wrapper.find('.mc-tile__content').exists()).toBe(true);
|
|
165
|
+
expect(wrapper.text()).toContain('Details content');
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('does not render content container when details slot is missing', () => {
|
|
169
|
+
const wrapper = mount(MTileSelectable, {
|
|
170
|
+
props: {
|
|
171
|
+
modelValue: false,
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
expect(wrapper.find('.mc-tile__content').exists()).toBe(false);
|
|
176
|
+
});
|
|
177
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3-vite';
|
|
2
|
+
import { action } from 'storybook/actions';
|
|
3
|
+
import MTileSelectable from './MTileSelectable.vue';
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof MTileSelectable> = {
|
|
6
|
+
title: 'Content/Tile/Selectable',
|
|
7
|
+
component: MTileSelectable,
|
|
8
|
+
parameters: {
|
|
9
|
+
docs: {
|
|
10
|
+
description: {
|
|
11
|
+
component:
|
|
12
|
+
'A tile is a container component used to group related content and actions within a structured layout. It provides a clickable or static area that can display text, images, icons, or interactive elements. Tiles are commonly used to present key information, navigate to detailed views, or trigger specific actions in dashboards, cards, and grid-based layouts. Their adaptable design allows them to accommodate various content types while maintaining a consistent and organized interface.',
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
args: {
|
|
17
|
+
modelValue: false,
|
|
18
|
+
inputType: 'checkbox',
|
|
19
|
+
inputPosition: 'right',
|
|
20
|
+
bordered: true,
|
|
21
|
+
default: `
|
|
22
|
+
<div class="placeholder-slot">
|
|
23
|
+
Insert a form element here to replace this slot.
|
|
24
|
+
</div>
|
|
25
|
+
`,
|
|
26
|
+
},
|
|
27
|
+
render: (args) => ({
|
|
28
|
+
components: { MTileSelectable },
|
|
29
|
+
setup() {
|
|
30
|
+
const handleUpdate = action('update:modelValue');
|
|
31
|
+
return { args, handleUpdate };
|
|
32
|
+
},
|
|
33
|
+
template: `
|
|
34
|
+
<MTileSelectable v-bind="args" v-model="args.modelValue" @update:modelValue="handleUpdate">
|
|
35
|
+
${args.default}
|
|
36
|
+
</MTileSelectable>
|
|
37
|
+
`,
|
|
38
|
+
}),
|
|
39
|
+
};
|
|
40
|
+
export default meta;
|
|
41
|
+
type Story = StoryObj<typeof MTileSelectable>;
|
|
42
|
+
|
|
43
|
+
export const Default: Story = {};
|
|
44
|
+
|
|
45
|
+
export const RadioButton: Story = {
|
|
46
|
+
args: {
|
|
47
|
+
inputType: 'radio',
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const LeftPositionInput: Story = {
|
|
52
|
+
args: {
|
|
53
|
+
inputPosition: 'left',
|
|
54
|
+
},
|
|
55
|
+
};
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
:class="{
|
|
4
|
+
'mc-tile mc-tile--selectable': true,
|
|
5
|
+
'mc-tile--selected': checked,
|
|
6
|
+
'mc-tile--bordered': props.bordered,
|
|
7
|
+
'mc-tile--input-left': props.inputPosition === 'left',
|
|
8
|
+
'mc-tile--input-center': props.centered,
|
|
9
|
+
'mc-tile--no-input': props.hideInput,
|
|
10
|
+
}"
|
|
11
|
+
v-bind="props.hideInput && { onClick: () => (checked = !checked) }"
|
|
12
|
+
>
|
|
13
|
+
<div v-if="$slots.details" class="mc-tile__header">
|
|
14
|
+
<div class="mc-tile__body">
|
|
15
|
+
<slot />
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
<div class="mc-tile__action">
|
|
19
|
+
<MCheckbox
|
|
20
|
+
v-if="inputType === 'checkbox'"
|
|
21
|
+
v-model="checked"
|
|
22
|
+
:id="`checkbox-${id}`"
|
|
23
|
+
name="tile-select-group"
|
|
24
|
+
aria-label="Tile checkbox"
|
|
25
|
+
/>
|
|
26
|
+
|
|
27
|
+
<MRadio
|
|
28
|
+
v-else
|
|
29
|
+
v-model="checked"
|
|
30
|
+
:id="`radio-${id}`"
|
|
31
|
+
name="tile-select-group"
|
|
32
|
+
aria-label="Tile radio button"
|
|
33
|
+
/>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<template v-else>
|
|
38
|
+
<div class="mc-tile__body">
|
|
39
|
+
<slot />
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
<div class="mc-tile__action">
|
|
43
|
+
<MCheckbox
|
|
44
|
+
v-if="inputType === 'checkbox'"
|
|
45
|
+
v-model="checked"
|
|
46
|
+
:id="`checkbox-${id}`"
|
|
47
|
+
name="tile-select-group"
|
|
48
|
+
aria-label="Tile checkbox"
|
|
49
|
+
/>
|
|
50
|
+
|
|
51
|
+
<MRadio
|
|
52
|
+
v-else
|
|
53
|
+
v-model="checked"
|
|
54
|
+
:id="`radio-${id}`"
|
|
55
|
+
name="tile-select-group"
|
|
56
|
+
aria-label="Tile radio button"
|
|
57
|
+
/>
|
|
58
|
+
</div>
|
|
59
|
+
</template>
|
|
60
|
+
|
|
61
|
+
<div v-if="$slots.details" class="mc-tile__content">
|
|
62
|
+
<slot name="details" />
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
</template>
|
|
66
|
+
|
|
67
|
+
<script setup lang="ts">
|
|
68
|
+
import { computed, useId, type VNode } from 'vue';
|
|
69
|
+
import MCheckbox from '../checkbox/MCheckbox.vue';
|
|
70
|
+
import MRadio from '../radio/MRadio.vue';
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* A tile is a container component used to group related content and actions within a structured layout. It provides a clickable or static area that can display text, images, icons, or interactive elements. Tiles are commonly used to present key information, navigate to detailed views, or trigger specific actions in dashboards, cards, and grid-based layouts. Their adaptable design allows them to accommodate various content types while maintaining a consistent and organized interface.
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
const props = withDefaults(
|
|
77
|
+
defineProps<{
|
|
78
|
+
/**
|
|
79
|
+
* The current value of the tile (selected or not).
|
|
80
|
+
*/
|
|
81
|
+
modelValue: boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Adds a border around the tile.
|
|
84
|
+
*/
|
|
85
|
+
bordered?: boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Type of input used for selection.
|
|
88
|
+
*/
|
|
89
|
+
inputType?: 'checkbox' | 'radio';
|
|
90
|
+
/**
|
|
91
|
+
* Position of the input relative to the tile content.
|
|
92
|
+
*/
|
|
93
|
+
inputPosition?: 'left' | 'right';
|
|
94
|
+
/**
|
|
95
|
+
* Vertical alignment of the input.
|
|
96
|
+
*/
|
|
97
|
+
centered?: boolean;
|
|
98
|
+
/**
|
|
99
|
+
* If `true`, hides the input and makes the whole tile selectable.
|
|
100
|
+
*/
|
|
101
|
+
hideInput?: boolean;
|
|
102
|
+
}>(),
|
|
103
|
+
{
|
|
104
|
+
inputType: 'checkbox',
|
|
105
|
+
inputPosition: 'right',
|
|
106
|
+
bordered: true,
|
|
107
|
+
},
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
defineSlots<{
|
|
111
|
+
/**
|
|
112
|
+
* Default slot for the main content of the tile.
|
|
113
|
+
*/
|
|
114
|
+
default?: VNode[];
|
|
115
|
+
/**
|
|
116
|
+
* Named slot for additional content shown below the main content.
|
|
117
|
+
*/
|
|
118
|
+
details?: VNode[];
|
|
119
|
+
}>();
|
|
120
|
+
|
|
121
|
+
const emit = defineEmits<{
|
|
122
|
+
/**
|
|
123
|
+
* Emits when the value changes.
|
|
124
|
+
*/
|
|
125
|
+
(on: 'update:modelValue', value: boolean): void;
|
|
126
|
+
}>();
|
|
127
|
+
|
|
128
|
+
const id = useId();
|
|
129
|
+
|
|
130
|
+
const checked = computed({
|
|
131
|
+
get() {
|
|
132
|
+
return props.modelValue;
|
|
133
|
+
},
|
|
134
|
+
set(value) {
|
|
135
|
+
emit('update:modelValue', value);
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
</script>
|
|
139
|
+
|
|
140
|
+
<style lang="scss" scoped>
|
|
141
|
+
@use '@mozaic-ds/styles/components/tile';
|
|
142
|
+
</style>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# MTileSelectable
|
|
2
|
+
|
|
3
|
+
A tile is a container component used to group related content and actions within a structured layout. It provides a clickable or static area that can display text, images, icons, or interactive elements. Tiles are commonly used to present key information, navigate to detailed views, or trigger specific actions in dashboards, cards, and grid-based layouts. Their adaptable design allows them to accommodate various content types while maintaining a consistent and organized interface.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## Props
|
|
7
|
+
|
|
8
|
+
| Name | Description | Type | Default |
|
|
9
|
+
| --- | --- | --- | --- |
|
|
10
|
+
| `modelValue*` | The current value of the tile (selected or not). | `boolean` | - |
|
|
11
|
+
| `bordered` | Adds a border around the tile. | `boolean` | `true` |
|
|
12
|
+
| `inputType` | Type of input used for selection. | `"checkbox"` `"radio"` | `"checkbox"` |
|
|
13
|
+
| `inputPosition` | Position of the input relative to the tile content. | `"left"` `"right"` | `"right"` |
|
|
14
|
+
| `centered` | Vertical alignment of the input. | `boolean` | - |
|
|
15
|
+
| `hideInput` | If `true`, hides the input and makes the whole tile selectable. | `boolean` | - |
|
|
16
|
+
|
|
17
|
+
## Slots
|
|
18
|
+
|
|
19
|
+
| Name | Description |
|
|
20
|
+
| --- | --- |
|
|
21
|
+
| `default` | Default slot for the main content of the tile. |
|
|
22
|
+
| `details` | Named slot for additional content shown below the main content. |
|
|
23
|
+
|
|
24
|
+
## Events
|
|
25
|
+
|
|
26
|
+
| Name | Description | Type |
|
|
27
|
+
| --- | --- | --- |
|
|
28
|
+
| `update:modelValue` | Emits when the value changes. | [value: boolean] |
|
|
29
|
+
|
|
30
|
+
## Dependencies
|
|
31
|
+
|
|
32
|
+
### Depends on
|
|
33
|
+
|
|
34
|
+
- [MCheckbox](../checkbox)
|
|
35
|
+
- [MRadio](../radio)
|
|
36
|
+
|
|
37
|
+
### Graph
|
|
38
|
+
|
|
39
|
+
```mermaid
|
|
40
|
+
graph TD;
|
|
41
|
+
MTileSelectable --> MCheckbox
|
|
42
|
+
MTileSelectable --> MRadio
|
|
43
|
+
style MTileSelectable fill:#008240,stroke:#333,stroke-width:4px
|
|
44
|
+
```
|
|
@@ -8,7 +8,7 @@ A toaster is a temporary notification that appears briefly on the screen to prov
|
|
|
8
8
|
| Name | Description | Type | Default |
|
|
9
9
|
| --- | --- | --- | --- |
|
|
10
10
|
| `open` | If `true`, display the Toaster. | `boolean` | - |
|
|
11
|
-
| `position` | Position of the toaster. | `"
|
|
11
|
+
| `position` | Position of the toaster. | `"bottom"` `"top"` `"top-center"` `"bottom-center"` | - |
|
|
12
12
|
| `description*` | Description of the toaster. | `string` | - |
|
|
13
13
|
| `status` | Allows to define the toaster style. | `"info"` `"warning"` `"error"` `"success"` | `"info"` |
|
|
14
14
|
| `closable` | If `true`, display the close button. | `boolean` | `true` |
|
|
@@ -30,6 +30,10 @@ const props = withDefaults(
|
|
|
30
30
|
* If `true`, the tooltip display a pointer.
|
|
31
31
|
*/
|
|
32
32
|
pointer?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Standalone tooltip
|
|
35
|
+
*/
|
|
36
|
+
standalone?: boolean;
|
|
33
37
|
}>(),
|
|
34
38
|
{
|
|
35
39
|
position: 'top',
|
|
@@ -48,6 +52,7 @@ const classObject = computed(() => {
|
|
|
48
52
|
return {
|
|
49
53
|
[`mc-tooltip--${props.position}`]: props.position,
|
|
50
54
|
'mc-tooltip--no-pointer': !props.pointer,
|
|
55
|
+
'mc-tooltip--standalone': props.standalone,
|
|
51
56
|
};
|
|
52
57
|
});
|
|
53
58
|
</script>
|
|
@@ -9,11 +9,26 @@ A tooltip is a small, contextual message that appears when users hover over, foc
|
|
|
9
9
|
| --- | --- | --- | --- |
|
|
10
10
|
| `id*` | A unique identifier for the tooltip, used to describe the tooltip. | `string` | - |
|
|
11
11
|
| `text*` | Content of the tooltip. | `string` | - |
|
|
12
|
-
| `position` | Determines the position of the tooltip. | `"
|
|
12
|
+
| `position` | Determines the position of the tooltip. | `"bottom"` `"top"` `"left"` `"right"` | `"top"` |
|
|
13
13
|
| `pointer` | If `true`, the tooltip display a pointer. | `boolean` | `true` |
|
|
14
|
+
| `standalone` | Standalone tooltip | `boolean` | - |
|
|
14
15
|
|
|
15
16
|
## Slots
|
|
16
17
|
|
|
17
18
|
| Name | Description |
|
|
18
19
|
| --- | --- |
|
|
19
20
|
| `default` | The tooltip will point to the content of the slot. |
|
|
21
|
+
|
|
22
|
+
## Dependencies
|
|
23
|
+
|
|
24
|
+
### Used By
|
|
25
|
+
|
|
26
|
+
- [MSidebarNavItem](../sidebarnavitem)
|
|
27
|
+
|
|
28
|
+
### Graph
|
|
29
|
+
|
|
30
|
+
```mermaid
|
|
31
|
+
graph TD;
|
|
32
|
+
MSidebarNavItem --> MTooltip
|
|
33
|
+
style MTooltip fill:#008240,stroke:#333,stroke-width:4px
|
|
34
|
+
```
|