Feedback & status
Not Found
Minimal spring-displaced 404 error experience with tactile proximity physics
detent-not-found
Port status
- Catalog status
- implemented
- Origin
- upstream
- Phase
- 2
- Wave
- phase-2-feedback
- Group
- Feedback & status
7.1 KB gzip for the class module
Variants
Two configurations: the primary 404 above the Variants heading with a path chip and a secondary action, and this 410
with the chip hidden and the secondary control in detent-back mode. Both link sets are real
<a href> elements; the pointer parallax and the entrance rise stop under
prefers-reduced-motion: reduce.
Recorded states
focus-visiblerecorded state; no setterreduced motionrecorded state; no setteractiverecorded state; no setter
Usage
Import
import '/components/not-found/define.js';
// or register it yourself
import { DetentNotFound } from '/components/not-found/not-found.js';
Attributes
action-labelback-labelbadge-labeldescriptiondocument-titleerror-codehome-hrefhome-labelparallaxpathsecondary-action-labelshow-backtitle
Properties
suggestionsonActiononSecondaryAction
Slots
defaultdescriptionfooter
Events
detent-action— {}detent-secondary-action— {}detent-back— {}
Example
Runnable example: site/examples/not-found.ts. The snippet below is generated from the catalogued attributes.
<detent-not-found
action-label="Go back home"
back-label
badge-label
description="The requested page doesn\\'t exist or may have moved."
document-title
error-code="404"
home-href
home-label
parallax
path
secondary-action-label
show-back
title="This page took a wrong turn."
></detent-not-found>
Property-only values
const element = document.querySelector('detent-not-found');
if (element !== null) {
// onAction: () => void
element.onAction = () => {};
// onSecondaryAction: () => void
element.onSecondaryAction = () => {};
}
Source
The pinned upstream source for this row:
src/components/ui/NotFound.tsxsha256 d18b49cfe8db…
Native files
The native module and its artifacts:
src/components/not-found/not-found.tssrc/components/not-found/styles.csssrc/components/not-found/define.tsdocs/components/not-found.mdsite/examples/not-found.tstests/browser/not-found.spec.tsevidence/components/not-found.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 |
|---|---|---|---|---|
action-label | actionLabel | string | 'Go back home' | Kebab-case attribute; camelCase property. |
back-label | — | — | — | Recorded in the catalog as an attribute. |
badge-label | badgeLabel | string | undefined | Kebab-case attribute; camelCase property. |
description | description | string | 'The requested page doesn\\'t exist or may have moved.' | Kebab-case attribute; camelCase property. |
document-title | — | — | — | Recorded in the catalog as an attribute. |
error-code | errorCode | string | '404' | Kebab-case attribute; camelCase property. |
home-href | — | — | — | Recorded in the catalog as an attribute. |
home-label | — | — | — | Recorded in the catalog as an attribute. |
parallax | — | — | — | Recorded in the catalog as an attribute. |
path | — | — | — | Recorded in the catalog as an attribute. |
secondary-action-label | secondaryActionLabel | string | undefined | Kebab-case attribute; camelCase property. |
show-back | — | — | — | Recorded in the catalog as an attribute. |
title | title | string | 'This page took a wrong turn.' | Kebab-case attribute; camelCase property. |
Properties
| Property | Type | Default | Notes |
|---|---|---|---|
suggestions | — | — | Recorded in the catalog without a top-level type; pinned from source when the row is ported. |
onAction | () => void | undefined | Property-only: assign from script; not accepted as an attribute. |
onSecondaryAction | () => void | undefined | Property-only: assign from script; not accepted as an attribute. |
Events
| Event | Upstream prop | Payload type | Notes |
|---|---|---|---|
detent-action | onAction | () => void | Composed, bubbles; fires only for a user action. |
detent-secondary-action | onSecondaryAction | () => void | Composed, bubbles; fires only for a user action. |
detent-back | onBack | () => void | Composed, bubbles; fires only for a user action. |
Slots
| Slot | Notes |
|---|---|
default | Consumer content; rendered through a slot, never re-created. |
description | Consumer content; rendered through a slot, never re-created. |
footer | Consumer content; rendered through a slot, never re-created. |
CSS customisation
- `className` prop is replaced by documented CSS parts/custom properties; no Tailwind in consumers.
- 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.
- No `LinkComponent` property (a React component reference cannot be an attribute or plain-data property, PC-3.1); links are real `<a href>` (PC-12.1) and the callbacks become cancelable composed events.
- `onAction`/`onBack`/`onSecondaryAction` become `detent-action`, `detent-back` and `detent-secondary-action` (detail `{}`, bubbles + composed, cancelable): `detent-action` on primary activation, and the secondary control emits `detent-secondary-action` when `secondary-action-label` is set, otherwise `detent-back` - exactly one event per activation.
- `className` replaced by 16 parts and 2 custom properties.
- Token palette instead of the dark-only hex set; solid heading instead of gradient-clipped text (contrast).
- `document-title` attribute instead of React 19 head hoisting, and no `<meta name="robots">` write.
- `--detent-not-found-min-height` (22rem) instead of `min-h-screen`.
- CSS keyframes/transitions and a throttled transform instead of Framer Motion springs (no spring smoothing on the parallax).
- `suggestions` is property-only with a URL-scheme allow-list (`javascript:`/`data:` never become hrefs).
- Illustration re-created as local SVG/CSS (glass panel + SVG-text 404 glyphs) - an L5 visual gap until compared against the reference.
- `show-back`/`parallax` keep the upstream true default with presence semantics + property opt-out.
What it does
A recovery page for a missing route: an illustration (orange panel, big 404, frosted-glass folder, cross badge), a badge, a heading, a description, an optional "missing path" chip, one primary recovery control, an optional secondary/back control, up to three suggestion links and a footer.
Upstream behaviour
- Pure floating spring-physics entities for each character with custom mass and damping
- Continuous pointer proximity repulsion without React state re-renders (zero-jank 60fps)
- Mobile-first tactile tap impulse feedback for touch screens
- Strictly adheres to EasyUI dark neutral palette and Sky-400 focus ring
- Full accessibility support with screen reader announcements and semantic heading hierarchy
- Seamless prefers-reduced-motion fallback disabling continuous movement
Differences from upstream
- `className` prop is replaced by documented CSS parts/custom properties; no Tailwind in consumers.
- 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.
- No `LinkComponent` property (a React component reference cannot be an attribute or plain-data property, PC-3.1); links are real `<a href>` (PC-12.1) and the callbacks become cancelable composed events.
- `onAction`/`onBack`/`onSecondaryAction` become `detent-action`, `detent-back` and `detent-secondary-action` (detail `{}`, bubbles + composed, cancelable): `detent-action` on primary activation, and the secondary control emits `detent-secondary-action` when `secondary-action-label` is set, otherwise `detent-back` - exactly one event per activation.
- `className` replaced by 16 parts and 2 custom properties.
- Token palette instead of the dark-only hex set; solid heading instead of gradient-clipped text (contrast).
- `document-title` attribute instead of React 19 head hoisting, and no `<meta name="robots">` write.
- `--detent-not-found-min-height` (22rem) instead of `min-h-screen`.
- CSS keyframes/transitions and a throttled transform instead of Framer Motion springs (no spring smoothing on the parallax).
- `suggestions` is property-only with a URL-scheme allow-list (`javascript:`/`data:` never become hrefs).
- Illustration re-created as local SVG/CSS (glass panel + SVG-text 404 glyphs) - an L5 visual gap until compared against the reference.
- `show-back`/`parallax` keep the upstream true default with presence semantics + property opt-out.