revert(tasks-ui): drop the shadcn/Tailwind layer and return to the plugin's own UI system
shadcn's defaults are built for a standalone app: 14px body, 36px controls, solid primary fills and elevation read as a foreign surface next to this plugin's own tabs (files, changes, side chat, settings), which are 12/11/10px type, 28px controls, hairline borders and flat panels. Retuning the layer did not converge, so the layer goes. - Removed: src/client/ui/** (21 vendored components), components.json, scripts/ui-css.mjs, the Tailwind/PostCSS compile step in tsdown, and the deps tailwindcss / @tailwindcss/postcss / postcss / radix-ui / class-variance-authority / tailwind-merge. (diff and simple-icons stay: they patch undeclared bare imports of the host primitives, unrelated to shadcn.) - The seven page surfaces are back on the plugin's own base: *.module.css with --dsw-* tokens plus the host primitives (Button/Menu/Modal/Pill/Tag/Switch/ Input/Tooltip/StateDot/MarkdownText). Behaviour, data-* hooks, aria labels, i18n keys and the AnchoredPopover geometry/drag/dismiss contract are unchanged; the non-styling fixes landed during the shadcn era (model id dedupe, task-window CAS, drawer arming, popover dragging, the chunk packaging glob) were re-applied and are covered by the existing specs. - The tasks page returns to the core bundle: `tasks` left CHUNK_NAMES / CHUNKS / ChunkName, src/client/chunks/tasks.tsx is gone and tabs.tsx imports SubagentView directly. - The reverted stylesheet was retuned to the plugin's measured vocabulary (12/11/10px, 28px controls, border-l2 with border-l1 hairlines, hover fills, no static shadows, --dsw-shadow-lv2/3 on floating layers only) and verified against a 70-assertion real-browser contract; the harness's own two measurement defects were fixed with a falsification test proving the assertions still catch injected regressions (56/70, 14 FAIL). - Tests: ui-foundation / ui-bundle / ui-shadows (the shadcn guards) deleted, theme.spec scoped back to the plugin's own stylesheets, bundle-route and manifest-consistency chunk lists back to four. Docs: AGENTS.md and the plugin guide drop the Tailwind/shadcn guidance; the design doc marks those sections superseded and records why the layer was removed. Verified: typecheck/lint clean; 133 files / 1410 tests; core bundle 987.3 KiB with no radix-ui/--tw-/tailwind strings and no client-tasks.js; mount e2e 7/7; 20 real-browser screenshots at 360/720 for graph, tree, board, task window, drawer (including armed), both popovers and the 77-node fixture.
This commit is contained in:
@@ -1,69 +1,63 @@
|
||||
/**
|
||||
* Canvas-only styles of the workflow graph (TasksGraph.tsx): the dotted grid,
|
||||
* the transformed node layer, the SVG relation layer and the edge stroke
|
||||
* recipe. These are the four pieces Tailwind utilities cannot express in the
|
||||
* markup (a radial-gradient background image, `transform-origin: 0 0` on the
|
||||
* scaled layer, an overflow-visible SVG stage, and SVG stroke/dash painting) —
|
||||
* everything else in the graph is a utility class over the shadcn tokens.
|
||||
* Graph-only styles of the workflow graph (TasksGraph.tsx) — the two pieces
|
||||
* the page sheet (tasks-graph.module.css) does not carry:
|
||||
*
|
||||
* Skin contract: every color is a `--dsw-*` token (no literal, no palette
|
||||
* class), so the canvas follows the host light/dark theme like the rest of the
|
||||
* page. Relations are 1px hairlines in the border ink — the KIND of a relation
|
||||
* is its dash pattern and opacity, never a second hue.
|
||||
* - the card title, clamped to TWO lines (the 68px card reserve in
|
||||
* tasks-graph-layout.ts is sized for that second line: a single ellipsized
|
||||
* line left too few CJK characters to tell two siblings apart), and
|
||||
* - the hydration hint drawn over an empty canvas.
|
||||
*
|
||||
* Everything else the graph wears (the dotted canvas, the bezier edges, the
|
||||
* node cards, the control cluster) stays in the page sheet — one source of
|
||||
* truth per rule.
|
||||
*
|
||||
* Skin contract: colors resolve to `--dsw-alias-*`, type to `--dsw-font-*` —
|
||||
* tokens only, no literal, no palette class, no shadow on a static panel.
|
||||
*/
|
||||
|
||||
.canvas {
|
||||
/* Card line 1 of an agent / run node. `-webkit-box` + `-webkit-line-clamp` is
|
||||
* the only way to cap WRAPPED text with an ellipsis, and `overflow-wrap:
|
||||
* anywhere` keeps an unbroken run id from forcing one wide line. The recipe
|
||||
* mirrors the page sheet's node title (12px strong) so only the truncation
|
||||
* differs; the untruncated text stays in the element's `title`. */
|
||||
.nodeTitle {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
overflow-wrap: anywhere;
|
||||
font: var(--dsw-font-xxs-strong-12);
|
||||
color: var(--dsw-alias-label-primary);
|
||||
}
|
||||
|
||||
/* The fold aggregate carries a count, not a name: it recedes one rung in both
|
||||
* weight and ink (the page sheet's plain title). */
|
||||
.nodeTitlePlain {
|
||||
font: var(--dsw-font-xxs-12);
|
||||
color: var(--dsw-alias-label-secondary);
|
||||
}
|
||||
|
||||
/* The graph twin of the tree's loading row: centred over the canvas and
|
||||
* click-transparent, so pan / zoom / node clicks stay live underneath. It sits
|
||||
* above the transformed node layer (z-index auto) and below the control
|
||||
* cluster (z-index 6). */
|
||||
.loading {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
cursor: grab;
|
||||
/* Panning must never turn into a text selection or a native scroll. */
|
||||
touch-action: none;
|
||||
user-select: none;
|
||||
/* Graph paper: the dotted grid is part of the language. */
|
||||
background-image: radial-gradient(circle, var(--dsw-alias-border-l1) 0.6px, transparent 0.6px);
|
||||
background-size: 16px 16px;
|
||||
background-position: 0 0;
|
||||
}
|
||||
|
||||
.canvasDragging {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.canvasInner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
transform-origin: 0 0;
|
||||
}
|
||||
|
||||
.edges {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
overflow: visible;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
pointer-events: none;
|
||||
font: var(--dsw-font-xxs-12);
|
||||
color: var(--dsw-alias-label-tertiary);
|
||||
}
|
||||
|
||||
.edge {
|
||||
fill: none;
|
||||
stroke: var(--dsw-alias-border-l4);
|
||||
stroke-width: 1;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
/* Team membership: dashed. */
|
||||
.edgeTeam {
|
||||
stroke-dasharray: 3 3;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
/* Workflow member: solid, one notch stronger than a plain lineage edge. */
|
||||
.edgeWorkflow {
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
/* Collapsed aggregate: dotted and faint — it stands for many rows. */
|
||||
.edgeFold {
|
||||
stroke-dasharray: 1 4;
|
||||
opacity: 0.4;
|
||||
/* The hint's glyph is decoration: the copy line carries the message. */
|
||||
.loadingGlyph {
|
||||
display: inline-flex;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user