merge(frontend): fix #339 — renforce la couleur projet dans les onglets non sélectionnés, teinte 5% + hover thématisé (QA verte)
This commit is contained in:
@ -7,9 +7,15 @@
|
||||
|
||||
import { cn } from "../lib/cn";
|
||||
import { IconButton } from "./IconButton";
|
||||
import type { ReactNode } from "react";
|
||||
import type { CSSProperties, ReactNode } from "react";
|
||||
import { useI18n } from "@/i18n";
|
||||
|
||||
interface ThemedTabStyle extends CSSProperties {
|
||||
"--tab-theme-active-bg": string;
|
||||
"--tab-theme-inactive-bg": string;
|
||||
"--tab-theme-hover-bg": string;
|
||||
}
|
||||
|
||||
export interface TabItem {
|
||||
/** Stable id, returned by `onSelect`/`onClose`. */
|
||||
id: string;
|
||||
@ -44,22 +50,32 @@ export function Tabs({ items, value, onSelect, onClose, className }: TabsProps)
|
||||
>
|
||||
{items.map((tab) => {
|
||||
const active = tab.id === value;
|
||||
const themedStyle: ThemedTabStyle | undefined = tab.themeColor
|
||||
? {
|
||||
"--tab-theme-active-bg": `color-mix(in srgb, var(--color-raised) 90%, ${tab.themeColor})`,
|
||||
// 5% project colour is 25% stronger than the previous 4% tint.
|
||||
"--tab-theme-inactive-bg": `color-mix(in srgb, var(--color-raised) 95%, ${tab.themeColor})`,
|
||||
"--tab-theme-hover-bg": `color-mix(in srgb, var(--color-raised) 93%, ${tab.themeColor})`,
|
||||
...(active ? { borderColor: tab.themeAccent ?? tab.themeColor } : {}),
|
||||
}
|
||||
: undefined;
|
||||
return (
|
||||
<div
|
||||
key={tab.id}
|
||||
style={
|
||||
tab.themeColor
|
||||
? {
|
||||
backgroundColor: `color-mix(in srgb, var(--color-raised) ${active ? 90 : 96}%, ${tab.themeColor})`,
|
||||
...(active ? { borderColor: tab.themeAccent ?? tab.themeColor } : {}),
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
style={themedStyle}
|
||||
className={cn(
|
||||
"group flex items-center gap-1 rounded-md border px-1 transition-colors",
|
||||
active
|
||||
? "border-border-strong bg-raised"
|
||||
: "border-transparent hover:bg-raised",
|
||||
? cn(
|
||||
"border-border-strong",
|
||||
tab.themeColor ? "bg-[var(--tab-theme-active-bg)]" : "bg-raised",
|
||||
)
|
||||
: cn(
|
||||
"border-transparent",
|
||||
tab.themeColor
|
||||
? "bg-[var(--tab-theme-inactive-bg)] hover:bg-[var(--tab-theme-hover-bg)]"
|
||||
: "hover:bg-raised",
|
||||
),
|
||||
)}
|
||||
>
|
||||
<button
|
||||
|
||||
@ -115,6 +115,35 @@ describe("Tabs", () => {
|
||||
fireEvent.click(screen.getByRole("button", { name: "fermer beta" }));
|
||||
expect(onClose).toHaveBeenCalledWith("b");
|
||||
});
|
||||
|
||||
it("keeps themed inactive, hover and active backgrounds visually ordered (#339)", () => {
|
||||
render(
|
||||
<Tabs
|
||||
items={[
|
||||
{ id: "a", label: "alpha", themeColor: "#AA3366", themeAccent: "#CC5588" },
|
||||
{ id: "b", label: "beta", themeColor: "#22AA66", themeAccent: "#44CC88" },
|
||||
]}
|
||||
value="a"
|
||||
onSelect={() => {}}
|
||||
/>,
|
||||
);
|
||||
|
||||
const active = screen.getByRole("tab", { name: "alpha" }).parentElement!;
|
||||
const inactive = screen.getByRole("tab", { name: "beta" }).parentElement!;
|
||||
|
||||
expect(active.style.getPropertyValue("--tab-theme-active-bg"))
|
||||
.toBe("color-mix(in srgb, var(--color-raised) 90%, #AA3366)");
|
||||
expect(active.className).toContain("bg-[var(--tab-theme-active-bg)]");
|
||||
expect(active.style.borderColor).toBe("rgb(204, 85, 136)");
|
||||
|
||||
expect(inactive.style.getPropertyValue("--tab-theme-inactive-bg"))
|
||||
.toBe("color-mix(in srgb, var(--color-raised) 95%, #22AA66)");
|
||||
expect(inactive.style.getPropertyValue("--tab-theme-hover-bg"))
|
||||
.toBe("color-mix(in srgb, var(--color-raised) 93%, #22AA66)");
|
||||
expect(inactive.className).toContain("bg-[var(--tab-theme-inactive-bg)]");
|
||||
expect(inactive.className).toContain("hover:bg-[var(--tab-theme-hover-bg)]");
|
||||
expect(inactive.style.borderColor).toBe("");
|
||||
});
|
||||
});
|
||||
|
||||
describe("SmallDropdown", () => {
|
||||
|
||||
Reference in New Issue
Block a user