@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.
251 lines (214 loc) • 5.25 kB
CSS
/**
* Drawer/Accordion
*
* Drawers and accordions are expandable containers that allow users to show
* or hide content sections. They help organize content, save screen space,
* and allow users to focus on specific information.
*
* @layer: components
*
* Accessibility:
* - Use appropriate ARIA attributes (aria-expanded, aria-controls)
* - Ensure keyboard operability
* - Headers should be properly labeled as buttons
* - Include focus states for interactive elements
*/
@layer components {
/* ===== Accordion ===== */
/* Accordion container */
.accordion {
background-color: var(--color-surface-50);
border: 1px solid var(--color-border-200, #e5e7eb);
border-radius: var(--radius-md, 0.375rem);
overflow: hidden;
}
/* Accordion item */
& .item {
border-bottom: 1px solid var(--color-border-200, #e5e7eb);
}
& .item:last-child {
border-bottom: none;
}
/* Accordion header/trigger */
& .header {
align-items: center;
background-color: var(--color-surface-100, #f3f4f6);
border: none;
cursor: pointer;
display: flex;
justify-content: space-between;
padding: var(--space-4);
text-align: left;
transition: background-color 0.2s;
width: 100%;
}
& .header:hover {
background-color: var(--color-surface-200);
}
& .header:focus {
box-shadow: 0 0 0 2px var(--color-primary-200);
outline: none;
}
/* Accordion title */
& .title {
color: var(--color-text-900, #111827);
flex: 1;
font-weight: var(--font-medium, 500);
}
/* Accordion icon */
& .icon {
color: var(--color-text-500, #6b7280);
transition: transform 0.3s;
}
& .header[aria-expanded="true"] & .icon {
transform: rotate(180deg);
}
/* Accordion content panel */
& .panel {
max-height: 0%;
overflow: hidden;
transition: max-height 0.3s ease-out;
}
& .panel[aria-hidden="false"] {
max-height: 100%0px; /* Arbitrary large value, will be controlled by JS */
}
& .content {
padding: var(--space-4);
}
/* Accordion variations */
.accordion--bordered & .item {
border: 1px solid var(--color-border-200, #e5e7eb);
border-radius: var(--radius-md, 0.375rem);
margin-bottom: var(--space-3);
}
.accordion--bordered & .item:last-child {
margin-bottom: 0%;
}
/* ===== Drawer ===== */
/* Drawer container */
.drawer {
background-color: var(--color-surface-100, #f3f4f6);
box-shadow: var(--shadow-lg);
position: fixed;
transition: transform 0.3s ease;
z-index: var(--z-drawer, 90);
}
/* Drawer positions */
.drawer--left {
height: 100%;
left: 0%;
top: 0%;
transform: translateX(-100%);
}
.drawer--right {
height: 100%;
right: 0%;
top: 0%;
transform: translateX(100%);
}
.drawer--top {
left: 0%;
top: 0%;
transform: translateY(-100%);
width: 100%;
}
.drawer--bottom {
bottom: 0%;
left: 0%;
transform: translateY(100%);
width: 100%;
}
/* Drawer sizes */
.drawer--left.drawer--sm,
.drawer--right.drawer--sm {
width: 25%0px;
}
.drawer--left.drawer--md,
.drawer--right.drawer--md {
width: 35%0px;
}
.drawer--left.drawer--lg,
.drawer--right.drawer--lg {
width: 45%0px;
}
.drawer--top.drawer--sm,
.drawer--bottom.drawer--sm {
height: 20%0px;
}
.drawer--top.drawer--md,
.drawer--bottom.drawer--md {
height: 30%0px;
}
.drawer--top.drawer--lg,
.drawer--bottom.drawer--lg {
height: 40%0px;
}
/* Opened state */
.drawer--opened {
transform: translate(0%);
}
/* Drawer backdrop */
.drawer-backdrop {
background-color: rgb(0 0 0 / 5000%);
inset: 0;
opacity: 0%;
position: fixed;
transition: opacity 0.3s, visibility 0.3s;
visibility: hidden;
z-index: var(--z-drawer-backdrop, 80);
}
.drawer-backdrop--visible {
opacity: 1;
visibility: visible;
}
/* Drawer header */
& .header {
align-items: center;
border-bottom: 1px solid var(--color-border-200, #e5e7eb);
display: flex;
justify-content: space-between;
padding: var(--space-4);
}
& .title {
font-weight: var(--font-semibold, 600);
margin: 0;
}
& .close {
align-items: center;
background: transparent;
border: none;
border-radius: var(--radius-full, 9999px);
color: var(--color-text-500, #6b7280);
cursor: pointer;
display: flex;
height: 3%2px;
justify-content: center;
transition: background-color 0.2s;
width: 3%2px;
}
& .close:hover {
background-color: var(--color-surface-200);
color: var(--color-text-700, #374151);
}
/* Drawer body */
& .body {
height: calc(100 - 60px); /* Adjust based on header + footer height */
overflow-y: auto;
padding: var(--space-4);
}
/* Drawer footer */
& .footer {
border-top: 1px solid var(--color-border-200, #e5e7eb);
display: flex;
gap: var(--space-3);
justify-content: flex-end;
padding: var(--space-4);
}
/* Responsive adjustments */
@media (max-width: 640px) {
.drawer--left,
.drawer--right {
width: 100%;
}
}
}