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-visualization-block.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@slack/types": minor
---

feat: add `DataVisualizationBlock` type for the [`data_visualization`](https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block) Block Kit block
167 changes: 167 additions & 0 deletions packages/types/src/block-kit/blocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export type KnownBlock =
| ContextBlock
| ContextActionsBlock
| DataTableBlock
| DataVisualizationBlock
| DividerBlock
| FileBlock
| HeaderBlock
Expand Down Expand Up @@ -291,6 +292,172 @@ export interface ContextActionsBlock extends Block {
elements: ContextActionsBlockElement[];
}

/**
* @description A single slice of a {@link DataVisualizationPieChart}.
* @see {@link https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block Data visualization block reference}.
*/
interface DataVisualizationPieSegment {
/**
* @description Display name for this slice, shown in the legend and on hover. Maximum of 20 characters.
*/
label: string;
/**
* @description Numeric weight of this slice. Must be greater than 0. Rendered percentage is the value divided by
* the sum of all segment values.
*/
value: number;
}

/**
* @description A single data point within a {@link DataVisualizationSeries}.
* @see {@link https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block Data visualization block reference}.
*/
interface DataVisualizationDataPoint {
/**
* @description The x-axis category this point belongs to. Must match one of the values in `axis_config.categories`.
* Maximum of 20 characters.
*/
label: string;
/**
* @description Numeric y-axis value. Negative values are permitted.
*/
value: number;
}

/**
* @description A series of data points displayed in a bar, area, or line {@link DataVisualizationBlock} chart.
* @see {@link https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block Data visualization block reference}.
*/
interface DataVisualizationSeries {
/**
* @description Human-readable identifier displayed in the chart legend. Must be unique across all series in the
* same chart. Maximum 20 characters.
*/
name: string;
/**
* @description Ordered data points. Min 1, max 20. Must contain exactly one entry for every label in
* `axis_config.categories`.
*/
data: DataVisualizationDataPoint[];
}

/**
* @description Axis configuration for a bar, area, or line {@link DataVisualizationBlock} chart.
* @see {@link https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block Data visualization block reference}.
*/
interface DataVisualizationAxisConfig {
/**
* @description Category labels for the x-axis. Defines valid labels and their left-to-right display order. Each
* category label has a maximum of 20 characters.
*/
categories: string[];
/**
* @description Descriptive title displayed below the x-axis (e.g., "Time of Day"). Maximum of 50 characters.
*/
x_label?: string;
/**
* @description Descriptive title displayed beside the y-axis (e.g., "Latency (ms)"). Maximum of 50 characters.
*/
y_label?: string;
}

/**
* @description A pie chart for a {@link DataVisualizationBlock}.
* @see {@link https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block Data visualization block reference}.
*/
interface DataVisualizationPieChart {
/**
* @description The type of chart. In this case, `pie`.
*/
type: 'pie';
/**
* @description Labeled slices that make up the pie. Min 1, max 12. Each is a {@link DataVisualizationPieSegment}.
*/
segments: DataVisualizationPieSegment[];
}

/**
* @description A bar chart for a {@link DataVisualizationBlock}.
* @see {@link https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block Data visualization block reference}.
*/
interface DataVisualizationBarChart {
/**
* @description The type of chart. In this case, `bar`.
*/
type: 'bar';
/**
* @description Series to plot as bar groups. Min 1, max 12. For multiple series, bars are grouped by label. Each is
* a {@link DataVisualizationSeries}.
*/
series: DataVisualizationSeries[];
/**
* @description X-axis categories and axis titles. See {@link DataVisualizationAxisConfig}.
*/
axis_config: DataVisualizationAxisConfig;
}

/**
* @description An area chart for a {@link DataVisualizationBlock}.
* @see {@link https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block Data visualization block reference}.
*/
interface DataVisualizationAreaChart {
/**
* @description The type of chart. In this case, `area`.
*/
type: 'area';
/**
* @description Series to plot as filled areas. Min 1, max 12. Series are layered in array order (first at back).
* Each is a {@link DataVisualizationSeries}.
*/
series: DataVisualizationSeries[];
/**
* @description X-axis categories and axis titles. See {@link DataVisualizationAxisConfig}.
*/
axis_config: DataVisualizationAxisConfig;
}

