Feedback & status
Intro Loader
Apple-style multilingual greeting welcome splash
detent-intro-loader
Port status
- Catalog status
- implemented
- Origin
- upstream
- Phase
- 4
- Wave
- phase-4-cinematic
- Group
- Feedback & status
7.4 KB gzip for the class module · inlines the shared spring
Variants
This loader is the full-screen default: it opens as a native modal
<dialog> (Escape or the Skip button completes it once and focus returns to the page). The one in
the preview is the inline documentation mode: it cycles the same greetings in normal flow and shows
Replay Intro when it finishes. Both emit exactly one composed detent-complete with an
empty detail.
Reduced motion is honoured at runtime as well: with prefers-reduced-motion: reduce both loaders
complete immediately, with no timer and no animation frame. Visible demonstration data: the greeting list comes from
the pinned upstream defaults.
Recorded states
closedrecorded state; no setterreduced motionrecorded state; no settercompletedrecorded state; no setter
Usage
Import
import '/components/intro-loader/define.js';
// or register it yourself
import { DetentIntroLoader } from '/components/intro-loader/intro-loader.js';
Attributes
allow-skipfull-screeninterval-msshow-lang-badgeshow-progressspeed-multiplier
Properties
greetingsonComplete
Slots
No slots are recorded for this component.
Events
detent-complete— {}
Example
Runnable example: site/examples/intro-loader.ts. The snippet below is generated from the catalogued attributes.
<detent-intro-loader
allow-skip
full-screen
interval-ms="240"
show-lang-badge
show-progress
speed-multiplier="1"
></detent-intro-loader>
Property-only values
const element = document.querySelector('detent-intro-loader');
if (element !== null) {
// greetings: (string | GreetingItem)[]
element.greetings = () => {};
// onComplete: () => void
element.onComplete = () => {};
}
Source
The pinned upstream source for this row:
src/components/ui/IntroLoader.tsxsha256 be9623d2721e…
Native files
The native module and its artifacts:
src/components/intro-loader/intro-loader.tssrc/components/intro-loader/styles.csssrc/components/intro-loader/define.tsdocs/components/intro-loader.mdsite/examples/intro-loader.tstests/browser/intro-loader.spec.tsevidence/components/intro-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 |
|---|---|---|---|---|
allow-skip | allowSkip | boolean | true | Presence semantics: present means true, absent means false. |
full-screen | fullScreen | boolean | true | Presence semantics: present means true, absent means false. |
interval-ms | intervalMs | number | 240 | Kebab-case attribute; camelCase property. |
show-lang-badge | showLangBadge | boolean | true | Presence semantics: present means true, absent means false. |
show-progress | showProgress | boolean | true | Presence semantics: present means true, absent means false. |
speed-multiplier | speedMultiplier | number | 1 | Kebab-case attribute; camelCase property. |
Properties
| Property | Type | Default | Notes |
|---|---|---|---|
greetings | (string | GreetingItem)[] | ['Hello', 'Hola', 'Bonjour', ...] | Property-only: assign from script; not accepted as an attribute. |
onComplete | () => void | undefined | Property-only: assign from script; not accepted as an attribute. |
Events
| Event | Upstream prop | Payload type | Notes |
|---|---|---|---|
detent-complete | onComplete | () => void | Composed, bubbles; fires only for a user action. |
Slots
No slots are recorded for this component.
CSS customisation
- React callback props become typed composed CustomEvents; programmatic state assignment emits none.
- 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.
- The 650 ms AnimatePresence exit transition is removed: the overlay closes immediately on completion or skip so focus returns without a dead window (PC-12.4); the greeting entry and replay entrance are preserved.
- The visible language badge is rendered; the pinned source destructured showLangBadge and typed GreetingItem.lang but never rendered a badge.
- The visible greeting is aria-hidden and the live region is the single announcement, where upstream rendered the greeting twice.
- A native modal dialog replaces the role=dialog div: real top layer, real inertness, native cancel on Escape, and aria-modal=true only in full-screen mode.
- Reduced motion completes in a microtask with no timer, and a runtime preference change also completes immediately.
- Empty or invalid greetings fall back to the pinned default list instead of crashing on undefined.
- The ESC skip hint hides below 640 px while the button keeps its accessible name.
- showLangBadge, fullScreen, showProgress and allowSkip default true and are reflected while connected; the property is the opt-out (PC-3.2).
- Progress track and boundaries use #6b6b6b/#8a8a8a instead of the upstream hairlines that measured below the 1.4.11 3:1 threshold (PC-12.6).
What it does
An Apple-style multilingual welcome splash: it cycles greetings, tracks the sequence with a hairline progress bar, can be skipped with Escape or a button, and completes exactly once.
Upstream behaviour
- Rapid multilingual greeting cycling inspired by Apple OS welcome splash
- Fluid blur, scale, and opacity entry transitions calibrated with cubic-bezier curves
- Apple-style hairline progress indicator tracking sequence completion
- Keyboard and tactile skip mechanism (ESC key or dedicated discrete button)
- Full accessibility support with aria-live announcements and reduced-motion fallbacks
- Supports both full-screen initial overlay and inline documentation preview modes
Differences from upstream
- React callback props become typed composed CustomEvents; programmatic state assignment emits none.
- 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.
- The 650 ms AnimatePresence exit transition is removed: the overlay closes immediately on completion or skip so focus returns without a dead window (PC-12.4); the greeting entry and replay entrance are preserved.
- The visible language badge is rendered; the pinned source destructured showLangBadge and typed GreetingItem.lang but never rendered a badge.
- The visible greeting is aria-hidden and the live region is the single announcement, where upstream rendered the greeting twice.
- A native modal dialog replaces the role=dialog div: real top layer, real inertness, native cancel on Escape, and aria-modal=true only in full-screen mode.
- Reduced motion completes in a microtask with no timer, and a runtime preference change also completes immediately.
- Empty or invalid greetings fall back to the pinned default list instead of crashing on undefined.
- The ESC skip hint hides below 640 px while the button keeps its accessible name.
- showLangBadge, fullScreen, showProgress and allowSkip default true and are reflected while connected; the property is the opt-out (PC-3.2).
- Progress track and boundaries use #6b6b6b/#8a8a8a instead of the upstream hairlines that measured below the 1.4.11 3:1 threshold (PC-12.6).