shadcn.io is not affiliated with official shadcn/ui
Shadcn Anatomy for React and Tailwind
Labeled part diagrams for component docs.
Installation
bunx --bun shadcn@latest add https://kit.dev/r/anatomy.jsonpnpm dlx shadcn@latest add https://kit.dev/r/anatomy.jsonnpx shadcn@latest add https://kit.dev/r/anatomy.jsonyarn shadcn@latest add https://kit.dev/r/anatomy.jsonInstall the following dependencies:
bun add @ark-ui/reactpnpm add @ark-ui/reactnpm install @ark-ui/reactyarn add @ark-ui/reactCopy and paste the following code into your project.
"use client";
import { useLocaleContext } from "@ark-ui/react/locale";
import type React from "react";
import { createContext, useContext, useId } from "react";
import { cn } from "@/lib/utils";
export const ANATOMY_HEIGHT = 630;
export const ANATOMY_WIDTH = 1200;
export type AnatomyAlign = "start" | "center" | "end";
export type AnatomyCallout = "line" | "brace" | "elbow";
export type AnatomyDir = "ltr" | "rtl";
export type AnatomySide = "top" | "bottom" | "start" | "end";
export type AnatomyTone = "surface" | "emphasis";
export interface AnatomyColors {
bg: string;
emphasis: string;
fg: string;
line: string;
outline: string;
surface: string;
}
export interface AnatomyCorners {
bl?: number;
br?: number;
tl?: number;
tr?: number;
}
export interface AnatomyRect {
height: number;
width: number;
x: number;
y: number;
}
type PhysicalSide = "top" | "right" | "bottom" | "left";
const BOX_OUTSET = 32;
const BOX_RADIUS = 16;
const BRACE_GAP = 24;
const BRACE_TICK = 12;
const LINE_LENGTH = 26;
const LINE_CAP = 18;
const ELBOW_ARM = 110;
const ELBOW_STEM = 26;
const LABEL_GAP = 16;
const LABEL_SIZE = 22;
const STROKE = 2.5;
const SHARE_FONT =
'"Helvetica Neue", Helvetica, Arial, "DejaVu Sans", "Liberation Sans", sans-serif';
const DOCS_FONT = "var(--font-sans), ui-sans-serif, system-ui, sans-serif";
const SHARE_SPACE_EM = 0.55;
const shareAdvance = (text: string, fontSize: number) => {
let em = 0;
for (const char of text) {
if ("ilI.,'".includes(char)) {
em += 0.3;
} else if ("mwMW".includes(char)) {
em += 0.92;
} else if (char !== char.toLowerCase()) {
em += 0.76;
} else {
em += 0.58;
}
}
return em * fontSize;
};
const BRAND_CHAR_EM = 0.56;
const BRAND_DEFAULT = "shadcn.io";
const BRAND_FONT = 18;
const BRAND_GAP = 10;
const BRAND_MARK = 26;
const BRAND_MARK_VB = 324;
const BRAND_PAD = 48;
export const anatomyCssColors: AnatomyColors = {
bg: "var(--anatomy-bg)",
emphasis: "var(--anatomy-emphasis)",
fg: "var(--anatomy-fg)",
line: "var(--anatomy-line)",
outline: "var(--anatomy-outline)",
surface: "var(--anatomy-surface)",
};
export const anatomyShareColors: AnatomyColors = {
bg: "#5a5a5a",
emphasis: "#171717",
fg: "#f5f5f5",
line: "#f0f0f0",
outline: "#e8e8e8",
surface: "#2f2f2f",
};
const anatomyVars = {
"--anatomy-bg": "oklch(from var(--primary) 0.42 c h)",
"--anatomy-emphasis": "oklch(from var(--primary) 0.24 c h)",
"--anatomy-fg": "oklch(from var(--primary) 0.97 calc(c * 0.2) h)",
"--anatomy-line": "oklch(from var(--primary) 0.93 c h)",
"--anatomy-outline": "oklch(from var(--primary) 0.9 c h / 0.72)",
"--anatomy-surface": "oklch(from var(--primary) 0.33 c h)",
} as React.CSSProperties;
interface AnatomyContextValue {
colors: AnatomyColors;
dir: AnatomyDir;
frame: AnatomyRect | null;
height: number;
origin: { x: number; y: number };
share: boolean;
width: number;
}
const AnatomyContext = createContext<AnatomyContextValue | null>(null);
export const useAnatomyContext = () => {
const context = useContext(AnatomyContext);
if (!context) {
throw new Error("AnatomyPart must be used within Anatomy");
}
return context;
};
export const useAnatomyPart = useAnatomyContext;
const expand = (rect: AnatomyRect, outset: number): AnatomyRect => ({
height: rect.height + outset * 2,
width: rect.width + outset * 2,
x: rect.x - outset,
y: rect.y - outset,
});
const flipX = (
x: number,
width: number,
parentWidth: number,
dir: AnatomyDir
) => (dir === "rtl" ? parentWidth - x - width : x);
const physicalSide = (side: AnatomySide, dir: AnatomyDir): PhysicalSide => {
if (side === "top" || side === "bottom") {
return side;
}
if (side === "start") {
return dir === "rtl" ? "right" : "left";
}
return dir === "rtl" ? "left" : "right";
};
const alongX = (rect: AnatomyRect, align: AnatomyAlign, dir: AnatomyDir) => {
let t = 0.5;
if (align === "start") {
t = 0.28;
} else if (align === "end") {
t = 0.72;
}
if (dir === "rtl" && align !== "center") {
t = 1 - t;
}
return rect.x + rect.width * t;
};
const alongY = (rect: AnatomyRect, align: AnatomyAlign) => {
if (align === "start") {
return rect.y + rect.height * 0.28;
}
if (align === "end") {
return rect.y + rect.height * 0.72;
}
return rect.y + rect.height * 0.5;
};
const flipCorners = (
corners: AnatomyCorners,
dir: AnatomyDir
): AnatomyCorners => {
if (dir === "ltr") {
return corners;
}
return {
bl: corners.br,
br: corners.bl,
tl: corners.tr,
tr: corners.tl,
};
};
const roundedRectPath = (rect: AnatomyRect, corners: AnatomyCorners) => {
const { x, y, width: w, height: h } = rect;
const tl = Math.min(corners.tl ?? 0, w / 2, h / 2);
const tr = Math.min(corners.tr ?? 0, w / 2, h / 2);
const br = Math.min(corners.br ?? 0, w / 2, h / 2);
const bl = Math.min(corners.bl ?? 0, w / 2, h / 2);
const topRight = tr
? `A ${tr} ${tr} 0 0 1 ${x + w} ${y + tr}`
: `L ${x + w} ${y}`;
const bottomRight = br
? `A ${br} ${br} 0 0 1 ${x + w - br} ${y + h}`
: `L ${x + w} ${y + h}`;
const bottomLeft = bl
? `A ${bl} ${bl} 0 0 1 ${x} ${y + h - bl}`
: `L ${x} ${y + h}`;
const topLeft = tl ? `A ${tl} ${tl} 0 0 1 ${x + tl} ${y}` : `L ${x} ${y}`;
return `M ${x + tl} ${y} H ${x + w - tr} ${topRight} V ${y + h - br} ${bottomRight} H ${x + bl} ${bottomLeft} V ${y + tl} ${topLeft} Z`;
};
const resolveLabel = (
label: string | false | undefined,
name: string | undefined
) => {
if (label === false) {
return null;
}
if (label !== undefined) {
return label === "" ? null : label;
}
return name ?? null;
};
const resolveBrand = (brand: boolean | string | undefined) => {
if (brand === true) {
return BRAND_DEFAULT;
}
if (typeof brand === "string") {
const text = brand.trim();
return text === "" ? null : text;
}
return null;
};
const resolveCorners = (
rx: number | AnatomyCorners | undefined,
dir: AnatomyDir
): AnatomyCorners | null => {
if (rx === undefined) {
return null;
}
if (typeof rx === "number") {
return { bl: rx, br: rx, tl: rx, tr: rx };
}
return flipCorners(rx, dir);
};
const fontFamily = (share: boolean) => (share ? SHARE_FONT : DOCS_FONT);
interface SvgLabelProps {
anchor: "start" | "middle" | "end";
colors: AnatomyColors;
share: boolean;
text: string;
x: number;
y: number;
}
const PlacedText = (props: {
anchor: "start" | "middle" | "end";
fill: string;
fontSize: number;
fontWeight: number;
share: boolean;
slot?: string;
text: string;
x: number;
y: number;
}) => {
const family = fontFamily(props.share);
if (!(props.share && props.text.includes(" "))) {
return (
<text
data-slot={props.slot}
dominantBaseline="middle"
fill={props.fill}
fontFamily={family}
fontSize={props.fontSize}
fontWeight={props.fontWeight}
letterSpacing={props.share ? undefined : "0.02em"}
textAnchor={props.anchor}
textRendering="geometricPrecision"
x={props.x}
y={props.y}
>
{props.text}
</text>
);
}
const words = props.text.split(" ");
const gap = props.fontSize * SHARE_SPACE_EM;
const widths = words.map((word) => shareAdvance(word, props.fontSize));
const total =
widths.reduce((sum, width) => sum + width, 0) + gap * (words.length - 1);
let cursor = props.x;
if (props.anchor === "middle") {
cursor -= total / 2;
} else if (props.anchor === "end") {
cursor -= total;
}
return (
<g data-slot={props.slot}>
{words.map((word, index) => {
const x = cursor;
cursor += widths[index] + gap;
return (
<text
dominantBaseline="middle"
fill={props.fill}
fontFamily={family}
fontSize={props.fontSize}
fontWeight={props.fontWeight}
key={`${index}-${word}`}
textAnchor="start"
textRendering="geometricPrecision"
x={x}
y={props.y}
>
{word}
</text>
);
})}
</g>
);
};
const SvgLabel = (props: SvgLabelProps) => (
<PlacedText
anchor={props.anchor}
fill={props.colors.line}
fontSize={LABEL_SIZE}
fontWeight={500}
share={props.share}
slot="anatomy-label"
text={props.text}
x={props.x}
y={props.y}
/>
);
const AnatomyBrand = (props: {
colors: AnatomyColors;
share: boolean;
text: string;
}) => {
const { colors, share, text } = props;
const textWidth = text.length * BRAND_FONT * BRAND_CHAR_EM;
const x = ANATOMY_WIDTH - BRAND_PAD - BRAND_MARK - BRAND_GAP - textWidth;
const y = ANATOMY_HEIGHT - BRAND_PAD - BRAND_MARK;
const scale = BRAND_MARK / BRAND_MARK_VB;
return (
<g data-slot="anatomy-brand" opacity={0.92}>
<g transform={`translate(${x} ${y}) scale(${scale})`}>
<rect fill={colors.fg} height="323" rx="161.5" width="323" x="0.5" />
<circle cx="162" cy="161.5" fill={colors.bg} r="60" />
</g>
<PlacedText
anchor="start"
fill={colors.fg}
fontSize={BRAND_FONT}
fontWeight={700}
share={share}
text={text}
x={x + BRAND_MARK + BRAND_GAP}
y={y + BRAND_MARK / 2}
/>
</g>
);
};
const StrokePath = (props: { colors: AnatomyColors; d: string }) => (
<path
d={props.d}
data-slot="anatomy-stroke"
fill="none"
shapeRendering="geometricPrecision"
stroke={props.colors.line}
strokeLinecap="square"
strokeLinejoin="miter"
strokeWidth={STROKE}
/>
);
const wallRect = (frame: AnatomyRect | null, part: AnatomyRect): AnatomyRect =>
frame ? expand(frame, BOX_OUTSET) : part;
const lineGeom = (props: {
align: AnatomyAlign;
dir: AnatomyDir;
part: AnatomyRect;
side: PhysicalSide;
wall: AnatomyRect;
}) => {
const { align, dir, part, side, wall } = props;
const x = alongX(part, align, dir);
const y = alongY(part, align);
const tick = LINE_CAP / 2;
if (side === "top") {
return {
anchor: "middle" as const,
d: `M ${x - tick} ${wall.y} H ${x + tick} M ${x} ${wall.y} V ${wall.y - LINE_LENGTH}`,
x,
y: wall.y - LINE_LENGTH - LABEL_GAP - LABEL_SIZE / 2,
};
}
if (side === "bottom") {
return {
anchor: "middle" as const,
d: `M ${x - tick} ${wall.y + wall.height} H ${x + tick} M ${x} ${wall.y + wall.height} V ${wall.y + wall.height + LINE_LENGTH}`,
x,
y: wall.y + wall.height + LINE_LENGTH + LABEL_GAP + LABEL_SIZE / 2,
};
}
if (side === "left") {
return {
anchor: "end" as const,
d: `M ${wall.x} ${y - tick} V ${y + tick} M ${wall.x} ${y} H ${wall.x - LINE_LENGTH}`,
x: wall.x - LINE_LENGTH - LABEL_GAP,
y,
};
}
return {
anchor: "start" as const,
d: `M ${wall.x + wall.width} ${y - tick} V ${y + tick} M ${wall.x + wall.width} ${y} H ${wall.x + wall.width + LINE_LENGTH}`,
x: wall.x + wall.width + LINE_LENGTH + LABEL_GAP,
y,
};
};
const braceGeom = (props: { part: AnatomyRect; side: PhysicalSide }) => {
const { part, side } = props;
if (side === "left") {
const x = part.x - BRACE_GAP;
return {
anchor: "end" as const,
d: `M ${x} ${part.y} H ${x - BRACE_TICK} V ${part.y + part.height} H ${x}`,
x: x - BRACE_TICK - LABEL_GAP,
y: part.y + part.height / 2,
};
}
if (side === "right") {
const x = part.x + part.width + BRACE_GAP;
return {
anchor: "start" as const,
d: `M ${x} ${part.y} H ${x + BRACE_TICK} V ${part.y + part.height} H ${x}`,
x: x + BRACE_TICK + LABEL_GAP,
y: part.y + part.height / 2,
};
}
if (side === "top") {
const y = part.y - BRACE_GAP;
return {
anchor: "middle" as const,
d: `M ${part.x} ${y} V ${y - BRACE_TICK} H ${part.x + part.width} V ${y}`,
x: part.x + part.width / 2,
y: y - BRACE_TICK - LABEL_GAP - LABEL_SIZE / 2,
};
}
const y = part.y + part.height + BRACE_GAP;
return {
anchor: "middle" as const,
d: `M ${part.x} ${y} V ${y + BRACE_TICK} H ${part.x + part.width} V ${y}`,
x: part.x + part.width / 2,
y: y + BRACE_TICK + LABEL_GAP + LABEL_SIZE / 2,
};
};
const elbowGeom = (props: {
align: AnatomyAlign;
dir: AnatomyDir;
part: AnatomyRect;
side: PhysicalSide;
wall: AnatomyRect;
}) => {
const { align, dir, part, side, wall } = props;
const towardStart = dir === "rtl" ? 1 : -1;
const x = alongX(part, align, dir);
const y = alongY(part, align);
const wallBottom = wall.y + wall.height;
const wallRight = wall.x + wall.width;
if (side === "bottom") {
const armX = x + towardStart * ELBOW_ARM;
return {
anchor: "middle" as const,
d: `M ${x} ${part.y + part.height} L ${x} ${wallBottom} L ${armX} ${wallBottom}`,
x: (x + armX) / 2,
y: wallBottom + LABEL_GAP + LABEL_SIZE / 2,
};
}
if (side === "top") {
const armX = x + towardStart * ELBOW_ARM;
return {
anchor: "middle" as const,
d: `M ${x} ${part.y} L ${x} ${wall.y} L ${armX} ${wall.y}`,
x: (x + armX) / 2,
y: wall.y - LABEL_GAP - LABEL_SIZE / 2,
};
}
if (side === "left") {
const armY = align === "start" ? y - ELBOW_ARM : y + ELBOW_ARM;
const stemX = wall === part ? part.x - ELBOW_STEM : wall.x;
return {
anchor: "middle" as const,
d: `M ${part.x} ${y} L ${stemX} ${y} L ${stemX} ${armY}`,
x: stemX,
y:
align === "start"
? armY - LABEL_GAP - LABEL_SIZE / 2
: armY + LABEL_GAP + LABEL_SIZE / 2,
};
}
const armY = align === "start" ? y - ELBOW_ARM : y + ELBOW_ARM;
const stemX = wall === part ? part.x + part.width + ELBOW_STEM : wallRight;
return {
anchor: "middle" as const,
d: `M ${part.x + part.width} ${y} L ${stemX} ${y} L ${stemX} ${armY}`,
x: stemX,
y:
align === "start"
? armY - LABEL_GAP - LABEL_SIZE / 2
: armY + LABEL_GAP + LABEL_SIZE / 2,
};
};
const Callout = (props: {
align: AnatomyAlign;
callout: AnatomyCallout;
colors: AnatomyColors;
dir: AnatomyDir;
frame: AnatomyRect | null;
label: string;
part: AnatomyRect;
share: boolean;
side: AnatomySide;
}) => {
const { align, callout, colors, dir, frame, label, part, share, side } =
props;
const physical = physicalSide(side, dir);
const wall = callout === "brace" ? part : wallRect(frame, part);
let geom = lineGeom({ align, dir, part, side: physical, wall });
if (callout === "brace") {
geom = braceGeom({ part, side: physical });
} else if (callout === "elbow") {
geom = elbowGeom({ align, dir, part, side: physical, wall });
}
return (
<>
<StrokePath colors={colors} d={geom.d} />
<SvgLabel
anchor={geom.anchor}
colors={colors}
share={share}
text={label}
x={geom.x}
y={geom.y}
/>
</>
);
};
export interface AnatomyProps {
brand?: boolean | string;
children?: React.ReactNode;
className?: string;
colors?: AnatomyColors;
dir?: AnatomyDir;
share?: boolean;
title?: string;
}
export interface AnatomyPartProps {
align?: AnatomyAlign;
box?: boolean;
callout?: AnatomyCallout;
children?: React.ReactNode;
height?: number;
label?: string | false;
name?: string;
rx?: number | AnatomyCorners;
side?: AnatomySide;
tone?: AnatomyTone;
width?: number;
x?: number;
y?: number;
}
export const Anatomy = (props: AnatomyProps) => {
const locale = useLocaleContext();
const {
brand = false,
children,
className,
colors: colorsProp,
dir: dirProp,
share = false,
title = "Component anatomy",
} = props;
const dir = dirProp ?? locale.dir;
const colors = colorsProp ?? (share ? anatomyShareColors : anatomyCssColors);
const brandText = resolveBrand(brand);
const titleId = useId();
const context: AnatomyContextValue = {
colors,
dir,
frame: null,
height: ANATOMY_HEIGHT,
origin: { x: 0, y: 0 },
share,
width: ANATOMY_WIDTH,
};
const scene = (
<>
<rect
fill={colors.bg}
height={ANATOMY_HEIGHT}
rx={24}
width={ANATOMY_WIDTH}
/>
{children}
{brandText ? (
<AnatomyBrand colors={colors} share={share} text={brandText} />
) : null}
</>
);
if (share) {
return (
<AnatomyContext.Provider value={context}>
<svg
aria-labelledby={titleId}
data-slot="anatomy"
direction={dir}
height={ANATOMY_HEIGHT}
role="img"
viewBox={`0 0 ${ANATOMY_WIDTH} ${ANATOMY_HEIGHT}`}
width={ANATOMY_WIDTH}
xmlns="http://www.w3.org/2000/svg"
>
<title id={titleId}>{title}</title>
{scene}
</svg>
</AnatomyContext.Provider>
);
}
return (
<AnatomyContext.Provider value={context}>
<figure
aria-labelledby={titleId}
className={cn("relative w-full min-w-0 select-none", className)}
data-slot="anatomy"
dir={dir}
style={{
...anatomyVars,
aspectRatio: `${ANATOMY_WIDTH} / ${ANATOMY_HEIGHT}`,
}}
>
<svg
aria-label={title}
className="block h-auto w-full"
data-slot="anatomy-svg"
direction={dir}
height={ANATOMY_HEIGHT}
style={anatomyVars}
viewBox={`0 0 ${ANATOMY_WIDTH} ${ANATOMY_HEIGHT}`}
width={ANATOMY_WIDTH}
>
<title id={titleId}>{title}</title>
{scene}
</svg>
</figure>
</AnatomyContext.Provider>
);
};
export const AnatomyPart = (props: AnatomyPartProps) => {
const {
align = "center",
box = false,
callout = "line",
children,
height: heightProp,
label,
name,
rx,
side = "top",
tone,
width: widthProp,
x = 0,
y = 0,
} = props;
const parent = useAnatomyContext();
const width = widthProp ?? parent.width - x;
const height = heightProp ?? parent.height - y;
const displayX = parent.origin.x + flipX(x, width, parent.width, parent.dir);
const displayY = parent.origin.y + y;
const partRect: AnatomyRect = {
height,
width,
x: displayX,
y: displayY,
};
const corners = resolveCorners(rx, parent.dir);
let fill: string | null = null;
if (tone === "emphasis") {
fill = parent.colors.emphasis;
} else if (tone === "surface") {
fill = parent.colors.surface;
}
const resolvedLabel = resolveLabel(label, name);
const frame = box ? partRect : parent.frame;
const childContext: AnatomyContextValue = {
colors: parent.colors,
dir: parent.dir,
frame,
height,
origin: { x: displayX, y: displayY },
share: parent.share,
width,
};
return (
<AnatomyContext.Provider value={childContext}>
<g
data-align={align}
data-callout={callout}
data-name={name}
data-side={side}
data-slot="anatomy-part"
data-tone={tone}
>
{fill && corners ? (
<path d={roundedRectPath(partRect, corners)} fill={fill} />
) : null}
{fill && !corners ? (
<rect
fill={fill}
height={height}
width={width}
x={displayX}
y={displayY}
/>
) : null}
{children}
{box ? (
<rect
data-slot="anatomy-box"
fill="none"
height={height + BOX_OUTSET * 2}
rx={BOX_RADIUS}
shapeRendering="geometricPrecision"
stroke={parent.colors.outline}
strokeDasharray="7 6"
strokeWidth={STROKE}
width={width + BOX_OUTSET * 2}
x={displayX - BOX_OUTSET}
y={displayY - BOX_OUTSET}
/>
) : null}
{resolvedLabel ? (
<Callout
align={align}
callout={callout}
colors={parent.colors}
dir={parent.dir}
frame={frame}
label={resolvedLabel}
part={partRect}
share={parent.share}
side={side}
/>
) : null}
</g>
</AnatomyContext.Provider>
);
};
export interface AnatomyTextProps {
children: string;
fontSize?: number;
fontWeight?: number;
padX?: number;
}
export const AnatomyText = (props: AnatomyTextProps) => {
const { children, fontSize = 26, fontWeight = 500, padX = 24 } = props;
const { colors, dir, height, origin, share, width } = useAnatomyPart();
const x = dir === "rtl" ? origin.x + width - padX : origin.x + padX;
const anchor = dir === "rtl" ? "end" : "start";
return (
<PlacedText
anchor={anchor}
fill={colors.fg}
fontSize={fontSize}
fontWeight={fontWeight}
share={share}
text={children}
x={x}
y={origin.y + height / 2}
/>
);
};
export interface AnatomyChevronProps {
align?: "center" | "end";
direction: "down" | "up";
size?: number;
}
export const AnatomyChevron = (props: AnatomyChevronProps) => {
const { align = "end", direction, size = 18 } = props;
const { colors, dir, height, origin, width } = useAnatomyPart();
const pad = 22;
let cx = origin.x + width / 2;
if (align === "end") {
cx =
dir === "rtl"
? origin.x + pad + size / 2
: origin.x + width - pad - size / 2;
}
const cy = origin.y + height / 2;
const w = size;
const h = size * 0.55;
const down = direction === "down";
const y1 = down ? cy - h / 3 : cy + h / 3;
const y2 = down ? cy + h / 3 : cy - h / 3;
return (
<path
d={`M ${cx - w / 2} ${y1} L ${cx} ${y2} L ${cx + w / 2} ${y1}`}
fill="none"
stroke={colors.fg}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2.4}
/>
);
};
export const AnatomyCheck = (props: { size?: number }) => {
const { size = 18 } = props;
const { colors, height, origin, width } = useAnatomyPart();
const cx = origin.x + width / 2;
const cy = origin.y + height / 2;
const s = size / 2;
return (
<path
d={`M ${cx - s * 0.55} ${cy} L ${cx - s * 0.1} ${cy + s * 0.45} L ${cx + s * 0.6} ${cy - s * 0.4}`}
fill="none"
stroke={colors.fg}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2.6}
/>
);
};
export const AnatomyX = (props: { size?: number }) => {
const { size = 16 } = props;
const { colors, height, origin, width } = useAnatomyPart();
const cx = origin.x + width / 2;
const cy = origin.y + height / 2;
const s = size / 2;
return (
<path
d={`M ${cx - s} ${cy - s} L ${cx + s} ${cy + s} M ${cx + s} ${cy - s} L ${cx - s} ${cy + s}`}
fill="none"
stroke={colors.fg}
strokeLinecap="round"
strokeWidth={2.6}
/>
);
};
export { AnatomyContext };Update the import paths to match your project setup.
Usage
import {
Anatomy,
AnatomyCheck,
AnatomyPart,
AnatomyText,
} from "@/components/ui/anatomy";<Anatomy brand title="Checkbox anatomy">
<AnatomyPart
box
height={96}
name="root"
rx={14}
width={480}
x={360}
y={267}
>
<AnatomyPart
height={44}
name="control"
rx={8}
side="start"
tone="emphasis"
width={44}
x={26}
y={26}
>
<AnatomyCheck />
</AnatomyPart>
<AnatomyPart
height={96}
name="label"
side="bottom"
width={360}
x={86}
y={0}
>
<AnatomyText fontSize={32}>Checkbox Label</AnatomyText>
</AnatomyPart>
</AnatomyPart>
</Anatomy>Demos
Accordion
Action Bar
Toc
API Reference
Anatomy
PropType
AttributeType
ANATOMY_HEIGHT
ANATOMY_WIDTH
CSS variableType
AnatomyPart
PropType
AttributeType
AnatomyText
PropType
AnatomyChevron
PropType