From 2299d034aed1c0993fae990fcf3ddaad3bae7c97 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Sun, 14 Jun 2026 19:08:33 -0500 Subject: fix(theme-studio): keep dropdown color names legible The color-picker popup colored each row's name and hex for contrast against the swatch, but the rows sit on the popup's fixed dark background. A mid or dark swatch (the blues past blue-1) got near-black text that vanished on the dark popup. The text now inherits the popup foreground for every real palette color. Only the solid "default" row, whose background is the color itself, still contrasts against its own fill. I moved the decision into dropdownRowTextColor with unit coverage, including a dark-swatch regression case. --- scripts/theme-studio/test-app-core.mjs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'scripts/theme-studio/test-app-core.mjs') diff --git a/scripts/theme-studio/test-app-core.mjs b/scripts/theme-studio/test-app-core.mjs index 63e79a95c..e98e511e5 100644 --- a/scripts/theme-studio/test-app-core.mjs +++ b/scripts/theme-studio/test-app-core.mjs @@ -7,7 +7,7 @@ import assert from 'node:assert/strict'; import { readFileSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { - nameToHex, normalizePkgFace, buildPkgmap, packagesForExport, mergePackagesInto, effResolve, resolveSyntaxFg, resolveUiAttr, optList, paletteOptionList, spanNeighborHex, slugify, + nameToHex, normalizePkgFace, buildPkgmap, packagesForExport, mergePackagesInto, effResolve, resolveSyntaxFg, resolveUiAttr, dropdownRowTextColor, optList, paletteOptionList, spanNeighborHex, slugify, clearPalettePlan, deletePaletteColumnPlan, groundColumnMembersFromPalette, areAllLocked, lockToggleLabel, toggleLockSet, } from './app-core.js'; import { planPaletteGenerator, entriesForGeneratedColumn } from './palette-generator-core.js'; @@ -769,3 +769,21 @@ test('resolveUiAttr: returns null when nothing up the chain is set', () => { test('resolveUiAttr: a face with no inherit and an unset attribute returns null', () => { assert.equal(resolveUiAttr('region', 'bg', { 'region': { bg: null } }), null); }); + +// dropdownRowTextColor: a popup row showing a real palette color inherits the +// popup foreground (legible on the fixed dark popup); only the filled default +// row uses a contrast color against its own background. textOn is stubbed so the +// test asserts the decision, not the contrast math. +const stubTextOn = (h) => (h === '#000000' ? '#fff' : '#000'); +test('dropdownRowTextColor: a real palette color inherits the popup fg (empty)', () => { + assert.equal(dropdownRowTextColor('#2a3a5a', '#2a3a5a', stubTextOn), ''); +}); +test('dropdownRowTextColor: a dark swatch still inherits (regression: blues were unreadable)', () => { + assert.equal(dropdownRowTextColor('#000000', '#000000', stubTextOn), ''); +}); +test('dropdownRowTextColor: the filled default row contrasts against its fill', () => { + assert.equal(dropdownRowTextColor('', '#cdced1', stubTextOn), '#000'); +}); +test('dropdownRowTextColor: a default row with no fill inherits (empty)', () => { + assert.equal(dropdownRowTextColor('', '', stubTextOn), ''); +}); -- cgit v1.2.3