macos-settings-ui
Skill90 starsChanged 5 months agoMITView on GitHub
Build a proper macOS settings/preferences window with liquid glass support for macOS 26 (Tahoe). Use this skill whenever the user asks to create a settings window, preferences UI, settings view, or preferences pane for a macOS app. Also trigger when the user mentions "liquid glass settings", "NavigationSplitView settings", "grouped Form settings", "macOS settings layout", or wants to add/fix/rebuild a settings screen in any native macOS SwiftUI app. This includes phrases like "add settings to my app", "create a preferences window", "my settings look wrong", "fix my settings UI", or even just "I need a settings view". If the user is building a macOS app and mentions settings or preferences in any context, use this skill.
2 other projects use a version of this.
Adopted by
Most recently taken up by
- lingyired/status-trioword for word, first seen Nov 8, 2026
- fayazara/macos-app-skillsword for word, first seen May 27, 2026
Other versions2 projects use a version of this.
Word for word · 2
- lingyired/status-trio★ 1.8k100% same
- fayazara/macos-app-skills★ 660100% same
Edited · 0
None found.
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository5 other files it gives its agents.
- macos-auto-updateSkill
- macos-buildSkill
- macos-notch-uiSkill
- macos-patternsSkill
- macos-releaseSkill
The file
We split this skill into the rules it gives an agent
6 rules. About 0 are common, 1 is distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 36
Every detail pane MUST have these three modifiers on its Form:
- Distinctive: line 67
Read the reference files for complete, working code:
- Very specific: line 149
Do NOT use a SwiftUI Window scene.
- Very specific: line 153
If you previously had a Window("Settings", id: "SETTINGS") scene in your App struct, remove it entirely.
- Very specific: line 216
If your app uses NSApp.setActivationPolicy(.accessory) (no Dock icon), you need activation policy management so the settings window brings …
- Very specific: line 239
If your app always shows in the Dock, remove the AppActivationPolicy calls from the window controller and just use …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
macOS Settings UI with Liquid Glass
This skill produces a native macOS settings window that follows Apple's macOS 26 design guidelines. The result is a sidebar + detail NavigationSplitView with liquid glass window chrome, back/forward toolbar navigation, grouped Form sections with transparent backgrounds, and proper scroll edge effects.
Architecture Overview
The settings UI is composed of 3 layers:
- Window Controller (
SettingsWindowController.swift) — AnNSWindowControllerthat creates theNSWindowprogrammatically with.fullSizeContentView. This is what gives the window rounded liquid glass corners. You cannot get this effect from a SwiftUIWindowscene. - Root View (
SettingsView.swift) — ANavigationSplitViewwith a sidebar list and detail pane. Includes back/forward navigation history in the toolbar, which also forces the creation of anNSToolbar(required for the liquid glass title bar treatment). - Detail Panes (one file per tab) — Each pane uses
Form { Section(...) { ... } }.formStyle(.grouped).scrollContentBackground(.hidden).
Why NSWindowController Instead of SwiftUI Window Scene
SwiftUI's declarative Window scene does not expose the NSWindow style mask. The .fullSizeContentView flag must be set at window creation time for macOS 26 to render the liquid glass chrome (rounded corners, translucent sidebar, blurred title bar). Trying to inject it later via NSViewRepresentable is unreliable because SwiftUI resets the window's configuration.
The NSWindowController approach also lets you control the toolbar style, frame autosave, minimum size, and delegate lifecycle directly.
Critical Modifiers
Every detail pane MUST have these three modifiers on its Form:
.formStyle(.grouped)
.scrollContentBackground(.hidden)
.contentMargins(.top, 8, for: .scrollContent).formStyle(.grouped)— gives the native inset rounded-rect section appearance.scrollContentBackground(.hidden)— makes the form background transparent so the liquid glass window chrome shows through. Without this, you get an opaque white/dark background that breaks the glass effect..contentMargins(.top, 8)— adds breathing room between the toolbar and the first section
The sidebar List MUST have:
.listStyle(.sidebar)
.scrollEdgeEffectStyleSoftIfAvailable() // macOS 26 progressive blur at scroll edges
.navigationTitle("Settings")The NavigationSplitView MUST have:
NavigationSplitView(columnVisibility: .constant(.all)) // sidebar always visible
// ...
.navigationTitle("Settings")
.navigationSplitViewStyle(.balanced)Reference Implementation
Read the reference files for complete, working code:
references/SettingsWindowController.swift— The window controller (copy as-is, adapt the activation policy calls to your app)references/SettingsView.swift— The root view with sidebar, detail routing, and navigation historyreferences/ExampleDetailPane.swift— A template detail pane showing common control patterns (Toggle, Picker, Slider, LabeledContent)
Step-by-Step: Adding Settings to a New App
1. Create the Tab Enum
Define your settings categories. Each case needs a title and SF Symbol icon:
enum SettingsTab: String, CaseIterable, Identifiable {
case general
case appearance
case about
var id: Self { self }
var title: String {
switch self {
case .general: "General"
case .appearance: "Appearance"
case .about: "About"
}
}
var systemImage: String {
switch self {
case .general: "gearshape"
case .appearance: "paintbrush"
case .about: "info.circle"
}
}
}2. Create the Window Controller
Copy references/SettingsWindowController.swift into your project. Adapt:
- The initial
contentRectsize (default700x540is good for most apps) - The
minSize(default620x460) - The activation policy calls (
AppActivationPolicy.enter()/leave()) — if your app isn't a menu-bar-only app, remove these
3. Create the Root Settings View
Copy references/SettingsView.swift. Adapt:
- The
SettingsTabenum cases to match your categories - The
SettingsDetailViewswitch to return your panes
4. Create Detail Panes
For each tab, create a pane file. Use this template:
import SwiftUI
struct GeneralSettingsPane: View {
@AppStorage("someKey") private var someValue = false
var body: some View {
Form {
Section("Section Name") {
Toggle("Toggle label", isOn: $someValue)
}
}
.formStyle(.grouped)
.scrollContentBackground(.hidden)
.contentMargins(.top, 8, for: .scrollContent)
}
}5. Open Settings from Your App
From a menu bar, button, or anywhere:
SettingsWindowController.show(tab: .general)Do NOT use a SwiftUI Window scene. Do NOT use openWindow(id:). The window controller handles everything.
6. Remove Any SwiftUI Window Scene
If you previously had a Window("Settings", id: "SETTINGS") scene in your App struct, remove it entirely. The SettingsWindowController replaces it.
Common Control Patterns Inside Form Sections
Toggle with description:
Toggle(isOn: $value) {
VStack(alignment: .leading, spacing: 2) {
Text("Primary label")
Text("Description text explaining what this does.")
.font(.caption)
.foregroundStyle(.secondary)
}
}
.toggleStyle(.switch)Picker (dropdown):
Picker("Label", selection: $value) {
Text("Option A").tag(OptionEnum.a)
Text("Option B").tag(OptionEnum.b)
}
.pickerStyle(.menu)Picker (segmented):
Picker("Label", selection: $value) {
ForEach(SomeEnum.allCases) { item in
Text(item.title).tag(item)
}
}
.pickerStyle(.segmented)Slider with value label:
LabeledContent("Size") {
HStack(spacing: 12) {
Slider(value: $size, in: 24...96, step: 2)
.frame(width: 180)
Text("\(Int(size)) pt")
.monospacedDigit()
.foregroundStyle(.secondary)
.frame(width: 46, alignment: .trailing)
}
}Button row:
HStack(spacing: 8) {
Button("Action") { doSomething() }
.controlSize(.small)
Button("Reset") { reset() }
.controlSize(.small)
.disabled(isDefault)
}Menu-Bar-Only Apps
If your app uses NSApp.setActivationPolicy(.accessory) (no Dock icon), you need activation policy management so the settings window brings the app to the foreground. The reference SettingsWindowController calls AppActivationPolicy.enter() on show and .leave() on close. Implement this as a simple reference-counting wrapper:
@MainActor
enum AppActivationPolicy {
private static var count = 0
static func enter() {
count += 1
NSApp.setActivationPolicy(.regular)
NSApp.activate(ignoringOtherApps: true)
}
static func leave() {
count = max(0, count - 1)
guard count == 0 else { return }
Task { @MainActor in
NSApp.setActivationPolicy(.accessory)
}
}
}If your app always shows in the Dock, remove the AppActivationPolicy calls from the window controller and just use NSApp.activate(ignoringOtherApps: true) in showWindow.
macOS Version Compatibility
The scrollEdgeEffectStyle(.soft) API is macOS 26+ only. Always wrap it in an availability check:
private extension View {
@ViewBuilder
func scrollEdgeEffectStyleSoftIfAvailable() -> some View {
if #available(macOS 26.0, *) {
scrollEdgeEffectStyle(.soft, for: .all)
} else {
self
}
}
}The rest of the pattern (NSWindowController with .fullSizeContentView, grouped Form, NavigationSplitView) works on macOS 14+.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

