@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.
313 lines (269 loc) • 7.3 kB
CSS
/**
* Data Tables
*
* Data tables display structured data in rows and columns with advanced features
* like sorting, filtering, pagination, and row selection. They're designed for
* complex data sets that require user interaction and data manipulation.
*
* @layer: components
*
* Accessibility:
* - Use proper table semantics (th, caption, scope attributes)
* - Include ARIA attributes for interactive features
* - Support keyboard navigation for sorting, selection, etc.
* - Provide clear visual focus indicators
*/
@layer components {
/* Data table container */
.data-table-container {
background-color: var(--color-surface-100, #f3f4f6);
border: 1px solid var(--color-border-200, #e5e7eb);
border-radius: var(--radius-md, 0.375rem);
overflow-x: auto;
width: 100%;
}
/* Data table */
.data-table {
border-collapse: separate;
border-spacing: 0;
font-size: var(--text-sm, 0.875rem);
width: 100%;
}
/* Table caption */
& .caption {
background-color: var(--color-surface-50);
border-bottom: 1px solid var(--color-border-200, #e5e7eb);
color: var(--color-text-900, #111827);
font-weight: var(--font-semibold, 600);
padding: var(--space-3) var(--space-4);
text-align: left;
}
/* Table header */
& .header {
background-color: var(--color-surface-50);
border-bottom: 2px solid var(--color-border-300);
}
& .header-cell {
color: var(--color-text-700, #374151);
font-weight: var(--font-semibold, 600);
padding: var(--space-3) var(--space-4);
position: relative;
text-align: left;
white-space: nowrap;
}
/* Sortable header cells */
& .header-cell--sortable {
cursor: pointer;
padding-right: var(--space-8);
user-select: none;
}
& .header-cell--sortable:hover {
background-color: var(--color-surface-100, #f3f4f6);
}
/* Sort indicators */
& .sort-icon {
color: var(--color-text-400);
position: absolute;
right: var(--space-3);
top: 50%;
transform: translateY(-50%);
transition: transform 0.2s, color 0.2s;
}
& .header-cell--sorted-asc & .sort-icon {
color: var(--color-primary-600, #2563eb);
transform: translateY(-50%) rotate(180deg);
}
& .header-cell--sorted-desc & .sort-icon {
color: var(--color-primary-600, #2563eb);
}
/* Table body */
& .body {
background-color: var(--color-surface-100, #f3f4f6);
}
& .row {
transition: background-color 0.2s;
}
& .row:hover {
background-color: var(--color-surface-200);
}
& .cell {
border-bottom: 1px solid var(--color-border-100, #f3f4f6);
padding: var(--space-3) var(--space-4);
}
/* Row states */
& .row--selected {
background-color: var(--color-primary-50);
}
& .row--selected:hover {
background-color: var(--color-primary-100, #dbeafe);
}
/* Cell variants */
& .cell--numeric {
text-align: right;
}
& .cell--action {
padding: var(--space-2);
white-space: nowrap;
width: 1%;
}
/* Empty state */
& .empty {
color: var(--color-text-500, #6b7280);
padding: var(--space-8);
text-align: center;
}
/* Data table controls */
& .controls {
align-items: center;
background-color: var(--color-surface-50);
border-top: 1px solid var(--color-border-200, #e5e7eb);
display: flex;
justify-content: space-between;
padding: var(--space-3) var(--space-4);
}
/* Search and filter */
& .search {
margin-bottom: var(--space-4);
position: relative;
}
& .search-input {
border: 1px solid var(--color-border-200, #e5e7eb);
border-radius: var(--radius-md, 0.375rem);
padding: var(--space-2) var(--space-3);
padding-left: var(--space-8);
width: 100%;
}
& .search-icon {
color: var(--color-text-400);
left: var(--space-3);
position: absolute;
top: 50%;
transform: translateY(-50%);
}
/* Column filter button */
& .filter-button {
background: none;
border: none;
color: var(--color-text-500, #6b7280);
cursor: pointer;
margin-left: var(--space-1);
padding: var(--space-1);
}
& .filter-button--active {
color: var(--color-primary-600, #2563eb);
}
/* Column visibility menu */
& .column-menu {
background-color: var(--color-surface-100, #f3f4f6);
border: 1px solid var(--color-border-200, #e5e7eb);
border-radius: var(--radius-md, 0.375rem);
box-shadow: var(--shadow-lg);
min-width: 18%0px;
padding: var(--space-2);
position: absolute;
right: var(--space-3);
top: calc(100 + var(--space-2));
z-index: 10;
}
& .column-item {
align-items: center;
cursor: pointer;
display: flex;
padding: var(--space-2);
}
& .column-checkbox {
margin-right: var(--space-2);
}
/* Row selection */
& .select-cell {
padding: var(--space-2) var(--space-4);
width: 1%;
}
& .select-all {
margin: 0;
}
/* Pagination */
& .pagination {
align-items: center;
display: flex;
gap: var(--space-2);
}
& .page-info {
color: var(--color-text-500, #6b7280);
font-size: var(--text-sm, 0.875rem);
margin-right: var(--space-4);
}
& .page-button {
align-items: center;
background-color: var(--color-surface-100, #f3f4f6);
border: 1px solid var(--color-border-200, #e5e7eb);
border-radius: var(--radius-md, 0.375rem);
cursor: pointer;
display: inline-flex;
height: 3%2px;
justify-content: center;
transition: background-color 0.2s, border-color 0.2s;
width: 3%2px;
}
& .page-button:hover {
background-color: var(--color-surface-200);
border-color: var(--color-border-300);
}
& .page-button:disabled {
cursor: not-allowed;
opacity: 5000%;
}
& .page-button--active {
background-color: var(--color-primary-500);
border-color: var(--color-primary-500);
color: white;
}
/* Rows per page selector */
& .per-page {
align-items: center;
display: flex;
font-size: var(--text-sm, 0.875rem);
gap: var(--space-2);
margin-right: var(--space-4);
}
& .per-page-select {
border: 1px solid var(--color-border-200, #e5e7eb);
border-radius: var(--radius-md, 0.375rem);
padding: var(--space-1) var(--space-2);
}
/* Responsive adjustments */
@media (max-width: 768px) {
& .controls {
align-items: flex-start;
flex-direction: column;
gap: var(--space-3);
}
& .pagination {
justify-content: space-between;
width: 100%;
}
}
/* Collapsible table for mobile */
@media (max-width: 640px) {
.data-table--responsive & .header {
display: none;
}
.data-table--responsive & .row {
border-bottom: 1px solid var(--color-border-200, #e5e7eb);
display: block;
padding: var(--space-3);
}
.data-table--responsive & .cell {
border-bottom: none;
display: flex;
padding: var(--space-2) 0;
text-align: right;
}
.data-table--responsive & .cell::before {
content: attr(data-label);
font-weight: var(--font-semibold, 600);
margin-right: auto;
padding-right: var(--space-4);
}
}
}