Accordion

Labelled Accordion

An accordion with label tiles and counters: across ten sections the eye catches the tile instead of re-reading the headings.

  • accordion
  • icons
  • badges
  • settings

Preview

1440pxHost theme

Use it with AI

  1. 1. Copy the link.
  2. 2. Write to your agent in your own words and drop the link into the sentence.
  3. 3. The agent opens the link and installs the component from the registry.

put this in the header: https://vibeui.ru/c/accordion-007?lang=en

Доступ и роли12

Владелец, редактор и читатель. Роль меняется в настройках участника и вступает в силу сразу, без повторного входа.

Оплата и счета5

Счета формируются первого числа, закрывающие документы приходят на почту администратора и лежат в разделе документов.

ИнтеграцииBeta

Почта, платежи и аналитика подключаются в один клик. Остальное — через веб-хуки: ключ выдаётся в настройках проекта.

Безопасность

Двухфакторный вход, журнал действий за 90 дней и выгрузка всех данных проекта по запросу владельца.

Show the full instructions

What the link says, spelled out. Use it when your agent cannot open links — paste this text instead.

# Install and place "accordion-007" (Labelled Accordion) from VibeUI

## 1. Install first — do not skip, do not recreate
Run this exact command before writing any code:
npx shadcn@latest add https://vibeui.ru/r/accordion-007.json

