claudecode-omc 5.6.6 → 5.6.8

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 (179) hide show
  1. package/.local/skills/THIRD_PARTY_LICENSES/AvdLee-SwiftUI-Agent-Skill.LICENSE +21 -0
  2. package/.local/skills/THIRD_PARTY_LICENSES/Dimillian-Skills.LICENSE +21 -0
  3. package/.local/skills/THIRD_PARTY_LICENSES/README.md +36 -0
  4. package/.local/skills/THIRD_PARTY_LICENSES/twostraws-swiftui-agent-skill.LICENSE +21 -0
  5. package/.local/skills/h5-to-swiftui/SKILL.md +201 -0
  6. package/.local/skills/h5-to-swiftui/assets/calibration/README.md +176 -0
  7. package/.local/skills/h5-to-swiftui/assets/calibration/h5-twin/index.html +52 -0
  8. package/.local/skills/h5-to-swiftui/assets/calibration/h5-twin/style.css +133 -0
  9. package/.local/skills/h5-to-swiftui/assets/calibration/swiftui-twin/Package.swift +26 -0
  10. package/.local/skills/h5-to-swiftui/assets/calibration/swiftui-twin/Sources/CalibrationScreen/CalibrationScreen.swift +142 -0
  11. package/.local/skills/h5-to-swiftui/assets/calibration/swiftui-twin-divergent/Package.swift +32 -0
  12. package/.local/skills/h5-to-swiftui/assets/calibration/swiftui-twin-divergent/Sources/CalibrationScreenDivergent/CalibrationScreenDivergent.swift +122 -0
  13. package/.local/skills/h5-to-swiftui/assets/calibration/tokens.json +42 -0
  14. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/index.html +14 -0
  15. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/package.json +20 -0
  16. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/public/api/articles/001.json +96 -0
  17. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/public/api/articles/index.json +89 -0
  18. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/App.jsx +22 -0
  19. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/App.module.css +11 -0
  20. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/components/ArticleCard.jsx +53 -0
  21. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/components/ArticleCard.module.css +139 -0
  22. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/components/NavBar.jsx +37 -0
  23. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/components/NavBar.module.css +72 -0
  24. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/components/TagCloud.jsx +30 -0
  25. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/components/TagCloud.module.css +50 -0
  26. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/components/TrendChart.jsx +159 -0
  27. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/components/TrendChart.module.css +21 -0
  28. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/main.jsx +12 -0
  29. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/screens/ArticleScreen.jsx +182 -0
  30. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/screens/ArticleScreen.module.css +294 -0
  31. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/screens/FeedScreen.jsx +147 -0
  32. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/screens/FeedScreen.module.css +161 -0
  33. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/styles/global.css +50 -0
  34. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/styles/tokens.css +103 -0
  35. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/vite.config.js +6 -0
  36. package/.local/skills/h5-to-swiftui/assets/sample-h5-vanilla/data/tasks.js +67 -0
  37. package/.local/skills/h5-to-swiftui/assets/sample-h5-vanilla/index.html +26 -0
  38. package/.local/skills/h5-to-swiftui/assets/sample-h5-vanilla/router.js +73 -0
  39. package/.local/skills/h5-to-swiftui/assets/sample-h5-vanilla/screens/detail.js +164 -0
  40. package/.local/skills/h5-to-swiftui/assets/sample-h5-vanilla/screens/home.js +53 -0
  41. package/.local/skills/h5-to-swiftui/assets/sample-h5-vanilla/screens/list.js +87 -0
  42. package/.local/skills/h5-to-swiftui/assets/sample-h5-vanilla/styles/app.css +342 -0
  43. package/.local/skills/h5-to-swiftui/assets/sample-h5-vanilla/styles/tokens.css +68 -0
  44. package/.local/skills/h5-to-swiftui/references/css-to-swiftui-map.md +205 -0
  45. package/.local/skills/h5-to-swiftui/references/design-token-extraction.md +209 -0
  46. package/.local/skills/h5-to-swiftui/references/high-risk-triage.md +209 -0
  47. package/.local/skills/h5-to-swiftui/references/render-equivalence-calibration.md +193 -0
  48. package/.local/skills/h5-to-swiftui/references/stack-detection.md +160 -0
  49. package/.local/skills/h5-to-swiftui/references/visual-diff-loop-protocol.md +365 -0
  50. package/.local/skills/h5-to-swiftui/scripts/_calib-consts.mjs +150 -0
  51. package/.local/skills/h5-to-swiftui/scripts/_imglib.mjs +547 -0
  52. package/.local/skills/h5-to-swiftui/scripts/_provenance.mjs +123 -0
  53. package/.local/skills/h5-to-swiftui/scripts/calibrate-render.mjs +625 -0
  54. package/.local/skills/h5-to-swiftui/scripts/capture-reference.mjs +386 -0
  55. package/.local/skills/h5-to-swiftui/scripts/detect-stack.mjs +305 -0
  56. package/.local/skills/h5-to-swiftui/scripts/evaluate-convergence.mjs +1093 -0
  57. package/.local/skills/h5-to-swiftui/scripts/extract-tokens.mjs +600 -0
  58. package/.local/skills/h5-to-swiftui/scripts/mark-overlay.mjs +379 -0
  59. package/.local/skills/h5-to-swiftui/scripts/pixel-diff.mjs +530 -0
  60. package/.local/skills/h5-to-swiftui/scripts/sim-screenshot.sh +544 -0
  61. package/.local/skills/ios-debugger-agent/SKILL.md +51 -0
  62. package/.local/skills/ios-debugger-agent/agents/openai.yaml +4 -0
  63. package/.local/skills/swift-concurrency-expert/SKILL.md +105 -0
  64. package/.local/skills/swift-concurrency-expert/agents/openai.yaml +4 -0
  65. package/.local/skills/swift-concurrency-expert/references/approachable-concurrency.md +63 -0
  66. package/.local/skills/swift-concurrency-expert/references/swift-6-2-concurrency.md +272 -0
  67. package/.local/skills/swift-concurrency-expert/references/swiftui-concurrency-tour-wwdc.md +33 -0
  68. package/.local/skills/swiftui-expert-skill/SKILL.md +162 -0
  69. package/.local/skills/swiftui-expert-skill/references/accessibility-patterns.md +215 -0
  70. package/.local/skills/swiftui-expert-skill/references/animation-advanced.md +403 -0
  71. package/.local/skills/swiftui-expert-skill/references/animation-basics.md +284 -0
  72. package/.local/skills/swiftui-expert-skill/references/animation-transitions.md +326 -0
  73. package/.local/skills/swiftui-expert-skill/references/charts-accessibility.md +135 -0
  74. package/.local/skills/swiftui-expert-skill/references/charts.md +602 -0
  75. package/.local/skills/swiftui-expert-skill/references/focus-patterns.md +299 -0
  76. package/.local/skills/swiftui-expert-skill/references/image-optimization.md +203 -0
  77. package/.local/skills/swiftui-expert-skill/references/latest-apis.md +488 -0
  78. package/.local/skills/swiftui-expert-skill/references/layout-best-practices.md +266 -0
  79. package/.local/skills/swiftui-expert-skill/references/liquid-glass.md +423 -0
  80. package/.local/skills/swiftui-expert-skill/references/list-patterns.md +446 -0
  81. package/.local/skills/swiftui-expert-skill/references/macos-scenes.md +318 -0
  82. package/.local/skills/swiftui-expert-skill/references/macos-views.md +357 -0
  83. package/.local/skills/swiftui-expert-skill/references/macos-window-styling.md +303 -0
  84. package/.local/skills/swiftui-expert-skill/references/performance-patterns.md +403 -0
  85. package/.local/skills/swiftui-expert-skill/references/scroll-patterns.md +293 -0
  86. package/.local/skills/swiftui-expert-skill/references/sheet-navigation-patterns.md +363 -0
  87. package/.local/skills/swiftui-expert-skill/references/state-management.md +388 -0
  88. package/.local/skills/swiftui-expert-skill/references/text-patterns.md +32 -0
  89. package/.local/skills/swiftui-expert-skill/references/trace-analysis.md +295 -0
  90. package/.local/skills/swiftui-expert-skill/references/trace-recording.md +134 -0
  91. package/.local/skills/swiftui-expert-skill/references/view-structure.md +780 -0
  92. package/.local/skills/swiftui-expert-skill/scripts/__pycache__/analyze_trace.cpython-313.pyc +0 -0
  93. package/.local/skills/swiftui-expert-skill/scripts/__pycache__/record_trace.cpython-313.pyc +0 -0
  94. package/.local/skills/swiftui-expert-skill/scripts/analyze_trace.py +301 -0
  95. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/__init__.py +1 -0
  96. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/__pycache__/__init__.cpython-313.pyc +0 -0
  97. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/__pycache__/causes.cpython-313.pyc +0 -0
  98. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/__pycache__/correlate.cpython-313.pyc +0 -0
  99. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/__pycache__/events.cpython-313.pyc +0 -0
  100. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/__pycache__/hangs.cpython-313.pyc +0 -0
  101. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/__pycache__/hitches.cpython-313.pyc +0 -0
  102. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/__pycache__/summary.cpython-313.pyc +0 -0
  103. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/__pycache__/swiftui.cpython-313.pyc +0 -0
  104. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/__pycache__/time_profiler.cpython-313.pyc +0 -0
  105. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/__pycache__/xctrace.cpython-313.pyc +0 -0
  106. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/__pycache__/xml_utils.cpython-313.pyc +0 -0
  107. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/causes.py +187 -0
  108. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/correlate.py +179 -0
  109. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/events.py +291 -0
  110. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/hangs.py +108 -0
  111. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/hitches.py +145 -0
  112. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/summary.py +243 -0
  113. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/swiftui.py +195 -0
  114. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/time_profiler.py +135 -0
  115. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/xctrace.py +117 -0
  116. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/xml_utils.py +224 -0
  117. package/.local/skills/swiftui-expert-skill/scripts/record_trace.py +252 -0
  118. package/.local/skills/swiftui-liquid-glass/SKILL.md +90 -0
  119. package/.local/skills/swiftui-liquid-glass/agents/openai.yaml +4 -0
  120. package/.local/skills/swiftui-liquid-glass/references/liquid-glass.md +280 -0
  121. package/.local/skills/swiftui-performance-audit/SKILL.md +106 -0
  122. package/.local/skills/swiftui-performance-audit/agents/openai.yaml +4 -0
  123. package/.local/skills/swiftui-performance-audit/references/code-smells.md +150 -0
  124. package/.local/skills/swiftui-performance-audit/references/demystify-swiftui-performance-wwdc23.md +46 -0
  125. package/.local/skills/swiftui-performance-audit/references/optimizing-swiftui-performance-instruments.md +29 -0
  126. package/.local/skills/swiftui-performance-audit/references/profiling-intake.md +44 -0
  127. package/.local/skills/swiftui-performance-audit/references/report-template.md +47 -0
  128. package/.local/skills/swiftui-performance-audit/references/understanding-hangs-in-your-app.md +33 -0
  129. package/.local/skills/swiftui-performance-audit/references/understanding-improving-swiftui-performance.md +52 -0
  130. package/.local/skills/swiftui-pro/SKILL.md +108 -0
  131. package/.local/skills/swiftui-pro/agents/openai.yaml +10 -0
  132. package/.local/skills/swiftui-pro/assets/swiftui-pro-icon.png +0 -0
  133. package/.local/skills/swiftui-pro/assets/swiftui-pro-icon.svg +29 -0
  134. package/.local/skills/swiftui-pro/references/accessibility.md +13 -0
  135. package/.local/skills/swiftui-pro/references/api.md +39 -0
  136. package/.local/skills/swiftui-pro/references/data.md +43 -0
  137. package/.local/skills/swiftui-pro/references/design.md +32 -0
  138. package/.local/skills/swiftui-pro/references/hygiene.md +9 -0
  139. package/.local/skills/swiftui-pro/references/navigation.md +14 -0
  140. package/.local/skills/swiftui-pro/references/performance.md +46 -0
  141. package/.local/skills/swiftui-pro/references/swift.md +56 -0
  142. package/.local/skills/swiftui-pro/references/views.md +36 -0
  143. package/.local/skills/swiftui-ui-patterns/SKILL.md +95 -0
  144. package/.local/skills/swiftui-ui-patterns/agents/openai.yaml +4 -0
  145. package/.local/skills/swiftui-ui-patterns/references/app-wiring.md +201 -0
  146. package/.local/skills/swiftui-ui-patterns/references/async-state.md +96 -0
  147. package/.local/skills/swiftui-ui-patterns/references/components-index.md +50 -0
  148. package/.local/skills/swiftui-ui-patterns/references/controls.md +57 -0
  149. package/.local/skills/swiftui-ui-patterns/references/deeplinks.md +66 -0
  150. package/.local/skills/swiftui-ui-patterns/references/focus.md +90 -0
  151. package/.local/skills/swiftui-ui-patterns/references/form.md +97 -0
  152. package/.local/skills/swiftui-ui-patterns/references/grids.md +71 -0
  153. package/.local/skills/swiftui-ui-patterns/references/haptics.md +71 -0
  154. package/.local/skills/swiftui-ui-patterns/references/input-toolbar.md +51 -0
  155. package/.local/skills/swiftui-ui-patterns/references/lightweight-clients.md +93 -0
  156. package/.local/skills/swiftui-ui-patterns/references/list.md +86 -0
  157. package/.local/skills/swiftui-ui-patterns/references/loading-placeholders.md +38 -0
  158. package/.local/skills/swiftui-ui-patterns/references/macos-settings.md +71 -0
  159. package/.local/skills/swiftui-ui-patterns/references/matched-transitions.md +59 -0
  160. package/.local/skills/swiftui-ui-patterns/references/media.md +73 -0
  161. package/.local/skills/swiftui-ui-patterns/references/menu-bar.md +101 -0
  162. package/.local/skills/swiftui-ui-patterns/references/navigationstack.md +159 -0
  163. package/.local/skills/swiftui-ui-patterns/references/overlay.md +45 -0
  164. package/.local/skills/swiftui-ui-patterns/references/performance.md +62 -0
  165. package/.local/skills/swiftui-ui-patterns/references/previews.md +48 -0
  166. package/.local/skills/swiftui-ui-patterns/references/scroll-reveal.md +133 -0
  167. package/.local/skills/swiftui-ui-patterns/references/scrollview.md +87 -0
  168. package/.local/skills/swiftui-ui-patterns/references/searchable.md +71 -0
  169. package/.local/skills/swiftui-ui-patterns/references/sheets.md +155 -0
  170. package/.local/skills/swiftui-ui-patterns/references/split-views.md +72 -0
  171. package/.local/skills/swiftui-ui-patterns/references/tabview.md +114 -0
  172. package/.local/skills/swiftui-ui-patterns/references/theming.md +71 -0
  173. package/.local/skills/swiftui-ui-patterns/references/title-menus.md +93 -0
  174. package/.local/skills/swiftui-ui-patterns/references/top-bar.md +49 -0
  175. package/.local/skills/swiftui-view-refactor/SKILL.md +202 -0
  176. package/.local/skills/swiftui-view-refactor/agents/openai.yaml +4 -0
  177. package/.local/skills/swiftui-view-refactor/references/mv-patterns.md +161 -0
  178. package/bundled/manifest.json +1 -1
  179. package/package.json +1 -1
