Display

Collapsed Log

A collapsed build log: the line and error tally sits in the header, and the log itself expands only when something needs triage.

  • collapsible
  • log
  • details
  • counter

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/collapsible-004?lang=en

Build output7 строк1 ошибки
  1. ▲ Next.js 16.0.1 — compiling registry
  2. indexes: 39 реестров, 463 items
  3. meta: проверено, ошибок нет
  4. warn collapsible-004: preview шире карточки
  5. registry:build → public/r (463 файла)
  6. error route /r/[name] не отдал JSON
  7. build failed in 12.4s
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 "collapsible-004" (Collapsed Log) 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/collapsible-004.json

Registry item: https://vibeui.ru/r/collapsible-004.json
Installs to: components/vibeui/collapsible-004.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
A collapsed build log: the line and error tally sits in the header, and the log itself expands only when something needs triage.

A collapsed build log: line and error counts right in the header, line numbers from a CSS counter, levels told apart by colour. No client JS. Zero dependencies, one file.

## 3. How to use it
import { Collapsible004 } from "@/components/vibeui/collapsible-004"

<Collapsible004 title="Build output" lines={[{ text: "build failed", level: "error" }]} />

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-collapsible-004-* palette — do not swap it for your theme tokens
- the error tally in summary: otherwise a collapsed log hides the only thing that matters
- numbering through a CSS counter rather than markup: a copied log stays clean
- the monospaced face — columns and indentation carry meaning in build output
- the block border: a dark panel merges into a dark showcase without it
- the capped height with scrolling: a long log must not stretch the page

## 6. You may change
- the heading through the title prop
- the lines array and their levels
- the maximum scroll height
- the accent through the accent prop

## 7. Rules
- There is no syntax highlighting: it costs a library and build output does not need it.
- The row level comes from the level field; an unknown value renders as an ordinary line.
- For a live log, scroll to the last line from outside: the component does not watch for updates.
- 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/collapsible-004.json
https://vibeui.ru/r/collapsible-004.json

Компонент самодостаточен: один файл, без зависимостей, собственная палитра в локальных переменных --vibeui-collapsible-004-*. Серверный: хуков нет, корень — details. Количество ошибок считается из массива lines по полю level и попадает в summary, поэтому разворачивать блок ради подсчёта не нужно. Номера строк рисует счётчик CSS через counter-reset и li::before: в разметке их нет, и копия лога остаётся чистой. Поверхность тёмная, лог моноширинный, уровни различаются цветом строки.

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 Collapsible004Line = {
  text: string
  level?: "info" | "warn" | "error"
}

export type Collapsible004Props = Omit<
  ComponentPropsWithoutRef<"details">,
  "children" | "title"
> & {
  title?: string
  lines?: Collapsible004Line[]
  accent?: string
}

