Desktop Window

import { DesktopWindow, DesktopWindowControls } from '@hanzo/ui'

Default

A title bar with traffic lights over a content area; drag the bar to move it, drag the corner to resize.

export function Default() {
return (
<YStack height={360} position="relative">
<DesktopWindow title="Editor" initialPosition={{ x: 20, y: 20 }} initialSize={{ width: 420, height: 260 }} >
<YStack p="$4" gap="$2">
<Text fontWeight="600">Window content</Text>
<Text color="$color11">Drag the title bar to move it.</Text>
</YStack>
</DesktopWindow>
</YStack>
)
}

Window types

The four documented surfaces: default, dark, light and transparent.

export function WindowTypes() {
return (
<XStack height={220} gap="$4" flexWrap="wrap">
{(["default", "dark", "light", "transparent"] as const).map((windowType, i) => (
<YStack key={windowType} height={200} width={220} position="relative">
<DesktopWindow title={windowType} windowType={windowType} initialPosition={{ x: 0, y: 0 }} initialSize={{ width: 200, height: 140 }} draggable={false} resizable={false} hideControls={i === 3} >
<YStack p="$3">
<Text>{windowType} window</Text>
</YStack>
</DesktopWindow>
</YStack>
))}
</XStack>
)
}

Controlled close

The close light calls back into your own state, so the window can be reopened from a button.

export function ControlledClose() {
const [open, setOpen] = useState(true)
return (
<YStack height={300} position="relative" gap="$3">
{!open ? (
<Button variant="outline" onPress={() => setOpen(true)}>
Reopen Settings
</Button>
) : null}
{open ? (
<DesktopWindow title="Settings" onClose={() => setOpen(false)} initialPosition={{ x: 10, y: 10 }} initialSize={{ width: 360, height: 220 }} >
<YStack p="$4" gap="$2">
<Text>Settings content goes here.</Text>
</YStack>
</DesktopWindow>
) : null}
</YStack>
)
}

No controls

`hideControls` drops the traffic lights for a window whose state is shown elsewhere.

export function NoControls() {
return (
<YStack height={220} position="relative">
<DesktopWindow title="Read-only preview" hideControls draggable={false} resizable={false} initialPosition={{ x: 0, y: 0 }} initialSize={{ width: 320, height: 180 }} >
<YStack p="$4">
<Text>No traffic lights, no drag, no resize.</Text>
</YStack>
</DesktopWindow>
</YStack>
)
}

Types

export type DesktopWindowType = 'default' | 'dark' | 'light' | 'transparent'
export type DesktopWindowControlsProps = {
onClose?: () => void
onMinimize?: () => void
onMaximize?: () => void
isMaximized?: boolean
}
export type DesktopWindowProps = {
/** Text shown in the title bar. */
title: string
icon?: ReactNode
children?: ReactNode
onClose?: () => void
onMinimize?: () => void
onMaximize?: () => void
/** Fires on pointer-down anywhere on the frame — wire it to bring-to-front. */
onFocus?: () => void
initialPosition?: { x: number; y: number }
initialSize?: { width: number; height: number }
minWidth?: number
minHeight?: number
maxWidth?: number
maxHeight?: number
/** Style variant — the frame's background, border and title-text color. */
windowType?: DesktopWindowType
/** Drag the corner to resize. Defaults to on. */
resizable?: boolean
/** Drag the title bar to move. Defaults to on. */
draggable?: boolean
/** Hide the three traffic-light dots. */
hideControls?: boolean
zIndex?: number
}

Exports

DesktopWindowDesktopWindowControlstype DesktopWindowControlsPropstype DesktopWindowPropstype DesktopWindowType