Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/data-table-action-cell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@slack/types": minor
---

feat(types): support `action_cell` cells in [`data_table`](https://docs.slack.dev/reference/block-kit/blocks/data-table-block) block rows with the new `ActionCellElement` type
3 changes: 2 additions & 1 deletion packages/types/src/block-kit/blocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import type {
WorkflowButton,
} from './block-elements';
import type {
ActionCellElement,
MrkdwnElement,
PlainTextElement,
RawNumberElement,
Expand Down Expand Up @@ -369,7 +370,7 @@ export interface DataTableBlock extends Block {
/**
* @description An array consisting of table rows.
*/
rows: (RawTextElement | RawNumberElement | RichTextBlock)[][];
rows: (ActionCellElement | RawTextElement | RawNumberElement | RichTextBlock)[][];
/**
* @description A caption for the table; used as the value for the HTML caption element.
*/
Expand Down
21 changes: 21 additions & 0 deletions packages/types/src/block-kit/composition-objects.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// This file contains objects documented here: https://docs.slack.dev/reference/block-kit/composition-objects

import type { Button } from './block-elements';

/**
* Re-usable labels for common color schemes present in Slack. `danger` displays with a red background (red text on
* mobile), while `primary` displays with a green background (green text on mobile).
Expand Down Expand Up @@ -173,6 +175,25 @@ export interface MrkdwnElement {
verbatim?: boolean;
}

/**
* @description Defines a data table cell containing a button element.
* @see {@link https://docs.slack.dev/reference/block-kit/blocks/data-table-block#schema-action-cell Action cell reference}.
*/
export interface ActionCellElement {
/**
* @description The type of cell. In this case `type` is always `action_cell`.
*/
type: 'action_cell';
/**
* @description A button element.
*/
element: Button;
/**
* @description A raw_text or raw_number cell.
*/
fallback?: RawTextElement | RawNumberElement;
}

/**
* @description Defines an object containing a numeric value.
*/
Expand Down
71 changes: 71 additions & 0 deletions packages/types/test/blocks.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,14 @@ expectError<DataTableBlock>({
type: 'data_table',
caption: 'A list of fruit and their quantities',
}); // missing required rows
expectError<DataTableBlock>({
type: 'data_table',
caption: 'A list of tasks',
rows: [
[{ type: 'raw_text', text: 'Action' }],
[{ type: 'action_cell', fallback: { type: 'raw_text', text: 'Open' } }],
],
}); // action_cell missing required element
// -- happy path
expectAssignable<DataTableBlock>({
type: 'data_table',
Expand Down Expand Up @@ -211,6 +219,51 @@ expectAssignable<DataTableBlock>({
],
],
});
expectAssignable<DataTableBlock>({
type: 'data_table',
caption: 'A list of tasks',
rows: [
[
{ type: 'raw_text', text: 'Task' },
{ type: 'raw_text', text: 'Action' },
],
[
{ type: 'raw_text', text: 'Write docs' },
{
type: 'action_cell',
element: {
type: 'button',
text: { type: 'plain_text', text: 'Mark done' },
action_id: 'mark_done',
value: 'task_123',
},
fallback: { type: 'raw_text', text: 'Open' },
},
],
],
});
expectAssignable<DataTableBlock>({
type: 'data_table',
caption: 'A list of tasks',
rows: [
[
{ type: 'raw_text', text: 'Task' },
{ type: 'raw_text', text: 'Action' },
],
[
{ type: 'raw_text', text: 'Write docs' },
{
type: 'action_cell',
element: {
type: 'button',
text: { type: 'plain_text', text: 'Mark done' },
action_id: 'mark_done',
value: 'task_123',
},
},
],
],
});
expectAssignable<KnownBlock>({
type: 'data_table',
caption: 'A minimal table',
Expand All @@ -221,6 +274,24 @@ expectAssignable<KnownBlock>({
// -- sad path
expectError<TableBlock>({}); // missing type and rows
expectError<TableBlock>({ type: 'table' }); // missing required rows
expectError<TableBlock>({
type: 'table',
rows: [
[{ type: 'raw_text', text: 'Action' }],
[
{
type: 'action_cell',
element: {
type: 'button',
text: { type: 'plain_text', text: 'Mark done' },
action_id: 'mark_done',
value: 'task_123',
},
fallback: { type: 'raw_text', text: 'Open' },
},
],
],
}); // action_cell is only allowed in data_table
// -- happy path
// Table cells can be rich_text, raw_text, or raw_number; column_settings describe column behavior.
expectAssignable<TableBlock>({
Expand Down
43 changes: 42 additions & 1 deletion packages/types/test/composition-objects.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,46 @@
import { expectAssignable, expectError } from 'tsd';
import type { RawNumberElement, RawTextElement } from '../src/index';
import type { ActionCellElement, RawNumberElement, RawTextElement } from '../src/index';

// ActionCellElement
// -- sad path
expectError<ActionCellElement>({}); // missing type and element
expectError<ActionCellElement>({ type: 'action_cell' }); // missing required element
expectError<ActionCellElement>({ type: 'action_cell', fallback: { type: 'raw_text', text: 'Open' } }); // missing required element
expectError<ActionCellElement>({
type: 'action_cell',
element: { type: 'button', text: { type: 'plain_text', text: 'Mark done' } },
fallback: { type: 'rich_text', elements: [] },
}); // fallback must be raw_text or raw_number
// -- happy path
expectAssignable<ActionCellElement>({
type: 'action_cell',
element: {
type: 'button',
text: { type: 'plain_text', text: 'Mark done' },
action_id: 'mark_done',
value: 'task_123',
},
fallback: { type: 'raw_text', text: 'Open' },
});
expectAssignable<ActionCellElement>({
type: 'action_cell',
element: {
type: 'button',
text: { type: 'plain_text', text: 'Mark done' },
action_id: 'mark_done',
value: 'task_123',
},
fallback: { type: 'raw_number', value: 1, text: '1' },
});
expectAssignable<ActionCellElement>({
type: 'action_cell',
element: {
type: 'button',
text: { type: 'plain_text', text: 'Mark done' },
action_id: 'mark_done',
value: 'task_123',
},
});

// RawNumberElement
// -- sad path
Expand Down
Loading