Registry item: https://vibeui.ru/r/accordion-007.json
Installs to: components/vibeui/accordion-007.tsx (the exact path follows this project's components.json aliases).
npm dependencies: none.
Registry dependencies: none.

Install it from the registry. Do not recreate it from the description,
do not substitute a similar component from another library, and do not
rewrite it to match the project's existing style.

## 2. What it is
An accordion with label tiles and counters: across ten sections the eye catches the tile instead of re-reading the headings.

A settings accordion: a two- or three-letter tile on the left, the heading in the middle, a badge with a count or a label such as "Beta" on the right. The open section's tile takes the accent colour, so the position in a long list is visible without reading. Zero dependencies, one file, its own palette, no client JS.

## 3. How to use it
import { Accordion007 } from "@/components/vibeui/accordion-007"

<Accordion007
  items={[{ glyph: "Ac", title: "Access and roles", badge: "12", body: "Owner, editor and viewer." }]}
/>

Read the installed file for the full prop list.

## 4. Where to place it
This is a small inline component. Put it exactly where the user asked,
inside the existing markup. Do not create a new page, section or
wrapper for it. If a similar control already sits in that spot,
replace it instead of adding a second one.

Placement: ___
(The user fills this line in. If it is still blank, ask where to put it
instead of guessing.)

## 5. Keep exactly as installed
- the local --vibeui-accordion-007-* palette — do not swap it for your theme tokens (bg-muted, text-primary and the like)
- the tile as text in a square: an icon library for four glyphs is a dependency for the life of the project
- aria-hidden on the tile: the heading carries the meaning, the tile only helps find it
- the native details/summary instead of stateful buttons
- colouring the open section's tile — it marks the position in the list
- the @container query that hides the badge in a narrow column: otherwise the heading collapses
- the <style> block inside the component — it holds the palette, the tiles and the layout

## 6. You may change
- the items array: tile, heading, badge and body
- defaultOpen — which section starts open; -1 closes them all
- the tile content: two or three letters, or one symbol — more will not fit
- the accent through the accent prop — it colours the open tile and focus
- max width and outer spacing through className

## 7. Rules
- The tiles have to differ: four identical abbreviations are worse than none.
- The badge is a count or a short label, not a second heading: about six characters fit.
- If you need real icons, put your own <svg> in the tile and keep the sizes.
- Do not lift the CSS variables into globals.css: the component has to stay a single file.

## 8. Verify
- it renders with no console errors;
- it looks like the preview on the VibeUI page you copied this from;
- if it does not, you changed something listed in section 5 — put it back.

For developers

npx shadcn@latest add https://vibeui.ru/r/accordion-007.json
https://vibeui.ru/r/accordion-007.json

Компонент самодостаточен: один файл, без зависимостей, собственная палитра в локальных переменных --vibeui-accordion-007-*. Раскрытие держат нативные <details>/<summary>. Плитка слева — текст в квадрате, а не иконка из библиотеки: набор разделов у каждого свой, а зависимость осталась бы навсегда. Плашка справа принимает и число, и слово. В узкой колонке плашка скрывается через @container, чтобы заголовок не сжимался.

Component source

The same file your agent installs. Here in case you would rather copy it by hand.

import type { ComponentPropsWithoutRef, CSSProperties } from "react"

export type Accordion007Item = {
  title: string
  body: string
  /** Две-три буквы в плитке слева: раздел узнают по ней, а не по тексту. */
  glyph?: string
  /** Плашка справа: «12», «Beta», «Новое». */
  badge?: string
}

export type Accordion007Props = Omit<
  ComponentPropsWithoutRef<"div">,
  "children"
> & {
  items?: Accordion007Item[]
  defaultOpen?: number
  accent?: string
}

// Идея компонента: у каждого раздела своя плитка-метка и счётчик справа.
// В списке из десяти пунктов взгляд цепляется за плитку, а не перечитывает
// заголовки. Плитка — текст в квадрате, а не иконка из библиотеки: набор
// разделов у всех разный, а зависимость осталась бы навсегда.
const STYLES = `
:where([data-vibeui-block="accordion-007"]){
--vibeui-accordion-007-fg:oklch(0.22 0.014 265);
--vibeui-accordion-007-muted:oklch(0.52 0.014 265);
--vibeui-accordion-007-bg:oklch(1 0 0);
--vibeui-accordion-007-border:oklch(0.91 0.006 265);
--vibeui-accordion-007-accent:oklch(0.55 0.2 262);
--vibeui-accordion-007-radius:0.875rem;
--vibeui-accordion-007-font:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
container-type:inline-size;
}
[data-vibeui-block="accordion-007"]{
display:flex;flex-direction:column;
width:100%;max-width:42rem;box-sizing:border-box;overflow:hidden;
border:1px solid var(--vibeui-accordion-007-border);
border-radius:var(--vibeui-accordion-007-radius);
background:var(--vibeui-accordion-007-bg);
color:var(--vibeui-accordion-007-fg);font-family:var(--vibeui-accordion-007-font);
}
[data-vibeui-block="accordion-007"] details + details{border-top:1px solid var(--vibeui-accordion-007-border)}
[data-vibeui-block="accordion-007"] summary{
display:flex;align-items:center;gap:0.75rem;
padding:0.875rem 1rem;cursor:pointer;list-style:none;
font-size:0.9375rem;font-weight:550;line-height:1.35;
}
[data-vibeui-block="accordion-007"] summary::-webkit-details-marker{display:none}
[data-vibeui-block="accordion-007"] summary:hover [data-part="glyph"]{
border-color:color-mix(in oklab,var(--vibeui-accordion-007-accent) 40%,var(--vibeui-accordion-007-border));
color:var(--vibeui-accordion-007-accent);
}
[data-vibeui-block="accordion-007"] summary:focus-visible{outline:2px solid var(--vibeui-accordion-007-accent);outline-offset:-2px}
/* Плитка-метка: буквы в квадрате вместо иконки из библиотеки. */
[data-vibeui-block="accordion-007"] [data-part="glyph"]{
display:flex;align-items:center;justify-content:center;flex:none;
width:2rem;height:2rem;border-radius:0.625rem;
border:1px solid var(--vibeui-accordion-007-border);
background:color-mix(in oklab,var(--vibeui-accordion-007-border) 22%,transparent);
color:var(--vibeui-accordion-007-muted);
font-size:0.6875rem;font-weight:700;letter-spacing:0.02em;text-transform:uppercase;
transition:color .16s ease,border-color .16s ease,background-color .16s ease;
}
[data-vibeui-block="accordion-007"] details[open] [data-part="glyph"]{
background:color-mix(in oklab,var(--vibeui-accordion-007-accent) 12%,transparent);
border-color:color-mix(in oklab,var(--vibeui-accordion-007-accent) 45%,transparent);
color:var(--vibeui-accordion-007-accent);
}
[data-vibeui-block="accordion-007"] [data-part="title"]{flex:1 1 auto;min-width:0}
[data-vibeui-block="accordion-007"] [data-part="badge"]{
flex:none;padding:0.125rem 0.4375rem;border-radius:9999px;
border:1px solid var(--vibeui-accordion-007-border);
font-size:0.6875rem;font-weight:600;color:var(--vibeui-accordion-007-muted);
font-variant-numeric:tabular-nums;
}
[data-vibeui-block="accordion-007"] [data-part="chevron"]{
flex:none;width:0.4375rem;height:0.4375rem;
border-right:1.5px solid var(--vibeui-accordion-007-muted);
border-bottom:1.5px solid var(--vibeui-accordion-007-muted);
transform:rotate(45deg) translate(-0.0625rem,-0.0625rem);
transition:transform .18s ease;
}
[data-vibeui-block="accordion-007"] details[open] [data-part="chevron"]{transform:rotate(225deg) translate(-0.0625rem,-0.0625rem)}
[data-vibeui-block="accordion-007"] [data-part="body"]{
margin:0;padding:0 1rem 1rem 3.75rem;
font-size:0.875rem;line-height:1.6;color:var(--vibeui-accordion-007-muted);max-width:60ch;
}
@container (max-width: 24rem){
[data-vibeui-block="accordion-007"] [data-part="badge"]{display:none}
[data-vibeui-block="accordion-007"] [data-part="body"]{padding-left:1rem}
}
@media (prefers-reduced-motion:reduce){[data-vibeui-block="accordion-007"] *{animation:none!important;transition:none!important}}
`

const DEFAULT_ITEMS: Accordion007Item[] = [
  {
    glyph: "Дс",
    title: "Доступ и роли",
    badge: "12",
    body: "Владелец, редактор и читатель. Роль меняется в настройках участника и вступает в силу сразу, без повторного входа.",
  },
  {
    glyph: "Оп",
    title: "Оплата и счета",
    badge: "5",
    body: "Счета формируются первого числа, закрывающие документы приходят на почту администратора и лежат в разделе документов.",
  },
  {
    glyph: "Ин",
    title: "Интеграции",
    badge: "Beta",
    body: "Почта, платежи и аналитика подключаются в один клик. Остальное — через веб-хуки: ключ выдаётся в настройках проекта.",
  },
  {
    glyph: "Бз",
    title: "Безопасность",
    body: "Двухфакторный вход, журнал действий за 90 дней и выгрузка всех данных проекта по запросу владельца.",
  },
]

/**
 * Аккордеон с плитками-метками и счётчиками: список опознают по плитке.
 * Один файл, ноль зависимостей, собственная палитра.
 */
export function Accordion007({
  items = DEFAULT_ITEMS,
  defaultOpen = 0,
  accent,
  className,
  style,
  ...props
}: Accordion007Props) {
  const palette = {
    ...(accent ? { "--vibeui-accordion-007-accent": accent } : null),
    ...style,
  } as CSSProperties

  return (
    <>
      <style href="vibeui-accordion-007" precedence="medium">
        {STYLES}
      </style>
      <div
        {...props}
        data-vibeui-block="accordion-007"
        className={className}
        style={palette}
      >
        {items.map((item, index) => (
          <details key={item.title} open={index === defaultOpen}>
            <summary>
              {item.glyph ? (
                <span data-part="glyph" aria-hidden="true">
                  {item.glyph}
                </span>
              ) : null}
              <span data-part="title">{item.title}</span>
              {item.badge ? <span data-part="badge">{item.badge}</span> : null}
              <span data-part="chevron" aria-hidden="true" />
            </summary>
            <p data-part="body">{item.body}</p>
          </details>
        ))}
      </div>
    </>
  )
}