/**
* @description A line chart for a {@link DataVisualizationBlock}.
* @see {@link https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block Data visualization block reference}.
*/
interface DataVisualizationLineChart {
/**
* @description The type of chart. In this case, `line`.
*/
type: 'line';
/**
* @description Series to plot as lines. Min 1, max 12. Each is a {@link DataVisualizationSeries}.
*/
series: DataVisualizationSeries[];
/**
* @description X-axis categories and axis titles. See {@link DataVisualizationAxisConfig}.
*/
axis_config: DataVisualizationAxisConfig;
}

/**
* @description Displays a chart visualizing a dataset, such as a pie, bar, area, or line chart.
* @see {@link https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block Data visualization block reference}.
*/
export interface DataVisualizationBlock extends Block {
/**
* @description The type of block. For a data visualization block, `type` is always `data_visualization`.
*/
type: 'data_visualization';
/**
* @description A short label displayed above the chart. Maximum 50 characters.
*/
title: string;
/**
* @description The chart-specific payload. Must be one of the following: `pie`, `bar`, `area`, or `line`.
*/
chart:
| DataVisualizationPieChart
| DataVisualizationBarChart
| DataVisualizationAreaChart
| DataVisualizationLineChart;
}

/**
* @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}.
Expand Down
88 changes: 87 additions & 1 deletion packages/types/test/blocks.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { expectAssignable, expectError } from 'tsd';
import type { AlertBlock, CardBlock, CarouselBlock, ContainerBlock, DataTableBlock, KnownBlock } from '../src/index';
import type {
AlertBlock,
CardBlock,
CarouselBlock,
ContainerBlock,
DataTableBlock,
DataVisualizationBlock,
KnownBlock,
} from '../src/index';

// CardBlock
// -- sad path
Expand Down Expand Up @@ -103,6 +111,84 @@ expectAssignable<KnownBlock>({
child_blocks: [{ type: 'divider' }],
});

// DataVisualizationBlock
// -- sad path
expectError<DataVisualizationBlock>({}); // missing type, title and chart
expectError<DataVisualizationBlock>({ type: 'data_visualization', title: 'Sales' }); // missing required chart
expectError<DataVisualizationBlock>({
type: 'data_visualization',
title: 'Sales',
chart: { type: 'pie' }, // pie chart missing required segments
});
expectError<DataVisualizationBlock>({
type: 'data_visualization',
title: 'Sales',
chart: { type: 'bar', series: [{ name: 'Q1', data: [{ label: 'Jan', value: 1 }] }] }, // series chart missing axis_config
});
expectError<DataVisualizationBlock>({
type: 'data_visualization',
title: 'Sales',
chart: { type: 'scatter', segments: [{ label: 'A', value: 1 }] }, // unknown chart type
});
// -- happy path
expectAssignable<DataVisualizationBlock>({
type: 'data_visualization',
title: 'Revenue by region',
chart: {
type: 'pie',
segments: [
{ label: 'North', value: 40 },
{ label: 'South', value: 60 },
],
},
});
expectAssignable<DataVisualizationBlock>({
type: 'data_visualization',
title: 'Quarterly revenue',
block_id: 'viz_1',
chart: {
type: 'bar',
series: [
{
name: 'Product A',
data: [
{ label: 'Q1', value: 10 },
{ label: 'Q2', value: 20 },
],
},
{
name: 'Product B',
data: [
{ label: 'Q1', value: 5 },
{ label: 'Q2', value: -3 },
],
},
],
axis_config: { categories: ['Q1', 'Q2'], x_label: 'Quarter', y_label: 'Revenue' },
},
});
expectAssignable<DataVisualizationBlock>({
type: 'data_visualization',
title: 'Daily active users',
chart: {
type: 'area',
series: [
{ name: 'Free tier', data: [{ label: 'Mon', value: 12000 }] },
{ name: 'Paid tier', data: [{ label: 'Mon', value: 4500 }] },
],
axis_config: { categories: ['Mon'], x_label: 'Day', y_label: 'Users' },
},
});
expectAssignable<KnownBlock>({
type: 'data_visualization',
title: 'Trend',
chart: {
type: 'line',
series: [{ name: 'Users', data: [{ label: 'Mon', value: 1 }] }],
axis_config: { categories: ['Mon'] },
},
});

// DataTableBlock
// -- sad path
expectError<DataTableBlock>({}); // missing type, rows, and caption
Expand Down