Media & effects
Folder Cards
macOS folder icon with fluid spring card reveal
detent-folder-cards
Port status
- Catalog status
- implemented
- Origin
- upstream
- Phase
- 4
- Wave
- phase-4-cinematic
- Group
- Media & effects
7.9 KB gzip for the class module · inlines the shared spring
Variants
Hover the folder to lift the peeking cards and tilt the flap; click it (or press Enter/Space) to open the card grid. Focus moves to Close when the folder opens, and Escape or Close collapses it again with focus back on the folder. The row records no events, so nothing is dispatched.
Demonstration data: the open folder shows a labelled demo list, not consumer content. With
prefers-reduced-motion: reduce the parallax is removed entirely (no spring, no animation frame) and
both states are reached instantly.
Recorded states
hoverrecorded state; no setterexpandedrecorded state; no setterreduced motionrecorded state; no setter
Usage
Import
import '/components/folder-cards/define.js';
// or register it yourself
import { DetentFolderCards } from '/components/folder-cards/folder-cards.js';
Attributes
default-openfolder-categoryfolder-titleis-peeked
Properties
items
Slots
No slots are recorded for this component.
Events
No events are recorded for this component.
Example
Runnable example: site/examples/folder-cards.ts. The snippet below is generated from the catalogued attributes.
<detent-folder-cards
default-open
folder-category="Pipeline"
folder-title="Components"
is-peeked
></detent-folder-cards>
Property-only values
const element = document.querySelector('detent-folder-cards');
if (element !== null) {
// items: MacOSFolderCardItem[]
element.items = [];
}
Source
The pinned upstream source for this row:
src/components/ui/MacOSFolderCards.tsxsha256 32967c238837…
Native files
The native module and its artifacts:
src/components/folder-cards/folder-cards.tssrc/components/folder-cards/styles.csssrc/components/folder-cards/define.tsdocs/components/folder-cards.mdsite/examples/folder-cards.tstests/browser/folder-cards.spec.tsevidence/components/folder-cards.md
API
Boolean attributes follow HTML presence semantics: present means true, absent means false, and disabled="false" still means disabled.
Attributes
| Attribute | Property | Type | Default | Notes |
|---|---|---|---|---|
default-open | defaultOpen | boolean | false | Presence semantics: present means true, absent means false. |
folder-category | folderCategory | string | 'Pipeline' | Kebab-case attribute; camelCase property. |
folder-title | folderTitle | string | 'Components' | Kebab-case attribute; camelCase property. |
is-peeked | — | — | — | Recorded in the catalog as an attribute. |
Properties
| Property | Type | Default | Notes |
|---|---|---|---|
items | MacOSFolderCardItem[] | demo items | Property-only: assign from script; not accepted as an attribute. |
Events
No custom events are recorded for this component.
Slots
No slots are recorded for this component.
CSS customisation
- Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
- `lucide-react` icon components replaced with local SVG assets (ISC notice retained).
- React state/hooks replaced by element-owned state with pre-upgrade property preservation.
- One static tree and a deliberate focus contract replace the AnimatePresence subtree swap that dropped focus to body; the inactive section is hidden and focus moves into the expanded view and back on close.
- folderCategory is rendered as the header category breadcrumb (hidden when empty); the pinned source declared it but never rendered it.
- items[].icon is a glyph name over four local SVGs instead of a ReactNode; unknown names fall back to layers.
- VelocityAwareScrollCards is dropped because it was a deprecation alias of the same component; the upstream alias stays in upstreamAliases.
- Collapse is immediate so the documented focus return is not delayed; the panel and card entrance animation is kept.
- The expanded panel and card entrance use WAAPI with the same 260 ms curve and 30 ms stagger; hover and parallax keep the pinned springs.
- Boundary colours are raised to #6b6b6b and card meta text to #a1a1a1 for 1.4.11 and 1.4.3; the card grid stays a fixed dark surface in both schemes.
- items is validated as plain data and the built-in list is upstream demonstration data.
- The trigger has no hand-written aria-label: its accessible name is computed from its visible title and count plus a visually hidden hint, so the visible text cannot fall out of the name (WCAG 2.5.3). The decorative folder art stays aria-hidden.
What it does
A porcelain-white macOS folder that lifts its three peeking cards under the pointer and opens into a card grid.
Upstream behaviour
- Porcelain-white macOS folder silhouette with 3D flap hinge and cards peeking from pocket
- Interactive hover parallax lifts cards and tilts folder flap in 3D perspective
- Opens into a minimal, seamless card grid with Apple fluid spring easing
- Crisp pure white icons and EasyUI dark surface harmony
Differences from upstream
- Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
- `lucide-react` icon components replaced with local SVG assets (ISC notice retained).
- React state/hooks replaced by element-owned state with pre-upgrade property preservation.
- One static tree and a deliberate focus contract replace the AnimatePresence subtree swap that dropped focus to body; the inactive section is hidden and focus moves into the expanded view and back on close.
- folderCategory is rendered as the header category breadcrumb (hidden when empty); the pinned source declared it but never rendered it.
- items[].icon is a glyph name over four local SVGs instead of a ReactNode; unknown names fall back to layers.
- VelocityAwareScrollCards is dropped because it was a deprecation alias of the same component; the upstream alias stays in upstreamAliases.
- Collapse is immediate so the documented focus return is not delayed; the panel and card entrance animation is kept.
- The expanded panel and card entrance use WAAPI with the same 260 ms curve and 30 ms stagger; hover and parallax keep the pinned springs.
- Boundary colours are raised to #6b6b6b and card meta text to #a1a1a1 for 1.4.11 and 1.4.3; the card grid stays a fixed dark surface in both schemes.
- items is validated as plain data and the built-in list is upstream demonstration data.
- The trigger has no hand-written aria-label: its accessible name is computed from its visible title and count plus a visually hidden hint, so the visible text cannot fall out of the name (WCAG 2.5.3). The decorative folder art stays aria-hidden.