🚧 Glyx is pre-release software. APIs may change before v1.0. Get started →
Documentation
Guides
Custom Title Bar

Custom Title Bar

Glyx lets you replace the OS title bar with any React component. Set decorations: false in your config to get a frameless window, then build your own title bar in React.

Enable frameless window

In glyx.config.json:

{
  "window": {
    "decorations": false
  }
}

The OS title bar is removed. Your React component fills the entire window area.

Drag regions

Mark any View as a drag region with the glyxDraggable prop:

function TitleBar() {
  return (
    <View
      glyxDraggable
      style={{
        height: 44,
        flexDirection: 'row',
        alignItems: 'center',
        paddingHorizontal: 16,
        background: '#0E0E14',
      }}
    >
      <Text style={{ flex: 1, color: '#F0F0F2' }}>My App</Text>
 
      {/* Pressable children inside a drag region still receive press events */}
      <Pressable onPress={openMenu}>
        <Text style={{ color: '#A0A0B2' }}>Menu</Text>
      </Pressable>
    </View>
  )
}

glyxDraggable is a Glyx component prop, not a CSS style. Click-and-drag on a glyxDraggable view moves the window. Pressable children inside still fire their own onPress events normally.

Window controls

Use the built-in WindowControls component, or build your own:

import { WindowControls } from '@glyx-dev/react'
 
function TitleBar() {
  return (
    <View glyxDraggable style={{ height: 44, flexDirection: 'row', alignItems: 'center' }}>
      <Text style={{ flex: 1, paddingLeft: 16, color: '#F0F0F2' }}>My App</Text>
      <WindowControls />
    </View>
  )
}

Or build custom controls with glyxWindow:

import { glyxWindow } from '@glyx-dev/react'
 
function WindowControls() {
  return (
    <View style={{ flexDirection: 'row' }}>
      <Pressable
        onPress={() => glyxWindow.setMinimized()}
        style={({ hovered }) => ({
          width: 46, height: 32,
          alignItems: 'center', justifyContent: 'center',
          background: hovered ? '#2A2A3A' : 'transparent',
        })}
      >
        <Text style={{ color: '#A0A0B2', fontSize: 16 }}>─</Text>
      </Pressable>
 
      <Pressable
        onPress={() => glyxWindow.setMaximized(!glyxWindow.isMaximized())}
        style={({ hovered }) => ({
          width: 46, height: 32,
          alignItems: 'center', justifyContent: 'center',
          background: hovered ? '#2A2A3A' : 'transparent',
        })}
      >
        <Text style={{ color: '#A0A0B2', fontSize: 12 }}>□</Text>
      </Pressable>
 
      <Pressable
        onPress={() => glyxWindow.close()}
        style={({ hovered }) => ({
          width: 46, height: 32,
          alignItems: 'center', justifyContent: 'center',
          background: hovered ? '#C42B1C' : 'transparent',
        })}
      >
        <Text style={{ color: hovered ? '#fff' : '#A0A0B2' }}>✕</Text>
      </Pressable>
    </View>
  )
}

Platform detection

Use glyxWindow.platform() to adapt the title bar per OS:

import { glyxWindow } from '@glyx-dev/react'
 
function TitleBar() {
  const isMac = glyxWindow.platform() === 'macos'
 
  return (
    <View
      glyxDraggable
      style={{
        height: 44,
        flexDirection: 'row',
        alignItems: 'center',
        // macOS: leave room on the left for the native traffic light buttons
        paddingLeft: isMac ? 76 : 16,
        paddingRight: 12,
        background: '#0E0E14',
      }}
    >
      <View style={{ flex: 1 }}>
        <TextInput placeholder="Search..." style={{ maxWidth: 280 }} />
      </View>
 
      {/* Only render custom controls on Windows/Linux */}
      {!isMac && <WindowControls />}
    </View>
  )
}

On macOS with decorations: false, the native traffic light buttons (close / minimize / maximize) remain visible in the top-left corner. You do not need to render your own close button on macOS.

Edge resize

Glyx automatically provides 8px edge resize zones on frameless windows. No additional code is needed.

Full example

import { View, Text, Pressable, TextInput } from '@glyx-dev/react'
import { glyxWindow, WindowControls } from '@glyx-dev/react'
 
export function AppShell({ children }) {
  const isMac = glyxWindow.platform() === 'macos'
 
  return (
    <View style={{ flex: 1, flexDirection: 'column' }}>
      <View
        glyxDraggable
        style={{
          height: 44,
          flexDirection: 'row',
          alignItems: 'center',
          paddingLeft: isMac ? 76 : 16,
          paddingRight: 12,
          background: '#0E0E14',
          borderBottomWidth: 1,
          borderBottomColor: '#2A2A3A',
        }}
      >
        <Text style={{ color: '#F0F0F2', fontWeight: 600, flex: 1 }}>My App</Text>
        {!isMac && <WindowControls />}
      </View>
 
      <View style={{ flex: 1 }}>
        {children}
      </View>
    </View>
  )
}