Skip to content

Lozenge

Lozenge represents entities using icons, labels, and images.

Key Features

  • Label:The main text displayed on the lozenge.
  • Tone: Seven different visual styles to indicate status or type: plain, pending, information, success, neutral, danger, and caution.
  • Fill Type:Switch between hollow (outline) and filled styles for different visual emphasis.
  • Avatar Support:Display user avatars using URL property or custom avatar slot.
  • Icon Slots:Named slots for prefix icons, postfix icons, and custom avatar components.
  • Interactive States:Support for interactive and dropdown modes with hover and active states.
  • Loading State:Built-in skeletal loading state for async content.

Basic Usage

A basic lozenge with a text is created with the label property.

Lozenge
vue
<spr-lozenge label="Lozenge" />

Tone and Fill

Customize the lozenge's color style (tone) and choose between filled or outlined appearance (fill) to indicate status or emphasis.

plain
pending
information
success
neutral
danger
caution
plain
pending
information
success
neutral
danger
caution
vue
<div class="spr-flex spr-items-center spr-gap-2 spr-overflow-auto spr-py-3">
  <spr-lozenge label="plain"/>
  <spr-lozenge label="pending" tone="pending" />
  <spr-lozenge label="information" tone="information" />
  <spr-lozenge label="success" tone="success" />
  <spr-lozenge label="neutral" tone="neutral" />
  <spr-lozenge label="danger" tone="danger" />
  <spr-lozenge label="caution" tone="caution" />
</div>
<div class="spr-flex spr-items-center spr-gap-2 spr-overflow-auto spr-py-3">
  <spr-lozenge label="plain" fill />
  <spr-lozenge label="pending" tone="pending" fill />
  <spr-lozenge label="information" tone="information" fill />
  <spr-lozenge label="success" tone="success" fill />
  <spr-lozenge label="neutral" tone="neutral" fill />
  <spr-lozenge label="danger" tone="danger" fill />
  <spr-lozenge label="caution" tone="caution" fill />
</div>

Avatar

You can use the url property to display an avatar image, or use the avatar slot for custom avatar components.

avatar
pending
avatar
information
avatar
success
avatar
neutral
avatar
danger
avatar
caution
avatar
plain
avatar
pending
avatar
information
avatar
success
avatar
neutral
avatar
danger
avatar
caution
avatar
plain
vue
<spr-lozenge label="pending" tone="pending" url="https://tinyurl.com/2vzn782p" />
<spr-lozenge label="information" tone="information" url="https://tinyurl.com/2vzn782p" />
<spr-lozenge label="success" tone="success" url="https://tinyurl.com/2vzn782p" />
<spr-lozenge label="neutral" tone="neutral" url="https://tinyurl.com/2vzn782p" />
<spr-lozenge label="danger" tone="danger" url="https://tinyurl.com/2vzn782p" />
<spr-lozenge label="caution" tone="caution" url="https://tinyurl.com/2vzn782p" />

<spr-lozenge label="pending" tone="pending" fill url="https://tinyurl.com/2vzn782p" />
<spr-lozenge label="information" tone="information" fill url="https://tinyurl.com/2vzn782p" />
<spr-lozenge label="success" tone="success" fill url="https://tinyurl.com/2vzn782p" />
<spr-lozenge label="neutral" tone="neutral" fill url="https://tinyurl.com/2vzn782p" />
<spr-lozenge label="danger" tone="danger" fill url="https://tinyurl.com/2vzn782p" />
<spr-lozenge label="caution" tone="caution" fill url="https://tinyurl.com/2vzn782p" />

Slotted Avatar

You can also use the avatar slot to customize the avatar component.

avatar
Users
vue
<template>
  <spr-lozenge label="Users" tone="information">
    <template #icon>
      <Icon icon="ph:users-three" />
    </template>

    <template #avatar>
      <img class="h-full w-full rounded-full object-cover" src="https://tinyurl.com/2vzn782p" alt="avatar" />
    </template>
  </spr-lozenge>
</template>

<script lang="ts" setup>
import { Icon } from '@iconify/vue';
</script>

Prefix and Postfix Icon

You can use the icon property or the icon slot to add a prefix icon to the lozenge. By default, the icon property or slot renders as a prefix icon before the label.
To add a postfix icon, use the postfixIcon property or the postfixIcon slot. This allows you to display an icon after the label.

pending
information
success
neutral
danger
caution
plain
pending
information
success
neutral
danger
caution
plain
pending
information
success
neutral
danger
caution
plain
pending
information
success
neutral
danger
caution
plain
vue
<template>
  <!-- Prefix Icon -->
  <spr-lozenge label="pending" tone="pending" icon="ph:users-three" />
  <spr-lozenge label="pending" tone="pending">
    <template #icon>
      <Icon icon="ph:users-three" />
    </template>
  </spr-lozenge>

  <!-- Postfix Icon -->
   <spr-lozenge label="pending" tone="pending" postfix-icon="ph:users-three" />
  <spr-lozenge label="pending" tone="pending">
    <template #postfixIcon>
      <Icon icon="ph:users-three" />
    </template>
  </spr-lozenge>
</template>

<script lang="ts" setup>
import { Icon } from '@iconify/vue';
</script>

Interactive

The interactive prop enables interactive states for the lozenge, allowing it to respond to user actions such as hover and pressed. This is useful for making the lozenge behave like a button or menu trigger.

plain
pending
information
success
neutral
danger
caution
plain
pending
information
success
neutral
danger
caution
vue
<div class="spr-flex spr-items-center spr-gap-2 spr-overflow-auto spr-py-3">
  <spr-lozenge label="plain" interactive />
  <spr-lozenge label="pending" tone="pending" interactive />
  <spr-lozenge label="information" tone="information" interactive />
  <spr-lozenge label="success" tone="success" interactive />
  <spr-lozenge label="neutral" tone="neutral" interactive />
  <spr-lozenge label="danger" tone="danger" interactive />
  <spr-lozenge label="caution" tone="caution" interactive />
