Detent web components
By Shane Logsdon

Media & effects

Particle Delete

Implemented

Physics-driven pixel particle dissolution delete animation

detent-particle-delete

Port status
Catalog status
implemented
Origin
upstream
Phase
4
Wave
phase-4-canvas
Group
Media & effects

9.1 KB gzip for the class module

Variants

Demo data: the three rows are the component's pinned sample defaults. Delete a row with the mouse or the keyboard (Tab to a trigger, Enter or Space) to see the masked sweep, the pixel dust, one detent-item-deleted and one detent-delete event, and the row count follow. Restore returns every row and emits one detent-restore. With “Reduce motion” enabled the dust and the sweep are replaced by the pinned 160 ms fade and no animation frame is scheduled.

No action yet.

Recorded states

  • focus-visible recorded state; no setter
  • dragging recorded state; no setter
  • reduced motion recorded state; no setter

Usage

Import

import '/components/particle-delete/define.js';

// or register it yourself
import { DetentParticleDelete } from '/components/particle-delete/particle-delete.js';

Attributes

  • options.dissolve-pattern
  • options.duration
  • options.force
  • options.particle-size
  • options.sample-step

Properties

  • initialItems
  • onDelete
  • onItemDeleted
  • onRestore
  • options

Slots

No slots are recorded for this component.

Events

  • detent-delete — {}
  • detent-item-deleted — { item: { id, title, category, description, icon, tag, meta } }
  • detent-restore — {}

Example

Runnable example: site/examples/particle-delete.ts. The snippet below is generated from the catalogued attributes.

<detent-particle-delete
  options.dissolve-pattern="center-first"
  options.duration="850"
  options.force="1.0"
  options.particle-size="1.5"
  options.sample-step
></detent-particle-delete>

Property-only values

const element = document.querySelector('detent-particle-delete');
if (element !== null) {
  // onDelete: () => void
  element.onDelete = () => {};
}

Source

The pinned upstream source for this row:

  • src/components/ui/ParticleDelete.tsx sha256 bbebb78d5a80…

Native files

The native module and its artifacts:

  • src/components/particle-delete/particle-delete.ts
  • src/components/particle-delete/styles.css
  • src/components/particle-delete/define.ts
  • docs/components/particle-delete.md
  • site/examples/particle-delete.ts
  • tests/browser/particle-delete.spec.ts
  • evidence/components/particle-delete.md

API

Boolean attributes follow HTML presence semantics: present means true, absent means false, and disabled="false" still means disabled.

Attributes

Attributes
AttributePropertyTypeDefaultNotes
options.dissolve-patternoptions.dissolvePattern'center-first' | 'edges-first' | 'uniform' | 'random''center-first'Kebab-case attribute; camelCase property.
options.durationoptions.durationnumber850Kebab-case attribute; camelCase property.
options.forceoptions.forcenumber1.0Kebab-case attribute; camelCase property.
options.particle-sizeoptions.particleSizenumber1.5Kebab-case attribute; camelCase property.
options.sample-stepoptions.sampleStepnumber2 (desktop) / 3 (mobile)Kebab-case attribute; camelCase property.

Properties

Properties
PropertyTypeDefaultNotes
initialItems——Recorded in the catalog without a top-level type; pinned from source when the row is ported.
onDelete() => void—Property-only: assign from script; not accepted as an attribute.
onItemDeleted——Recorded in the catalog without a top-level type; pinned from source when the row is ported.
onRestore——Recorded in the catalog without a top-level type; pinned from source when the row is ported.
options——Recorded in the catalog without a top-level type; pinned from source when the row is ported.

Events

Events
EventUpstream propPayload typeNotes
detent-deleteonDelete() => voidComposed, bubbles; fires only for a user action.
detent-item-deletedonItemDeleted(item: ParticleDeleteItem) => voidComposed, bubbles; fires only for a user action.
detent-restoreonRestore() => voidComposed, 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.
  • The catalog option surface replaces the source density, maxParticles, direction and colors options.
  • The dust overlay is shadow-local, so nothing is appended to the consumer document.
  • The speck count is bounded to 80..480.
  • Framer layout and height springs become CSS: no row position projection and no animated digit.
  • The dark-only palette becomes theme tokens.
  • Focus after restore moves to the first trigger (accessibility correction).
  • dragging is the press affordance (data-pressed + scale 0.92); the pinned source has no drag.
  • React-only exports (useParticleDelete, ParticleDeleteContainer) are dropped and name is not a host property.
  • The status label is rendered once.
  • The row exportName is the upstream function name, so the class is declared lowercase and exported as both particleDelete and ParticleDelete; the PascalCase class rename is scheduled in the naming review (U7).

What it does

Every trigger draws a 2 px focus ring in :focus-visible and the ring is measured at 6.5:1 (light) / 7.8:1 (dark).

Upstream behaviour
  • Authentic pixel capture inherits real component colors and typography
  • Hardware-accelerated 60 FPS Canvas rendering with zero DOM overhead
  • Configurable physics: duration, explosion force, drag, and dissolution spread
  • Full accessibility support with automatic prefers-reduced-motion fallback
  • Available as direct utility particleDelete(), hook useParticleDelete(), or <ParticleDeleteContainer /> wrapper
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.
  • The catalog option surface replaces the source density, maxParticles, direction and colors options.
  • The dust overlay is shadow-local, so nothing is appended to the consumer document.
  • The speck count is bounded to 80..480.
  • Framer layout and height springs become CSS: no row position projection and no animated digit.
  • The dark-only palette becomes theme tokens.
  • Focus after restore moves to the first trigger (accessibility correction).
  • dragging is the press affordance (data-pressed + scale 0.92); the pinned source has no drag.
  • React-only exports (useParticleDelete, ParticleDeleteContainer) are dropped and name is not a host property.
  • The status label is rendered once.
  • The row exportName is the upstream function name, so the class is declared lowercase and exported as both particleDelete and ParticleDelete; the PascalCase class rename is scheduled in the naming review (U7).
Previous: Package Box Next: Payment Receipt Printer

Docs

Components

Project