Carousels — Hero Expressive extension
Material 3 Expressive extension to base Hero carousel (specs/components/ carousels.kmd). Adds shape morphing between selected/peek items (square ↔ pill ↔ squircle) and gesture inertia driven by spring physics (motion.kmd R9.1). Connected to shape-library.kmd morph contract.
Spec — Carousels Hero Expressive
Strict extension to
carousels.kmd§Hero layout. Adds shape morph + spring-driven inertia. Base spec remains valid; Expressive opt-in per surface OR per preset.
Princípios
- *trict extension*— base Hero layout from
carousels.kmdunchanged. - *hape morph items*— selected item uses larger radius, peek items smaller.
- *pring inertia*— gesture release follows spring decay, NOT linear.
- *idth tokens*— large item 64
90% viewport; peek 1032%.
R1 — Anatomy (extension)
Base Hero per carousels.kmd. Expressive adds:
┌──┐ ┌──────────────────┐ ┌──┐
│ ◐│ │ ◯ │ │◐ │
│ │ │ ⬢⬡⬢ │ │ │ ← peek items (Cookie-7-ish) + selected (Pill-ish)
│ ◐│ │ ◯ │ │◐ │
└──┘ └──────────────────┘ └──┘During swipe, shapes morph in real-time (corner radius interpolates).
R2 — Shape tokens
| Position | Default shape (per shape-library.kmd) |
Corner radius |
|---|---|---|
| Selected (center large) | Pill or shape-corner-extra-large |
32dp+ |
| Peek (sides) | shape-corner-large |
16-24dp |
| Mid-transition | interpolated linear | varies |
During swipe gesture:
- Position 0% (center): selected shape full radius.
- Position 50% (mid-swipe): item halfway out, radius interpolates toward peek.
- Position 100% (off-screen): peek shape OR fully gone.
R3 — Spring inertia
Release gesture (swipe-release):
- Velocity captured; preserved into spring
motion-spatial-default. - Spring decay: snap to nearest item center (large OR peek).
- Bounce: subtle overshoot (max ±5dp) by default; configurable per preset.
Forbidden antipattern: linear decay OR frictionbased (felt "slidey").
R4 — Width tokens
| Token | Range | Use |
|---|---|---|
hero-item-large |
64-90% viewport | Selected center |
hero-item-peek |
10-32% viewport | Sides |
hero-gap |
8-16dp | Between items |
Compact widthclass: large 90% + peek 5% (almost only large). Medium/Expanded: large 6470% + peek 18% each side.
R5 — Per-preset variation
| Preset | Hero Expressive style |
|---|---|
material3 |
Subtle (radius delta 16dp; minimal bounce) |
material_expressive |
Full (radius delta 32dp; bounce ±5dp) |
material2 |
Disabled — falls back to baseline carousels |
terminal_classic |
n/a (no carousels in terminal) |
brutalist |
Sharp corners only; no morph; no bounce (instant snap) |
cyberpunk_neon |
Default + glow on selected |
minimalist_mono |
No radius variation; only width difference |
R6 — Surface bindings
| Surface | API |
|---|---|
| Flutter | Extension of KoderCarousel (per carousels.kmd); KoderCarousel(variant: hero, expressive: true) |
| Web | <koder-carousel variant="hero" expressive> |
| Compose | KoderCarousel(variant = Hero, expressive = true) |
| SwiftUI | idem |
| CLI / TUI | n/a |
R7 — Acessibilidade
- Items:
role="listitem"per base spec. - Selected:
aria-current="true". - Swipe alternative: arrow keys advance one item at a time.
- Reduced-motion: no shape morph; no bounce; snap direct (instant transition).
- Touch target: each item ≥ 48dp tap area.
R8 — Reduced-motion
- Shape morph: disabled (static shapes per position).
- Spring inertia: replaced by linear snap (no overshoot, no bounce).
- Item swap: instant.
R9 — i18n
Inherits from carousels.kmd. No new keys.
T-suite
- *1*Mount Hero Expressive: selected item visible center with
Pillshape; peek items sides withshape-corner-large. - *2*Swipe gesture: radius interpolates continuously during drag.
- *3*Release with velocity: spring decay; snaps to nearest center.
- *4*Bounce: subtle overshoot visible (~5dp) before settle in
material_expressive. - *5*Width tokens: Compact width-class → large 90%; Medium → 64% + 18% peeks.
- *6*Reduced-motion: no morph + no bounce; instant snap.
- *7*Keyboard: arrows advance one item.
- *8*Selected aria-current: assistive tech announces correctly.
- *9*Material2 preset: falls back to base carousels (no extension).
Cross-link
- Base:
carousels.kmd§Hero - Shape morph:
shape-library.kmdR2 - Motion:
motion.kmdR9.1 - Layout:
app-layout/window-size-classes.kmd(width tokens) - Refs: M3 Carousel guidelines (Expressive Hero)