Button, Input, Select, Badge, SeverityBadge, Table, Card, Modal, Tooltip, Tabs, Skeleton, EmptyState -- a shared library so pages stop hand-rolling markup per page (web/src/lib/components/ui, barrel export in index.ts). Modal and CommandPalette are built on native <dialog> for a real focus trap, Escape-to-close, and top-layer stacking instead of hand-rolling those. Tabs uses roving tabindex with arrow-key nav. NavSidebar replaces the old top-nav with a persistent sidebar (Search/Dashboards/Alerts/Data Sources/Settings), a live tenant indicator (api.ts's new getCurrentSession(), a client for the already-existing POST /internal/authorize -- zero new backend surface), theme/density quick-toggles, and a command-palette hint. Collapses to an off-canvas drawer under 860px. CommandPalette (Cmd/Ctrl+K) indexes the five static destinations plus live-fetched dashboards/alert rules. Data Sources is a new, honestly-scoped placeholder page (one data source per tenant today, no UI needed yet). Settings and Select-tenant are re-tokened onto the new component library. +layout.svelte's content wrapper is a plain <div>, not a second <main> -- every page already renders its own top-level <main>.
53 lines
1.4 KiB
Svelte
53 lines
1.4 KiB
Svelte
<script lang="ts">
|
|
import type { Snippet } from 'svelte';
|
|
|
|
// A thin styling wrapper, not a data grid -- real <table> markup
|
|
// underneath (native semantics matter for screen readers), density-
|
|
// aware row height/padding from tokens.css's --row-* variables.
|
|
// Column sort/resize (task 6) layers on top of this later; this just
|
|
// establishes the shared chrome every table in the app should share.
|
|
let { children }: { children: Snippet } = $props();
|
|
</script>
|
|
|
|
<div class="scroll">
|
|
<table class="ui-table">
|
|
{@render children()}
|
|
</table>
|
|
</div>
|
|
|
|
<style>
|
|
.scroll {
|
|
overflow-x: auto;
|
|
}
|
|
table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
font-family: var(--font-mono);
|
|
font-size: var(--text-base);
|
|
}
|
|
:global(.ui-table thead th) {
|
|
text-align: left;
|
|
font-family: var(--font-ui);
|
|
font-size: var(--text-xs);
|
|
font-weight: var(--font-weight-medium);
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.04em;
|
|
color: var(--color-text-muted);
|
|
padding: var(--space-2) var(--row-padding-x);
|
|
border-bottom: 1px solid var(--color-border);
|
|
white-space: nowrap;
|
|
}
|
|
:global(.ui-table tbody td) {
|
|
padding: var(--row-padding-y) var(--row-padding-x);
|
|
border-bottom: 1px solid var(--color-border);
|
|
color: var(--color-text);
|
|
vertical-align: middle;
|
|
}
|
|
:global(.ui-table tbody tr:last-child td) {
|
|
border-bottom: none;
|
|
}
|
|
:global(.ui-table tbody tr:hover td) {
|
|
background: var(--color-surface-raised);
|
|
}
|
|
</style>
|