Components

Breadcrumbs

Allow your users to navigate easily in your app.

Source Code

Copy the following code into your project.

<template>
  <div class="flex w-full items-center gap-4">
    <template v-for="(item, i) in items" :key="i">
      <div class="flex items-center gap-3">
        <div class="flex cursor-pointer items-center gap-2">
          <slot name="crumbIcon" :item="item" :index="i">
            <Icon
              v-if="item.icon"
              :name="item.icon"
              :class="[!isNotLastItem(i) && 'text-primary']"
            />
          </slot>
          <slot :item="item" :isNotLastItem="isNotLastItem" :index="i" name="link">
            <NuxtLink
              @click="item?.click?.()"
              :to="!item?.disabled ? item.link : ''"
              :class="[
                isNotLastItem(i)
                  ? 'text-muted-foreground hover:underline'
                  : 'font-semibold text-primary',
              ]"
              class="text-sm text-foreground"
              v-if="item.label"
              >{{ item.label }}</NuxtLink
            >
          </slot>
        </div>
        <slot name="separator" :item="item" :index="i">
          <Icon v-if="isNotLastItem(i)" :name="separator" class="h-3 w-3 text-muted-foreground" />
        </slot>
      </div>
    </template>
  </div>
</template>

<script setup lang="ts">
  export interface Crumbs {
    label: string;
    icon?: string;
    link?: string;
    disabled?: boolean;
    click?: Function;
  }
  const props = withDefaults(
    defineProps<{
      /**
       * The items to display in the breadcrumbs.
       */
      items?: Crumbs[];
      /**
       * The separator to use between each breadcrumb.
       */
      separator?: string;
    }>(),
    {
      separator: "heroicons:chevron-right",
      items: () => [],
    }
  );

  const isNotLastItem = (index: number) => {
    return index !== props?.items?.length - 1;
  };
</script>