From 74c9841ad73f82835fc5c40fbf9ac1b239f3880d Mon Sep 17 00:00:00 2001 From: lucaronin Date: Sat, 2 May 2026 10:02:57 +0200 Subject: [PATCH] fix(ui): refine icon picker appearance --- src/components/TypeCustomizePopover.test.tsx | 31 ++++++++++++++++++-- src/components/TypeCustomizePopover.tsx | 25 +++++++++++++--- 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/src/components/TypeCustomizePopover.test.tsx b/src/components/TypeCustomizePopover.test.tsx index d3ba4942..0be073d0 100644 --- a/src/components/TypeCustomizePopover.test.tsx +++ b/src/components/TypeCustomizePopover.test.tsx @@ -110,7 +110,7 @@ describe('TypeCustomizePopover', () => { it('calls onChangeColor when a color is clicked', () => { renderPopover() - const colorButtons = screen.getAllByTitle(/red|blue|green|purple|yellow|orange|teal|pink/i) + const colorButtons = screen.getAllByTitle(/red|blue|green|purple|yellow|orange|pink/i) fireEvent.click(colorButtons[0]) expect(onChangeColor).toHaveBeenCalled() @@ -123,6 +123,31 @@ describe('TypeCustomizePopover', () => { expect(onChangeIcon).toHaveBeenCalledWith('wrench') }) + it('renders picker icons slightly larger than the sidebar icon size', () => { + renderPopover() + + const icon = screen.getByTitle('wrench').querySelector('svg') + expect(icon).toHaveAttribute('width', '18') + expect(icon).toHaveAttribute('height', '18') + expect(icon).toHaveClass('size-[18px]') + }) + + it('orders color swatches by hue before neutral gray', () => { + renderPopover() + + const colorRow = screen.getByTitle('Red').parentElement + expect(Array.from(colorRow?.children ?? []).map((element) => element.getAttribute('title'))).toEqual([ + 'Red', + 'Orange', + 'Yellow', + 'Green', + 'Blue', + 'Purple', + 'Pink', + 'Gray', + ]) + }) + it('calls onClose when Done is clicked', () => { renderPopover() @@ -130,10 +155,10 @@ describe('TypeCustomizePopover', () => { expect(onClose).toHaveBeenCalled() }) - it('renders all color options including teal and pink', () => { + it('renders curated color options without the teal near-duplicate', () => { renderPopover() - expect(screen.getByTitle('Teal')).toBeInTheDocument() + expect(screen.queryByTitle('Teal')).not.toBeInTheDocument() expect(screen.getByTitle('Pink')).toBeInTheDocument() }) diff --git a/src/components/TypeCustomizePopover.tsx b/src/components/TypeCustomizePopover.tsx index 186881fa..b0544ac1 100644 --- a/src/components/TypeCustomizePopover.tsx +++ b/src/components/TypeCustomizePopover.tsx @@ -49,6 +49,20 @@ interface TemplateSectionProps { onTemplateChange: (value: string) => void } +const ICON_PICKER_ICON_SIZE = 18 +const ICON_PICKER_ICON_CLASS_NAME = 'size-[18px]' +const COLOR_PICKER_ACCENT_COLORS = [ + 'red', + 'orange', + 'yellow', + 'green', + 'blue', + 'purple', + 'pink', + 'gray', +].map((key) => ACCENT_COLORS.find((color) => color.key === key) ?? null) + .filter((color): color is typeof ACCENT_COLORS[number] => color !== null) + /** Debounce a callback by `delay` ms. Returns a stable ref-based wrapper. */ function useDebouncedCallback(fn: (v: string) => void, delay: number): (v: string) => void { const timerRef = useRef | undefined>(undefined) @@ -68,7 +82,7 @@ function ColorSection({ selectedColor, locale, onSelectColor }: ColorSectionProp <>
{translate(locale, 'customize.color')}
- {ACCENT_COLORS.map((color) => ( + {COLOR_PICKER_ACCENT_COLORS.map((color) => (
-
+
{filteredIcons.length === 0 ? (
{translate(locale, 'customize.noIconsFound')} @@ -131,7 +148,7 @@ function IconSection({ variant="ghost" size="icon-xs" className={cn( - 'h-[30px] w-[30px] rounded p-0 transition-colors', + 'h-[30px] w-[30px] justify-self-center rounded p-0 transition-colors', selectedIcon === name ? 'bg-primary/10 text-primary' : 'text-muted-foreground hover:bg-accent hover:text-foreground', @@ -140,7 +157,7 @@ function IconSection({ title={name} aria-label={name} > - + )) )}