@tightknitai/block-kitchen 0.10.18 → 0.10.20
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 +27 -0
- package/dist/helpers.d.cts +2 -2
- package/dist/helpers.d.ts +2 -2
- package/dist/index.cjs +822 -160
- 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 +825 -163
- package/dist/index.js.map +1 -1
- package/dist/{palette-Cxh1yNzW.d.cts → palette-4BJw_nd7.d.cts} +99 -7
- package/dist/{palette-Cxh1yNzW.d.ts → palette-4BJw_nd7.d.ts} +99 -7
- package/dist/palette.cjs +52 -0
- package/dist/palette.cjs.map +1 -1
- package/dist/palette.d.cts +1 -1
- package/dist/palette.d.ts +1 -1
- package/dist/palette.js +52 -0
- package/dist/palette.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +15 -4
package/dist/index.cjs
CHANGED
|
@@ -22,6 +22,7 @@ var RadioGroupPrimitive = require('@radix-ui/react-radio-group');
|
|
|
22
22
|
var Link = require('@tiptap/extension-link');
|
|
23
23
|
var react = require('@tiptap/react');
|
|
24
24
|
var StarterKit = require('@tiptap/starter-kit');
|
|
25
|
+
var suggestion = require('@tiptap/suggestion');
|
|
25
26
|
|
|
26
27
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
27
28
|
|
|
@@ -1095,6 +1096,58 @@ var defaultPalette = [
|
|
|
1095
1096
|
]
|
|
1096
1097
|
]
|
|
1097
1098
|
})
|
|
1099
|
+
},
|
|
1100
|
+
{
|
|
1101
|
+
// Slack's documented example.
|
|
1102
|
+
id: "data_table_basic",
|
|
1103
|
+
label: "Data table",
|
|
1104
|
+
factory: () => ({
|
|
1105
|
+
type: "data_table",
|
|
1106
|
+
caption: "A Fabulous Table",
|
|
1107
|
+
rows: [
|
|
1108
|
+
[
|
|
1109
|
+
{ type: "raw_text", text: "Name" },
|
|
1110
|
+
{ type: "raw_text", text: "Department" },
|
|
1111
|
+
{ type: "raw_text", text: "Badge" }
|
|
1112
|
+
],
|
|
1113
|
+
[
|
|
1114
|
+
{ type: "raw_text", text: "Data Refinement Department" },
|
|
1115
|
+
{ type: "raw_text", text: "MDR" },
|
|
1116
|
+
{
|
|
1117
|
+
type: "rich_text",
|
|
1118
|
+
elements: [
|
|
1119
|
+
{ type: "rich_text_section", elements: [{ type: "text", text: "Blue", style: { bold: true } }] }
|
|
1120
|
+
]
|
|
1121
|
+
}
|
|
1122
|
+
],
|
|
1123
|
+
[
|
|
1124
|
+
{ type: "raw_text", text: "Art Sourcing Department" },
|
|
1125
|
+
{ type: "raw_text", text: "O&D" },
|
|
1126
|
+
{
|
|
1127
|
+
type: "rich_text",
|
|
1128
|
+
elements: [
|
|
1129
|
+
{
|
|
1130
|
+
type: "rich_text_section",
|
|
1131
|
+
elements: [
|
|
1132
|
+
{ type: "text", text: "Green " },
|
|
1133
|
+
{ type: "text", text: "review", style: { italic: true } }
|
|
1134
|
+
]
|
|
1135
|
+
}
|
|
1136
|
+
]
|
|
1137
|
+
}
|
|
1138
|
+
],
|
|
1139
|
+
[
|
|
1140
|
+
{ type: "raw_text", text: "Wellness Department" },
|
|
1141
|
+
{ type: "raw_text", text: "Wellness Center" },
|
|
1142
|
+
{
|
|
1143
|
+
type: "rich_text",
|
|
1144
|
+
elements: [
|
|
1145
|
+
{ type: "rich_text_section", elements: [{ type: "text", text: "Limited", style: { bold: true } }] }
|
|
1146
|
+
]
|
|
1147
|
+
}
|
|
1148
|
+
]
|
|
1149
|
+
]
|
|
1150
|
+
})
|
|
1098
1151
|
}
|
|
1099
1152
|
]
|
|
1100
1153
|
},
|
|
@@ -1759,6 +1812,8 @@ function labelForBlockType(type) {
|
|
|
1759
1812
|
return "Data Visualization";
|
|
1760
1813
|
case "container":
|
|
1761
1814
|
return "Container";
|
|
1815
|
+
case "data_table":
|
|
1816
|
+
return "Data Table";
|
|
1762
1817
|
}
|
|
1763
1818
|
}
|
|
1764
1819
|
var Sheet = DialogPrimitive__namespace.Root;
|
|
@@ -1863,6 +1918,13 @@ function CustomEmojiProvider({ customEmojis, children }) {
|
|
|
1863
1918
|
function useCustomEmojis() {
|
|
1864
1919
|
return React.useContext(CustomEmojiContext);
|
|
1865
1920
|
}
|
|
1921
|
+
var MentionsContext = React.createContext(null);
|
|
1922
|
+
function MentionsProvider({ mentions, children }) {
|
|
1923
|
+
return /* @__PURE__ */ jsxRuntime.jsx(MentionsContext.Provider, { value: mentions ?? null, children });
|
|
1924
|
+
}
|
|
1925
|
+
function useMentions() {
|
|
1926
|
+
return React.useContext(MentionsContext);
|
|
1927
|
+
}
|
|
1866
1928
|
|
|
1867
1929
|
// src/lib/error-grouping.ts
|
|
1868
1930
|
function toValidatorSurface(surface) {
|
|
@@ -3363,12 +3425,27 @@ function ChannelCombobox({
|
|
|
3363
3425
|
] });
|
|
3364
3426
|
}
|
|
3365
3427
|
var EMBED_SELECTOR = "iframe[src], embed[src], object[data], source[src], video[src], audio[src], track[src]";
|
|
3428
|
+
function useLatestHooks(hooks) {
|
|
3429
|
+
const latest = React.useRef(hooks);
|
|
3430
|
+
latest.current = hooks;
|
|
3431
|
+
const [live] = React.useState(
|
|
3432
|
+
() => new Proxy(
|
|
3433
|
+
{},
|
|
3434
|
+
{
|
|
3435
|
+
get: (_target, key) => typeof key === "string" ? latest.current?.[key] : void 0,
|
|
3436
|
+
has: (_target, key) => typeof key === "string" && latest.current !== void 0 && key in latest.current
|
|
3437
|
+
}
|
|
3438
|
+
)
|
|
3439
|
+
);
|
|
3440
|
+
return live;
|
|
3441
|
+
}
|
|
3366
3442
|
function SlackBlockPreview({
|
|
3367
3443
|
block,
|
|
3368
3444
|
hooks,
|
|
3369
3445
|
theme = "light"
|
|
3370
3446
|
}) {
|
|
3371
3447
|
const rootRef = React.useRef(null);
|
|
3448
|
+
const liveHooks = useLatestHooks(hooks);
|
|
3372
3449
|
const safeBlock = React.useMemo(() => sanitizeBlock(block), [block]);
|
|
3373
3450
|
React.useEffect(() => {
|
|
3374
3451
|
const root = rootRef.current;
|
|
@@ -3423,7 +3500,7 @@ function SlackBlockPreview({
|
|
|
3423
3500
|
withoutWrapper: true,
|
|
3424
3501
|
theme,
|
|
3425
3502
|
blocks: [safeBlock],
|
|
3426
|
-
hooks
|
|
3503
|
+
hooks: liveHooks
|
|
3427
3504
|
}
|
|
3428
3505
|
) })
|
|
3429
3506
|
);
|
|
@@ -5196,14 +5273,16 @@ function makeEmojiImportResolver(customByName, index = getEmojiIndex()) {
|
|
|
5196
5273
|
}
|
|
5197
5274
|
|
|
5198
5275
|
// src/lib/rich-text-tiptap.ts
|
|
5276
|
+
var USER_MENTION_NODE = "userMention";
|
|
5199
5277
|
var SUPPORTED_BLOCK_KINDS = /* @__PURE__ */ new Set([
|
|
5200
5278
|
"rich_text_section",
|
|
5201
5279
|
"rich_text_list",
|
|
5202
5280
|
"rich_text_quote",
|
|
5203
5281
|
"rich_text_preformatted"
|
|
5204
5282
|
]);
|
|
5205
|
-
var SUPPORTED_INLINE_KINDS = /* @__PURE__ */ new Set(["text", "link", "emoji"]);
|
|
5283
|
+
var SUPPORTED_INLINE_KINDS = /* @__PURE__ */ new Set(["text", "link", "emoji", "user"]);
|
|
5206
5284
|
var SUPPORTED_TEXT_STYLE_KEYS = /* @__PURE__ */ new Set(["bold", "italic", "strike", "underline", "code"]);
|
|
5285
|
+
var SUPPORTED_USER_STYLE_KEYS = /* @__PURE__ */ new Set(["bold", "italic", "strike", "underline"]);
|
|
5207
5286
|
var MAX_LIST_INDENT = 8;
|
|
5208
5287
|
function detectLossy(block) {
|
|
5209
5288
|
const out = [];
|
|
@@ -5226,6 +5305,17 @@ function detectLossy(block) {
|
|
|
5226
5305
|
if ("border" in el && (el.border ?? 0) > 0) {
|
|
5227
5306
|
out.push({ label: "Quote/preformatted border", where });
|
|
5228
5307
|
}
|
|
5308
|
+
if (el.type === "rich_text_preformatted") {
|
|
5309
|
+
el.elements?.forEach((inline, i) => {
|
|
5310
|
+
const sub = `${where}.elements[${i}]`;
|
|
5311
|
+
if (inline.type !== "text") {
|
|
5312
|
+
out.push({ label: `In code block: ${inline.type}`, where: sub });
|
|
5313
|
+
} else if (Object.values(inline.style ?? {}).some(Boolean)) {
|
|
5314
|
+
out.push({ label: "Styled text in code block", where: sub });
|
|
5315
|
+
}
|
|
5316
|
+
});
|
|
5317
|
+
return;
|
|
5318
|
+
}
|
|
5229
5319
|
scanInlines(el.elements ?? [], where, out);
|
|
5230
5320
|
});
|
|
5231
5321
|
return out;
|
|
@@ -5247,6 +5337,13 @@ function scanInlines(inlines, where, out) {
|
|
|
5247
5337
|
}
|
|
5248
5338
|
}
|
|
5249
5339
|
}
|
|
5340
|
+
if (inline.type === "user") {
|
|
5341
|
+
for (const k of Object.keys(inline.style ?? {})) {
|
|
5342
|
+
if (!SUPPORTED_USER_STYLE_KEYS.has(k)) {
|
|
5343
|
+
out.push({ label: `Mention style: ${k}`, where: sub });
|
|
5344
|
+
}
|
|
5345
|
+
}
|
|
5346
|
+
}
|
|
5250
5347
|
});
|
|
5251
5348
|
}
|
|
5252
5349
|
var defaultEmojiResolver = (el) => ({
|
|
@@ -5358,6 +5455,17 @@ function inlinesToPM(inlines, resolveEmoji) {
|
|
|
5358
5455
|
continue;
|
|
5359
5456
|
}
|
|
5360
5457
|
out.push({ type: "emoji", attrs });
|
|
5458
|
+
} else if (inline.type === "user") {
|
|
5459
|
+
const user = inline;
|
|
5460
|
+
if (!user.user_id) {
|
|
5461
|
+
continue;
|
|
5462
|
+
}
|
|
5463
|
+
const node = { type: USER_MENTION_NODE, attrs: { userId: user.user_id, name: null } };
|
|
5464
|
+
const marks = styleToMarks(user.style);
|
|
5465
|
+
if (marks.length > 0) {
|
|
5466
|
+
node.marks = marks;
|
|
5467
|
+
}
|
|
5468
|
+
out.push(node);
|
|
5361
5469
|
} else if (inline.type === "link") {
|
|
5362
5470
|
const link = inline;
|
|
5363
5471
|
const text = link.text || link.url || "";
|
|
@@ -5491,6 +5599,19 @@ function proseMirrorInlinesToRichTextElements(nodes) {
|
|
|
5491
5599
|
out.push(emoji);
|
|
5492
5600
|
continue;
|
|
5493
5601
|
}
|
|
5602
|
+
if (node.type === USER_MENTION_NODE) {
|
|
5603
|
+
const userId = String(node.attrs?.userId ?? "");
|
|
5604
|
+
if (!userId) {
|
|
5605
|
+
continue;
|
|
5606
|
+
}
|
|
5607
|
+
const user = { type: "user", user_id: userId };
|
|
5608
|
+
const style2 = userStyle(node.marks ?? []);
|
|
5609
|
+
if (Object.keys(style2).length > 0) {
|
|
5610
|
+
user.style = style2;
|
|
5611
|
+
}
|
|
5612
|
+
out.push(user);
|
|
5613
|
+
continue;
|
|
5614
|
+
}
|
|
5494
5615
|
if (node.type === "hardBreak") {
|
|
5495
5616
|
out.push({ type: "text", text: "\n" });
|
|
5496
5617
|
continue;
|
|
@@ -5545,6 +5666,15 @@ function marksToStyle(marks) {
|
|
|
5545
5666
|
}
|
|
5546
5667
|
return style;
|
|
5547
5668
|
}
|
|
5669
|
+
function userStyle(marks) {
|
|
5670
|
+
const style = {};
|
|
5671
|
+
for (const [key, value] of Object.entries(marksToStyle(marks))) {
|
|
5672
|
+
if (SUPPORTED_USER_STYLE_KEYS.has(key)) {
|
|
5673
|
+
style[key] = value;
|
|
5674
|
+
}
|
|
5675
|
+
}
|
|
5676
|
+
return style;
|
|
5677
|
+
}
|
|
5548
5678
|
function mergeAdjacentTextRuns(inlines) {
|
|
5549
5679
|
const out = [];
|
|
5550
5680
|
for (const inline of inlines) {
|
|
@@ -5611,6 +5741,91 @@ var EmojiNode = react.Node.create({
|
|
|
5611
5741
|
return react.ReactNodeViewRenderer(EmojiNodeView);
|
|
5612
5742
|
}
|
|
5613
5743
|
});
|
|
5744
|
+
var MENTION_SEARCH_DEBOUNCE_MS = 200;
|
|
5745
|
+
function insertUserMention(editor, range, user) {
|
|
5746
|
+
const to = editor.state.doc.textBetween(range.to, Math.min(range.to + 1, editor.state.doc.content.size)) === " " ? range.to + 1 : range.to;
|
|
5747
|
+
editor.chain().focus().insertContentAt({ from: range.from, to }, [
|
|
5748
|
+
{ type: USER_MENTION_NODE, attrs: { userId: user.id, name: user.name } },
|
|
5749
|
+
{ type: "text", text: " " }
|
|
5750
|
+
]).run();
|
|
5751
|
+
}
|
|
5752
|
+
function insertMentionTrigger(editor) {
|
|
5753
|
+
const { from } = editor.state.selection;
|
|
5754
|
+
const before = from > 1 ? editor.state.doc.textBetween(from - 1, from, void 0, "\uFFFC") : "";
|
|
5755
|
+
const needsSpace = before !== "" && !/\s/.test(before);
|
|
5756
|
+
editor.chain().focus().insertContent(needsSpace ? " @" : "@").run();
|
|
5757
|
+
}
|
|
5758
|
+
function dismissMentionSuggestion(editor) {
|
|
5759
|
+
suggestion.exitSuggestion(editor.view);
|
|
5760
|
+
}
|
|
5761
|
+
var MentionSuggestion = react.Extension.create({
|
|
5762
|
+
name: "userMentionSuggestion",
|
|
5763
|
+
addOptions() {
|
|
5764
|
+
return {
|
|
5765
|
+
isEnabled: () => false,
|
|
5766
|
+
search: async () => [],
|
|
5767
|
+
render: () => ({})
|
|
5768
|
+
};
|
|
5769
|
+
},
|
|
5770
|
+
addProseMirrorPlugins() {
|
|
5771
|
+
const { isEnabled, search, render } = this.options;
|
|
5772
|
+
return [
|
|
5773
|
+
suggestion.Suggestion({
|
|
5774
|
+
editor: this.editor,
|
|
5775
|
+
char: "@",
|
|
5776
|
+
debounce: MENTION_SEARCH_DEBOUNCE_MS,
|
|
5777
|
+
allow: () => isEnabled(),
|
|
5778
|
+
items: ({ query, signal }) => search(query, signal),
|
|
5779
|
+
command: ({ editor, range, props }) => insertUserMention(editor, range, props),
|
|
5780
|
+
render
|
|
5781
|
+
})
|
|
5782
|
+
];
|
|
5783
|
+
}
|
|
5784
|
+
});
|
|
5785
|
+
function userMentionLabel(attrs, getUserName) {
|
|
5786
|
+
return getUserName?.(attrs.userId) ?? attrs.name ?? attrs.userId;
|
|
5787
|
+
}
|
|
5788
|
+
function UserMentionNodeView({ node }) {
|
|
5789
|
+
const mentions = useMentions();
|
|
5790
|
+
const attrs = node.attrs;
|
|
5791
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(react.NodeViewWrapper, { as: "span", className: "bk-user-mention", "data-user-mention": attrs.userId, children: [
|
|
5792
|
+
"@",
|
|
5793
|
+
userMentionLabel(attrs, mentions?.getUserName)
|
|
5794
|
+
] });
|
|
5795
|
+
}
|
|
5796
|
+
var UserMentionNode = react.Node.create({
|
|
5797
|
+
name: USER_MENTION_NODE,
|
|
5798
|
+
group: "inline",
|
|
5799
|
+
inline: true,
|
|
5800
|
+
atom: true,
|
|
5801
|
+
selectable: true,
|
|
5802
|
+
addAttributes() {
|
|
5803
|
+
return {
|
|
5804
|
+
userId: {
|
|
5805
|
+
default: "",
|
|
5806
|
+
parseHTML: (element) => element.getAttribute("data-user-mention") ?? "",
|
|
5807
|
+
renderHTML: (attributes) => ({ "data-user-mention": attributes.userId })
|
|
5808
|
+
},
|
|
5809
|
+
name: {
|
|
5810
|
+
default: null,
|
|
5811
|
+
parseHTML: (element) => element.getAttribute("data-user-name"),
|
|
5812
|
+
renderHTML: (attributes) => attributes.name ? { "data-user-name": attributes.name } : {}
|
|
5813
|
+
}
|
|
5814
|
+
};
|
|
5815
|
+
},
|
|
5816
|
+
parseHTML() {
|
|
5817
|
+
return [{ tag: "span[data-user-mention]" }];
|
|
5818
|
+
},
|
|
5819
|
+
renderHTML({ node, HTMLAttributes }) {
|
|
5820
|
+
return ["span", react.mergeAttributes(HTMLAttributes), `@${userMentionLabel(node.attrs)}`];
|
|
5821
|
+
},
|
|
5822
|
+
renderText({ node }) {
|
|
5823
|
+
return `@${userMentionLabel(node.attrs)}`;
|
|
5824
|
+
},
|
|
5825
|
+
addNodeView() {
|
|
5826
|
+
return react.ReactNodeViewRenderer(UserMentionNodeView);
|
|
5827
|
+
}
|
|
5828
|
+
});
|
|
5614
5829
|
|
|
5615
5830
|
// src/lib/emoji-recents.ts
|
|
5616
5831
|
var STORAGE_KEY = "bk:emoji-recents";
|
|
@@ -5892,6 +6107,133 @@ function EmojiPickerButton({
|
|
|
5892
6107
|
) })
|
|
5893
6108
|
] });
|
|
5894
6109
|
}
|
|
6110
|
+
function nextMentionPickerState(props, prev) {
|
|
6111
|
+
return {
|
|
6112
|
+
items: props.loading && prev ? prev.items : props.items,
|
|
6113
|
+
loading: props.loading,
|
|
6114
|
+
clientRect: props.clientRect ?? null,
|
|
6115
|
+
command: props.command
|
|
6116
|
+
};
|
|
6117
|
+
}
|
|
6118
|
+
function MentionPicker({
|
|
6119
|
+
editor,
|
|
6120
|
+
state,
|
|
6121
|
+
keyHandlerRef,
|
|
6122
|
+
onDismiss
|
|
6123
|
+
}) {
|
|
6124
|
+
const { items, loading, clientRect, command } = state;
|
|
6125
|
+
const [activeIndex, setActiveIndex] = React.useState(0);
|
|
6126
|
+
const [shownItems, setShownItems] = React.useState(items);
|
|
6127
|
+
if (shownItems !== items) {
|
|
6128
|
+
setShownItems(items);
|
|
6129
|
+
setActiveIndex(0);
|
|
6130
|
+
}
|
|
6131
|
+
const listRef = React.useRef(null);
|
|
6132
|
+
React.useEffect(() => {
|
|
6133
|
+
keyHandlerRef.current = (event) => {
|
|
6134
|
+
if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
|
6135
|
+
if (items.length > 0) {
|
|
6136
|
+
const step = event.key === "ArrowDown" ? 1 : -1;
|
|
6137
|
+
setActiveIndex((index) => (index + step + items.length) % items.length);
|
|
6138
|
+
}
|
|
6139
|
+
return true;
|
|
6140
|
+
}
|
|
6141
|
+
if (event.key === "Enter" || event.key === "Tab") {
|
|
6142
|
+
const user = items[activeIndex];
|
|
6143
|
+
if (!user) {
|
|
6144
|
+
return false;
|
|
6145
|
+
}
|
|
6146
|
+
command(user);
|
|
6147
|
+
return true;
|
|
6148
|
+
}
|
|
6149
|
+
return false;
|
|
6150
|
+
};
|
|
6151
|
+
return () => {
|
|
6152
|
+
keyHandlerRef.current = () => false;
|
|
6153
|
+
};
|
|
6154
|
+
}, [keyHandlerRef, items, activeIndex, command]);
|
|
6155
|
+
React.useEffect(() => {
|
|
6156
|
+
const row = listRef.current?.querySelectorAll('[role="option"]')[activeIndex];
|
|
6157
|
+
row?.scrollIntoView?.({ block: "nearest" });
|
|
6158
|
+
}, [activeIndex]);
|
|
6159
|
+
const anchorRef = React.useMemo(
|
|
6160
|
+
() => ({
|
|
6161
|
+
current: {
|
|
6162
|
+
getBoundingClientRect: () => clientRect?.() ?? editor.view.dom.getBoundingClientRect()
|
|
6163
|
+
}
|
|
6164
|
+
}),
|
|
6165
|
+
[clientRect, editor]
|
|
6166
|
+
);
|
|
6167
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6168
|
+
Popover,
|
|
6169
|
+
{
|
|
6170
|
+
open: true,
|
|
6171
|
+
onOpenChange: (open) => {
|
|
6172
|
+
if (!open) {
|
|
6173
|
+
onDismiss();
|
|
6174
|
+
}
|
|
6175
|
+
},
|
|
6176
|
+
children: [
|
|
6177
|
+
/* @__PURE__ */ jsxRuntime.jsx(PopoverAnchor, { virtualRef: anchorRef }),
|
|
6178
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6179
|
+
PopoverContent,
|
|
6180
|
+
{
|
|
6181
|
+
side: "bottom",
|
|
6182
|
+
align: "start",
|
|
6183
|
+
sideOffset: 4,
|
|
6184
|
+
className: "max-h-[min(15rem,var(--radix-popover-content-available-height))] w-64 p-1",
|
|
6185
|
+
onOpenAutoFocus: (e) => e.preventDefault(),
|
|
6186
|
+
onCloseAutoFocus: (e) => e.preventDefault(),
|
|
6187
|
+
onEscapeKeyDown: (e) => e.stopPropagation(),
|
|
6188
|
+
onInteractOutside: (e) => {
|
|
6189
|
+
if (e.target instanceof Node && editor.view.dom.contains(e.target)) {
|
|
6190
|
+
e.preventDefault();
|
|
6191
|
+
}
|
|
6192
|
+
},
|
|
6193
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: listRef, role: "listbox", "aria-label": "People to mention", children: items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "px-2 py-3 text-center text-xs text-muted-foreground", children: loading ? "Searching\u2026" : "No people match that search." }) : items.map((user, index) => (
|
|
6194
|
+
// biome-ignore lint/a11y/useFocusableInteractive: focus stays in the editor, which drives this list through the suggestion plugin's key handling.
|
|
6195
|
+
// biome-ignore lint/a11y/useKeyWithClickEvents: the keyboard path is the editor's, forwarded via keyHandlerRef.
|
|
6196
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
6197
|
+
"div",
|
|
6198
|
+
{
|
|
6199
|
+
role: "option",
|
|
6200
|
+
"aria-selected": index === activeIndex,
|
|
6201
|
+
onPointerDown: (e) => e.preventDefault(),
|
|
6202
|
+
onClick: () => command(user),
|
|
6203
|
+
onMouseMove: () => setActiveIndex(index),
|
|
6204
|
+
className: cn(
|
|
6205
|
+
"flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm text-foreground",
|
|
6206
|
+
index === activeIndex && "bg-accent"
|
|
6207
|
+
),
|
|
6208
|
+
children: [
|
|
6209
|
+
/* @__PURE__ */ jsxRuntime.jsx(MentionAvatar, { user }),
|
|
6210
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: user.name })
|
|
6211
|
+
]
|
|
6212
|
+
},
|
|
6213
|
+
user.id
|
|
6214
|
+
)
|
|
6215
|
+
)) })
|
|
6216
|
+
}
|
|
6217
|
+
)
|
|
6218
|
+
]
|
|
6219
|
+
}
|
|
6220
|
+
);
|
|
6221
|
+
}
|
|
6222
|
+
function MentionAvatar({ user }) {
|
|
6223
|
+
const [failed, setFailed] = React.useState(false);
|
|
6224
|
+
const src = user.avatarUrl && isSafeImageSrc(user.avatarUrl) ? user.avatarUrl : null;
|
|
6225
|
+
if (src && !failed) {
|
|
6226
|
+
return /* @__PURE__ */ jsxRuntime.jsx("img", { src, alt: "", className: "h-5 w-5 shrink-0 rounded object-cover", onError: () => setFailed(true) });
|
|
6227
|
+
}
|
|
6228
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6229
|
+
"span",
|
|
6230
|
+
{
|
|
6231
|
+
"aria-hidden": "true",
|
|
6232
|
+
className: "flex h-5 w-5 shrink-0 items-center justify-center rounded bg-muted text-[10px] font-medium text-muted-foreground",
|
|
6233
|
+
children: Array.from(user.name.trim())[0]?.toUpperCase() ?? "@"
|
|
6234
|
+
}
|
|
6235
|
+
);
|
|
6236
|
+
}
|
|
5895
6237
|
var BLOCK_ELEMENT_LABEL = {
|
|
5896
6238
|
rich_text_section: "Section",
|
|
5897
6239
|
rich_text_list: "List",
|
|
@@ -6467,7 +6809,7 @@ function LossyBanner({ reasons }) {
|
|
|
6467
6809
|
] });
|
|
6468
6810
|
}
|
|
6469
6811
|
var RICH_TEXT_INPUT_RULE_ALLOWLIST = ["bold", "italic", "strike", "code"];
|
|
6470
|
-
function buildRichTextExtensions() {
|
|
6812
|
+
function buildRichTextExtensions(mentionSuggestion) {
|
|
6471
6813
|
return [
|
|
6472
6814
|
StarterKit__default.default.configure({
|
|
6473
6815
|
heading: false,
|
|
@@ -6500,7 +6842,11 @@ function buildRichTextExtensions() {
|
|
|
6500
6842
|
// via the link button.
|
|
6501
6843
|
shouldAutoLink: hasExplicitSafeScheme,
|
|
6502
6844
|
HTMLAttributes: { rel: "noreferrer noopener", target: "_blank" }
|
|
6503
|
-
})
|
|
6845
|
+
}),
|
|
6846
|
+
// Always registered, so mentions already in the content round-trip with
|
|
6847
|
+
// or without the picker.
|
|
6848
|
+
UserMentionNode,
|
|
6849
|
+
...mentionSuggestion ? [MentionSuggestion.configure(mentionSuggestion)] : []
|
|
6504
6850
|
];
|
|
6505
6851
|
}
|
|
6506
6852
|
function RichTextWysiwygEditor({ block, onChange }) {
|
|
@@ -6527,8 +6873,25 @@ function RichTextWysiwygEditor({ block, onChange }) {
|
|
|
6527
6873
|
},
|
|
6528
6874
|
[onChange]
|
|
6529
6875
|
);
|
|
6876
|
+
const mentions = useMentions();
|
|
6877
|
+
const mentionsEnabled = mentions !== null;
|
|
6878
|
+
const mentionsRef = React.useRef(mentions);
|
|
6879
|
+
React.useEffect(() => {
|
|
6880
|
+
mentionsRef.current = mentions;
|
|
6881
|
+
}, [mentions]);
|
|
6882
|
+
const [mentionPicker, setMentionPicker] = React.useState(null);
|
|
6883
|
+
const mentionKeyHandlerRef = React.useRef(() => false);
|
|
6530
6884
|
const editor = react.useEditor({
|
|
6531
|
-
extensions: buildRichTextExtensions(
|
|
6885
|
+
extensions: buildRichTextExtensions({
|
|
6886
|
+
isEnabled: () => mentionsRef.current !== null,
|
|
6887
|
+
search: async (query, signal) => await mentionsRef.current?.searchUsers(query, { signal }) ?? [],
|
|
6888
|
+
render: () => ({
|
|
6889
|
+
onStart: (props) => setMentionPicker((prev) => nextMentionPickerState(props, prev)),
|
|
6890
|
+
onUpdate: (props) => setMentionPicker((prev) => nextMentionPickerState(props, prev)),
|
|
6891
|
+
onExit: () => setMentionPicker(null),
|
|
6892
|
+
onKeyDown: ({ event }) => mentionKeyHandlerRef.current(event)
|
|
6893
|
+
})
|
|
6894
|
+
}),
|
|
6532
6895
|
enableInputRules: RICH_TEXT_INPUT_RULE_ALLOWLIST,
|
|
6533
6896
|
content: richTextToProseMirror(block, resolveEmoji),
|
|
6534
6897
|
editorProps: {
|
|
@@ -6538,10 +6901,16 @@ function RichTextWysiwygEditor({ block, onChange }) {
|
|
|
6538
6901
|
},
|
|
6539
6902
|
onUpdate: ({ editor: ed }) => handleUpdate(ed)
|
|
6540
6903
|
});
|
|
6904
|
+
const seenBlockRef = React.useRef(block);
|
|
6541
6905
|
React.useEffect(() => {
|
|
6542
6906
|
if (!editor) {
|
|
6543
6907
|
return;
|
|
6544
6908
|
}
|
|
6909
|
+
const blockChanged = seenBlockRef.current !== block;
|
|
6910
|
+
seenBlockRef.current = block;
|
|
6911
|
+
if (!blockChanged && lastEmittedRef.current) {
|
|
6912
|
+
return;
|
|
6913
|
+
}
|
|
6545
6914
|
if (lastEmittedRef.current && JSON.stringify(lastEmittedRef.current) === JSON.stringify(block)) {
|
|
6546
6915
|
return;
|
|
6547
6916
|
}
|
|
@@ -6553,11 +6922,26 @@ function RichTextWysiwygEditor({ block, onChange }) {
|
|
|
6553
6922
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-[120px] rounded-md border border-input bg-background" });
|
|
6554
6923
|
}
|
|
6555
6924
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
6556
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6557
|
-
|
|
6925
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6926
|
+
Toolbar,
|
|
6927
|
+
{
|
|
6928
|
+
editor,
|
|
6929
|
+
mention: mentionsEnabled ? { active: mentionPicker !== null, insert: () => insertMentionTrigger(editor) } : null
|
|
6930
|
+
}
|
|
6931
|
+
),
|
|
6932
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.EditorContent, { editor }),
|
|
6933
|
+
mentionPicker && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6934
|
+
MentionPicker,
|
|
6935
|
+
{
|
|
6936
|
+
editor,
|
|
6937
|
+
state: mentionPicker,
|
|
6938
|
+
keyHandlerRef: mentionKeyHandlerRef,
|
|
6939
|
+
onDismiss: () => dismissMentionSuggestion(editor)
|
|
6940
|
+
}
|
|
6941
|
+
)
|
|
6558
6942
|
] });
|
|
6559
6943
|
}
|
|
6560
|
-
function Toolbar({ editor }) {
|
|
6944
|
+
function Toolbar({ editor, mention }) {
|
|
6561
6945
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-0.5 rounded-md border bg-muted/30 p-1", children: [
|
|
6562
6946
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6563
6947
|
ToolbarButton,
|
|
@@ -6616,6 +7000,7 @@ function Toolbar({ editor }) {
|
|
|
6616
7000
|
}).run()
|
|
6617
7001
|
}
|
|
6618
7002
|
),
|
|
7003
|
+
mention && /* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { label: "Mention", active: mention.active, onClick: mention.insert, Icon: lucideReact.AtSign }),
|
|
6619
7004
|
/* @__PURE__ */ jsxRuntime.jsx(Divider, {}),
|
|
6620
7005
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6621
7006
|
ToolbarButton,
|
|
@@ -7479,6 +7864,387 @@ function ImageItemCard({
|
|
|
7479
7864
|
) })
|
|
7480
7865
|
] });
|
|
7481
7866
|
}
|
|
7867
|
+
var REMOVE_BUTTON_CLASS = "flex h-6 w-6 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-destructive/10 hover:text-destructive disabled:cursor-not-allowed disabled:opacity-40";
|
|
7868
|
+
function CellGrid({
|
|
7869
|
+
label,
|
|
7870
|
+
help,
|
|
7871
|
+
rows,
|
|
7872
|
+
minRows,
|
|
7873
|
+
maxRows,
|
|
7874
|
+
maxColumns,
|
|
7875
|
+
lockFirstRow = false,
|
|
7876
|
+
blankCell,
|
|
7877
|
+
renderCell,
|
|
7878
|
+
renderColumnControl,
|
|
7879
|
+
onChange
|
|
7880
|
+
}) {
|
|
7881
|
+
const columnCount = rows[0]?.length ?? 0;
|
|
7882
|
+
const setCell = (rowIdx, colIdx, next) => {
|
|
7883
|
+
onChange(rows.map((row, r) => r === rowIdx ? row.map((cell, c) => c === colIdx ? next : cell) : row));
|
|
7884
|
+
};
|
|
7885
|
+
const addRow = () => {
|
|
7886
|
+
onChange([...rows, Array.from({ length: columnCount || 1 }, blankCell)]);
|
|
7887
|
+
};
|
|
7888
|
+
const removeRow = (rowIdx) => {
|
|
7889
|
+
if (rows.length <= minRows) {
|
|
7890
|
+
return;
|
|
7891
|
+
}
|
|
7892
|
+
onChange(rows.filter((_, r) => r !== rowIdx));
|
|
7893
|
+
};
|
|
7894
|
+
const addColumn = () => {
|
|
7895
|
+
onChange(
|
|
7896
|
+
rows.map((row) => [...row, blankCell()]),
|
|
7897
|
+
{ kind: "add" }
|
|
7898
|
+
);
|
|
7899
|
+
};
|
|
7900
|
+
const removeColumn = (colIdx) => {
|
|
7901
|
+
if (columnCount <= 1) {
|
|
7902
|
+
return;
|
|
7903
|
+
}
|
|
7904
|
+
onChange(
|
|
7905
|
+
rows.map((row) => row.filter((_, c) => c !== colIdx)),
|
|
7906
|
+
{ kind: "remove", index: colIdx }
|
|
7907
|
+
);
|
|
7908
|
+
};
|
|
7909
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
7910
|
+
/* @__PURE__ */ jsxRuntime.jsx(EditorField, { label, help, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 overflow-x-auto", children: [
|
|
7911
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
7912
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-6 shrink-0", "aria-hidden": "true" }),
|
|
7913
|
+
Array.from({ length: columnCount }, (_, c) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-[120px] flex-1 items-center gap-1", children: [
|
|
7914
|
+
renderColumnControl ? renderColumnControl(c) : /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex-1 truncate px-1.5 text-[11px] text-muted-foreground", children: [
|
|
7915
|
+
"Column ",
|
|
7916
|
+
c + 1
|
|
7917
|
+
] }),
|
|
7918
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7919
|
+
"button",
|
|
7920
|
+
{
|
|
7921
|
+
type: "button",
|
|
7922
|
+
"aria-label": `Remove column ${c + 1}`,
|
|
7923
|
+
onClick: () => removeColumn(c),
|
|
7924
|
+
disabled: columnCount <= 1,
|
|
7925
|
+
className: REMOVE_BUTTON_CLASS,
|
|
7926
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-3 w-3" })
|
|
7927
|
+
}
|
|
7928
|
+
)
|
|
7929
|
+
] }, c))
|
|
7930
|
+
] }),
|
|
7931
|
+
rows.map((row, r) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
7932
|
+
lockFirstRow && r === 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-6 shrink-0", "aria-hidden": "true" }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
7933
|
+
"button",
|
|
7934
|
+
{
|
|
7935
|
+
type: "button",
|
|
7936
|
+
"aria-label": `Remove row ${r + 1}`,
|
|
7937
|
+
onClick: () => removeRow(r),
|
|
7938
|
+
disabled: rows.length <= minRows,
|
|
7939
|
+
className: REMOVE_BUTTON_CLASS,
|
|
7940
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-3 w-3" })
|
|
7941
|
+
}
|
|
7942
|
+
),
|
|
7943
|
+
row.map((cell, c) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-w-[120px] flex-1 flex-col gap-0.5", children: renderCell(
|
|
7944
|
+
cell,
|
|
7945
|
+
{ row: r, col: c, label: `Row ${r + 1}, column ${c + 1}` },
|
|
7946
|
+
(next) => setCell(r, c, next)
|
|
7947
|
+
) }, c))
|
|
7948
|
+
] }, r))
|
|
7949
|
+
] }) }),
|
|
7950
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
|
|
7951
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", size: "sm", onClick: addRow, disabled: rows.length >= maxRows, children: [
|
|
7952
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3.5 w-3.5" }),
|
|
7953
|
+
" Add row"
|
|
7954
|
+
] }),
|
|
7955
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", size: "sm", onClick: addColumn, disabled: columnCount >= maxColumns, children: [
|
|
7956
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3.5 w-3.5" }),
|
|
7957
|
+
" Add column"
|
|
7958
|
+
] })
|
|
7959
|
+
] })
|
|
7960
|
+
] });
|
|
7961
|
+
}
|
|
7962
|
+
function CellTextInput({
|
|
7963
|
+
cell,
|
|
7964
|
+
label,
|
|
7965
|
+
placeholder,
|
|
7966
|
+
leading,
|
|
7967
|
+
richTextNote = "Was rich-text; editing replaces with plain text.",
|
|
7968
|
+
onChange
|
|
7969
|
+
}) {
|
|
7970
|
+
const input = /* @__PURE__ */ jsxRuntime.jsx(
|
|
7971
|
+
Input,
|
|
7972
|
+
{
|
|
7973
|
+
"aria-label": label,
|
|
7974
|
+
value: cell.type === "raw_text" ? cell.text : "[rich_text]",
|
|
7975
|
+
placeholder,
|
|
7976
|
+
onChange: (e) => onChange({ type: "raw_text", text: e.target.value }),
|
|
7977
|
+
className: "h-8 text-xs"
|
|
7978
|
+
}
|
|
7979
|
+
);
|
|
7980
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
7981
|
+
leading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
7982
|
+
leading,
|
|
7983
|
+
input
|
|
7984
|
+
] }) : input,
|
|
7985
|
+
cell.type === "rich_text" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-[10px] text-muted-foreground", leading && "pl-7"), children: richTextNote }) : null
|
|
7986
|
+
] });
|
|
7987
|
+
}
|
|
7988
|
+
function NumberInput({
|
|
7989
|
+
id,
|
|
7990
|
+
value,
|
|
7991
|
+
onCommit,
|
|
7992
|
+
ariaLabel,
|
|
7993
|
+
className
|
|
7994
|
+
}) {
|
|
7995
|
+
const [draft, setDraft] = React.useState(String(value));
|
|
7996
|
+
React.useEffect(() => {
|
|
7997
|
+
setDraft(String(value));
|
|
7998
|
+
}, [value]);
|
|
7999
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8000
|
+
Input,
|
|
8001
|
+
{
|
|
8002
|
+
id,
|
|
8003
|
+
type: "number",
|
|
8004
|
+
inputMode: "numeric",
|
|
8005
|
+
"aria-label": ariaLabel,
|
|
8006
|
+
value: draft,
|
|
8007
|
+
className,
|
|
8008
|
+
onChange: (e) => {
|
|
8009
|
+
const raw = e.target.value;
|
|
8010
|
+
setDraft(raw);
|
|
8011
|
+
if (raw === "" || raw === "-" || raw === "." || raw === "-.") {
|
|
8012
|
+
return;
|
|
8013
|
+
}
|
|
8014
|
+
const next = Number(raw);
|
|
8015
|
+
if (!Number.isNaN(next)) {
|
|
8016
|
+
onCommit(next);
|
|
8017
|
+
}
|
|
8018
|
+
},
|
|
8019
|
+
onBlur: () => {
|
|
8020
|
+
const next = Number(draft);
|
|
8021
|
+
const safe = draft.trim() === "" || Number.isNaN(next) ? 0 : next;
|
|
8022
|
+
onCommit(safe);
|
|
8023
|
+
setDraft(String(safe));
|
|
8024
|
+
}
|
|
8025
|
+
}
|
|
8026
|
+
);
|
|
8027
|
+
}
|
|
8028
|
+
var MAX_ROWS = 201;
|
|
8029
|
+
var MIN_ROWS = 2;
|
|
8030
|
+
var MAX_COLUMNS = 20;
|
|
8031
|
+
var MAX_PAGE_SIZE = 100;
|
|
8032
|
+
var SELECT_CLASS = "flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50";
|
|
8033
|
+
function withOptional(block, key, value) {
|
|
8034
|
+
const next = { ...block };
|
|
8035
|
+
if (value === void 0) {
|
|
8036
|
+
delete next[key];
|
|
8037
|
+
} else {
|
|
8038
|
+
next[key] = value;
|
|
8039
|
+
}
|
|
8040
|
+
return next;
|
|
8041
|
+
}
|
|
8042
|
+
function realignRowHeader(index, edit) {
|
|
8043
|
+
if (index === void 0 || edit.kind === "add" || edit.index > index) {
|
|
8044
|
+
return index;
|
|
8045
|
+
}
|
|
8046
|
+
return edit.index === index ? void 0 : index - 1;
|
|
8047
|
+
}
|
|
8048
|
+
function cellText(cell) {
|
|
8049
|
+
switch (cell?.type) {
|
|
8050
|
+
case "raw_text":
|
|
8051
|
+
return cell.text;
|
|
8052
|
+
case "raw_number":
|
|
8053
|
+
return cell.text ?? String(cell.value);
|
|
8054
|
+
case "action_cell":
|
|
8055
|
+
return cell.element.text.text;
|
|
8056
|
+
default:
|
|
8057
|
+
return "";
|
|
8058
|
+
}
|
|
8059
|
+
}
|
|
8060
|
+
function toNumberCell(cell) {
|
|
8061
|
+
const text = cell.text.trim();
|
|
8062
|
+
const parsed = text === "" ? Number.NaN : Number(text.replace(/,/g, ""));
|
|
8063
|
+
if (Number.isFinite(parsed)) {
|
|
8064
|
+
return String(parsed) === text ? { type: "raw_number", value: parsed } : { type: "raw_number", value: parsed, text };
|
|
8065
|
+
}
|
|
8066
|
+
return text ? { type: "raw_number", value: 0, text } : { type: "raw_number", value: 0 };
|
|
8067
|
+
}
|
|
8068
|
+
function toTextCell(cell) {
|
|
8069
|
+
return { type: "raw_text", text: cell.text ?? String(cell.value) };
|
|
8070
|
+
}
|
|
8071
|
+
function DataTableEditor({ block, onChange }) {
|
|
8072
|
+
const rows = block.rows ?? [];
|
|
8073
|
+
const header = rows[0] ?? [];
|
|
8074
|
+
const rowHeader = block.row_header_column_index ?? 0;
|
|
8075
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
8076
|
+
/* @__PURE__ */ jsxRuntime.jsx(EditorField, { label: "Caption", help: "Required. Names the table for screen readers.", htmlFor: "data-table-caption", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8077
|
+
Input,
|
|
8078
|
+
{
|
|
8079
|
+
id: "data-table-caption",
|
|
8080
|
+
value: block.caption,
|
|
8081
|
+
placeholder: "e.g. Open deals by stage",
|
|
8082
|
+
onChange: (e) => onChange({ ...block, caption: e.target.value })
|
|
8083
|
+
}
|
|
8084
|
+
) }),
|
|
8085
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
8086
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8087
|
+
EditorField,
|
|
8088
|
+
{
|
|
8089
|
+
label: "Rows per page",
|
|
8090
|
+
help: "Optional, 1-100. Slack shows 5 when empty.",
|
|
8091
|
+
htmlFor: "data-table-page-size",
|
|
8092
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8093
|
+
Input,
|
|
8094
|
+
{
|
|
8095
|
+
id: "data-table-page-size",
|
|
8096
|
+
type: "number",
|
|
8097
|
+
min: 1,
|
|
8098
|
+
max: MAX_PAGE_SIZE,
|
|
8099
|
+
value: block.page_size ?? "",
|
|
8100
|
+
placeholder: "5",
|
|
8101
|
+
onChange: (e) => {
|
|
8102
|
+
const n = Math.trunc(Number(e.target.value));
|
|
8103
|
+
const next = e.target.value === "" || Number.isNaN(n) ? void 0 : Math.min(MAX_PAGE_SIZE, Math.max(1, n));
|
|
8104
|
+
onChange(withOptional(block, "page_size", next));
|
|
8105
|
+
}
|
|
8106
|
+
}
|
|
8107
|
+
)
|
|
8108
|
+
}
|
|
8109
|
+
),
|
|
8110
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8111
|
+
EditorField,
|
|
8112
|
+
{
|
|
8113
|
+
label: "Row header column",
|
|
8114
|
+
help: "The column that identifies each row for screen readers.",
|
|
8115
|
+
htmlFor: "data-table-row-header",
|
|
8116
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8117
|
+
"select",
|
|
8118
|
+
{
|
|
8119
|
+
id: "data-table-row-header",
|
|
8120
|
+
value: rowHeader,
|
|
8121
|
+
disabled: header.length === 0,
|
|
8122
|
+
onChange: (e) => {
|
|
8123
|
+
const index = Number(e.target.value);
|
|
8124
|
+
onChange(withOptional(block, "row_header_column_index", index === 0 ? void 0 : index));
|
|
8125
|
+
},
|
|
8126
|
+
className: SELECT_CLASS,
|
|
8127
|
+
children: [
|
|
8128
|
+
header.map((cell, c) => {
|
|
8129
|
+
const text = cellText(cell);
|
|
8130
|
+
return /* @__PURE__ */ jsxRuntime.jsx("option", { value: c, children: text ? `Column ${c + 1}: ${text}` : `Column ${c + 1}` }, c);
|
|
8131
|
+
}),
|
|
8132
|
+
rowHeader >= header.length ? /* @__PURE__ */ jsxRuntime.jsxs("option", { value: rowHeader, children: [
|
|
8133
|
+
"Column ",
|
|
8134
|
+
rowHeader + 1,
|
|
8135
|
+
" (missing)"
|
|
8136
|
+
] }) : null
|
|
8137
|
+
]
|
|
8138
|
+
}
|
|
8139
|
+
)
|
|
8140
|
+
}
|
|
8141
|
+
)
|
|
8142
|
+
] }),
|
|
8143
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8144
|
+
CellGrid,
|
|
8145
|
+
{
|
|
8146
|
+
label: "Cells",
|
|
8147
|
+
help: "The first row is the header. Up to 200 more rows and 20 columns. Use # to make a cell a number; a column of only numbers sorts numerically.",
|
|
8148
|
+
rows,
|
|
8149
|
+
minRows: MIN_ROWS,
|
|
8150
|
+
maxRows: MAX_ROWS,
|
|
8151
|
+
maxColumns: MAX_COLUMNS,
|
|
8152
|
+
lockFirstRow: true,
|
|
8153
|
+
blankCell: () => ({ type: "raw_text", text: "" }),
|
|
8154
|
+
onChange: (nextRows, edit) => {
|
|
8155
|
+
const next = { ...block, rows: nextRows };
|
|
8156
|
+
onChange(
|
|
8157
|
+
edit ? withOptional(next, "row_header_column_index", realignRowHeader(block.row_header_column_index, edit)) : next
|
|
8158
|
+
);
|
|
8159
|
+
},
|
|
8160
|
+
renderCell: (cell, position, update) => /* @__PURE__ */ jsxRuntime.jsx(DataTableCellField, { cell, position, onChange: update })
|
|
8161
|
+
}
|
|
8162
|
+
)
|
|
8163
|
+
] });
|
|
8164
|
+
}
|
|
8165
|
+
function DataTableCellField({
|
|
8166
|
+
cell,
|
|
8167
|
+
position,
|
|
8168
|
+
onChange
|
|
8169
|
+
}) {
|
|
8170
|
+
const { row, col, label } = position;
|
|
8171
|
+
if (cell.type === "action_cell") {
|
|
8172
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
8173
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
8174
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToggleSpacer, {}),
|
|
8175
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-8 min-w-0 flex-1 items-center gap-1.5 rounded-md border border-dashed px-2 text-xs text-muted-foreground", children: [
|
|
8176
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.MousePointerClick, { className: "h-3 w-3 shrink-0", "aria-hidden": "true" }),
|
|
8177
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: cellText(cell) || "Button" })
|
|
8178
|
+
] })
|
|
8179
|
+
] }),
|
|
8180
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pl-7 text-[10px] text-muted-foreground", children: "Button cell. Edit it via View JSON." })
|
|
8181
|
+
] });
|
|
8182
|
+
}
|
|
8183
|
+
if (cell.type === "raw_number") {
|
|
8184
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
8185
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
8186
|
+
/* @__PURE__ */ jsxRuntime.jsx(NumberToggle, { label, pressed: true, onClick: () => onChange(toTextCell(cell)) }),
|
|
8187
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8188
|
+
NumberInput,
|
|
8189
|
+
{
|
|
8190
|
+
value: cell.value,
|
|
8191
|
+
ariaLabel: `${label} value`,
|
|
8192
|
+
onCommit: (value) => onChange({ ...cell, value }),
|
|
8193
|
+
className: "h-8 text-xs"
|
|
8194
|
+
}
|
|
8195
|
+
)
|
|
8196
|
+
] }),
|
|
8197
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
8198
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToggleSpacer, {}),
|
|
8199
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8200
|
+
Input,
|
|
8201
|
+
{
|
|
8202
|
+
"aria-label": `${label} display text`,
|
|
8203
|
+
value: cell.text ?? "",
|
|
8204
|
+
placeholder: "Display as (optional)",
|
|
8205
|
+
onChange: (e) => {
|
|
8206
|
+
const { text: _omit, ...rest } = cell;
|
|
8207
|
+
onChange(e.target.value ? { ...rest, text: e.target.value } : rest);
|
|
8208
|
+
},
|
|
8209
|
+
className: "h-7 text-[11px]"
|
|
8210
|
+
}
|
|
8211
|
+
)
|
|
8212
|
+
] })
|
|
8213
|
+
] });
|
|
8214
|
+
}
|
|
8215
|
+
const isHeader = row === 0;
|
|
8216
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8217
|
+
CellTextInput,
|
|
8218
|
+
{
|
|
8219
|
+
cell,
|
|
8220
|
+
label,
|
|
8221
|
+
placeholder: isHeader ? `Header ${col + 1}` : "Cell text",
|
|
8222
|
+
richTextNote: isHeader ? "Header cells can't be rich text. Type to replace it." : void 0,
|
|
8223
|
+
leading: !isHeader && cell.type === "raw_text" ? /* @__PURE__ */ jsxRuntime.jsx(NumberToggle, { label, pressed: false, onClick: () => onChange(toNumberCell(cell)) }) : /* @__PURE__ */ jsxRuntime.jsx(ToggleSpacer, {}),
|
|
8224
|
+
onChange
|
|
8225
|
+
}
|
|
8226
|
+
);
|
|
8227
|
+
}
|
|
8228
|
+
function ToggleSpacer() {
|
|
8229
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-6 w-6 shrink-0", "aria-hidden": "true" });
|
|
8230
|
+
}
|
|
8231
|
+
function NumberToggle({ label, pressed, onClick }) {
|
|
8232
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8233
|
+
"button",
|
|
8234
|
+
{
|
|
8235
|
+
type: "button",
|
|
8236
|
+
"aria-label": `${label} as number`,
|
|
8237
|
+
"aria-pressed": pressed,
|
|
8238
|
+
title: pressed ? "Number cell. Click to make it text." : "Text cell. Click to make it a number.",
|
|
8239
|
+
onClick,
|
|
8240
|
+
className: cn(
|
|
8241
|
+
"flex h-6 w-6 shrink-0 items-center justify-center rounded transition-colors",
|
|
8242
|
+
pressed ? "bg-primary/10 text-foreground" : "text-muted-foreground hover:bg-accent hover:text-foreground"
|
|
8243
|
+
),
|
|
8244
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Hash, { className: "h-3 w-3" })
|
|
8245
|
+
}
|
|
8246
|
+
);
|
|
8247
|
+
}
|
|
7482
8248
|
var CHART_TYPES = ["line", "bar", "area", "pie"];
|
|
7483
8249
|
function isCartesian(chart) {
|
|
7484
8250
|
return chart.type !== "pie";
|
|
@@ -7533,46 +8299,6 @@ function DataVisualizationEditor({ block, onChange }) {
|
|
|
7533
8299
|
isCartesian(chart) ? /* @__PURE__ */ jsxRuntime.jsx(CartesianFields, { chart, onChange: setChart }) : /* @__PURE__ */ jsxRuntime.jsx(PieFields, { chart, onChange: setChart })
|
|
7534
8300
|
] });
|
|
7535
8301
|
}
|
|
7536
|
-
function NumberInput({
|
|
7537
|
-
id,
|
|
7538
|
-
value,
|
|
7539
|
-
onCommit,
|
|
7540
|
-
ariaLabel,
|
|
7541
|
-
className
|
|
7542
|
-
}) {
|
|
7543
|
-
const [draft, setDraft] = React.useState(String(value));
|
|
7544
|
-
React.useEffect(() => {
|
|
7545
|
-
setDraft(String(value));
|
|
7546
|
-
}, [value]);
|
|
7547
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7548
|
-
Input,
|
|
7549
|
-
{
|
|
7550
|
-
id,
|
|
7551
|
-
type: "number",
|
|
7552
|
-
inputMode: "numeric",
|
|
7553
|
-
"aria-label": ariaLabel,
|
|
7554
|
-
value: draft,
|
|
7555
|
-
className,
|
|
7556
|
-
onChange: (e) => {
|
|
7557
|
-
const raw = e.target.value;
|
|
7558
|
-
setDraft(raw);
|
|
7559
|
-
if (raw === "" || raw === "-" || raw === "." || raw === "-.") {
|
|
7560
|
-
return;
|
|
7561
|
-
}
|
|
7562
|
-
const next = Number(raw);
|
|
7563
|
-
if (!Number.isNaN(next)) {
|
|
7564
|
-
onCommit(next);
|
|
7565
|
-
}
|
|
7566
|
-
},
|
|
7567
|
-
onBlur: () => {
|
|
7568
|
-
const next = Number(draft);
|
|
7569
|
-
const safe = draft.trim() === "" || Number.isNaN(next) ? 0 : next;
|
|
7570
|
-
onCommit(safe);
|
|
7571
|
-
setDraft(String(safe));
|
|
7572
|
-
}
|
|
7573
|
-
}
|
|
7574
|
-
);
|
|
7575
|
-
}
|
|
7576
8302
|
function CartesianFields({ chart, onChange }) {
|
|
7577
8303
|
const series = chart.series;
|
|
7578
8304
|
const categories = chart.axis_config?.categories && chart.axis_config.categories.length > 0 ? chart.axis_config.categories : series[0]?.data.map((d) => d.label) ?? [];
|
|
@@ -9115,45 +9841,13 @@ function ImageAccessoryFields({ image, onChange }) {
|
|
|
9115
9841
|
] });
|
|
9116
9842
|
}
|
|
9117
9843
|
var ALIGN_OPTIONS = ["left", "center", "right"];
|
|
9118
|
-
function
|
|
9119
|
-
|
|
9120
|
-
return cell.text;
|
|
9121
|
-
}
|
|
9122
|
-
return "[rich_text]";
|
|
9844
|
+
function alignColumnSettings(settings, edit) {
|
|
9845
|
+
return edit.kind === "add" ? [...settings, null] : settings.filter((_, c) => c !== edit.index);
|
|
9123
9846
|
}
|
|
9124
9847
|
function TableEditor({ block, onChange }) {
|
|
9125
9848
|
const rows = block.rows ?? [];
|
|
9126
9849
|
const columnCount = rows[0]?.length ?? 0;
|
|
9127
9850
|
const columnSettings = block.column_settings ?? [];
|
|
9128
|
-
const setCell = (rowIdx, colIdx, text) => {
|
|
9129
|
-
const nextRows = rows.map(
|
|
9130
|
-
(row, r) => r === rowIdx ? row.map((cell, c) => c === colIdx ? { type: "raw_text", text } : cell) : row
|
|
9131
|
-
);
|
|
9132
|
-
onChange({ ...block, rows: nextRows });
|
|
9133
|
-
};
|
|
9134
|
-
const addRow = () => {
|
|
9135
|
-
const blankRow = Array.from({ length: columnCount || 1 }, () => ({ type: "raw_text", text: "" }));
|
|
9136
|
-
onChange({ ...block, rows: [...rows, blankRow] });
|
|
9137
|
-
};
|
|
9138
|
-
const removeRow = (rowIdx) => {
|
|
9139
|
-
if (rows.length <= 1) {
|
|
9140
|
-
return;
|
|
9141
|
-
}
|
|
9142
|
-
onChange({ ...block, rows: rows.filter((_, r) => r !== rowIdx) });
|
|
9143
|
-
};
|
|
9144
|
-
const addColumn = () => {
|
|
9145
|
-
const nextRows = rows.map((row) => [...row, { type: "raw_text", text: "" }]);
|
|
9146
|
-
const nextSettings = [...columnSettings, null];
|
|
9147
|
-
onChange({ ...block, rows: nextRows, column_settings: nextSettings });
|
|
9148
|
-
};
|
|
9149
|
-
const removeColumn = (colIdx) => {
|
|
9150
|
-
if (columnCount <= 1) {
|
|
9151
|
-
return;
|
|
9152
|
-
}
|
|
9153
|
-
const nextRows = rows.map((row) => row.filter((_, c) => c !== colIdx));
|
|
9154
|
-
const nextSettings = columnSettings.filter((_, c) => c !== colIdx);
|
|
9155
|
-
onChange({ ...block, rows: nextRows, column_settings: nextSettings });
|
|
9156
|
-
};
|
|
9157
9851
|
const setColumnAlign = (colIdx, align) => {
|
|
9158
9852
|
const next = Array.from({ length: columnCount }, (_, i) => columnSettings[i] ?? null);
|
|
9159
9853
|
if (align === "") {
|
|
@@ -9164,81 +9858,45 @@ function TableEditor({ block, onChange }) {
|
|
|
9164
9858
|
}
|
|
9165
9859
|
onChange({ ...block, column_settings: next });
|
|
9166
9860
|
};
|
|
9167
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
9168
|
-
|
|
9169
|
-
|
|
9170
|
-
|
|
9171
|
-
|
|
9172
|
-
|
|
9173
|
-
|
|
9174
|
-
|
|
9175
|
-
|
|
9176
|
-
|
|
9177
|
-
|
|
9178
|
-
|
|
9179
|
-
|
|
9180
|
-
|
|
9181
|
-
|
|
9182
|
-
|
|
9183
|
-
|
|
9184
|
-
|
|
9185
|
-
|
|
9186
|
-
|
|
9187
|
-
|
|
9188
|
-
|
|
9189
|
-
|
|
9190
|
-
|
|
9191
|
-
|
|
9192
|
-
|
|
9193
|
-
|
|
9194
|
-
|
|
9195
|
-
|
|
9196
|
-
|
|
9197
|
-
|
|
9198
|
-
|
|
9199
|
-
|
|
9200
|
-
|
|
9201
|
-
|
|
9202
|
-
|
|
9203
|
-
|
|
9204
|
-
|
|
9205
|
-
|
|
9206
|
-
type: "button",
|
|
9207
|
-
"aria-label": `Remove row ${r + 1}`,
|
|
9208
|
-
onClick: () => removeRow(r),
|
|
9209
|
-
disabled: rows.length <= 1,
|
|
9210
|
-
className: "flex h-6 w-6 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-destructive/10 hover:text-destructive disabled:cursor-not-allowed disabled:opacity-40",
|
|
9211
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-3 w-3" })
|
|
9212
|
-
}
|
|
9213
|
-
),
|
|
9214
|
-
row.map((cell, c) => {
|
|
9215
|
-
const isRichText = cell.type === "rich_text";
|
|
9216
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-[120px] flex-1 flex-col gap-0.5", children: [
|
|
9217
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9218
|
-
Input,
|
|
9219
|
-
{
|
|
9220
|
-
value: cellAsText(cell),
|
|
9221
|
-
placeholder: r === 0 ? `Header ${c + 1}` : "Cell text",
|
|
9222
|
-
onChange: (e) => setCell(r, c, e.target.value),
|
|
9223
|
-
className: "h-8 text-xs"
|
|
9224
|
-
}
|
|
9225
|
-
),
|
|
9226
|
-
isRichText ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: "Was rich-text; editing replaces with plain text." }) : null
|
|
9227
|
-
] }, c);
|
|
9228
|
-
})
|
|
9229
|
-
] }, r))
|
|
9230
|
-
] }) }),
|
|
9231
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
|
|
9232
|
-
/* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", size: "sm", onClick: addRow, disabled: rows.length >= 100, children: [
|
|
9233
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3.5 w-3.5" }),
|
|
9234
|
-
" Add row"
|
|
9235
|
-
] }),
|
|
9236
|
-
/* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", size: "sm", onClick: addColumn, disabled: columnCount >= 20, children: [
|
|
9237
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3.5 w-3.5" }),
|
|
9238
|
-
" Add column"
|
|
9239
|
-
] })
|
|
9240
|
-
] })
|
|
9241
|
-
] });
|
|
9861
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9862
|
+
CellGrid,
|
|
9863
|
+
{
|
|
9864
|
+
label: "Cells",
|
|
9865
|
+
help: "Up to 100 rows and 20 columns. Slack allows one table per message.",
|
|
9866
|
+
rows,
|
|
9867
|
+
minRows: 1,
|
|
9868
|
+
maxRows: 100,
|
|
9869
|
+
maxColumns: 20,
|
|
9870
|
+
blankCell: () => ({ type: "raw_text", text: "" }),
|
|
9871
|
+
onChange: (nextRows, edit) => onChange({
|
|
9872
|
+
...block,
|
|
9873
|
+
rows: nextRows,
|
|
9874
|
+
...edit ? { column_settings: alignColumnSettings(columnSettings, edit) } : {}
|
|
9875
|
+
}),
|
|
9876
|
+
renderColumnControl: (c) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9877
|
+
"select",
|
|
9878
|
+
{
|
|
9879
|
+
"aria-label": `Column ${c + 1} alignment`,
|
|
9880
|
+
value: columnSettings[c]?.align ?? "",
|
|
9881
|
+
onChange: (e) => setColumnAlign(c, e.target.value),
|
|
9882
|
+
className: "h-7 flex-1 rounded-sm border border-input bg-background px-1.5 text-[11px] text-muted-foreground",
|
|
9883
|
+
children: [
|
|
9884
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Default" }),
|
|
9885
|
+
ALIGN_OPTIONS.map((a) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: a, children: a }, a))
|
|
9886
|
+
]
|
|
9887
|
+
}
|
|
9888
|
+
),
|
|
9889
|
+
renderCell: (cell, { row, col, label }, update) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
9890
|
+
CellTextInput,
|
|
9891
|
+
{
|
|
9892
|
+
cell,
|
|
9893
|
+
label,
|
|
9894
|
+
placeholder: row === 0 ? `Header ${col + 1}` : "Cell text",
|
|
9895
|
+
onChange: update
|
|
9896
|
+
}
|
|
9897
|
+
)
|
|
9898
|
+
}
|
|
9899
|
+
);
|
|
9242
9900
|
}
|
|
9243
9901
|
var STATUSES2 = ["pending", "in_progress", "complete", "error"];
|
|
9244
9902
|
function TaskCardEditor({ block, onChange }) {
|
|
@@ -9579,6 +10237,8 @@ function dispatch(block, onChange) {
|
|
|
9579
10237
|
return /* @__PURE__ */ jsxRuntime.jsx(DataVisualizationEditor, { block, onChange: (next) => onChange(next) });
|
|
9580
10238
|
case "container":
|
|
9581
10239
|
return /* @__PURE__ */ jsxRuntime.jsx(ContainerEditor, { block, onChange: (next) => onChange(next) });
|
|
10240
|
+
case "data_table":
|
|
10241
|
+
return /* @__PURE__ */ jsxRuntime.jsx(DataTableEditor, { block, onChange: (next) => onChange(next) });
|
|
9582
10242
|
default:
|
|
9583
10243
|
return null;
|
|
9584
10244
|
}
|
|
@@ -9602,7 +10262,8 @@ var BLOCK_TYPE_LABELS = {
|
|
|
9602
10262
|
plan: "Plan",
|
|
9603
10263
|
task_card: "Task Card",
|
|
9604
10264
|
data_visualization: "Data Visualization",
|
|
9605
|
-
container: "Container"
|
|
10265
|
+
container: "Container",
|
|
10266
|
+
data_table: "Data Table"
|
|
9606
10267
|
};
|
|
9607
10268
|
function BlockRow({
|
|
9608
10269
|
builderBlock,
|
|
@@ -10952,6 +11613,7 @@ function BlockKitchen(props) {
|
|
|
10952
11613
|
onValidationChange,
|
|
10953
11614
|
previewHooks,
|
|
10954
11615
|
customEmojis,
|
|
11616
|
+
mentions,
|
|
10955
11617
|
loadChannels,
|
|
10956
11618
|
loadSendAsUserStatus,
|
|
10957
11619
|
onSend,
|
|
@@ -11312,7 +11974,7 @@ function BlockKitchen(props) {
|
|
|
11312
11974
|
}
|
|
11313
11975
|
)
|
|
11314
11976
|
] }),
|
|
11315
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11977
|
+
/* @__PURE__ */ jsxRuntime.jsx(MentionsProvider, { mentions, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
11316
11978
|
Surface,
|
|
11317
11979
|
{
|
|
11318
11980
|
blocks,
|
|
@@ -11332,7 +11994,7 @@ function BlockKitchen(props) {
|
|
|
11332
11994
|
isPaletteDrag: activePaletteVariant !== null,
|
|
11333
11995
|
onOpenPalette: () => setPaletteOpen(true)
|
|
11334
11996
|
}
|
|
11335
|
-
)
|
|
11997
|
+
) })
|
|
11336
11998
|
] })
|
|
11337
11999
|
]
|
|
11338
12000
|
}
|