From fa5b28ea69f3bff0941f8a097a9746b7a67fa900 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Wed, 24 Jun 2026 14:44:28 -0400 Subject: feat(theme-studio): nerd-icons gallery as a hue-ordered icon grid The nerd-icons pane is now a grid: one row per color face, the rows ordered by hue so families cluster, distinct icons (deduped within a color) drawn in their color with the icon's nerd-font name beneath. A "preview:" dropdown above the grid picks the glyph size in points, with Left/Right arrows to step it. Single-pane apps show it disabled, naming the preview. This replaces the v1 legend in the pane, whose data is still captured for round-trip. build-nerd-icons-legend.el is now a library. A cj/nerd-icons-write-legend entry point requires nerd-icons only at write time, so the capture logic loads and unit-tests without it. It dedupes icons by name within a face, computes each face's native hue, and orders the groups by hue. Writing the test surfaced a latent bug: face-hsl used (cadr (assoc t spec)), which grabs the first keyword instead of the plist. It only worked because the real faces fall through to the face-foreground branch. I fixed it to a correct t-clause parse. Coverage: 7 ERT capture tests (dedupe, hue order, lightness tiebreak, name sort, skip rules), 4 Python validator edges, and browser gates for the grid and the size dropdown. Locate stays color-level: clicking a color flashes its icons, and clicking an icon flashes its color row. Icons aren't individually editable, so there's nothing per-icon to select. --- scripts/theme-studio/previews.js | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) (limited to 'scripts/theme-studio/previews.js') diff --git a/scripts/theme-studio/previews.js b/scripts/theme-studio/previews.js index 592640cea..11ea13caa 100644 --- a/scripts/theme-studio/previews.js +++ b/scripts/theme-studio/previews.js @@ -498,14 +498,31 @@ function renderMarkdownPreview(){const a='markdown-mode',L=[]; L.push(os(a,'markdown-html-tag-delimiter-face','<')+os(a,'markdown-html-tag-name-face','kbd')+os(a,'markdown-html-tag-delimiter-face','>')+'Ctrl-C'+os(a,'markdown-html-tag-delimiter-face','</')+os(a,'markdown-html-tag-name-face','kbd')+os(a,'markdown-html-tag-delimiter-face','>')); L.push(os(a,'markdown-footnote-marker-face','[^1]:')+' '+os(a,'markdown-footnote-text-face','the footnote text.')); return previewLines(L);} -// nerd-icons legend preview: each curated filetype's real nerd-font glyph drawn -// in its mapped color face, then the sample name. The legend rides -// APPS['nerd-icons'].legend (captured by build-nerd-icons-legend.el); recoloring -// a face repaints every row mapped to it because os() reads the live registry. -// Falls back to the generic preview if the legend is missing (the bespoke app -// only registers with a valid one, so that path is defensive). -function renderNerdIconsPreview(){ - const a='nerd-icons',rows=(APPS[a]&&APPS[a].legend)||[],L=[]; - if(!rows.length)return genericPreview(a); - for(const r of rows) L.push(os(a,r.face,r.glyph)+' '+r.label); - return previewLines(L);} +// nerd-icons gallery grid: the full colored catalog. Every distinct face-bearing +// nerd-icons glyph (APPS['nerd-icons'].gallery, captured by build-nerd-icons-legend.el), +// one row per color face, the rows ordered by hue so families cluster (blues +// together, reds together). Each cell draws the glyph in its face color with the +// icon's nerd-font name beneath. SIZEPT (points, default 14) sizes the glyphs so +// the designer can view the grid at different buffer sizes via the preview-pane +// dropdown; the cell width scales with it. Recoloring a face repaints its swatch +// and every glyph in its row because os() reads the live registry. Falls back to +// the generic preview if the gallery is missing (the bespoke app registers with a +// valid legend, so that path is defensive). +function renderNerdIconsPreview(sizePt){ + const a='nerd-icons',groups=(APPS[a]&&APPS[a].gallery)||[]; + if(!groups.length)return genericPreview(a); + const pt=sizePt||14,cellW=Math.round(pt*4.6+24); + let h=`';} -- cgit v1.2.3