Feedback & status
Shape Loader
Changing SVG shape loader
detent-shape-loader
Port status
- Catalog status
- implemented
- Origin
- upstream
- Phase
- 2
- Wave
- phase-2-feedback
- Group
- Feedback & status
4.4 KB gzip for the class module
Variants
Stroke and filled variants, three sizes and a custom shape list. With
prefers-reduced-motion: reduce each loader paints one static shape and schedules no frame.
Recorded states
loadingrecorded state; no setterreduced motionrecorded state; no setter
Usage
Import
import '/components/shape-loader/define.js';
// or register it yourself
import { DetentShapeLoader } from '/components/shape-loader/shape-loader.js';
Attributes
colordurationfilledhold-durationlabelloopsizestroke-width
Properties
shapes
Slots
No slots are recorded for this component.
Events
No events are recorded for this component.
Example
Runnable example: site/examples/shape-loader.ts. The snippet below is generated from the catalogued attributes.
<detent-shape-loader
color="#FAFAFA"
duration="1.6"
filled
hold-duration="0.4"
label
loop
size="96"
stroke-width
></detent-shape-loader>
Property-only values
const element = document.querySelector('detent-shape-loader');
if (element !== null) {
// shapes: ShapeKind[]
element.shapes = [];
}
Source
The pinned upstream source for this row:
src/components/ui/MorphingShapeLoader.tsxsha256 9c06f1e2ef4e…
Native files
The native module and its artifacts:
src/components/shape-loader/shape-loader.tssrc/components/shape-loader/styles.csssrc/components/shape-loader/define.tsdocs/components/shape-loader.mdsite/examples/shape-loader.tstests/browser/shape-loader.spec.tsevidence/components/shape-loader.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 |
|---|---|---|---|---|
color | color | string | '#FAFAFA' | Kebab-case attribute; camelCase property. |
duration | duration | number | 1.6 | Kebab-case attribute; camelCase property. |
filled | filled | boolean | false | Presence semantics: present means true, absent means false. |
hold-duration | holdDuration | number | 0.4 | Kebab-case attribute; camelCase property. |
label | — | — | — | Recorded in the catalog as an attribute. |
loop | loop | boolean | true | Presence semantics: present means true, absent means false. |
size | size | number | 96 | Kebab-case attribute; camelCase property. |
stroke-width | — | — | — | Recorded in the catalog as an attribute. |
Properties
| Property | Type | Default | Notes |
|---|---|---|---|
shapes | ShapeKind[] | ['circle','square','triangle','circle'] | 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.
- React state/hooks replaced by element-owned state with pre-upgrade property preservation.
- `color` no longer defaults to #FAFAFA (dark)/#0A0A0A (light) via a React theme hook; an absent `color` renders `currentColor` so the token sheet drives both schemes (the catalog default is dark-only and cannot be the native default).
- className replaced by parts svg/shape and `--detent-morphing-loader-color`.
- Morph is a scripted rAF timeline (PC-10.1) because SVG `d` is not interpolable via WAAPI/CSS transitions in Firefox/WebKit; upstream Framer Motion `motion.path` replaced, eased with the upstream cubic-bezier(0.45,0.05,0.2,1).
- `loop` keeps the upstream true default with presence semantics + reflection; opt-out is the property `loop = false`.
- Upstream duplicate aria-label + sr-only span reduced to one host aria-label (PC-12.5).
What it does
One SVG path whose eight anchor points are interpolated between configured shapes, so the morph is a genuine geometric interpolation of matched points rather than a cross-fade.
Upstream behaviour
- Continuous morph between matched-control-point shapes
- Configurable shape list, duration, hold time, and loop behavior
- Stroke and filled variants with optional gradient
- Respects prefers-reduced-motion (renders a single static shape)
Differences from upstream
- Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
- React state/hooks replaced by element-owned state with pre-upgrade property preservation.
- `color` no longer defaults to #FAFAFA (dark)/#0A0A0A (light) via a React theme hook; an absent `color` renders `currentColor` so the token sheet drives both schemes (the catalog default is dark-only and cannot be the native default).
- className replaced by parts svg/shape and `--detent-morphing-loader-color`.
- Morph is a scripted rAF timeline (PC-10.1) because SVG `d` is not interpolable via WAAPI/CSS transitions in Firefox/WebKit; upstream Framer Motion `motion.path` replaced, eased with the upstream cubic-bezier(0.45,0.05,0.2,1).
- `loop` keeps the upstream true default with presence semantics + reflection; opt-out is the property `loop = false`.
- Upstream duplicate aria-label + sr-only span reduced to one host aria-label (PC-12.5).