Split Accordion
NewCustomize
One at a time
Gap12px
Radius20px
Installation
npx shadcn@latest add https://uibrik.com/r/split-accordion.jsonInstall the packages
npm install motionAdd the cn helper
Imports
cnfrom@/lib/utils, whichshadcn initcreates. Add it by hand without shadcn.Copy the source into your project
components/uibrik/split-accordion/split-accordion.tsx"use client"; // Sections that sit together as one block. Opening a section splits it away // from its neighbours: its margin-block eases out to a gap and the corners on // either side of the split round off, while the answer fades up below its // question. Closing it merges the block back together. The list is plain block flow, so // the margins of two open neighbours collapse into a single gap instead of // doubling. Headers are real buttons inside headings; Up/Down, Home and End // move between them. import { AnimatePresence, motion, useReducedMotion } from "motion/react"; import { useId, useRef, useState, type KeyboardEvent, type ReactNode } from "react"; import { cn } from "@/lib/utils"; const EASE_OUT: [number, number, number, number] = [0.23, 1, 0.32, 1]; // Padding between a section and the header row inside it. const INSET = 6; export type SplitAccordionItem = { title: ReactNode; content: ReactNode }; export type SplitAccordionProps = { items: readonly SplitAccordionItem[]; /** One section open at a time, or any number. */ type?: "single" | "multiple";
Adds the files to
components/uibrik/split-accordion and installs motion. With the @uibrik namespace set up: npx shadcn@latest add @uibrik/split-accordion.Usage
import { SplitAccordion } from "@/components/uibrik/split-accordion/split-accordion";const items = [ { title: "How long is the free trial?", content: "Fourteen days with every feature included. No card needed to start, and nothing is charged unless you choose a plan." }, { title: "Can I change plans later?", content: "Yes, at any time. Upgrades apply straight away; downgrades take effect at the end of the current billing period." }, // …3 more];<SplitAccordion items={items} type="single" gap={12} radius={20} defaultOpen={[]} // open={[0]} // onOpenChange={(open) => {}}/>Props
SplitAccordion- type
- Type "single" | "multiple"
- "single"
- One section open at a time, or any number.
- gap
- Type number
- 12
- Space an open section pulls away from its neighbours, in px.
- radius
- Type number
- 20
- Corner radius of the block and each split piece, in px.
- itemsrequired
- Type { title: ReactNode; content: ReactNode }[]
- –
- The sections.
- defaultOpen
- Type number[]
- –
- Indexes open at first.
- open / onOpenChange
- Type number[] / (open) => void
- –
- Open indexes, controlled.
- className
- Type string
- –
- Classes for the list.