@tightknitai/block-kitchen 0.8.4 → 0.8.5
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/dist/helpers.cjs.map +1 -1
- package/dist/helpers.js.map +1 -1
- package/dist/index.cjs +61 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -4
- package/dist/index.d.ts +3 -4
- package/dist/index.js +61 -24
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react from 'react';
|
|
2
2
|
import { B as BlockKitchenProps, E as Template, q as PreviewSurface, r as PreviewTheme } from './palette-Dco-CVMi.cjs';
|
|
3
3
|
export { A as AlertBlock, a as AlertLevel, b as BrandPreset, c as BrandTheme, d as BrandTokens, e as BuilderBlock, C as CardBlock, f as CarouselBlock, g as ChannelOption, h as ContextActionsBlock, i as ContextActionsElement, j as CustomEmoji, F as FeedbackButtonSubobject, k as FeedbackButtonsElement, H as HeaderLevel, I as IconButtonElement, l as IconButtonIcon, m as InputBlock, M as MarkdownBlock, P as PaletteSection, n as PaletteVariant, o as PlanBlock, p as PreviewHooks, S as SendAsUserStatus, s as SendPayload, t as SendResult, u as SupportedBlock, v as SupportedBlockType, w as SupportedHeaderBlock, T as TableBlock, x as TableCell, y as TableColumnSetting, z as TaskCardBlock, D as TaskCardStatus, U as UrlSourceElement, V as VideoBlock, J as defaultPalette, K as extraAlertVariant, L as legacyInputVariants } from './palette-Dco-CVMi.cjs';
|
|
4
4
|
export { decodeBlocksFromString, encodeBlocksToString, toSlackBlocks } from './helpers.cjs';
|
|
5
|
-
import 'react';
|
|
6
5
|
import 'slack-web-api-client';
|
|
7
6
|
|
|
8
7
|
/**
|
|
@@ -13,7 +12,7 @@ import 'slack-web-api-client';
|
|
|
13
12
|
* @param props - {@link BlockKitchenProps}
|
|
14
13
|
* @returns the rendered Block Kit Builder
|
|
15
14
|
*/
|
|
16
|
-
declare function BlockKitchen(props: BlockKitchenProps):
|
|
15
|
+
declare function BlockKitchen(props: BlockKitchenProps): react.JSX.Element;
|
|
17
16
|
|
|
18
17
|
/**
|
|
19
18
|
* Standalone, page-sized picker that displays {@link Template}s as a
|
|
@@ -50,6 +49,6 @@ declare function TemplatePicker({ templates, onSelect, surface, theme, heading,
|
|
|
50
49
|
heading?: string;
|
|
51
50
|
emptyLabel?: string;
|
|
52
51
|
className?: string;
|
|
53
|
-
}):
|
|
52
|
+
}): react.JSX.Element;
|
|
54
53
|
|
|
55
54
|
export { BlockKitchen, BlockKitchenProps, PreviewSurface, PreviewTheme, Template, TemplatePicker };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react from 'react';
|
|
2
2
|
import { B as BlockKitchenProps, E as Template, q as PreviewSurface, r as PreviewTheme } from './palette-Dco-CVMi.js';
|
|
3
3
|
export { A as AlertBlock, a as AlertLevel, b as BrandPreset, c as BrandTheme, d as BrandTokens, e as BuilderBlock, C as CardBlock, f as CarouselBlock, g as ChannelOption, h as ContextActionsBlock, i as ContextActionsElement, j as CustomEmoji, F as FeedbackButtonSubobject, k as FeedbackButtonsElement, H as HeaderLevel, I as IconButtonElement, l as IconButtonIcon, m as InputBlock, M as MarkdownBlock, P as PaletteSection, n as PaletteVariant, o as PlanBlock, p as PreviewHooks, S as SendAsUserStatus, s as SendPayload, t as SendResult, u as SupportedBlock, v as SupportedBlockType, w as SupportedHeaderBlock, T as TableBlock, x as TableCell, y as TableColumnSetting, z as TaskCardBlock, D as TaskCardStatus, U as UrlSourceElement, V as VideoBlock, J as defaultPalette, K as extraAlertVariant, L as legacyInputVariants } from './palette-Dco-CVMi.js';
|
|
4
4
|
export { decodeBlocksFromString, encodeBlocksToString, toSlackBlocks } from './helpers.js';
|
|
5
|
-
import 'react';
|
|
6
5
|
import 'slack-web-api-client';
|
|
7
6
|
|
|
8
7
|
/**
|
|
@@ -13,7 +12,7 @@ import 'slack-web-api-client';
|
|
|
13
12
|
* @param props - {@link BlockKitchenProps}
|
|
14
13
|
* @returns the rendered Block Kit Builder
|
|
15
14
|
*/
|
|
16
|
-
declare function BlockKitchen(props: BlockKitchenProps):
|
|
15
|
+
declare function BlockKitchen(props: BlockKitchenProps): react.JSX.Element;
|
|
17
16
|
|
|
18
17
|
/**
|
|
19
18
|
* Standalone, page-sized picker that displays {@link Template}s as a
|
|
@@ -50,6 +49,6 @@ declare function TemplatePicker({ templates, onSelect, surface, theme, heading,
|
|
|
50
49
|
heading?: string;
|
|
51
50
|
emptyLabel?: string;
|
|
52
51
|
className?: string;
|
|
53
|
-
}):
|
|
52
|
+
}): react.JSX.Element;
|
|
54
53
|
|
|
55
54
|
export { BlockKitchen, BlockKitchenProps, PreviewSurface, PreviewTheme, Template, TemplatePicker };
|
package/dist/index.js
CHANGED
|
@@ -1640,6 +1640,12 @@ function isSafeHref(value) {
|
|
|
1640
1640
|
}
|
|
1641
1641
|
return SAFE_LINK_PROTOCOLS.test(scheme);
|
|
1642
1642
|
}
|
|
1643
|
+
function hasExplicitSafeScheme(value) {
|
|
1644
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
1645
|
+
return false;
|
|
1646
|
+
}
|
|
1647
|
+
return getScheme(value) !== null && isSafeHref(value);
|
|
1648
|
+
}
|
|
1643
1649
|
function isSafeImageSrc(value) {
|
|
1644
1650
|
if (value === null || value === void 0) {
|
|
1645
1651
|
return false;
|
|
@@ -5372,6 +5378,17 @@ function blockElementToPM(el, resolveEmoji) {
|
|
|
5372
5378
|
}
|
|
5373
5379
|
return null;
|
|
5374
5380
|
}
|
|
5381
|
+
function pushTextWithHardBreaks(out, text, marks) {
|
|
5382
|
+
const segments = text.split("\n");
|
|
5383
|
+
segments.forEach((segment, i) => {
|
|
5384
|
+
if (i > 0) {
|
|
5385
|
+
out.push({ type: "hardBreak" });
|
|
5386
|
+
}
|
|
5387
|
+
if (segment) {
|
|
5388
|
+
out.push({ type: "text", text: segment, marks });
|
|
5389
|
+
}
|
|
5390
|
+
});
|
|
5391
|
+
}
|
|
5375
5392
|
function inlinesToPM(inlines, resolveEmoji) {
|
|
5376
5393
|
const out = [];
|
|
5377
5394
|
for (const inline of inlines) {
|
|
@@ -5379,8 +5396,7 @@ function inlinesToPM(inlines, resolveEmoji) {
|
|
|
5379
5396
|
if (!inline.text) {
|
|
5380
5397
|
continue;
|
|
5381
5398
|
}
|
|
5382
|
-
|
|
5383
|
-
out.push({ type: "text", text: inline.text, marks });
|
|
5399
|
+
pushTextWithHardBreaks(out, inline.text, styleToMarks(inline.style));
|
|
5384
5400
|
} else if (inline.type === "emoji") {
|
|
5385
5401
|
const attrs = resolveEmoji(inline);
|
|
5386
5402
|
if (!attrs.name) {
|
|
@@ -5517,6 +5533,10 @@ function proseMirrorInlinesToRichTextElements(nodes) {
|
|
|
5517
5533
|
out.push(emoji);
|
|
5518
5534
|
continue;
|
|
5519
5535
|
}
|
|
5536
|
+
if (node.type === "hardBreak") {
|
|
5537
|
+
out.push({ type: "text", text: "\n" });
|
|
5538
|
+
continue;
|
|
5539
|
+
}
|
|
5520
5540
|
if (node.type !== "text" || !node.text) {
|
|
5521
5541
|
continue;
|
|
5522
5542
|
}
|
|
@@ -6204,6 +6224,43 @@ function LossyBanner({ reasons }) {
|
|
|
6204
6224
|
] })
|
|
6205
6225
|
] });
|
|
6206
6226
|
}
|
|
6227
|
+
var RICH_TEXT_INPUT_RULE_ALLOWLIST = ["bold", "italic", "strike", "code"];
|
|
6228
|
+
function buildRichTextExtensions() {
|
|
6229
|
+
return [
|
|
6230
|
+
StarterKit.configure({
|
|
6231
|
+
heading: false,
|
|
6232
|
+
horizontalRule: false,
|
|
6233
|
+
// StarterKit bundles its own Link extension (enabled by default),
|
|
6234
|
+
// which would register a second, unconfigured `link` mark and a
|
|
6235
|
+
// duplicate autolinker alongside the hardened one we add below.
|
|
6236
|
+
// Disable it so our single, security-configured Link is the only
|
|
6237
|
+
// link extension in the schema.
|
|
6238
|
+
link: false
|
|
6239
|
+
}),
|
|
6240
|
+
EmojiNode,
|
|
6241
|
+
Link.configure({
|
|
6242
|
+
openOnClick: false,
|
|
6243
|
+
autolink: true,
|
|
6244
|
+
defaultProtocol: "https",
|
|
6245
|
+
// Pin TipTap's link allowlist to the same set as our shared
|
|
6246
|
+
// `isSafeHref` helper. The upstream default also includes
|
|
6247
|
+
// ftp/cid/callto which we don't expect inside Slack content.
|
|
6248
|
+
protocols: ["http", "https", "mailto", "tel", "sms", "xmpp"],
|
|
6249
|
+
// Belt-and-suspenders: even if a downstream contributor widens
|
|
6250
|
+
// `protocols` later, our isSafeHref guard rejects everything
|
|
6251
|
+
// outside the safe-link set. setLink and toggleLink both gate
|
|
6252
|
+
// on this hook before applying the mark.
|
|
6253
|
+
isAllowedUri: (url) => isSafeHref(url),
|
|
6254
|
+
// Only auto-link tokens that carry an explicit, safe scheme. TipTap's
|
|
6255
|
+
// default would link any `host.tld` (e.g. `2.xyz`, `report.zip`,
|
|
6256
|
+
// `logo.png`) because the suffix is a real gTLD, which is wrong for
|
|
6257
|
+
// free-form Slack message text. Deliberate links can still be added
|
|
6258
|
+
// via the link button.
|
|
6259
|
+
shouldAutoLink: hasExplicitSafeScheme,
|
|
6260
|
+
HTMLAttributes: { rel: "noreferrer noopener", target: "_blank" }
|
|
6261
|
+
})
|
|
6262
|
+
];
|
|
6263
|
+
}
|
|
6207
6264
|
function RichTextWysiwygEditor({ block, onChange }) {
|
|
6208
6265
|
const lastEmittedRef = useRef(null);
|
|
6209
6266
|
const { byName: customByName } = useCustomEmojis();
|
|
@@ -6229,28 +6286,8 @@ function RichTextWysiwygEditor({ block, onChange }) {
|
|
|
6229
6286
|
[onChange]
|
|
6230
6287
|
);
|
|
6231
6288
|
const editor = useEditor({
|
|
6232
|
-
extensions:
|
|
6233
|
-
|
|
6234
|
-
heading: false,
|
|
6235
|
-
horizontalRule: false
|
|
6236
|
-
}),
|
|
6237
|
-
EmojiNode,
|
|
6238
|
-
Link.configure({
|
|
6239
|
-
openOnClick: false,
|
|
6240
|
-
autolink: true,
|
|
6241
|
-
defaultProtocol: "https",
|
|
6242
|
-
// Pin TipTap's link allowlist to the same set as our shared
|
|
6243
|
-
// `isSafeHref` helper. The upstream default also includes
|
|
6244
|
-
// ftp/cid/callto which we don't expect inside Slack content.
|
|
6245
|
-
protocols: ["http", "https", "mailto", "tel", "sms", "xmpp"],
|
|
6246
|
-
// Belt-and-suspenders: even if a downstream contributor widens
|
|
6247
|
-
// `protocols` later, our isSafeHref guard rejects everything
|
|
6248
|
-
// outside the safe-link set. setLink and toggleLink both gate
|
|
6249
|
-
// on this hook before applying the mark.
|
|
6250
|
-
isAllowedUri: (url) => isSafeHref(url),
|
|
6251
|
-
HTMLAttributes: { rel: "noreferrer noopener", target: "_blank" }
|
|
6252
|
-
})
|
|
6253
|
-
],
|
|
6289
|
+
extensions: buildRichTextExtensions(),
|
|
6290
|
+
enableInputRules: RICH_TEXT_INPUT_RULE_ALLOWLIST,
|
|
6254
6291
|
content: richTextToProseMirror(block, resolveEmoji),
|
|
6255
6292
|
editorProps: {
|
|
6256
6293
|
attributes: {
|