diff --git a/packages/ui/src/components/code.tsx b/packages/ui/src/components/code.tsx index eb0ba7826..a7687444f 100644 --- a/packages/ui/src/components/code.tsx +++ b/packages/ui/src/components/code.tsx @@ -91,6 +91,19 @@ export function Code(props: CodeProps) { return root } + const applyScheme = () => { + const host = container.querySelector("diffs-container") + if (!(host instanceof HTMLElement)) return + + const scheme = document.documentElement.dataset.colorScheme + if (scheme === "dark" || scheme === "light") { + host.dataset.colorScheme = scheme + return + } + + host.removeAttribute("data-color-scheme") + } + const applyCommentedLines = (ranges: SelectedLineRange[]) => { const root = getRoot() if (!root) return @@ -369,10 +382,24 @@ export function Code(props: CodeProps) { containerWrapper: container, }) + applyScheme() + setRendered((value) => value + 1) notifyRendered() }) + createEffect(() => { + if (typeof document === "undefined") return + if (typeof MutationObserver === "undefined") return + + const root = document.documentElement + const monitor = new MutationObserver(() => applyScheme()) + monitor.observe(root, { attributes: true, attributeFilter: ["data-color-scheme"] }) + applyScheme() + + onCleanup(() => monitor.disconnect()) + }) + createEffect(() => { rendered() const ranges = local.commentedLines ?? [] diff --git a/packages/ui/src/components/diff-ssr.tsx b/packages/ui/src/components/diff-ssr.tsx index 9456e4a3c..4ab632008 100644 --- a/packages/ui/src/components/diff-ssr.tsx +++ b/packages/ui/src/components/diff-ssr.tsx @@ -28,6 +28,16 @@ export function Diff(props: SSRDiffProps) { const getRoot = () => fileDiffRef?.shadowRoot ?? undefined + const applyScheme = () => { + const scheme = document.documentElement.dataset.colorScheme + if (scheme === "dark" || scheme === "light") { + fileDiffRef.dataset.colorScheme = scheme + return + } + + fileDiffRef.removeAttribute("data-color-scheme") + } + const findSide = (element: HTMLElement): "additions" | "deletions" => { const line = element.closest("[data-line], [data-alt-line]") if (line instanceof HTMLElement) { @@ -121,6 +131,16 @@ export function Diff(props: SSRDiffProps) { onMount(() => { if (isServer || !props.preloadedDiff) return + + applyScheme() + + if (typeof MutationObserver !== "undefined") { + const root = document.documentElement + const monitor = new MutationObserver(() => applyScheme()) + monitor.observe(root, { attributes: true, attributeFilter: ["data-color-scheme"] }) + onCleanup(() => monitor.disconnect()) + } + fileDiffInstance = new FileDiff( { ...createDefaultOptions(props.diffStyle), diff --git a/packages/ui/src/components/diff.tsx b/packages/ui/src/components/diff.tsx index 2fb2ea3bc..c97744a9f 100644 --- a/packages/ui/src/components/diff.tsx +++ b/packages/ui/src/components/diff.tsx @@ -102,6 +102,19 @@ export function Diff(props: DiffProps) { return root } + const applyScheme = () => { + const host = container.querySelector("diffs-container") + if (!(host instanceof HTMLElement)) return + + const scheme = document.documentElement.dataset.colorScheme + if (scheme === "dark" || scheme === "light") { + host.dataset.colorScheme = scheme + return + } + + host.removeAttribute("data-color-scheme") + } + const notifyRendered = () => { if (!local.onRendered) return @@ -488,10 +501,24 @@ export function Diff(props: DiffProps) { containerWrapper: container, }) + applyScheme() + setRendered((value) => value + 1) notifyRendered() }) + createEffect(() => { + if (typeof document === "undefined") return + if (typeof MutationObserver === "undefined") return + + const root = document.documentElement + const monitor = new MutationObserver(() => applyScheme()) + monitor.observe(root, { attributes: true, attributeFilter: ["data-color-scheme"] }) + applyScheme() + + onCleanup(() => monitor.disconnect()) + }) + createEffect(() => { rendered() const ranges = local.commentedLines ?? [] diff --git a/packages/ui/src/pierre/index.ts b/packages/ui/src/pierre/index.ts index a83af9890..f0da51979 100644 --- a/packages/ui/src/pierre/index.ts +++ b/packages/ui/src/pierre/index.ts @@ -35,9 +35,22 @@ const unsafeCSS = ` --diffs-selection-base: var(--surface-warning-strong); --diffs-selection-border: var(--border-warning-base); --diffs-selection-number-fg: #1c1917; - --diffs-bg-selection: var(--diffs-bg-selection-override, color-mix(in oklch, var(--surface-warning-base) 65%, transparent)); - --diffs-bg-selection-number: var(--diffs-bg-selection-number-override, color-mix(in oklch, var(--surface-warning-base) 85%, transparent)); - --diffs-bg-selection-text: color-mix(in oklch, var(--surface-warning-strong) 20%, transparent); + /* Use explicit alpha instead of color-mix(..., transparent) to avoid Safari's non-premultiplied interpolation bugs. */ + --diffs-bg-selection: var(--diffs-bg-selection-override, rgb(from var(--surface-warning-base) r g b / 0.65)); + --diffs-bg-selection-number: var( + --diffs-bg-selection-number-override, + rgb(from var(--surface-warning-base) r g b / 0.85) + ); + --diffs-bg-selection-text: rgb(from var(--surface-warning-strong) r g b / 0.2); +} + +:host([data-color-scheme='dark']) [data-diffs] { + --diffs-selection-number-fg: #fdfbfb; + --diffs-bg-selection: var(--diffs-bg-selection-override, rgb(from var(--solaris-dark-6) r g b / 0.65)); + --diffs-bg-selection-number: var( + --diffs-bg-selection-number-override, + rgb(from var(--solaris-dark-6) r g b / 0.85) + ); } [data-diffs] ::selection { @@ -78,12 +91,6 @@ const unsafeCSS = ` ); } -:host-context([data-color-scheme='dark']) [data-diffs] { - --diffs-selection-number-fg: #fdfbfb; - --diffs-bg-selection: var(--diffs-bg-selection-override, color-mix(in oklch, var(--solaris-dark-6) 65%, transparent)); - --diffs-bg-selection-number: var(--diffs-bg-selection-number-override, color-mix(in oklch, var(--solaris-dark-6) 85%, transparent)); -} - [data-diffs-header], [data-diffs] { [data-separator-wrapper] {