diff --git a/demo/31-tables.ts b/demo/31-tables.ts index 7daec1506d..24fc6030f8 100644 --- a/demo/31-tables.ts +++ b/demo/31-tables.ts @@ -1,7 +1,7 @@ // Example of how you would create a table and add data to it // Import from 'docx' rather than '../build' if you install from npm import * as fs from "fs"; -import { Document, HeadingLevel, Packer, Paragraph, Table, TableCell, TableRow, VerticalAlign } from "../build"; +import { Document, HeadingLevel, Packer, Paragraph, Table, TableCell, TableRow, VerticalAlign, TextDirection } from "../build"; const doc = new Document(); @@ -17,6 +17,14 @@ const table = new Table({ children: [new Paragraph({}), new Paragraph({})], verticalAlign: VerticalAlign.CENTER, }), + new TableCell({ + children: [new Paragraph({ text: "bottom to top" }), new Paragraph({})], + textDirection: TextDirection.BOTTOM_TO_TOP_LEFT_TO_RIGHT, + }), + new TableCell({ + children: [new Paragraph({ text: "top to bottom" }), new Paragraph({})], + textDirection: TextDirection.TOP_TO_BOTTOM_RIGHT_TO_LEFT, + }), ], }), new TableRow({ @@ -38,6 +46,22 @@ const table = new Table({ ], verticalAlign: VerticalAlign.CENTER, }), + new TableCell({ + children: [ + new Paragraph({ + text: "Text above should be vertical from bottom to top", + }), + ], + verticalAlign: VerticalAlign.CENTER, + }), + new TableCell({ + children: [ + new Paragraph({ + text: "Text above should be vertical from top to bottom", + }), + ], + verticalAlign: VerticalAlign.CENTER, + }), ], }), ], diff --git a/src/file/table/table-cell/table-cell-components.ts b/src/file/table/table-cell/table-cell-components.ts index e16c2f6885..f3ebe570e9 100644 --- a/src/file/table/table-cell/table-cell-components.ts +++ b/src/file/table/table-cell/table-cell-components.ts @@ -158,6 +158,31 @@ export class VAlign extends XmlComponent { } } +export enum TextDirection { + BOTTOM_TO_TOP_LEFT_TO_RIGHT = "btLr", + LEFT_TO_RIGHT_TOP_TO_BOTTOM = "lrTb", + TOP_TO_BOTTOM_RIGHT_TO_LEFT = "tbRl", +} + +class TDirectionAttributes extends XmlAttributeComponent<{ readonly val: TextDirection }> { + protected readonly xmlKeys = { val: "w:val" }; +} + +/** + * Text Direction within a table cell + */ +export class TDirection extends XmlComponent { + constructor(value: TextDirection) { + super("w:textDirection"); + + this.root.push( + new TDirectionAttributes({ + val: value, + }), + ); + } +} + export enum WidthType { /** Auto. */ AUTO = "auto", diff --git a/src/file/table/table-cell/table-cell-properties.ts b/src/file/table/table-cell/table-cell-properties.ts index aed56aaeda..e248290294 100644 --- a/src/file/table/table-cell/table-cell-properties.ts +++ b/src/file/table/table-cell/table-cell-properties.ts @@ -6,6 +6,8 @@ import { GridSpan, TableCellBorders, TableCellWidth, + TDirection, + TextDirection, VAlign, VerticalAlign, VerticalMerge, @@ -61,4 +63,10 @@ export class TableCellProperties extends IgnoreIfEmptyXmlComponent { return this; } + + public setTextDirection(type: TextDirection): TableCellProperties { + this.root.push(new TDirection(type)); + + return this; + } } diff --git a/src/file/table/table-cell/table-cell.spec.ts b/src/file/table/table-cell/table-cell.spec.ts index a4c316f7ba..2ba34bc9d4 100644 --- a/src/file/table/table-cell/table-cell.spec.ts +++ b/src/file/table/table-cell/table-cell.spec.ts @@ -5,7 +5,7 @@ import { BorderStyle } from "file/styles"; import { ShadingType } from "../shading"; import { TableCell } from "./table-cell"; -import { TableCellBorders, TableCellWidth, VerticalAlign, VerticalMergeType, WidthType } from "./table-cell-components"; +import { TableCellBorders, TableCellWidth, TextDirection, VerticalAlign, VerticalMergeType, WidthType } from "./table-cell-components"; describe("TableCellBorders", () => { describe("#prepForXml", () => { @@ -271,6 +271,34 @@ describe("TableCell", () => { }); }); + it("should create with text direction", () => { + const cell = new TableCell({ + children: [], + textDirection: TextDirection.BOTTOM_TO_TOP_LEFT_TO_RIGHT, + }); + + const tree = new Formatter().format(cell); + + expect(tree).to.deep.equal({ + "w:tc": [ + { + "w:tcPr": [ + { + "w:textDirection": { + _attr: { + "w:val": "btLr", + }, + }, + }, + ], + }, + { + "w:p": {}, + }, + ], + }); + }); + it("should create with vertical merge", () => { const cell = new TableCell({ children: [], diff --git a/src/file/table/table-cell/table-cell.ts b/src/file/table/table-cell/table-cell.ts index fe8f8b5868..c809c157ad 100644 --- a/src/file/table/table-cell/table-cell.ts +++ b/src/file/table/table-cell/table-cell.ts @@ -7,13 +7,14 @@ import { File } from "../../file"; import { ITableShadingAttributesProperties } from "../shading"; import { Table } from "../table"; import { ITableCellMarginOptions } from "./cell-margin/table-cell-margins"; -import { VerticalAlign, VerticalMergeType, WidthType } from "./table-cell-components"; +import { TextDirection, VerticalAlign, VerticalMergeType, WidthType } from "./table-cell-components"; import { TableCellProperties } from "./table-cell-properties"; export interface ITableCellOptions { readonly shading?: ITableShadingAttributesProperties; readonly margins?: ITableCellMarginOptions; readonly verticalAlign?: VerticalAlign; + readonly textDirection?: TextDirection; readonly verticalMerge?: VerticalMergeType; readonly width?: { readonly size: number | string; @@ -63,6 +64,10 @@ export class TableCell extends XmlComponent { this.properties.setVerticalAlign(options.verticalAlign); } + if (options.textDirection) { + this.properties.setTextDirection(options.textDirection); + } + if (options.verticalMerge) { this.properties.addVerticalMerge(options.verticalMerge); }