@ui-registries/pdf

SVG Elements

SVG components for drawing vector graphics in PDF documents.

@ui-registries/pdf includes SVG components for drawing vector graphics. Svg, G, and SvgText support className for layout and typography styles. Shape and gradient components use SVG attributes directly.

Available Components

ComponentclassNameDescription
Svg✓SVG container (supports full layout styles)
G✓Group element (supports full layout styles)
SvgText✓Text element (supports typography + layout styles)
Path—Path element
Rect—Rectangle
Circle—Circle
Ellipse—Ellipse
Line—Line
Polyline—Polyline
Polygon—Polygon
Tspan—Text span
Defs—Definitions container
ClipPath—Clip path
Stop—Gradient stop
LinearGradient—Linear gradient
RadialGradient—Radial gradient

Usage

With className (Svg, G, SvgText)

tsx
import { Block, Svg, G, SvgText, Circle, Path } from "@ui-registries/pdf";
<Block className="flex items-center gap-2">  <Svg className="w-10 h-10" viewBox="0 0 40 40">    <G className="opacity-80">      <Circle cx={20} cy={20} r={18} fill="#3b82f6" />      <Path d="M14 20l4 4 8-8" stroke="#ffffff" strokeWidth={2} fill="none" />    </G>    <SvgText className="text-xs font-bold" x={20} y={36}>      ✓    </SvgText>  </Svg></Block>

Shape components

Shape components (Path, Rect, Circle, Ellipse, Line, Polyline, Polygon) take SVG presentation attributes as props — fill, stroke, strokeWidth, opacity, etc. Their className accepts the fill-* and stroke-* utilities, resolved against the document theme; other classes are ignored. Explicit props win over classes.

tsx
<Svg width={120} height={40} viewBox="0 0 120 40">  <Rect className="fill-muted stroke-border" width={120} height={40} rx={6} />  <Circle className="fill-primary" cx={20} cy={20} r={10} />  <Path className="fill-none stroke-chart-2 stroke-2" d="M40 30 L60 10 L80 25 L110 8" /></Svg>

Colors with an opacity modifier (fill-primary/50) become a hex color plus fillOpacity / strokeOpacity, which react-pdf's SVG renderer needs.

To use a theme color in a prop (a gradient stop, a computed color), read it with useThemeColor:

tsx
import { Stop, useThemeColor } from "@ui-registries/pdf";
const Brand = () => <Stop offset="0%" stopColor={useThemeColor("primary")} />;

Raw props still work everywhere:

tsx
<Svg width={40} height={40} viewBox="0 0 40 40">  <Defs>    <LinearGradient id="grad" x1="0" y1="0" x2="1" y2="1">      <Stop offset="0%" stopColor="#3b82f6" />      <Stop offset="100%" stopColor="#8b5cf6" />    </LinearGradient>  </Defs>  <Circle cx={20} cy={20} r={18} fill="url(#grad)" />  <Rect x={5} y={5} width={30} height={30} rx={4} fill="none" stroke="#000" strokeWidth={1} /></Svg>

SvgText is exported under that name because Text is already used by the className-enabled text component.

Props

Svg

PropTypeDefault
children?React.ReactNode—
className?string—
style?Style—
break?boolean

Force the wrapping algorithm to start a new page when rendering the element.

—
clipPath?string—
color?string—
debug?boolean

Enables debug mode on page bounding box.

—
dominantBaseline?"middle" | "auto" | "central" | "hanging" | "mathematical" | "text-after-edge" | "text-before-edge"—
fill?string—
fillOpacity?string | number—
fillRule?"nonzero" | "evenodd"—
fixed?boolean

Render component in all wrapped pages.

—
height?string | number—
id?string—
markerEnd?string—
markerMid?string—
markerStart?string—
minPresenceAhead?number

Hint that no page wrapping should occur between all sibling elements following the element within n points

—
opacity?string | number—
preserveAspectRatio?string—
stroke?string—
strokeDasharray?string—
strokeLinecap?"butt" | "round" | "square"—
strokeLinejoin?"butt" | "round" | "square" | "miter" | "bevel"—
strokeOpacity?string | number—
strokeWidth?string | number—
textAnchor?"start" | "middle" | "end"—
transform?string—
viewBox?string—
visibility?"visible" | "hidden" | "collapse"—
width?string | number—

G

PropTypeDefault
children?React.ReactNode—
className?string—
style?Style—
clipPath?string—
color?string—
dominantBaseline?"middle" | "auto" | "central" | "hanging" | "mathematical" | "text-after-edge" | "text-before-edge"—
fill?string—
fillOpacity?string | number—
fillRule?"nonzero" | "evenodd"—
markerEnd?string—
markerMid?string—
markerStart?string—
opacity?string | number—
stroke?string—
strokeDasharray?string—
strokeLinecap?"butt" | "round" | "square"—
strokeLinejoin?"butt" | "round" | "square" | "miter" | "bevel"—
strokeOpacity?string | number—
strokeWidth?string | number—
textAnchor?"start" | "middle" | "end"—
transform?string—
visibility?"visible" | "hidden" | "collapse"—

SvgText

PropTypeDefault
children?React.ReactNode—
className?string—
style?Style—
clipPath?string—
color?string—
dominantBaseline?"middle" | "auto" | "central" | "hanging" | "mathematical" | "text-after-edge" | "text-before-edge"—
fill?string—
fillOpacity?string | number—
fillRule?"nonzero" | "evenodd"—
hyphenationCallback?HyphenationCallback

Override the default hyphenation-callback

—
markerEnd?string—
markerMid?string—
markerStart?string—
opacity?string | number—
stroke?string—
strokeDasharray?string—
strokeLinecap?"butt" | "round" | "square"—
strokeLinejoin?"butt" | "round" | "square" | "miter" | "bevel"—
strokeOpacity?string | number—
strokeWidth?string | number—
textAnchor?"start" | "middle" | "end"—
transform?string—
visibility?"visible" | "hidden" | "collapse"—
xstring | number—
ystring | number—