slackblock 1.1.0 → 2.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +62 -0
- package/README.md +227 -68
- package/dist/block.cjs +79 -124
- package/dist/block.cjs.map +1 -1
- package/dist/{block.d.mts → block.d.cts} +128 -92
- package/dist/block.d.ts +128 -92
- package/dist/block.mjs +80 -114
- package/dist/block.mjs.map +1 -1
- package/dist/index.cjs +250 -143
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +22 -0
- package/dist/index.d.ts +19 -4
- package/dist/index.mjs +243 -133
- package/dist/index.mjs.map +1 -1
- package/dist/jsx-dev-runtime.cjs +43 -0
- package/dist/jsx-dev-runtime.cjs.map +1 -0
- package/dist/jsx-dev-runtime.d.cts +1 -0
- package/dist/jsx-dev-runtime.d.ts +1 -0
- package/dist/jsx-dev-runtime.mjs +15 -0
- package/dist/jsx-dev-runtime.mjs.map +1 -0
- package/dist/jsx-runtime.cjs +46 -0
- package/dist/jsx-runtime.cjs.map +1 -0
- package/dist/jsx-runtime.d.cts +28 -0
- package/dist/jsx-runtime.d.ts +28 -0
- package/dist/jsx-runtime.mjs +19 -0
- package/dist/jsx-runtime.mjs.map +1 -0
- package/dist/{types.d-0WEt-h92.d.mts → types.d-BHoTwZUO.d.cts} +11 -11
- package/dist/{types.d-0WEt-h92.d.ts → types.d-BHoTwZUO.d.ts} +11 -11
- package/package.json +35 -30
- package/dist/index.d.mts +0 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,58 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.0.0-beta.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 2dc3b09: Fixes included files
|
|
8
|
+
|
|
9
|
+
## 2.0.0-beta.0
|
|
10
|
+
|
|
11
|
+
### Major Changes
|
|
12
|
+
|
|
13
|
+
- e243699: ---
|
|
14
|
+
|
|
15
|
+
React dependency removed — migrate jsxImportSource to "slackblock"
|
|
16
|
+
|
|
17
|
+
In your tsconfig.json, change:
|
|
18
|
+
"jsxImportSource": "react" → "jsxImportSource": "slackblock"
|
|
19
|
+
|
|
20
|
+
Remove react / react-dom from your dependencies. No JSX syntax changes required.
|
|
21
|
+
|
|
22
|
+
***
|
|
23
|
+
|
|
24
|
+
Breaking changes:
|
|
25
|
+
- React peer dependency dropped; replaced with a zero-dependency custom JSX runtime
|
|
26
|
+
- @slack/web-api runtime dependency removed; Slack types are now bundled locally
|
|
27
|
+
- Node.js >=20 required (previously >=18 was tolerated in practice)
|
|
28
|
+
- render() now defaults to validate: 'warn', emitting console warnings when output
|
|
29
|
+
would violate Slack Block Kit limits (text too long, too many options, etc.).
|
|
30
|
+
Pass { validate: 'off' } to suppress all warnings.
|
|
31
|
+
|
|
32
|
+
New API:
|
|
33
|
+
- renderToBlocks(element, options?) — returns Block[] directly; use for modals and
|
|
34
|
+
home tabs where no <Message> wrapper is needed. Fragments are unwrapped transparently.
|
|
35
|
+
- renderToMessage(element, options?) — named alias for render(); both are equivalent.
|
|
36
|
+
- blockKitBuilderUrl(blocks) — generates a Block Kit Builder preview URL for a block array.
|
|
37
|
+
- escapeMrkdwn(text) — escapes Slack mrkdwn special characters in plain text strings.
|
|
38
|
+
- validate option on render() / renderToBlocks() / renderToMessage():
|
|
39
|
+
'warn' (default) — console.warn on limit violations
|
|
40
|
+
'strict' — throws SlackblockValidationError on any violation
|
|
41
|
+
'off' — no validation
|
|
42
|
+
- SlackblockValidationError — structured error with .path, .rule, and .message fields.
|
|
43
|
+
- RenderOptions and ValidationMode types exported from package root.
|
|
44
|
+
|
|
45
|
+
Other improvements:
|
|
46
|
+
- strictNullChecks enabled; zero `any` types in source
|
|
47
|
+
- All public components and render functions have JSDoc
|
|
48
|
+
- Component reference at docs/components.md
|
|
49
|
+
- Validation guide at docs/validation.md
|
|
50
|
+
- Migration guides from jsx-slack and slack-block-builder at docs/migrating-\*.md
|
|
51
|
+
- 12 Block Kit JSON samples in examples/block-kit/ covering all validatable components
|
|
52
|
+
- Changesets-based release automation with npm provenance
|
|
53
|
+
|
|
3
54
|
### 1.1.0
|
|
55
|
+
|
|
4
56
|
- Drop `@slack/web-api` runtime dependency; types replicated locally
|
|
5
57
|
- Lower Node engine requirement to `>=20` (from `>=24`)
|
|
6
58
|
- Add CI matrix for Node 20, 22, and 24
|
|
@@ -11,6 +63,7 @@
|
|
|
11
63
|
- Fix publish hygiene: delete `.npmignore`, rename `prepublish` → `prepublishOnly`
|
|
12
64
|
|
|
13
65
|
### 1.0.1
|
|
66
|
+
|
|
14
67
|
- Upgrade `@slack/web-api` to 7.14.1 (resolves CVE-2026-25639 via axios upgrade)
|
|
15
68
|
- Bump `rollup` to 4.59.0 (resolves CVE-2026-27606)
|
|
16
69
|
- Bump `minimatch` to 10.2.3+ (resolves CVE-2026-27904, CVE-2026-27903, CVE-2026-26996)
|
|
@@ -18,6 +71,7 @@
|
|
|
18
71
|
- Resolve CVE-2026-25547 via minimatch 10.2.3+ (replaces @isaacs/brace-expansion)
|
|
19
72
|
|
|
20
73
|
### 1.0.0
|
|
74
|
+
|
|
21
75
|
- Modernize tooling (Node 24, pnpm, tsup, Vitest, XO, Husky + lint-staged)
|
|
22
76
|
- Stabilize parser/transformer routing and align output types to serialized JSON
|
|
23
77
|
- Expand Block Kit coverage (header, rich_text, video, checkboxes, time/datetime pickers)
|
|
@@ -25,26 +79,34 @@
|
|
|
25
79
|
- Add validation warnings for Slack limits
|
|
26
80
|
|
|
27
81
|
### 0.4.0
|
|
82
|
+
|
|
28
83
|
- Allow for `<Section/>` blocks to have `null` components (useful for conditional renders)
|
|
29
84
|
|
|
30
85
|
### 0.3.1
|
|
86
|
+
|
|
31
87
|
- Fix issue that caused an error to be thrown if a child is `null`
|
|
32
88
|
|
|
33
89
|
### 0.3.0
|
|
90
|
+
|
|
34
91
|
- Add `Container` block to allow for better conditional rendering
|
|
35
92
|
|
|
36
93
|
### 0.2.0
|
|
94
|
+
|
|
37
95
|
- Add ability to color messages
|
|
38
96
|
|
|
39
97
|
### 0.1.0
|
|
98
|
+
|
|
40
99
|
- Add all additional props to the top level `<Message/>` component
|
|
41
100
|
- Remove `token` / `channel` prop since they are out of scope for the component
|
|
42
101
|
|
|
43
102
|
### 0.0.4
|
|
103
|
+
|
|
44
104
|
- Fix issue where `<Actions/>` block would have incorrect type
|
|
45
105
|
|
|
46
106
|
### 0.0.3
|
|
107
|
+
|
|
47
108
|
- Fix issue where `<Button/>` element was outputting `actionId` when it should be `action_id`
|
|
48
109
|
|
|
49
110
|
### 0.0.1 / 0.0.2
|
|
111
|
+
|
|
50
112
|
- Initial release
|
package/README.md
CHANGED
|
@@ -1,95 +1,254 @@
|
|
|
1
1
|
# SlackBlock
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
JSX-based Slack Block Kit message renderer
|
|
3
4
|
|
|
4
5
|
[](https://github.com/kolyaventuri/block/actions/workflows/ci.yml)
|
|
6
|
+
[](https://www.npmjs.com/package/slackblock)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
[](https://www.typescriptlang.org/)
|
|
9
|
+
|
|
10
|
+
Build Slack messages with JSX. No React required — SlackBlock ships its own lightweight JSX runtime. Write your blocks as components, call `render()`, and post the result straight to the Slack API.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Compatibility
|
|
15
|
+
|
|
16
|
+
| | Supported |
|
|
17
|
+
|---|---|
|
|
18
|
+
| Node.js | `>= 20` |
|
|
19
|
+
| TypeScript | `>= 5.0` |
|
|
20
|
+
| React | Not required — uses a built-in JSX runtime |
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Install
|
|
25
|
+
|
|
26
|
+
```sh
|
|
27
|
+
npm install slackblock
|
|
28
|
+
# or
|
|
29
|
+
pnpm add slackblock
|
|
30
|
+
# or
|
|
31
|
+
yarn add slackblock
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
5
35
|
|
|
6
|
-
##
|
|
7
|
-
A message builder for Slack bots, using JSX with a React-compatible API. Generally follows the [Block Kit](https://api.slack.com/block-kit) naming and options.
|
|
36
|
+
## TypeScript setup
|
|
8
37
|
|
|
9
|
-
|
|
10
|
-
Install the library with your package manager, for example `pnpm add slackblock`.
|
|
38
|
+
Add the following options to your `tsconfig.json`:
|
|
11
39
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"compilerOptions": {
|
|
43
|
+
"jsx": "react-jsx",
|
|
44
|
+
"jsxImportSource": "slackblock"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
This tells TypeScript to use SlackBlock's built-in JSX runtime instead of React.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Quick start
|
|
17
54
|
|
|
18
|
-
|
|
55
|
+
```tsx
|
|
56
|
+
import render from 'slackblock';
|
|
57
|
+
import { Message, Section, Text, Header, Divider, Actions, Button } from 'slackblock/block';
|
|
19
58
|
|
|
20
59
|
const message = render(
|
|
21
|
-
<Message>
|
|
22
|
-
<
|
|
23
|
-
|
|
24
|
-
|
|
60
|
+
<Message text="Deployment complete">
|
|
61
|
+
<Header text="Deploy finished" />
|
|
62
|
+
<Section text={<Text>Service *api* deployed to production.</Text>} />
|
|
63
|
+
<Divider />
|
|
64
|
+
<Actions>
|
|
65
|
+
<Button actionId="view_logs" url="https://example.com/logs">View logs</Button>
|
|
66
|
+
<Button actionId="rollback" style="danger">Rollback</Button>
|
|
67
|
+
</Actions>
|
|
25
68
|
</Message>
|
|
26
69
|
);
|
|
27
70
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
71
|
+
// message is ready to post — just add your channel:
|
|
72
|
+
await slackClient.chat.postMessage({ channel: '#deploys', ...message });
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The rendered output is a plain object you can spread directly into `chat.postMessage`.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## API
|
|
80
|
+
|
|
81
|
+
### `render(element, options?)` — default export
|
|
82
|
+
|
|
83
|
+
Renders a `<Message>` tree to a full Slack message payload.
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
import render from 'slackblock';
|
|
87
|
+
|
|
88
|
+
const message = render(<Message text="Hello">...</Message>);
|
|
89
|
+
// → { text: "Hello", blocks: [...] }
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
The top-level element must be a `<Message>`. Throws a `TypeError` otherwise.
|
|
93
|
+
|
|
94
|
+
### `renderToMessage(element, options?)`
|
|
95
|
+
|
|
96
|
+
Named alias for `render`. Use whichever reads more naturally in your codebase.
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
import { renderToMessage } from 'slackblock';
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### `renderToBlocks(element, options?)`
|
|
103
|
+
|
|
104
|
+
Renders any JSX element (or fragment) directly to a `Block[]` array, without a `<Message>` wrapper. Useful for modals and home tabs, which accept a `blocks` array rather than a full message payload.
|
|
105
|
+
|
|
106
|
+
```tsx
|
|
107
|
+
import { renderToBlocks } from 'slackblock';
|
|
108
|
+
import { Section, Text } from 'slackblock/block';
|
|
109
|
+
|
|
110
|
+
const blocks = renderToBlocks(
|
|
111
|
+
<>
|
|
112
|
+
<Section text={<Text>Hello from a modal</Text>} />
|
|
113
|
+
</>
|
|
114
|
+
);
|
|
115
|
+
// → [{ type: "section", text: { type: "mrkdwn", text: "Hello from a modal" } }]
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### `blockKitBuilderUrl(blocks)`
|
|
119
|
+
|
|
120
|
+
Returns a [Block Kit Builder](https://app.slack.com/block-kit-builder) URL for the given blocks. Open it in a browser to preview layout and interactivity during development.
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
import { renderToBlocks, blockKitBuilderUrl } from 'slackblock';
|
|
124
|
+
|
|
125
|
+
const blocks = renderToBlocks(<Section text={<Text>Hello</Text>} />);
|
|
126
|
+
console.log(blockKitBuilderUrl(blocks));
|
|
127
|
+
// → https://app.slack.com/block-kit-builder#{"blocks":[...]}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### `escapeMrkdwn(text)`
|
|
131
|
+
|
|
132
|
+
Escapes Slack mrkdwn special characters (`*`, `_`, `~`, `` ` ``, `>`, `&`, `<`, `>`) in a string. Use this when inserting untrusted user content into a mrkdwn text field.
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
import { escapeMrkdwn } from 'slackblock';
|
|
136
|
+
|
|
137
|
+
const safe = escapeMrkdwn(userInput); // "hello *world*" → "hello \*world\*"
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Options
|
|
141
|
+
|
|
142
|
+
Both `render` / `renderToMessage` / `renderToBlocks` accept an optional `options` object:
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
type RenderOptions = {
|
|
146
|
+
validate?: 'off' | 'warn' | 'strict'; // default: 'warn'
|
|
147
|
+
};
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
See [docs/validation.md](docs/validation.md) for details.
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Validation
|
|
155
|
+
|
|
156
|
+
SlackBlock validates your message against Slack's documented limits and required fields. The `validate` option controls what happens when a violation is detected:
|
|
157
|
+
|
|
158
|
+
| Mode | Behavior |
|
|
159
|
+
|------|----------|
|
|
160
|
+
| `'warn'` (default) | Logs a warning to `console.warn`; rendering continues |
|
|
161
|
+
| `'strict'` | Throws a `SlackblockValidationError` |
|
|
162
|
+
| `'off'` | No validation |
|
|
163
|
+
|
|
164
|
+
```tsx
|
|
165
|
+
// Throw on any violation — recommended for tests
|
|
166
|
+
const message = render(<Message>...</Message>, { validate: 'strict' });
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
```ts
|
|
170
|
+
import { SlackblockValidationError } from 'slackblock';
|
|
171
|
+
|
|
172
|
+
try {
|
|
173
|
+
render(<Message>...</Message>, { validate: 'strict' });
|
|
174
|
+
} catch (err) {
|
|
175
|
+
if (err instanceof SlackblockValidationError) {
|
|
176
|
+
console.error(err.message); // "Message > Header: Header text exceeds 150 characters."
|
|
177
|
+
console.error(err.path); // ["Message", "Header"]
|
|
178
|
+
console.error(err.rule); // "too-long"
|
|
46
179
|
}
|
|
47
|
-
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
See [docs/validation.md](docs/validation.md) for the full rule reference.
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Conventions
|
|
188
|
+
|
|
189
|
+
**camelCase props** — Slack's API uses `snake_case`; SlackBlock uses `camelCase` props that map to the correct API fields:
|
|
190
|
+
|
|
191
|
+
```tsx
|
|
192
|
+
// Slack API: { "block_id": "...", "action_id": "..." }
|
|
193
|
+
<Button blockId="my_block" actionId="my_action">Click me</Button>
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
**Children as fields** — When Slack expects an array (e.g. select options, section fields), pass them as JSX children:
|
|
197
|
+
|
|
198
|
+
```tsx
|
|
199
|
+
<Select placeholder="Pick one" actionId="pick">
|
|
200
|
+
<Option value="a">Option A</Option>
|
|
201
|
+
<Option value="b">Option B</Option>
|
|
202
|
+
</Select>
|
|
48
203
|
```
|
|
49
204
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
205
|
+
**Conditional rendering** — Use `<Container>` to wrap elements that may or may not render, or use standard JS short-circuit expressions:
|
|
206
|
+
|
|
207
|
+
```tsx
|
|
208
|
+
<Message text="Hello">
|
|
209
|
+
{isAdmin && <Section text={<Text>Admin panel</Text>} />}
|
|
53
210
|
<Container>
|
|
54
|
-
<Text>
|
|
211
|
+
{items.map(item => <Section key={item.id} text={<Text>{item.name}</Text>} />)}
|
|
55
212
|
</Container>
|
|
56
|
-
|
|
213
|
+
</Message>
|
|
214
|
+
```
|
|
57
215
|
|
|
58
|
-
|
|
216
|
+
**Color / attachment** — Setting `color` on `<Message>` wraps blocks in a legacy attachment for the colored left border. `color` accepts any hex value or Slack named colors:
|
|
59
217
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
);
|
|
218
|
+
```tsx
|
|
219
|
+
<Message text="Alert" color="#ff0000">
|
|
220
|
+
<Section text={<Text>Something went wrong.</Text>} />
|
|
221
|
+
</Message>
|
|
65
222
|
```
|
|
66
223
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Supported components
|
|
227
|
+
|
|
228
|
+
**Layout blocks:** `Message`, `Section`, `Actions`, `Context`, `Divider`, `File`, `Header`, `Image` (block), `Input`, `RichText`, `Video`
|
|
229
|
+
|
|
230
|
+
**Block elements:** `Text`, `Image` (element), `Button`, `Confirmation`
|
|
231
|
+
|
|
232
|
+
**Input elements:** `Select`, `Option`, `OptionGroup`, `Overflow`, `Checkboxes`, `RadioGroup`, `TextInput`, `DatePicker`, `TimePicker`, `DateTimePicker`
|
|
233
|
+
|
|
234
|
+
**Rich text helpers:** `RichTextSection`, `RichTextList`, `RichTextQuote`, `RichTextPreformatted`, `RichTextText`, `RichTextLink`, `RichTextUser`, `RichTextChannel`, `RichTextEmoji`, `RichTextDate`, `RichTextBroadcast`, `RichTextUserGroup`
|
|
235
|
+
|
|
236
|
+
**Utility:** `Container`
|
|
237
|
+
|
|
238
|
+
See [docs/components.md](docs/components.md) for the full props reference.
|
|
81
239
|
|
|
82
|
-
|
|
83
|
-
Blocks: `Message` (top-level), `Section`, `Actions`, `Context`, `Divider`, `File`, `Image` (block), `Header`, `Input`, `RichText`, `Video`.
|
|
240
|
+
---
|
|
84
241
|
|
|
85
|
-
|
|
242
|
+
## Further reading
|
|
86
243
|
|
|
87
|
-
|
|
244
|
+
- [Component reference](docs/components.md) — all components with props tables
|
|
245
|
+
- [Validation guide](docs/validation.md) — validation modes and error handling
|
|
246
|
+
- [Migrating from jsx-slack](docs/migrating-from-jsx-slack.md)
|
|
247
|
+
- [Migrating from slack-block-builder](docs/migrating-from-slack-block-builder.md)
|
|
248
|
+
- [Slack Block Kit reference](https://api.slack.com/block-kit)
|
|
88
249
|
|
|
89
|
-
|
|
250
|
+
---
|
|
90
251
|
|
|
252
|
+
## License
|
|
91
253
|
|
|
92
|
-
|
|
93
|
-
- Add real documentation
|
|
94
|
-
- Add validation
|
|
95
|
-
- Add richer rich_text validation
|
|
254
|
+
MIT
|