@tightknitai/block-kitchen 0.8.9 → 0.8.11
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/README.md +65 -1
- package/dist/helpers.d.cts +2 -2
- package/dist/helpers.d.ts +2 -2
- package/dist/index.cjs +733 -365
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +734 -366
- package/dist/index.js.map +1 -1
- package/dist/{palette-DBTHRygt.d.cts → palette-Bup05opK.d.cts} +152 -4
- package/dist/{palette-DBTHRygt.d.ts → palette-Bup05opK.d.ts} +152 -4
- package/dist/palette.d.cts +1 -1
- package/dist/palette.d.ts +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -108,6 +108,10 @@ export function MyBuilderPage() {
|
|
|
108
108
|
| `loadChannels` | `() => Promise<{ id: string; name: string }[]>` | yes | Returns channels available to send to. The package never makes Slack API calls itself. |
|
|
109
109
|
| `loadSendAsUserStatus` | `() => Promise<{ canSendAsUser: boolean; oauthUrl?: string }>` | yes | Whether the current user has a Slack user-token and can post as themselves. If `canSendAsUser` is false, `oauthUrl` is shown as a "Sign in with Slack" link. |
|
|
110
110
|
| `onSend` | `(payload) => Promise<{ ok: boolean; error?: string }>` | yes | Called when the user submits the send dialog. Payload is `{ channelId, blocks, sendAsUser }`. |
|
|
111
|
+
| `editing` | `{ onLoadMessage, onUpdate, loadRecentMessages? }` | no | Opt-in edit mode. When present, the toolbar exposes "Edit message": the user pastes a Slack message link, `onLoadMessage({ link })` returns a host-computed [editability verdict](#editing-an-existing-message-opt-in), and a successful load flips the primary action to "Update message" wired to `onUpdate`. Pass `loadRecentMessages` to add a "recent messages from this app" picker beside the paste input. Omit `editing` to keep send-only behavior. |
|
|
112
|
+
| `loadButtonLabel` | `string` | no | Label + accessible name for the toolbar button that opens the load-message dialog (the edit-mode entry point). Defaults to `'Load message'`. Only shown when `editing` is set and no message is loaded. |
|
|
113
|
+
| `updateButtonLabel` | `string` | no | Label for the toolbar's primary button while a message is loaded for editing. It's a split button: clicking it updates the message in place; the menu beside it also offers "Send as a new message" (post the current blocks as new). Defaults to `'Review & update'`. |
|
|
114
|
+
| `confirmUpdateLabel` | `string` | no | Label for the update dialog's final confirm button. Defaults to `'Update message'` (shows `'Updating…'` while in flight). |
|
|
111
115
|
| `previewHooks` | `PreviewHooks` | no | Hooks forwarded to `slack-blocks-to-jsx`'s `<Message>` for resolving user / channel / emoji directives. |
|
|
112
116
|
| `customEmojis` | `CustomEmoji[]` | no | Workspace custom emoji (`{ name, url, alias }`) the preview resolves. Entries with a `url` render `:name:` as the workspace image; alias entries (`url: null`) fall back to their target emoji. Render-only — never serialized into the emitted Block Kit JSON. A caller-supplied `previewHooks.emoji` takes precedence. |
|
|
113
117
|
| `palette` | `PaletteSection[]` | no | The left-hand palette of draggable variants. Defaults to `defaultPalette`. Spread it to filter, reorder, or add your own pre-configured variants — see [Customizing the palette](#customizing-the-palette). |
|
|
@@ -119,10 +123,70 @@ export function MyBuilderPage() {
|
|
|
119
123
|
| `showThemeControl` | `boolean` | no | Defaults to `true`. When `false`, the toolbar's light/dark toggle is hidden and the theme stays at `defaultPreviewTheme`. Ignored when `previewTheme` is set (a controlled theme always hides the toggle). |
|
|
120
124
|
| `defaultPreviewTheme` | `'light' \| 'dark'` | no | Initial (uncontrolled) preview theme. Pass the host app's current theme so the preview opens matched to the consuming app's appearance. Ignored when `previewTheme` is provided. |
|
|
121
125
|
| `previewTheme` | `'light' \| 'dark'` | no | Controlled preview theme. When set, the preview renders in this theme, follows it reactively, and the toolbar's light/dark toggle is hidden so the host app fully owns the theme. Leave unset to keep the preview uncontrolled (seeded from `defaultPreviewTheme`, toggle shown). |
|
|
122
|
-
| `sendButtonLabel` | `string` | no | Label and accessible name for the toolbar's Send button (which opens the send dialog). Defaults to `'
|
|
126
|
+
| `sendButtonLabel` | `string` | no | Label and accessible name for the toolbar's Send button (which opens the send dialog). Defaults to `'Review & send'` (the dialog is the review step). Override it for product-specific copy, e.g. `'Send to channel…'`. |
|
|
123
127
|
| `confirmSendLabel` | `string` | no | Label for the send dialog's final confirm button. Defaults to `'Send'` (shows `'Sending…'` while in flight). |
|
|
124
128
|
| `theme` | `BrandTheme \| BrandPreset` | no | Branding tokens applied to the builder chrome (toolbar, palette, popovers, dialogs). Accepts a `Partial<BrandTokens>` map and optional `light`/`dark` overrides. See [Styling](#styling) below. |
|
|
125
129
|
|
|
130
|
+
## Editing an existing message (opt-in)
|
|
131
|
+
|
|
132
|
+
By default the builder is send-only. Pass `editing` to let users load an
|
|
133
|
+
already-posted message, edit its blocks, and dispatch a `chat.update`. The
|
|
134
|
+
package stays integration-agnostic: it makes no Slack calls and computes
|
|
135
|
+
nothing about who can edit; the host does both.
|
|
136
|
+
|
|
137
|
+
```tsx
|
|
138
|
+
<BlockKitchen
|
|
139
|
+
/* …send-only props… */
|
|
140
|
+
editing={{
|
|
141
|
+
// Host parses the pasted permalink, fetches the message, and returns a
|
|
142
|
+
// verdict. `chat.update` only edits a message authored by the calling
|
|
143
|
+
// token, so the host decides: bot message → 'bot', the user's own
|
|
144
|
+
// message → 'user', anything else → not editable.
|
|
145
|
+
onLoadMessage: async ({ link }) => {
|
|
146
|
+
const msg = await fetchMessageFromPermalink(link); // your code
|
|
147
|
+
if (!msg) return { ok: false, reason: "Couldn't find that message." };
|
|
148
|
+
if (!msg.blocks?.length) return { ok: false, reason: 'This message has no editable blocks.' };
|
|
149
|
+
// `username` + `iconUrl` are optional; when present they show in the
|
|
150
|
+
// preview header instead of the generic workspace name/avatar.
|
|
151
|
+
const author = { username: msg.authorName, iconUrl: msg.authorAvatarUrl };
|
|
152
|
+
if (msg.appId === MY_APP_ID)
|
|
153
|
+
return { ok: true, channelId: msg.channel, channelName: msg.channelName, ts: msg.ts, blocks: msg.blocks, editableVia: 'bot', ...author };
|
|
154
|
+
if (msg.userId === currentUserId)
|
|
155
|
+
return { ok: true, channelId: msg.channel, channelName: msg.channelName, ts: msg.ts, blocks: msg.blocks, editableVia: 'user', ...author };
|
|
156
|
+
return { ok: false, reason: 'Only messages your app or you posted can be edited.', blocks: msg.blocks };
|
|
157
|
+
},
|
|
158
|
+
// Sibling to onSend; carries the source channel + ts. `asUser` follows
|
|
159
|
+
// the verdict's `editableVia`.
|
|
160
|
+
onUpdate: async ({ channelId, ts, blocks, asUser }) => {
|
|
161
|
+
await chatUpdate({ channel: channelId, ts, blocks, asUser }); // your code
|
|
162
|
+
return { ok: true };
|
|
163
|
+
},
|
|
164
|
+
// Optional: adds a "recent messages from this app" picker beside the paste
|
|
165
|
+
// input. These are editable-by-construction (the app authored them), so
|
|
166
|
+
// picking one loads it straight into edit mode (no verdict needed).
|
|
167
|
+
loadRecentMessages: async () => {
|
|
168
|
+
const msgs = await fetchRecentAppMessages(); // your code
|
|
169
|
+
return msgs.map((m) => ({
|
|
170
|
+
channelId: m.channel,
|
|
171
|
+
channelName: m.channelName,
|
|
172
|
+
ts: m.ts,
|
|
173
|
+
blocks: m.blocks,
|
|
174
|
+
editableVia: 'bot', // defaults to 'bot' if omitted
|
|
175
|
+
label: m.preview // one-line preview shown in the picker row
|
|
176
|
+
}));
|
|
177
|
+
}
|
|
178
|
+
}}
|
|
179
|
+
/>
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
- On `ok`, the builder hydrates with `blocks`, shows an edit-mode badge, locks
|
|
183
|
+
the destination to the source channel, and fixes the post-as identity to
|
|
184
|
+
`editableVia` (the `'user'` path reuses `loadSendAsUserStatus` for the "Sign
|
|
185
|
+
in with Slack" gate).
|
|
186
|
+
- On `{ ok: false, reason }`, the load dialog renders the reason inline and
|
|
187
|
+
offers **Open as a new message instead**. Pass `blocks` on the failure
|
|
188
|
+
result to hydrate the draft for that fallback.
|
|
189
|
+
|
|
126
190
|
## Customizing the palette
|
|
127
191
|
|
|
128
192
|
The default palette ships with curated presets for every supported block type. To narrow what's available, or add your own pre-configured variants (e.g. a "Help footer" section), pass a `palette` array. Define it at module scope (or wrap in `useMemo`) so it stays referentially stable across renders.
|
package/dist/helpers.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { T as SupportedBlock } from './palette-Bup05opK.cjs';
|
|
2
|
+
export { U as SupportedBlockType } from './palette-Bup05opK.cjs';
|
|
3
3
|
import 'react';
|
|
4
4
|
import 'slack-web-api-client';
|
|
5
5
|
|
package/dist/helpers.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { T as SupportedBlock } from './palette-Bup05opK.js';
|
|
2
|
+
export { U as SupportedBlockType } from './palette-Bup05opK.js';
|
|
3
3
|
import 'react';
|
|
4
4
|
import 'slack-web-api-client';
|
|
5
5
|
|