"use client"; import { useState } from "react"; interface LlmBlockProps { /** Путь страницы, например "/foundation/colors" */ path: string; /** Версия данных, например "v2.1" */ version: string; /** Плоский текст для копирования */ specText: string; /** Содержимое блока — таблицы, правила */ children: React.ReactNode; } /** * LlmBlock — переиспользуемый блок LLM-спецификации. * Добавляется в конец каждой страницы брендбука, содержащей дизайн-стандарты. * Требование: ФТ-03-LLM (TZ.md) · docs/LLM_CONTEXT.md */ export function LlmBlock({ path, version, specText, children }: LlmBlockProps) { const [copied, setCopied] = useState(false); function handleCopy(e: React.MouseEvent) { e.preventDefault(); navigator.clipboard.writeText(specText); setCopied(true); setTimeout(() => setCopied(false), 2000); } return (
{/* Заголовок */}
LLM LLM-спецификация · машиночитаемые данные · docs/LLM_CONTEXT.md
{path} · {version}
{/* Содержимое */}
{children}
); } /* ─── Утилиты для содержимого блока ──────────────────────────── */ /** Заголовок подсекции внутри LLM-блока */ export function LlmSection({ title }: { title: string }) { return (

{title}

); } /** Компактная таблица для LLM-блока */ export function LlmTable({ headers, rows, }: { headers: string[]; rows: (string | React.ReactNode)[][]; }) { return (
{headers.map((h) => ( ))} {rows.map((row, ri) => ( {row.map((cell, ci) => ( ))} ))}
{h}
{cell}
); } /** Список правил ✓ / ✕ */ export function LlmRules({ rules }: { rules: { ok: boolean; text: string }[] }) { return (
{rules.map((r) => (
{r.ok ? "✓" : "✕"} {r.text}
))}
); }