mirror of
https://github.com/Boof2015/prism.git
synced 2026-08-16 00:00:31 +02:00
fix sizing issues
This commit is contained in:
+112
-89
@@ -13,7 +13,6 @@ import type { ProfileMenuRequest } from '../types/profileMenu'
|
||||
import { SCOPE_KINDS, type ScopeKind } from '../types/scope'
|
||||
|
||||
let mainWindow: BrowserWindow | null = null
|
||||
let currentSettingsHeight = 0
|
||||
let moveInterval: ReturnType<typeof setInterval> | null = null
|
||||
let moveStartCursor: { x: number; y: number } | null = null
|
||||
let moveStartPosition: number[] | null = null
|
||||
@@ -21,6 +20,8 @@ let moveStartPosition: number[] | null = null
|
||||
const scopePopoutWindows = new Map<ScopeKind, BrowserWindow>()
|
||||
const scopePopoutCloseAllowed = new Set<ScopeKind>()
|
||||
const popoutBoundsTimers = new Map<ScopeKind, ReturnType<typeof setTimeout>>()
|
||||
const windowSettingsHeights = new Map<number, number>()
|
||||
const windowSettingsBottomAnchors = new Map<number, number>()
|
||||
|
||||
const WINDOW_DEFAULTS = {
|
||||
width: 900,
|
||||
@@ -48,6 +49,99 @@ function isMainRendererWindow(window: BrowserWindow | null): boolean {
|
||||
return window !== null && window === mainWindow
|
||||
}
|
||||
|
||||
function getBaseMinHeight(window: BrowserWindow): number {
|
||||
return isMainRendererWindow(window) ? WINDOW_DEFAULTS.minHeight : POPOUT_DEFAULTS.minHeight
|
||||
}
|
||||
|
||||
function getSettingsHeight(window: BrowserWindow | null): number {
|
||||
if (!window) return 0
|
||||
return windowSettingsHeights.get(window.id) ?? 0
|
||||
}
|
||||
|
||||
function setSettingsHeightForWindow(window: BrowserWindow, height: number): void {
|
||||
const nextHeight = Math.max(0, Math.round(height))
|
||||
if (nextHeight === 0) {
|
||||
windowSettingsHeights.delete(window.id)
|
||||
windowSettingsBottomAnchors.delete(window.id)
|
||||
return
|
||||
}
|
||||
|
||||
windowSettingsHeights.set(window.id, nextHeight)
|
||||
}
|
||||
|
||||
function toLogicalBounds(window: BrowserWindow, bounds = window.getBounds()): WindowBounds {
|
||||
return {
|
||||
...bounds,
|
||||
height: Math.max(getBaseMinHeight(window), bounds.height - getSettingsHeight(window)),
|
||||
}
|
||||
}
|
||||
|
||||
function applyLogicalBounds(window: BrowserWindow, bounds: WindowBounds): void {
|
||||
window.setBounds({
|
||||
...bounds,
|
||||
height: bounds.height + getSettingsHeight(window),
|
||||
})
|
||||
}
|
||||
|
||||
function setWindowHeight(window: BrowserWindow, bounds: WindowBounds, height: number, y = bounds.y): void {
|
||||
window.setBounds({
|
||||
x: bounds.x,
|
||||
y,
|
||||
width: bounds.width,
|
||||
height,
|
||||
})
|
||||
}
|
||||
|
||||
function applySettingsHeight(window: BrowserWindow, rawNextHeight: number): void {
|
||||
const currentSettingsHeight = getSettingsHeight(window)
|
||||
const nextSettingsHeight = Math.max(0, Math.round(rawNextHeight))
|
||||
const delta = nextSettingsHeight - currentSettingsHeight
|
||||
const baseMinHeight = getBaseMinHeight(window)
|
||||
const [minW] = window.getMinimumSize()
|
||||
|
||||
window.setMinimumSize(minW, baseMinHeight + nextSettingsHeight)
|
||||
|
||||
if (delta !== 0) {
|
||||
const bounds = window.getBounds()
|
||||
const newHeight = Math.max(baseMinHeight + nextSettingsHeight, bounds.height + delta)
|
||||
const display = screen.getDisplayMatching(bounds)
|
||||
const workArea = display.workArea
|
||||
const workAreaBottom = workArea.y + workArea.height
|
||||
const bottomEdge = bounds.y + newHeight
|
||||
|
||||
if (delta > 0 && bottomEdge > workAreaBottom) {
|
||||
if (!windowSettingsBottomAnchors.has(window.id)) {
|
||||
windowSettingsBottomAnchors.set(window.id, bounds.y + bounds.height)
|
||||
}
|
||||
const newY = Math.max(workArea.y, workAreaBottom - newHeight)
|
||||
setWindowHeight(window, bounds, newHeight, newY)
|
||||
} else if (delta < 0) {
|
||||
const anchoredBottom = windowSettingsBottomAnchors.get(window.id)
|
||||
if (anchoredBottom !== undefined) {
|
||||
const targetY = Math.max(workArea.y, Math.min(anchoredBottom - newHeight, workAreaBottom - newHeight))
|
||||
setWindowHeight(window, bounds, newHeight, targetY)
|
||||
} else {
|
||||
const baseHeight = newHeight - nextSettingsHeight
|
||||
const naturalBottom = bounds.y + baseHeight
|
||||
if (naturalBottom < workAreaBottom) {
|
||||
const maxY = workAreaBottom - newHeight
|
||||
if (bounds.y < maxY) {
|
||||
setWindowHeight(window, bounds, newHeight)
|
||||
} else {
|
||||
setWindowHeight(window, bounds, newHeight, maxY)
|
||||
}
|
||||
} else {
|
||||
setWindowHeight(window, bounds, newHeight)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setWindowHeight(window, bounds, newHeight)
|
||||
}
|
||||
}
|
||||
|
||||
setSettingsHeightForWindow(window, nextSettingsHeight)
|
||||
}
|
||||
|
||||
function sendToRenderer(sender: WebContents, channel: string, ...args: unknown[]): void {
|
||||
if (!sender.isDestroyed()) {
|
||||
sender.send(channel, ...args)
|
||||
@@ -189,8 +283,11 @@ function createMainWindow(): void {
|
||||
})
|
||||
|
||||
mainWindow.on('closed', () => {
|
||||
if (mainWindow) {
|
||||
windowSettingsHeights.delete(mainWindow.id)
|
||||
windowSettingsBottomAnchors.delete(mainWindow.id)
|
||||
}
|
||||
mainWindow = null
|
||||
currentSettingsHeight = 0
|
||||
|
||||
for (const kind of SCOPE_KINDS) {
|
||||
destroyScopePopoutWindow(kind)
|
||||
@@ -219,7 +316,7 @@ function emitPopoutBoundsChanged(kind: ScopeKind, window: BrowserWindow): void {
|
||||
popoutBoundsTimers.delete(kind)
|
||||
|
||||
if (!mainWindow || mainWindow.isDestroyed() || window.isDestroyed()) return
|
||||
const bounds = window.getBounds()
|
||||
const bounds = toLogicalBounds(window)
|
||||
mainWindow.webContents.send('scope-popout:bounds-changed', kind, bounds)
|
||||
}, 80)
|
||||
|
||||
@@ -293,6 +390,7 @@ function createScopePopoutWindow(kind: ScopeKind, rawBounds?: WindowBounds): Bro
|
||||
}
|
||||
|
||||
const popoutWindow = new BrowserWindow(options)
|
||||
setSettingsHeightForWindow(popoutWindow, 0)
|
||||
scopePopoutWindows.set(kind, popoutWindow)
|
||||
|
||||
popoutWindow.once('ready-to-show', () => {
|
||||
@@ -311,6 +409,8 @@ function createScopePopoutWindow(kind: ScopeKind, rawBounds?: WindowBounds): Bro
|
||||
})
|
||||
|
||||
popoutWindow.on('closed', () => {
|
||||
windowSettingsHeights.delete(popoutWindow.id)
|
||||
windowSettingsBottomAnchors.delete(popoutWindow.id)
|
||||
scopePopoutWindows.delete(kind)
|
||||
scopePopoutCloseAllowed.delete(kind)
|
||||
|
||||
@@ -348,7 +448,7 @@ function syncScopePopouts(nextState: ScopePopoutSyncStateMap): void {
|
||||
|| currentBounds.height !== nextBounds.height
|
||||
|
||||
if (hasBoundsDelta) {
|
||||
popoutWindow.setBounds(nextBounds)
|
||||
applyLogicalBounds(popoutWindow, nextBounds)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -486,30 +586,14 @@ function setupIPC(): void {
|
||||
const targetWindow = getWindowFromSender(event.sender)
|
||||
if (!targetWindow) return
|
||||
|
||||
if (isMainRendererWindow(targetWindow)) {
|
||||
targetWindow.setBounds({
|
||||
...bounds,
|
||||
height: bounds.height + currentSettingsHeight,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
targetWindow.setBounds(bounds)
|
||||
applyLogicalBounds(targetWindow, bounds)
|
||||
})
|
||||
|
||||
ipcMain.handle('window:get-bounds', (event) => {
|
||||
const targetWindow = getWindowFromSender(event.sender)
|
||||
if (!targetWindow) return null
|
||||
|
||||
const bounds = targetWindow.getBounds()
|
||||
if (!isMainRendererWindow(targetWindow)) {
|
||||
return bounds
|
||||
}
|
||||
|
||||
return {
|
||||
...bounds,
|
||||
height: bounds.height - currentSettingsHeight,
|
||||
}
|
||||
return toLogicalBounds(targetWindow)
|
||||
})
|
||||
|
||||
ipcMain.on('window:reposition', (event, position: 'top' | 'bottom') => {
|
||||
@@ -530,84 +614,23 @@ function setupIPC(): void {
|
||||
|
||||
ipcMain.on('window:expand-settings', (event, panelHeight: number) => {
|
||||
const targetWindow = getWindowFromSender(event.sender)
|
||||
if (!targetWindow || !isMainRendererWindow(targetWindow)) return
|
||||
if (!targetWindow) return
|
||||
|
||||
const bounds = targetWindow.getBounds()
|
||||
const [minW] = targetWindow.getMinimumSize()
|
||||
const newHeight = bounds.height + panelHeight
|
||||
targetWindow.setMinimumSize(minW, WINDOW_DEFAULTS.minHeight + panelHeight)
|
||||
|
||||
const display = screen.getDisplayMatching(bounds)
|
||||
const workArea = display.workArea
|
||||
const bottomEdge = bounds.y + newHeight
|
||||
if (bottomEdge > workArea.y + workArea.height) {
|
||||
const newY = Math.max(workArea.y, workArea.y + workArea.height - newHeight)
|
||||
targetWindow.setBounds({ x: bounds.x, y: newY, width: bounds.width, height: newHeight })
|
||||
} else {
|
||||
targetWindow.setSize(bounds.width, newHeight, true)
|
||||
}
|
||||
currentSettingsHeight = Math.max(0, currentSettingsHeight + Math.round(panelHeight))
|
||||
applySettingsHeight(targetWindow, getSettingsHeight(targetWindow) + panelHeight)
|
||||
})
|
||||
|
||||
ipcMain.on('window:collapse-settings', (event, panelHeight: number) => {
|
||||
const targetWindow = getWindowFromSender(event.sender)
|
||||
if (!targetWindow || !isMainRendererWindow(targetWindow)) return
|
||||
if (!targetWindow) return
|
||||
|
||||
const bounds = targetWindow.getBounds()
|
||||
const [minW] = targetWindow.getMinimumSize()
|
||||
const newHeight = Math.max(WINDOW_DEFAULTS.minHeight, bounds.height - panelHeight)
|
||||
targetWindow.setMinimumSize(minW, WINDOW_DEFAULTS.minHeight)
|
||||
|
||||
const display = screen.getDisplayMatching(bounds)
|
||||
const workArea = display.workArea
|
||||
const wasAtBottom = bounds.y + bounds.height >= workArea.y + workArea.height - 10
|
||||
if (wasAtBottom) {
|
||||
const newY = Math.min(bounds.y + panelHeight, workArea.y + workArea.height - newHeight)
|
||||
targetWindow.setBounds({ x: bounds.x, y: newY, width: bounds.width, height: newHeight })
|
||||
} else {
|
||||
targetWindow.setSize(bounds.width, newHeight, true)
|
||||
}
|
||||
currentSettingsHeight = Math.max(0, currentSettingsHeight - Math.round(panelHeight))
|
||||
applySettingsHeight(targetWindow, getSettingsHeight(targetWindow) - panelHeight)
|
||||
})
|
||||
|
||||
ipcMain.on('window:set-settings-height', (event, panelHeight: number) => {
|
||||
const targetWindow = getWindowFromSender(event.sender)
|
||||
if (!targetWindow || !isMainRendererWindow(targetWindow)) return
|
||||
if (!targetWindow) return
|
||||
|
||||
const nextHeight = Math.max(0, Math.round(panelHeight))
|
||||
const delta = nextHeight - currentSettingsHeight
|
||||
const [width, height] = targetWindow.getSize()
|
||||
const [minW] = targetWindow.getMinimumSize()
|
||||
|
||||
targetWindow.setMinimumSize(minW, WINDOW_DEFAULTS.minHeight + nextHeight)
|
||||
if (delta !== 0) {
|
||||
const newHeight = Math.max(WINDOW_DEFAULTS.minHeight, height + delta)
|
||||
const bounds = targetWindow.getBounds()
|
||||
const display = screen.getDisplayMatching(bounds)
|
||||
const workArea = display.workArea
|
||||
const bottomEdge = bounds.y + newHeight
|
||||
if (delta > 0 && bottomEdge > workArea.y + workArea.height) {
|
||||
const newY = Math.max(workArea.y, workArea.y + workArea.height - newHeight)
|
||||
targetWindow.setBounds({ x: bounds.x, y: newY, width, height: newHeight })
|
||||
} else if (delta < 0) {
|
||||
const baseHeight = newHeight - nextHeight
|
||||
const naturalBottom = bounds.y + baseHeight
|
||||
if (naturalBottom < workArea.y + workArea.height) {
|
||||
const maxY = workArea.y + workArea.height - newHeight
|
||||
if (bounds.y < maxY) {
|
||||
targetWindow.setSize(width, newHeight, true)
|
||||
} else {
|
||||
targetWindow.setBounds({ x: bounds.x, y: maxY, width, height: newHeight })
|
||||
}
|
||||
} else {
|
||||
targetWindow.setSize(width, newHeight, true)
|
||||
}
|
||||
} else {
|
||||
targetWindow.setSize(width, newHeight, true)
|
||||
}
|
||||
}
|
||||
|
||||
currentSettingsHeight = nextHeight
|
||||
applySettingsHeight(targetWindow, panelHeight)
|
||||
})
|
||||
|
||||
ipcMain.on('scope-popout:sync', (event, state: ScopePopoutSyncStateMap) => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useCallback, useEffect, useMemo, useRef, useState, type JSX, type MouseEvent as ReactMouseEvent, type PointerEvent as ReactPointerEvent } from 'react'
|
||||
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, type JSX, type MouseEvent as ReactMouseEvent, type PointerEvent as ReactPointerEvent } from 'react'
|
||||
import type { ScopePopoutSnapshot } from '../../types/popout'
|
||||
import { SCOPE_LABELS, type ScopeKind } from '../../types/scope'
|
||||
import { DEFAULT_SCOPE_SETTINGS, type ScopeSettings } from '../../types/settings'
|
||||
@@ -41,11 +41,12 @@ interface ScopePopoutWindowProps {
|
||||
scopeKind: ScopeKind
|
||||
}
|
||||
|
||||
const POPOUT_SETTINGS_EXPAND_HEIGHT = 260
|
||||
|
||||
export default function ScopePopoutWindow({ scopeKind }: ScopePopoutWindowProps): JSX.Element {
|
||||
const [snapshot, setSnapshot] = useState<ScopePopoutSnapshot<ScopeKind> | null>(null)
|
||||
const [miniSettingsOpen, setMiniSettingsOpen] = useState(false)
|
||||
const [chromeHeight, setChromeHeight] = useState(0)
|
||||
const chromeRef = useRef<HTMLDivElement>(null)
|
||||
const prevMiniSettingsOpenRef = useRef(false)
|
||||
const dataSource = useMemo(() => new ScopePopoutDataSource(scopeKind), [scopeKind])
|
||||
|
||||
useEffect(() => {
|
||||
@@ -74,6 +75,7 @@ export default function ScopePopoutWindow({ scopeKind }: ScopePopoutWindowProps)
|
||||
|
||||
const effectiveAccent = snapshot?.accent ?? '#38bdf8'
|
||||
const effectiveSettings = (snapshot?.settings ?? DEFAULT_SCOPE_SETTINGS[scopeKind]) as ScopeSettings[ScopeKind]
|
||||
const settingsHeight = miniSettingsOpen ? POPOUT_SETTINGS_EXPAND_HEIGHT : 0
|
||||
|
||||
const handleUpdateScopeSettings = <K extends ScopeKind>(kind: K, partial: Partial<ScopeSettings[K]>): void => {
|
||||
if (kind !== scopeKind) return
|
||||
@@ -121,26 +123,21 @@ export default function ScopePopoutWindow({ scopeKind }: ScopePopoutWindowProps)
|
||||
window.electronAPI.stopWindowMove()
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
const chrome = chromeRef.current
|
||||
if (!chrome) return
|
||||
|
||||
const updateHeight = (): void => {
|
||||
setChromeHeight(chrome.scrollHeight)
|
||||
useLayoutEffect(() => {
|
||||
if (miniSettingsOpen && !prevMiniSettingsOpenRef.current) {
|
||||
window.electronAPI.expandSettings(POPOUT_SETTINGS_EXPAND_HEIGHT)
|
||||
} else if (!miniSettingsOpen && prevMiniSettingsOpenRef.current) {
|
||||
window.electronAPI.collapseSettings(POPOUT_SETTINGS_EXPAND_HEIGHT)
|
||||
}
|
||||
|
||||
updateHeight()
|
||||
|
||||
const observer = typeof ResizeObserver === 'undefined'
|
||||
? null
|
||||
: new ResizeObserver(() => updateHeight())
|
||||
observer?.observe(chrome)
|
||||
|
||||
return () => observer?.disconnect()
|
||||
}, [miniSettingsOpen, snapshot])
|
||||
prevMiniSettingsOpenRef.current = miniSettingsOpen
|
||||
}, [miniSettingsOpen])
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (prevMiniSettingsOpenRef.current) {
|
||||
window.electronAPI.setSettingsHeight(0)
|
||||
}
|
||||
window.electronAPI.stopWindowMove()
|
||||
}
|
||||
}, [])
|
||||
@@ -152,57 +149,77 @@ export default function ScopePopoutWindow({ scopeKind }: ScopePopoutWindowProps)
|
||||
onMouseUp={handleAltDragEnd}
|
||||
>
|
||||
<div
|
||||
ref={chromeRef}
|
||||
className={[
|
||||
'scope-popout__chrome',
|
||||
miniSettingsOpen ? 'is-expanded' : '',
|
||||
].join(' ').trim()}
|
||||
className="scope-popout__viewport"
|
||||
style={{ height: `calc(100vh - ${settingsHeight}px)` }}
|
||||
>
|
||||
<header className="scope-popout__header">
|
||||
<div className="scope-popout__drag">
|
||||
<button
|
||||
type="button"
|
||||
className="scope-popout__drag-handle"
|
||||
onPointerDown={handleDragStart}
|
||||
onPointerUp={handleDragEnd}
|
||||
onPointerCancel={handleDragEnd}
|
||||
onLostPointerCapture={handleDragEnd}
|
||||
aria-label="Drag window"
|
||||
title="Drag window"
|
||||
>
|
||||
<span className="scope-popout__drag-icon" aria-hidden="true">
|
||||
<GripIcon />
|
||||
</span>
|
||||
</button>
|
||||
<div className="scope-popout__title-group">
|
||||
<span className="scope-popout__title">{snapshot?.label ?? SCOPE_LABELS[scopeKind]}</span>
|
||||
<span className="scope-popout__subtitle">Detached Scope</span>
|
||||
<div
|
||||
className={[
|
||||
'scope-popout__chrome',
|
||||
miniSettingsOpen ? 'is-expanded' : '',
|
||||
].join(' ').trim()}
|
||||
>
|
||||
<header className="scope-popout__header">
|
||||
<div className="scope-popout__drag">
|
||||
<button
|
||||
type="button"
|
||||
className="scope-popout__drag-handle"
|
||||
onPointerDown={handleDragStart}
|
||||
onPointerUp={handleDragEnd}
|
||||
onPointerCancel={handleDragEnd}
|
||||
onLostPointerCapture={handleDragEnd}
|
||||
aria-label="Drag window"
|
||||
title="Drag window"
|
||||
>
|
||||
<span className="scope-popout__drag-icon" aria-hidden="true">
|
||||
<GripIcon />
|
||||
</span>
|
||||
</button>
|
||||
<div className="scope-popout__title-group">
|
||||
<span className="scope-popout__title">{snapshot?.label ?? SCOPE_LABELS[scopeKind]}</span>
|
||||
<span className="scope-popout__subtitle">Detached Scope</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="scope-popout__actions">
|
||||
<button
|
||||
type="button"
|
||||
className={`scope-popout__button ${miniSettingsOpen ? 'is-active' : ''}`.trim()}
|
||||
onClick={() => setMiniSettingsOpen((prev) => !prev)}
|
||||
aria-label="Toggle mini settings"
|
||||
title="Mini settings"
|
||||
>
|
||||
<SettingsIcon />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="scope-popout__button"
|
||||
onClick={() => window.electronAPI.requestScopePopIn(scopeKind)}
|
||||
aria-label={`Pop in ${SCOPE_LABELS[scopeKind]}`}
|
||||
title={`Pop in ${SCOPE_LABELS[scopeKind]}`}
|
||||
>
|
||||
<PopInIcon />
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
<div className="scope-popout__actions">
|
||||
<button
|
||||
type="button"
|
||||
className={`scope-popout__button ${miniSettingsOpen ? 'is-active' : ''}`.trim()}
|
||||
onClick={() => setMiniSettingsOpen((prev) => !prev)}
|
||||
aria-label="Toggle mini settings"
|
||||
title="Mini settings"
|
||||
>
|
||||
<SettingsIcon />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="scope-popout__button"
|
||||
onClick={() => window.electronAPI.requestScopePopIn(scopeKind)}
|
||||
aria-label={`Pop in ${SCOPE_LABELS[scopeKind]}`}
|
||||
title={`Pop in ${SCOPE_LABELS[scopeKind]}`}
|
||||
>
|
||||
<PopInIcon />
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
|
||||
{miniSettingsOpen && (
|
||||
<div className="scope-popout__content">
|
||||
<div className="scope-popout__canvas-region">
|
||||
<ScopeModule
|
||||
scopeKind={scopeKind}
|
||||
lineColor={effectiveAccent}
|
||||
settings={effectiveSettings}
|
||||
dataSource={dataSource}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{miniSettingsOpen && (
|
||||
<div
|
||||
className="scope-popout__settings-region"
|
||||
style={{ height: `${settingsHeight}px` }}
|
||||
>
|
||||
<div className="scope-popout__settings-panel">
|
||||
<ScopeSettingsSection
|
||||
kind={scopeKind}
|
||||
@@ -210,22 +227,8 @@ export default function ScopePopoutWindow({ scopeKind }: ScopePopoutWindowProps)
|
||||
onUpdate={handleUpdateScopeSettings}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="scope-popout__content"
|
||||
style={miniSettingsOpen ? { paddingTop: `${chromeHeight}px` } : undefined}
|
||||
>
|
||||
<div className="scope-popout__canvas-region">
|
||||
<ScopeModule
|
||||
scopeKind={scopeKind}
|
||||
lineColor={effectiveAccent}
|
||||
settings={effectiveSettings}
|
||||
dataSource={dataSource}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -817,6 +817,13 @@ select {
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.scope-popout__viewport {
|
||||
position: relative;
|
||||
flex: 0 0 auto;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.scope-popout__chrome {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@@ -831,7 +838,7 @@ select {
|
||||
transition: max-height 160ms ease, opacity 120ms ease, transform 160ms ease;
|
||||
}
|
||||
|
||||
.scope-popout:hover .scope-popout__chrome,
|
||||
.scope-popout__viewport:hover .scope-popout__chrome,
|
||||
.scope-popout__chrome:hover,
|
||||
.scope-popout__chrome.is-expanded {
|
||||
max-height: 58px;
|
||||
@@ -840,10 +847,6 @@ select {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.scope-popout__chrome.is-expanded {
|
||||
max-height: 420px;
|
||||
}
|
||||
|
||||
.scope-popout__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -951,12 +954,12 @@ select {
|
||||
}
|
||||
|
||||
.scope-popout__settings-panel {
|
||||
flex-shrink: 0;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
background: linear-gradient(180deg, rgba(6, 8, 11, 0.98), rgba(4, 5, 7, 0.98));
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
||||
padding: 12px 0 8px;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.06);
|
||||
padding: 12px 0 10px;
|
||||
}
|
||||
|
||||
.scope-popout__settings-panel .settings-scope-section {
|
||||
@@ -964,12 +967,17 @@ select {
|
||||
padding: 0 14px 12px;
|
||||
}
|
||||
|
||||
.scope-popout__settings-region {
|
||||
flex: 0 0 auto;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.scope-popout__content {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
transition: padding-top 160ms ease;
|
||||
}
|
||||
|
||||
.scope-popout__canvas-region {
|
||||
|
||||
Reference in New Issue
Block a user