Browse Source

fix(app): line selection colors

adamelmore 3 weeks ago
parent
commit
5369e96ab7

+ 27 - 0
packages/ui/src/components/code.tsx

@@ -91,6 +91,19 @@ export function Code<T>(props: CodeProps<T>) {
     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<T>(props: CodeProps<T>) {
       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 ?? []

+ 20 - 0
packages/ui/src/components/diff-ssr.tsx

@@ -28,6 +28,16 @@ export function Diff<T>(props: SSRDiffProps<T>) {
 
   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<T>(props: SSRDiffProps<T>) {
 
   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<T>(
       {
         ...createDefaultOptions(props.diffStyle),

+ 27 - 0
packages/ui/src/components/diff.tsx

@@ -102,6 +102,19 @@ export function Diff<T>(props: DiffProps<T>) {
     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<T>(props: DiffProps<T>) {
       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 ?? []

+ 16 - 9
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] {