/// Data Display
Spoiler
Clamps content to a max height with a fade, revealing the rest behind a Show more / Show less toggle.
import { Spoiler } from "@protocore/pds";Basics
Spoiler clamps its children to maxHeight, fades the cut edge, and offers a mono UPPERCASE Show more toggle. When the content already fits, no toggle appears — the clamp is inert, so short content looks untouched.
Reconciliation run #4821 processed 12,904 transactions across three settlement rails. The ledger matched the bank feed on all but two entries, both flagged for manual review. Currency normalisation applied the 04:00 UTC rate table. The cleared batch was settled at 04:12 UTC and the audit log was sealed. No discrepancies remained after the second pass, and the downstream reporting job was triggered automatically.
Custom labels & height
Tune maxHeight and swap showLabel / hideLabel for domain wording — "Expand log" / "Collapse log". The toggle state is uncontrolled by default; wire expanded + onExpandedChange to control it.
[04:12:01] settle: batch #4821 opened
[04:12:01] rail: SEPA connected
[04:12:02] rail: SWIFT connected
[04:12:02] rail: ACH connected
[04:12:04] fx: applied rate table 04:00Z
[04:12:07] match: 12902/12904 entries reconciled
[04:12:07] flag: 2 entries -> manual review
[04:12:09] settle: batch sealed
[04:12:09] report: downstream job triggeredWhen to use it
Spoiler is for one long block you want to preview — a verbose changelog entry, a long error stack, a policy paragraph — where a full accordion header would be overkill. When you have *several* independently collapsible sections, use Accordion; when the hidden content is a distinct panel, use a Collapse-style disclosure.
It measures the real content height and only shows the toggle when the content actually overflows the clamp, so it never offers a "Show more" that reveals nothing. The fade uses the canvas colour, so place it on the page canvas or a matching surface.
Usage
Do
- Use it to preview a single long block with a graceful cut.
- Give the toggle domain wording via `showLabel` / `hideLabel`.
- Control it with `expanded` when the state lives in your model.
Don't
- For several sections, use an Accordion.
- Set `maxHeight` high enough not to clip a single line.
- Place it over a surface matching the fade's canvas color.
Accessibility
- The toggle is a real `button` with `aria-expanded` reflecting state and `aria-controls` pointing at the clamped region.
- The control only renders when content overflows, so keyboard users never tab to a no-op toggle.
- The height transition and fade are decorative and honour `prefers-reduced-motion`.
Spoiler props
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | The (potentially long) content to clamp. |
className | string | — | |
defaultExpanded | boolean | false | Initial expanded state (uncontrolled). |
expanded | boolean | — | Controlled expanded state. |
hideLabel | ReactNode | Show less | Toggle label shown while expanded. |
maxHeight | string | number | 120 | Collapsed height in px (number) or any CSS length. |
onExpandedChange | ((expanded: boolean) => void) | — | Fires when the user toggles; receives the next expanded state. |
showLabel | ReactNode | Show more | Toggle label shown while collapsed. |
style | CSSProperties | — |