Skip to content

v0.3.0 - The chrome-customization release

Choose a tag to compare

@glendonC glendonC released this 12 Jun 12:22
· 41 commits to main since this release

v0.3.0 opens up the framework chrome. Everything a host could previously change
only by forking NookExpandedView is now an additive, non-breaking seam on
NookConfiguration - corner radii, transition curves, expanded width, the
top-bar trailing items, labels, metrics, motion, brand mark, launch defaults,
and a replaceable Settings surface. It also adds a Liquid Glass surface style,
a chrome-derived safe-area for host content (NookContentInsets), and the
module drill-in breadcrumb.

This is the surface downstream hosts have been pinning from main. As of
0.3.0 you can pin a tag again.

This is still 0.x: the public API is not frozen. Pin to a tag.

No source-breaking changes

Every new seam defaults to the existing behavior, and nothing changes for a
single-module host. NookConfiguration(), the Nook demo, and all Examples/*
build unchanged.

One behavior change for multi-module hosts: the module switcher is no longer
a chrome band at the top of the expanded surface. By default switching now
lives in a "Modules" menu-bar section and the cycle / per-module hotkeys, and
the surface stays entirely the module's own. Opt back into an on-screen
switcher with host.moduleSwitcherPlacement = .leadingCluster.

What's new

Chrome customization seams

The headline of the release. All additive on NookConfiguration:

  • style - chrome corner radii.
  • transitions - expand / collapse / convert animation curves.
  • expandedWidth plus a top-bar width mode (.contentColumn) so the top bar
    and host content share one horizontal edge.
  • setSettings(_:) / settings - drop in a custom Settings surface, still
    reached via the gear. NookAppearanceSettingsSection lets you embed the
    framework's appearance controls inside it.
  • setTopBarTrailingItems - host actions left of the lock / gear.
  • NookChromeBehavior - hover side-effects, the cold-launch shimmer, and the
    appearance-to-backdrop mapping.
  • NookChromeLabels / NookChromeMetrics / NookChromeMotion and host status
    severity - localized strings, the few fixed layout values, the in-panel
    springs, and info / success / warning / error banners.
  • NookPreferenceDefaults - host-seeded launch appearance, hotkey, and display
    target. Seed-only: a user value always wins and the seed is never persisted,
    so a later build can revise it for untouched users.
  • NookHostBranding brand mark + NookMarkView - a custom mark that replaces
    the OpenNook glyph in the top bar, About card, and menu bar.
  • NookAccentPreset / accentPreset, NookResolvedTheme.accent, and
    NookResolvedTheme.fontDesign - brand the interactive chrome tint and the
    chrome's own typography.

See the new Examples/ChromeNook for the deeper seams in one place.

Liquid Glass surface style

A third surface style alongside translucent and solid: the real macOS 26
glassEffect material, with a layered pre-Tahoe approximation as the fallback.
It is availability-gated, so it renders the modern material on macOS 26 and the
approximation everywhere else without a runtime-version crash. Host-configurable
like the other styles.

NookContentInsets

A chrome-derived safe-area. Host content can read the inset the chrome occupies
and align to the same horizontal edge as the top bar instead of double-padding.
The per-edge expanded-content inset is configurable (NookEdgeInsets).

Module drill-in breadcrumb

AppState.moduleBreadcrumb renders a drill-in breadcrumb on the host top bar
for multi-module hosts, with an overflow fade mask constrained to the pre-notch
region so it never bleeds under the physical notch.

Module switcher placement

host.moduleSwitcherPlacement decides where a multi-module host surfaces its
switcher; switching is always reachable through the cycle and per-module
hotkeys regardless.

  • .menuBar (default) - a "Modules" section in the menu-bar item, with a check
    on the active module. Nothing is added to the expanded surface.
  • .leadingCluster - a compact switcher folded into the top bar's leading
    cluster. It replaces the leading title rather than adding a band, so it costs
    no extra height and never duplicates the active module's identity.
  • .none - no on-screen switcher; hotkeys only.

Host file picker for modules

Modules present open / save panels through the host's file picker
(filePicker), which activates the app so the panel is interactive from the
non-activating notch panel and holds the surface open while it is up. File
import is folded into the shelf.

Install

.package(url: "https://github.com/glendonC/opennook", from: "0.3.0")

Requirements

  • macOS 15 or later
  • Swift 5.9+
  • Apple Silicon or Intel; notched display preferred but not required

Migration

Nothing required beyond bumping the dependency. Every chrome seam defaults to
the current behavior; adopt them only where you want to diverge from the demo
chrome.