swift-code-reviewer-skill 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/CHANGELOG.md +43 -169
  2. package/README.md +43 -2
  3. package/SKILL.md +194 -711
  4. package/bin/install.js +1 -1
  5. package/package.json +2 -1
  6. package/references/agent-loop-feedback.md +148 -0
  7. package/references/companion-skills.md +70 -0
  8. package/references/spec-adherence.md +157 -0
  9. package/skills/README.md +43 -0
  10. package/skills/swift-concurrency/NOTICE.md +18 -0
  11. package/skills/swift-concurrency/SKILL.md +235 -0
  12. package/skills/swift-concurrency/references/actors.md +640 -0
  13. package/skills/swift-concurrency/references/async-await-basics.md +249 -0
  14. package/skills/swift-concurrency/references/async-sequences.md +635 -0
  15. package/skills/swift-concurrency/references/core-data.md +533 -0
  16. package/skills/swift-concurrency/references/glossary.md +96 -0
  17. package/skills/swift-concurrency/references/linting.md +38 -0
  18. package/skills/swift-concurrency/references/memory-management.md +542 -0
  19. package/skills/swift-concurrency/references/migration.md +721 -0
  20. package/skills/swift-concurrency/references/performance.md +574 -0
  21. package/skills/swift-concurrency/references/sendable.md +578 -0
  22. package/skills/swift-concurrency/references/tasks.md +604 -0
  23. package/skills/swift-concurrency/references/testing.md +565 -0
  24. package/skills/swift-concurrency/references/threading.md +452 -0
  25. package/skills/swift-expert/NOTICE.md +18 -0
  26. package/skills/swift-expert/SKILL.md +226 -0
  27. package/skills/swift-expert/references/async-concurrency.md +363 -0
  28. package/skills/swift-expert/references/memory-performance.md +380 -0
  29. package/skills/swift-expert/references/protocol-oriented.md +357 -0
  30. package/skills/swift-expert/references/swiftui-patterns.md +294 -0
  31. package/skills/swift-expert/references/testing-patterns.md +402 -0
  32. package/skills/swift-testing/NOTICE.md +18 -0
  33. package/skills/swift-testing/SKILL.md +295 -0
  34. package/skills/swift-testing/references/async-testing.md +245 -0
  35. package/skills/swift-testing/references/dump-snapshot-testing.md +265 -0
  36. package/skills/swift-testing/references/fixtures.md +193 -0
  37. package/skills/swift-testing/references/integration-testing.md +189 -0
  38. package/skills/swift-testing/references/migration-xctest.md +301 -0
  39. package/skills/swift-testing/references/parameterized-tests.md +171 -0
  40. package/skills/swift-testing/references/snapshot-testing.md +201 -0
  41. package/skills/swift-testing/references/test-doubles.md +243 -0
  42. package/skills/swift-testing/references/test-organization.md +231 -0
  43. package/skills/swiftui-expert-skill/NOTICE.md +18 -0
  44. package/skills/swiftui-expert-skill/SKILL.md +281 -0
  45. package/skills/swiftui-expert-skill/references/accessibility-patterns.md +151 -0
  46. package/skills/swiftui-expert-skill/references/animation-advanced.md +403 -0
  47. package/skills/swiftui-expert-skill/references/animation-basics.md +284 -0
  48. package/skills/swiftui-expert-skill/references/animation-transitions.md +326 -0
  49. package/skills/swiftui-expert-skill/references/charts-accessibility.md +135 -0
  50. package/skills/swiftui-expert-skill/references/charts.md +602 -0
  51. package/skills/swiftui-expert-skill/references/image-optimization.md +203 -0
  52. package/skills/swiftui-expert-skill/references/latest-apis.md +464 -0
  53. package/skills/swiftui-expert-skill/references/layout-best-practices.md +266 -0
  54. package/skills/swiftui-expert-skill/references/liquid-glass.md +414 -0
  55. package/skills/swiftui-expert-skill/references/list-patterns.md +394 -0
  56. package/skills/swiftui-expert-skill/references/macos-scenes.md +318 -0
  57. package/skills/swiftui-expert-skill/references/macos-views.md +357 -0
  58. package/skills/swiftui-expert-skill/references/macos-window-styling.md +303 -0
  59. package/skills/swiftui-expert-skill/references/performance-patterns.md +403 -0
  60. package/skills/swiftui-expert-skill/references/scroll-patterns.md +293 -0
  61. package/skills/swiftui-expert-skill/references/sheet-navigation-patterns.md +363 -0
  62. package/skills/swiftui-expert-skill/references/state-management.md +417 -0
  63. package/skills/swiftui-expert-skill/references/view-structure.md +389 -0
  64. package/skills/swiftui-ui-patterns/NOTICE.md +18 -0
  65. package/skills/swiftui-ui-patterns/SKILL.md +95 -0
  66. package/skills/swiftui-ui-patterns/references/app-wiring.md +201 -0
  67. package/skills/swiftui-ui-patterns/references/async-state.md +96 -0
  68. package/skills/swiftui-ui-patterns/references/components-index.md +50 -0
  69. package/skills/swiftui-ui-patterns/references/controls.md +57 -0
  70. package/skills/swiftui-ui-patterns/references/deeplinks.md +66 -0
  71. package/skills/swiftui-ui-patterns/references/focus.md +90 -0
  72. package/skills/swiftui-ui-patterns/references/form.md +97 -0
  73. package/skills/swiftui-ui-patterns/references/grids.md +71 -0
  74. package/skills/swiftui-ui-patterns/references/haptics.md +71 -0
  75. package/skills/swiftui-ui-patterns/references/input-toolbar.md +51 -0
  76. package/skills/swiftui-ui-patterns/references/lightweight-clients.md +93 -0
  77. package/skills/swiftui-ui-patterns/references/list.md +86 -0
  78. package/skills/swiftui-ui-patterns/references/loading-placeholders.md +38 -0
  79. package/skills/swiftui-ui-patterns/references/macos-settings.md +71 -0
  80. package/skills/swiftui-ui-patterns/references/matched-transitions.md +59 -0
  81. package/skills/swiftui-ui-patterns/references/media.md +73 -0
  82. package/skills/swiftui-ui-patterns/references/menu-bar.md +101 -0
  83. package/skills/swiftui-ui-patterns/references/navigationstack.md +159 -0
  84. package/skills/swiftui-ui-patterns/references/overlay.md +45 -0
  85. package/skills/swiftui-ui-patterns/references/performance.md +62 -0
  86. package/skills/swiftui-ui-patterns/references/previews.md +48 -0
  87. package/skills/swiftui-ui-patterns/references/scroll-reveal.md +133 -0
  88. package/skills/swiftui-ui-patterns/references/scrollview.md +87 -0
  89. package/skills/swiftui-ui-patterns/references/searchable.md +71 -0
  90. package/skills/swiftui-ui-patterns/references/sheets.md +155 -0
  91. package/skills/swiftui-ui-patterns/references/split-views.md +72 -0
  92. package/skills/swiftui-ui-patterns/references/tabview.md +114 -0
  93. package/skills/swiftui-ui-patterns/references/theming.md +71 -0
  94. package/skills/swiftui-ui-patterns/references/title-menus.md +93 -0
  95. package/skills/swiftui-ui-patterns/references/top-bar.md +49 -0
