List
The List component is a flexible way to display a list of items in your Vue application. This documentation covers how to use various features of the List component, such as links, slots, icons, headers, and collapse functionality.
Usage
Basic Usage
To use the VList component, just use the component in your template like so:
INFO
The VList component is registered globally when you install with @morpheme/ui. So you don't need to import it manually.
Hover Effect
The Hover variant of the List component allows you to add custom shapes to the list items. You can use the hover prop on a ListItem to apply the default hover style, or use the hover-class prop to specify a custom hover class.
Shaped
The Shaped variant of the List component allows you to add custom shapes to the list items. You can use the shaped prop on a ListItem to apply the default shaped style, or use the shaped-class prop to specify a custom shaped class.
Rounded
The Rounded variant of the List component adds rounded corners to the list items. You can use the rounded prop on a VListItem to apply the rounded style.
Tile
The Tile variant of the List component displays the list items as tiles. You can use the tile prop on a ListItem to apply the tile style.
Hide Prepend & Hide Append
The List component allows you to hide the prepend and append elements of a VListItem. You can use the hide-prepend and hide-append props on a VListItem to hide these elements. Alternatively, you can pass the hide-prepend and hide-append props to the parent VList component and bind them to the child VListItem components via slot props.
Hide Text
The VList component allows you to hide the text of a VListItem. You can use the hide-text prop on a VListItem to hide the text. This can be useful for displaying icons only, for example.
Two Line
To display a list with two lines per list item, you can nest elements inside the VListItem component:
Three Line
To display a list with three lines per list item, you can nest additional elements inside the VListItem component:
Link
You can use the to prop on a VListItem to make it a router link, or the href prop to make it a regular link:
Slots
The VListItem component has prepend and append slots that allow you to insert custom content at the beginning and end of each list item:
Icons
You can use the prepend-icon and append-icon props to add icons to your list items. The value for these props should be the name of the icon in the Icones icon set.
Header
You can use the VListItemHeader component to add header to the list.
Collapse
You can use the VListCollapse component to add collapsible list.
Image
You can place image to the list using prepend slot in the VListItem component.
Navigation Drawer VList
This example shows how to use VList inside VNavDrawer component to create sidebar navigation component.
IOS Settings
This example shows how to create IOS Settings menu using VList component.
Dropdown
This example shows how to use VList component in the dropdown component.
Active State
We can set active state to the list by passing active prop to the VListItem component. We can also choose different styles of active item via active-variant and active-border-position props. The active-variant prop accept "filled" | "bordered" | "filled-bordered" values and the active-border-position prop accept "top" | "right" | "bottom" | "left" values.
Event
This example demonstrates how to use events in the VList component. It shows examples of how to listen for clicks on the prepend and append icons, the prepend and append icon wrapper areas, and the append text. When one of these elements is clicked, a message is displayed using the showMessage function.
Props
VList
| Property | Type | Description |
|---|---|---|
hidePrepend | boolean | Whether to hide the prepend element. |
hideAppend | boolean | Whether to hide the append element. |
shaped | boolean | Whether to apply shaped styling to the list item. |
rounded | boolean | Whether to apply rounded styling to the list item. |
tile | boolean | Whether to apply tile styling to the list item. |
hover | boolean | Whether to apply hover styling to the list item. |
flush | boolean | Whether to remove the border between list items. |
dense | boolean | Whether to reduce the padding on the list item. |
small | boolean | Whether to apply small styling to the list item. |
hideText | boolean | Whether to apply hide text on the list item. |
activeVariant | "filled" | "bordered" | "filled-bordered" | The active state variant. |
activeBorderPosition | "top" | "right" | "bottom" | "left" | The border position. |
VListItem
| Name | Type | Default |
|---|---|---|
to | string | RouteLocation | undefined |
href | string | undefined |
as | any | undefined |
defaultClass | string | `` |
prependClass | string | `` |
prependIcon | string | '' |
prependIconClass | string | '' |
appendClass | string | `` |
appendIcon | string | '' |
appendIconClass | string | '' |
hidePrepend | boolean | false |
hideAppend | boolean | false |
hover | boolean | false |
hoverClass | string | v-list-item--hover |
shaped | boolean | false |
shapedClass | string | v-list-item--shaped |
rounded | boolean | false |
hideText | boolean | false |
appendText | string | '' |
appendTextClass | string | false |
tile | boolean | false |
Events
VList
None.
VListItem
| Event | Description |
|---|---|
(e: 'click:prepend'): void | Emitted when the element wrapped around the prepend slot is clicked. |
(e: 'click:prependIcon'): void | Emitted when the prependIcon element is clicked. |
(e: 'click:append'): void | Emitted when the element wrapped around the append slot is clicked. |
(e: 'click:appendIcon'): void | Emitted when the appendIcon element is clicked. |
(e: 'click:appendText'): void | Emitted when the element wrapped around the appendText slot is clicked. |
Here is example of listening event in VListItem component:
<script setup lang="ts">
function handleClickPrepend() {
// handle click event on prepend slot
}
</script>
<template>
<VList>
<VListItem @click:prepend="handleClickPrepend">
<template #prepend>
<div class="text-cyan-500">prepend</div>
</template>
</VListItem>
</VList>
</template><script setup lang="ts">
function handleClickPrepend() {
// handle click event on prepend slot
}
</script>
<template>
<VList>
<VListItem @click:prepend="handleClickPrepend">
<template #prepend>
<div class="text-cyan-500">prepend</div>
</template>
</VListItem>
</VList>
</template>Slots
| Event | Description |
|---|---|
prepend | Slot for custom content to be displayed before the main content. |
prepend.icon | Slot for a custom icon to be displayed before the main content. |
default | The default slot for the main content. |
append | Slot for custom content to be displayed after the main content. |
append.icon | Slot for a custom icon to be displayed after the main content. |
append.text | Slot for custom text to be displayed after the main content. |
Here is example of using slot in VListItem component:
<template>
<VList>
<VListItem>
<template #prepend>
<div class="text-cyan-500">prepend</div>
</template>
</VListItem>
</VList>
</template><template>
<VList>
<VListItem>
<template #prepend>
<div class="text-cyan-500">prepend</div>
</template>
</VListItem>
</VList>
</template>CSS Variables
:root {
--v-list-padding-y: var(--size-spacing-1);
--v-list-padding-x: var(--size-spacing-1);
--v-list-gap: 0;
--v-list-bg-color: var(--color-transparent);
/* item */
--v-list-item-bg-color: var(--color-transparent);
--v-list-item-color: var(--color-gray-700);
--v-list-item-padding-y: var(--size-spacing-2);
--v-list-item-padding-x: var(--size-spacing-3);
--v-list-item-border-radius: var(--border-radius-md);
--v-list-item-border-width: 0;
--v-list-item-border-color: var(--color-transparent);
--v-list-item-border-style: solid;
--v-list-item-gap: var(--size-spacing-3);
--v-list-item-font-size: var(--size-font-sm);
--v-list-item-font-weight: var(--font-weight-regular);
--v-list-item-line-height: 20px;
--v-list-item-text-align: left;
--v-list-item-icon-width: var(--size-spacing-4);
--v-list-item-icon-height: var(--size-spacing-4);
/* item hover */
--v-list-item-hover-bg-color: var(--color-gray-100);
--v-list-item-hover-color: var(--color-gray-700);
/* item active */
--v-list-item-active-bg-color: var(--color-primary-600);
--v-list-item-active-border-color: var(--color-primary-600);
--v-list-item-active-color: var(--color-white);
/* filled bordered */
--v-list-item-active-filled-bordered-bg-color: var(--color-primary-50);
--v-list-item-active-filled-bordered-border-color: var(--color-primary-500);
--v-list-item-active-filled-bordered-color: var(--color-primary-600);
/* append & prepend */
--v-list-item-append-prepend-min-width: var(--size-spacing-5);
/* item header */
--v-list-item-header-bg-color: var(--v-list-item-bg-color);
--v-list-item-header-color: var(--color-gray-500);
--v-list-item-header-padding-y: var(--size-spacing-1);
--v-list-item-header-padding-x: var(--v-list-item-padding-x);
--v-list-item-header-border-radius: var(--v-list-item-border-radius);
--v-list-item-header-border-width: var(--v-list-item-border-width);
--v-list-item-header-border-color: var(--v-list-item-border-color);
--v-list-item-header-border-style: var(--v-list-item-border-style);
--v-list-item-header-gap: var(--v-list-item-gap);
--v-list-item-header-font-size: var(--size-font-xs);
--v-list-item-header-font-weight: var(--font-weight-medium);
--v-list-item-header-line-height: var(--v-list-item-line-height);
--v-list-item-header-text-transform: uppercase;
--v-list-item-header-text-align: var(--v-list-item-text-align);
/* divider */
--v-list-item-divider-width: 1px;
--v-list-item-divider-color: var(--color-gray-200);
--v-list-item-divider-style: solid;
// icon
--v-list-item-icon-color: currentColor;
// append text
--v-list-item-append-text-color: var(--v-list-item-color);
--v-list-item-append-font-size: var(--v-list-item-font-size);
--v-list-item-append-font-weight: var(--v-list-item-font-weight);
}:root {
--v-list-padding-y: var(--size-spacing-1);
--v-list-padding-x: var(--size-spacing-1);
--v-list-gap: 0;
--v-list-bg-color: var(--color-transparent);
/* item */
--v-list-item-bg-color: var(--color-transparent);
--v-list-item-color: var(--color-gray-700);
--v-list-item-padding-y: var(--size-spacing-2);
--v-list-item-padding-x: var(--size-spacing-3);
--v-list-item-border-radius: var(--border-radius-md);
--v-list-item-border-width: 0;
--v-list-item-border-color: var(--color-transparent);
--v-list-item-border-style: solid;
--v-list-item-gap: var(--size-spacing-3);
--v-list-item-font-size: var(--size-font-sm);
--v-list-item-font-weight: var(--font-weight-regular);
--v-list-item-line-height: 20px;
--v-list-item-text-align: left;
--v-list-item-icon-width: var(--size-spacing-4);
--v-list-item-icon-height: var(--size-spacing-4);
/* item hover */
--v-list-item-hover-bg-color: var(--color-gray-100);
--v-list-item-hover-color: var(--color-gray-700);
/* item active */
--v-list-item-active-bg-color: var(--color-primary-600);
--v-list-item-active-border-color: var(--color-primary-600);
--v-list-item-active-color: var(--color-white);
/* filled bordered */
--v-list-item-active-filled-bordered-bg-color: var(--color-primary-50);
--v-list-item-active-filled-bordered-border-color: var(--color-primary-500);
--v-list-item-active-filled-bordered-color: var(--color-primary-600);
/* append & prepend */
--v-list-item-append-prepend-min-width: var(--size-spacing-5);
/* item header */
--v-list-item-header-bg-color: var(--v-list-item-bg-color);
--v-list-item-header-color: var(--color-gray-500);
--v-list-item-header-padding-y: var(--size-spacing-1);
--v-list-item-header-padding-x: var(--v-list-item-padding-x);
--v-list-item-header-border-radius: var(--v-list-item-border-radius);
--v-list-item-header-border-width: var(--v-list-item-border-width);
--v-list-item-header-border-color: var(--v-list-item-border-color);
--v-list-item-header-border-style: var(--v-list-item-border-style);
--v-list-item-header-gap: var(--v-list-item-gap);
--v-list-item-header-font-size: var(--size-font-xs);
--v-list-item-header-font-weight: var(--font-weight-medium);
--v-list-item-header-line-height: var(--v-list-item-line-height);
--v-list-item-header-text-transform: uppercase;
--v-list-item-header-text-align: var(--v-list-item-text-align);
/* divider */
--v-list-item-divider-width: 1px;
--v-list-item-divider-color: var(--color-gray-200);
--v-list-item-divider-style: solid;
// icon
--v-list-item-icon-color: currentColor;
// append text
--v-list-item-append-text-color: var(--v-list-item-color);
--v-list-item-append-font-size: var(--v-list-item-font-size);
--v-list-item-append-font-weight: var(--v-list-item-font-weight);
}View full styles here.
Standalone Installation
You can also install the VList component individually via @morpheme/list package:
npm i @morpheme/listnpm i @morpheme/listThen, use it in the template like so:
<script setup lang="ts">
import { VList, VListItem } from "@morpheme/list";
</script>
<template>
<VList>
<VListItem prepend-icon="ic:round-home"> Text </VListItem>
</VList>
</template><script setup lang="ts">
import { VList, VListItem } from "@morpheme/list";
</script>
<template>
<VList>
<VListItem prepend-icon="ic:round-home"> Text </VListItem>
</VList>
</template>Storybook
View Storybook documentation here.
Morpheme