Helpers
PhoenixPaper.Ripple, Elevation, Shape and the motion tokens: the plumbing every component is built on. Color has its own guide.
Ripple
The Material ripple: a circle that expands from the click point and fades. A vanilla inline onclick, no hook or bundler. On by default on buttons, FABs, linked list items and rail items; off by default on Switch, Checkbox and RadioGroup (their 40dp state layer already gives feedback); always off with paperize={false}.
ripple: true (default) vs. ripple: false
| Option | Description |
|---|---|
ripple
|
the boolean attr on interactive components (see each component's options) |
PhoenixPaper.Ripple.on_click/1
|
the onclick script, or nil when disabled (the attribute is dropped) |
PhoenixPaper.Ripple.container_classes/1,2
|
the relative/overflow-hidden the ripple needs; the /2 form takes a position for components with a position attr |
Show code
<.pp_button>Ripples (default)</.pp_button>
<.pp_button ripple={false}>No ripple</.pp_button>
Elevation
MD3 has six elevation levels (0–5) with its own shadows; PhoenixPaper.Elevation.class/1 maps a level (clamped to 5) to a pp-elevation-N class. MD3 mostly separates surfaces by color (the surface-container scale, see Paper), and keeps shadows for things that float.
Levels 0–5
| Option | Description |
|---|---|
Elevation.class(level)
|
the literal "pp-elevation-N" class, level 0–5 |
Show code
<div class={["rounded-pp-md bg-pp-surface-container-low p-4", PhoenixPaper.Elevation.class(3)]}>Level 3</div>
Shape
The MD3 corner scale as --radius-pp-* tokens and rounded-pp-* utilities, including M3 Expressive's lg_increased, xl_increased and xxl. PhoenixPaper.Shape.class/1,2 maps a token to its class, optionally on one edge (:top, :bottom, :start, :end).
The scale
| Option | Description |
|---|---|
Shape.class(token)
|
all four corners |
Shape.class(token, :top | :bottom | :start | :end)
|
only that edge's two corners |
Show code
<div class={["size-14 bg-pp-primary-container", PhoenixPaper.Shape.class(:xl_increased)]} />
<div class={["size-14 bg-pp-primary-container", PhoenixPaper.Shape.class(:lg, :top)]} />
<%!-- or the utilities directly --%>
<div class="size-14 rounded-pp-xxl bg-pp-primary-container" />
Motion
M3 Expressive's motion as springs: spatial springs (for position and size; they can overshoot) and effects springs (for color and opacity; no overshoot), each fast/default/slow, as CSS linear() easings sampled from the real springs. Components use them already; pp-motion-* utilities set the transition for your own elements. data-pp-motion="standard" on an ancestor switches to the calmer standard scheme, prefers-reduced-motion is respected, and the classic MD3 duration easings are available as ease-pp-*.
Hover a row: the square slides with that spring
| Option | Description |
|---|---|
pp-motion-spatial-fast / -default / -slow
|
transition timing + duration for movement and size |
pp-motion-effects-fast / -default / -slow
|
transition timing + duration for color and opacity |
data-pp-motion="standard"
|
on any ancestor: the standard (non-Expressive) motion scheme |
ease-pp-standard / -emphasized (and -accelerate / -decelerate)
|
MD3's cubic-bezier easings, for your own transition-* utilities |
Show code
<%!-- A spring for movement --%>
<div class="transition-transform pp-motion-spatial-default hover:translate-x-4">...</div>
<%!-- An effects spring for color --%>
<div class="bg-pp-surface-container transition-colors pp-motion-effects-fast hover:bg-pp-secondary-container">...</div>
<%!-- The calmer standard scheme for a whole subtree --%>
<div data-pp-motion="standard">...</div>