BlockKitProvider
Every prop of the provider that connects rendered blocks to your app.
<BlockKitProvider> holds the state of every input rendered beneath it, and is where interactions reach your code. It’s optional: without one, blocks render and inputs work, but actions go nowhere.
import { BlockKitProvider, Message } from "@nkootstra/block-kit";
<BlockKitProvider
onAction={(action, { views, message, state }) => {}}
onSubmit={(payload, { views }) => {}}
onOptions={(payload) => ({ options: [] })}
resolvers={{ user: (id) => users[id]?.name }}
>
<Message blocks={blocks} />
</BlockKitProvider>;
One provider can hold several surfaces. Each action still carries the message or view it came from.
Props
Handlers
onAction?(action: BlockAction, context: ActionContext) => void
Called for every action: a click, a selection, a date picked. `action` is one entry of the `block_actions` payload's `actions` array. `context` has `state`, `views` and, for actions in a message, `message`.
(action: BlockAction, context: ActionContext) => voidonPayload?(payload: BlockActionsPayload, context: PayloadContext) => void
The same actions, wrapped in the full `block_actions` payload your request URL would receive: team, user, container, `response_url` and `state`. Use it to forward actions to an existing app.
(payload: BlockActionsPayload, context: PayloadContext) => voidonSubmit?(payload, context: { views }) => SubmitResult | Promise<SubmitResult>
Called with a `view_submission` payload when a modal's submit button is pressed and its inputs are valid. Return a `response_action` (`errors`, `update`, `push` or `clear`), or nothing to close the modal. If it throws or rejects, the modal stays open.
(payload, context: { views }) => SubmitResult | Promise<SubmitResult>onClose?(payload) => void
Called with a `view_closed` payload when a modal's close button is pressed.
(payload) => voidonOptions?(payload: BlockSuggestionPayload) => OptionsResponse | Promise<OptionsResponse>
Answers an `external_select`'s `block_suggestion` request with `{ options }` or `{ option_groups }`, as your options load URL would. Without it, external selects accept a typed value on Enter.
(payload: BlockSuggestionPayload) => OptionsResponse | Promise<OptionsResponse>onStateChange?(state: StateValues) => void
Called whenever an input value changes, with the full `state.values`.
(state: StateValues) => voidData
resolvers?Resolvers
Look up names for user, channel and usergroup ids, and profiles for the card a user mention opens. See [Mentions and resolvers](/guides/mentions-and-resolvers).
Resolversemoji?EmojiOptions
`imageUrl(unified)` builds the image URL for a standard emoji; `custom` maps workspace emoji names to image URLs or `alias:<name>`. See [Emoji](/guides/emoji).
EmojiOptionsApple emoji from jsDelivridentity?PayloadIdentity
`team`, `user`, `apiAppId`, `token`, `triggerId` and `responseUrl` stamped onto the payloads the provider builds.
PayloadIdentityPlaceholder ids such as `T00000000` and `U00000000`errors?Record<string, string>
Validation errors keyed by `block_id`, shown under `input` blocks: the shape of `response_action: "errors"`.
Record<string, string>Display
surface?"message" | "modal" | "home"
The surface loose `<Blocks>` are laid out for. `<Message>`, `<Modal>` and `<HomeTab>` set their own.
"message" | "modal" | "home""message"theme?"light" | "dark"
Forces a colour scheme for everything inside. Without it, the page's `data-theme` or the system preference applies. See [Theming](/guides/theming).
"light" | "dark"timeZone?string
IANA zone for `<!date>` tokens and date and time elements.
stringThe viewer's zonechildrenReactNode
The surfaces to render.
ReactNodeActionContext
The second argument to onAction.
state?StateValues
The value of every input on the surface when the action happened, keyed by `block_id`, then `action_id`, like `view.state.values`.
StateValuesviews?ViewsApi
Open, push, update, close and clear modals, and publish the Home tab.
ViewsApimessage?MessageApi | undefined
Set for actions in a `<Message>`. `update({ blocks, text })` replaces the message; `delete()` removes it.
MessageApi | undefinedViewsApi
The calls your app makes with Slack’s views.* methods. A modal opened this way renders above the provider’s children and gets its own input state. Slack allows three modals in the stack.
open?(view) => string
`views.open`: replaces any open modals with this one. Returns the new view id.
(view) => stringpush?(view) => string
`views.push`: stacks a modal on top of the current one. Returns the new view id.
(view) => stringupdate?(view, target?: { viewId?; externalId? }) => void
`views.update`: swaps a modal's content, keeping input values whose `block_id` and `action_id` are unchanged. Targets the top modal unless you pass `viewId` or `externalId`.
(view, target?: { viewId?; externalId? }) => voidclose?() => void
Closes the top modal.
() => voidclear?() => void
Closes every open modal.
() => voidpublish?(view) => void
`views.publish`: replaces the content of the `<HomeTab>` under this provider.
(view) => void