From 7d1129900f97b825efb7407027780c2a28bc6389 Mon Sep 17 00:00:00 2001 From: Firat Ciftci <2052855+firatciftci@users.noreply.github.com> Date: Fri, 2 May 2025 13:58:10 -0500 Subject: [PATCH] Fix: separate vertical alignment enums for ITableCellOptions and ISectionPropertiesOptions (#3079) * fix: separate vertical alignment enums for table and section properties - Introduced `VerticalAlignTable` for table-cell vertical alignment with valid values: `top`, `center`, and `bottom`. - Added `VerticalAlignSection` for section properties, extending `VerticalAlignTable` with an additional value `both`. - Marked the original `VerticalAlign` as deprecated for backward compatibility, directing users to the new enums. - Updated type definitions for better clarity on valid vertical alignments. * refactor: update vertical alignment imports and types for section and table properties - Renamed `VerticalAlign` to `VerticalAlignSection` in section properties and `VerticalAlignTable` in table-cell properties for clarity. - Updated type definitions to reflect the new enum names, ensuring better organization and understanding of vertical alignment options. - Adjusted related test cases to utilize the new imports and types. * refactor: update demos to use new enums for table and section properties for vertical alignment --- demo/31-tables.ts | 12 +++---- demo/48-vertical-align.ts | 4 +-- demo/49-table-borders.ts | 12 +++---- demo/50-readme-demo.ts | 9 ++++-- demo/79-table-from-data-source.ts | 14 ++++---- demo/85-template-document.ts | 12 +++---- demo/96-template-document.ts | 12 +++---- docs/usage/tables.md | 6 ++-- .../section-properties.spec.ts | 4 +-- .../section-properties/section-properties.ts | 4 +-- .../table-cell/table-cell-properties.spec.ts | 4 +-- .../table/table-cell/table-cell-properties.ts | 4 +-- src/file/table/table-cell/table-cell.spec.ts | 4 +-- src/file/vertical-align/vertical-align.ts | 32 +++++++++++++++++-- 14 files changed, 81 insertions(+), 52 deletions(-) diff --git a/demo/31-tables.ts b/demo/31-tables.ts index 251cbbc890..03f7d617c0 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 * as fs from "fs"; -import { Document, HeadingLevel, Packer, Paragraph, Table, TableCell, TableRow, VerticalAlign, TextDirection } from "docx"; +import { Document, HeadingLevel, Packer, Paragraph, Table, TableCell, TableRow, VerticalAlignTable, TextDirection } from "docx"; const doc = new Document({ sections: [ @@ -13,11 +13,11 @@ const doc = new Document({ children: [ new TableCell({ children: [new Paragraph({}), new Paragraph({})], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, }), new TableCell({ children: [new Paragraph({}), new Paragraph({})], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, }), new TableCell({ children: [new Paragraph({ text: "bottom to top" }), new Paragraph({})], @@ -45,7 +45,7 @@ const doc = new Document({ text: "This text should be in the middle of the cell", }), ], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, }), new TableCell({ children: [ @@ -53,7 +53,7 @@ const doc = new Document({ text: "Text above should be vertical from bottom to top", }), ], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, }), new TableCell({ children: [ @@ -61,7 +61,7 @@ const doc = new Document({ text: "Text above should be vertical from top to bottom", }), ], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, }), ], }), diff --git a/demo/48-vertical-align.ts b/demo/48-vertical-align.ts index 135c0ee387..b27bfbdf76 100644 --- a/demo/48-vertical-align.ts +++ b/demo/48-vertical-align.ts @@ -1,13 +1,13 @@ // Example of making content of section vertically aligned import * as fs from "fs"; -import { Document, Packer, Paragraph, VerticalAlign, TextRun, Tab } from "docx"; +import { Document, Packer, Paragraph, VerticalAlignSection, TextRun, Tab } from "docx"; const doc = new Document({ sections: [ { properties: { - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignSection.CENTER, }, children: [ new Paragraph({ diff --git a/demo/49-table-borders.ts b/demo/49-table-borders.ts index d1f3afadcf..acec8b8a9e 100644 --- a/demo/49-table-borders.ts +++ b/demo/49-table-borders.ts @@ -12,7 +12,7 @@ import { TableCell, TableRow, TextDirection, - VerticalAlign, + VerticalAlignTable, } from "docx"; const table = new Table({ @@ -102,11 +102,11 @@ const noBorderTable = new Table({ children: [ new TableCell({ children: [new Paragraph({}), new Paragraph({})], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, }), new TableCell({ children: [new Paragraph({}), new Paragraph({})], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, }), new TableCell({ children: [new Paragraph({ text: "bottom to top" }), new Paragraph({})], @@ -134,7 +134,7 @@ const noBorderTable = new Table({ text: "This text should be in the middle of the cell", }), ], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, }), new TableCell({ children: [ @@ -142,7 +142,7 @@ const noBorderTable = new Table({ text: "Text above should be vertical from bottom to top", }), ], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, }), new TableCell({ children: [ @@ -150,7 +150,7 @@ const noBorderTable = new Table({ text: "Text above should be vertical from top to bottom", }), ], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, }), ], }), diff --git a/demo/50-readme-demo.ts b/demo/50-readme-demo.ts index 5330d09618..8090d936c6 100644 --- a/demo/50-readme-demo.ts +++ b/demo/50-readme-demo.ts @@ -1,7 +1,7 @@ // The demo on the README.md import * as fs from "fs"; -import { Document, HeadingLevel, ImageRun, Packer, Paragraph, Table, TableCell, TableRow, VerticalAlign } from "docx"; +import { Document, HeadingLevel, ImageRun, Packer, Paragraph, Table, TableCell, TableRow, VerticalAlignTable } from "docx"; const table = new Table({ rows: [ @@ -13,6 +13,7 @@ const table = new Table({ children: [ new ImageRun({ data: fs.readFileSync("./demo/images/image1.jpeg"), + type: "jpg", transformation: { width: 100, height: 100, @@ -21,7 +22,7 @@ const table = new Table({ ], }), ], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, }), new TableCell({ children: [ @@ -30,7 +31,7 @@ const table = new Table({ heading: HeadingLevel.HEADING_1, }), ], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, }), ], }), @@ -50,6 +51,7 @@ const table = new Table({ children: [ new ImageRun({ data: fs.readFileSync("./demo/images/image1.jpeg"), + type: "jpg", transformation: { width: 100, height: 100, @@ -77,6 +79,7 @@ const doc = new Document({ children: [ new ImageRun({ data: fs.readFileSync("./demo/images/pizza.gif"), + type: "gif", transformation: { width: 100, height: 100, diff --git a/demo/79-table-from-data-source.ts b/demo/79-table-from-data-source.ts index d2ac3f690c..39a6d0a46e 100644 --- a/demo/79-table-from-data-source.ts +++ b/demo/79-table-from-data-source.ts @@ -9,7 +9,7 @@ import { Table, TableCell, TableRow, - VerticalAlign, + VerticalAlignTable, TextDirection, TextRun, WidthType, @@ -101,17 +101,17 @@ const generateRows = (prices: StockPrice[]): TableRow[] => children: [ new TableCell({ children: [new Paragraph(date.toString())], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, textDirection: TextDirection.LEFT_TO_RIGHT_TOP_TO_BOTTOM, }), new TableCell({ children: [new Paragraph(ticker)], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, textDirection: TextDirection.LEFT_TO_RIGHT_TOP_TO_BOTTOM, }), new TableCell({ children: [new Paragraph(price.toString())], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, textDirection: TextDirection.TOP_TO_BOTTOM_RIGHT_TO_LEFT, }), ], @@ -143,7 +143,7 @@ const doc = new Document({ ], }), ], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, textDirection: TextDirection.LEFT_TO_RIGHT_TOP_TO_BOTTOM, }), new TableCell({ @@ -159,7 +159,7 @@ const doc = new Document({ ], }), ], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, textDirection: TextDirection.LEFT_TO_RIGHT_TOP_TO_BOTTOM, }), new TableCell({ @@ -175,7 +175,7 @@ const doc = new Document({ ], }), ], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, textDirection: TextDirection.TOP_TO_BOTTOM_RIGHT_TO_LEFT, }), ], diff --git a/demo/85-template-document.ts b/demo/85-template-document.ts index 38ab563156..24ab1ceabf 100644 --- a/demo/85-template-document.ts +++ b/demo/85-template-document.ts @@ -13,7 +13,7 @@ import { TableRow, TextDirection, TextRun, - VerticalAlign, + VerticalAlignTable, } from "docx"; patchDocument({ @@ -105,11 +105,11 @@ patchDocument({ children: [ new TableCell({ children: [new Paragraph({}), new Paragraph({})], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, }), new TableCell({ children: [new Paragraph({}), new Paragraph({})], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, }), new TableCell({ children: [new Paragraph({ text: "bottom to top" }), new Paragraph({})], @@ -137,7 +137,7 @@ patchDocument({ text: "This text should be in the middle of the cell", }), ], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, }), new TableCell({ children: [ @@ -145,7 +145,7 @@ patchDocument({ text: "Text above should be vertical from bottom to top", }), ], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, }), new TableCell({ children: [ @@ -153,7 +153,7 @@ patchDocument({ text: "Text above should be vertical from top to bottom", }), ], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, }), ], }), diff --git a/demo/96-template-document.ts b/demo/96-template-document.ts index 949712e898..64454dd664 100644 --- a/demo/96-template-document.ts +++ b/demo/96-template-document.ts @@ -13,7 +13,7 @@ import { TableRow, TextDirection, TextRun, - VerticalAlign, + VerticalAlignTable, } from "docx"; patchDocument({ @@ -105,11 +105,11 @@ patchDocument({ children: [ new TableCell({ children: [new Paragraph({}), new Paragraph({})], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, }), new TableCell({ children: [new Paragraph({}), new Paragraph({})], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, }), new TableCell({ children: [new Paragraph({ text: "bottom to top" }), new Paragraph({})], @@ -137,7 +137,7 @@ patchDocument({ text: "This text should be in the middle of the cell", }), ], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, }), new TableCell({ children: [ @@ -145,7 +145,7 @@ patchDocument({ text: "Text above should be vertical from bottom to top", }), ], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, }), new TableCell({ children: [ @@ -153,7 +153,7 @@ patchDocument({ text: "Text above should be vertical from top to bottom", }), ], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, }), ], }), diff --git a/docs/usage/tables.md b/docs/usage/tables.md index 3d48d3a80a..6455dd2549 100644 --- a/docs/usage/tables.md +++ b/docs/usage/tables.md @@ -159,7 +159,7 @@ const tableRow = new TableRow({ | children | `Array` | Required. You can nest tables by adding a table into a cell | | shading | `IShadingAttributesProperties` | Optional | | margins | `ITableCellMarginOptions` | Optional | -| verticalAlign | `VerticalAlign` | Optional | +| verticalAlign | `VerticalAlignTable` | Optional | | columnSpan | `number` | Optional | | rowSpan | `number` | Optional | | borders | `BorderOptions` | Optional | @@ -266,7 +266,7 @@ Sets the vertical alignment of the contents of the cell ```ts const cell = new TableCell({ ..., - verticalAlign: VerticalAlign, + verticalAlign: VerticalAlignTable, }); ``` @@ -282,7 +282,7 @@ For example, to center align a cell: ```ts const cell = new TableCell({ - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, }); ``` diff --git a/src/file/document/body/section-properties/section-properties.spec.ts b/src/file/document/body/section-properties/section-properties.spec.ts index a31d2723b8..1b58beefc8 100644 --- a/src/file/document/body/section-properties/section-properties.spec.ts +++ b/src/file/document/body/section-properties/section-properties.spec.ts @@ -6,7 +6,7 @@ import { FooterWrapper } from "@file/footer-wrapper"; import { HeaderWrapper } from "@file/header-wrapper"; import { Media } from "@file/media"; import { NumberFormat } from "@file/shared/number-format"; -import { VerticalAlign } from "@file/vertical-align"; +import { VerticalAlignSection } from "@file/vertical-align"; import { convertInchesToTwip } from "@util/convenience-functions"; import { PageOrientation } from "./properties"; @@ -75,7 +75,7 @@ describe("SectionProperties", () => { even: new FooterWrapper(media, 200), }, titlePage: true, - verticalAlign: VerticalAlign.TOP, + verticalAlign: VerticalAlignSection.TOP, }); const tree = new Formatter().format(properties); diff --git a/src/file/document/body/section-properties/section-properties.ts b/src/file/document/body/section-properties/section-properties.ts index 004f2c2cce..9a4c5a3b6c 100644 --- a/src/file/document/body/section-properties/section-properties.ts +++ b/src/file/document/body/section-properties/section-properties.ts @@ -2,7 +2,7 @@ import { FooterWrapper } from "@file/footer-wrapper"; import { HeaderWrapper } from "@file/header-wrapper"; -import { VerticalAlign, VerticalAlignElement } from "@file/vertical-align"; +import { SectionVerticalAlign, VerticalAlignElement } from "@file/vertical-align"; import { OnOffElement, XmlComponent } from "@file/xml-components"; import { Columns, IColumnsAttributes } from "./properties/columns"; @@ -35,7 +35,7 @@ export type ISectionPropertiesOptions = { readonly footerWrapperGroup?: IHeaderFooterGroup; readonly lineNumbers?: ILineNumberAttributes; readonly titlePage?: boolean; - readonly verticalAlign?: (typeof VerticalAlign)[keyof typeof VerticalAlign]; + readonly verticalAlign?: SectionVerticalAlign; readonly column?: IColumnsAttributes; readonly type?: (typeof SectionType)[keyof typeof SectionType]; }; diff --git a/src/file/table/table-cell/table-cell-properties.spec.ts b/src/file/table/table-cell/table-cell-properties.spec.ts index 995459a3c5..dde4ab8d75 100644 --- a/src/file/table/table-cell/table-cell-properties.spec.ts +++ b/src/file/table/table-cell/table-cell-properties.spec.ts @@ -2,7 +2,7 @@ import { describe, expect, it } from "vitest"; import { Formatter } from "@export/formatter"; import { BorderStyle } from "@file/border"; -import { VerticalAlign } from "@file/vertical-align"; +import { VerticalAlignTable } from "@file/vertical-align"; import { WidthType } from "../table-width"; import { VerticalMergeType } from "./table-cell-components"; @@ -32,7 +32,7 @@ describe("TableCellProperties", () => { }); it("sets vertical align", () => { - const properties = new TableCellProperties({ verticalAlign: VerticalAlign.BOTTOM }); + const properties = new TableCellProperties({ verticalAlign: VerticalAlignTable.BOTTOM }); const tree = new Formatter().format(properties); expect(tree).to.deep.equal({ "w:tcPr": [{ "w:vAlign": { _attr: { "w:val": "bottom" } } }] }); }); diff --git a/src/file/table/table-cell/table-cell-properties.ts b/src/file/table/table-cell/table-cell-properties.ts index f9dcb12875..5859f6dbd7 100644 --- a/src/file/table/table-cell/table-cell-properties.ts +++ b/src/file/table/table-cell/table-cell-properties.ts @@ -1,4 +1,4 @@ -import { VerticalAlign, VerticalAlignElement } from "@file/vertical-align"; +import { TableVerticalAlign, VerticalAlignElement } from "@file/vertical-align"; import { IgnoreIfEmptyXmlComponent } from "@file/xml-components"; import { IShadingAttributesProperties, Shading } from "../../shading"; @@ -17,7 +17,7 @@ import { export type ITableCellPropertiesOptions = { readonly shading?: IShadingAttributesProperties; readonly margins?: ITableCellMarginOptions; - readonly verticalAlign?: (typeof VerticalAlign)[keyof typeof VerticalAlign]; + readonly verticalAlign?: TableVerticalAlign; readonly textDirection?: (typeof TextDirection)[keyof typeof TextDirection]; readonly verticalMerge?: (typeof VerticalMergeType)[keyof typeof VerticalMergeType]; readonly width?: ITableWidthProperties; diff --git a/src/file/table/table-cell/table-cell.spec.ts b/src/file/table/table-cell/table-cell.spec.ts index a453a30899..bf712b673b 100644 --- a/src/file/table/table-cell/table-cell.spec.ts +++ b/src/file/table/table-cell/table-cell.spec.ts @@ -3,7 +3,7 @@ import { describe, expect, it } from "vitest"; import { Formatter } from "@export/formatter"; import { BorderStyle } from "@file/border"; import { ShadingType } from "@file/shading"; -import { VerticalAlign } from "@file/vertical-align"; +import { VerticalAlignTable } from "@file/vertical-align"; import { WidthType } from "../table-width"; import { TableCell } from "./table-cell"; @@ -286,7 +286,7 @@ describe("TableCell", () => { it("should create with vertical align", () => { const cell = new TableCell({ children: [], - verticalAlign: VerticalAlign.CENTER, + verticalAlign: VerticalAlignTable.CENTER, }); const tree = new Formatter().format(cell); diff --git a/src/file/vertical-align/vertical-align.ts b/src/file/vertical-align/vertical-align.ts index 7556ae552c..a9d6c66766 100644 --- a/src/file/vertical-align/vertical-align.ts +++ b/src/file/vertical-align/vertical-align.ts @@ -6,17 +6,43 @@ import { XmlAttributeComponent, XmlComponent } from "@file/xml-components"; // // +// // // // // // -export const VerticalAlign = { - BOTTOM: "bottom", - CENTER: "center", + +/** + * Enumeration for table-cell vertical alignment. Only `top`, `center`, `bottom` + * are valid according to ECMA-376 (§17.18.87 ST_VerticalJc within ). + */ +export const VerticalAlignTable = { TOP: "top", + CENTER: "center", + BOTTOM: "bottom", } as const; +/** + * Enumeration for section () vertical alignment. Adds `both` on top of + * the table-cell set (§17.18.87 ST_VerticalJc within ). + */ +export const VerticalAlignSection = { + ...VerticalAlignTable, + BOTH: "both", +} as const; + +/** + * @deprecated Use {@link VerticalAlignTable} for table cells or + * {@link VerticalAlignSection} for section properties. This alias remains for + * backward-compatibility and will be removed in the next major release. + */ +export const VerticalAlign = VerticalAlignSection; + +export type TableVerticalAlign = (typeof VerticalAlignTable)[keyof typeof VerticalAlignTable]; + +export type SectionVerticalAlign = (typeof VerticalAlignSection)[keyof typeof VerticalAlignSection]; + export class VerticalAlignAttributes extends XmlAttributeComponent<{ readonly verticalAlign?: (typeof VerticalAlign)[keyof typeof VerticalAlign]; }> {