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/list
npm i @morpheme/list
Then, 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.