Add permanent table index rail layout
This commit is contained in:
@@ -62,6 +62,7 @@ It is intentionally implementation-focused:
|
|||||||
| 2026-03-21 | Post-P2 fix 2 | Completed | Rebuilt the shell omnibox as a dedicated command palette instead of a repurposed drawer, with shell-owned overlay markup, explicit viewport-safe geometry, autofocus, Escape and navigation close behavior, and a stable scrollable result body. |
|
| 2026-03-21 | Post-P2 fix 2 | Completed | Rebuilt the shell omnibox as a dedicated command palette instead of a repurposed drawer, with shell-owned overlay markup, explicit viewport-safe geometry, autofocus, Escape and navigation close behavior, and a stable scrollable result body. |
|
||||||
| 2026-03-21 | Post-P2 fix 3 | Completed | Moved omnibox overlay ownership from the header subtree into `AppShell` itself via a shared omnibox state service and a top-level palette host, which restored full-screen backdrop coverage and reliable outside-click close behavior. |
|
| 2026-03-21 | Post-P2 fix 3 | Completed | Moved omnibox overlay ownership from the header subtree into `AppShell` itself via a shared omnibox state service and a top-level palette host, which restored full-screen backdrop coverage and reliable outside-click close behavior. |
|
||||||
| 2026-03-21 | P3.1 | Completed | Split `Tables.razor` into focused table components for the selector header, context bar, canvas, and legend while leaving loading, deep-link synchronization, and dialog state in the page host. |
|
| 2026-03-21 | P3.1 | Completed | Split `Tables.razor` into focused table components for the selector header, context bar, canvas, and legend while leaving loading, deep-link synchronization, and dialog state in the page host. |
|
||||||
|
| 2026-03-21 | P3.2 | Completed | Replaced the floating table picker with a permanent left-rail layout, converted the old selector component into a real page header, and kept the current selection flow intact inside the new reference frame. |
|
||||||
|
|
||||||
### Lessons Learned
|
### Lessons Learned
|
||||||
|
|
||||||
@@ -93,6 +94,7 @@ It is intentionally implementation-focused:
|
|||||||
- A command palette is not just a styled drawer. It needs shell-owned geometry, predictable focus behavior, and a bounded scroll region; treating it as a generic side panel led directly to the layout regressions found in Phase 2.
|
- A command palette is not just a styled drawer. It needs shell-owned geometry, predictable focus behavior, and a bounded scroll region; treating it as a generic side panel led directly to the layout regressions found in Phase 2.
|
||||||
- Backdrop and outside-click behavior depend on overlay ownership as much as CSS. If the trigger owns the overlay inside a sticky header subtree, fixed-position assumptions can break; shell-level overlays should be rendered by the shell, not by individual header controls.
|
- Backdrop and outside-click behavior depend on overlay ownership as much as CSS. If the trigger owns the overlay inside a sticky header subtree, fixed-position assumptions can break; shell-level overlays should be rendered by the shell, not by individual header controls.
|
||||||
- The `Tables` rewrite is safer when orchestration and rendering are separated early. Keeping loading, persistence, and dialog state in the page host while extracting render-only components makes later layout and interaction changes much lower risk.
|
- The `Tables` rewrite is safer when orchestration and rendering are separated early. Keeping loading, persistence, and dialog state in the page host while extracting render-only components makes later layout and interaction changes much lower risk.
|
||||||
|
- The `Tables` navigation model needs its own persistent geometry before advanced behaviors land. Converting the selector to a real rail first keeps later search and keyboard work from being tangled up with another structural rewrite.
|
||||||
|
|
||||||
## Target Outcomes
|
## Target Outcomes
|
||||||
|
|
||||||
@@ -454,7 +456,7 @@ Build the shared interaction infrastructure needed by multiple destinations befo
|
|||||||
| Task | Status | Notes |
|
| Task | Status | Notes |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `P3.1` | Completed | `Tables.razor` now acts as the stateful host while selector/header/canvas/legend rendering lives in dedicated `Components/Tables` components. |
|
| `P3.1` | Completed | `Tables.razor` now acts as the stateful host while selector/header/canvas/legend rendering lives in dedicated `Components/Tables` components. |
|
||||||
| `P3.2` | Pending | Replace the selector dropdown shell with the permanent left rail layout. |
|
| `P3.2` | Completed | The old dropdown picker is gone; `/tables` now uses a permanent left rail and a real page header while keeping the current selection flow intact. |
|
||||||
| `P3.3` | Pending | Add search, keyboard navigation, pinned/recent sections, curated percentage chips, and family filtering to the rail. |
|
| `P3.3` | Pending | Add search, keyboard navigation, pinned/recent sections, curated percentage chips, and family filtering to the rail. |
|
||||||
| `P3.4` | Pending | Introduce the sticky context bar with roll jump and mode/filter controls. |
|
| `P3.4` | Pending | Introduce the sticky context bar with roll jump and mode/filter controls. |
|
||||||
| `P3.5` | Pending | Rework the canvas for sticky headers, sticky roll bands, stronger reading emphasis, and density control. |
|
| `P3.5` | Pending | Rework the canvas for sticky headers, sticky roll bands, stronger reading emphasis, and density control. |
|
||||||
|
|||||||
@@ -11,16 +11,7 @@
|
|||||||
<PageTitle>Critical Tables</PageTitle>
|
<PageTitle>Critical Tables</PageTitle>
|
||||||
|
|
||||||
<section class="panel tables-page">
|
<section class="panel tables-page">
|
||||||
<TablesPageHeader
|
<TablesPageHeader />
|
||||||
ReferenceData="referenceData"
|
|
||||||
SelectedTableReference="SelectedTableReference"
|
|
||||||
SelectedTableSlug="selectedTableSlug"
|
|
||||||
IsTableMenuOpen="isTableMenuOpen"
|
|
||||||
IsTableSelectionDisabled="IsTableSelectionDisabled"
|
|
||||||
IsPinned="PinnedTablesState.IsPinned"
|
|
||||||
OnToggleTableMenu="ToggleTableMenu"
|
|
||||||
OnCloseTableMenu="CloseTableMenu"
|
|
||||||
OnSelectTable="SelectTableAsync" />
|
|
||||||
|
|
||||||
@if (referenceData is null)
|
@if (referenceData is null)
|
||||||
{
|
{
|
||||||
@@ -30,34 +21,49 @@
|
|||||||
{
|
{
|
||||||
<p class="muted">No critical tables are available yet.</p>
|
<p class="muted">No critical tables are available yet.</p>
|
||||||
}
|
}
|
||||||
else if (!hasResolvedStoredTableSelection)
|
else
|
||||||
{
|
{
|
||||||
<p class="muted">Restoring table context...</p>
|
<div class="tables-reference-layout">
|
||||||
}
|
<aside class="tables-reference-rail">
|
||||||
else if (isDetailLoading)
|
<TablesIndexRail
|
||||||
{
|
Tables="referenceData.CriticalTables"
|
||||||
<p class="muted">Loading the selected table...</p>
|
SelectedTableSlug="selectedTableSlug"
|
||||||
}
|
IsPinned="PinnedTablesState.IsPinned"
|
||||||
else if (!string.IsNullOrWhiteSpace(detailError))
|
OnSelectTable="SelectTableAsync" />
|
||||||
{
|
</aside>
|
||||||
<p class="error-text">@detailError</p>
|
|
||||||
}
|
|
||||||
else if (tableDetail is null)
|
|
||||||
{
|
|
||||||
<p class="muted">The selected table could not be loaded.</p>
|
|
||||||
}
|
|
||||||
else if (tableDetail is { } detail)
|
|
||||||
{
|
|
||||||
<div class="table-shell">
|
|
||||||
<TablesContextBar
|
|
||||||
Detail="detail"
|
|
||||||
IsPinned="PinnedTablesState.IsPinned(detail.Slug)"
|
|
||||||
OnTogglePin="TogglePinnedTableAsync" />
|
|
||||||
|
|
||||||
<TablesCanvas
|
<div class="tables-reference-main">
|
||||||
Detail="detail"
|
@if (!hasResolvedStoredTableSelection)
|
||||||
OnOpenCuration="OpenCellCurationAsync"
|
{
|
||||||
OnOpenEditor="OpenCellEditorAsync" />
|
<p class="muted">Restoring table context...</p>
|
||||||
|
}
|
||||||
|
else if (isDetailLoading)
|
||||||
|
{
|
||||||
|
<p class="muted">Loading the selected table...</p>
|
||||||
|
}
|
||||||
|
else if (!string.IsNullOrWhiteSpace(detailError))
|
||||||
|
{
|
||||||
|
<p class="error-text">@detailError</p>
|
||||||
|
}
|
||||||
|
else if (tableDetail is null)
|
||||||
|
{
|
||||||
|
<p class="muted">The selected table could not be loaded.</p>
|
||||||
|
}
|
||||||
|
else if (tableDetail is { } detail)
|
||||||
|
{
|
||||||
|
<div class="table-shell">
|
||||||
|
<TablesContextBar
|
||||||
|
Detail="detail"
|
||||||
|
IsPinned="PinnedTablesState.IsPinned(detail.Slug)"
|
||||||
|
OnTogglePin="TogglePinnedTableAsync" />
|
||||||
|
|
||||||
|
<TablesCanvas
|
||||||
|
Detail="detail"
|
||||||
|
OnOpenCuration="OpenCellCurationAsync"
|
||||||
|
OnOpenEditor="OpenCellEditorAsync" />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</section>
|
</section>
|
||||||
@@ -127,7 +133,6 @@
|
|||||||
private string? curationQuickParseError;
|
private string? curationQuickParseError;
|
||||||
private int? curatingResultId;
|
private int? curatingResultId;
|
||||||
private CriticalCellEditorModel? curationModel;
|
private CriticalCellEditorModel? curationModel;
|
||||||
private bool isTableMenuOpen;
|
|
||||||
private bool hasResolvedStoredTableSelection;
|
private bool hasResolvedStoredTableSelection;
|
||||||
private CriticalTableReference? SelectedTableReference =>
|
private CriticalTableReference? SelectedTableReference =>
|
||||||
referenceData?.CriticalTables.FirstOrDefault(item => string.Equals(item.Key, selectedTableSlug, StringComparison.OrdinalIgnoreCase));
|
referenceData?.CriticalTables.FirstOrDefault(item => string.Equals(item.Key, selectedTableSlug, StringComparison.OrdinalIgnoreCase));
|
||||||
@@ -138,25 +143,9 @@
|
|||||||
isReferenceDataLoading = false;
|
isReferenceDataLoading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ToggleTableMenu()
|
|
||||||
{
|
|
||||||
if (IsTableSelectionDisabled)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
isTableMenuOpen = !isTableMenuOpen;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CloseTableMenu()
|
|
||||||
{
|
|
||||||
isTableMenuOpen = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SelectTableAsync(string tableSlug)
|
private async Task SelectTableAsync(string tableSlug)
|
||||||
{
|
{
|
||||||
selectedTableSlug = tableSlug;
|
selectedTableSlug = tableSlug;
|
||||||
isTableMenuOpen = false;
|
|
||||||
await LoadTableDetailAsync();
|
await LoadTableDetailAsync();
|
||||||
await PersistAndSyncTableContextAsync();
|
await PersistAndSyncTableContextAsync();
|
||||||
}
|
}
|
||||||
|
|||||||
59
src/RolemasterDb.App/Components/Tables/TablesIndexRail.razor
Normal file
59
src/RolemasterDb.App/Components/Tables/TablesIndexRail.razor
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<section class="tables-index-rail" aria-labelledby="tables-index-heading">
|
||||||
|
<div class="tables-index-rail-header">
|
||||||
|
<h2 id="tables-index-heading" class="tables-index-title">Table Index</h2>
|
||||||
|
<p class="tables-index-copy">Choose a table, then read from the roll band across to the result you need.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tables-index-list" role="listbox" aria-label="Critical tables">
|
||||||
|
@foreach (var table in Tables)
|
||||||
|
{
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
role="option"
|
||||||
|
aria-selected="@string.Equals(table.Key, SelectedTableSlug, StringComparison.OrdinalIgnoreCase)"
|
||||||
|
class="table-index-option @GetTableOptionCssClass(table)"
|
||||||
|
@onclick="() => OnSelectTable.InvokeAsync(table.Key)">
|
||||||
|
<span class="table-index-option-copy">
|
||||||
|
<strong class="table-index-option-title">@table.Label</strong>
|
||||||
|
<span class="table-index-option-meta">@table.Family</span>
|
||||||
|
</span>
|
||||||
|
<span class="table-index-option-chips">
|
||||||
|
@if (GetIsPinned(table.Key))
|
||||||
|
{
|
||||||
|
<StatusChip Tone="accent">Pinned</StatusChip>
|
||||||
|
}
|
||||||
|
<span class="chip">@($"{table.CurationPercentage}%")</span>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[Parameter]
|
||||||
|
public IReadOnlyList<CriticalTableReference> Tables { get; set; } = Array.Empty<CriticalTableReference>();
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string SelectedTableSlug { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public Func<string, bool>? IsPinned { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public EventCallback<string> OnSelectTable { get; set; }
|
||||||
|
|
||||||
|
private bool GetIsPinned(string tableSlug) => IsPinned?.Invoke(tableSlug) ?? false;
|
||||||
|
|
||||||
|
private string GetTableOptionCssClass(CriticalTableReference table)
|
||||||
|
{
|
||||||
|
var classes = new List<string>();
|
||||||
|
|
||||||
|
if (string.Equals(table.Key, SelectedTableSlug, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
classes.Add("is-selected");
|
||||||
|
}
|
||||||
|
|
||||||
|
classes.Add(table.CurationPercentage >= 100 ? "is-curated" : "needs-curation");
|
||||||
|
return string.Join(' ', classes);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,105 +1,7 @@
|
|||||||
<div class="table-browser-toolbar">
|
<header class="tables-page-header">
|
||||||
<div class="table-selector">
|
<div class="tables-page-header-copy">
|
||||||
<label id="critical-table-selector-label">Table</label>
|
<p class="tables-page-eyebrow">Reference</p>
|
||||||
<div class="table-select-shell">
|
<h1 class="panel-title">Critical Tables</h1>
|
||||||
<button
|
<p class="tables-page-intro">Browse the index, open a table, and read the result directly from the grid without leaving the page.</p>
|
||||||
type="button"
|
|
||||||
class="input-shell table-select-trigger"
|
|
||||||
aria-haspopup="listbox"
|
|
||||||
aria-expanded="@IsTableMenuOpen"
|
|
||||||
aria-labelledby="critical-table-selector-label critical-table-selector-value"
|
|
||||||
@onclick="() => OnToggleTableMenu.InvokeAsync()"
|
|
||||||
disabled="@IsTableSelectionDisabled">
|
|
||||||
<span class="table-select-trigger-copy">
|
|
||||||
<span id="critical-table-selector-value" class="table-select-trigger-title">@GetSelectedTableLabel()</span>
|
|
||||||
</span>
|
|
||||||
@if (SelectedTableReference is { } selected)
|
|
||||||
{
|
|
||||||
<span class="table-select-trigger-chips">
|
|
||||||
@if (GetIsPinned(selected.Key))
|
|
||||||
{
|
|
||||||
<StatusChip Tone="accent">Pinned</StatusChip>
|
|
||||||
}
|
|
||||||
<span class="chip">@($"{selected.CurationPercentage}%")</span>
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
@if (IsTableMenuOpen && ReferenceData is not null)
|
|
||||||
{
|
|
||||||
<button type="button" class="table-selector-backdrop" @onclick="() => OnCloseTableMenu.InvokeAsync()" aria-label="Close table selector"></button>
|
|
||||||
|
|
||||||
<div class="table-select-menu" role="listbox" aria-labelledby="critical-table-selector-label">
|
|
||||||
@foreach (var table in ReferenceData.CriticalTables)
|
|
||||||
{
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
role="option"
|
|
||||||
aria-selected="@string.Equals(table.Key, SelectedTableSlug, StringComparison.OrdinalIgnoreCase)"
|
|
||||||
class="table-select-option @GetTableOptionCssClass(table)"
|
|
||||||
@onclick="() => OnSelectTable.InvokeAsync(table.Key)">
|
|
||||||
<span class="table-select-option-main">
|
|
||||||
<strong class="table-select-option-title">@table.Label</strong>
|
|
||||||
</span>
|
|
||||||
<span class="table-select-option-chips">
|
|
||||||
@if (GetIsPinned(table.Key))
|
|
||||||
{
|
|
||||||
<StatusChip Tone="accent">Pinned</StatusChip>
|
|
||||||
}
|
|
||||||
<span class="chip">@($"{table.CurationPercentage}%")</span>
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</header>
|
||||||
<p class="table-browser-toolbar-copy">Choose a table, then read from the roll band on the left across to the result you need.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
[Parameter]
|
|
||||||
public LookupReferenceData? ReferenceData { get; set; }
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public CriticalTableReference? SelectedTableReference { get; set; }
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public string SelectedTableSlug { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public bool IsTableMenuOpen { get; set; }
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public bool IsTableSelectionDisabled { get; set; }
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public Func<string, bool>? IsPinned { get; set; }
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public EventCallback OnToggleTableMenu { get; set; }
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public EventCallback OnCloseTableMenu { get; set; }
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public EventCallback<string> OnSelectTable { get; set; }
|
|
||||||
|
|
||||||
private bool GetIsPinned(string tableSlug) => IsPinned?.Invoke(tableSlug) ?? false;
|
|
||||||
|
|
||||||
private string GetSelectedTableLabel() => SelectedTableReference?.Label ?? "Select a table";
|
|
||||||
|
|
||||||
private string GetTableOptionCssClass(CriticalTableReference table)
|
|
||||||
{
|
|
||||||
var classes = new List<string>();
|
|
||||||
|
|
||||||
if (string.Equals(table.Key, SelectedTableSlug, StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
classes.Add("is-selected");
|
|
||||||
}
|
|
||||||
|
|
||||||
classes.Add(table.CurationPercentage >= 100 ? "is-curated" : "needs-curation");
|
|
||||||
return string.Join(' ', classes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1115,150 +1115,148 @@ pre,
|
|||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-browser-toolbar {
|
.tables-page-header {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 0.85rem;
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-selector {
|
.tables-page-header-copy {
|
||||||
display: flex;
|
display: grid;
|
||||||
flex-direction: column;
|
gap: 0.35rem;
|
||||||
|
max-width: 52rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tables-page-eyebrow {
|
||||||
|
margin: 0;
|
||||||
|
color: var(--accent-strong);
|
||||||
|
font-family: var(--font-ui);
|
||||||
|
font-size: 0.82rem;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.12em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tables-page-intro,
|
||||||
|
.tables-index-copy,
|
||||||
|
.table-browser-reading-hint,
|
||||||
|
.table-browser-edit-hint {
|
||||||
|
margin: 0;
|
||||||
|
color: var(--ink-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tables-reference-layout {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(17rem, 20rem) minmax(0, 1fr);
|
||||||
|
gap: 1rem;
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tables-reference-rail {
|
||||||
|
position: sticky;
|
||||||
|
top: calc(var(--shell-header-height) + 1rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tables-index-rail {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.85rem;
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: 18px;
|
||||||
|
background: var(--surface-card-subtle);
|
||||||
|
border: 1px solid rgba(127, 96, 55, 0.16);
|
||||||
|
box-shadow: 0 16px 26px rgba(41, 22, 11, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tables-index-rail-header {
|
||||||
|
display: grid;
|
||||||
gap: 0.35rem;
|
gap: 0.35rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-select-shell {
|
.tables-index-title {
|
||||||
position: relative;
|
margin: 0;
|
||||||
|
color: var(--ink-strong);
|
||||||
|
font-family: var(--font-display);
|
||||||
|
font-size: clamp(1.1rem, 1rem + 0.4vw, 1.35rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-select-trigger {
|
.tables-index-list {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.35rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-index-option {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: flex-start;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
gap: 0.5rem;
|
gap: 0.75rem;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.7rem 0.8rem;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: rgba(255, 250, 242, 0.72);
|
||||||
|
color: inherit;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
padding: 0.55rem 0.7rem;
|
transition: background-color 0.16s ease, border-color 0.16s ease, transform 0.16s ease;
|
||||||
border: 1px solid rgba(127, 96, 55, 0.28);
|
|
||||||
border-radius: 8px;
|
|
||||||
background: rgba(255, 252, 247, 0.96);
|
|
||||||
box-shadow: none;
|
|
||||||
appearance: none;
|
|
||||||
transition: border-color 0.16s ease, background-color 0.16s ease;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-select-trigger:hover,
|
.table-index-option:hover,
|
||||||
.table-select-trigger:focus-visible {
|
.table-index-option:focus-visible {
|
||||||
border-color: rgba(184, 121, 59, 0.4);
|
border-color: rgba(184, 121, 59, 0.28);
|
||||||
background: rgba(255, 248, 239, 0.98);
|
background: rgba(255, 247, 235, 0.94);
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-select-trigger-copy {
|
.table-index-option.is-selected {
|
||||||
display: block;
|
border-color: rgba(41, 22, 11, 0.18);
|
||||||
|
background: rgba(248, 238, 221, 0.98);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-index-option.is-curated {
|
||||||
|
background: rgba(102, 138, 83, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-index-option.is-curated:hover,
|
||||||
|
.table-index-option.is-curated:focus-visible {
|
||||||
|
background: rgba(102, 138, 83, 0.18);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-index-option.needs-curation {
|
||||||
|
background: rgba(184, 121, 59, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-index-option.needs-curation:hover,
|
||||||
|
.table-index-option.needs-curation:focus-visible {
|
||||||
|
background: rgba(184, 121, 59, 0.18);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-index-option-copy {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.18rem;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-select-trigger-title {
|
.table-index-option-title {
|
||||||
color: var(--ink);
|
color: var(--ink);
|
||||||
font-family: var(--font-ui);
|
font-family: var(--font-ui);
|
||||||
|
font-size: 0.98rem;
|
||||||
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-select-trigger-chips,
|
.table-index-option-meta {
|
||||||
.table-select-option-chips {
|
color: var(--ink-soft);
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-index-option-chips {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.25rem;
|
gap: 0.25rem;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-selector-backdrop {
|
.tables-reference-main {
|
||||||
position: fixed;
|
|
||||||
inset: 0;
|
|
||||||
border: none;
|
|
||||||
background: transparent;
|
|
||||||
padding: 0;
|
|
||||||
z-index: 15;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-select-menu {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
top: calc(100% + 0.1rem);
|
|
||||||
z-index: 20;
|
|
||||||
display: grid;
|
|
||||||
gap: 0;
|
|
||||||
padding: 0.1rem;
|
|
||||||
border-radius: 8px;
|
|
||||||
background: rgba(255, 250, 242, 0.98);
|
|
||||||
border: 1px solid rgba(127, 96, 55, 0.22);
|
|
||||||
box-shadow: 0 10px 18px rgba(41, 22, 11, 0.1);
|
|
||||||
max-height: min(28rem, 60vh);
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-select-option {
|
|
||||||
border: none;
|
|
||||||
border-radius: 0;
|
|
||||||
background: transparent;
|
|
||||||
padding: 0.35rem 0.45rem;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
gap: 0.45rem;
|
|
||||||
text-align: left;
|
|
||||||
transition: background-color 0.16s ease, outline-color 0.16s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-select-option:hover,
|
|
||||||
.table-select-option:focus-visible {
|
|
||||||
outline: 1px solid rgba(41, 22, 11, 0.16);
|
|
||||||
outline-offset: -1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-select-option.is-selected {
|
|
||||||
outline: 1px solid rgba(41, 22, 11, 0.14);
|
|
||||||
outline-offset: -1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-select-option.is-curated {
|
|
||||||
background: rgba(102, 138, 83, 0.12);
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-select-option.is-curated:hover,
|
|
||||||
.table-select-option.is-curated:focus-visible {
|
|
||||||
background: rgba(102, 138, 83, 0.18);
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-select-option.needs-curation {
|
|
||||||
background: rgba(184, 121, 59, 0.12);
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-select-option.needs-curation:hover,
|
|
||||||
.table-select-option.needs-curation:focus-visible {
|
|
||||||
background: rgba(184, 121, 59, 0.18);
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-select-option-main {
|
|
||||||
display: block;
|
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-select-option-title {
|
|
||||||
color: var(--ink);
|
|
||||||
font-family: var(--font-ui);
|
|
||||||
font-weight: 400;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-browser-toolbar-copy,
|
|
||||||
.table-browser-reading-hint,
|
|
||||||
.table-browser-edit-hint {
|
|
||||||
margin: 0;
|
|
||||||
color: var(--ink-soft);
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-shell {
|
.table-shell {
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
padding: 1.2rem;
|
padding: 1.2rem;
|
||||||
@@ -1283,6 +1281,16 @@ pre,
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1023px) {
|
||||||
|
.tables-reference-layout {
|
||||||
|
grid-template-columns: minmax(0, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tables-reference-rail {
|
||||||
|
position: static;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.table-shell .table-scroll {
|
.table-shell .table-scroll {
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user