ui: the invert disc's half is actually filled — and the demos match
Lucide's Contrast leaves its half-moon unfilled (fill=none default) - the owner's catch. Hand-rolled InvertDiscIcon: same geometry, the half carries fill=currentColor, so the filled side is filled. The demo cards get the identical disc + 'Invert colors' tooltip on their invert toggles, matching the figures.
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
import { useContext, useEffect, useMemo, useRef, useState } from "react";
|
import { useContext, useEffect, useMemo, useRef, useState } from "react";
|
||||||
import { DownloadIcon } from "lucide-react";
|
import { DownloadIcon } from "lucide-react";
|
||||||
import { Toggle } from "@/components/settings/controls";
|
import { Toggle } from "@/components/settings/controls";
|
||||||
|
import { InvertDiscIcon } from "@/components/artifacts/invert-disc";
|
||||||
import { ChatActionsContext } from "@/components/chat";
|
import { ChatActionsContext } from "@/components/chat";
|
||||||
import { downloadFile, slugFilename } from "@/components/artifacts/download";
|
import { downloadFile, slugFilename } from "@/components/artifacts/download";
|
||||||
import { DispatchCard } from "@/components/artifacts/dispatch-card";
|
import { DispatchCard } from "@/components/artifacts/dispatch-card";
|
||||||
@@ -181,7 +182,13 @@ function DemoFrame({
|
|||||||
<span className="truncate text-xs font-medium tracking-wide text-foreground">{title}</span>
|
<span className="truncate text-xs font-medium tracking-wide text-foreground">{title}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex shrink-0 items-center gap-1.5">
|
<div className="flex shrink-0 items-center gap-1.5">
|
||||||
<Toggle checked={inverted} onChange={toggleInverted} label="Invert demo brightness" />
|
<Toggle
|
||||||
|
checked={inverted}
|
||||||
|
onChange={toggleInverted}
|
||||||
|
label="Invert demo brightness"
|
||||||
|
title="Invert colors"
|
||||||
|
discIcon={<InvertDiscIcon className="size-3" />}
|
||||||
|
/>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
aria-label="Download demo as HTML"
|
aria-label="Download demo as HTML"
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/** The invert disc (owner round, 2026-10-07): the half-filled circle that
|
||||||
|
* IS the invert toggle's sliding disc. Hand-rolled because lucide's
|
||||||
|
* Contrast leaves its half-moon unfilled (fill="none" by default) — the
|
||||||
|
* owner's catch: the filled side must be ACTUALLY filled. Same geometry
|
||||||
|
* as lucide's (circle r10 + left half-moon), the half carries
|
||||||
|
* fill="currentColor". */
|
||||||
|
export function InvertDiscIcon({ className }: { className?: string }) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
className={className}
|
||||||
|
aria-hidden
|
||||||
|
>
|
||||||
|
<circle cx="12" cy="12" r="10" />
|
||||||
|
<path d="M12 18a6 6 0 0 0 0-12v12z" fill="currentColor" stroke="none" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
import { useContext, useState } from "react";
|
import { useContext, useState } from "react";
|
||||||
import { ChatActionsContext } from "@/components/chat";
|
import { ChatActionsContext } from "@/components/chat";
|
||||||
import { ContrastIcon, DownloadIcon, MaximizeIcon } from "lucide-react";
|
import { DownloadIcon, MaximizeIcon } from "lucide-react";
|
||||||
|
import { InvertDiscIcon } from "@/components/artifacts/invert-disc";
|
||||||
import { Toggle } from "@/components/settings/controls";
|
import { Toggle } from "@/components/settings/controls";
|
||||||
import { useSessionMermaid } from "@/components/session-overlay";
|
import { useSessionMermaid } from "@/components/session-overlay";
|
||||||
import { downloadFile } from "@/components/artifacts/download";
|
import { downloadFile } from "@/components/artifacts/download";
|
||||||
@@ -138,7 +139,7 @@ export function VisualOutputCard({
|
|||||||
onChange={toggleInverted}
|
onChange={toggleInverted}
|
||||||
label="Invert figure brightness"
|
label="Invert figure brightness"
|
||||||
title="Invert colors"
|
title="Invert colors"
|
||||||
discIcon={<ContrastIcon className="size-3" />}
|
discIcon={<InvertDiscIcon className="size-3" />}
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
@@ -520,6 +520,12 @@ describe("artifact chrome — scrollbar, invert toggles, downloads (release poli
|
|||||||
// The invert affordance: the contrast-circle disc + the tooltip.
|
// The invert affordance: the contrast-circle disc + the tooltip.
|
||||||
assert.ok(html.includes("size-3"), "the icon disc");
|
assert.ok(html.includes("size-3"), "the icon disc");
|
||||||
assert.ok(html.includes('title="Invert colors"'), "the tooltip names the toggle");
|
assert.ok(html.includes('title="Invert colors"'), "the tooltip names the toggle");
|
||||||
|
// The half-moon is ACTUALLY filled (owner catch: lucide's Contrast
|
||||||
|
// renders it hollow — fill="none" default; ours fills currentColor).
|
||||||
|
assert.ok(
|
||||||
|
html.includes('fill="currentColor" stroke="none"'),
|
||||||
|
"the filled half of the invert disc",
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("svgNaturalWidth: declared px sizes parse; %, auto, and absent fall back to null", () => {
|
it("svgNaturalWidth: declared px sizes parse; %, auto, and absent fall back to null", () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user