Add the Monolith and Cobalt Stripe templates
Standalone layouts for Canva templates 3 and 8, with the user's logo sized to the placeholder box, a CapRule decor primitive, optional TableRows rule/heading options, and a separate 1..45-row sweep test file.
This commit is contained in:
@@ -141,6 +141,8 @@ export interface TableRowsProps extends TableLook {
|
||||
roles: TableRoles;
|
||||
/** Per column; default left. */
|
||||
align?: Array<"left" | "right" | "center">;
|
||||
/** Header alignment per column when it differs from the body's; default `align`. */
|
||||
headAlign?: Array<"left" | "right" | "center">;
|
||||
/** Passed as minPresenceAhead on the last row so the totals never start a page without an item row. */
|
||||
tailH?: number;
|
||||
/** Content after the last row, inside the table container (the totals). */
|
||||
@@ -178,6 +180,12 @@ export interface TableRowsProps extends TableLook {
|
||||
* of the container's left edge. Plan with planItemsTable at width - 2 * rowInset.
|
||||
*/
|
||||
pill?: { indent: number; inset: number };
|
||||
/**
|
||||
* Vertical rules between the columns only (no outer edges, no rule above the header): `width` after every column but
|
||||
* the last, in `color` on body rows and `headerColor` in the header (default `color`). The cells stretch to the row's
|
||||
* height. Plan with `innerRulePadRight(...)` added to the padding so wrapping uses the real inner width.
|
||||
*/
|
||||
innerRules?: { width: number; color: string; headerColor?: string };
|
||||
}
|
||||
|
||||
/** Extra right padding per column that stands in for a grid's vertical rules, for planItemsTable's `padRight`. */
|
||||
@@ -185,12 +193,17 @@ export function gridPadRight(columns: number, ruleWidth: number): number[] {
|
||||
return Array.from({ length: columns }, (_, i) => (i === 0 ? 2 : 1) * ruleWidth);
|
||||
}
|
||||
|
||||
/** Extra right padding per column that stands in for the inner rules of `innerRules`, for planItemsTable's `padRight`. */
|
||||
export function innerRulePadRight(columns: number, ruleWidth: number): number[] {
|
||||
return Array.from({ length: columns }, (_, i) => (i < columns - 1 ? ruleWidth : 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Header (a `fixed` first child, so it repeats on every page the table spans) followed by one
|
||||
* `wrap={false}` row per item. The container has no padding or border; those go on the rows, because
|
||||
* the repeated header is positioned against the container's top.
|
||||
*/
|
||||
export function TableRows({ columns, gap, width, header, rows, roles, align = [], tailH, tail, headerStyle, rowStyle, headCellStyle, borderColor, headColor, headerTail, grid, bleed, pill, ...look }: TableRowsProps) {
|
||||
export function TableRows({ columns, gap, width, header, rows, roles, align = [], tailH, tail, headerStyle, rowStyle, headCellStyle, borderColor, headColor, headerTail, grid, bleed, pill, innerRules, headAlign, ...look }: TableRowsProps) {
|
||||
const padX = look.padX ?? 0;
|
||||
const padY = look.padY ?? 4;
|
||||
const headPadY = look.headPadY ?? padY;
|
||||
@@ -208,14 +221,17 @@ export function TableRows({ columns, gap, width, header, rows, roles, align = []
|
||||
const last = i === values.length - 1;
|
||||
const inner = isHeader ? (grid?.headerColor ?? grid?.color) : grid?.color;
|
||||
const outer = isHeader ? (grid?.headerEdge ?? grid?.color) : grid?.color;
|
||||
const ruleW = edge * (i === 0 ? 2 : 1);
|
||||
const inner2 = innerRules && !last ? innerRules.width : 0;
|
||||
const ruleW = grid ? edge * (i === 0 ? 2 : 1) : inner2;
|
||||
const alignOf = isHeader ? (headAlign?.[i] ?? align[i]) : align[i];
|
||||
return (
|
||||
<Cell
|
||||
key={i}
|
||||
padding={{ top: isHeader ? headPadY : padY, bottom: isHeader ? headPadY : padY, left: padX + (look.padLeft?.[i] ?? 0), right: padX + (look.padRight?.[i] ?? 0) }}
|
||||
borderLeft={grid && i === 0 ? edge : 0}
|
||||
borderRight={edge}
|
||||
borderRight={grid ? edge : inner2}
|
||||
style={{
|
||||
...(innerRules ? { flexGrow: 1, flexBasis: "auto", ...(inner2 ? { borderRightColor: isHeader ? (innerRules.headerColor ?? innerRules.color) : innerRules.color } : {}) } : {}),
|
||||
...(grid
|
||||
? {
|
||||
flexGrow: 1,
|
||||
@@ -229,14 +245,14 @@ export function TableRows({ columns, gap, width, header, rows, roles, align = []
|
||||
}}
|
||||
>
|
||||
{cellParts(v).map((part, li) => (
|
||||
<Txt key={li} role={partRole(part, role)} color={color} width={Math.max(0, widths[i] - 2 * padX - (look.padRight?.[i] ?? 0) - (look.padLeft?.[i] ?? 0) - ruleW)} align={align[i]} faceOverrides={look.faceOverrides}>
|
||||
<Txt key={li} role={partRole(part, role)} color={color} width={Math.max(0, widths[i] - 2 * padX - (look.padRight?.[i] ?? 0) - (look.padLeft?.[i] ?? 0) - ruleW)} align={alignOf} faceOverrides={look.faceOverrides}>
|
||||
{partText(part)}
|
||||
</Txt>
|
||||
))}
|
||||
</Cell>
|
||||
);
|
||||
});
|
||||
const rowAlign = grid ? ("stretch" as const) : undefined;
|
||||
const rowAlign = grid || innerRules ? ("stretch" as const) : undefined;
|
||||
const inset = pill?.inset ?? 0;
|
||||
const cellsWidth = width - 2 * inset;
|
||||
/** One table line: a plain Row, or for pills an outer box (the fill) around a Row of the inner width. */
|
||||
|
||||
Reference in New Issue
Block a user