Merge pull request #73075 from NousResearch/bb/drop-leva-backdrop-controls

refactor(desktop): drop leva from the chat backdrop
This commit is contained in:
brooklyn! 2026-07-27 23:48:10 -05:00 committed by GitHub
commit 4cee9aab61
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 16 additions and 108 deletions

View file

@ -106,7 +106,6 @@
"hast-util-to-text": "^4.0.2",
"ignore": "^7.0.5",
"katex": "^0.16.45",
"leva": "^0.10.1",
"mermaid": "^11.15.0",
"motion": "^12.38.0",
"nanostores": "^1.3.0",

View file

@ -1,118 +1,24 @@
import { useStore } from '@nanostores/react'
import { Leva, useControls } from 'leva'
import { type CSSProperties, useEffect, useState } from 'react'
import { $backdrop } from '@/store/backdrop'
const BLEND_MODES = [
'normal',
'multiply',
'screen',
'overlay',
'darken',
'lighten',
'color-dodge',
'color-burn',
'hard-light',
'soft-light',
'difference',
'exclusion',
'hue',
'saturation',
'color',
'luminosity'
] as const
type BlendMode = (typeof BLEND_MODES)[number]
const assetPath = (path: string) => `${import.meta.env.BASE_URL}${path.replace(/^\/+/, '')}`
export function Backdrop() {
const [controlsOpen, setControlsOpen] = useState(false)
const on = useStore($backdrop)
useEffect(() => {
if (!import.meta.env.DEV) {
return
}
const onKeyDown = (event: KeyboardEvent) => {
const target = event.target as HTMLElement | null
const editing =
target?.isContentEditable ||
target instanceof HTMLInputElement ||
target instanceof HTMLTextAreaElement ||
target instanceof HTMLSelectElement
if (editing || event.repeat || event.altKey || event.ctrlKey || event.metaKey) {
return
}
if (event.shiftKey && event.code === 'KeyY') {
setControlsOpen(open => !open)
}
}
window.addEventListener('keydown', onKeyDown)
return () => window.removeEventListener('keydown', onKeyDown)
}, [])
const shape = useControls(
'UI / Shape',
{ radiusScalar: { value: 0.2, min: 0, max: 2, step: 0.1, label: 'radius scalar' } },
{ collapsed: true }
)
useEffect(() => {
document.documentElement.style.setProperty('--radius-scalar', String(shape.radiusScalar))
}, [shape.radiusScalar])
const statue = useControls(
'Backdrop / Statue',
{
enabled: { value: true, label: 'on' },
opacity: { value: 0.025, min: 0, max: 1, step: 0.005 },
blendMode: { value: 'difference' as BlendMode, options: BLEND_MODES, label: 'blend' },
invert: { value: true, label: 'invert color' },
saturate: { value: 1, min: 0, max: 3, step: 0.05, label: 'saturate' },
brightness: { value: 1, min: 0, max: 2, step: 0.05, label: 'brightness' },
objectPosition: {
value: 'top left',
options: ['top left', 'top right', 'bottom left', 'bottom right', 'center', 'top', 'bottom', 'left', 'right'],
label: 'position'
},
scale: { value: 160, min: 100, max: 300, step: 5, label: 'height (dvh)' }
},
{ collapsed: true }
)
if (!on) {
return null
}
return (
<>
<Leva collapsed hidden={!import.meta.env.DEV || !controlsOpen} titleBar={{ title: 'backdrop', drag: true }} />
{on && statue.enabled && (
<div
aria-hidden
className="pointer-events-none absolute inset-0 z-2"
style={{
mixBlendMode: statue.blendMode as CSSProperties['mixBlendMode'],
opacity: statue.opacity
}}
>
<img
alt=""
className="w-auto min-w-dvw object-cover"
fetchPriority="low"
src={assetPath('ds-assets/filler-bg0.jpg')}
style={{
height: `${statue.scale}dvh`,
objectPosition: statue.objectPosition,
filter: `invert(calc(${statue.invert ? 1 : 0} * var(--backdrop-invert-mul, 1))) saturate(${statue.saturate}) brightness(${statue.brightness})`
}}
/>
</div>
)}
</>
<div aria-hidden className="pointer-events-none absolute inset-0 z-2 opacity-[0.025] mix-blend-difference">
<img
alt=""
className="h-[160dvh] w-auto min-w-dvw object-cover object-left-top [filter:invert(var(--backdrop-invert-mul,1))]"
fetchPriority="low"
src={assetPath('ds-assets/filler-bg0.jpg')}
/>
</div>
)
}

View file

@ -387,7 +387,11 @@
--dt-spacing-mul: 1;
--radius: 0.75rem;
--radius-scalar: 0.6;
/* Effective value everywhere: the chat backdrop used to force 0.2 onto the
root element at runtime (an ungated leva slider default), so this 0.6
only ever applied to the windows that don't mount the backdrop. Pinned
to the value the app actually renders at. */
--radius-scalar: 0.2;
/* Space under last message vs overlay composer driven by the measured composer height (see composer/index.tsx)
plus the out-of-flow status stack's measured height (see status-stack/index.tsx) when one is showing.

1
package-lock.json generated
View file

@ -125,7 +125,6 @@
"hast-util-to-text": "^4.0.2",
"ignore": "^7.0.5",
"katex": "^0.16.45",
"leva": "^0.10.1",
"mermaid": "^11.15.0",
"motion": "^12.38.0",
"nanostores": "^1.3.0",