Files
zeekay cb6db9e659 design: every page and component outside the landing and beta paths is at zero lint
Inline style objects became gui props (Box for a div, View or Text rendering the
element for the rest, since Box styles only a div), raw colours and sizes became
the design's tokens, the brand swatches read @hanzo/design's own values, and the
project and creation hues moved to palette.json, which is data. The newsletter's
subscribe button is the standard filled Action. connect-steps.tsx, which nothing
imports, is deleted with the brand constants nobody read.

Pages compared before and after at 1440x900 and 390x844: blockchain, brand,
directory, projects, settings, unsubscribe identical; founder 0.03% of pixels;
buying specialist's title snaps from 28 to the ramp's 26px and the newsletter's
button is now filled.

Claude-Session: https://claude.ai/code/session_017vrVus6PPBgP5YRzKV1iqW
2026-10-26 03:49:42 -07:00

260 lines
7.6 KiB
TypeScript

'use client'
import { Box, View } from '@hanzo/ui'
import { useEffect, useState, type ReactNode } from 'react'
function getWindow() {
if (typeof window === 'undefined') return null
const w = window as any
if (w.__TAURI__?.window?.getCurrentWindow) {
try {
return w.__TAURI__.window.getCurrentWindow()
} catch {}
}
return null
}
function getWindowLabel(): string {
if (typeof window === 'undefined') return 'main'
const w = window as any
const win = getWindow()
return (
win?.label ||
w.__TAURI_INTERNALS__?.metadata?.currentWindow?.label ||
w.__TAURI_INTERNALS__?.metadata?.currentWebview?.windowLabel ||
'main'
)
}
function invokeTauri(cmd: string, args: Record<string, unknown> = {}) {
if (typeof window === 'undefined') return Promise.resolve()
const w = window as any
const label = getWindowLabel()
const payload = { label, ...args }
if (w.__TAURI_INTERNALS__?.invoke) {
return w.__TAURI_INTERNALS__.invoke(cmd, payload)
}
if (w.__TAURI__?.core?.invoke) {
return w.__TAURI__.core.invoke(cmd, payload)
}
if (w.__TAURI__?.invoke) {
return w.__TAURI__.invoke(cmd, payload)
}
return Promise.resolve()
}
const INTERACTIVE_SELECTOR = [
'button',
'input',
'select',
'textarea',
'label',
'summary',
'[role="button"]',
'[role="link"]',
'[role="menuitem"]',
'[role="menuitemcheckbox"]',
'[role="menuitemradio"]',
'[role="tab"]',
'[role="checkbox"]',
'[role="radio"]',
'[role="switch"]',
'[role="option"]',
'[role="combobox"]',
'[aria-haspopup]',
'[contenteditable="true"]',
'[tabindex]:not([tabindex="-1"])',
'[data-tauri-drag-region="false"]',
'[data-slot="window-controls"]',
].join(', ')
function isInteractiveTarget(target: EventTarget | null): boolean {
const el = target as HTMLElement | null
if (!el || typeof el.closest !== 'function') return false
if (el.closest(INTERACTIVE_SELECTOR)) return true
if (el.closest('a:not([data-tauri-drag-region])')) return true
return false
}
let lastReactMouseDown = 0
export function dragWindow(e: React.MouseEvent) {
if (e.button !== 0) return
if (isInteractiveTarget(e.target)) return
lastReactMouseDown = Date.now()
e.preventDefault?.()
e.stopPropagation?.()
if (e.detail && e.detail > 1) return
const win = getWindow()
if (win?.startDragging) {
try {
win.startDragging()
return
} catch {}
}
invokeTauri('plugin:window|start_dragging')
}
export function toggleWindowMaximize(e: React.MouseEvent) {
if (isInteractiveTarget(e.target)) return
e.preventDefault?.()
e.stopPropagation?.()
const el = e.target as HTMLElement | null
if (
e.type === 'dblclick' &&
Date.now() - lastReactMouseDown > 500 &&
typeof el?.closest === 'function' &&
el.closest('[data-tauri-drag-region]')
) {
return
}
const win = getWindow()
if (win?.toggleMaximize) {
try {
win.toggleMaximize()
return
} catch {}
}
invokeTauri('plugin:window|toggle_maximize')
}
/** One of the three controls: a quiet square that takes a wash, and the ink, on hover. */
function Control({ label, onPress, wash = 'var(--white-08)', children }: { label: string; onPress: (e: React.MouseEvent) => void | Promise<void>; wash?: 'var(--white-08)' | 'var(--state-error)'; children: ReactNode }) {
return (
<View
render={<button type="button" data-tauri-drag-region="false" aria-label={label} onClick={onPress} onMouseDown={(e) => e.stopPropagation()} />}
items="center"
justify="center"
width={28}
height={28}
rounded={6}
bg="transparent"
borderWidth={0}
cursor="pointer"
hoverStyle={{ bg: wash }}
$platform-web={{ display: 'inline-flex', flexDirection: 'row', color: 'var(--muted-foreground)', transition: 'all 0.15s ease' }}
>
{children}
</View>
)
}
export function WindowControls() {
const [isDesktop, setIsDesktop] = useState(false)
const [isMaximized, setIsMaximized] = useState(false)
useEffect(() => {
const desktop =
typeof window !== 'undefined' &&
Boolean(
(window as any).__TAURI__ ||
(window as any).__TAURI_INTERNALS__
)
setIsDesktop(desktop)
if (!desktop) return
document.documentElement.setAttribute('data-desktop', 'true')
const syncMaximized = () => {
const win = getWindow()
const checkMax = win?.isMaximized
? win.isMaximized()
: invokeTauri('plugin:window|is_maximized')
Promise.resolve(checkMax)
.then((val) => {
const max = Boolean(val)
setIsMaximized(max)
if (max) document.documentElement.setAttribute('data-maximized', 'true')
else document.documentElement.removeAttribute('data-maximized')
})
.catch(() => {})
}
syncMaximized()
window.addEventListener('resize', syncMaximized)
return () => window.removeEventListener('resize', syncMaximized)
}, [])
if (!isDesktop) return null
const handleMinimize = (e: React.MouseEvent) => {
e.preventDefault()
e.stopPropagation()
const win = getWindow()
if (win?.minimize) win.minimize().catch(() => invokeTauri('plugin:window|minimize'))
else invokeTauri('plugin:window|minimize')
}
const handleToggleMaximize = async (e: React.MouseEvent) => {
e.preventDefault()
e.stopPropagation()
const win = getWindow()
if (win?.toggleMaximize) {
await win.toggleMaximize().catch(() => invokeTauri('plugin:window|toggle_maximize'))
} else {
await invokeTauri('plugin:window|toggle_maximize')
}
const val = win?.isMaximized
? await win.isMaximized().catch(() => !isMaximized)
: await invokeTauri('plugin:window|is_maximized').catch(() => !isMaximized)
const max = Boolean(val)
setIsMaximized(max)
if (max) document.documentElement.setAttribute('data-maximized', 'true')
else document.documentElement.removeAttribute('data-maximized')
}
const handleClose = (e: React.MouseEvent) => {
e.preventDefault()
e.stopPropagation()
const win = getWindow()
if (win?.close) win.close().catch(() => invokeTauri('plugin:window|close'))
else invokeTauri('plugin:window|close')
}
return (
<Box
data-slot="window-controls"
data-tauri-drag-region="false"
items="center"
gap={4}
marginInlineStart="auto"
shrink={0}
z="var(--z-banner)"
$platform-web={{ display: 'inline-flex', userSelect: 'none', flexDirection: 'row' }}
>
<Control label="Minimize" onPress={handleMinimize}>
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.5">
<line x1="2" y1="6" x2="10" y2="6" strokeLinecap="round" />
</svg>
</Control>
<Control label={isMaximized ? 'Restore' : 'Maximize'} onPress={handleToggleMaximize}>
{isMaximized ? (
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.2">
<rect x="3.5" y="1.5" width="6.5" height="6.5" rx="1" />
<path d="M1.5 4.5v5a1 1 0 0 0 1 1h5" strokeLinecap="round" />
</svg>
) : (
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.2">
<rect x="2" y="2" width="8" height="8" rx="1.5" />
</svg>
)}
</Control>
<Control label="Close" onPress={handleClose} wash="var(--state-error)">
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.5">
<line x1="2.5" y1="2.5" x2="9.5" y2="9.5" strokeLinecap="round" />
<line x1="9.5" y1="2.5" x2="2.5" y2="9.5" strokeLinecap="round" />
</svg>
</Control>
</Box>
)
}