mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
- StateDot ongoing: gradient spin ring replaced by an 8-cell pixel chase (2px matrix cells, stepped trail, no tweening) - Chat: streaming pulse block replaced by a turn-level 4-pixel chase at the flow tail — rides the whole running turn (first-token wait, tools, streaming) instead of flickering with partial presence - Tool rows (ToolRow/BashRow): running no longer swaps the icon for a dot; an animated mask band sweeps the row content, gliding off on exit via mask-position transition - Composer: send/stop unified on the blue fill (bigger stop glyph, static white arrow), textarea box-sizing overflow fix, settling phase hides the composer while replay decides hero vs docked, workspace-placeholder fallback disables the bar - Hero: glow moved behind (z-index) with lower opacity; tool-row hover icon crossfade at 100ms
64 lines
2.0 KiB
TypeScript
64 lines
2.0 KiB
TypeScript
// StateDot: session state indicator (figma nodes 14:3303/3305/3312, 122:9182).
|
|
// done/warning/error: 10x10 halo (same color, 10% opacity) around a 6x6 solid
|
|
// core. ongoing: a pixel-art chase — the 8 outer cells of a 3x3 matrix light
|
|
// up clockwise with a stepped trail. Colors resolve through --dsw-* tokens only.
|
|
|
|
import clsx from 'clsx'
|
|
import css from './StateDot.module.css'
|
|
|
|
/** Four-color session state semantic (green done / amber approval-waiting / blue running ring / red error). */
|
|
export type StateDotState = 'done' | 'warning' | 'ongoing' | 'error'
|
|
|
|
/** Outer 3x3 matrix cells (2px pixels on a 10px grid), clockwise from top-left. */
|
|
const MATRIX_CELLS: readonly (readonly [number, number])[] = [
|
|
[0, 0], [4, 0], [8, 0], [8, 4], [8, 8], [4, 8], [0, 8], [0, 4],
|
|
]
|
|
|
|
/**
|
|
* Render a state dot.
|
|
* @param props.state - which of the four states to show.
|
|
* @param props.size - outer diameter in px (default 10, the figma size).
|
|
* @param props.className - extra class for layout placement.
|
|
* @returns the dot element (aria-hidden; pair with text for accessibility).
|
|
*/
|
|
export function StateDot({ state, size = 10, className }: {
|
|
state: StateDotState
|
|
size?: number
|
|
className?: string
|
|
}) {
|
|
if (state === 'ongoing') {
|
|
return (
|
|
<svg
|
|
className={clsx(css.matrix, className)}
|
|
data-state="ongoing"
|
|
width={size}
|
|
height={size}
|
|
viewBox="0 0 10 10"
|
|
shapeRendering="crispEdges"
|
|
aria-hidden="true"
|
|
>
|
|
{MATRIX_CELLS.map(([x, y], index) => (
|
|
<rect
|
|
key={`${x}-${y}`}
|
|
className={css.cell}
|
|
x={x}
|
|
y={y}
|
|
width="2"
|
|
height="2"
|
|
/* Negative delay phases the chase so every cell animates from mount. */
|
|
style={{ animationDelay: `${(index - MATRIX_CELLS.length) * 125}ms` }}
|
|
/>
|
|
))}
|
|
</svg>
|
|
)
|
|
}
|
|
return (
|
|
<span
|
|
className={clsx(css.dot, className)}
|
|
data-state={state}
|
|
style={{ width: size, height: size }}
|
|
aria-hidden="true"
|
|
/>
|
|
)
|
|
}
|