DropletSettingsPane
The root of a droplet's settings pane (DroppyKit 1.9.0).
@MainActor struct DropletSettingsPane<Content> where Content : View
Wrap your sections and cards in it and return it from makeSettingsPane(context:). The host places the pane in the grouped Form its own Settings pages are built from, and every row inside renders as that Form's own row: a DropletSettingsCard is a Section, a DropletToggleRow is the Form's switch row, a DropletSliderRow is its slider, a picker row carries the System Settings pop-up face. Nothing in the pane draws a card, a divider or a row metric by hand any more, so the page is indistinguishable from System Settings, and it follows the OS when the OS moves.
Its content is a list of sections, never a stack: a VStack inside a Form is one row. Put cards and DropletSettingsSections straight inside it, top to bottom.
DropletSettingsPane {
DropletSettingsCard {
DropletToggleRow(title: "Show seconds", isOn: droplet.showsSecondsBinding)
}
DropletSettingsSection {
settingsSectionHeader("Clocks")
} content: {
DropletSettingsCard { ... }
}
}A pane whose root is a VStack of cards, the shape every droplet built before 1.9.0 has, keeps working: the host mounts it on the same Form page, and the primitives draw the Form's card, rows and header by hand, so its page looks the same. What it does not get is the Form's own vertical rhythm between sections (that is the stack's spacing, which the pane owns) and the Form's native menu, keyboard and VoiceOver on each row. Wrapping the sections in this pane is the whole migration.
Before macOS 15 the host has no native form page, so the pane is a plain group of its content and the rows draw that hand-made chrome.
Initializers
init(content:)
@MainActor init(@ViewBuilder content: () -> Content)
Creates a pane from its sections and cards.
Properties
body
@MainActor var body: some View { get }