@nkootstra/block-kit 0.3.3 → 0.3.4
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/index.js +109 -27
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/styles.css.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7059,19 +7059,26 @@ const FORMATTING_GROUPS = [
|
|
|
7059
7059
|
}
|
|
7060
7060
|
]
|
|
7061
7061
|
];
|
|
7062
|
-
/** The
|
|
7063
|
-
*
|
|
7062
|
+
/** The formatting bar Slack shows above a modal's rich-text editor. The editor here is plain text,
|
|
7063
|
+
* so its buttons are there to look like Slack's but marked unavailable; they dim until the editor
|
|
7064
|
+
* has focus, as Slack's do. */
|
|
7064
7065
|
function RichTextToolbar() {
|
|
7065
7066
|
return /* @__PURE__ */ jsx("div", {
|
|
7066
7067
|
className: "sbk-rich-text-input__toolbar",
|
|
7067
|
-
|
|
7068
|
-
|
|
7068
|
+
role: "toolbar",
|
|
7069
|
+
"aria-orientation": "horizontal",
|
|
7070
|
+
"aria-label": "Formatting",
|
|
7071
|
+
children: FORMATTING_GROUPS.map((group, i) => /* @__PURE__ */ jsxs(Fragment$1, { children: [i > 0 && /* @__PURE__ */ jsx("span", { className: "sbk-rich-text-input__separator" }), group.map((icon) => /* @__PURE__ */ jsx("button", {
|
|
7072
|
+
type: "button",
|
|
7069
7073
|
className: "sbk-rich-text-input__tool",
|
|
7070
|
-
|
|
7074
|
+
"aria-label": icon.label,
|
|
7075
|
+
"aria-disabled": "true",
|
|
7076
|
+
tabIndex: -1,
|
|
7071
7077
|
children: /* @__PURE__ */ jsx("svg", {
|
|
7072
7078
|
viewBox: "0 0 20 20",
|
|
7073
7079
|
width: "18",
|
|
7074
7080
|
height: "18",
|
|
7081
|
+
"aria-hidden": "true",
|
|
7075
7082
|
children: /* @__PURE__ */ jsx("path", {
|
|
7076
7083
|
fill: "currentColor",
|
|
7077
7084
|
fillRule: icon.evenOdd ? "evenodd" : void 0,
|
|
@@ -7082,11 +7089,52 @@ function RichTextToolbar() {
|
|
|
7082
7089
|
}, icon.label))] }, group[0]?.label))
|
|
7083
7090
|
});
|
|
7084
7091
|
}
|
|
7092
|
+
/** Slack's "Aa" (show formatting) and emoji glyphs, 20-unit paths as Slack ships them. */
|
|
7093
|
+
const FORMATTING_ICON = "M6.941 3.952c-.459-1.378-2.414-1.363-2.853.022l-4.053 12.8a.75.75 0 0 0 1.43.452l1.101-3.476h6.06l1.163 3.487a.75.75 0 1 0 1.423-.474zm1.185 8.298L5.518 4.427 3.041 12.25zm6.198-5.537a4.74 4.74 0 0 1 3.037-.081A3.74 3.74 0 0 1 20 10.208V17a.75.75 0 0 1-1.5 0v-.745a8 8 0 0 1-2.847 1.355 3 3 0 0 1-3.15-1.143C10.848 14.192 12.473 11 15.287 11H18.5v-.792c0-.984-.641-1.853-1.581-2.143a3.24 3.24 0 0 0-2.077.056l-.242.089a2.22 2.22 0 0 0-1.34 1.382l-.048.145a.75.75 0 0 1-1.423-.474l.048-.145a3.72 3.72 0 0 1 2.244-2.315zM18.5 12.5h-3.213c-1.587 0-2.504 1.801-1.57 3.085.357.491.98.717 1.572.57a6.5 6.5 0 0 0 2.47-1.223l.741-.593z";
|
|
7094
|
+
const EMOJI_ICON = "M2.5 10a7.5 7.5 0 1 1 15 0 7.5 7.5 0 0 1-15 0M10 1a9 9 0 1 0 0 18 9 9 0 0 0 0-18M7.5 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3M14 8a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0m-6.385 3.766a.75.75 0 1 0-1.425.468C6.796 14.08 8.428 15 10.027 15s3.23-.92 3.838-2.766a.75.75 0 1 0-1.425-.468c-.38 1.155-1.38 1.734-2.413 1.734s-2.032-.58-2.412-1.734";
|
|
7095
|
+
function Glyph({ d }) {
|
|
7096
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
7097
|
+
viewBox: "0 0 20 20",
|
|
7098
|
+
width: "18",
|
|
7099
|
+
height: "18",
|
|
7100
|
+
"aria-hidden": "true",
|
|
7101
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
7102
|
+
fill: "currentColor",
|
|
7103
|
+
fillRule: "evenodd",
|
|
7104
|
+
clipRule: "evenodd",
|
|
7105
|
+
d
|
|
7106
|
+
})
|
|
7107
|
+
});
|
|
7108
|
+
}
|
|
7109
|
+
/** The row Slack draws under the editor: "Aa" shows or hides the formatting bar (underlined while
|
|
7110
|
+
* it's shown), and an emoji button, unavailable until block-kit has an emoji picker. */
|
|
7111
|
+
function RichTextComposerActions({ formatting, onToggleFormatting }) {
|
|
7112
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
7113
|
+
className: "sbk-rich-text-input__footer",
|
|
7114
|
+
role: "toolbar",
|
|
7115
|
+
"aria-orientation": "horizontal",
|
|
7116
|
+
"aria-label": "Composer actions",
|
|
7117
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
7118
|
+
type: "button",
|
|
7119
|
+
className: "sbk-rich-text-input__action sbk-rich-text-input__action--formatting",
|
|
7120
|
+
"aria-label": "Show formatting",
|
|
7121
|
+
"aria-pressed": formatting,
|
|
7122
|
+
onClick: onToggleFormatting,
|
|
7123
|
+
children: /* @__PURE__ */ jsx(Glyph, { d: FORMATTING_ICON })
|
|
7124
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
7125
|
+
type: "button",
|
|
7126
|
+
className: "sbk-rich-text-input__action",
|
|
7127
|
+
"aria-label": "Emoji",
|
|
7128
|
+
"aria-disabled": "true",
|
|
7129
|
+
tabIndex: -1,
|
|
7130
|
+
children: /* @__PURE__ */ jsx(Glyph, { d: EMOJI_ICON })
|
|
7131
|
+
})]
|
|
7132
|
+
});
|
|
7133
|
+
}
|
|
7085
7134
|
//#endregion
|
|
7086
7135
|
//#region src/elements/RichTextInput.tsx
|
|
7087
|
-
/** Wraps plain text into the `rich_text` block shape Slack uses for this element's value.
|
|
7088
|
-
*
|
|
7089
|
-
* Slack's (inert) formatting toolbar. */
|
|
7136
|
+
/** Wraps plain text into the `rich_text` block shape Slack uses for this element's value. The
|
|
7137
|
+
* editor is plain text; Slack's formatting bar and composer row are drawn around it for parity. */
|
|
7090
7138
|
function toRichText(text) {
|
|
7091
7139
|
return {
|
|
7092
7140
|
type: "rich_text",
|
|
@@ -7115,6 +7163,8 @@ function RichTextInput({ element, blockId }) {
|
|
|
7115
7163
|
const invalid = useInvalidProps();
|
|
7116
7164
|
const actionId = element.action_id ?? "";
|
|
7117
7165
|
const initialText = fromRichText(element.initial_value);
|
|
7166
|
+
const [formatting, setFormatting] = useState(true);
|
|
7167
|
+
const [empty, setEmpty] = useState(initialText === "");
|
|
7118
7168
|
useEffect(() => {
|
|
7119
7169
|
if (element.initial_value) setValue(blockId, actionId, {
|
|
7120
7170
|
type: "rich_text_input",
|
|
@@ -7122,7 +7172,9 @@ function RichTextInput({ element, blockId }) {
|
|
|
7122
7172
|
});
|
|
7123
7173
|
}, []);
|
|
7124
7174
|
function onInput() {
|
|
7125
|
-
const
|
|
7175
|
+
const text = ref.current?.innerText ?? "";
|
|
7176
|
+
setEmpty(text.trim() === "");
|
|
7177
|
+
const richText = toRichText(text);
|
|
7126
7178
|
setValue(blockId, actionId, {
|
|
7127
7179
|
type: "rich_text_input",
|
|
7128
7180
|
rich_text_value: richText
|
|
@@ -7134,25 +7186,39 @@ function RichTextInput({ element, blockId }) {
|
|
|
7134
7186
|
rich_text_value: richText
|
|
7135
7187
|
});
|
|
7136
7188
|
}
|
|
7189
|
+
const placeholder = element.placeholder?.text;
|
|
7137
7190
|
return /* @__PURE__ */ jsxs("div", {
|
|
7138
7191
|
className: "sbk-rich-text-input",
|
|
7139
|
-
children: [
|
|
7140
|
-
|
|
7141
|
-
|
|
7142
|
-
|
|
7143
|
-
|
|
7144
|
-
|
|
7145
|
-
|
|
7146
|
-
|
|
7147
|
-
|
|
7148
|
-
|
|
7149
|
-
|
|
7150
|
-
|
|
7151
|
-
|
|
7152
|
-
|
|
7153
|
-
|
|
7154
|
-
|
|
7155
|
-
|
|
7192
|
+
children: [
|
|
7193
|
+
formatting && /* @__PURE__ */ jsx(RichTextToolbar, {}),
|
|
7194
|
+
/* @__PURE__ */ jsxs("div", {
|
|
7195
|
+
className: "sbk-rich-text-input__body",
|
|
7196
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
7197
|
+
ref,
|
|
7198
|
+
className: "sbk-rich-text-input__editor",
|
|
7199
|
+
contentEditable: true,
|
|
7200
|
+
suppressContentEditableWarning: true,
|
|
7201
|
+
role: "textbox",
|
|
7202
|
+
"aria-multiline": "true",
|
|
7203
|
+
...invalid,
|
|
7204
|
+
"aria-label": placeholder ?? actionId,
|
|
7205
|
+
onInput,
|
|
7206
|
+
style: {
|
|
7207
|
+
minHeight: element.min_lines ? `${element.min_lines * 22}px` : void 0,
|
|
7208
|
+
maxHeight: element.max_lines ? `${element.max_lines * 22}px` : void 0
|
|
7209
|
+
},
|
|
7210
|
+
children: initialText
|
|
7211
|
+
}), placeholder && empty && /* @__PURE__ */ jsx("div", {
|
|
7212
|
+
className: "sbk-rich-text-input__placeholder",
|
|
7213
|
+
"aria-hidden": "true",
|
|
7214
|
+
children: placeholder
|
|
7215
|
+
})]
|
|
7216
|
+
}),
|
|
7217
|
+
/* @__PURE__ */ jsx(RichTextComposerActions, {
|
|
7218
|
+
formatting,
|
|
7219
|
+
onToggleFormatting: () => setFormatting((shown) => !shown)
|
|
7220
|
+
})
|
|
7221
|
+
]
|
|
7156
7222
|
});
|
|
7157
7223
|
}
|
|
7158
7224
|
//#endregion
|
|
@@ -10113,7 +10179,23 @@ function renderTopLevel(elements, ctx) {
|
|
|
10113
10179
|
i++;
|
|
10114
10180
|
}
|
|
10115
10181
|
const forest = buildListForest(run);
|
|
10116
|
-
|
|
10182
|
+
const lists = forest.map((group) => renderListGroup(group, ctx, key++, 0));
|
|
10183
|
+
if (!forest.some((group) => group.border)) {
|
|
10184
|
+
nodes.push(...lists);
|
|
10185
|
+
continue;
|
|
10186
|
+
}
|
|
10187
|
+
const quoted = [];
|
|
10188
|
+
while (i < elements.length && elements[i]?.type === "rich_text_quote") {
|
|
10189
|
+
quoted.push(/* @__PURE__ */ jsx("div", {
|
|
10190
|
+
className: "sbk-rich-text__quote-text",
|
|
10191
|
+
children: renderSectionChildren(elements[i].elements, ctx)
|
|
10192
|
+
}, key++));
|
|
10193
|
+
i++;
|
|
10194
|
+
}
|
|
10195
|
+
nodes.push(/* @__PURE__ */ jsxs("blockquote", {
|
|
10196
|
+
className: "sbk-rich-text__quote sbk-rich-text__quote--group",
|
|
10197
|
+
children: [lists, quoted]
|
|
10198
|
+
}, key++));
|
|
10117
10199
|
continue;
|
|
10118
10200
|
}
|
|
10119
10201
|
switch (el.type) {
|