</div>
<div class="spr-flex spr-items-center spr-gap-2 spr-overflow-auto spr-py-3">
  <spr-lozenge label="plain" fill interactive />
  <spr-lozenge label="pending" tone="pending" fill interactive />
  <spr-lozenge label="information" tone="information" fill interactive />
  <spr-lozenge label="success" tone="success" fill interactive />
  <spr-lozenge label="neutral" tone="neutral" fill interactive />
  <spr-lozenge label="danger" tone="danger" fill interactive />
  <spr-lozenge label="caution" tone="caution" fill interactive />
</div>

The dropdown prop makes the lozenge behave as a predefined interactive element with a default postfix dropdown icon (ph:caret-down-fill).

avatar
Neutral

avatar
Neutral
vue
<template>
  <spr-dropdown id="lozengeDropdown" v-model="dropdownSelection" :menu-list="menuList" lozenge @update:model-value="dropdownUpdateHandler" >
    <spr-lozenge v-bind="lozengeProps" dropdown />
  </spr-dropdown>
</template>

<script lang="ts" setup>
import { ref, computed } from 'vue';

import { LOZENGE_TONE } from '@/components/lozenge/lozenge';
import { MenuListType } from '@/components/list/list';
import { Header } from '@/components/table/table';

const menuList = ref(
  LOZENGE_TONE.map((tone: string) => ({
    text: `${tone.charAt(0).toUpperCase() + tone.slice(1)}`,
    value: tone,
    lozengeProps: {
      label: `${tone.charAt(0).toUpperCase() + tone.slice(1)}`,
      tone: tone,
      fill: true,
      url: "https://tinyurl.com/2vzn782p",
      icon: "ph:address-book-tabs",
    }
  })) as MenuListType[]
);

const dropdownSelection = ref('neutral');
const lozengeProps = computed(() => {
  return menuList.value.find(item => item.value === dropdownSelection.value)?.lozengeProps;
});

const dropdownUpdateHandler = (newSelection: string) => {
  console.log('Dropdown selection updated:', newSelection);
};

const hollowMenuList = ref(
  LOZENGE_TONE.map((tone: string) => ({
    text: `${tone.charAt(0).toUpperCase() + tone.slice(1)}`,
    value: tone,
    lozengeProps: {
      label: `${tone.charAt(0).toUpperCase() + tone.slice(1)}`,
      tone: tone,
      fill: false,
      url: "https://tinyurl.com/2vzn782p",
      icon: "ph:address-book-tabs",
    }
  })) as MenuListType[]
);

const dropdownSelectionHollow = ref('neutral');
const hollowLozengeProps = computed(() => {
  return hollowMenuList.value.find(item => item.value === dropdownSelectionHollow.value)?.lozengeProps;
});
</script>

NOTE

If you provide a postfixIcon prop or slot, it will override the default dropdown icon.

plain
vue
<spr-lozenge label="plain" dropdown>
  <template #postfixIcon>
    <Icon icon="ph:dots-three-vertical-bold" />
  </template>
</spr-lozenge>

Loading

vue
<template>
  <spr-lozenge loading />
</template>

Slot

NameDescription
iconcustomize prefix icon component
avatarcustomize avatar component
postfixIconcustomize postfix icon component (displayed after the label)

API Reference

Props

NameDescriptionTypeDefault
labelThe primary text content displayed in the lozenge.string'label'
toneDetermines the color scheme of the lozenge to indicate status or categorization. Each tone carries semantic meaning:
  • plain: Default, neutral styling
  • pending: For in-progress or waiting states
  • information: For informational content
  • success: For positive or completed actions
  • neutral: For general, non-emphasized content
  • danger: For errors or warnings requiring attention
  • caution: For cautionary information
'plain' | 'pending' | 'information' | 'success' | 'neutral' | 'caution' | 'danger''plain'
fillControls the lozenge's visual style. When true, the lozenge has a solid background color. When false, it has an outline style with a transparent background.booleanfalse
removableWhen true, the lozenge can be removed by the user (displays a remove icon).booleanfalse
urlURL for the avatar image to be displayed within the lozenge. If provided, an avatar will be shown at the beginning of the lozenge.string''
visibleControls the visibility of the lozenge. When false, the lozenge will not be rendered.booleantrue
loadingWhen true, displays a skeletal loading state instead of the actual content, indicating that data is being loaded.booleanfalse
iconName of an Iconify icon to be displayed as a prefix icon (before the label). Alternatively, use the icon slot for custom icons.string''
postfixIconName of an Iconify icon to be displayed as a postfix icon (after the label). Alternatively, use the postfixIcon slot for custom icons.string''
interactiveWhen true, the lozenge responds to user interactions with hover and active states, making it suitable for clickable elements.booleanfalse
dropdownWhen true, the lozenge behaves as a dropdown trigger with a default caret icon and interactive styling. This automatically sets interactive to true.booleanfalse

Events

NameDescriptionParameters
onRemoveEmitted when the remove button is clicked on a removable lozenge.(event: MouseEvent)

Slots

NameDescription
iconCustom content for the prefix icon area (displayed before the label). Use this slot to insert custom icons or components instead of using the icon prop.
avatarCustom content for the avatar area. Use this slot to insert a custom avatar component instead of using the url prop.
postfixIconCustom content for the postfix icon area (displayed after the label). Use this slot to insert custom icons or components instead of using the postfixIcon prop.

Product Uses

Sprout HR
Sprout Payroll
Sprout Ecosystem
Sprout Sidekick