diff --git a/src/components/forms/custom-form-builder.tsx b/src/components/forms/custom-form-builder.tsx index b183669..82182ee 100644 --- a/src/components/forms/custom-form-builder.tsx +++ b/src/components/forms/custom-form-builder.tsx @@ -727,6 +727,34 @@ export function CustomFormBuilder() { right: b.r ? onBorder : offBorder, }); + // Build TextRuns for an array of inline runs, honoring newlines (via break: 1) and bold/italic/underline. + const buildDocxRuns = (runs: InlineRun[], extra: { italic?: boolean } = {}): TextRun[] => { + const out: TextRun[] = []; + let isFirst = true; + for (const r of runs) { + const expanded = applyVariables(r.text, ctx); + const parts = expanded.split("\n"); + parts.forEach((part, i) => { + out.push( + new TextRun({ + text: part, + font: fontFamily, + size: fontSize * 2, + bold: !!r.bold, + italics: !!r.italic || !!extra.italic, + underline: r.underline ? {} : undefined, + break: !isFirst && i === 0 ? undefined : i > 0 ? 1 : undefined, + }), + ); + isFirst = false; + }); + } + if (out.length === 0) { + out.push(new TextRun({ text: "", font: fontFamily, size: fontSize * 2 })); + } + return out; + }; + for (const seg of segments) { if (seg.kind === "table") { const cols = Math.max(...seg.rows.map((r) => r.length)); @@ -742,21 +770,13 @@ export function CustomFormBuilder() { children: Array.from({ length: cols }).map((_, ci) => { const cell = row[ci]; const borders = cell?.borders ?? DEFAULT_BORDERS; - const isHeader = cell?.isHeader ?? false; return new DocxTableCell({ borders: docxBorders(borders), width: { size: colW, type: WidthType.DXA }, margins: { top: 80, bottom: 80, left: 120, right: 120 }, children: [ new DocxParagraph({ - children: [ - new TextRun({ - text: applyVariables(cell?.text ?? "", ctx), - font: fontFamily, - size: fontSize * 2, - bold: isHeader, - }), - ], + children: buildDocxRuns(cell?.runs ?? []), }), ], }); @@ -778,22 +798,11 @@ export function CustomFormBuilder() { ? AlignmentType.JUSTIFIED : AlignmentType.LEFT; const indentTwips = Math.round((seg.indent || 0) * 15); // ~px → twips (1px≈15twip) - const lines = applyVariables(seg.text, ctx).split("\n"); children.push( new DocxParagraph({ alignment: align, indent: indentTwips ? { left: indentTwips } : undefined, - children: lines.flatMap((line, idx) => { - const run = new TextRun({ - text: line, - font: fontFamily, - size: fontSize * 2, - italics: seg.caption, - bold: !!seg.heading && seg.heading > 0, - break: idx > 0 ? 1 : undefined, - }); - return [run]; - }), + children: buildDocxRuns(seg.runs, { italic: seg.caption }), }), ); }