Skip to main content

apple-platform-guide

The developer-facing guide to building Apple UI (iOS 26, iPadOS 26, macOS 26) with asset_pipeline's UI::View system. Backed by the Apple HIG corpus and validated by macOS + iOS screenshots. Answers "I want to show X — what component, what args, what HIG says."

Zur Installation springen

Quellinformationen

Repository
amberframework/asset_pipeline
Letzte Quellaktivität
20. Mai 2026 um 17:12
Erkannte Sprache von SKILL.md
Englisch
Sterne
5
Forks
0

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
100 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
apple-platform-guide
description
The developer-facing guide to building Apple UI (iOS 26, iPadOS 26, macOS 26) with asset_pipeline's UI::View system. Backed by the Apple HIG corpus and validated by macOS + iOS screenshots. Answers "I want to show X — what component, what args, what HIG says."
user-invocable
true
allowed-tools
Read, Write, Edit, Glob, Grep, Bash
version
0.1.0
# Apple Platform Guide The developer-facing guide to building Apple UI with asset_pipeline, backed by the HIG corpus and validated by screenshots. For every Apple HIG component there is a matching `components/<slug>.md` answering: what `UI::View` to use, a quickstart, the customization knobs, platform differences, and HIG citations. The `validation/` tree holds the audit trail (HIG reference + rendered screenshots + prose verdict) that proves each component doc is honest — it's the quality bar, not the primary output. The primary output is the usage docs. ## Three-tier structure ``` apple-platform-guide/ SKILL.md (you are here) foundations/ cross-cutting design concepts, hand-curated liquid-glass.md materials.md hierarchy-and-emphasis.md color-and-theming.md typography.md spacing-and-layout.md preview-composition.md preview-screen-recipes.md accessibility-defaults.md sound-and-motion.md components/ one doc per UI::View, generated by the loop buttons.md (not yet — generated per iteration) popovers.md ... recipes/ multi-component patterns, emergent popover-with-glass.md ... validation/ audit trail worklist.json Ralph loop state machine screenshots/ <slug>-macos.png + <slug>-ios.png reports/ one markdown verdict per slug gaps.md human-review queue README.md ``` `foundations/` is read once. `components/` is where you look up how to build X. `recipes/` is for cross-component patterns. `validation/` is the audit trail. ## Decision-tree lookup: "I want to show…" Use this table to pick the right starting doc. Descend into the linked component doc for constructor signatures, theming knobs, and HIG citations. | Intent | Go to | |--------|-------| | …a button that triggers an instantaneous action | `components/buttons.md` | | …a transient menu from a button (contextual actions) | `components/menu-button.md` | | …a focused inspector anchored to an element | `components/popovers.md` | | …a full-screen overlay that needs commit/cancel | `components/sheets.md` | | …an urgent decision the user must acknowledge | `components/alerts.md` | | …a blurred panel behind foreground controls | `foundations/materials.md` + `components/card.md` | | …a Liquid Glass background on a custom view | `foundations/liquid-glass.md` | | …a validation screenshot or HIG preview stage | `foundations/preview-composition.md` | | …the exact screen to render for a component preview | `foundations/preview-screen-recipes.md` | | …vertical or horizontal layout of child views | `components/vstack.md` / `components/hstack.md` | | …a toolbar across the top or leading edge | `components/toolbar.md` | | …a scrollable list of items | `components/list-view.md` | | …editable single-line text input | `components/text-field.md` | | …a selection between 2–5 mutually exclusive options | `components/segmented-control.md` | | …a binary on/off control | `components/toggle.md` | If your intent isn't in the table, consult `../apple-hig/pages/` (the raw HIG corpus) to find the closest matching component page, then look up that slug. ## Quickstart snippets Three canonical snippets. Each compiles with `crystal-alpha build ... -Dmacos` or `-Dios`. ### 1. Button with primary visual weight + glass on iOS 26 `UI::Button` exposes `label`, `foreground_color`, `font`, `disabled`, `on_tap` (source: `src/ui/views/button.cr`). A semantic `role` (`:primary | :cancel | :destructive`) is planned; today wrap in `UI::GlassBackground` for primary weight. ```crystal require "asset_pipeline/ui" primary = UI::Button.new("Continue") { puts "tapped" } primary.foreground_color = UI::Color.new(r: 1.0, g: 1.0, b: 1.0) primary.font = UI::Font.new(size: 17.0, weight: :semibold) glass_wrapped = UI::GlassBackground.new(content: primary, material: :regular) glass_wrapped.corner_radius = 12.0 glass_wrapped.padding = UI::EdgeInsets.new(top: 10.0, trailing: 16.0, bottom: 10.0, leading: 16.0) ``` ### 2. A popover anchored to a button with thin material `UI::Popover` takes a content view and an `arrow_edge`; the companion `UI::PopoverPresenter` owns the anchor-and-present relationship (see `src/ui/views/popover.cr`). ```crystal content = UI::VStack.new(spacing: 8.0) content << UI::Label.new("Filter by") content << UI::SegmentedControl.new(["All", "Unread"], 0) popover = UI::Popover.new(content: content, arrow_edge: :top) filter_btn = UI::Button.new("Filter") presenter = UI::PopoverPresenter.new(popover, anchor: filter_btn) filter_btn.on_tap = -> { presenter.present } # The renderer wraps the popover content in a :thin-material glass layer # on iOS 26 when you set the material explicitly: glass = UI::GlassBackground.new(content: content, material: :thin) popover.content = glass ``` ### 3. A sheet with a toolbar header and confirm/cancel buttons `UI::Sheet` carries a content view, detents, and a dismiss callback (see `src/ui/views/sheet.cr`). Compose a toolbar header + action row inside the sheet's content. ```crystal header = UI::Toolbar.new("Edit Reminder") header.add_item("cancel", "Cancel") { presenter.dismiss } header.add_item("save", "Save") { save_and_dismiss } body = UI::VStack.new(spacing: 12.0, alignment: UI::Alignment::Leading) body << UI::TextField.new("Title") body << UI::DatePicker.new sheet_content = UI::VStack.new(spacing: 0.0) sheet_content << header sheet_content << body sheet = UI::Sheet.new(content: sheet_content) sheet.detents = [:medium, :large] sheet.shows_drag_indicator = true presenter = UI::SheetPresenter.new(sheet) presenter.present ``` ## Customization layers There are three places to change how a component looks. Go to the leftmost option that solves your problem. 1. **Per-instance arguments.** Constructor args and properties on the `UI::View` itself. Example: `popover.arrow_edge = :leading`, `button.foreground_color = Color.new(...)`. Always prefer this — it's scoped to the one place that needs the change. 2. **`UI::Theme` tokens.** Global design tokens applied by the renderer to every component. The full token list lives in `src/ui/theme.cr` — inspect it directly for the canonical set. Current tokens include: - Colors: `primary`, `on_primary`, `primary_container`, `secondary`, `error`, `background`, `surface`, `outline` (plus `on_*` pairs for each). - Typography: `font_family`, `font_size_body`, `font_size_title`, `font_size_headline`, `font_size_caption`. - Shape: `corner_radius_small`, `corner_radius_medium`, `corner_radius_large`. Presets: `UI::Theme.apple_default` and `UI::Theme.material_baseline`. Component- specific tokens like `popover_corner_radius` or `button_min_hit_target` are planned but not yet in `theme.cr` — today those values are baked into the renderer. 3. **Renderer metadata.** Platform-specific overrides for when a knob doesn't exist anywhere else. This level means editing `appkit_renderer.cr` or `uikit_renderer.cr` directly. Avoid unless you've checked both of the above and confirmed there's no abstraction that fits. See `platform-renderers` skill. ## How to ask for a new customization If you need a knob that doesn't exist: 1. **Describe the design intent in one sentence.** "I want popovers to feel more formal — darker shadow, tighter corner." Design intent beats API wishlisting. 2. **Check `foundations/`** for a concept that already expresses this. If your intent is "more formal / quieter", that might already live under `hierarchy-and-emphasis.md` or `materials.md`. Reuse the vocabulary. 3. **Check `UI::Theme`** for an existing token. If your change is app-wide (all popovers, all buttons), a theme token is the right layer — propose adding one to `theme.cr` before adding a per-component property. 4. **If nothing fits, propose in a PR** with (a) the design intent, (b) a HIG citation justifying that it's a real Apple concept not a personal preference, (c) the proposed API shape, and (d) which layer (instance / theme / renderer) it lives at. ## How to re-validate a component When a `UI::View` changes or the HIG page is updated: 1. Open `validation/worklist.json`. 2. Find the row for the slug (e.g. `popovers`). 3. Flip `validation_state` back to `"pending"` and (optionally) clear `docs_written` to force the usage doc to be regenerated too. 4. Re-run the Ralph loop with the `apple-platform-designer` agent. It will re-render, re-screenshot, re-compare, and re-write both the report and the component doc. Previous screenshots are overwritten; previous reports are replaced. ## Cross-references - `apple-hig` — the raw HIG corpus (166 pages + 1,724 images). Source of truth for every citation. - `ios26-native-components` — native SwiftUI / UIKit / AppKit class catalog with iOS 26 Liquid Glass coverage. - `glass-effects` — ObjC bridge details for `NSVisualEffectView` and `UIVisualEffectView`. Go here when implementing a new glass-bearing view. - `build-ui` — the Crystal component DSL for web rendering. `apple-platform-guide` is the native-side analogue. - `component-api` — the full API reference for every `UI::View` type, record, and enum. - `accessibility` — WCAG 2.2 AA compliance — focus, motion, contrast. - `ax-test` — the macOS accessibility-tree test harness. Used by the validation loop to confirm rendered components show up in the AX tree. - `component-mapping-matrix` — the spine table that maps UI::View to SwiftUI / UIKit / AppKit / Compose / Android / Web. A `HIG slug` column links rows here back to `components/<slug>.md`. ## Regeneration Worklist is generated (not hand-edited) by the triage script: ``` python3 ../apple-hig/_build/triage.py ``` That emits `validation/worklist.json` — one row per HIG component page with the existing UI::View mapping, status, and priority. The Ralph loop then walks the `pending` rows and asks the `apple-platform-designer` agent to process each: ``` /ralph-loop:ralph-loop \ "Use the apple-platform-designer agent to validate and document every HIG \ component. Output <promise>HIG_VALIDATION_COMPLETE</promise> when zero pending \ entries remain and every slug has docs_written: true." \ --completion-promise HIG_VALIDATION_COMPLETE ``` > **Slash-command syntax:** the Ralph loop ships as a plugin skill, so the > command is `/ralph-loop:ralph-loop` (plugin name : skill name) — not > `/ralph-loop` alone. Without the colon and second declaration the > command fails with `Unknown skill: ralph-loop`. See `.claude/agents/apple-platform-designer/agent.md` for the per-iteration contract.
Auf GitHub ansehen