From 98542bc55b189486ff29cd0bd1a38ce3055f5c8a Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 25 Jul 2026 19:08:17 -0700 Subject: [PATCH] refactor(ui): inline stroke attributes via shared strokeIcon shell (#113952) --- ui/src/components/icons-tools.ts | 608 +++++++++++-------------------- ui/src/components/icons.ts | 596 +++++++++++------------------- 2 files changed, 422 insertions(+), 782 deletions(-) diff --git a/ui/src/components/icons-tools.ts b/ui/src/components/icons-tools.ts index b221741147cc..c70fa0c8a05d 100644 --- a/ui/src/components/icons-tools.ts +++ b/ui/src/components/icons-tools.ts @@ -1,255 +1,151 @@ // Control UI tool icon set, split from icons.ts to keep both under the max-lines cap. -import { html } from "lit"; +import { html, svg, type SVGTemplateResult, type TemplateResult } from "lit"; + +// Shared Lucide icon shell. Inline presentation attributes keep icons visible +// inside shadow roots that global stylesheet icon rules cannot reach; CSS +// rules still override them where a surface wants a different stroke width. +// Bodies must be svg`` fragments: html`` would parse the shapes outside the +// SVG namespace and they would silently render as nothing. +export function strokeIcon(body: SVGTemplateResult): TemplateResult { + return html` + + ${body} + + `; +} export const toolIcons = { - wrench: html` - - - - `, - fileCode: html` - - - - - - - `, - edit: html` - - - - - `, - home: html` - - - - - `, - penLine: html` - - - - - `, - paperclip: html` - - - - `, - globe: html` - - - - - - `, - image: html` - - - - - - `, - camera: html` - - - - - `, - cameraOff: html` - - - - - - - `, - smartphone: html` - - - - - `, - circleQuestionMark: html` - - - - - - `, - plug: html` - - - - - - - `, - circle: html` `, - puzzle: html` - - - - `, - panelLeft: html` - - - - - `, - panelLeftClose: html` - - - - - - `, - panelLeftOpen: html` - - - - - - `, - chevronDown: html` - - - - `, - chevronRight: html` - - - - `, - chevronLeft: html` - - - - `, - externalLink: html` - - - - - `, - send: html` - - - - - `, - stop: html` `, - pin: html` - - - - - `, - pinOff: html` - - - - - - `, - download: html` - - - - - - `, - mic: html` - - - - - - `, - volume2: html` - - - - - - `, - bookmark: html` - - `, - plus: html` - - - - - `, - gitBranch: html` - - - - - - - - `, - gitPullRequest: html` - - - - - - - `, - gitMerge: html` - - - - - - `, - terminal: html` - - - - - `, - claw: html` - - - - - `, - spark: html` - - - - `, + wrench: strokeIcon(svg` `), + fileCode: strokeIcon(svg` + + + `), + edit: strokeIcon(svg` + `), + home: strokeIcon(svg` + `), + penLine: strokeIcon(svg` + `), + paperclip: strokeIcon(svg` `), + globe: strokeIcon(svg` + + `), + image: strokeIcon(svg` + + `), + camera: strokeIcon(svg` + `), + cameraOff: strokeIcon(svg` + + + `), + smartphone: strokeIcon(svg` + `), + circleQuestionMark: strokeIcon(svg` + + `), + plug: strokeIcon(svg` + + + `), + circle: strokeIcon(svg``), + puzzle: strokeIcon(svg` `), + panelLeft: strokeIcon(svg` + `), + panelLeftClose: strokeIcon(svg` + + `), + panelLeftOpen: strokeIcon(svg` + + `), + chevronDown: strokeIcon(svg` `), + chevronRight: strokeIcon(svg` `), + chevronLeft: strokeIcon(svg` `), + externalLink: strokeIcon(svg` + `), + send: strokeIcon(svg` + `), + stop: strokeIcon(svg``), + pin: strokeIcon(svg` + `), + pinOff: strokeIcon(svg` + + `), + download: strokeIcon(svg` + + `), + mic: strokeIcon(svg` + + `), + volume2: strokeIcon(svg` + + `), + bookmark: strokeIcon(svg``), + plus: strokeIcon(svg` + `), + gitBranch: strokeIcon(svg` + + + + `), + gitPullRequest: strokeIcon(svg` + + + `), + gitMerge: strokeIcon(svg` + + `), + terminal: strokeIcon(svg` + `), + claw: strokeIcon(svg` + `), + spark: strokeIcon(svg` `), lobster: html` @@ -275,147 +171,75 @@ export const toolIcons = { `, - circleUser: html` - - - - - - `, - bell: html` - - - - - `, - palette: html` - - - - - - - - `, - flaskConical: html` - - - - - - `, - badgeCheck: html` - - - - - `, - refresh: html` - - - - - `, - trash: html` - - - - - - - - `, - eye: html` - - - - - `, - eyeOff: html` - - - - - - - `, - moreHorizontal: html` - - - - - - `, - arrowUpDown: html` - - - - - - - `, - panelRightOpen: html` - - - - - - `, - panelRightClose: html` - - - - - - `, - columns2: html` - - - - - `, - panelBottomOpen: html` - - - - - - `, - panelBottomClose: html` - - - - - - `, - maximize: html` - - - - - - - `, - minimize: html` - - - - - - - `, + circleUser: strokeIcon(svg` + + `), + bell: strokeIcon(svg` + `), + palette: strokeIcon(svg` + + + + `), + flaskConical: strokeIcon(svg` + + `), + badgeCheck: strokeIcon(svg` + `), + refresh: strokeIcon(svg` + `), + trash: strokeIcon(svg` + + + + `), + eye: strokeIcon(svg` + `), + eyeOff: strokeIcon(svg` + + + `), + moreHorizontal: strokeIcon(svg` + + `), + arrowUpDown: strokeIcon(svg` + + + `), + panelRightOpen: strokeIcon(svg` + + `), + panelRightClose: strokeIcon(svg` + + `), + columns2: strokeIcon(svg` + `), + panelBottomOpen: strokeIcon(svg` + + `), + panelBottomClose: strokeIcon(svg` + + `), + maximize: strokeIcon(svg` + + + `), + minimize: strokeIcon(svg` + + + `), } as const; diff --git a/ui/src/components/icons.ts b/ui/src/components/icons.ts index 56e38c8af224..bf1a5d8157b1 100644 --- a/ui/src/components/icons.ts +++ b/ui/src/components/icons.ts @@ -1,400 +1,216 @@ // Control UI module implements icons behavior. -import { html, type TemplateResult } from "lit"; -import { toolIcons } from "./icons-tools.ts"; +import { svg, type TemplateResult } from "lit"; +import { strokeIcon, toolIcons } from "./icons-tools.ts"; -// Lucide-style SVG icons -// All icons use currentColor for stroke +// Lucide-style SVG icons rendered through the shared strokeIcon() shell, +// which carries the stroke presentation attributes inline (see icons-tools.ts). export const icons = { // Navigation icons - messageSquare: html` - - - - `, - layoutGrid: html` - - - - - - - `, - barChart: html` - - - - - - `, - layoutDashboard: html` - - - - - - - `, - coins: html` - - - - - - - `, - activity: html` - - - - `, - clock: html` - - - - - `, - link: html` - - - - - `, - radio: html` - - - - - `, - fileText: html` - - - - - - - - `, - zap: html` - - `, - monitor: html` - - - - - - `, - monitorSmartphone: html` - - - - - - - `, - server: html` - - - - - - - `, - sun: html` - - - - - - - - - - - - `, - moon: html` - - - - `, - settings: html` - - - - - `, - bug: html` - - - - - - - - - - - - - - `, - scrollText: html` - - - - - - - `, - folder: html` - - - - `, - kanban: html` - - - - - - - `, - bot: html` - - - - - - - - - `, - users: html` - - - - - - - `, - shieldCheck: html` - - - - - `, + messageSquare: strokeIcon(svg` `), + layoutGrid: strokeIcon(svg` + + + `), + barChart: strokeIcon(svg` + + `), + layoutDashboard: strokeIcon(svg` + + + `), + coins: strokeIcon(svg` + + + `), + activity: strokeIcon(svg` `), + clock: strokeIcon(svg` + `), + link: strokeIcon(svg` + `), + radio: strokeIcon(svg` + `), + fileText: strokeIcon(svg` + + + + `), + zap: strokeIcon(svg``), + monitor: strokeIcon(svg` + + `), + monitorSmartphone: strokeIcon(svg` + + + `), + server: strokeIcon(svg` + + + `), + sun: strokeIcon(svg` + + + + + + + + `), + moon: strokeIcon(svg` `), + settings: strokeIcon(svg` + `), + bug: strokeIcon(svg` + + + + + + + + + + `), + scrollText: strokeIcon(svg` + + + `), + folder: strokeIcon(svg` `), + kanban: strokeIcon(svg` + + + `), + bot: strokeIcon(svg` + + + + + `), + users: strokeIcon(svg` + + + `), + shieldCheck: strokeIcon(svg` + `), // UI icons - menu: html` - - - - - - `, - x: html` - - - - - `, - check: html` `, - play: html` `, - pause: html` - - - - - `, - target: html` - - - - - - `, - switchCamera: html` - - - - - - - `, - archive: html` - - - - - - `, - archiveRestore: html` - - - - - - - `, - alertTriangle: html` - - - - - - `, - hand: html` - - - - - - - `, - key: html` - - - - - - `, - flag: html` - - - - - `, - lock: html` - - - - - `, - hourglass: html` - - - - - - - `, - layoutComfortable: html` - - - - - - - `, - layoutCompact: html` - - - - - - - `, - listFilter: html` - - - - - - `, - arrowDown: html` `, - arrowUp: html` `, - chevronUp: html` `, - arrowLeft: html` - - - - - `, - cornerDownLeft: html` - - - - - `, - cornerDownRight: html` - - - - - `, - copy: html` - - - - - `, - search: html` - - - - - `, - brain: html` - - - - - - - - - - - - `, - book: html` - - - - `, - loader: html` - - - - - - - - - - - `, - calendarClock: html` - - - - - - - - - `, - listChecks: html` - - - - - - - - `, + menu: strokeIcon(svg` + + `), + x: strokeIcon(svg` + `), + check: strokeIcon(svg``), + play: strokeIcon(svg``), + pause: strokeIcon(svg` + `), + target: strokeIcon(svg` + + `), + switchCamera: strokeIcon(svg` + + + `), + archive: strokeIcon(svg` + + `), + archiveRestore: strokeIcon(svg` + + + `), + alertTriangle: strokeIcon(svg` + + `), + hand: strokeIcon(svg` + + + `), + key: strokeIcon(svg` + + `), + flag: strokeIcon(svg` + `), + lock: strokeIcon(svg` + `), + hourglass: strokeIcon(svg` + + + `), + layoutComfortable: strokeIcon(svg` + + + `), + layoutCompact: strokeIcon(svg` + + + `), + listFilter: strokeIcon(svg` + + `), + arrowDown: strokeIcon(svg``), + arrowUp: strokeIcon(svg``), + chevronUp: strokeIcon(svg``), + arrowLeft: strokeIcon(svg` + `), + cornerDownLeft: strokeIcon(svg` + `), + cornerDownRight: strokeIcon(svg` + `), + copy: strokeIcon(svg` + `), + search: strokeIcon(svg` + `), + brain: strokeIcon(svg` + + + + + + + + `), + book: strokeIcon( + svg` `, + ), + loader: strokeIcon(svg` + + + + + + + `), + calendarClock: strokeIcon(svg` + + + + + `), + listChecks: strokeIcon(svg` + + + + `), ...toolIcons, } as const;