fix(web): dark-mode tokens for popup primitives + theme-color/color-scheme sync (#68)
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 <noreply@anthropic.com>
This commit is contained in:
@@ -31,7 +31,7 @@ function ComboboxClear({ className, ...props }: ComboboxPrimitive.Clear.Props) {
|
||||
<ComboboxPrimitive.Clear
|
||||
data-slot="combobox-clear"
|
||||
className={cn(
|
||||
"absolute right-6 text-neutral-400 hover:text-neutral-700",
|
||||
"absolute right-6 text-muted-foreground hover:text-foreground",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -43,7 +43,7 @@ function ComboboxTrigger({ className, ...props }: ComboboxPrimitive.Trigger.Prop
|
||||
return (
|
||||
<ComboboxPrimitive.Trigger
|
||||
data-slot="combobox-trigger"
|
||||
className={cn("absolute right-1 text-neutral-500", className)}
|
||||
className={cn("absolute right-1 text-muted-foreground", className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
@@ -56,7 +56,7 @@ function ComboboxPopup({ className, ...props }: ComboboxPrimitive.Popup.Props) {
|
||||
<ComboboxPrimitive.Popup
|
||||
data-slot="combobox-popup"
|
||||
className={cn(
|
||||
"max-h-64 min-w-48 overflow-auto rounded border bg-white p-1 text-sm shadow-md",
|
||||
"max-h-64 min-w-48 overflow-auto rounded border bg-popover p-1 text-sm text-popover-foreground shadow-md",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -81,7 +81,7 @@ function ComboboxItem({ className, ...props }: ComboboxPrimitive.Item.Props) {
|
||||
<ComboboxPrimitive.Item
|
||||
data-slot="combobox-item"
|
||||
className={cn(
|
||||
"flex cursor-default items-center gap-2 rounded px-2 py-1 data-[highlighted]:bg-indigo-50",
|
||||
"flex cursor-default items-center gap-2 rounded px-2 py-1 data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -103,7 +103,7 @@ function ComboboxEmpty({ className, ...props }: ComboboxPrimitive.Empty.Props) {
|
||||
return (
|
||||
<ComboboxPrimitive.Empty
|
||||
data-slot="combobox-empty"
|
||||
className={cn("px-2 py-1 text-neutral-500", className)}
|
||||
className={cn("px-2 py-1 text-muted-foreground", className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -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",
|
||||
)}
|
||||
>
|
||||
<div className="flex-1">
|
||||
@@ -28,15 +29,15 @@ function ToastList() {
|
||||
)}
|
||||
<ToastPrimitive.Description
|
||||
data-slot="toast-description"
|
||||
className="text-neutral-700"
|
||||
className="text-muted-foreground"
|
||||
/>
|
||||
</div>
|
||||
<ToastPrimitive.Close
|
||||
data-slot="toast-close"
|
||||
aria-label={t("common.close")}
|
||||
className="text-neutral-400 hover:text-neutral-700"
|
||||
className="text-muted-foreground hover:text-foreground"
|
||||
>
|
||||
×
|
||||
<X className="size-4" aria-hidden="true" />
|
||||
</ToastPrimitive.Close>
|
||||
</ToastPrimitive.Root>
|
||||
));
|
||||
|
||||
@@ -22,7 +22,7 @@ function TooltipPopup({ className, ...props }: TooltipPrimitive.Popup.Props) {
|
||||
<TooltipPrimitive.Popup
|
||||
data-slot="tooltip-popup"
|
||||
className={cn(
|
||||
"rounded border bg-white px-2 py-1 text-sm shadow-md",
|
||||
"rounded border bg-popover px-2 py-1 text-sm text-popover-foreground shadow-md",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
Reference in New Issue
Block a user