IconNav icon
Horizontale of verticale navigatiebalk met icoon per item, actieve state en optionele badge. Secundaire nav of in-page tabbar.
src/components/icon/IconNav.astro
---
/**
* IconNav
* Horizontale of verticale navigatiebalk met icoon per item en optionele badge.
* Geschikt als secundaire nav, in-page tabbar of sidebar-menu.
*
* Props:
* - items: { icon?: string; label: string; href: string; active?: boolean; badge?: string }[]
* - orientation?: 'horizontal' | 'vertical' default 'horizontal'
* - ariaLabel?: string default 'Navigatie'
* - accentColor?: string default '#6366f1'
* - theme?: 'light' | 'dark' default 'light'
*/
interface Props {
items: { icon?: string; label: string; href: string; active?: boolean; badge?: string }[];
orientation?: 'horizontal' | 'vertical';
ariaLabel?: string;
accentColor?: string;
theme?: 'light' | 'dark';
}
const {
items,
orientation = 'horizontal',
ariaLabel = 'Navigatie',
accentColor = '#6366f1',
theme = 'light',
} = Astro.props;
---
<section class:list={['bl-section', 'inav-section', `inav-section--${theme}`]}>
<div class="bl-inner inav-inner" style={`--color-accent: ${accentColor}`}>
<nav
class:list={['inav', orientation === 'vertical' && 'inav--vertical']}
aria-label={ariaLabel}
>
{items.map(item => (
<a
class:list={['inav__item', item.active && 'inav__item--active']}
href={item.href}
aria-current={item.active ? 'page' : undefined}
>
{item.icon && <span class="inav__icon" aria-hidden="true">{item.icon}</span>}
<span class="inav__label">{item.label}</span>
{item.badge && <span class="inav__badge">{item.badge}</span>}
</a>
))}
</nav>
</div>
</section>
<style>
.inav-section--light { background: var(--color-bg, #fff); }
.inav-section--dark { background: #0a0a0a; }
.inav {
display: flex;
gap: .25rem;
flex-wrap: wrap;
}
.inav--vertical { flex-direction: column; }
.inav__item {
display: flex;
align-items: center;
gap: .6rem;
padding: .6rem 1rem;
border-radius: 8px;
text-decoration: none;
color: #6b7280;
font-size: .9375rem;
font-weight: 500;
transition: background .15s, color .15s;
position: relative;
}
.inav__item:hover {
background: #f5f5f5;
color: var(--color-primary, #0a0a0a);
}
.inav-section--dark .inav__item { color: #aaa; }
.inav-section--dark .inav__item:hover {
background: #1a1a1a;
color: #e8e8e8;
}
.inav__item--active {
background: color-mix(in srgb, var(--color-accent) 10%, transparent);
color: var(--color-accent);
font-weight: 700;
}
.inav__icon { font-size: 1.1rem; }
.inav__badge {
position: absolute;
top: .25rem;
right: .25rem;
background: var(--color-accent);
color: #fff;
font-size: .625rem;
font-weight: 700;
padding: .1rem .35rem;
border-radius: 10px;
text-transform: uppercase;
letter-spacing: .04em;
}
</style>
Props
| Prop | Type | Default | Beschrijving |
|---|---|---|---|
items * | { icon?: string; label: string; href: string; active?: boolean; badge?: string }[] | - | Navigatie-items |
orientation | 'horizontal' | 'vertical' | 'horizontal' | Richting van de navigatie |
ariaLabel | string | 'Navigatie' | Aria-label voor de nav |
accentColor | string | '#6366f1' | Kleur voor actieve items |
theme | 'light' | 'dark' | 'light' | Achtergrondmodus |
* = verplicht