From 56815fbb94e723d48e4c9afb5d88114708a3b385 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Fri, 26 Jun 2026 16:45:43 -0700 Subject: [PATCH 1/9] feat(types): add data_table Block Kit block Add the `data_table` block (`DataTableBlock`) and the `raw_number` cell composition object (`RawNumberElement`) used for numeric, sortable cells. The block is added to the `KnownBlock` union and covered by tsd type tests. Ref: https://docs.slack.dev/reference/block-kit/blocks/data-table-block Co-Authored-By: Claude --- .changeset/data-table-block.md | 5 ++ packages/types/src/block-kit/blocks.ts | 38 ++++++++++++++ .../src/block-kit/composition-objects.ts | 19 +++++++ packages/types/test/blocks.test-d.ts | 52 ++++++++++++++++++- 4 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 .changeset/data-table-block.md diff --git a/.changeset/data-table-block.md b/.changeset/data-table-block.md new file mode 100644 index 000000000..0aa292665 --- /dev/null +++ b/.changeset/data-table-block.md @@ -0,0 +1,5 @@ +--- +"@slack/types": minor +--- + +feat: add `data_table` Block Kit block type (`DataTableBlock`) and the `raw_number` cell composition object (`RawNumberElement`) diff --git a/packages/types/src/block-kit/blocks.ts b/packages/types/src/block-kit/blocks.ts index 60ab5166c..8e0360d9d 100644 --- a/packages/types/src/block-kit/blocks.ts +++ b/packages/types/src/block-kit/blocks.ts @@ -28,6 +28,7 @@ import type { import type { MrkdwnElement, PlainTextElement, + RawNumberElement, RawTextElement, SlackFileImageObject, TextObject, @@ -61,6 +62,7 @@ export type KnownBlock = | ContainerBlock | ContextBlock | ContextActionsBlock + | DataTableBlock | DividerBlock | FileBlock | HeaderBlock @@ -289,6 +291,42 @@ export interface ContextActionsBlock extends Block { elements: ContextActionsBlockElement[]; } +/** + * A helper union type of all cell types that can be used in a {@link DataTableBlock} row. Cells can be of type + * `raw_text`, `raw_number`, or `rich_text`. Note that `rich_text` cells are not allowed in the header row. + */ +export type DataTableCell = RawTextElement | RawNumberElement | RichTextBlock; + +/** + * @description Displays structured, sortable, and paginated data in a table. + * @see {@link https://docs.slack.dev/reference/block-kit/blocks/data-table-block Data table block reference}. + */ +export interface DataTableBlock extends Block { + /** + * @description The type of block. For a data table block, `type` is always `data_table`. + */ + type: 'data_table'; + /** + * @description An array consisting of table rows, where the first row is the header row. Each row is an array of + * cells of type `raw_text`, `raw_number`, or `rich_text`. Minimum 2 rows (a header and one data row) and maximum 101 + * rows (a header and 100 data rows). Each row must contain the same number of cells, with a minimum of 1 and a maximum + * of 20 columns. The `rich_text` cell type is not allowed in the header row. + */ + rows: DataTableCell[][]; + /** + * @description A description of the table used for the underlying HTML element. + */ + caption: string; + /** + * @description The number of rows to display per page. Minimum 1, maximum 100. Defaults to 5 if not provided. + */ + page_size?: number; + /** + * @description The zero-based index of the column used as the row identifier. Defaults to 0 if not provided. + */ + row_header_column_index?: number; +} + /** * @description Visually separates pieces of info inside of a message. A content divider, like an `
`, to split up * different blocks inside of a message. The divider block is nice and neat, requiring only a `type`. diff --git a/packages/types/src/block-kit/composition-objects.ts b/packages/types/src/block-kit/composition-objects.ts index 886830344..59e607226 100644 --- a/packages/types/src/block-kit/composition-objects.ts +++ b/packages/types/src/block-kit/composition-objects.ts @@ -188,6 +188,25 @@ export interface RawTextElement { text: string; } +/** + * @description Defines an object containing a numeric value and its display text. Used for numeric cells in a + * {@link DataTableBlock}, allowing the column to be sorted numerically. + */ +export interface RawNumberElement { + /** + * @description The formatting to use for this object. + */ + type: 'raw_number'; + /** + * @description The numeric value used for sorting the column. + */ + value: number; + /** + * @description The text used to display the value. The minimum length is 1 character. + */ + text: string; +} + interface BaseConversationFilter { /** * @description Indicates which type of conversations should be included in the list. When this field is provided, any diff --git a/packages/types/test/blocks.test-d.ts b/packages/types/test/blocks.test-d.ts index 3169703e5..421941b23 100644 --- a/packages/types/test/blocks.test-d.ts +++ b/packages/types/test/blocks.test-d.ts @@ -1,5 +1,5 @@ import { expectAssignable, expectError } from 'tsd'; -import type { AlertBlock, CardBlock, CarouselBlock, ContainerBlock, KnownBlock } from '../src/index'; +import type { AlertBlock, CardBlock, CarouselBlock, ContainerBlock, DataTableBlock, KnownBlock } from '../src/index'; // CardBlock // -- sad path @@ -102,3 +102,53 @@ expectAssignable({ title: { type: 'plain_text', text: 'Known' }, child_blocks: [{ type: 'divider' }], }); + +// DataTableBlock +// -- sad path +expectError({}); // missing type, rows, and caption +expectError({ type: 'data_table' }); // missing required rows and caption +expectError({ + type: 'data_table', + rows: [[{ type: 'raw_text', text: 'Name' }]], +}); // missing required caption +expectError({ + type: 'data_table', + caption: 'A list of fruit and their quantities', +}); // missing required rows +// -- happy path +expectAssignable({ + type: 'data_table', + caption: 'A list of fruit and their quantities', + rows: [ + [ + { type: 'raw_text', text: 'Fruit' }, + { type: 'raw_text', text: 'Quantity' }, + ], + [ + { type: 'raw_text', text: 'Apples' }, + { type: 'raw_number', value: 12, text: '12' }, + ], + ], +}); +expectAssignable({ + type: 'data_table', + caption: 'A list of users', + block_id: 'users_table', + page_size: 10, + row_header_column_index: 0, + rows: [ + [ + { type: 'raw_text', text: 'User' }, + { type: 'raw_text', text: 'Bio' }, + ], + [ + { type: 'raw_text', text: 'Mark' }, + { type: 'rich_text', elements: [{ type: 'rich_text_section', elements: [{ type: 'text', text: 'Founder' }] }] }, + ], + ], +}); +expectAssignable({ + type: 'data_table', + caption: 'A minimal table', + rows: [[{ type: 'raw_text', text: 'Header' }], [{ type: 'raw_text', text: 'Value' }]], +}); From e2e26ff1c7c869d96bc65aa1c8a2b72904208de0 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Tue, 8 Sep 2026 14:25:46 -0700 Subject: [PATCH 2/9] fix(types): correct data_table max row count to 201 (200 data rows) The DataTableBlock.rows docstring stated a maximum of 101 rows (100 data rows), but the Block Kit reference documents a maximum of 201 rows (a header row plus 200 data rows). The 100 cap was the page_size maximum, not the row maximum. Align the docstring with docs.slack.dev. Co-Authored-By: Claude --- packages/types/src/block-kit/blocks.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/types/src/block-kit/blocks.ts b/packages/types/src/block-kit/blocks.ts index 8e0360d9d..16e23d0b2 100644 --- a/packages/types/src/block-kit/blocks.ts +++ b/packages/types/src/block-kit/blocks.ts @@ -308,8 +308,8 @@ export interface DataTableBlock extends Block { type: 'data_table'; /** * @description An array consisting of table rows, where the first row is the header row. Each row is an array of - * cells of type `raw_text`, `raw_number`, or `rich_text`. Minimum 2 rows (a header and one data row) and maximum 101 - * rows (a header and 100 data rows). Each row must contain the same number of cells, with a minimum of 1 and a maximum + * cells of type `raw_text`, `raw_number`, or `rich_text`. Minimum 2 rows (a header and one data row) and maximum 201 + * rows (a header and 200 data rows). Each row must contain the same number of cells, with a minimum of 1 and a maximum * of 20 columns. The `rich_text` cell type is not allowed in the header row. */ rows: DataTableCell[][]; From 66d420cfb5651752ff73574e3bb665929dc474f6 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Tue, 8 Sep 2026 14:46:50 -0700 Subject: [PATCH 3/9] refactor(types): inline DataTableCell union into DataTableBlock.rows The DataTableCell alias had a single use site and was not referenced anywhere else, so inline the union directly on `rows` and drop the exported helper type. Co-Authored-By: Claude --- packages/types/src/block-kit/blocks.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/types/src/block-kit/blocks.ts b/packages/types/src/block-kit/blocks.ts index 16e23d0b2..f773bf194 100644 --- a/packages/types/src/block-kit/blocks.ts +++ b/packages/types/src/block-kit/blocks.ts @@ -291,12 +291,6 @@ export interface ContextActionsBlock extends Block { elements: ContextActionsBlockElement[]; } -/** - * A helper union type of all cell types that can be used in a {@link DataTableBlock} row. Cells can be of type - * `raw_text`, `raw_number`, or `rich_text`. Note that `rich_text` cells are not allowed in the header row. - */ -export type DataTableCell = RawTextElement | RawNumberElement | RichTextBlock; - /** * @description Displays structured, sortable, and paginated data in a table. * @see {@link https://docs.slack.dev/reference/block-kit/blocks/data-table-block Data table block reference}. @@ -312,7 +306,7 @@ export interface DataTableBlock extends Block { * rows (a header and 200 data rows). Each row must contain the same number of cells, with a minimum of 1 and a maximum * of 20 columns. The `rich_text` cell type is not allowed in the header row. */ - rows: DataTableCell[][]; + rows: (RawTextElement | RawNumberElement | RichTextBlock)[][]; /** * @description A description of the table used for the underlying HTML element. */ From 6ca2d469d663d9a627548aec2be90a40fdc7cbcb Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Tue, 8 Sep 2026 14:51:06 -0700 Subject: [PATCH 4/9] docs(types): re-sync DataTableBlock JSDoc to docs + refine changeset Align the DataTableBlock summary and every field @description with the data-table-block reference page, and scope the changeset to the block itself (link + name), each comment on a single line. Co-Authored-By: Claude --- .changeset/data-table-block.md | 2 +- packages/types/src/block-kit/blocks.ts | 13 +++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/.changeset/data-table-block.md b/.changeset/data-table-block.md index 0aa292665..7b6f6b733 100644 --- a/.changeset/data-table-block.md +++ b/.changeset/data-table-block.md @@ -2,4 +2,4 @@ "@slack/types": minor --- -feat: add `data_table` Block Kit block type (`DataTableBlock`) and the `raw_number` cell composition object (`RawNumberElement`) +feat: add the [`data_table`](https://docs.slack.dev/reference/block-kit/blocks/data-table-block) Block Kit block type (`DataTableBlock`) diff --git a/packages/types/src/block-kit/blocks.ts b/packages/types/src/block-kit/blocks.ts index f773bf194..39fdc8c78 100644 --- a/packages/types/src/block-kit/blocks.ts +++ b/packages/types/src/block-kit/blocks.ts @@ -292,7 +292,7 @@ export interface ContextActionsBlock extends Block { } /** - * @description Displays structured, sortable, and paginated data in a table. + * @description Displays rich tables that support pagination, sorting, filtering, and interactivity. * @see {@link https://docs.slack.dev/reference/block-kit/blocks/data-table-block Data table block reference}. */ export interface DataTableBlock extends Block { @@ -301,22 +301,19 @@ export interface DataTableBlock extends Block { */ type: 'data_table'; /** - * @description An array consisting of table rows, where the first row is the header row. Each row is an array of - * cells of type `raw_text`, `raw_number`, or `rich_text`. Minimum 2 rows (a header and one data row) and maximum 201 - * rows (a header and 200 data rows). Each row must contain the same number of cells, with a minimum of 1 and a maximum - * of 20 columns. The `rich_text` cell type is not allowed in the header row. + * @description An array consisting of table rows. The first row is the header row, and `rich_text` cannot be used for header cells. Cells can be of type `raw_text`, `raw_number`, or `rich_text`. There must be a minimum of 2 rows (1 regular row plus the header) and a maximum of 201 rows (200 regular rows plus the header), a minimum of 1 column and a maximum of 20 columns, and all rows must have the same number of values. A single table's character count across all cells cannot exceed 20,000 characters. */ rows: (RawTextElement | RawNumberElement | RichTextBlock)[][]; /** - * @description A description of the table used for the underlying HTML element. + * @description A caption for the table; used as the value for the HTML caption element. */ caption: string; /** - * @description The number of rows to display per page. Minimum 1, maximum 100. Defaults to 5 if not provided. + * @description The number of rows per page. Min `1`, max `100`. Defaults to `5` if omitted. */ page_size?: number; /** - * @description The zero-based index of the column used as the row identifier. Defaults to 0 if not provided. + * @description The 0-based index of the column that uniquely identifies each row (the row header). This column is treated as the row's primary identifier for screen readers. Defaults to `0` if omitted. */ row_header_column_index?: number; } From bfd83d396c80fcae12834b85738d0b3308b2b478 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Tue, 8 Sep 2026 14:55:51 -0700 Subject: [PATCH 5/9] docs(types): match page_size description to docs verbatim Use the reference page's exact wording ("Number of rows per page. Min `1`, Max `100`. Defaults to `5` if omitted."). Co-Authored-By: Claude --- packages/types/src/block-kit/blocks.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/types/src/block-kit/blocks.ts b/packages/types/src/block-kit/blocks.ts index 39fdc8c78..f157f5448 100644 --- a/packages/types/src/block-kit/blocks.ts +++ b/packages/types/src/block-kit/blocks.ts @@ -309,7 +309,7 @@ export interface DataTableBlock extends Block { */ caption: string; /** - * @description The number of rows per page. Min `1`, max `100`. Defaults to `5` if omitted. + * @description Number of rows per page. Min `1`, Max `100`. Defaults to `5` if omitted. */ page_size?: number; /** From 5f47f4bc6d6fb5454b1b90adf757bf8e2d5d5581 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Tue, 8 Sep 2026 14:59:34 -0700 Subject: [PATCH 6/9] refactor(types): order RawNumberElement before RawTextElement alphabetically Place the new raw cell element pair in alphabetical order (Number before Text) as the intended ordering for composition objects going forward. Surrounding definitions are left untouched. Co-Authored-By: Claude --- .../src/block-kit/composition-objects.ts | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/types/src/block-kit/composition-objects.ts b/packages/types/src/block-kit/composition-objects.ts index 59e607226..beaf0814d 100644 --- a/packages/types/src/block-kit/composition-objects.ts +++ b/packages/types/src/block-kit/composition-objects.ts @@ -173,21 +173,6 @@ export interface MrkdwnElement { verbatim?: boolean; } -/** - * @description Defines an object containing some text. - * @see {@link https://docs.slack.dev/reference/block-kit/composition-objects/text-object Text object reference}. - */ -export interface RawTextElement { - /** - * @description The formatting to use for this text object. - */ - type: 'raw_text'; - /** - * @description The text for the block. The minimum length is 1 character. - */ - text: string; -} - /** * @description Defines an object containing a numeric value and its display text. Used for numeric cells in a * {@link DataTableBlock}, allowing the column to be sorted numerically. @@ -207,6 +192,21 @@ export interface RawNumberElement { text: string; } +/** + * @description Defines an object containing some text. + * @see {@link https://docs.slack.dev/reference/block-kit/composition-objects/text-object Text object reference}. + */ +export interface RawTextElement { + /** + * @description The formatting to use for this text object. + */ + type: 'raw_text'; + /** + * @description The text for the block. The minimum length is 1 character. + */ + text: string; +} + interface BaseConversationFilter { /** * @description Indicates which type of conversations should be included in the list. When this field is provided, any From 449525e3d5f9681196d1c60903f348ca0302dfea Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Tue, 8 Sep 2026 15:14:37 -0700 Subject: [PATCH 7/9] docs(types): trim DataTableBlock.rows @description to the essentials The rows field's @description had grown into the full docs Fields-table paragraph (row/column min-max, character cap). Those are runtime API limits, not part of the TS type contract, and the cell-type list just restated the union already in the type. Trim to the lead sentence plus the one type-inexpressible constraint: rich_text can't be a header cell. Matches the terse one-sentence @description style of the sibling fields. Co-Authored-By: Claude --- packages/types/src/block-kit/blocks.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/types/src/block-kit/blocks.ts b/packages/types/src/block-kit/blocks.ts index f157f5448..45813eb82 100644 --- a/packages/types/src/block-kit/blocks.ts +++ b/packages/types/src/block-kit/blocks.ts @@ -301,7 +301,7 @@ export interface DataTableBlock extends Block { */ type: 'data_table'; /** - * @description An array consisting of table rows. The first row is the header row, and `rich_text` cannot be used for header cells. Cells can be of type `raw_text`, `raw_number`, or `rich_text`. There must be a minimum of 2 rows (1 regular row plus the header) and a maximum of 201 rows (200 regular rows plus the header), a minimum of 1 column and a maximum of 20 columns, and all rows must have the same number of values. A single table's character count across all cells cannot exceed 20,000 characters. + * @description An array consisting of table rows. The first row is the header row, for which `rich_text` cannot be used. */ rows: (RawTextElement | RawNumberElement | RichTextBlock)[][]; /** From d6fca16fa0225d7c6c7d8dcef0febdecfc959f47 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Tue, 8 Sep 2026 15:46:39 -0700 Subject: [PATCH 8/9] docs(types): match DataTableBlock.rows @description to the docs verbatim The docs Fields-table Description cell for `rows` is exactly "An array consisting of table rows." The header-row / rich_text constraint lives in the page's usage prose, not the field's Description cell, so it stays out of the @description. Keep the SDK comment to what the docs field description says, nothing added. Co-Authored-By: Claude --- packages/types/src/block-kit/blocks.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/types/src/block-kit/blocks.ts b/packages/types/src/block-kit/blocks.ts index 45813eb82..20cd9561c 100644 --- a/packages/types/src/block-kit/blocks.ts +++ b/packages/types/src/block-kit/blocks.ts @@ -301,7 +301,7 @@ export interface DataTableBlock extends Block { */ type: 'data_table'; /** - * @description An array consisting of table rows. The first row is the header row, for which `rich_text` cannot be used. + * @description An array consisting of table rows. */ rows: (RawTextElement | RawNumberElement | RichTextBlock)[][]; /** From 377813d6b9743cd3837d4970640b7dbc7bfb8a5f Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Tue, 8 Sep 2026 16:05:46 -0700 Subject: [PATCH 9/9] docs(types): simplify RawNumberElement descriptions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop the invented tails on RawNumberElement's @descriptions (display text / DataTableBlock sorting framing on the object, "used for sorting the column" on value) that the docs don't carry — the docs describe raw_number minimally (numeric value; type enum; a number; text min length 1). Mirror the terse RawTextElement sibling: an object line, a "formatting to use for this numeric object" type line, and a bare value line. text keeps its display-text + min-length note. Co-Authored-By: Claude --- packages/types/src/block-kit/composition-objects.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/types/src/block-kit/composition-objects.ts b/packages/types/src/block-kit/composition-objects.ts index beaf0814d..b36d1cf50 100644 --- a/packages/types/src/block-kit/composition-objects.ts +++ b/packages/types/src/block-kit/composition-objects.ts @@ -174,16 +174,15 @@ export interface MrkdwnElement { } /** - * @description Defines an object containing a numeric value and its display text. Used for numeric cells in a - * {@link DataTableBlock}, allowing the column to be sorted numerically. + * @description Defines an object containing a numeric value. */ export interface RawNumberElement { /** - * @description The formatting to use for this object. + * @description The formatting to use for this numeric object. */ type: 'raw_number'; /** - * @description The numeric value used for sorting the column. + * @description The numeric value. */ value: number; /**