Detent web components
By Shane Logsdon

Buttons & actions

Ripple Button

Implemented

Pointer-origin liquid press feedback

detent-ripple-button

Port status
Catalog status
implemented
Origin
upstream
Phase
2
Wave
phase-2-controls
Group
Buttons & actions
Run interaction

3.8 KB gzip for the class module

Variants

Generate preview No icon

Recorded states

  • pressed recorded state; no setter
  • reduced motion recorded state; no setter

Usage

Import

import '/components/ripple-button/define.js';

// or register it yourself
import { DetentRippleButton } from '/components/ripple-button/ripple-button.js';

Attributes

  • show-icon
  • variant

Properties

  • variant
  • showIcon

Slots

  • default

Events

No events are recorded for this component.

Example

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

<detent-ripple-button
  show-icon
  variant="primary"
></detent-ripple-button>

Source

The pinned upstream source for this row:

  • src/components/ui/LiquidRippleButton.tsx sha256 f00a76b9e0e0…

Native files

The native module and its artifacts:

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

API

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

Attributes

Attributes
AttributePropertyTypeDefaultNotes
show-icon———Recorded in the catalog as an attribute.
variantvariant'primary' | 'secondary''primary'Kebab-case attribute; camelCase property.

Properties

Properties
PropertyTypeDefaultNotes
variant'primary' | 'secondary''primary'Property-only: assign from script; not accepted as an attribute.
showIcon——Recorded in the catalog without a top-level type; pinned from source when the row is ported.

Events

No custom events are recorded for this component.

Slots

Slots
SlotNotes
defaultConsumer content; rendered through a slot, never re-created.

CSS customisation

  • React `children`/`ReactNode` props become DOM slots; caller content stays light DOM.
  • 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.
  • `variant` defaults to 'primary' per this row and the upstream meta, although the pinned source declares 'secondary'.
  • `show-icon` resolves true and is reflected; the property is the opt-out (accepted PC-3.2 rule).
  • `children` becomes the default slot and `className` maps to parts and custom properties.
  • Framer whileHover/whileTap become CSS transitions (220ms) plus WAAPI ripples; springSnappy has no native counterpart, so the press settle is monotonic (PC-10.4).
  • The lucide Droplets icon becomes an inlined local SVG (ISC notice retained).
  • The fixed #161616/#FAFAFA/cyan palette becomes theme tokens with upstream hex fallbacks; the secondary boundary is a color-mix of the text token because upstream #3A3A3A only reaches 3:1 on a dark page.
  • Reduced motion keeps a brightness press cue (upstream kept none).

What it does

A button whose press feedback is a pair of rings expanding from the exact press point, over a slow wave layer that sits below the label and icon.

Upstream behaviour
  • Ripple originates from the actual press point
  • Slow secondary wave remains below the label and icon
  • Primary and secondary variants match EasyUI button surfaces
Differences from upstream
  • React `children`/`ReactNode` props become DOM slots; caller content stays light DOM.
  • 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.
  • `variant` defaults to 'primary' per this row and the upstream meta, although the pinned source declares 'secondary'.
  • `show-icon` resolves true and is reflected; the property is the opt-out (accepted PC-3.2 rule).
  • `children` becomes the default slot and `className` maps to parts and custom properties.
  • Framer whileHover/whileTap become CSS transitions (220ms) plus WAAPI ripples; springSnappy has no native counterpart, so the press settle is monotonic (PC-10.4).
  • The lucide Droplets icon becomes an inlined local SVG (ISC notice retained).
  • The fixed #161616/#FAFAFA/cyan palette becomes theme tokens with upstream hex fallbacks; the secondary boundary is a color-mix of the text token because upstream #3A3A3A only reaches 3:1 on a dark page.
  • Reduced motion keeps a brightness press cue (upstream kept none).
Previous: Expanding Search Field Next: Blob Toggle

Docs

Components

Project