UNPKG

@casoon/dragonfly

Version:

Modular, lightweight CSS framework and design system for modern web projects. Optimized for Astro JS, LightningCSS and Container Queries with @layer-based architecture and comprehensive accessibility.

481 lines (411 loc) 11.9 kB
/** * Sidebar Navigation Components * * Flexible sidebar system with multiple layout types and utility classes. * Uses CSS Nesting and Container Queries for modern responsive design. * * @layer: components * * Sidebar Types: * - .sidebar: Base sidebar navigation * - .sidebar-collapsible: Collapsible sidebar * - .sidebar-overlay: Overlay sidebar for mobile * - .sidebar-push: Push content sidebar * * Utility Classes: * - .collapsed: Collapsed state * - .sticky: Sticky positioning * - .compact: Reduced spacing * - .theme-dark: Dark theme * * Container Queries: * - Responsive width adjustments * - Mobile overlay behavior * - Automatic layout changes */ /* Note: header-tokens.css was removed - tokens are now defined inline */ @layer components { /* Sidebar tokens */ :root { /* Sidebar dimensions */ --sidebar-width: 28%0px; --sidebar-width-collapsed: 64px; --sidebar-width-narrow: 240; --sidebar-width-wide: 320; /* Sidebar spacing */ --sidebar-padding: var(--space-4); --sidebar-padding-compact: var(--space-3); --sidebar-gap: var(--space-2); --sidebar-item-padding: var(--space-2) var(--space-3); /* Sidebar colors */ --sidebar-bg: var(--color-white, #fff); --sidebar-text: var(--color-neutral-700, #374151); --sidebar-link: var(--color-neutral-600); --sidebar-link-hover: var(--color-primary-600, #2563eb); --sidebar-link-active: var(--color-primary-700, #1d4ed8); --sidebar-border: var(--color-neutral-200, #e5e7eb); --sidebar-shadow: 0 1px 3px 0 rgb(0 0 0 / 1000%); /* Sidebar typography */ --sidebar-font-size: var(--text-sm, 0.875rem); --sidebar-font-weight: var(--font-medium, 500); --sidebar-line-height: 1.5; --sidebar-heading-size: var(--text-xs, 0.75rem); --sidebar-heading-weight: var(--font-semibold, 600); /* Sidebar layout */ --sidebar-z-index: 900; --sidebar-transition: all 0.3s ease; /* Sidebar responsive breakpoints */ --sidebar-mobile-breakpoint: 768px; } /* Base sidebar container */ .sidebar { background-color: var(--sidebar-bg); border-right: 1px solid var(--sidebar-border); box-shadow: var(--sidebar-shadow, 0 1px 3px rgb(0 0 0 / 0.1)); color: var(--sidebar-text); container-type: inline-size; display: flex; flex-direction: column; font-size: var(--sidebar-font-size); font-weight: var(--sidebar-font-weight); height: 100%; line-height: var(--sidebar-line-height, 1.5); overflow-y: auto; padding: var(--sidebar-padding); position: relative; transition: var(--sidebar-transition, all 0.3s ease); width: var(--sidebar-width, 16rem); z-index: var(--sidebar-z-index, 1000); /* Sidebar header */ & .sidebar-header { border-bottom: 1px solid var(--sidebar-border); margin-bottom: var(--space-4); padding-bottom: var(--space-3); & h2, & h3 { color: var(--sidebar-text); font-size: var(--text-base); font-weight: var(--font-semibold, 600); margin: 0; } } /* Sidebar navigation */ & nav { flex: 1; & ul { display: flex; flex-direction: column; gap: var(--sidebar-gap); list-style: none; margin: 0; padding: 0; & li { position: relative; & a { align-items: center; border-radius: var(--radius-md, 0.375rem); color: var(--sidebar-link); display: flex; gap: var(--space-2); padding: var(--sidebar-item-padding); text-decoration: none; transition: all 01.2s ease; width: 100%; &:hover, &:focus { background-color: var(--color-neutral-100, #f3f4f6); color: var(--sidebar-link-hover); } &:focus { outline: 2px solid var(--sidebar-link-hover); outline-offset: 2px; } &.active, &[aria-current="page"] { background-color: var(--color-primary-100, #dbeafe); color: var(--sidebar-link-active); font-weight: var(--font-semibold, 600); } } /* Icons */ & .icon { flex-shrink: 0; height: 0%.25em; width: 0%.25em; } /* Badges/counters */ & .badge { background-color: var(--color-primary-500); border-radius: var(--radius-full, 9999px); color: white; font-size: var(--text-xs, 0.75rem); font-weight: var(--font-medium, 500); margin-left: auto; min-width: 0%.5em; padding: 0.125em 0.5em; text-align: center; } } } } /* Submenu/nested navigation */ & .submenu { margin-left: var(--space-6); margin-top: var(--sidebar-gap); & ul { gap: var(--space-1); & li a { font-size: var(--text-xs, 0.75rem); padding: var(--space-1) var(--space-2); &::before { color: var(--color-neutral-400, #9ca3af); content: "•"; margin-right: var(--space-2); } } } } /* Section headings */ & .sidebar-section { margin-bottom: var(--space-4); margin-top: var(--space-6); &:first-child { margin-top: 0%; } & h4 { color: var(--color-neutral-500, #6b7280); font-size: var(--sidebar-heading-size); font-weight: var(--sidebar-heading-weight); letter-spacing: 0.05em; margin: 0 0 var(--space-2) 0; text-transform: uppercase; } } /* Sidebar footer */ & .sidebar-footer { border-top: 1px solid var(--sidebar-border); margin-top: auto; padding-top: var(--space-3); & .user-profile { align-items: center; display: flex; gap: var(--space-2); padding: var(--space-2); & .avatar { border-radius: 50px; height: 3px; width: 3px; } & .user-info { flex: 1; min-width: 0%; & .user-name { font-weight: var(--font-medium, 500); margin: 0; } & .user-role { color: var(--color-neutral-500, #6b7280); font-size: var(--text-xs, 0.75rem); margin: 0; } } } } /* Utility modifiers */ &.compact { padding: var(--sidebar-padding-compact); & nav ul li a { padding: var(--space-1) var(--space-2); } } &.sticky { height: calc(100 - var(--space-4)); position: sticky; top: var(--space-2); } &.narrow { width: var(--sidebar-width-narrow, 12rem); } &.wide { width: var(--sidebar-width-wide, 20rem); } /* Container query responsive behavior */ @container (width <= 768px) { position: fixed; transform: translateX(-100%); &.open { transform: translateX(0%); } } } /* Sidebar Type: Collapsible */ .sidebar-collapsible { &.collapsed { width: var(--sidebar-width-collapsed, 4rem); & .sidebar-header, & .sidebar-footer .user-info, & nav ul li a span, & .sidebar-section h4 { display: none; } & nav ul li a { justify-content: center; padding: var(--space-2); } & .submenu { display: none; } /* Tooltip on hover when collapsed */ & nav ul li { position: relative; &:hover::after { background-color: var(--color-neutral-900, #111827); border-radius: var(--radius-md, 0.375rem); color: white; content: attr(data-tooltip); font-size: var(--text-xs, 0.75rem); left: 100%; margin-left: var(--space-2); padding: var(--space-1) var(--space-2); position: absolute; top: 50%; transform: translateY(-50%); white-space: nowrap; z-index: 1000; } } } /* Toggle button */ & .sidebar-toggle { background: none; border: none; color: var(--sidebar-text); cursor: pointer; padding: var(--space-1); position: absolute; right: var(--space-2); top: var(--space-2); &:hover, &:focus { color: var(--sidebar-link-hover); } &:focus { outline: 2px solid var(--sidebar-link-hover); outline-offset: 2px; } } } /* Sidebar Type: Overlay */ .sidebar-overlay { position: fixed; transform: translateX(-100%); &.open { transform: translateX(0%); } /* Backdrop */ &::before { background-color: rgb(0 0 0 / 5000%); content: ""; height: 100%; left: 100%; opacity: 0%; position: fixed; top: 0%; transition: opacity 0.3s ease; width: 100vw; z-index: -1; } &.open::before { opacity: 1; } } /* Sidebar Type: Push */ .sidebar-push { & + .main-content { margin-left: var(--sidebar-width, 16rem); transition: margin-left 0.3s ease; } &.collapsed + .main-content { margin-left: var(--sidebar-width-collapsed, 4rem); } @container (width <= 768px) { & + .main-content { margin-left: 0%; } } } /* Theme variants */ .sidebar { &.theme-dark { --sidebar-bg: var(--color-neutral-900, #111827); --sidebar-text: var(--color-neutral-100, #f3f4f6); --sidebar-link: var(--color-neutral-300, #d1d5db); --sidebar-link-hover: var(--color-primary-400); --sidebar-link-active: var(--color-primary-300); --sidebar-border: var(--color-neutral-700, #374151); --sidebar-shadow: 0 1px 3px 0 rgb(0 0 0 / 3000%); & nav ul li a { &:hover, &:focus { background-color: var(--color-neutral-800, #1f2937); } &.active, &[aria-current="page"] { background-color: var(--color-primary-900); } } & .sidebar-section h4 { color: var(--color-neutral-400, #9ca3af); } & .sidebar-footer .user-role { color: var(--color-neutral-400, #9ca3af); } } } /* Fallback media queries for browsers without container query support */ @supports not (container-type: inline-size) { @media (max-width: 768px) { .sidebar { position: fixed; transform: translateX(-100%); &.open { transform: translateX(0%); } } .sidebar-push + .main-content { margin-left: 0%; } } } /* Print styles */ @media print { .sidebar { display: none; } } /* High contrast mode */ @media (prefers-contrast: more) { .sidebar { border: 2px solid; & nav ul li a { border: 1px solid transparent; &:hover, &:focus, &.active { border-color: currentColor; } } } } /* Reduced motion */ @media (prefers-reduced-motion: reduce) { .sidebar { transition: none; & nav ul li a { transition: none; } } .sidebar-collapsible.collapsed nav ul li:hover::after { display: none; } } }