Files
fusion/packages/dashboard/app/components/Lane.css
gsxdsm dfb037edd8 FN-6133: fix workflow toolbar toggle accessibility
Replace the empty workflow toolbar icon toggle with an accessible text control.

- move workflow toolbar collapse/expand handling into shared click and keyboard callbacks
- make the expanded toolbar itself clickable while rendering a focusable "Workflow" label in collapsed mode
- update toolbar styling and Board tests to cover keyboard toggling, single-workflow cases, and the absence of empty icon buttons

Files changed:
 packages/dashboard/app/components/Board.tsx        |  51 ++++++++---
 packages/dashboard/app/components/Lane.css         |  19 +++-
 .../app/components/__tests__/Board.test.tsx        | 100 +++++++++++++++++++--
 3 files changed, 147 insertions(+), 23 deletions(-)

Fusion-Task-Id: FN-6133

Fusion-Task-Lineage: 6dd217a0-ede0-424a-8ab7-cdde39d2b6ce
2026-06-09 15:05:25 -07:00

210 lines
4.4 KiB
CSS

/* Multi-lane board lane (U9). Each lane is a full-width vertical row whose
* columns scroll horizontally inside the lane. Tokens mirror .board/.column in
* app/styles.css; no monolith CSS is touched. */
.board-lanes {
display: flex;
flex-direction: column;
gap: var(--column-gap, 12px);
flex: 1 1 auto;
min-height: 0;
min-width: 0;
overflow-y: auto;
overflow-x: hidden;
padding: var(--board-padding, 12px);
box-sizing: border-box;
}
.board-workflow-view {
display: flex;
flex-direction: column;
flex: 1 1 auto;
width: 100%;
min-width: 0;
min-height: 0;
overflow: hidden;
background: var(--bg);
}
.board-workflow-toolbar {
display: flex;
align-items: center;
justify-content: flex-end;
gap: var(--space-md);
padding: var(--space-md) var(--space-xl);
border-bottom: 1px solid var(--border);
background: var(--surface);
}
.board-workflow-toolbar[data-collapsed] {
justify-content: flex-start;
gap: var(--space-sm);
padding: var(--space-xs) var(--space-md);
}
.board-workflow-toolbar:not([data-collapsed]),
.board-workflow-collapsed-label {
cursor: pointer;
}
.board-workflow-toolbar:focus-visible,
.board-workflow-collapsed-label:focus-visible {
outline: none;
box-shadow: var(--focus-ring-strong);
}
.board-workflow-collapsed-label {
border-radius: var(--radius-sm);
color: var(--text-muted);
font-size: 0.8rem;
}
.board-workflow-collapsed-label:hover,
.board-workflow-collapsed-label:focus-visible {
color: var(--text);
}
.board-workflow-selector {
margin-left: auto;
}
.board-workflow-create-btn,
.board-workflow-edit-btn {
flex: 0 0 auto;
}
.board.board-workflow-columns {
flex: 1 1 auto;
display: flex;
flex-direction: row;
align-items: stretch;
width: 100%;
min-height: 0;
overflow-x: auto;
overflow-y: hidden;
scroll-snap-type: x proximity;
}
.board.board-workflow-columns > .column {
flex: 1 0 300px;
min-width: 300px;
scroll-snap-align: center;
}
.lane {
display: flex;
flex-direction: column;
flex: 0 0 auto;
width: 100%;
min-width: 0;
border: 1px solid var(--border);
border-radius: var(--radius-lg, 10px);
background: var(--surface-muted, var(--surface));
}
.lane-header {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 12px;
border-bottom: 1px solid var(--border);
cursor: pointer;
user-select: none;
}
.lane-header:hover {
background: var(--surface-hover, var(--surface));
}
.lane-header:focus-visible {
outline: 2px solid var(--focus-ring, var(--color-primary));
outline-offset: -2px;
}
.lane-name {
font-size: 0.95rem;
font-weight: 600;
margin: 0;
}
.lane-count {
font-variant-numeric: tabular-nums;
font-size: 0.8rem;
color: var(--text-muted, var(--text));
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius-sm, 6px);
padding: 0 6px;
min-width: 1.5rem;
text-align: center;
}
.lane-columns {
display: flex;
gap: var(--column-gap, 12px);
padding: 12px;
overflow-x: auto;
overflow-y: hidden;
scroll-snap-type: x proximity;
scrollbar-color: var(--border) transparent;
scrollbar-width: thin;
min-height: 0;
}
.lane-columns > .column {
flex: 0 0 clamp(280px, 28vw, 340px);
/* Repo convention (mobile-scroll-snap test): snap-align must be `center`. */
scroll-snap-align: center;
}
.lane-columns::-webkit-scrollbar {
height: 6px;
}
.lane-columns::-webkit-scrollbar-thumb {
background: var(--border);
border-radius: var(--radius-sm, 6px);
}
/* Inline column feedback (capacity-exhausted promote, deterministic drag
* rejection) — rendered in-column, not a toast (R17 / promote spec). */
.column-inline-feedback {
margin: 4px 12px 0;
padding: 6px 8px;
font-size: 0.8rem;
color: var(--danger, #d9534f);
background: color-mix(in srgb, var(--danger, #d9534f) 12%, transparent);
border: 1px solid color-mix(in srgb, var(--danger, #d9534f) 35%, transparent);
border-radius: var(--radius-sm, 6px);
}
@media (max-width: 1024px) {
.board.board-lanes {
flex-direction: column;
overflow-x: hidden;
overflow-y: auto;
scroll-snap-type: none;
}
.board.board-lanes > .lane {
width: 100%;
min-width: 0;
flex-shrink: 0;
}
.board.board-workflow-columns {
flex-direction: row;
overflow-x: auto;
overflow-y: hidden;
scroll-snap-type: x proximity;
}
}
@media (max-width: 768px) {
.board-workflow-toolbar[data-collapsed] {
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
}
}