Quiet resting cells in tables canvas

This commit is contained in:
2026-03-21 15:10:06 +01:00
parent ae582367d6
commit 9cfb9ac364
3 changed files with 41 additions and 18 deletions

View File

@@ -66,6 +66,7 @@ It is intentionally implementation-focused:
| 2026-03-21 | P3.3 | Completed | Added rail search, family filters, pinned and recent sections, curated status chips, and keyboard up/down plus Enter handling on top of the new permanent table index rail. | | 2026-03-21 | P3.3 | Completed | Added rail search, family filters, pinned and recent sections, curated status chips, and keyboard up/down plus Enter handling on top of the new permanent table index rail. |
| 2026-03-21 | P3.4 | Completed | Added a sticky context bar with reference-mode tabs, variant and severity selectors, roll-jump state, and active filter chips, then wired those controls into page state and canvas filtering. | | 2026-03-21 | P3.4 | Completed | Added a sticky context bar with reference-mode tabs, variant and severity selectors, roll-jump state, and active filter chips, then wired those controls into page state and canvas filtering. |
| 2026-03-21 | P3.5 | Completed | Reworked the canvas with sticky headers, a sticky roll-band column, row and column emphasis driven by selection and roll-jump state, selected-cell treatment, and a comfortable/dense density toggle. | | 2026-03-21 | P3.5 | Completed | Reworked the canvas with sticky headers, a sticky roll-band column, row and column emphasis driven by selection and roll-jump state, selected-cell treatment, and a comfortable/dense density toggle. |
| 2026-03-21 | P3.6 | Completed | Removed the always-visible cell button stack from resting cells, leaving status-only hints by default and limiting compact edit/curation buttons to the currently selected cell. |
### Lessons Learned ### Lessons Learned
@@ -101,6 +102,7 @@ It is intentionally implementation-focused:
- Rail keyboard behavior is easiest to maintain when it works from one deduplicated option order, even if the UI shows multiple sections. Keeping one internal option list avoids separate arrow-key state per section. - Rail keyboard behavior is easiest to maintain when it works from one deduplicated option order, even if the UI shows multiple sections. Keeping one internal option list avoids separate arrow-key state per section.
- The context bar controls should own one shared view-state model before the canvas gets more visual treatment. Wiring the filters into the host page now avoids a second refactor when row, column, and cell emphasis land. - The context bar controls should own one shared view-state model before the canvas gets more visual treatment. Wiring the filters into the host page now avoids a second refactor when row, column, and cell emphasis land.
- Canvas emphasis becomes maintainable once selection, roll-jump, and density are all fed through one explicit state model. That lets the grid respond to context without hiding selection logic inside CSS-only heuristics. - Canvas emphasis becomes maintainable once selection, roll-jump, and density are all fed through one explicit state model. That lets the grid respond to context without hiding selection logic inside CSS-only heuristics.
- Resting-cell quietness should be enforced structurally, not only visually. Showing actions only for the selected cell prevents future CSS regressions from reintroducing button clutter across the whole grid.
## Target Outcomes ## Target Outcomes
@@ -466,7 +468,7 @@ Build the shared interaction infrastructure needed by multiple destinations befo
| `P3.3` | Completed | The rail now supports search-as-you-type, family filters, pinned and recent sections, curated status chips, and a deduplicated arrow/Enter keyboard path. | | `P3.3` | Completed | The rail now supports search-as-you-type, family filters, pinned and recent sections, curated status chips, and a deduplicated arrow/Enter keyboard path. |
| `P3.4` | Completed | The table surface now has a sticky context bar with mode tabs, variant/severity focus, roll-jump state, and active filter chips wired into host-page view state. | | `P3.4` | Completed | The table surface now has a sticky context bar with mode tabs, variant/severity focus, roll-jump state, and active filter chips wired into host-page view state. |
| `P3.5` | Completed | The canvas now supports sticky headers and roll bands, row and column emphasis from selection and roll-jump state, selected-cell treatment, and a comfortable/dense density toggle. | | `P3.5` | Completed | The canvas now supports sticky headers and roll bands, row and column emphasis from selection and roll-jump state, selected-cell treatment, and a comfortable/dense density toggle. |
| `P3.6` | Pending | Remove visible resting-state action stacks from non-selected cells. | | `P3.6` | Completed | Resting cells now show only status hints; compact edit/curation buttons appear only for the selected cell. |
| `P3.7` | Pending | Add the desktop selection-driven inspector. | | `P3.7` | Pending | Add the desktop selection-driven inspector. |
| `P3.8` | Pending | Add the mobile bottom-sheet inspector variant. | | `P3.8` | Pending | Add the mobile bottom-sheet inspector variant. |
| `P3.9` | Pending | Move legend/help to an on-demand secondary surface. | | `P3.9` | Pending | Move legend/help to an on-demand secondary surface. |

