Zoeken...  ⌘K GitHub

Breadcrumb UI Elements

Navigatie broodkruimelpad. 3 separator stijlen. Aria-labeled, aria-current op huidig item.

/breadcrumb
src/components/ui/Breadcrumb.astro
---
/**
 * Breadcrumb
 * Toegankelijke paginanavigatie. 3 scheidingsteken-varianten.
 */
interface BreadcrumbItem {
  label: string;
  href?: string;
  icon?: string;
}

interface Props {
  items: BreadcrumbItem[];
  separator?: 'slash' | 'chevron' | 'dot';
  size?: 'sm' | 'md';
}

const {
  items = [],
  separator = 'chevron',
  size = 'md',
} = Astro.props;
---

<nav aria-label="Paginapad" class:list={['bc', `bc--${size}`]} data-component="breadcrumb">
  <ol class="bc__list">
    {items.map((item, i) => {
      const isLast = i === items.length - 1;
      return (
        <li class="bc__item">
          {i > 0 && (
            <span class="bc__sep" aria-hidden="true">
              {separator === 'chevron' && (
                <svg width="12" height="12" viewBox="0 0 12 12" fill="none">
                  <path d="M4 2l4 4-4 4" stroke="currentColor" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
                </svg>
              )}
              {separator === 'slash' && '/'}
              {separator === 'dot' && '·'}
            </span>
          )}

          {isLast ? (
            <span class="bc__current" aria-current="page">
              {item.icon && <span set:html={item.icon} aria-hidden="true" />}
              {item.label}
            </span>
          ) : (
            <a href={item.href ?? '#'} class="bc__link">
              {item.icon && <span set:html={item.icon} aria-hidden="true" />}
              {item.label}
            </a>
          )}
        </li>
      );
    })}
  </ol>
</nav>

<style>
  .bc__list {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0;
    padding: 0;
    margin: 0;
  }

  .bc__item {
    display: flex;
    align-items: center;
    gap: 0;
  }

  .bc__sep {
    display: flex;
    align-items: center;
    color: rgba(0,0,0,0.25);
    margin: 0 0.375rem;
    font-size: 0.75rem;
  }

  .bc__link, .bc__current {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.875rem;
    line-height: 1;
    transition: color 0.15s;
  }

  .bc--sm .bc__link,
  .bc--sm .bc__current { font-size: 0.8125rem; }

  .bc__link {
    color: var(--color-muted, #6b7280);
    text-decoration: none;
    font-weight: 500;
  }

  .bc__link:hover { color: var(--color-primary, #0a0a0a); }

  .bc__current {
    color: var(--color-primary, #0a0a0a);
    font-weight: 600;
  }
</style>

Props

Prop Type Default Beschrijving
items * { label: string; href?: string }[] Pad items — laatste is actief
separator 'chevron' | 'slash' | 'dot' 'chevron' Scheidingsteken variant

* = verplicht