Skip to content
/ TUIkit Public

Commit f654ea4

Browse files
committed
Update status bar shortcut documentation
1 parent 57f2b4e commit f654ea4

4 files changed

Lines changed: 138 additions & 27 deletions

File tree

Sources/TUIkit/Extensions/View+Events.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,10 @@ extension View {
255255
/// When this view is rendered, the specified items will be displayed
256256
/// in the status bar. This replaces any existing global items.
257257
///
258+
/// If a user item uses the same shortcut string as a system item
259+
/// (for example `q`), the user item wins in both display and event
260+
/// handling for that view context.
261+
///
258262
/// # Example
259263
///
260264
/// ```swift
@@ -283,6 +287,10 @@ extension View {
283287
/// items using the `.merge` strategy (default). Use
284288
/// ``statusBarItems(_:_:)`` to specify a different strategy.
285289
///
290+
/// A user-defined item can intentionally override a system shortcut such
291+
/// as `q`. When the item has an action, it intercepts the key before the
292+
/// built-in quit binding runs.
293+
///
286294
/// # Example
287295
///
288296
/// ```swift
@@ -309,6 +317,9 @@ extension View {
309317
/// Child wins on shortcut conflict.
310318
/// - **`.replace`**: Items replace all parent items (cascade barrier).
311319
///
320+
/// Shortcut conflicts are resolved in favor of the most local user item.
321+
/// This also applies to system shortcuts such as `q`.
322+
///
312323
/// # Example
313324
///
314325
/// ```swift

Sources/TUIkit/Modifiers/StatusBarSystemItemsModifier.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ public extension View {
6868
/// .statusBarSystemItems(theme: true, appearance: true)
6969
/// ```
7070
///
71+
/// To hide the status bar completely, combine this with no registered
72+
/// user items and set ``StatusBarState/showSystemItems`` to `false`.
73+
///
7174
/// - Parameters:
7275
/// - theme: Whether to show the theme switcher (`t theme`). Default is `false`.
7376
/// - appearance: Whether to show the appearance switcher (`a appearance`). Default is `false`.

Sources/TUIkit/TUIkit.docc/Articles/KeyboardShortcuts.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,39 @@ Dialog(title: "Confirm") {
186186
}
187187
```
188188

189+
### Changing the built-in quit key
190+
191+
The default quit binding is configurable through ``StatusBarState/quitShortcut``:
192+
193+
```swift
194+
@Environment(\.statusBar) private var statusBar
195+
196+
statusBar.quitShortcut = .escape
197+
statusBar.quitShortcut = .ctrlQ
198+
statusBar.quitShortcut = QuitShortcut(
199+
key: .f12,
200+
shortcutSymbol: Shortcut.f12,
201+
label: "exit"
202+
)
203+
```
204+
205+
This changes both the Layer 4 quit binding and the displayed system item.
206+
207+
### Overriding `q` in a local view context
208+
209+
A user-defined status bar item with shortcut `q` and an action intercepts the key before the default quit binding runs:
210+
211+
```swift
212+
EditorView()
213+
.statusBarItems {
214+
StatusBarItem(shortcut: "q", label: "close") {
215+
dismissEditor()
216+
}
217+
}
218+
```
219+
220+
This is the correct way to repurpose `q` for a specific screen, dialog, or focus section. The matching user item handles the event in Layer 1, so Layer 4's built-in quit binding is never reached.
221+
189222
## Status Bar Shortcuts
190223

191224
The status bar displays available shortcuts to the user. Use the ``Shortcut`` namespace for consistent, platform-standard symbols:
@@ -304,6 +337,8 @@ statusBar.showThemeItem = false // Hide only theme cycling
304337
statusBar.showAppearanceItem = false // Hide only appearance cycling
305338
```
306339

340+
When all system items are hidden and there are no active user items, the status bar is hidden completely.
341+
307342
## Topics
308343

309344
### Input Types

Sources/TUIkit/TUIkit.docc/Articles/StatusBarGuide.md

Lines changed: 89 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ Configure the shortcut bar at the bottom of the terminal.
44

55
## Overview
66

7-
The status bar is a persistent row at the bottom of the terminal that shows keyboard shortcuts and contextual information. It is always visible and updates every frame.
7+
The status bar is a row at the bottom of the terminal that shows keyboard shortcuts and contextual information. It updates every frame while it has active items.
8+
9+
The status bar is hidden automatically when there are no active user items and no visible system items.
810

911
TUIkit provides two status bar styles: ``StatusBarStyle/compact`` (single-line, shortcuts only) and ``StatusBarStyle/bordered`` (bordered with title support).
1012

@@ -25,60 +27,120 @@ VStack {
2527
Text("My App")
2628
}
2729
.statusBarItems {
28-
StatusBarItem(.character("n"), label: "New") {
30+
StatusBarItem(shortcut: "n", label: "new") {
2931
// handle "n" key press
3032
}
31-
StatusBarItem(.character("d"), label: "Delete") {
33+
StatusBarItem(shortcut: "d", label: "delete") {
3234
// handle "d" key press
3335
}
3436
}
3537
```
3638

3739
Items are registered per frame during rendering. When a view is removed from the tree, its items automatically disappear from the status bar.
3840

39-
## The Shortcut Enum
41+
## Shortcut Display Symbols
4042

41-
``Shortcut`` defines the key trigger for a status bar item:
43+
Use ``Shortcut`` to keep displayed shortcut symbols consistent:
4244

43-
| Shortcut | Display | Description |
45+
| Constant | Display | Description |
4446
|----------|---------|-------------|
45-
| `.character("q")` | `q` | A single character key |
46-
| `.tab` | `` | Tab key |
47-
| `.enter` | `` | Enter / Return |
48-
| `.escape` | `` | Escape key |
49-
| `.backspace` | `` | Backspace / Delete |
50-
| `.arrows` | `↑↓` | Arrow keys |
51-
| `.arrowsHorizontal` | `←→` | Left / Right arrows |
52-
| `.arrowsVertical` | `↑↓` | Up / Down arrows |
47+
| `Shortcut.quit` | `q` | Default quit display |
48+
| `Shortcut.enter` | `` | Enter / Return |
49+
| `Shortcut.escape` | `` | Escape |
50+
| `Shortcut.tab` | `` | Tab |
51+
| `Shortcut.arrowUp` | `` | Arrow up |
52+
| `Shortcut.arrowDown` | `` | Arrow down |
53+
| `Shortcut.arrowsUpDown` | `↑↓` | Vertical navigation |
54+
| `Shortcut.ctrl("q")` | `⌃q` | Ctrl+Q display |
55+
56+
`Shortcut` defines how the item is displayed. If you do not pass `key:`, `StatusBarItem` derives a trigger key from the shortcut string where possible.
5357

5458
## Context Stack
5559

56-
Status bar items use a **context stack**. When a dialog or menu opens, it can push its own items onto the stack. The status bar always shows the topmost context:
60+
Status bar items use a **context stack**. Context-specific items can temporarily replace global items, for example while a dialog is visible:
5761

5862
```swift
59-
// Push a new context (e.g. when opening a dialog)
60-
statusBar.pushContext()
61-
62-
// Add items to the new context
63-
statusBar.addItem(StatusBarItem(.escape, label: "Close") { ... })
64-
65-
// Pop the context when the dialog closes
66-
statusBar.popContext()
63+
Dialog(title: "Confirm") {
64+
Text("Delete file?")
65+
} footer: {
66+
ButtonRow {
67+
Button("Delete") { delete() }
68+
Button("Cancel") { cancel() }
69+
}
70+
}
71+
.statusBarItems(context: "confirm-dialog") {
72+
StatusBarItem(shortcut: "y", label: "yes") { delete() }
73+
StatusBarItem(shortcut: "n", label: "no") { cancel() }
74+
}
6775
```
6876

69-
This means the main view's shortcuts are hidden while a modal is active, and automatically restored when it closes.
77+
The topmost context replaces global user items in the display. System items remain visible unless a user item uses the same shortcut string.
7078

7179
## System Items
7280

7381
TUIkit registers built-in system items automatically:
7482

7583
| Key | Label | Action |
7684
|-----|-------|--------|
77-
| `q` / `Ctrl+C` | Quit | Exit the application |
78-
| `p` | Palette | Cycle to next color palette |
85+
| `q` | Quit | Exit the application |
7986
| `a` | Appearance | Cycle to next border appearance |
87+
| `t` | Theme | Cycle to next color theme |
88+
89+
These appear on the right side of the status bar. Only `q quit` is shown by default. Enable `a appearance` and `t theme` with the ``View/statusBarSystemItems(theme:appearance:)`` modifier.
90+
91+
### Overriding `q quit`
92+
93+
A user-defined status bar item with shortcut `q` overrides the built-in quit binding for that view context:
94+
95+
```swift
96+
EditorView()
97+
.statusBarItems {
98+
StatusBarItem(shortcut: "q", label: "close") {
99+
closeEditor()
100+
}
101+
}
102+
```
103+
104+
This works because status bar items with actions are handled before the default quit binding. The built-in `q quit` system item is also removed from the display when a user item uses the same shortcut string.
105+
106+
### Changing the global quit shortcut
107+
108+
Change the built-in quit key through ``StatusBarState/quitShortcut``:
109+
110+
```swift
111+
@main
112+
struct MyApp: App {
113+
@Environment(\.statusBar) private var statusBar
114+
115+
var body: some Scene {
116+
WindowGroup {
117+
ContentView()
118+
}
119+
.task {
120+
statusBar.quitShortcut = .escape
121+
}
122+
}
123+
}
124+
```
125+
126+
Available presets include ``QuitShortcut/q``, ``QuitShortcut/escape``, ``QuitShortcut/ctrlQ``, and ``QuitShortcut/ctrlC``. You can also create a fully custom ``QuitShortcut``.
127+
128+
### Hiding the status bar completely
129+
130+
Hide all system items and do not register any user items:
131+
132+
```swift
133+
ContentView()
134+
.statusBarSystemItems(theme: false, appearance: false)
135+
```
136+
137+
```swift
138+
@Environment(\.statusBar) private var statusBar
139+
140+
statusBar.showSystemItems = false
141+
```
80142

81-
These appear on the right side of the status bar. You can configure quit behavior via ``QuitBehavior``.
143+
When there are no active items left, the status bar height becomes zero and it is not rendered.
82144

83145
## Status Bar Styles
84146

0 commit comments

Comments
 (0)