@tabula-css/react
선택적인 Tabula 정석 경로(paved-path) 프리미티브: <Text>, <Separator>, <Prose>. 레지스트리 기반 병합이며, import 그래프에 Tailwind가 없습니다.
설치
npm install @tabula-css/react런타임 의존성입니다 — 개발 측 도구 패키지들과 달리, @tabula-css/react는 여러분의 앱이 렌더링하는 컴포넌트를 제공합니다. @tabula-css/merge에만 의존하며(react는 피어, ^18.0.0 || ^19.0.0), 런타임의 나머지 부분과 마찬가지로 Tailwind는 결코 import 그래프에 나타나지 않습니다.
개요
이 세 컴포넌트는 선택적입니다: 프로파일 안의 그 무엇도 React를 요구하지 않으며, 각각은 손으로 작성할 수 있는 마크업 위의 편의일 뿐입니다. 각 컴포넌트는 프로파일이 무언가를 금지하고 그에 대한 대체제를 빚지고 있기 때문에 존재합니다 — <Separator>는 금지된 divide-* 패밀리를 자식들 사이의 실제 요소로 대체하고, <Text>는 등록되지 않은 부분 타이포그래피 유틸리티(text-sm, font-medium) 대신 닫힌 type-*/ink-* 텍스트 리프이며, <Prose>는 프로파일이 명시적으로 관리를 거부하는 미작성 HTML(렌더링된 마크다운, CMS 출력)을 위한 격리 경계입니다. 모든 프리미티브는 자신의 ref를 전달하고 호출자의 className을 cn()을 통해 마지막에 병합하므로, 호출자의 오버라이드가 항상 결정론적으로 이깁니다.
Text
정확히 하나의 type-* 묶음과 하나의 ink-* 색상을 담는 단일 텍스트 리프를 렌더링합니다 — 상속 가능한 타이포그래피 속성을 기록하도록 허용된 유일한 클래스입니다. as는 의도적으로 텍스트 리프 태그의 닫힌 목록입니다: 임의의 컨테이너를 허용하면 이 컴포넌트가 제거하려는 조상-상속 문제를 다시 들여오게 될 것이기 때문입니다.
| 프로퍼티 | 타입 | 기본값 | 설명 |
|---|---|---|---|
as | 'p' | 'span' | 'label' | 'strong' | 'em' | 'small' | 'h1'..'h6' | 'legend' | 'figcaption' | 'p' | 렌더링되는 태그. |
variant | 'body' | 'label' | 'small' | 'heading' | 'body' | type-body / type-label / type-small / type-heading에 매핑됩니다. |
tone | 'text' | 'muted' | 'accent' | 'danger' | 'on-accent' | 'text' | ink-text / ink-text-muted / ink-accent / ink-danger / ink-on-accent에 매핑됩니다. |
htmlFor | string | — | as="label"일 때 for로 전달됩니다. |
className | ClassName | — | 통과 클래스로, cn()을 통해 마지막에 병합됩니다. |
그리고 모든 React.HTMLAttributes<HTMLElement> 프로퍼티.
프로젝트에 다음 토큰이 존재할 것을 요구합니다: type.body, type.label, type.small, type.heading, color.text, color.text-muted, color.accent, color.danger, color.on-accent.
import { Text } from '@tabula-css/react';
<Text as="h2" variant="heading" tone="text">Section title</Text>
<Text variant="small" tone="muted">Last updated 3 days ago</Text>Separator
divide-*(부모로부터 형제를 스타일링하는, 금지된 비지역적 메커니즘) 대신 자식들 사이에 실제 요소를 렌더링합니다. 이후 각 자식 고유의 간격은 그 자식 자신의 마크업 안에 존재합니다.
| 프로퍼티 | 타입 | 기본값 | 설명 |
|---|---|---|---|
orientation | 'horizontal' | 'vertical' | 'horizontal' | bg-border w-full h-hairline / bg-border w-hairline h-full에 매핑되며, aria-orientation도 설정합니다. |
decorative | boolean | false | 그룹화가 다른 곳에서 전달되는, 순수하게 시각적인 구분선을 위해 aria-orientation 없이 role="none"을 렌더링합니다. |
className | ClassName | — | 통과 클래스로, cn()을 통해 마지막에 병합됩니다. |
그리고 모든 React.HTMLAttributes<HTMLDivElement> 프로퍼티.
다음 토큰을 요구합니다: color.border, size.hairline(1px), size.full(100%).
import { Separator } from '@tabula-css/react';
<Separator />
<Separator orientation="vertical" decorative />Prose
프로파일이 관리하지 않는 하위 트리를 표시합니다 — 스타일이 아니라 정직한 무-주장(no-claim)입니다. 이 경계 안에서는 지역성이 명시적으로 유예됩니다: resolve_element(@tabula-css/mcp 참고)는 그 안의 무엇에 대해서든 { managed: false, reason: "prose-quarantine" }으로 답합니다. 모든 요소 자식은 등록된 not-prose 마커 유틸리티로 자동 울타리(fence)가 쳐져, 생성된 리셋이 하나의 허가된 조상 결합자를 통해 그 하위 트리를 제외할 수 있게 합니다; 컴포넌트 자식은 울타리가 자리 잡으려면 className을 자신의 루트로 전달해야 합니다.
| 프로퍼티 | 타입 | 기본값 | 설명 |
|---|---|---|---|
html | string | — | 경계 안에 렌더링할 미작성 HTML(마크다운/CMS 사례). children과 상호 배타적입니다. |
children | ReactNode | — | 작성된 자식들; 모든 요소 자식은 자동으로 울타리가 쳐집니다. html과 상호 배타적입니다. |
as | 'article' | 'div' | 'section' | 'aside' | 'div' | 렌더링되는 태그. |
className | ClassName | — | 레이아웃/박스 유틸리티만(w-, max-w-, m*, p*) — 마지막에 병합됩니다. 개발 환경에서는, 관리를 거부한 콘텐츠로 상속될 수 있는 그 무엇도 경계가 설정해서는 안 되므로, 그 밖의 유틸리티는 던집니다. |
import { Prose } from '@tabula-css/react';
<Prose html={renderedMarkdownHtml} className="max-w-prose" />
<Prose>
<p>Authored paragraph, auto-fenced with <code>not-prose</code>.</p>
</Prose>또한 내보내는 것: useInQuarantine() — 호출하는 컴포넌트가 <Prose> 경계 안에서 렌더링되고 있는지를 반환하는 훅 — 그리고 경계가 설정하는 QUARANTINE_ATTRIBUTE/QUARANTINE_KIND 상수로, @tabula-css/core로부터 다시 내보내어 컴포넌트와 어떤 도구든 동일한 값을 읽도록 합니다.
개발 환경에서 <Prose>는 조용히 잘못된 마크업을 렌더링하는 대신 던집니다: 다른 <Prose> 경계 안에 중첩되었을 때(격리는 다시 중첩될 수 없습니다), html과 children이 모두 전달되었을 때, 또는 className이 박스/레이아웃 허용 목록 밖의 무언가를 담고 있을 때입니다.
함께 보기
@tabula-css/merge— 이 컴포넌트들이 사용하는cn()/ClassName.- 핵심 개념 — 금지된 메커니즘 —
divide-*와 부분 타이포그래피 유틸리티가 금지된 이유. - 에이전트 서피스 —
resolve_element의managed: false격리 보고.