@tightknitai/block-kit-builder 0.1.0-alpha.0

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.
@@ -0,0 +1,352 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { SectionBlock, HeaderBlock, DividerBlock, ContextBlock, ActionsBlock, ImageBlock, RichTextBlock, ImageElement, Button, ViewInputBlock } from 'slack-web-api-client';
3
+
4
+ /**
5
+ * The Slack Block Kit block types supported by the builder in v1.
6
+ */
7
+ type SupportedBlockType = 'section' | 'header' | 'divider' | 'context' | 'actions' | 'image' | 'markdown' | 'rich_text' | 'table' | 'alert' | 'card' | 'carousel' | 'context_actions' | 'input';
8
+ /**
9
+ * Slack `markdown` block payload. Renders standard markdown (GFM)
10
+ * via `slack-blocks-to-jsx`'s react-markdown integration.
11
+ * `slack-web-api-client` doesn't ship this type yet, so we declare
12
+ * the minimal shape ourselves.
13
+ */
14
+ interface MarkdownBlock {
15
+ type: 'markdown';
16
+ text: string;
17
+ block_id?: string;
18
+ }
19
+ /**
20
+ * One cell in a {@link TableBlock} row. Slack accepts either a raw text
21
+ * cell or a rich-text cell; the visual editor only emits raw text in v1
22
+ * but preserves rich-text cells on edit.
23
+ */
24
+ type TableCell = {
25
+ type: 'raw_text';
26
+ text: string;
27
+ } | {
28
+ type: 'rich_text';
29
+ elements: unknown[];
30
+ };
31
+ /**
32
+ * Per-column setting in a {@link TableBlock}. May be null to skip a
33
+ * column. Matches Slack's `table_column_setting` schema.
34
+ */
35
+ type TableColumnSetting = null | {
36
+ align?: 'left' | 'center' | 'right';
37
+ is_wrapped?: boolean;
38
+ };
39
+ /**
40
+ * Slack `table` block payload. Up to 100 rows, 20 cells per row.
41
+ * `slack-web-api-client` doesn't ship this type, so we declare it.
42
+ */
43
+ interface TableBlock {
44
+ type: 'table';
45
+ rows: TableCell[][];
46
+ column_settings?: TableColumnSetting[];
47
+ block_id?: string;
48
+ }
49
+ /**
50
+ * Severity level for an {@link AlertBlock}. Controls the icon and color
51
+ * accent rendered by Slack. Defaults to `default` when omitted.
52
+ */
53
+ type AlertLevel = 'default' | 'info' | 'warning' | 'error' | 'success';
54
+ /**
55
+ * Slack `alert` block payload. Single-line status notification with an
56
+ * optional severity level. Per Slack's surface compatibility rules, alert
57
+ * blocks render on modal surfaces only (not messages or home tabs).
58
+ * `slack-web-api-client` doesn't ship this type yet, so we declare it.
59
+ */
60
+ interface AlertBlock {
61
+ type: 'alert';
62
+ text: {
63
+ type: 'plain_text' | 'mrkdwn';
64
+ text: string;
65
+ emoji?: boolean;
66
+ verbatim?: boolean;
67
+ };
68
+ level?: AlertLevel;
69
+ block_id?: string;
70
+ }
71
+ /**
72
+ * Slack `card` block payload. Renders a media-rich card with optional
73
+ * hero image, icon, title, subtitle, body, and action buttons. At least
74
+ * one of `hero_image`, `title`, `actions`, or `body` is required.
75
+ * `slack-web-api-client` doesn't ship this type yet, so we declare it.
76
+ */
77
+ interface CardBlock {
78
+ type: 'card';
79
+ block_id?: string;
80
+ hero_image?: ImageElement;
81
+ icon?: ImageElement;
82
+ title?: {
83
+ type: 'plain_text' | 'mrkdwn';
84
+ text: string;
85
+ emoji?: boolean;
86
+ verbatim?: boolean;
87
+ };
88
+ subtitle?: {
89
+ type: 'plain_text' | 'mrkdwn';
90
+ text: string;
91
+ emoji?: boolean;
92
+ verbatim?: boolean;
93
+ };
94
+ body?: {
95
+ type: 'plain_text' | 'mrkdwn';
96
+ text: string;
97
+ emoji?: boolean;
98
+ verbatim?: boolean;
99
+ };
100
+ actions?: Button[];
101
+ }
102
+ /**
103
+ * Slack `carousel` block payload. A horizontally scrollable group of
104
+ * 1-10 {@link CardBlock} elements. `slack-web-api-client` doesn't ship
105
+ * this type yet, so we declare it.
106
+ */
107
+ interface CarouselBlock {
108
+ type: 'carousel';
109
+ elements: CardBlock[];
110
+ block_id?: string;
111
+ }
112
+ /**
113
+ * Sub-button used inside a {@link FeedbackButtonsElement}.
114
+ */
115
+ interface FeedbackButtonSubobject {
116
+ text: {
117
+ type: 'plain_text';
118
+ text: string;
119
+ emoji?: boolean;
120
+ };
121
+ value: string;
122
+ accessibility_label?: string;
123
+ }
124
+ /**
125
+ * `feedback_buttons` element. Pair of positive/negative buttons used
126
+ * inside a {@link ContextActionsBlock} (e.g. "Good Response" / "Bad
127
+ * Response" thumbs).
128
+ */
129
+ interface FeedbackButtonsElement {
130
+ type: 'feedback_buttons';
131
+ positive_button: FeedbackButtonSubobject;
132
+ negative_button: FeedbackButtonSubobject;
133
+ action_id?: string;
134
+ }
135
+ /**
136
+ * Slack icon names valid on an {@link IconButtonElement}. Slack only
137
+ * ships `trash` today; widen as Slack adds more.
138
+ */
139
+ type IconButtonIcon = 'trash';
140
+ /**
141
+ * `icon_button` element. Compact icon-with-label button used inside a
142
+ * {@link ContextActionsBlock} (e.g. a "Remove" trash-icon button).
143
+ */
144
+ interface IconButtonElement {
145
+ type: 'icon_button';
146
+ icon: IconButtonIcon;
147
+ text: {
148
+ type: 'plain_text';
149
+ text: string;
150
+ emoji?: boolean;
151
+ };
152
+ action_id?: string;
153
+ value?: string;
154
+ accessibility_label?: string;
155
+ }
156
+ /**
157
+ * Element accepted by a {@link ContextActionsBlock}.
158
+ */
159
+ type ContextActionsElement = FeedbackButtonsElement | IconButtonElement;
160
+ /**
161
+ * Slack `context_actions` block payload. Renders a row of contextual
162
+ * action buttons (1-5 elements) attached to a message. Only valid on
163
+ * the message surface; the validator already encodes that.
164
+ * `slack-web-api-client` doesn't ship this type yet, so we declare it.
165
+ */
166
+ interface ContextActionsBlock {
167
+ type: 'context_actions';
168
+ elements: ContextActionsElement[];
169
+ block_id?: string;
170
+ }
171
+ /**
172
+ * Slack `input` block payload. Aliased to `ViewInputBlock` from
173
+ * `slack-web-api-client`, which is the superset that accepts every
174
+ * supported input element (including `rich_text_input` and `file_input`).
175
+ * Surface compatibility (input is valid on modal and home tab; some
176
+ * elements are modal-only) is enforced by the validator, not the type.
177
+ */
178
+ type InputBlock = ViewInputBlock;
179
+ /**
180
+ * Header heading level shown in the preview. Slack's API has no
181
+ * `level` field on header blocks, so this is a builder-only extension
182
+ * that round-trips on the block payload but is otherwise cosmetic.
183
+ */
184
+ type HeaderLevel = 1 | 2 | 3 | 4;
185
+ /**
186
+ * Header block as edited by the builder. Extends Slack's HeaderBlock
187
+ * with an optional {@link HeaderLevel}.
188
+ */
189
+ type SupportedHeaderBlock = HeaderBlock & {
190
+ level?: HeaderLevel;
191
+ };
192
+ /**
193
+ * Discriminated union of supported block payload shapes.
194
+ * Subset of {@link AnyMessageBlock} from `slack-web-api-client`,
195
+ * plus a header `level` extension.
196
+ */
197
+ type SupportedBlock = SectionBlock | SupportedHeaderBlock | DividerBlock | ContextBlock | ActionsBlock | ImageBlock | MarkdownBlock | RichTextBlock | TableBlock | AlertBlock | CardBlock | CarouselBlock | ContextActionsBlock | InputBlock;
198
+ /**
199
+ * A block as represented inside the builder's working state.
200
+ * `id` is an ephemeral client-side identifier used by DnD and selection.
201
+ * It is stripped before serialization to Slack.
202
+ */
203
+ interface BuilderBlock {
204
+ id: string;
205
+ block: SupportedBlock;
206
+ }
207
+ /**
208
+ * Channel record returned by {@link BlockKitBuilderProps.loadChannels}.
209
+ */
210
+ interface ChannelOption {
211
+ id: string;
212
+ name: string;
213
+ }
214
+ /**
215
+ * User-token status returned by {@link BlockKitBuilderProps.loadSendAsUserStatus}.
216
+ * If `canSendAsUser` is false, `oauthUrl` is required so the UI can show a
217
+ * "Sign in with Slack" link.
218
+ */
219
+ interface SendAsUserStatus {
220
+ canSendAsUser: boolean;
221
+ oauthUrl?: string;
222
+ }
223
+ /**
224
+ * Payload passed to {@link BlockKitBuilderProps.onSend}.
225
+ */
226
+ interface SendPayload {
227
+ channelId: string;
228
+ blocks: SupportedBlock[];
229
+ sendAsUser: boolean;
230
+ }
231
+ /**
232
+ * Result returned from {@link BlockKitBuilderProps.onSend}.
233
+ * `error` is a human-readable message; the dialog renders it as-is.
234
+ */
235
+ interface SendResult {
236
+ ok: boolean;
237
+ error?: string;
238
+ }
239
+ /**
240
+ * Hooks forwarded to `slack-blocks-to-jsx`'s `<Message>` so the consumer can
241
+ * resolve user mentions, channel mentions, custom emojis, and links to
242
+ * application-specific UI. See the upstream library for the full hook shape.
243
+ * Marked as `unknown`-keyed at this layer to avoid leaking the upstream
244
+ * library's internal types into our public API.
245
+ */
246
+ type PreviewHooks = Record<string, unknown>;
247
+ /**
248
+ * Light or dark theme for the rendered Slack preview. Wired to
249
+ * `slack-blocks-to-jsx`'s `theme` prop and `data-theme` attribute.
250
+ */
251
+ type PreviewTheme = 'light' | 'dark';
252
+ /**
253
+ * Props for the top-level {@link BlockKitBuilder} component.
254
+ * The package is integration-agnostic: every I/O concern is brokered
255
+ * through these props. The component never makes a network call itself.
256
+ */
257
+ interface BlockKitBuilderProps {
258
+ /**
259
+ * Workspace name shown in the preview chrome to mimic a Slack message header.
260
+ * Cosmetic only.
261
+ */
262
+ workspaceName?: string;
263
+ /**
264
+ * Initial draft blocks. If omitted the builder starts empty.
265
+ */
266
+ initialBlocks?: SupportedBlock[];
267
+ /**
268
+ * Fires whenever the draft state changes. Use to persist the draft
269
+ * (URL search param, localStorage, etc).
270
+ */
271
+ onChange?: (blocks: SupportedBlock[]) => void;
272
+ /**
273
+ * Optional hooks forwarded to the underlying `<Message>` component for
274
+ * resolving user / channel / emoji directives. If omitted, those
275
+ * directives render with the library's defaults.
276
+ */
277
+ previewHooks?: PreviewHooks;
278
+ /**
279
+ * Returns channels available to send to. Called when the send dialog opens.
280
+ */
281
+ loadChannels: () => Promise<ChannelOption[]>;
282
+ /**
283
+ * Returns whether the current user can post as themselves and, if not, an
284
+ * OAuth URL to start the install flow.
285
+ */
286
+ loadSendAsUserStatus: () => Promise<SendAsUserStatus>;
287
+ /**
288
+ * Called when the user submits the send dialog. Should return
289
+ * `{ ok: true }` on success or `{ ok: false, error }` on failure.
290
+ */
291
+ onSend: (payload: SendPayload) => Promise<SendResult>;
292
+ /**
293
+ * Whether the toolbar exposes the preview-surface dropdown
294
+ * (Message / Modal / App Home). Defaults to `true`. When `false`,
295
+ * the surface is locked to {@link PreviewSurface} `'message'`.
296
+ */
297
+ showSurfaceControl?: boolean;
298
+ /**
299
+ * Whether the toolbar exposes the light/dark theme dropdown.
300
+ * Defaults to `true`. When `false`, the theme is locked to
301
+ * {@link PreviewTheme} `'light'`.
302
+ */
303
+ showThemeControl?: boolean;
304
+ /**
305
+ * Initial preview theme. Defaults to `'light'`. Pass the host app's
306
+ * current theme (e.g. from `next-themes` or your own theme hook) so
307
+ * the preview opens matched to the consuming app's appearance. The
308
+ * user can still override via the toolbar dropdown if
309
+ * {@link BlockKitBuilderProps.showThemeControl} is `true`.
310
+ */
311
+ defaultPreviewTheme?: PreviewTheme;
312
+ }
313
+
314
+ /**
315
+ * Top-level Slack Block Kit builder component.
316
+ * Renders the toolbar, palette, preview surface, popover editors, send
317
+ * dialog, and View-JSON drawer. Integration-agnostic: all I/O is brokered
318
+ * through props.
319
+ * @param props - {@link BlockKitBuilderProps}
320
+ * @returns the rendered Block Kit Builder
321
+ */
322
+ declare function BlockKitBuilder(props: BlockKitBuilderProps): react_jsx_runtime.JSX.Element;
323
+
324
+ /**
325
+ * Strip builder-only fields from blocks so they conform to Slack's
326
+ * Block Kit schema. Currently removes the cosmetic `level` field from
327
+ * header blocks, which is a builder-only extension that the validator
328
+ * (and Slack's API) would otherwise reject.
329
+ * @param blocks - the working draft blocks
330
+ * @returns blocks with builder-only fields removed
331
+ */
332
+ declare function toSlackBlocks(blocks: SupportedBlock[]): SupportedBlock[];
333
+
334
+ /**
335
+ * Encodes a block list to a base64url string suitable for use as a URL
336
+ * search param. The consumer chooses where to put it (search param, hash,
337
+ * localStorage, etc).
338
+ * Returns an empty string for an empty list so the consumer can omit the
339
+ * param entirely.
340
+ * @param blocks - the blocks to encode
341
+ * @returns base64url-encoded JSON, or '' if blocks is empty
342
+ */
343
+ declare function encodeBlocksToString(blocks: SupportedBlock[]): string;
344
+ /**
345
+ * Decodes a string produced by {@link encodeBlocksToString} back to a
346
+ * block list. Returns null on any decode/parse error.
347
+ * @param encoded - the encoded string
348
+ * @returns decoded blocks, or null if input is empty/invalid
349
+ */
350
+ declare function decodeBlocksFromString(encoded: string | undefined | null): SupportedBlock[] | null;
351
+
352
+ export { BlockKitBuilder, type BlockKitBuilderProps, type BuilderBlock, type ChannelOption, type PreviewHooks, type SendAsUserStatus, type SendPayload, type SendResult, type SupportedBlock, type SupportedBlockType, decodeBlocksFromString, encodeBlocksToString, toSlackBlocks };
@@ -0,0 +1,352 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { SectionBlock, HeaderBlock, DividerBlock, ContextBlock, ActionsBlock, ImageBlock, RichTextBlock, ImageElement, Button, ViewInputBlock } from 'slack-web-api-client';
3
+
4
+ /**
5
+ * The Slack Block Kit block types supported by the builder in v1.
6
+ */
7
+ type SupportedBlockType = 'section' | 'header' | 'divider' | 'context' | 'actions' | 'image' | 'markdown' | 'rich_text' | 'table' | 'alert' | 'card' | 'carousel' | 'context_actions' | 'input';
8
+ /**
9
+ * Slack `markdown` block payload. Renders standard markdown (GFM)
10
+ * via `slack-blocks-to-jsx`'s react-markdown integration.
11
+ * `slack-web-api-client` doesn't ship this type yet, so we declare
12
+ * the minimal shape ourselves.
13
+ */
14
+ interface MarkdownBlock {
15
+ type: 'markdown';
16
+ text: string;
17
+ block_id?: string;
18
+ }
19
+ /**
20
+ * One cell in a {@link TableBlock} row. Slack accepts either a raw text
21
+ * cell or a rich-text cell; the visual editor only emits raw text in v1
22
+ * but preserves rich-text cells on edit.
23
+ */
24
+ type TableCell = {
25
+ type: 'raw_text';
26
+ text: string;
27
+ } | {
28
+ type: 'rich_text';
29
+ elements: unknown[];
30
+ };
31
+ /**
32
+ * Per-column setting in a {@link TableBlock}. May be null to skip a
33
+ * column. Matches Slack's `table_column_setting` schema.
34
+ */
35
+ type TableColumnSetting = null | {
36
+ align?: 'left' | 'center' | 'right';
37
+ is_wrapped?: boolean;
38
+ };
39
+ /**
40
+ * Slack `table` block payload. Up to 100 rows, 20 cells per row.
41
+ * `slack-web-api-client` doesn't ship this type, so we declare it.
42
+ */
43
+ interface TableBlock {
44
+ type: 'table';
45
+ rows: TableCell[][];
46
+ column_settings?: TableColumnSetting[];
47
+ block_id?: string;
48
+ }
49
+ /**
50
+ * Severity level for an {@link AlertBlock}. Controls the icon and color
51
+ * accent rendered by Slack. Defaults to `default` when omitted.
52
+ */
53
+ type AlertLevel = 'default' | 'info' | 'warning' | 'error' | 'success';
54
+ /**
55
+ * Slack `alert` block payload. Single-line status notification with an
56
+ * optional severity level. Per Slack's surface compatibility rules, alert
57
+ * blocks render on modal surfaces only (not messages or home tabs).
58
+ * `slack-web-api-client` doesn't ship this type yet, so we declare it.
59
+ */
60
+ interface AlertBlock {
61
+ type: 'alert';
62
+ text: {
63
+ type: 'plain_text' | 'mrkdwn';
64
+ text: string;
65
+ emoji?: boolean;
66
+ verbatim?: boolean;
67
+ };
68
+ level?: AlertLevel;
69
+ block_id?: string;
70
+ }
71
+ /**
72
+ * Slack `card` block payload. Renders a media-rich card with optional
73
+ * hero image, icon, title, subtitle, body, and action buttons. At least
74
+ * one of `hero_image`, `title`, `actions`, or `body` is required.
75
+ * `slack-web-api-client` doesn't ship this type yet, so we declare it.
76
+ */
77
+ interface CardBlock {
78
+ type: 'card';
79
+ block_id?: string;
80
+ hero_image?: ImageElement;
81
+ icon?: ImageElement;
82
+ title?: {
83
+ type: 'plain_text' | 'mrkdwn';
84
+ text: string;
85
+ emoji?: boolean;
86
+ verbatim?: boolean;
87
+ };
88
+ subtitle?: {
89
+ type: 'plain_text' | 'mrkdwn';
90
+ text: string;
91
+ emoji?: boolean;
92
+ verbatim?: boolean;
93
+ };
94
+ body?: {
95
+ type: 'plain_text' | 'mrkdwn';
96
+ text: string;
97
+ emoji?: boolean;
98
+ verbatim?: boolean;
99
+ };
100
+ actions?: Button[];
101
+ }
102
+ /**
103
+ * Slack `carousel` block payload. A horizontally scrollable group of
104
+ * 1-10 {@link CardBlock} elements. `slack-web-api-client` doesn't ship
105
+ * this type yet, so we declare it.
106
+ */
107
+ interface CarouselBlock {
108
+ type: 'carousel';
109
+ elements: CardBlock[];
110
+ block_id?: string;
111
+ }
112
+ /**
113
+ * Sub-button used inside a {@link FeedbackButtonsElement}.
114
+ */
115
+ interface FeedbackButtonSubobject {
116
+ text: {
117
+ type: 'plain_text';
118
+ text: string;
119
+ emoji?: boolean;
120
+ };
121
+ value: string;
122
+ accessibility_label?: string;
123
+ }
124
+ /**
125
+ * `feedback_buttons` element. Pair of positive/negative buttons used
126
+ * inside a {@link ContextActionsBlock} (e.g. "Good Response" / "Bad
127
+ * Response" thumbs).
128
+ */
129
+ interface FeedbackButtonsElement {
130
+ type: 'feedback_buttons';
131
+ positive_button: FeedbackButtonSubobject;
132
+ negative_button: FeedbackButtonSubobject;
133
+ action_id?: string;
134
+ }
135
+ /**
136
+ * Slack icon names valid on an {@link IconButtonElement}. Slack only
137
+ * ships `trash` today; widen as Slack adds more.
138
+ */
139
+ type IconButtonIcon = 'trash';
140
+ /**
141
+ * `icon_button` element. Compact icon-with-label button used inside a
142
+ * {@link ContextActionsBlock} (e.g. a "Remove" trash-icon button).
143
+ */
144
+ interface IconButtonElement {
145
+ type: 'icon_button';
146
+ icon: IconButtonIcon;
147
+ text: {
148
+ type: 'plain_text';
149
+ text: string;
150
+ emoji?: boolean;
151
+ };
152
+ action_id?: string;
153
+ value?: string;
154
+ accessibility_label?: string;
155
+ }
156
+ /**
157
+ * Element accepted by a {@link ContextActionsBlock}.
158
+ */
159
+ type ContextActionsElement = FeedbackButtonsElement | IconButtonElement;
160
+ /**
161
+ * Slack `context_actions` block payload. Renders a row of contextual
162
+ * action buttons (1-5 elements) attached to a message. Only valid on
163
+ * the message surface; the validator already encodes that.
164
+ * `slack-web-api-client` doesn't ship this type yet, so we declare it.
165
+ */
166
+ interface ContextActionsBlock {
167
+ type: 'context_actions';
168
+ elements: ContextActionsElement[];
169
+ block_id?: string;
170
+ }
171
+ /**
172
+ * Slack `input` block payload. Aliased to `ViewInputBlock` from
173
+ * `slack-web-api-client`, which is the superset that accepts every
174
+ * supported input element (including `rich_text_input` and `file_input`).
175
+ * Surface compatibility (input is valid on modal and home tab; some
176
+ * elements are modal-only) is enforced by the validator, not the type.
177
+ */
178
+ type InputBlock = ViewInputBlock;
179
+ /**
180
+ * Header heading level shown in the preview. Slack's API has no
181
+ * `level` field on header blocks, so this is a builder-only extension
182
+ * that round-trips on the block payload but is otherwise cosmetic.
183
+ */
184
+ type HeaderLevel = 1 | 2 | 3 | 4;
185
+ /**
186
+ * Header block as edited by the builder. Extends Slack's HeaderBlock
187
+ * with an optional {@link HeaderLevel}.
188
+ */
189
+ type SupportedHeaderBlock = HeaderBlock & {
190
+ level?: HeaderLevel;
191
+ };
192
+ /**
193
+ * Discriminated union of supported block payload shapes.
194
+ * Subset of {@link AnyMessageBlock} from `slack-web-api-client`,
195
+ * plus a header `level` extension.
196
+ */
197
+ type SupportedBlock = SectionBlock | SupportedHeaderBlock | DividerBlock | ContextBlock | ActionsBlock | ImageBlock | MarkdownBlock | RichTextBlock | TableBlock | AlertBlock | CardBlock | CarouselBlock | ContextActionsBlock | InputBlock;
198
+ /**
199
+ * A block as represented inside the builder's working state.
200
+ * `id` is an ephemeral client-side identifier used by DnD and selection.
201
+ * It is stripped before serialization to Slack.
202
+ */
203
+ interface BuilderBlock {
204
+ id: string;
205
+ block: SupportedBlock;
206
+ }
207
+ /**
208
+ * Channel record returned by {@link BlockKitBuilderProps.loadChannels}.
209
+ */
210
+ interface ChannelOption {
211
+ id: string;
212
+ name: string;
213
+ }
214
+ /**
215
+ * User-token status returned by {@link BlockKitBuilderProps.loadSendAsUserStatus}.
216
+ * If `canSendAsUser` is false, `oauthUrl` is required so the UI can show a
217
+ * "Sign in with Slack" link.
218
+ */
219
+ interface SendAsUserStatus {
220
+ canSendAsUser: boolean;
221
+ oauthUrl?: string;
222
+ }
223
+ /**
224
+ * Payload passed to {@link BlockKitBuilderProps.onSend}.
225
+ */
226
+ interface SendPayload {
227
+ channelId: string;
228
+ blocks: SupportedBlock[];
229
+ sendAsUser: boolean;
230
+ }
231
+ /**
232
+ * Result returned from {@link BlockKitBuilderProps.onSend}.
233
+ * `error` is a human-readable message; the dialog renders it as-is.
234
+ */
235
+ interface SendResult {
236
+ ok: boolean;
237
+ error?: string;
238
+ }
239
+ /**
240
+ * Hooks forwarded to `slack-blocks-to-jsx`'s `<Message>` so the consumer can
241
+ * resolve user mentions, channel mentions, custom emojis, and links to
242
+ * application-specific UI. See the upstream library for the full hook shape.
243
+ * Marked as `unknown`-keyed at this layer to avoid leaking the upstream
244
+ * library's internal types into our public API.
245
+ */
246
+ type PreviewHooks = Record<string, unknown>;
247
+ /**
248
+ * Light or dark theme for the rendered Slack preview. Wired to
249
+ * `slack-blocks-to-jsx`'s `theme` prop and `data-theme` attribute.
250
+ */
251
+ type PreviewTheme = 'light' | 'dark';
252
+ /**
253
+ * Props for the top-level {@link BlockKitBuilder} component.
254
+ * The package is integration-agnostic: every I/O concern is brokered
255
+ * through these props. The component never makes a network call itself.
256
+ */
257
+ interface BlockKitBuilderProps {
258
+ /**
259
+ * Workspace name shown in the preview chrome to mimic a Slack message header.
260
+ * Cosmetic only.
261
+ */
262
+ workspaceName?: string;
263
+ /**
264
+ * Initial draft blocks. If omitted the builder starts empty.
265
+ */
266
+ initialBlocks?: SupportedBlock[];
267
+ /**
268
+ * Fires whenever the draft state changes. Use to persist the draft
269
+ * (URL search param, localStorage, etc).
270
+ */
271
+ onChange?: (blocks: SupportedBlock[]) => void;
272
+ /**
273
+ * Optional hooks forwarded to the underlying `<Message>` component for
274
+ * resolving user / channel / emoji directives. If omitted, those
275
+ * directives render with the library's defaults.
276
+ */
277
+ previewHooks?: PreviewHooks;
278
+ /**
279
+ * Returns channels available to send to. Called when the send dialog opens.
280
+ */
281
+ loadChannels: () => Promise<ChannelOption[]>;
282
+ /**
283
+ * Returns whether the current user can post as themselves and, if not, an
284
+ * OAuth URL to start the install flow.
285
+ */
286
+ loadSendAsUserStatus: () => Promise<SendAsUserStatus>;
287
+ /**
288
+ * Called when the user submits the send dialog. Should return
289
+ * `{ ok: true }` on success or `{ ok: false, error }` on failure.
290
+ */
291
+ onSend: (payload: SendPayload) => Promise<SendResult>;
292
+ /**
293
+ * Whether the toolbar exposes the preview-surface dropdown
294
+ * (Message / Modal / App Home). Defaults to `true`. When `false`,
295
+ * the surface is locked to {@link PreviewSurface} `'message'`.
296
+ */
297
+ showSurfaceControl?: boolean;
298
+ /**
299
+ * Whether the toolbar exposes the light/dark theme dropdown.
300
+ * Defaults to `true`. When `false`, the theme is locked to
301
+ * {@link PreviewTheme} `'light'`.
302
+ */
303
+ showThemeControl?: boolean;
304
+ /**
305
+ * Initial preview theme. Defaults to `'light'`. Pass the host app's
306
+ * current theme (e.g. from `next-themes` or your own theme hook) so
307
+ * the preview opens matched to the consuming app's appearance. The
308
+ * user can still override via the toolbar dropdown if
309
+ * {@link BlockKitBuilderProps.showThemeControl} is `true`.
310
+ */
311
+ defaultPreviewTheme?: PreviewTheme;
312
+ }
313
+
314
+ /**
315
+ * Top-level Slack Block Kit builder component.
316
+ * Renders the toolbar, palette, preview surface, popover editors, send
317
+ * dialog, and View-JSON drawer. Integration-agnostic: all I/O is brokered
318
+ * through props.
319
+ * @param props - {@link BlockKitBuilderProps}
320
+ * @returns the rendered Block Kit Builder
321
+ */
322
+ declare function BlockKitBuilder(props: BlockKitBuilderProps): react_jsx_runtime.JSX.Element;
323
+
324
+ /**
325
+ * Strip builder-only fields from blocks so they conform to Slack's
326
+ * Block Kit schema. Currently removes the cosmetic `level` field from
327
+ * header blocks, which is a builder-only extension that the validator
328
+ * (and Slack's API) would otherwise reject.
329
+ * @param blocks - the working draft blocks
330
+ * @returns blocks with builder-only fields removed
331
+ */
332
+ declare function toSlackBlocks(blocks: SupportedBlock[]): SupportedBlock[];
333
+
334
+ /**
335
+ * Encodes a block list to a base64url string suitable for use as a URL
336
+ * search param. The consumer chooses where to put it (search param, hash,
337
+ * localStorage, etc).
338
+ * Returns an empty string for an empty list so the consumer can omit the
339
+ * param entirely.
340
+ * @param blocks - the blocks to encode
341
+ * @returns base64url-encoded JSON, or '' if blocks is empty
342
+ */
343
+ declare function encodeBlocksToString(blocks: SupportedBlock[]): string;
344
+ /**
345
+ * Decodes a string produced by {@link encodeBlocksToString} back to a
346
+ * block list. Returns null on any decode/parse error.
347
+ * @param encoded - the encoded string
348
+ * @returns decoded blocks, or null if input is empty/invalid
349
+ */
350
+ declare function decodeBlocksFromString(encoded: string | undefined | null): SupportedBlock[] | null;
351
+
352
+ export { BlockKitBuilder, type BlockKitBuilderProps, type BuilderBlock, type ChannelOption, type PreviewHooks, type SendAsUserStatus, type SendPayload, type SendResult, type SupportedBlock, type SupportedBlockType, decodeBlocksFromString, encodeBlocksToString, toSlackBlocks };