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.