revert(icons): drop the glyph outlines, keep only the terminal's smaller size
The hairline outline I added to the colored tab glyphs reads as a thick stroke in the live instance, so it goes: the glyphs stay exactly as the icon set draws them, tinted only through the wrapper's token. What the feedback actually asked for was the terminal SIZE, and that is all that remains — it renders a step down (0.85x, floor 10px) because the VSCodicon terminal is a wide filled rectangle that read heavier than its neighbours. tests/builtins.spec.ts keeps pinning both readings (tasks = layers, terminal = the shrunk VscTerminal with no style override), so the assertion now also guards against an outline creeping back in.
This commit is contained in:
@@ -29,8 +29,8 @@
|
||||
}
|
||||
|
||||
.terminal {
|
||||
/* The shell chip is ink, not accent — and it is the widest glyph in the set,
|
||||
so it renders a step smaller than its siblings (see tab-icons.tsx). */
|
||||
/* The shell chip is ink, not accent. Its glyph is the widest in the set and
|
||||
renders a step smaller than its siblings (see tab-icons.tsx). */
|
||||
color: var(--dsw-alias-label-primary);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* `files` is the one exception in kind rather than in color: it renders DSH's
|
||||
* own folder artwork (`FileTypeIcon`), matching the file rows this tab shows.
|
||||
*/
|
||||
import { cloneElement, type ReactElement, type ReactNode } from 'react'
|
||||
import type { ReactNode } from 'react'
|
||||
import { FileTypeIcon } from '@deepseek-ai/dsh-client-ui-primitives'
|
||||
import styles from './tab-icons.module.css'
|
||||
import {
|
||||
@@ -35,35 +35,6 @@ function themed(className: string, glyph: ReactNode): ReactNode {
|
||||
return <span className={className}>{glyph}</span>
|
||||
}
|
||||
|
||||
/**
|
||||
* Give a filled VSCodicon a hairline of its own ink.
|
||||
*
|
||||
* The plugin's hand-drawn icons are 1.5px strokes on a 16px grid; the
|
||||
* VSCodicon set is filled at that size, and next to the plugin's own chrome a
|
||||
* bare fill reads heavy and slightly out of place — most visibly on the
|
||||
* terminal chip. A `currentColor` stroke in the SVG's own user units keeps the
|
||||
* host's shape and the token's color while lending it the same drawn weight,
|
||||
* and `paint-order: stroke` centres that hairline on the fill's edge instead
|
||||
* of fattening it.
|
||||
* @param icon - the glyph element to outline.
|
||||
* @returns the same glyph with its outline applied.
|
||||
*/
|
||||
function outlined(icon: ReactElement): ReactElement {
|
||||
return cloneElement(icon as ReactElement<{ style?: React.CSSProperties }>, {
|
||||
style: {
|
||||
// `non-scaling-stroke` keeps the hairline one device pixel whatever the
|
||||
// glyph's own grid is (the sets mix 16- and 24-unit viewBoxes and the
|
||||
// strip renders at 14px), and `paint-order: stroke` centres it on the
|
||||
// fill's edge instead of fattening the shape.
|
||||
stroke: 'currentColor',
|
||||
strokeWidth: 1,
|
||||
strokeLinejoin: 'round',
|
||||
paintOrder: 'stroke',
|
||||
vectorEffect: 'non-scaling-stroke',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/** The Files tab: the host's folder artwork, like the rows it opens. */
|
||||
export const filesTabIcon: TabIcon = (size) => (
|
||||
<span className={css.files}>
|
||||
@@ -73,7 +44,7 @@ export const filesTabIcon: TabIcon = (size) => (
|
||||
|
||||
/** Changes / diff: the commit glyph, green like the diff affordances. */
|
||||
export const changesTabIcon: TabIcon = (size) =>
|
||||
themed(css.changes, outlined(<VscGitCommit size={size} />))
|
||||
themed(css.changes, <VscGitCommit size={size} />)
|
||||
|
||||
/**
|
||||
* Tasks (subagents and background jobs) — the live-activity amber. The glyph
|
||||
@@ -81,20 +52,20 @@ export const changesTabIcon: TabIcon = (size) =>
|
||||
* sessions plus the host's background jobs), not a to-do list.
|
||||
*/
|
||||
export const tasksTabIcon: TabIcon = (size) =>
|
||||
themed(css.tasks, outlined(<VscLayers size={size} />))
|
||||
themed(css.tasks, <VscLayers size={size} />)
|
||||
|
||||
/** Side chat — the conversational/secondary accent. */
|
||||
export const sidechatTabIcon: TabIcon = (size) =>
|
||||
themed(css.sidechat, outlined(<VscCommentDiscussion size={size} />))
|
||||
themed(css.sidechat, <VscCommentDiscussion size={size} />)
|
||||
|
||||
/**
|
||||
* Terminal — primary ink, the shell is text. Drawn one step down from the
|
||||
* strip's 14px and with the outline above: the VSCodicon terminal is a wide
|
||||
* filled rectangle that dominated the chip at full size.
|
||||
* Terminal — primary ink, the shell is text. Rendered one step down from the
|
||||
* strip's 14px: the VSCodicon terminal is a wide filled rectangle and read
|
||||
* heavier than its neighbours at full size.
|
||||
*/
|
||||
export const terminalTabIcon: TabIcon = (size) =>
|
||||
themed(css.terminal, outlined(<VscTerminal size={Math.max(10, Math.round(size * 0.85))} />))
|
||||
themed(css.terminal, <VscTerminal size={Math.max(10, Math.round(size * 0.85))} />)
|
||||
|
||||
/** Browser — the same secondary accent as the side chat's sibling surfaces. */
|
||||
export const browserTabIcon: TabIcon = (size) =>
|
||||
themed(css.browser, outlined(<VscGlobe size={size} />))
|
||||
themed(css.browser, <VscGlobe size={size} />)
|
||||
|
||||
@@ -257,15 +257,14 @@ describe('built-in tab registrations', () => {
|
||||
expect(glyphOf('git')).toBe(VscGitCommit)
|
||||
expect(glyphOf('sidechat')).toBe(VscCommentDiscussion)
|
||||
expect(glyphOf('browser')).toBe(VscGlobe)
|
||||
// The terminal glyph is the widest in the set: it renders a step down from
|
||||
// the strip's size and keeps a hairline outline so it matches the plugin's
|
||||
// own drawn chrome instead of reading as a heavy filled block.
|
||||
// The terminal glyph is the widest in the set, so it renders a step down
|
||||
// from the strip's size. No outline: the glyphs stay exactly as the icon
|
||||
// set draws them, only tinted through the wrapper's token.
|
||||
const wrapper = iconOf('terminal') as ReactElement<{ children?: ReactElement }>
|
||||
const terminal = wrapper.props.children as ReactElement<{ size?: number; style?: Record<string, unknown> }>
|
||||
expect(terminal.type).toBe(VscTerminal)
|
||||
expect(terminal.props.size).toBeLessThan(14)
|
||||
expect(terminal.props.style?.strokeWidth).toBe(1)
|
||||
expect(terminal.props.style?.vectorEffect).toBe('non-scaling-stroke')
|
||||
expect(terminal.props.style).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user