ShelfWidgetLayout
What a widget mount is, and the box it draws in (DroppyKit 1.23.0).
struct ShelfWidgetLayout
The host builds one for every mount and hands it to makeWidgetContent(_:layout:), and the same value is in the environment (dropletWidgetLayout) for every building block inside the widget. Branch on mode, never on a width: density is already the host's answer to "how much room".
Available from DroppyKit 1.23.0.
Cases
ShelfWidgetLayout.Mode.single
case single
Alone on the shelf: the full single composition.
ShelfWidgetLayout.Mode.singleWrapped(_:)
case singleWrapped(ShelfWidgetNotchWrap)
Alone on the shelf with the header row wrapped beside the camera (a notched Mac or the camera island): the single composition, with ShelfWidgetHeader drawn into the bands.
ShelfWidgetLayout.Mode.split(_:)
case split(ShelfWidgetPlacement)
Sharing a row with one to three other widgets: the split composition, in this slot.
ShelfWidgetLayout.Density.regular
case regular
Alone on the shelf.
ShelfWidgetLayout.Density.compact
case compact
In a row of two to four widgets.
ShelfWidgetLayout.Density.tight
case tight
In a row so full the card is narrower than tightCardWidth: drop the least essential control, as Pomodoro does.
Initializers
init(mode:density:contentSize:surface:isInteractive:isPreview:isVisible:usesAdaptiveForegrounds:foreground:)
init(mode: Mode, density: Density, contentSize: CGSize, surface: DropletSurfaceKind, isInteractive: Bool, isPreview: Bool, isVisible: Bool, usesAdaptiveForegrounds: Bool, foreground: Color)
Creates a layout. Constructed by hosts, read by droplets.
Properties
contentSize
let contentSize: CGSize
The settled box inside the host's insets, in points at the Regular shelf size: exactly what the widget's content is laid out in. Never a frame from the middle of a spring. Its height is zero while the host has not measured the card yet (the first frame of a mount, a preview); lay out to the box, not to this number.
density
let density: Density
How much room the mount has.
foreground
let foreground: Color
The primary ink: the user's Widget Text colour when one applies, the label colour under adaptive foregrounds, white on the notch.
isInteractive
let isInteractive: Bool
false while the shelf springs open or closed and in a preview: the host takes no clicks then and blocks animations, so do not start one.
isPreview
let isPreview: Bool
The mount is a non-interactive preview (Settings, the Custom Shelf editor, the harness's screenshots). Skip side effects.
isSingle
var isSingle: Bool { get }
The widget is alone on the shelf, wrapped or not.
isSplit
var isSplit: Bool { get }
The widget shares its row.
isVisible
let isVisible: Bool
The mount is on a shelf the user can see. Pause timers, polling and animation while it is false.
metrics
let metrics: DroppyWidgetMetrics
The metrics for this mount: spacing, control sizes, the type scale.
mode
let mode: Mode
Where the widget is.
notchWrap
var notchWrap: ShelfWidgetNotchWrap? { get }
The bands beside the camera while the header row is wrapped.
placement
var placement: ShelfWidgetPlacement { get }
The widget's slot in its row; .solo alone.
secondaryForeground
var secondaryForeground: Color { get }
The secondary ink (0.82 of foreground).
surface
let surface: DropletSurfaceKind
The shelf's shape.
tertiaryForeground
var tertiaryForeground: Color { get }
The tertiary ink (0.60 of foreground).
usesAdaptiveForegrounds
let usesAdaptiveForegrounds: Bool
The host draws the shelf over a transparent notch and asks for adaptive foregrounds.
Type methods
density(isSplit:cardWidth:)
static func density(isSplit: Bool, cardWidth: CGFloat?) -> Density
The host's density rule: a card in a row narrower than tightCardWidth is tight, any other card in a row compact, a card alone regular.
standardForeground(usesAdaptiveForegrounds:)
static func standardForeground(usesAdaptiveForegrounds: Bool) -> Color
The ink a mount uses before any Widget Text colour applies.