View File

@@ -29,6 +29,7 @@
if (TryGetCell(rollBand.Label, displayColumn.GroupKey, displayColumn.ColumnKey, out var resolvedCell) && resolvedCell is not null) if (TryGetCell(rollBand.Label, displayColumn.GroupKey, displayColumn.ColumnKey, out var resolvedCell) && resolvedCell is not null)
{ {
var cell = resolvedCell; var cell = resolvedCell;
var isSelectedCell = IsSelectedCell(cell);
@if (MatchesModeFilter(cell)) @if (MatchesModeFilter(cell))
{ {
@@ -40,6 +41,14 @@
<span class="critical-cell-status-chip is-curated">Curated</span> <span class="critical-cell-status-chip is-curated">Curated</span>
} }
else else
{
<span class="critical-cell-status-chip needs-curation">Needs Curation</span>
}
@if (isSelectedCell)
{
<div class="critical-cell-selected-actions">
@if (!cell.IsCurated)
{ {
<button <button
type="button" type="button"
@@ -47,7 +56,7 @@
title="Open the curation preview for this cell." title="Open the curation preview for this cell."
@onclick:stopPropagation="true" @onclick:stopPropagation="true"
@onclick="() => OnOpenCuration.InvokeAsync(cell.ResultId)"> @onclick="() => OnOpenCuration.InvokeAsync(cell.ResultId)">
Needs Curation Curate
</button> </button>
} }
@@ -60,6 +69,8 @@
Edit Edit
</button> </button>
</div> </div>
}
</div>
<CompactCriticalCell <CompactCriticalCell
Description="@(cell.Description ?? string.Empty)" Description="@(cell.Description ?? string.Empty)"
@@ -317,5 +328,8 @@
private Task SelectCell(CriticalTableCellDetail cell) => private Task SelectCell(CriticalTableCellDetail cell) =>
OnSelectCell.InvokeAsync(new TablesCellSelection(cell.ResultId, cell.RollBand, cell.ColumnKey, cell.GroupKey)); OnSelectCell.InvokeAsync(new TablesCellSelection(cell.ResultId, cell.RollBand, cell.ColumnKey, cell.GroupKey));
private bool IsSelectedCell(CriticalTableCellDetail cell) =>
SelectedCell is not null && cell.ResultId == SelectedCell.ResultId;
private static string BuildColumnSpanStyle(int span) => $"grid-column: span {span};"; private static string BuildColumnSpanStyle(int span) => $"grid-column: span {span};";
} }

View File

@@ -1619,6 +1619,13 @@ pre,
flex-wrap: wrap; flex-wrap: wrap;
} }
.critical-cell-selected-actions {
display: inline-flex;
align-items: center;
gap: 0.35rem;
margin-left: auto;
}
.critical-cell-action-button { .critical-cell-action-button {
border: 1px solid rgba(127, 96, 55, 0.18); border: 1px solid rgba(127, 96, 55, 0.18);
border-radius: 999px; border-radius: 999px;
@@ -1636,7 +1643,7 @@ pre,
} }
.critical-cell-action-button.is-edit { .critical-cell-action-button.is-edit {
margin-left: auto; margin-left: 0;
} }
.critical-cell-action-button:hover { .critical-cell-action-button:hover {