---
title: "DroppyWidgetMetrics, DroppyKit"
description: "Droppy&#x27;s shelf-widget metrics for one mount (DroppyKit 1.23.0)."
canonical: "https://getdroppy.app/docs/droppykit/api/droppy-widget-metrics"
last-updated: "2026-09-09"
---

# DroppyWidgetMetrics

Droppy's shelf-widget metrics for one mount (DroppyKit 1.23.0).

`struct DroppyWidgetMetrics`

Read them from [`metrics`](https://getdroppy.app/docs/droppykit/api/shelf-widget-layout#metrics), which the host resolves for the mount (alone, wrapped beside the camera, in a row, in a narrow row), or from the environment through [`ShelfWidgetLayout`](https://getdroppy.app/docs/droppykit/api/shelf-widget-layout) inside a building block. Never write 34, 28, 10 or 8 in a widget: the number is wrong in another placement.

|  | Alone | In a row | Narrow row (3-4 across) |
| --- | --- | --- | --- |
| `rowSpacing` | 8 | 6 | 4 |
| `sectionSpacing` | 10 | 8 | 8 |
| `controlSpacing` | 10 | 8 | 6 |
| `controlSize` | 34 | 28 | 24 |
| `controlRowHeight` | 34 | 28 | 28 |
| `headerHeight` | 34 | 28 | 24 |
| `figureTextSize` | 30 | 22 | 18 |

Wrapped beside the camera the numbers are the solo ones, except the header row's control, which is 28 (`headerControlSize`), Stay Awake's wrapped size.

Available from DroppyKit 1.23.0.

## Type properties

### contentHeightRange

`static let contentHeightRange: ClosedRange<CGFloat>`

The range a content height declared with [`ShelfWidgetModeSize`](https://getdroppy.app/docs/droppykit/api/shelf-widget-mode-size) is clamped to: [`shelfWidgetFixedContentHeightRange`](https://getdroppy.app/docs/droppykit/api/droppy-shell-metrics#shelf-widget-fixed-content-height-range) less the 16pt of insets the host adds alone under a notch, so a card never leaves that range.

### single

`static let single: DroppyWidgetMetrics`

Alone on the shelf.

### singleWrapped

`static let singleWrapped: DroppyWidgetMetrics`

Alone on the shelf with the header row wrapped beside the camera: the solo numbers, the header's control at Stay Awake's wrapped 28pt.

### split

`static let split: DroppyWidgetMetrics`

In a row of two to four widgets.

### splitTight

`static let splitTight: DroppyWidgetMetrics`

In a row so full the card is narrower than `tightCardWidth`: Pomodoro's ultra-narrow tier.

### tightCardWidth

`static let tightCardWidth: CGFloat`

A card in a row narrower than this takes `splitTight`: Pomodoro's ultra-narrow threshold, where three fixed-size controls stop leaving room. The host decides it from the settled slot width, so a widget never compares a width itself.

### wrapMinimumBandWidth

`static let wrapMinimumBandWidth: CGFloat`

The narrowest band beside the camera a header row wraps into: Droppy's `NotchWingWrap.minimumBandWidth`.

### wrapSectionSpacing

`static let wrapSectionSpacing: CGFloat`

Between a wrapped header row and what follows it: the solo timers' section spacing, Droppy's `NotchWingWrap.sectionSpacing`.

## Properties

### bodyTextSize

`let bodyTextSize: CGFloat`

[`body`](https://getdroppy.app/docs/droppykit/api/droppy-widget-text-style#body)'s point size.

### captionTextSize

`let captionTextSize: CGFloat`

[`caption`](https://getdroppy.app/docs/droppykit/api/droppy-widget-text-style#caption)'s point size.

### controlRowHeight

`let controlRowHeight: CGFloat`

The height of a last row of controls. In a row of widgets it is 28 even where the discs shrink, so control rows on both sides of a divider share their centre line (`IslandExpandedOptics.PairedRow`).

### controlSize

`let controlSize: CGFloat`

A control in the widget's body or its last row: Pomodoro's discs.

### controlSpacing

`let controlSpacing: CGFloat`

Between two controls in a row: Pomodoro's disc spacing.

### density

`let density: ShelfWidgetLayout.Density`

The density these metrics are for.

### emptyStateGlyphSize

`let emptyStateGlyphSize: CGFloat`

The symbol of an empty state.

### figureTextSize

`let figureTextSize: CGFloat`

[`figure`](https://getdroppy.app/docs/droppykit/api/droppy-widget-text-style#figure)'s point size: Pomodoro's readout.

### headerControlSize

`let headerControlSize: CGFloat`

A control in the header row: `controlSize`, or 28 beside the camera.

### headerHeight

`let headerHeight: CGFloat`

The classic header row's height: as tall as the control at its trailing end, whether or not there is one, so the row never jumps.

### headerSpacing

`let headerSpacing: CGFloat`

Between the header's symbol and its title.

### headerSymbolFont

`var headerSymbolFont: Font { get }`

The header row's symbol: the header's size, medium.

### headerTextSize

`let headerTextSize: CGFloat`

[`header`](https://getdroppy.app/docs/droppykit/api/droppy-widget-text-style#header)'s point size.

### isWrapped

`let isWrapped: Bool`

Whether these are the metrics of a widget wrapped beside the camera.

### listRowControlSize

`let listRowControlSize: CGFloat`

A control inside a list row, wherever the list is.

### readoutTrailingBearing

`let readoutTrailingBearing: CGFloat`

How far a readout's last digit is pulled past its frame in a row, so its ink, not its advance, ends on the card's edge (Pomodoro's 1.3pt at 22pt). Zero alone on the shelf.

### ringDiameter

`let ringDiameter: CGFloat`

A ring's outer diameter: System Stats' ring.

### ringGlyphSize

`let ringGlyphSize: CGFloat`

The symbol inside a ring.

### ringLineWidth

`let ringLineWidth: CGFloat`

A ring's stroke.

### rowSpacing

`let rowSpacing: CGFloat`

Between two rows of a list or a stack: Pomodoro's row spacing.

### secondaryTextSize

`let secondaryTextSize: CGFloat`

[`secondary`](https://getdroppy.app/docs/droppykit/api/droppy-widget-text-style#secondary)'s point size.

### sectionSpacing

`let sectionSpacing: CGFloat`

Between the header row and what follows, and between two groups: Pomodoro's section spacing.

### titleTextSize

`let titleTextSize: CGFloat`

[`title`](https://getdroppy.app/docs/droppykit/api/droppy-widget-text-style#title)'s point size.

## Type methods

### metrics(for:isWrapped:)

`static func metrics(for density: ShelfWidgetLayout.Density, isWrapped: Bool = false) -> DroppyWidgetMetrics`

The metrics for a density.

### resolve(isSplit:isWrapped:cardWidth:)

`static func resolve(isSplit: Bool, isWrapped: Bool, cardWidth: CGFloat?) -> DroppyWidgetMetrics`

The metrics for a mount.

- Parameters:
- isSplit: The widget shares its row.
- isWrapped: The widget's header row is wrapped beside the camera.
- cardWidth: The settled slot width, or `nil` when unknown.

## Methods

### font(_:)

`func font(_ style: DroppyWidgetTextStyle) -> Font`

The font of a role at this mount's size.

### pointSize(_:)

`func pointSize(_ style: DroppyWidgetTextStyle) -> CGFloat`

The point size of a role.