@@ -0,0 +1,357 @@
1
+ # macOS Views & Components Reference
2
+
3
+ > macOS-specific SwiftUI views, file operations, drag & drop, and AppKit interop. Covers `HSplitView`, `VSplitView`, `Table`, `PasteButton`, file dialogs, cross-app drag & drop, and `NSViewRepresentable`.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Quick Lookup Table](#quick-lookup-table)
8
+ - [HSplitView & VSplitView (macOS-only)](#hsplitview--vsplitview-macos-only)
9
+ - [Table](#table)
10
+ - [PasteButton & CopyButton](#pastebutton--copybutton)
11
+ - [File Operations](#file-operations)
12
+ - [Drag, Drop & Pasteboard](#drag-drop--pasteboard)
13
+ - [AppKit Interop](#appkit-interop)
14
+ - [Best Practices](#best-practices)
15
+
16
+ ---
17
+
18
+ ## Quick Lookup Table
19
+
20
+ ### Views
21
+
22
+ | API | Availability | macOS-Only? | Usage |
23
+ |-----|-------------|:-----------:|-------|
24
+ | `HSplitView` | macOS 10.15+ | Yes | Horizontal resizable split layout with user-draggable dividers |
25
+ | `VSplitView` | macOS 10.15+ | Yes | Vertical resizable split layout with user-draggable dividers |
26
+ | `Table` | macOS 12.0+ | No | Full multi-column layout with sorting; on iOS compact, columns collapse |
27
+ | `PasteButton` | macOS 10.15+ | No | System button that reads clipboard; does NOT auto-validate on macOS |
28
+ | `CopyButton` | macOS 15.0+ | Yes | System button that copies `Transferable` content to clipboard |
29
+
30
+ ### File Operations
31
+
32
+ | API | Availability | macOS-Only? | Usage |
33
+ |-----|-------------|:-----------:|-------|
34
+ | `fileImporter()` | macOS 11.0+ | No | Native NSOpenPanel with column/list/gallery view, sidebar, tags, QuickLook |
35
+ | `fileExporter()` | macOS 11.0+ | No | Native NSSavePanel with format dropdown, tags field |
36
+ | `fileMover()` | macOS 11.0+ | No | Native macOS move panel with Finder-like navigation |
37
+ | `fileDialogMessage(_:)` | macOS 13.0+ | Yes | Custom message text in file dialogs |
38
+ | `fileDialogConfirmationLabel(_:)` | macOS 13.0+ | Yes | Custom confirm button text in file dialogs |
39
+ | `fileExporterFilenameLabel(_:)` | macOS 13.0+ | Yes | Custom filename field label in file exporter |
40
+
41
+ ### Drag, Drop & Pasteboard
42
+
43
+ | API | Availability | macOS-Only? | Usage |
44
+ |-----|-------------|:-----------:|-------|
45
+ | `onDrag(_:)` / `draggable(_:)` | macOS 11.0+ | No | Drag image follows cursor; items draggable between apps |
46
+ | `onDrop(of:delegate:)` / `dropDestination(for:action:)` | macOS 11.0+ | No | Accepts drops from any macOS app including Finder |
47
+
48
+ ### AppKit Interop
49
+
50
+ | API | Availability | macOS-Only? | Usage |
51
+ |-----|-------------|:-----------:|-------|
52
+ | `NSViewRepresentable` | macOS 10.15+ | Yes | Wrap an AppKit `NSView` in SwiftUI |
53
+ | `NSViewControllerRepresentable` | macOS 10.15+ | Yes | Wrap an AppKit `NSViewController` in SwiftUI |
54
+ | `NSHostingController` | macOS 10.15+ | Yes | Host SwiftUI inside an AppKit view controller |
55
+ | `NSHostingView` | macOS 10.15+ | Yes | Host SwiftUI inside an AppKit `NSView` hierarchy |
56
+
57
+ ---
58
+
59
+ ## HSplitView & VSplitView (macOS-only)
60
+
61
+ Resizable split layouts with user-draggable dividers. Use for IDE-style panes where all panels are equal peers. `VSplitView` works identically but splits vertically (use `minHeight` instead).
62
+
63
+ ```swift
64
+ HSplitView {
65
+ FileTreeView()
66
+ .frame(minWidth: 200)
67
+ CodeEditorView()
68
+ .frame(minWidth: 400)
69
+ PreviewPane()
70
+ .frame(minWidth: 200)
71
+ }
72
+ ```
73
+
74
+ > **When to use which:**
75
+ > - **`NavigationSplitView`** — sidebar-based navigation (sidebar drives content/detail)
76
+ > - **`HSplitView`/`VSplitView`** — IDE-style layouts where all panes are equal peers
77
+
78
+ ---
79
+
80
+ ## Table
81
+
82
+ For `Table` basics (creation, selection, sorting, adaptive compact layout), see `list-patterns.md`. This section covers macOS-specific table styling.
83
+
84
+ ### Table styles
85
+
86
+ ```swift
87
+ // Bordered with visible grid lines (macOS-only)
88
+ Table(people) { /* columns */ }
89
+ .tableStyle(.bordered)
90
+
91
+ // Bordered with alternating row backgrounds
92
+ Table(people) { /* columns */ }
93
+ .tableStyle(.bordered(alternatesRowBackgrounds: true))
94
+
95
+ // Inset (no borders)
96
+ Table(people) { /* columns */ }
97
+ .tableStyle(.inset)
98
+
99
+ // Hide column headers
100
+ Table(people) { /* columns */ }
101
+ .tableColumnHeaders(.hidden)
102
+ ```
103
+
104
+ ---
105
+
106
+ ## PasteButton & CopyButton
107
+
108
+ ### PasteButton
109
+
110
+ System button that reads clipboard content via `Transferable`. On macOS, it does NOT auto-validate pasteboard changes (unlike iOS).
111
+
112
+ ```swift
113
+ struct ClipboardView: View {
114
+ @State private var pastedText = ""
115
+
116
+ var body: some View {
117
+ HStack {
118
+ PasteButton(payloadType: String.self) { strings in
119
+ pastedText = strings[0]
120
+ }
121
+ Divider()
122
+ Text(pastedText)
123
+ Spacer()
124
+ }
125
+ }
126
+ }
127
+ ```
128
+
129
+ ### CopyButton (macOS 15.0+, macOS-only)
130
+
131
+ System button that copies `Transferable` content to the clipboard.
132
+
133
+ ```swift
134
+ struct CopyableContent: View {
135
+ let shareableText = "Hello, world!"
136
+
137
+ var body: some View {
138
+ HStack {
139
+ Text(shareableText)
140
+ CopyButton(item: shareableText)
141
+ }
142
+ }
143
+ }
144
+ ```
145
+
146
+ ---
147
+
148
+ ## File Operations
149
+
150
+ ### fileImporter
151
+
152
+ On macOS, presents a native `NSOpenPanel` with column/list/gallery view, sidebar favorites, tags, and QuickLook.
153
+
154
+ ```swift
155
+ .fileImporter(
156
+ isPresented: $showImporter,
157
+ allowedContentTypes: [.pdf],
158
+ allowsMultipleSelection: false
159
+ ) { result in
160
+ if case .success(let urls) = result, let url = urls.first {
161
+ guard url.startAccessingSecurityScopedResource() else { return }
162
+ defer { url.stopAccessingSecurityScopedResource() }
163
+ // use url
164
+ }
165
+ }
166
+ ```
167
+
168
+ > **Important:** Always call `startAccessingSecurityScopedResource()` on returned URLs, and `stopAccessingSecurityScopedResource()` when done. These are security-scoped bookmarks — access fails without this.
169
+
170
+ ### fileExporter
171
+
172
+ On macOS, presents a native `NSSavePanel` with format dropdown and tags.
173
+
174
+ ```swift
175
+ .fileExporter(
176
+ isPresented: $showExporter,
177
+ document: document,
178
+ contentType: .plainText,
179
+ defaultFilename: "MyFile.txt"
180
+ ) { result in
181
+ // handle Result<URL, Error>
182
+ }
183
+ ```
184
+
185
+ ### File dialog customization (macOS-only)
186
+
187
+ Customize text in file dialogs with these macOS-specific modifiers:
188
+
189
+ ```swift
190
+ // Custom message and confirm button on file importer
191
+ .fileImporter(
192
+ isPresented: $showImporter,
193
+ allowedContentTypes: [.image]
194
+ ) { result in
195
+ // handle result
196
+ }
197
+ .fileDialogMessage("Select an image to use as your profile photo")
198
+ .fileDialogConfirmationLabel("Use This Photo")
199
+
200
+ // Custom filename label on file exporter
201
+ .fileExporter(
202
+ isPresented: $showExporter,
203
+ document: myDocument,
204
+ contentType: .png
205
+ ) { result in
206
+ // handle result
207
+ }
208
+ .fileExporterFilenameLabel("Export As:")
209
+ ```
210
+
211
+ ---
212
+
213
+ ## Drag, Drop & Pasteboard
214
+
215
+ On macOS, drag and drop works **across applications** (e.g., drag from your app to Finder, Mail, or other apps).
216
+
217
+ ### Modern approach (Transferable)
218
+
219
+ ```swift
220
+ // Drag source
221
+ struct DraggableCard: View {
222
+ let item: MyItem
223
+
224
+ var body: some View {
225
+ Text(item.title)
226
+ .draggable(item) // Requires Transferable conformance
227
+ }
228
+ }
229
+
230
+ // Drop target
231
+ struct DropZone: View {
232
+ @State private var droppedItems: [MyItem] = []
233
+
234
+ var body: some View {
235
+ VStack {
236
+ ForEach(droppedItems) { item in
237
+ Text(item.title)
238
+ }
239
+ }
240
+ .dropDestination(for: MyItem.self) { items, location in
241
+ droppedItems.append(contentsOf: items)
242
+ return true
243
+ }
244
+ .frame(width: 300, height: 200)
245
+ .border(.secondary)
246
+ }
247
+ }
248
+ ```
249
+
250
+ ### Legacy approach (NSItemProvider)
251
+
252
+ ```swift
253
+ // Drag source
254
+ Image(systemName: "doc")
255
+ .onDrag {
256
+ NSItemProvider(object: fileURL as NSURL)
257
+ }
258
+
259
+ // Drop target
260
+ Text("Drop files here")
261
+ .onDrop(of: [.fileURL], isTargeted: nil) { providers in
262
+ // handle providers
263
+ return true
264
+ }
265
+ ```
266
+
267
+ ---
268
+
269
+ ## AppKit Interop
270
+
271
+ ### NSViewRepresentable (macOS-only)
272
+
273
+ Wraps an AppKit `NSView` for use in SwiftUI. Implement `makeNSView(context:)` and `updateNSView(_:context:)`.
274
+
275
+ ```swift
276
+ struct WebView: NSViewRepresentable {
277
+ let url: URL
278
+ func makeNSView(context: Context) -> WKWebView { WKWebView() }
279
+ func updateNSView(_ nsView: WKWebView, context: Context) {
280
+ nsView.load(URLRequest(url: url))
281
+ }
282
+ }
283
+ ```
284
+
285
+ ### NSViewRepresentable with Coordinator
286
+
287
+ Use a Coordinator to forward delegate/target-action callbacks to SwiftUI.
288
+
289
+ ```swift
290
+ struct SearchField: NSViewRepresentable {
291
+ @Binding var text: String
292
+
293
+ func makeNSView(context: Context) -> NSSearchField {
294
+ let field = NSSearchField()
295
+ field.delegate = context.coordinator
296
+ return field
297
+ }
298
+ func updateNSView(_ nsView: NSSearchField, context: Context) {
299
+ nsView.stringValue = text
300
+ }
301
+ func makeCoordinator() -> Coordinator { Coordinator(text: $text) }
302
+
303
+ class Coordinator: NSObject, NSSearchFieldDelegate {
304
+ var text: Binding<String>
305
+ init(text: Binding<String>) { self.text = text }
306
+ func controlTextDidChange(_ obj: Notification) {
307
+ if let field = obj.object as? NSSearchField {
308
+ text.wrappedValue = field.stringValue
309
+ }
310
+ }
311
+ }
312
+ }
313
+ ```
314
+
315
+ > **Warning:** Never set `frame`/`bounds` directly on the managed `NSView` — SwiftUI owns the layout.
316
+
317
+ ### NSViewControllerRepresentable (macOS-only)
318
+
319
+ Wraps an AppKit `NSViewController` for use in SwiftUI.
320
+
321
+ ```swift
322
+ struct MapViewWrapper: NSViewControllerRepresentable {
323
+ func makeNSViewController(context: Context) -> MapViewController {
324
+ MapViewController()
325
+ }
326
+
327
+ func updateNSViewController(_ nsViewController: MapViewController, context: Context) {
328
+ // Update the controller when SwiftUI state changes
329
+ }
330
+ }
331
+ ```
332
+
333
+ ### NSHostingController & NSHostingView (macOS-only)
334
+
335
+ Host SwiftUI content inside AppKit (reverse direction — AppKit app embedding SwiftUI views).
336
+
337
+ ```swift
338
+ // Host SwiftUI as a view controller
339
+ let hostingController = NSHostingController(rootView: MySwiftUIView())
340
+ window.contentViewController = hostingController
341
+
342
+ // Host SwiftUI directly as an NSView
343
+ let hostingView = NSHostingView(rootView: MySwiftUIView())
344
+ someNSView.addSubview(hostingView)
345
+ ```
346
+
347
+ ---
348
+
349
+ ## Best Practices
350
+
351
+ - **Use `NavigationSplitView`** for sidebar-driven navigation — reserve `HSplitView`/`VSplitView` for IDE-style equal peer panes
352
+ - **Make `Table` adaptive** — handle compact size classes by showing combined info in the first column
353
+ - **Always call `startAccessingSecurityScopedResource()`** on URLs from `fileImporter` — they are security-scoped
354
+ - **Use `Transferable`** for drag & drop (modern) — fall back to `NSItemProvider` only for legacy compatibility
355
+ - **Use `NSViewRepresentable` with Coordinator** when you need delegate callbacks from AppKit views
356
+ - **Never set `frame`/`bounds`** directly on views managed by `NSViewRepresentable` — SwiftUI owns the layout
357
+ - **Prefer native SwiftUI** over AppKit interop when possible — only use `NSViewRepresentable` for features SwiftUI doesn't provide
@@ -0,0 +1,303 @@
1
+ # macOS Window & Toolbar Styling Reference
2
+
3
+ > Window configuration, toolbar styles, sizing, positioning, and navigation patterns specific to macOS SwiftUI apps.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Quick Lookup Table](#quick-lookup-table)
8
+ - [Toolbar Styles](#toolbar-styles)
9
+ - [Window Style](#window-style)
10
+ - [Window Sizing](#window-sizing)
11
+ - [MenuBarExtra Style (macOS-only)](#menubarextra-style-macos-only)
12
+ - [Navigation Layout (macOS behavior)](#navigation-layout-macos-behavior)
13
+ - [Commands & Keyboard](#commands--keyboard)
14
+ - [Best Practices](#best-practices)
15
+
16
+ ---
17
+
18
+ ## Quick Lookup Table
19
+
20
+ | API | Availability | macOS-Only? | Usage |
21
+ |-----|-------------|:-----------:|-------|
22
+ | `windowToolbarStyle(_:)` | macOS 11.0+ | Yes | Sets toolbar style: `.unified`, `.unifiedCompact`, `.expanded` |
23
+ | `windowStyle(_:)` | macOS 11.0+ | No | Supports `.hiddenTitleBar` for chromeless windows |
24
+ | `windowResizability(_:)` | macOS 13.0+ | No | Controls resize handle and green zoom button behavior |
25
+ | `defaultSize(width:height:)` | macOS 13.0+ | No | Initial frame size when user creates a new window |
26
+ | `defaultPosition(_:)` | macOS 13.0+ | No | Initial window position on screen |
27
+ | `windowIdealPlacement(_:)` | macOS 15.0+ | No | Closure with display geometry for precise window positioning |
28
+ | `menuBarExtraStyle(_:)` | macOS 13.0+ | Yes | Sets MenuBarExtra to `.menu` or `.window` style |
29
+ | `NavigationSplitView` | macOS 13.0+ | No | Columns always visible side-by-side on macOS; translucent sidebar |
30
+ | `Inspector` | macOS 14.0+ | No | Trailing-edge sidebar panel; resizable by dragging |
31
+
32
+ ---
33
+
34
+ ## Toolbar Styles
35
+
36
+ ### windowToolbarStyle (macOS-only)
37
+
38
+ Controls how the toolbar and title bar are displayed. Applied to a scene.
39
+
40
+ ```swift
41
+ @main
42
+ struct MyApp: App {
43
+ var body: some Scene {
44
+ WindowGroup {
45
+ ContentView()
46
+ }
47
+ // Title bar and toolbar in a single row
48
+ .windowToolbarStyle(.unified)
49
+ }
50
+ }
51
+ ```
52
+
53
+ **Available styles:**
54
+
55
+ | Style | Description |
56
+ |-------|-------------|
57
+ | `.automatic` | System default |
58
+ | `.unified` | Title bar and toolbar in a single combined row |
59
+ | `.unifiedCompact` | Same as unified but with reduced vertical height |
60
+ | `.expanded` | Title bar displayed above the toolbar (more toolbar space) |
61
+
62
+ ```swift
63
+ // Unified compact — minimal chrome
64
+ .windowToolbarStyle(.unifiedCompact)
65
+
66
+ // Expanded — title bar above toolbar
67
+ .windowToolbarStyle(.expanded)
68
+
69
+ // Unified with title hidden
70
+ .windowToolbarStyle(.unified(showsTitle: false))
71
+ ```
72
+
73
+ ### Toolbar content
74
+
75
+ ```swift
76
+ struct ContentView: View {
77
+ @State private var searchText = ""
78
+
79
+ var body: some View {
80
+ NavigationSplitView {
81
+ SidebarView()
82
+ } detail: {
83
+ DetailView()
84
+ }
85
+ .toolbar {
86
+ ToolbarItem(placement: .automatic) {
87
+ Button(action: addItem) {
88
+ Label("Add", systemImage: "plus")
89
+ }
90
+ }
91
+ }
92
+ .searchable(text: $searchText, placement: .sidebar)
93
+ }
94
+ }
95
+ ```
96
+
97
+ ---
98
+
99
+ ## Window Style
100
+
101
+ ### windowStyle
102
+
103
+ Set the visual style of a window. Use `.hiddenTitleBar` for chromeless, immersive windows.
104
+
105
+ ```swift
106
+ // Standard title bar (default)
107
+ WindowGroup {
108
+ ContentView()
109
+ }
110
+ .windowStyle(.titleBar)
111
+
112
+ // Hidden title bar — chromeless window
113
+ WindowGroup {
114
+ ContentView()
115
+ }
116
+ .windowStyle(.hiddenTitleBar)
117
+ ```
118
+
119
+ > **Use case:** `.hiddenTitleBar` is useful for media players, custom-chrome apps, or immersive experiences where the standard title bar is unwanted.
120
+
121
+ ---
122
+
123
+ ## Window Sizing
124
+
125
+ ### windowResizability, defaultSize, defaultPosition
126
+
127
+ These modifiers work together to configure window sizing and placement:
128
+
129
+ ```swift
130
+ WindowGroup {
131
+ ContentView()
132
+ .frame(minWidth: 600, minHeight: 400)
133
+ }
134
+ .defaultSize(width: 900, height: 600)
135
+ .defaultPosition(.center)
136
+ .windowResizability(.contentMinSize)
137
+ ```
138
+
139
+ **`windowResizability` options:**
140
+
141
+ | Value | Behavior |
142
+ |-------|----------|
143
+ | `.automatic` | System decides resize behavior |
144
+ | `.contentSize` | Fixed to content size; no user resize; zoom button disabled |
145
+ | `.contentMinSize` | Resizable with minimum based on content's `minWidth`/`minHeight` |
146
+
147
+ **`defaultPosition` options:** `.center`, `.topLeading`, `.top`, `.topTrailing`, `.leading`, `.trailing`, `.bottomLeading`, `.bottom`, `.bottomTrailing`
148
+
149
+ **Guidelines:**
150
+ - Set `minWidth`/`minHeight` via `.frame()` on content, enforce with `.contentMinSize`
151
+ - Use `.defaultSize()` for initial dimensions (larger than minimums)
152
+ - `defaultSize` also accepts `CGSize`
153
+
154
+ ### windowIdealPlacement (macOS 15.0+)
155
+
156
+ For precise programmatic positioning, use a closure with display geometry:
157
+
158
+ ```swift
159
+ .windowIdealPlacement { context in
160
+ let screen = context.defaultDisplay.visibleArea
161
+ return WindowPlacement(x: screen.midX, y: screen.midY,
162
+ width: screen.width / 2, height: screen.height)
163
+ }
164
+ ```
165
+
166
+ ---
167
+
168
+ ## MenuBarExtra Style (macOS-only)
169
+
170
+ Choose between dropdown menu and popover panel for `MenuBarExtra`.
171
+
172
+ ```swift
173
+ // Dropdown menu (default)
174
+ MenuBarExtra("Status", systemImage: "chart.bar") {
175
+ Button("Action") { /* ... */ }
176
+ }
177
+ .menuBarExtraStyle(.menu)
178
+
179
+ // Popover panel with custom SwiftUI content
180
+ MenuBarExtra("Status", systemImage: "chart.bar") {
181
+ DashboardView()
182
+ }
183
+ .menuBarExtraStyle(.window)
184
+ ```
185
+
186
+ ---
187
+
188
+ ## Navigation Layout (macOS behavior)
189
+
190
+ ### NavigationSplitView
191
+
192
+ On macOS, `NavigationSplitView` displays columns side-by-side (never overlaid). The sidebar gets a translucent material background. Columns support variable-width resizing by the user.
193
+
194
+ ```swift
195
+ NavigationSplitView {
196
+ List(items, selection: $selectedId) { item in
197
+ Text(item.name)
198
+ }
199
+ .navigationSplitViewColumnWidth(min: 180, ideal: 220, max: 300)
200
+ } detail: {
201
+ DetailView(id: selectedId)
202
+ }
203
+ .navigationSplitViewStyle(.balanced)
204
+ ```
205
+
206
+ Use the three-column variant (`sidebar` / `content` / `detail`) for master-detail-detail layouts. Customize column widths with `.navigationSplitViewColumnWidth(min:ideal:max:)`.
207
+
208
+ ### Inspector (macOS 14.0+)
209
+
210
+ A trailing-edge panel for supplementary information. On macOS, it appears as a sidebar-style panel that can be resized by dragging its edge.
211
+
212
+ ```swift
213
+ struct ContentView: View {
214
+ @State private var showInspector = false
215
+
216
+ var body: some View {
217
+ MainContent()
218
+ .inspector(isPresented: $showInspector) {
219
+ InspectorView()
220
+ .inspectorColumnWidth(min: 200, ideal: 250, max: 400)
221
+ }
222
+ .toolbar {
223
+ ToolbarItem {
224
+ Button {
225
+ showInspector.toggle()
226
+ } label: {
227
+ Label("Inspector", systemImage: "info.circle")
228
+ }
229
+ }
230
+ }
231
+ }
232
+ }
233
+ ```
234
+
235
+ ---
236
+
237
+ ## Commands & Keyboard
238
+
239
+ ### Commands, CommandGroup, CommandMenu
240
+
241
+ Define menu bar commands. On macOS, these populate the menu bar directly. On iOS, they create key commands.
242
+
243
+ ```swift
244
+ .commands {
245
+ CommandMenu("Tools") {
246
+ Button("Run Analysis") { /* ... */ }
247
+ .keyboardShortcut("r", modifiers: [.command, .shift])
248
+ }
249
+ CommandGroup(after: .newItem) {
250
+ Button("New From Template...") { /* ... */ }
251
+ }
252
+ }
253
+ ```
254
+
255
+ **`CommandGroup` placement options:** `.replacing(_:)` replaces a system group, `.before(_:)` / `.after(_:)` inserts adjacent to it. Common placements: `.newItem`, `.saveItem`, `.help`, `.toolbar`, `.sidebar`.
256
+
257
+ ### KeyboardShortcut
258
+
259
+ On macOS, shortcuts are displayed alongside menu items and in button tooltips on hover.
260
+
261
+ ```swift
262
+ Button("Save") {
263
+ save()
264
+ }
265
+ .keyboardShortcut("s", modifiers: .command)
266
+
267
+ Button("Delete") {
268
+ delete()
269
+ }
270
+ .keyboardShortcut(.delete, modifiers: .command)
271
+ ```
272
+
273
+ ### openWindow
274
+
275
+ Programmatically open a window. If the target window is already open, brings it to the front.
276
+
277
+ ```swift
278
+ struct ToolbarActions: View {
279
+ @Environment(\.openWindow) private var openWindow
280
+
281
+ var body: some View {
282
+ Button("Connection Doctor") {
283
+ openWindow(id: "connection-doctor")
284
+ }
285
+
286
+ Button("Show Message") {
287
+ openWindow(value: message.id) // Type-matched to WindowGroup
288
+ }
289
+ }
290
+ }
291
+ ```
292
+
293
+ ---
294
+
295
+ ## Best Practices
296
+
297
+ - **Use `.unified` or `.unifiedCompact`** for most apps — `.expanded` only when you need many toolbar items
298
+ - **Set min frame sizes on content** and use `.windowResizability(.contentMinSize)` to enforce them
299
+ - **Always provide `defaultSize`** so new windows start at a reasonable size
300
+ - **Use `NavigationSplitView`** for sidebar navigation — not `HSplitView`
301
+ - **Use `Inspector`** for supplementary panels — it integrates with the toolbar automatically
302
+ - **Define `Commands`** for all repeatable actions — users expect keyboard shortcuts on macOS
303
+ - **Use `#if os(macOS)`** to wrap macOS-only window configuration in multiplatform projects