Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
gpt-engineer-app[bot]
2026-04-18 02:09:23 +00:00
co-authored by renee-png
parent de84c0792b
commit 1e3378439e
@@ -132,6 +132,65 @@ const FONT_FAMILIES = [
const FONT_SIZES = [9, 10, 11, 12, 13, 14, 16, 18, 20, 24];
// Extend table cells with per-side border attributes (default: all on).
type CellBorders = { t: boolean; r: boolean; b: boolean; l: boolean };
const DEFAULT_BORDERS: CellBorders = { t: true, r: true, b: true, l: true };
function borderStyleString(b: CellBorders): string {
const on = "1px solid #999";
const off = "1px solid transparent";
return `border-top:${b.t ? on : off};border-right:${b.r ? on : off};border-bottom:${b.b ? on : off};border-left:${b.l ? on : off};`;
}
function parseBordersFromAttr(val: unknown): CellBorders {
if (typeof val === "string") {
return {
t: val.includes("t"),
r: val.includes("r"),
b: val.includes("b"),
l: val.includes("l"),
};
}
if (val && typeof val === "object") return { ...DEFAULT_BORDERS, ...(val as any) };
return DEFAULT_BORDERS;
}
function bordersToAttr(b: CellBorders): string {
return `${b.t ? "t" : ""}${b.r ? "r" : ""}${b.b ? "b" : ""}${b.l ? "l" : ""}` || "none";
}
const BorderedTableCell = TableCell.extend({
addAttributes() {
return {
...this.parent?.(),
borders: {
default: "trbl",
parseHTML: (el: HTMLElement) => el.getAttribute("data-borders") ?? "trbl",
renderHTML: (attrs: { borders?: string }) => {
const b = parseBordersFromAttr(attrs.borders);
return { "data-borders": bordersToAttr(b), style: borderStyleString(b) };
},
},
};
},
});
const BorderedTableHeader = TableHeader.extend({
addAttributes() {
return {
...this.parent?.(),
borders: {
default: "trbl",
parseHTML: (el: HTMLElement) => el.getAttribute("data-borders") ?? "trbl",
renderHTML: (attrs: { borders?: string }) => {
const b = parseBordersFromAttr(attrs.borders);
return { "data-borders": bordersToAttr(b), style: borderStyleString(b) };
},
},
};
},
});
interface SavedTemplate {
id: string;
name: string;