Toggle Sidebar B
AppearanceLight & dark mode D

Shredder

A list with a paper shredder at the bottom. Drag a row into the slit and the rollers tug it in, pull it through and cut it into strips that curl out underneath, tumble away and fade out. The rest of the list settles down on a spring and the shredded item is handed to you to delete.

Default

Drag a row down into the slit, or focus it and press Delete. Drop it elsewhere in the list to reorder. Every prop is wired to the controls underneath.

Light previewReplay previewOpen in new tab
  • Harbour at duskEdited yesterday
    4.1 MB
  • Studio, take twoEdited 2 days ago
    2.8 MB
  • Fog over the bayEdited last week
    6.3 MB
  • Sunday marketEdited 12 Mar
    3.5 MB

Customize

Feed Speed180px/s
Bite18px
Strip Width10px
Curl1
Drag Tilt6°
Lift1.02
Width340px
Height460px
Inset14px
Gap10px
Slit Thickness4px
Fall Height140px
Slit
Text

API Reference

Shredder

PropTypeDefaultDescription
itemsT[][]Rows to render, top to bottom. Each item needs a unique id.
widthnumber340Width of the whole machine in pixels.
heightnumber460Total height. The rows stack up from the slit, which sits above the fall zone at the bottom.
insetnumber14Horizontal inset of the rows from the edges. The slit is 6px wider than the rows on each side.
gapnumber10Space between rows in pixels.
slitHeightnumber4Thickness of the slit. It is always a full pill.
fallHeightnumber140Height of the zone under the slit where the strips fall and fade out.
feedSpeednumber180Roller speed in pixels per second. The first pull is faster and eases into it.
bitenumber18How far a row has to be pushed into the slit before the rollers grab it, in pixels.
autoFeedbooleantrueGrab the row as soon as it is pushed in far enough, even while it is still held. Off, it feeds only on release over the slit.
stripWidthnumber10Target width of each strip in pixels. The row is cut into equal columns.
curlnumber1How much the strips curl and wave as they come out. 0 keeps them straight.
autoAnimatebooleanfalsePlays through the rows on its own, bottom to top, then brings them back and starts over. Keep the rows in your list while it runs; the shred event still fires.
loopbooleanfalseOnce the last row has been shredded, bring them all back. Keep the rows in your list while it is on.
loopAfterDeletebooleanfalseAfter a row is shredded it comes back a moment later at a random spot, so the list never runs dry. Keep the rows in your list while it is on.
dragTiltnumber6Maximum lean in degrees while a row is dragged sideways.
liftnumber1.02Scale of a row while it is held.
slitColorstring"#3f3f46"Colour of the slit.
colorstring"#f5f5f5"Text colour inherited by the rows.
disabledbooleanfalseRows cannot be dragged or shredded.

Shredder events and slots

PropTypeDefaultDescription
item (slot){ item: T, index: number }-Renders one row. A snapshot of the rendered row is what gets cut into strips, so plain markup, inline images and inline SVG all work.
@shred(item: T) => void-Emitted the moment a row has gone through the rollers. Remove the item from your list here, unless loop, loopAfterDelete or autoAnimate is on.
@reorder(items: T[]) => void-Emitted with the items in their new order after a row is dropped somewhere else in the list.

Accessibility

Keyboard shortcuts and ARIA behavior.

Shortcut Description
TabMove focus between the rows.
Delete + BackspaceFeed the focused row into the shredder.
  • With prefers-reduced-motion set, a row is removed immediately instead of animating through the rollers.
  • Rows stay focusable, but drag-to-reorder has no keyboard equivalent.