mirror of
https://github.com/Dimillian/Skills.git
synced 2026-04-27 14:57:40 +00:00
Add macOS Settings and menu bar reference docs
Added new reference guides for building macOS Settings windows and customizing menu bar commands in SwiftUI. Updated the components index to include links to these new resources.
This commit is contained in:
parent
4fb872727e
commit
4c59f14753
3 changed files with 174 additions and 0 deletions
|
|
@ -9,6 +9,7 @@ Use this file to find component-specific guidance. Each entry lists when to use
|
|||
- Sheets and modal routing: `references/sheets.md` — Use when you want centralized, enum-driven sheet presentation.
|
||||
- App wiring and dependency graph: `references/app-wiring.md` — Use to wire TabView + NavigationStack + sheets at the root and install global dependencies.
|
||||
- Form and Settings: `references/form.md` — Use for settings, grouped inputs, and structured data entry.
|
||||
- macOS Settings: `references/macos-settings.md` — Use when building a macOS Settings window with SwiftUI's Settings scene.
|
||||
- Split views and columns: `references/split-views.md` — Use for iPad/macOS multi-column layouts or custom secondary columns.
|
||||
- List and Section: `references/list.md` — Use for feed-style content and settings rows.
|
||||
- ScrollView and Lazy stacks: `references/scrollview.md` — Use for custom layouts, horizontal scrollers, or grids.
|
||||
|
|
@ -25,6 +26,7 @@ Use this file to find component-specific guidance. Each entry lists when to use
|
|||
- Matched transitions: `references/matched-transitions.md` — Use for smooth source-to-destination animations.
|
||||
- Deep links and URL routing: `references/deeplinks.md` — Use for in-app navigation from URLs.
|
||||
- Title menus: `references/title-menus.md` — Use for filter or context menus in the navigation title.
|
||||
- Menu bar commands: `references/menu-bar.md` — Use when adding or customizing macOS/iPadOS menu bar commands.
|
||||
- Loading & placeholders: `references/loading-placeholders.md` — Use for redacted skeletons, empty states, and loading UX.
|
||||
- Lightweight clients: `references/lightweight-clients.md` — Use for small, closure-based API clients injected into stores.
|
||||
|
||||
|
|
|
|||
71
swiftui-ui-patterns/references/macos-settings.md
Normal file
71
swiftui-ui-patterns/references/macos-settings.md
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
# macOS Settings
|
||||
|
||||
## Intent
|
||||
|
||||
Use this when building a macOS Settings window backed by SwiftUI's `Settings` scene.
|
||||
|
||||
## Core patterns
|
||||
|
||||
- Declare the Settings scene in the `App` and compile it only for macOS.
|
||||
- Keep settings content in a dedicated root view (`SettingsView`) and drive values with `@AppStorage`.
|
||||
- Use `TabView` to group settings sections when you have more than one category.
|
||||
- Use `Form` inside each tab to keep controls aligned and accessible.
|
||||
- Use `OpenSettingsAction` or `SettingsLink` for in-app entry points to the Settings window.
|
||||
|
||||
## Example: settings scene
|
||||
|
||||
```swift
|
||||
@main
|
||||
struct MyApp: App {
|
||||
var body: some Scene {
|
||||
WindowGroup {
|
||||
ContentView()
|
||||
}
|
||||
#if os(macOS)
|
||||
Settings {
|
||||
SettingsView()
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Example: tabbed settings view
|
||||
|
||||
```swift
|
||||
@MainActor
|
||||
struct SettingsView: View {
|
||||
@AppStorage("showPreviews") private var showPreviews = true
|
||||
@AppStorage("fontSize") private var fontSize = 12.0
|
||||
|
||||
var body: some View {
|
||||
TabView {
|
||||
Form {
|
||||
Toggle("Show Previews", isOn: $showPreviews)
|
||||
Slider(value: $fontSize, in: 9...96) {
|
||||
Text("Font Size (\(fontSize, specifier: "%.0f") pts)")
|
||||
}
|
||||
}
|
||||
.tabItem { Label("General", systemImage: "gear") }
|
||||
|
||||
Form {
|
||||
Toggle("Enable Advanced Mode", isOn: .constant(false))
|
||||
}
|
||||
.tabItem { Label("Advanced", systemImage: "star") }
|
||||
}
|
||||
.scenePadding()
|
||||
.frame(maxWidth: 420, minHeight: 240)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Skip navigation
|
||||
|
||||
- Avoid wrapping `SettingsView` in a `NavigationStack` unless you truly need deep push navigation.
|
||||
- Prefer tabs or sections; Settings is already presented as a separate window and should feel flat.
|
||||
- If you must show hierarchical settings, use a single `NavigationSplitView` with a sidebar list of categories.
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- Don’t reuse iOS-only settings layouts (full-screen stacks, toolbar-heavy flows).
|
||||
- Avoid large custom view hierarchies inside `Form`; keep rows focused and accessible.
|
||||
101
swiftui-ui-patterns/references/menu-bar.md
Normal file
101
swiftui-ui-patterns/references/menu-bar.md
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
# Menu Bar
|
||||
|
||||
## Intent
|
||||
|
||||
Use this when adding or customizing the macOS/iPadOS menu bar with SwiftUI commands.
|
||||
|
||||
## Core patterns
|
||||
|
||||
- Add commands at the `Scene` level with `.commands { ... }`.
|
||||
- Use `SidebarCommands()` when your UI includes a navigation sidebar.
|
||||
- Use `CommandMenu` for app-specific menus and group related actions.
|
||||
- Use `CommandGroup` to insert items before/after system groups or replace them.
|
||||
- Use `FocusedValue` for context-sensitive menu items that depend on the active scene.
|
||||
|
||||
## Example: basic command menu
|
||||
|
||||
```swift
|
||||
@main
|
||||
struct MyApp: App {
|
||||
var body: some Scene {
|
||||
WindowGroup {
|
||||
ContentView()
|
||||
}
|
||||
.commands {
|
||||
CommandMenu("Actions") {
|
||||
Button("Run", action: run)
|
||||
.keyboardShortcut("R")
|
||||
Button("Stop", action: stop)
|
||||
.keyboardShortcut(".")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func run() {}
|
||||
private func stop() {}
|
||||
}
|
||||
```
|
||||
|
||||
## Example: insert and replace groups
|
||||
|
||||
```swift
|
||||
WindowGroup {
|
||||
ContentView()
|
||||
}
|
||||
.commands {
|
||||
CommandGroup(before: .systemServices) {
|
||||
Button("Check for Updates") { /* open updater */ }
|
||||
}
|
||||
|
||||
CommandGroup(after: .newItem) {
|
||||
Button("New from Clipboard") { /* create item */ }
|
||||
}
|
||||
|
||||
CommandGroup(replacing: .help) {
|
||||
Button("User Manual") { /* open docs */ }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Example: focused menu state
|
||||
|
||||
```swift
|
||||
@Observable
|
||||
final class DataModel {
|
||||
var items: [String] = []
|
||||
}
|
||||
|
||||
struct ContentView: View {
|
||||
@State private var model = DataModel()
|
||||
|
||||
var body: some View {
|
||||
List(model.items, id: \.self) { item in
|
||||
Text(item)
|
||||
}
|
||||
.focusedSceneValue(model)
|
||||
}
|
||||
}
|
||||
|
||||
struct ItemCommands: Commands {
|
||||
@FocusedValue(DataModel.self) private var model: DataModel?
|
||||
|
||||
var body: some Commands {
|
||||
CommandGroup(after: .newItem) {
|
||||
Button("New Item") {
|
||||
model?.items.append("Untitled")
|
||||
}
|
||||
.disabled(model == nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Menu bar and Settings
|
||||
|
||||
- Defining a `Settings` scene adds the Settings menu item on macOS automatically.
|
||||
- If you need a custom entry point inside the app, use `OpenSettingsAction` or `SettingsLink`.
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- Avoid registering the same keyboard shortcut in multiple command groups.
|
||||
- Don’t use menu items as the only discoverable entry point for critical features.
|
||||
Loading…
Reference in a new issue