// Идея компонента: свёрнутый вывод сборки. Пока всё хорошо, лог занимает одну
// строку; развернуть его нужно только когда что-то упало, поэтому итог
// (количество строк и ошибок) считается из данных и показан прямо в summary —
// разворачивать ради подсчёта не приходится. Номера строк рисует счётчик CSS,
// в разметке их нет: копирование лога не тащит за собой нумерацию.
const STYLES = `
:where([data-vibeui-block="collapsible-004"]){
--vibeui-collapsible-004-bg:oklch(0.21 0.02 265);
--vibeui-collapsible-004-fg:oklch(0.93 0.006 265);
--vibeui-collapsible-004-muted:oklch(0.68 0.014 265);
--vibeui-collapsible-004-border:oklch(1 0 0 / 14%);
--vibeui-collapsible-004-warn:oklch(0.82 0.14 85);
--vibeui-collapsible-004-error:oklch(0.7 0.18 22);
--vibeui-collapsible-004-accent:oklch(0.8 0.14 152);
--vibeui-collapsible-004-mono:ui-monospace,SFMono-Regular,Menlo,Consolas,"Liberation Mono",monospace;
--vibeui-collapsible-004-font:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
}
[data-vibeui-block="collapsible-004"]{
display:block;box-sizing:border-box;width:100%;max-width:27rem;overflow:hidden;
background:var(--vibeui-collapsible-004-bg);color:var(--vibeui-collapsible-004-fg);
border:1px solid var(--vibeui-collapsible-004-border);border-radius:0.875rem;
font-family:var(--vibeui-collapsible-004-font);
}
[data-vibeui-block="collapsible-004"] summary{
display:flex;align-items:center;gap:0.5rem;
padding:0.6875rem 0.875rem;cursor:pointer;list-style:none;
font-size:0.8125rem;font-weight:640;
}
[data-vibeui-block="collapsible-004"] summary::-webkit-details-marker{display:none}
[data-vibeui-block="collapsible-004"] summary:focus-visible{outline:2px solid var(--vibeui-collapsible-004-accent);outline-offset:-2px}
[data-vibeui-block="collapsible-004"] [data-part="mark"]{
flex:none;width:0.4375rem;height:0.4375rem;
border-right:2px solid var(--vibeui-collapsible-004-muted);
border-bottom:2px solid var(--vibeui-collapsible-004-muted);
transform:rotate(-45deg);transform-origin:60% 60%;transition:transform .18s ease;
}
[data-vibeui-block="collapsible-004"][open] [data-part="mark"]{transform:rotate(45deg)}
[data-vibeui-block="collapsible-004"] [data-part="count"]{
margin-left:auto;display:inline-flex;gap:0.5rem;
font-family:var(--vibeui-collapsible-004-mono);font-size:0.6875rem;font-weight:500;
color:var(--vibeui-collapsible-004-muted);
}
[data-vibeui-block="collapsible-004"] [data-part="count"] b{color:var(--vibeui-collapsible-004-error);font-weight:700}
/* Номера строк рисует счётчик: в разметке их нет, копия лога остаётся чистой. */
[data-vibeui-block="collapsible-004"] [data-part="log"]{
counter-reset:vibeui-line;list-style:none;
margin:0;padding:0.625rem 0 0.75rem;
border-top:1px solid var(--vibeui-collapsible-004-border);
max-height:13rem;overflow:auto;
font-family:var(--vibeui-collapsible-004-mono);font-size:0.75rem;line-height:1.7;
}
[data-vibeui-block="collapsible-004"] [data-part="log"] li{
display:flex;gap:0.75rem;padding:0 0.875rem;color:var(--vibeui-collapsible-004-muted);
}
[data-vibeui-block="collapsible-004"] [data-part="log"] li::before{
counter-increment:vibeui-line;content:counter(vibeui-line);
flex:none;width:1.5rem;text-align:right;
color:oklch(1 0 0 / 30%);user-select:none;
}
[data-vibeui-block="collapsible-004"] [data-part="log"] li[data-level="warn"]{color:var(--vibeui-collapsible-004-warn)}
[data-vibeui-block="collapsible-004"] [data-part="log"] li[data-level="error"]{color:var(--vibeui-collapsible-004-error);background:oklch(0.7 0.18 22 / 10%)}
@media (prefers-reduced-motion:reduce){[data-vibeui-block="collapsible-004"] *{animation:none!important;transition:none!important}}
`

const DEFAULT_LINES: Collapsible004Line[] = [
  { text: "▲ Next.js 16.0.1 — compiling registry" },
  { text: "indexes: 39 реестров, 463 items" },
  { text: "meta: проверено, ошибок нет" },
  { text: "warn  collapsible-004: preview шире карточки", level: "warn" },
  { text: "registry:build → public/r (463 файла)" },
  { text: "error  route /r/[name] не отдал JSON", level: "error" },
  { text: "build failed in 12.4s" },
]

/**
 * Свёрнутый лог сборки: итог виден в заголовке, номера строк рисует CSS.
 * Один файл, ноль зависимостей, клиентского кода нет.
 */
export function Collapsible004({
  title = "Вывод сборки",
  lines = DEFAULT_LINES,
  accent,
  className,
  style,
  ...props
}: Collapsible004Props) {
  const failed = lines.filter((line) => line.level === "error").length

  const palette = {
    ...(accent ? { "--vibeui-collapsible-004-accent": accent } : null),
    ...style,
  } as CSSProperties

  return (
    <>
      <style href="vibeui-collapsible-004" precedence="medium">
        {STYLES}
      </style>
      <details
        {...props}
        data-vibeui-block="collapsible-004"
        className={className}
        style={palette}
      >
        <summary>
          <span data-part="mark" aria-hidden="true" />
          {title}
          <span data-part="count">
            <span>{lines.length} строк</span>
            {failed > 0 ? <b>{failed} ошибки</b> : null}
          </span>
        </summary>
        <ol data-part="log">
          {lines.map((line) => (
            <li key={line.text} data-level={line.level ?? "info"}>
              <span>{line.text}</span>
            </li>
          ))}
        </ol>
      </details>
    </>
  )
}