List
The List component is a powerful and flexible UI element designed for displaying and selecting items from a list. It supports a wide range of features including single and multi-select modes, item grouping, search functionality, hierarchical navigation, and lozenge display formats.
Basic Usage
The most basic usage involves binding your selection to v-model and providing a list of items via the menu-list prop. Each item must have at minimum a text (display label) and value (unique identifier) property.
<template>
<div
:class="[
'mc-max-h-[300px] mc-overflow-auto mc-rounded-md mc-p-2',
'mc-border-color-weak mc-border mc-border-solid',
]"
>
<mc-list v-model="selectedItems" :menu-list="menuList" />
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const selectedItems = ref([]);
const menuList = ref([
{ text: 'Apple', value: 'apple' },
{ text: 'Banana', value: 'banana' },
{ text: 'Cherry', value: 'cherry' },
{ text: 'Date', value: 'date' },
{ text: 'Elderberry', value: 'elderberry' },
{ text: 'Fig', value: 'fig' },
{ text: 'Grape', value: 'grape' },
{ text: 'Honeydew', value: 'honeydew' },
{ text: 'Kiwi', value: 'kiwi' },
{ text: 'Mango', value: 'mango' },
]);
</script>Multi-Select
Enable multiple item selection by adding the multi-select prop. This displays checkboxes next to each item, allowing users to select multiple items simultaneously.
<template>
<div
:class="[
'mc-max-h-[300px] mc-overflow-auto mc-rounded-md mc-p-2',
'mc-border-color-weak mc-border mc-border-solid',
]"
>
<mc-list v-model="selectedItems" :menu-list="menuList" multi-select />
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const selectedItems = ref([]);
const menuList = ref([
{ text: 'Apple', value: 'apple' },
{ text: 'Banana', value: 'banana' },
{ text: 'Cherry', value: 'cherry' },
{ text: 'Date', value: 'date' },
{ text: 'Elderberry', value: 'elderberry' },
]);
</script>Select All / Unselect All
When using multi-select mode, a "Select All" / "Unselect All" button is automatically provided. This button allows users to quickly select or deselect all available items in the list.
Features:
- Automatic Toggle: The button text automatically changes based on the current selection state
- Smart Selection: Only enabled (non-disabled) items are affected by the select all action
- Works with Filtering: When items are filtered through search, select all only affects the visible items
- Group Awareness: Works correctly with both grouped and non-grouped lists
<template>
<div
:class="[
'mc-max-h-[300px] mc-overflow-auto mc-rounded-md mc-p-2',
'mc-border-color-weak mc-border mc-border-solid',
]"
>
<mc-list v-model="selectedItems" :menu-list="menuList" multi-select allow-select-all display-list-item-selected />
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const selectedItems = ref([]);
const menuList = ref([
{ text: 'Apple', value: 'apple' },
{ text: 'Banana', value: 'banana' },
{ text: 'Cherry', value: 'cherry' },
{ text: 'Date', value: 'date' },
{ text: 'Elderberry', value: 'elderberry' },
{ text: 'Fig', value: 'fig' },
{ text: 'Grape', value: 'grape' },
{ text: 'Honeydew', value: 'honeydew' },
]);
</script>The select all button appears when:
multi-selectprop is enabled- OR
display-list-item-selectedprop is enabled - OR
searchable-menuprop is enabled
Note: Disabled items are automatically excluded from select all operations to ensure only interactive items are affected.
Grouping Items
Group items using the group-items-by prop with values 'default', 'A-Z', or 'Z-A':
- default: Groups by the item's
groupproperty - A-Z: Sorts alphabetically in ascending order
- Z-A: Sorts alphabetically in descending order
Grouped by default
Grouped by A-Z
<template>
<mc-list v-model="selectedItems" :menu-list="menuList" group-items-by="default" />
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const selectedItems = ref([]);
const menuList = ref([
{ text: 'Apple', value: 'apple', group: 'Fruits' },
{ text: 'Banana', value: 'banana', group: 'Fruits' },
{ text: 'Carrot', value: 'carrot', group: 'Vegetables' },
{ text: 'Date', value: 'date', group: 'Fruits' },
{ text: 'Eggplant', value: 'eggplant', group: 'Vegetables' },
]);
</script>Searchable List
Add search functionality with the searchable-menu prop. Users can filter items by typing in the search field.
<template>
<mc-list
v-model="selectedItems"
:menu-list="menuList"
searchable-menu
searchable-menu-placeholder="Search items..."
/>
</template>Radio List
Display a radio button selector for single-select lists using the radio-list prop. Radio buttons appear before the item text and icon, providing a clear visual indicator for single selection mode.
<template>
<mc-list v-model="selectedItems" :menu-list="menuList" radio-list />
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const selectedItems = ref([]);
const menuList = ref([
{ text: 'Option 1', value: 'option1' },
{ text: 'Option 2', value: 'option2' },
{ text: 'Option 3', value: 'option3' },
{ text: 'Option 4', value: 'option4' },
{ text: 'Option 5', value: 'option5' },
]);
</script>Subtext
Add descriptive subtext to list items by including the subtext property. This is useful for providing additional context or information about each item.
<template>
<mc-list v-model="selectedItems" :menu-list="itemsWithSubtext" />
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const selectedItems = ref([]);
const itemsWithSubtext = ref([
{
text: 'Home',
value: 'home',
subtext: 'Go to home page',
},
{
text: 'Settings',
value: 'settings',
subtext: 'Configure preferences',
},
{
text: 'Users',
value: 'users',
subtext: 'Manage user accounts',
},
]);
</script>Icons
Default Item Icon
Apply a default icon to all items in the list using the itemIcon prop. This is useful when all items should display the same icon.
<template>
<mc-list v-model="selectedItems" :menu-list="menuList" item-icon="ph:check" />
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const selectedItems = ref([]);
const menuList = ref([
{ text: 'Apple', value: 'apple' },
{ text: 'Banana', value: 'banana' },
{ text: 'Cherry', value: 'cherry' },
]);
</script>Item Icons
Add icons to individual list items by including the icon property. You can optionally customize the icon color with the iconColor property.
<template>
<mc-list v-model="selectedItems" :menu-list="itemsWithIcons" />
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const selectedItems = ref([]);
const itemsWithIcons = ref([
{
text: 'Home',
value: 'home',
icon: 'ph:house',
},
{
text: 'Settings',
value: 'settings',
icon: 'ph:gear',
iconColor: 'mc-text-blue-500',
},
{
text: 'Users',
value: 'users',
icon: 'ph:users',
},
]);
</script>Icon Tone and Fill
Customize the appearance of default item icons using the item-icon-tone and item-icon-fill props. These allow you to apply color tones and fill styles similar to the lozenge component.
Available tones: 'plain', 'pending', 'information', 'success', 'danger', 'neutral', 'caution'
<template>
<mc-list
v-model="selectedItems"
:menu-list="menuList"
item-icon="ph:star"
item-icon-tone="success"
:item-icon-fill="true"
/>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const selectedItems = ref([]);
const menuList = ref([
{ text: 'Option 1', value: 'option1' },
{ text: 'Option 2', value: 'option2' },
{ text: 'Option 3', value: 'option3' },
]);
</script>Ladderized (Hierarchical) List
Create nested hierarchical lists using the ladderized prop and including sublevel properties in items.
<template>
<mc-ladderized-list v-model="selectedItems" :menu-list="hierarchicalData" />
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const selectedItems = ref([]);
const hierarchicalData = ref([
{
text: 'Fruits',
value: 'fruits',
sublevel: [
{ text: 'Apple', value: 'apple' },
{ text: 'Banana', value: 'banana' },
{ text: 'Cherry', value: 'cherry' },
],
},
{
text: 'Vegetables',
value: 'vegetables',
sublevel: [
{ text: 'Carrot', value: 'carrot' },
{ text: 'Broccoli', value: 'broccoli' },
],
},
]);
</script>Lozenge Display
The List component supports two different lozenge display modes:
1. Full Lozenge Mode (Item as Lozenge)
Display entire list items as lozenges by enabling the lozenge prop and providing lozengeProps for each item. The item becomes the lozenge itself.
<template>
<mc-list v-model="selectedItems" :menu-list="lozengeItems" lozenge />
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const selectedItems = ref([]);
const lozengeItems = ref([
{
text: 'Active',
value: 'active',
lozengeProps: {
label: 'Active',
tone: 'success',
fill: true,
icon: 'ph:check-circle',
},
},
{
text: 'Pending',
value: 'pending',
lozengeProps: {
label: 'Pending',
tone: 'neutral',
fill: false,
icon: 'ph:clock',
},
},
{
text: 'Disabled',
value: 'disabled',
lozengeProps: {
label: 'Disabled',
tone: 'negative',
fill: true,
icon: 'ph:x-circle',
},
},
]);
</script>2. Lozenge Badge (Item with Right-Side Lozenge)
Display a regular list item with a lozenge badge on the right side by using the lozenge property on individual items. This allows you to show metadata or status alongside the item text.
<template>
<mc-list v-model="selectedItems" :menu-list="menuItems" />
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const selectedItems = ref([]);
const menuItems = ref([
{
text: 'Task 1',
value: 'task1',
subtext: 'Due tomorrow',
lozenge: {
label: 'Pending',
tone: 'neutral',
fill: false,
},
},
{
text: 'Task 2',
value: 'task2',
subtext: 'Completed',
lozenge: {
label: 'Done',
tone: 'success',
fill: true,
},
},
{
text: 'Task 3',
value: 'task3',
subtext: 'In progress',
lozenge: {
label: 'Active',
tone: 'success',
fill: true,
},
},
]);
</script>Pre-Selected Items
Use pre-selected-items to set initial selections based on item values.
<template>
<mc-list v-model="selectedItems" :menu-list="menuList" :pre-selected-items="['apple', 'banana']" />
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const selectedItems = ref([]);
const menuList = ref([
{ text: 'Apple', value: 'apple' },
{ text: 'Banana', value: 'banana' },
{ text: 'Cherry', value: 'cherry' },
]);
</script>Event Handling
Use @update:model-value to react to selection changes and retrieve the complete selected item objects.
Selected: None selected
<template>
<mc-list v-model="selectedItems" :menu-list="menuList" @update:model-value="handleSelection" />
<div v-if="selectedItem" class="mc-mt-4 mc-bg-blue-50 mc-p-4">
<p>Selected Item: {{ selectedItem.text }}</p>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const selectedItems = ref([]);
const selectedItem = ref(null);
const menuList = ref([
{ text: 'Apple', value: 'apple' },
{ text: 'Banana', value: 'banana' },
{ text: 'Cherry', value: 'cherry' },
]);
const handleSelection = (items) => {
selectedItem.value = items[0] || null;
};
</script>API Reference
Props
| Prop | Description | Type | Default |
|---|---|---|---|
model-value (v-model) | Two-way binding for selected items containing full item objects | MenuListType[] | [] |
menu-list | Array of items to display | MenuListType[] | [] (required) |
group-items-by | Grouping strategy: 'default' (by group property), 'A-Z' (ascending), or 'Z-A' (descending) | 'default' | 'A-Z' | 'Z-A' | undefined |
multi-select | Enable multi-selection mode with checkboxes | boolean | false |
pre-selected-items | Pre-select items by their values | (string | number | Record<string, unknown>)[] | [] |
searchable-menu | Display search input for filtering items | boolean | false |
searchable-menu-placeholder | Placeholder text for search input | string | 'Search...' |
search-value | External search value (two-way binding) | string | '' |
menu-level | Nesting level for hierarchical lists | number | 0 |
ladderized | Enable hierarchical/ladderized list display | boolean | false |
disabled-local-search | Disable local search filtering | boolean | false |
loading | Show loading skeleton instead of items | boolean | false |
no-check | Hide checkmark icon in single-select mode | boolean | false |
lozenge | Display items as lozenges | boolean | false |
supporting-display-text | Display custom text (e.g., "2 Selected") | string | '' |
display-list-item-selected | Display count of selected items when searchable | boolean | false |
sticky-search-offset | Offset for sticky search header | string | number | 0 |
item-icon | Default icon for all items | string | '' |
item-icon-tone | Tone/color for item icons: 'plain', 'pending', 'information', 'success', 'danger', 'neutral', or 'caution' | string | 'plain' |
item-icon-fill | Fill style for item icons (solid background) | boolean | false |
disabled-unselected-items | Disable and gray out unselected items | boolean | false |
radio-list | Display radio buttons for single-select mode (requires single-select, incompatible with multi-select) | boolean | false |
allow-deselect | When true, allows deselection on selected item (requires single-select, incompatible with multi-select) | boolean | false |
Events
| Event | Description | Payload |
|---|---|---|
update:modelValue | Emitted when selection changes | MenuListType[] - Array of selected item objects |
update:searchValue | Emitted when search input changes | string - New search text |
@get-single-selected-item | Emitted when item selected in single-select mode | MenuListType - Selected item object |
@get-single-deselected-item | Emitted when item is deselected in allow-deselect mode | MenuListType - Deselected item object |