summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authoradamelmore <[email protected]>2026-01-25 19:07:19 -0600
committeradamelmore <[email protected]>2026-01-25 19:07:24 -0600
commit5369e96ab70b88abf1492c50f191dcf9e3bb7108 (patch)
tree466c39d6d5ff44a445a432d18033511eadab7058
parentfbcf13852658750bc3e5ba4d7114f7411f61a772 (diff)
downloadopencode-5369e96ab70b88abf1492c50f191dcf9e3bb7108.tar.gz
opencode-5369e96ab70b88abf1492c50f191dcf9e3bb7108.zip
fix(app): line selection colors
-rw-r--r--packages/ui/src/components/code.tsx27
-rw-r--r--packages/ui/src/components/diff-ssr.tsx20
-rw-r--r--packages/ui/src/components/diff.tsx27
-rw-r--r--packages/ui/src/pierre/index.ts25
4 files changed, 90 insertions, 9 deletions
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<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,11 +382,25 @@ 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 ?? []
requestAnimationFrame(() => applyCommentedLines(ranges))
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<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),
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<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,11 +501,25 @@ 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 ?? []
requestAnimationFrame(() => applyCommentedLines(ranges))
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] {