Add Ledger and Band template families with decor primitives
Crimson Grid, Tangerine Ledger, Slate Band and Teal Swoosh are rebuilt from the Canva PDFs with grid and band tables that survive page breaks, full-bleed fixed bands, pennant tabs, gradient corner swooshes with keep-outs, Carbon icon circles, and the user's logo in the measured slot (knockout or white chip on the dark Slate band). Adds static Poppins 500-700 and Inter fonts. Thumbnails regenerated for all eight templates; the item-count sweeps run in their own test file.
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import { Circle, G, Path, Svg } from "@react-pdf/renderer";
|
||||
import { ICONS, type IconName } from "./icons.generated";
|
||||
|
||||
export interface ContactIconProps {
|
||||
name: IconName;
|
||||
/** Side of the square box, pt. */
|
||||
size: number;
|
||||
color: string;
|
||||
}
|
||||
|
||||
/** A Carbon icon as a static Svg, filled with `color`. */
|
||||
export function ContactIcon({ name, size, color }: ContactIconProps) {
|
||||
const icon = ICONS[name];
|
||||
return (
|
||||
<Svg width={size} height={size} viewBox={icon.viewBox}>
|
||||
{icon.paths.map((d, i) => (
|
||||
<Path key={i} d={d} fill={color} />
|
||||
))}
|
||||
</Svg>
|
||||
);
|
||||
}
|
||||
|
||||
export interface CircledIconProps extends ContactIconProps {
|
||||
/** Ring thickness, pt. */
|
||||
ring: number;
|
||||
/** The icon's share of the diameter, 0..1. */
|
||||
glyph?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* An icon inside a ring (Slate Band's footer): one static Svg, ring and glyph together. The glyph sits in a
|
||||
* translated and scaled static group (verified to work as a static child, unlike inside a render prop).
|
||||
*/
|
||||
export function CircledIcon({ name, size, color, ring, glyph = 0.5 }: CircledIconProps) {
|
||||
const icon = ICONS[name];
|
||||
const [minX, minY, vw, vh] = icon.viewBox.split(" ").map(Number);
|
||||
const scale = (size * glyph) / Math.max(vw, vh);
|
||||
const ox = (size - vw * scale) / 2 - minX * scale;
|
||||
const oy = (size - vh * scale) / 2 - minY * scale;
|
||||
return (
|
||||
<Svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
|
||||
<Circle cx={size / 2} cy={size / 2} r={size / 2 - ring / 2} stroke={color} strokeWidth={ring} fill="none" />
|
||||
<G transform={`translate(${ox} ${oy}) scale(${scale})`}>
|
||||
{icon.paths.map((d, i) => (
|
||||
<Path key={i} d={d} fill={color} />
|
||||
))}
|
||||
</G>
|
||||
</Svg>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user