@@ -0,0 +1,318 @@
1
+ # macOS Scenes Reference
2
+
3
+ > SwiftUI scene types for macOS apps — `Settings`, `MenuBarExtra`, `WindowGroup`, `Window`, `UtilityWindow`, and `DocumentGroup`. Covers macOS-only scenes and cross-platform scenes with macOS-specific behavior.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Quick Lookup Table](#quick-lookup-table)
8
+ - [Settings (macOS-only)](#settings-macos-only)
9
+ - [MenuBarExtra (macOS-only)](#menubarextra-macos-only)
10
+ - [WindowGroup (macOS behavior)](#windowgroup-macos-behavior)
11
+ - [Window](#window)
12
+ - [UtilityWindow (macOS-only)](#utilitywindow-macos-only)
13
+ - [DocumentGroup](#documentgroup)
14
+ - [Platform Conditionals](#platform-conditionals)
15
+ - [Best Practices](#best-practices)
16
+
17
+ ---
18
+
19
+ ## Quick Lookup Table
20
+
21
+ | API | Availability | macOS-Only? | macOS-Specific Behavior |
22
+ |-----|-------------|:-----------:|------------------------|
23
+ | `WindowGroup` | macOS 11.0+ | No | Multiple window instances, tabbed interface, automatic Window menu commands |
24
+ | `Window` | macOS 13.0+ | No | App quits when sole window closes; adds itself to Windows menu |
25
+ | `UtilityWindow` | macOS 15.0+ | Yes | Floating tool palette; receives `FocusedValues` from active main window |
26
+ | `Settings` | macOS 11.0+ | Yes | Presents preferences window (Cmd+,) |
27
+ | `MenuBarExtra` | macOS 13.0+ | Yes | Persistent icon/menu in the system menu bar |
28
+ | `DocumentGroup` | macOS 11.0+ | No | Document-based menu bar commands (File > New/Open/Save); multiple document windows |
29
+
30
+ ---
31
+
32
+ ## Settings (macOS-only)
33
+
34
+ Presents the app's preferences window, accessible via **Cmd+,** or the app menu. SwiftUI automatically enables the Settings menu item and manages the window lifecycle.
35
+
36
+ ```swift
37
+ Settings {
38
+ TabView {
39
+ Tab("General", systemImage: "gear") { GeneralSettingsView() }
40
+ Tab("Advanced", systemImage: "star") { AdvancedSettingsView() }
41
+ }
42
+ .scenePadding()
43
+ .frame(maxWidth: 350, minHeight: 100)
44
+ }
45
+ ```
46
+
47
+ Use `TabView` with `Tab` items for multi-pane preferences. Each tab's content is typically a `Form` with `@AppStorage`-backed controls.
48
+
49
+ ### SettingsLink (macOS 14.0+)
50
+
51
+ A button that opens the Settings scene. Use for in-app navigation to preferences.
52
+
53
+ ```swift
54
+ struct SidebarFooter: View {
55
+ var body: some View {
56
+ SettingsLink {
57
+ Label("Preferences", systemImage: "gear")
58
+ }
59
+ }
60
+ }
61
+ ```
62
+
63
+ ### openSettings environment action (macOS 14.0+)
64
+
65
+ Programmatically open (or bring to front) the Settings window.
66
+
67
+ ```swift
68
+ struct OpenSettingsButton: View {
69
+ @Environment(\.openSettings) private var openSettings
70
+
71
+ var body: some View {
72
+ Button("Open Settings") {
73
+ openSettings()
74
+ }
75
+ }
76
+ }
77
+ ```
78
+
79
+ ---
80
+
81
+ ## MenuBarExtra (macOS-only)
82
+
83
+ Renders a persistent control in the system menu bar. Two styles available:
84
+ - **`.menu`** (default) — standard dropdown menu
85
+ - **`.window`** — popover panel with custom SwiftUI views
86
+
87
+ ### Menu-style (dropdown)
88
+
89
+ ```swift
90
+ MenuBarExtra("My Utility", systemImage: "hammer") {
91
+ Button("Action One") { /* ... */ }
92
+ Button("Action Two") { /* ... */ }
93
+ Divider()
94
+ Button("Quit") { NSApplication.shared.terminate(nil) }
95
+ }
96
+ ```
97
+
98
+ ### Window-style (popover panel)
99
+
100
+ ```swift
101
+ MenuBarExtra("Status", systemImage: "chart.bar") {
102
+ DashboardView()
103
+ .frame(width: 240)
104
+ }
105
+ .menuBarExtraStyle(.window)
106
+ ```
107
+
108
+ **Variations:**
109
+ - **Toggleable** — pass `isInserted:` with an `@AppStorage` binding to let users show/hide the extra: `MenuBarExtra("Status", systemImage: "chart.bar", isInserted: $showMenuBarExtra)`
110
+ - **Menu-bar-only app** — use `MenuBarExtra` as the sole scene + set `LSUIElement = true` in Info.plist to hide the Dock icon. The app auto-terminates if the user removes the extra from the menu bar.
111
+
112
+ ---
113
+
114
+ ## WindowGroup (macOS behavior)
115
+
116
+ On macOS, `WindowGroup` supports:
117
+ - **Multiple window instances** — users can open many windows from File > New Window
118
+ - **Tabbed interface** — users can merge windows into tabs
119
+ - **Automatic Window menu** — commands for window management appear automatically
120
+
121
+ ```swift
122
+ @main
123
+ struct Mail: App {
124
+ var body: some Scene {
125
+ // Basic multi-window support
126
+ WindowGroup {
127
+ MailViewer()
128
+ }
129
+
130
+ // Data-presenting window opened programmatically
131
+ WindowGroup("Message", for: Message.ID.self) { $messageID in
132
+ MessageDetail(messageID: messageID)
133
+ }
134
+ }
135
+ }
136
+
137
+ // Open a specific window programmatically
138
+ struct NewMessageButton: View {
139
+ var message: Message
140
+ @Environment(\.openWindow) private var openWindow
141
+
142
+ var body: some View {
143
+ Button("Open Message") {
144
+ openWindow(value: message.id)
145
+ }
146
+ }
147
+ }
148
+ ```
149
+
150
+ > **Key difference from `Window`:** `WindowGroup` keeps the app running even after all windows are closed. `Window` (as sole scene) quits the app when closed.
151
+
152
+ ---
153
+
154
+ ## Window
155
+
156
+ A single, unique window scene. The system ensures only one instance exists.
157
+
158
+ ```swift
159
+ @main
160
+ struct Mail: App {
161
+ var body: some Scene {
162
+ WindowGroup {
163
+ MailViewer()
164
+ }
165
+
166
+ // Supplementary singleton window
167
+ Window("Connection Doctor", id: "connection-doctor") {
168
+ ConnectionDoctor()
169
+ }
170
+ }
171
+ }
172
+
173
+ // Open programmatically — brings to front if already open
174
+ struct OpenDoctorButton: View {
175
+ @Environment(\.openWindow) private var openWindow
176
+
177
+ var body: some View {
178
+ Button("Connection Doctor") {
179
+ openWindow(id: "connection-doctor")
180
+ }
181
+ }
182
+ }
183
+ ```
184
+
185
+ ### Window as sole scene
186
+
187
+ If `Window` is the only scene, the app quits when the window closes:
188
+
189
+ ```swift
190
+ @main
191
+ struct VideoCall: App {
192
+ var body: some Scene {
193
+ Window("VideoCall", id: "main") {
194
+ CameraView()
195
+ }
196
+ }
197
+ }
198
+ ```
199
+
200
+ > **Recommendation:** In most cases, prefer `WindowGroup` for the primary scene. Use `Window` for supplementary singleton windows.
201
+
202
+ ---
203
+
204
+ ## UtilityWindow (macOS-only)
205
+
206
+ A specialized floating window for tool palettes and inspector panels. Available since macOS 15.0.
207
+
208
+ **Key behaviors:**
209
+ - Receives `FocusedValues` from the focused main scene (like menu bar commands)
210
+ - Floats above main windows (default level: `.floating`)
211
+ - Hides when the app is no longer active
212
+ - Only becomes focused when explicitly needed (e.g., clicking the title bar)
213
+ - Dismissible with the Escape key
214
+ - Not minimizable by default
215
+ - Automatically adds a show/hide item to the View menu
216
+
217
+ ```swift
218
+ @main
219
+ struct PhotoBrowser: App {
220
+ var body: some Scene {
221
+ WindowGroup {
222
+ PhotoGallery()
223
+ }
224
+
225
+ UtilityWindow("Photo Info", id: "photo-info") {
226
+ PhotoInfoViewer()
227
+ }
228
+ }
229
+ }
230
+
231
+ struct PhotoInfoViewer: View {
232
+ // Automatically updates based on whichever main window is focused
233
+ @FocusedValue(PhotoSelection.self) private var selectedPhotos
234
+
235
+ var body: some View {
236
+ if let photos = selectedPhotos {
237
+ Text("\(photos.count) photos selected")
238
+ } else {
239
+ Text("No selection")
240
+ .foregroundStyle(.secondary)
241
+ }
242
+ }
243
+ }
244
+ ```
245
+
246
+ > **Tip:** Remove the automatic View menu item with `.commandsRemoved()` and place a `WindowVisibilityToggle` elsewhere in your commands.
247
+
248
+ ---
249
+
250
+ ## DocumentGroup
251
+
252
+ Document-based apps with automatic file management. On macOS, provides:
253
+ - **Document-based menu bar commands** (File > New, Open, Save, Revert)
254
+ - **Multiple document windows** simultaneously
255
+ - On iOS, shows a document browser instead
256
+
257
+ ```swift
258
+ DocumentGroup(newDocument: TextFile()) { config in
259
+ ContentView(document: config.$document)
260
+ }
261
+ ```
262
+
263
+ The document type must conform to `FileDocument` (value type) or `ReferenceFileDocument` (reference type). Key requirements:
264
+
265
+ ```swift
266
+ struct TextFile: FileDocument {
267
+ static var readableContentTypes: [UTType] { [.plainText] }
268
+ var text: String = ""
269
+ init() {}
270
+ init(configuration: ReadConfiguration) throws {
271
+ text = String(data: configuration.file.regularFileContents ?? Data(), encoding: .utf8) ?? ""
272
+ }
273
+ func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
274
+ FileWrapper(regularFileWithContents: Data(text.utf8))
275
+ }
276
+ }
277
+ ```
278
+
279
+ For multiple document types, add additional `DocumentGroup` scenes — use `DocumentGroup(viewing:)` for read-only formats.
280
+
281
+ ---
282
+
283
+ ## Platform Conditionals
284
+
285
+ Always wrap macOS-only scenes in `#if os(macOS)`:
286
+
287
+ ```swift
288
+ @main
289
+ struct MyApp: App {
290
+ var body: some Scene {
291
+ WindowGroup {
292
+ ContentView()
293
+ }
294
+
295
+ #if os(macOS)
296
+ Settings {
297
+ SettingsView()
298
+ }
299
+
300
+ MenuBarExtra("Status", systemImage: "bolt") {
301
+ StatusMenu()
302
+ }
303
+ #endif
304
+ }
305
+ }
306
+ ```
307
+
308
+ ---
309
+
310
+ ## Best Practices
311
+
312
+ - **Use `Settings`** for preferences — prefer this over a custom preferences window
313
+ - **Use `MenuBarExtra`** for menu bar items — prefer this over managing AppKit's `NSStatusItem` directly
314
+ - **Use `WindowGroup`** as the primary scene — reserve `Window` for supplementary singletons
315
+ - **Use `UtilityWindow`** for inspectors/palettes — it handles floating, focus, and visibility automatically
316
+ - **Use `DocumentGroup`** for document-based apps — it provides the full File menu and document lifecycle
317
+ - **Gate macOS-only scenes** with `#if os(macOS)` for multiplatform projects
318
+ - **Use `openWindow(id:)`** to open windows programmatically — it brings existing windows to front
@@ -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