This component no longer exists. It was in ns-ui’s manifest when we first indexed it and is not there now — the registry served its inventory on 2026-08-07 and this item was not on it. The install command below will fail. It is kept here because a tutorial somewhere still tells people to run it.
Accordion Latch
ns-ui/accordion-latchRemovedComponent
An accordion whose sections latch shut with a small SVG hasp-and-staple on each closed header — opening swings the hasp off its staple, lifts the lid 2px, then unfolds the content; closing reverses and the hasp settles back down with a bounce.
Live preview
live · rendered by the registry
Rendered by ns-ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://design.helpmarq.com/r/accordion-latch.jsonSource
1"use client";23import { useId, useRef, useState, type KeyboardEvent as ReactKeyboardEvent, type ReactNode } from "react";45// ---------------------------------------------------------------------------6// HaspFold — an accordion whose sections latch shut with a visible hasp.7// Each closed header shows a small SVG hasp-and-staple on its right edge:8// a fixed U-shaped staple bracket and a hinged strap+loop that, at rest,9// hooks down over it. The whole open/close choreography is staged with10// plain CSS transitions keyed off one `data-state="open"|"closed"`11// attribute per stage (hasp / lid / content-rows) — no rAF loop, no12// per-frame React state — each stage just carries its own duration and13// transition-delay so the same state flip plays four moments in order:14// open: hasp swings up off the staple (spring overshoot, 0ms delay)15// -> the header ("lid") lifts 2px (starts as the hasp is16// settling) -> the content unfolds via the codebase's17// grid-template-rows 0fr->1fr trick, ease-out-expo, fading18// upward 4px (starts as the lid finishes lifting).19// close: reverse order — content folds first, then the lid drops,20// then the hasp drops back over the staple with a bouncier21// cubic-bezier so it reads as a settle rather than a snap.22// Hover on a closed header slides the hasp 1px via a plain CSS :hover23// rule (no JS) — "testing the latch." Single-open by default (opening24// one closes any other); `multiple` allows independent panels. Headers25// are real <button> elements with a roving tabindex (only the active26// header is in the tab sequence; ArrowUp/Down/Home/End move focus,27// matching the dropdown-drape pattern), aria-expanded + aria-controls, and28// a <div role="region" aria-labelledby> panel per the standard29// disclosure pattern. prefers-reduced-motion collapses every stage's30// duration/delay to zero, so open/close still happens (nothing gets31// stuck) but as a single instant snap, hasp included.32// ---------------------------------------------------------------------------3334export interface HaspFoldItem {35 id: string;36 title: ReactNode;37 content: ReactNode;38}3940export interface HaspFoldProps {41 items: HaspFoldItem[];42 /** Allow more than one section open at once. Default false (single-open). */43 multiple?: boolean;44 /** Initially open item ids. */45 defaultOpen?: string[];46 className?: string;47}4849function HaspIcon({ open }: { open: boolean }) {50 return (51 <svg52// … truncated
