From 79a6567530a8f860dc8aa78e6fa3a2731dd7c263 Mon Sep 17 00:00:00 2001 From: Anders Olsson Date: Wed, 10 Jun 2026 09:42:57 +0200 Subject: [PATCH] fix(web): dark-mode tokens for popup primitives + theme-color/color-scheme sync (#68) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tooltip, toast, and combobox popups still hardcoded light colors (bg-white, neutral-*, indigo-50) and rendered as white boxes in dark mode; the objects-table page-size select did the same in app code. Swap all of them to theme tokens (popover/accent/muted/destructive/ success) and replace the toast's literal "×" with the lucide X icon. Wire browser chrome into the theme: color-scheme via CSS on :root/.dark (follows the in-app toggle, not just the OS), a theme-color meta kept in sync by the preload script and applyTheme(), plus a unit test for the meta sync. Extend check-no-raw-colors to also flag shadeless white/black utilities outside components/ui/ so the objects-table case can't recur. Closes #68 Co-Authored-By: Claude Opus 4.8 --- web/index.html | 5 +++++ web/scripts/check-no-raw-colors.mjs | 2 +- web/src/components/ui/combobox.tsx | 10 +++++----- web/src/components/ui/toast.tsx | 13 +++++++------ web/src/components/ui/tooltip.tsx | 2 +- web/src/index.css | 2 ++ web/src/objects/objects-table.tsx | 2 +- web/src/theme/theme.test.ts | 15 +++++++++++++++ web/src/theme/theme.ts | 10 +++++++++- 9 files changed, 46 insertions(+), 15 deletions(-) diff --git a/web/index.html b/web/index.html index f3064e9..04bf4e7 100644 --- a/web/index.html +++ b/web/index.html @@ -3,6 +3,8 @@ + + Collection diff --git a/web/scripts/check-no-raw-colors.mjs b/web/scripts/check-no-raw-colors.mjs index e2bc9d6..7b228a6 100644 --- a/web/scripts/check-no-raw-colors.mjs +++ b/web/scripts/check-no-raw-colors.mjs @@ -5,7 +5,7 @@ import { join, relative } from "node:path"; const root = "src"; const excludeDir = join("src", "components", "ui"); const RAW_COLOR = - /(?:text|bg|border|ring|fill|stroke|from|to|via|decoration|outline|divide|placeholder)-(?:neutral|gray|slate|zinc|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950)\b/; + /(?:text|bg|border|ring|fill|stroke|from|to|via|decoration|outline|divide|placeholder)-(?:(?:neutral|gray|slate|zinc|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950)|white|black)\b/; function walk(dir) { const files = []; diff --git a/web/src/components/ui/combobox.tsx b/web/src/components/ui/combobox.tsx index 722fe33..9a72ca5 100644 --- a/web/src/components/ui/combobox.tsx +++ b/web/src/components/ui/combobox.tsx @@ -31,7 +31,7 @@ function ComboboxClear({ className, ...props }: ComboboxPrimitive.Clear.Props) { ); @@ -56,7 +56,7 @@ function ComboboxPopup({ className, ...props }: ComboboxPrimitive.Popup.Props) { ); diff --git a/web/src/components/ui/toast.tsx b/web/src/components/ui/toast.tsx index b4152fe..656a814 100644 --- a/web/src/components/ui/toast.tsx +++ b/web/src/components/ui/toast.tsx @@ -1,6 +1,7 @@ import type * as React from "react"; import { useTranslation } from "react-i18next"; import { Toast as ToastPrimitive } from "@base-ui/react/toast"; +import { X } from "lucide-react"; import { cn } from "@/lib/utils"; import { toastManager } from "@/toast/toast-manager"; @@ -14,9 +15,9 @@ function ToastList() { toast={toast} data-slot="toast" className={cn( - "flex items-start gap-2 rounded-md border bg-white p-3 text-sm shadow-md", - toast.type === "error" && "border-red-300", - toast.type === "success" && "border-green-300", + "flex items-start gap-2 rounded-md border bg-popover p-3 text-sm text-popover-foreground shadow-md", + toast.type === "error" && "border-destructive", + toast.type === "success" && "border-success", )} >
@@ -28,15 +29,15 @@ function ToastList() { )}
- × + )); diff --git a/web/src/components/ui/tooltip.tsx b/web/src/components/ui/tooltip.tsx index 53b4512..6f05691 100644 --- a/web/src/components/ui/tooltip.tsx +++ b/web/src/components/ui/tooltip.tsx @@ -22,7 +22,7 @@ function TooltipPopup({ className, ...props }: TooltipPrimitive.Popup.Props) { setLimit(Number(event.target.value))} aria-label={t("objects.pageSize")} - className="rounded-md border bg-white px-1 py-0.5" + className="rounded-md border bg-background px-1 py-0.5" > {PAGE_SIZES.map((size) => (