slack-blocks-to-jsx 0.1.9 → 0.2.1
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.d.mts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +72 -41
- package/dist/index.mjs +72 -41
- package/package.json +1 -1
- package/readme.md +111 -11
package/dist/index.d.mts
CHANGED
|
@@ -1129,6 +1129,10 @@ type Props = {
|
|
|
1129
1129
|
user_groups?: GlobalStore["user_groups"];
|
|
1130
1130
|
};
|
|
1131
1131
|
hooks?: GlobalStore["hooks"];
|
|
1132
|
+
/**
|
|
1133
|
+
* If true, the header and the container which wraps the message will be removed and only the slack blocks will be returned.
|
|
1134
|
+
*/
|
|
1135
|
+
withoutWrapper?: boolean;
|
|
1132
1136
|
};
|
|
1133
1137
|
declare const Message: (props: Props) => JSX.Element;
|
|
1134
1138
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1129,6 +1129,10 @@ type Props = {
|
|
|
1129
1129
|
user_groups?: GlobalStore["user_groups"];
|
|
1130
1130
|
};
|
|
1131
1131
|
hooks?: GlobalStore["hooks"];
|
|
1132
|
+
/**
|
|
1133
|
+
* If true, the header and the container which wraps the message will be removed and only the slack blocks will be returned.
|
|
1134
|
+
*/
|
|
1135
|
+
withoutWrapper?: boolean;
|
|
1132
1136
|
};
|
|
1133
1137
|
declare const Message: (props: Props) => JSX.Element;
|
|
1134
1138
|
|
package/dist/index.js
CHANGED
|
@@ -183,7 +183,7 @@ var is_accessory_stacked = (element) => {
|
|
|
183
183
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
184
184
|
var Header = (props) => {
|
|
185
185
|
const { name, time } = props;
|
|
186
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex gap-[5px] items-center w-full", children: [
|
|
186
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex gap-[5px] items-center w-full slack_blocks_to_jsx--header", children: [
|
|
187
187
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "font-black text-[15px]", children: name }),
|
|
188
188
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-[14px] w-[27px] leading-[12.5px] py-[1px] px-[3px] uppercase text-[10px] text-black-primary/[0.7] bg-black-primary/[0.13] font-semibold rounded-[2px] text-center", children: "APP" }),
|
|
189
189
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "text-xs text-black-secondary uppercase leading-[17.6px]", children: dateToTime(time) })
|
|
@@ -199,7 +199,7 @@ var ImageElement = (props) => {
|
|
|
199
199
|
{
|
|
200
200
|
src: image_url,
|
|
201
201
|
alt: alt_text,
|
|
202
|
-
className: "w-[88px] h-[88px] rounded-lg overflow-hidden object-cover"
|
|
202
|
+
className: "w-[88px] h-[88px] rounded-lg overflow-hidden object-cover slack_blocks_to_jsx__image_element"
|
|
203
203
|
}
|
|
204
204
|
) });
|
|
205
205
|
};
|
|
@@ -251,7 +251,7 @@ var ButtonElement = (props) => {
|
|
|
251
251
|
type: "button",
|
|
252
252
|
id: action_id,
|
|
253
253
|
"aria-label": accessibility_label,
|
|
254
|
-
className: `px-2 pt-0 pb-[1px] text-small h-[28px] min-w-[56px] border rounded whitespace-nowrap font-semibold
|
|
254
|
+
className: `px-2 pt-0 pb-[1px] text-small h-[28px] min-w-[56px] border rounded whitespace-nowrap font-semibold slack_blocks_to_jsx__button_element ${style === "primary" ? "border-green-primary.3 text-green-primary" : style === "danger" ? "border-red-primary.3 text-red-primary" : "border-black-primary.3 text-black-primary"}`,
|
|
255
255
|
onClick: () => {
|
|
256
256
|
if (url) {
|
|
257
257
|
window.open(url, "_blank");
|
|
@@ -392,7 +392,7 @@ var CheckboxesElement = (props) => {
|
|
|
392
392
|
input_ref.current.focus();
|
|
393
393
|
}
|
|
394
394
|
}, [focus_on_load]);
|
|
395
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { id: action_id, className: "my-1 flex w-full
|
|
395
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { id: action_id, className: "my-1 flex w-full slack_blocks_to_jsx__checkboxes_element", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("fieldset", { className: "flex flex-col gap-2", children: options.map((option, i) => {
|
|
396
396
|
const { text, value, description } = option;
|
|
397
397
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
398
398
|
"label",
|
|
@@ -456,34 +456,42 @@ var PlaintTextInput = (props) => {
|
|
|
456
456
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
457
457
|
};
|
|
458
458
|
}, []);
|
|
459
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
459
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
460
|
+
"div",
|
|
461
|
+
{
|
|
462
|
+
id: action_id,
|
|
463
|
+
className: "relative text-small w-full slack_blocks_to_jsx__plain_text_input_element",
|
|
464
|
+
tabIndex: 0,
|
|
465
|
+
children: [
|
|
466
|
+
!value && placeholder && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "absolute left-2 top-2 text-black-primary.3", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TextObject, { data: placeholder }) }),
|
|
467
|
+
!value && !placeholder && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "absolute left-2 top-2 text-black-primary.3", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
468
|
+
TextObject,
|
|
469
|
+
{
|
|
470
|
+
data: {
|
|
471
|
+
type: "plain_text",
|
|
472
|
+
text: "Write something"
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
) }),
|
|
476
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
477
|
+
"textarea",
|
|
478
|
+
{
|
|
479
|
+
value,
|
|
480
|
+
onChange: (e) => setValue(e.target.value),
|
|
481
|
+
className: "w-full focus:outline-none rounded border border-black-primary.3 p-2",
|
|
482
|
+
minLength: min_length,
|
|
483
|
+
maxLength: max_length,
|
|
484
|
+
style: {
|
|
485
|
+
maxHeight: "200px",
|
|
486
|
+
minHeight: "80px",
|
|
487
|
+
height: "100px"
|
|
488
|
+
},
|
|
489
|
+
"aria-label": "Select an item"
|
|
490
|
+
}
|
|
491
|
+
)
|
|
492
|
+
]
|
|
493
|
+
}
|
|
494
|
+
);
|
|
487
495
|
};
|
|
488
496
|
|
|
489
497
|
// src/components/elements/users_select_element.tsx
|
|
@@ -517,7 +525,7 @@ var UsersSelectElement = (props) => {
|
|
|
517
525
|
"div",
|
|
518
526
|
{
|
|
519
527
|
id: action_id,
|
|
520
|
-
className: "py-1 px-2 h-7 min-h-[28px] relative flex items-center justify-between rounded text-small w-[190px] border border-black-primary.3",
|
|
528
|
+
className: "py-1 px-2 h-7 min-h-[28px] relative flex items-center justify-between rounded text-small w-[190px] border border-black-primary.3 slack_blocks_to_jsx__users_select_element",
|
|
521
529
|
tabIndex: 0,
|
|
522
530
|
children: [
|
|
523
531
|
visible && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
@@ -805,6 +813,7 @@ var RichTextSectionBroadcast = (props) => {
|
|
|
805
813
|
className: `
|
|
806
814
|
inline-block
|
|
807
815
|
slack_broadcast
|
|
816
|
+
slack_blocks_to_jsx__rich_text_section_element_broadcast
|
|
808
817
|
${(style == null ? void 0 : style.italic) ? "italic" : ""}
|
|
809
818
|
${(style == null ? void 0 : style.strike) ? "line-through" : ""}
|
|
810
819
|
${(style == null ? void 0 : style.bold) ? "font-medium" : ""}
|
|
@@ -832,6 +841,7 @@ var RichTextSectionChannel = (props) => {
|
|
|
832
841
|
className: `
|
|
833
842
|
inline-block
|
|
834
843
|
slack_channel
|
|
844
|
+
slack_blocks_to_jsx__rich_text_section_element_channel
|
|
835
845
|
${(style == null ? void 0 : style.italic) ? "italic" : ""}
|
|
836
846
|
${(style == null ? void 0 : style.strike) ? "line-through" : ""}
|
|
837
847
|
${(style == null ? void 0 : style.bold) ? "font-medium" : ""}
|
|
@@ -851,7 +861,7 @@ var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
|
851
861
|
var RichTextSectionEmoji = (props) => {
|
|
852
862
|
const { name } = props;
|
|
853
863
|
const { hooks } = useGlobalData();
|
|
854
|
-
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { children: hooks.emoji ? hooks.emoji(name) : parseEmojis(`:${name}:`) });
|
|
864
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "slack_blocks_to_jsx__rich_text_section_element_emoji", children: hooks.emoji ? hooks.emoji(name) : parseEmojis(`:${name}:`) });
|
|
855
865
|
};
|
|
856
866
|
|
|
857
867
|
// src/components/blocks/rich_text/rich_text_section_user.tsx
|
|
@@ -868,6 +878,7 @@ var RichTextSectionUser = (props) => {
|
|
|
868
878
|
className: `
|
|
869
879
|
inline-block
|
|
870
880
|
slack_user
|
|
881
|
+
slack_blocks_to_jsx__rich_text_section_element_user
|
|
871
882
|
${(style == null ? void 0 : style.italic) ? "italic" : ""}
|
|
872
883
|
${(style == null ? void 0 : style.strike) ? "line-through" : ""}
|
|
873
884
|
${(style == null ? void 0 : style.bold) ? "font-medium" : ""}
|
|
@@ -896,6 +907,7 @@ var RichTextSectionUserGroup = (props) => {
|
|
|
896
907
|
className: `
|
|
897
908
|
inline-block
|
|
898
909
|
slack_user_group
|
|
910
|
+
slack_blocks_to_jsx__rich_text_section_element_user_group
|
|
899
911
|
${(style == null ? void 0 : style.italic) ? "italic" : ""}
|
|
900
912
|
${(style == null ? void 0 : style.strike) ? "line-through" : ""}
|
|
901
913
|
${(style == null ? void 0 : style.bold) ? "font-medium" : ""}
|
|
@@ -925,6 +937,7 @@ var RichTextSectionElement = (props) => {
|
|
|
925
937
|
"span",
|
|
926
938
|
{
|
|
927
939
|
className: `
|
|
940
|
+
slack_blocks_to_jsx__rich_text_section_element_text
|
|
928
941
|
${(style == null ? void 0 : style.italic) ? "italic" : ""}
|
|
929
942
|
${(style == null ? void 0 : style.strike) ? "line-through" : ""}
|
|
930
943
|
${(style == null ? void 0 : style.code) ? "slack_inline_code" : ""}
|
|
@@ -943,6 +956,7 @@ var RichTextSectionElement = (props) => {
|
|
|
943
956
|
rel: "noreferrer noopener",
|
|
944
957
|
href: url,
|
|
945
958
|
className: `
|
|
959
|
+
slack_blocks_to_jsx__rich_text_section_element_link
|
|
946
960
|
text-blue-primary hover:underline underline-offset-4
|
|
947
961
|
${(style == null ? void 0 : style.italic) ? "italic" : ""}
|
|
948
962
|
${(style == null ? void 0 : style.strike) ? "line-through" : ""}
|
|
@@ -968,7 +982,7 @@ var Element = (props) => {
|
|
|
968
982
|
const { element } = props;
|
|
969
983
|
if (element.type === "rich_text_list") {
|
|
970
984
|
const { elements, style, border = 0, indent, offset } = element;
|
|
971
|
-
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex gap-2", children: [
|
|
985
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex gap-2 slack_blocks_to_jsx__rich_text_list_element", children: [
|
|
972
986
|
border === 1 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "w-1 rounded bg-gray-primary self-stretch" }),
|
|
973
987
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(RichTextListWrapper, { element, className: `list-none`, children: elements.map((el, i) => {
|
|
974
988
|
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
@@ -1006,7 +1020,7 @@ var Element = (props) => {
|
|
|
1006
1020
|
}
|
|
1007
1021
|
if (element.type === "rich_text_preformatted") {
|
|
1008
1022
|
const { elements, border } = element;
|
|
1009
|
-
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("code", { className: "flex gap-2 w-full", children: [
|
|
1023
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("code", { className: "flex gap-2 w-full slack_blocks_to_jsx__rich_text_preformatted_element", children: [
|
|
1010
1024
|
border === 1 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "w-1 rounded bg-gray-primary self-stretch" }),
|
|
1011
1025
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
1012
1026
|
"pre",
|
|
@@ -1025,7 +1039,7 @@ var Element = (props) => {
|
|
|
1025
1039
|
}
|
|
1026
1040
|
if (element.type === "rich_text_quote") {
|
|
1027
1041
|
const { elements, border } = element;
|
|
1028
|
-
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("blockquote", { className: "flex gap-2", children: [
|
|
1042
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("blockquote", { className: "flex gap-2 slack_blocks_to_jsx__rich_text_quote_element", children: [
|
|
1029
1043
|
border === 1 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "w-1 rounded bg-gray-primary self-stretch" }),
|
|
1030
1044
|
elements.map((el, i) => {
|
|
1031
1045
|
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(RichTextSectionElement, { element: el }, `${el.type}__${i}`);
|
|
@@ -1034,7 +1048,7 @@ var Element = (props) => {
|
|
|
1034
1048
|
}
|
|
1035
1049
|
if (element.type === "rich_text_section") {
|
|
1036
1050
|
const { elements } = element;
|
|
1037
|
-
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "inline-block", children: elements.map((el, i) => {
|
|
1051
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "inline-block slack_blocks_to_jsx__rich_text_section_element", children: elements.map((el, i) => {
|
|
1038
1052
|
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(RichTextSectionElement, { element: el }, `${el.type}__${i}`);
|
|
1039
1053
|
}) });
|
|
1040
1054
|
}
|
|
@@ -1148,7 +1162,7 @@ var getElementComponent = (element) => {
|
|
|
1148
1162
|
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
1149
1163
|
var BlockWrapper = (props) => {
|
|
1150
1164
|
const { children } = props;
|
|
1151
|
-
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "text-base break-words font-normal", children });
|
|
1165
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "text-base slack_blocks_to_jsx--block_wrapper break-words font-normal", children });
|
|
1152
1166
|
};
|
|
1153
1167
|
|
|
1154
1168
|
// src/message.tsx
|
|
@@ -1165,7 +1179,8 @@ var Message = (props) => {
|
|
|
1165
1179
|
showBlockKitDebug = false,
|
|
1166
1180
|
unstyled = false,
|
|
1167
1181
|
data = {},
|
|
1168
|
-
hooks = {}
|
|
1182
|
+
hooks = {},
|
|
1183
|
+
withoutWrapper = false
|
|
1169
1184
|
} = props;
|
|
1170
1185
|
const { setChannels, setUsers, setHooks } = useGlobalData();
|
|
1171
1186
|
(0, import_react6.useEffect)(() => {
|
|
@@ -1176,6 +1191,22 @@ var Message = (props) => {
|
|
|
1176
1191
|
if (hooks)
|
|
1177
1192
|
setHooks(hooks);
|
|
1178
1193
|
}, [data]);
|
|
1194
|
+
if (withoutWrapper) {
|
|
1195
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
1196
|
+
"div",
|
|
1197
|
+
{
|
|
1198
|
+
id: "slack_blocks_to_jsx",
|
|
1199
|
+
className: `slack_blocks_to_jsx relative flex gap-2 w-full max-w-[600px] ${unstyled ? "styles_disabled" : "styles_enabled"} ${className}`,
|
|
1200
|
+
style,
|
|
1201
|
+
children: blocks.map((block, i) => {
|
|
1202
|
+
const element = getBlockComponent(block);
|
|
1203
|
+
if (!element)
|
|
1204
|
+
return null;
|
|
1205
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(BlockWrapper, { children: element }, i);
|
|
1206
|
+
})
|
|
1207
|
+
}
|
|
1208
|
+
);
|
|
1209
|
+
}
|
|
1179
1210
|
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { id: "slack_blocks_to_jsx", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
1180
1211
|
"section",
|
|
1181
1212
|
{
|
|
@@ -1197,7 +1228,7 @@ var Message = (props) => {
|
|
|
1197
1228
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("img", { src: logo, className: "w-9 h-9", alt: name }) }),
|
|
1198
1229
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col w-full", children: [
|
|
1199
1230
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Header, { name, time }),
|
|
1200
|
-
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { children: blocks.map((block, i) => {
|
|
1231
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "slack_blocks_to_jsx--blocks", children: blocks.map((block, i) => {
|
|
1201
1232
|
const element = getBlockComponent(block);
|
|
1202
1233
|
if (!element)
|
|
1203
1234
|
return null;
|
package/dist/index.mjs
CHANGED
|
@@ -150,7 +150,7 @@ var is_accessory_stacked = (element) => {
|
|
|
150
150
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
151
151
|
var Header = (props) => {
|
|
152
152
|
const { name, time } = props;
|
|
153
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex gap-[5px] items-center w-full", children: [
|
|
153
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex gap-[5px] items-center w-full slack_blocks_to_jsx--header", children: [
|
|
154
154
|
/* @__PURE__ */ jsx("h3", { className: "font-black text-[15px]", children: name }),
|
|
155
155
|
/* @__PURE__ */ jsx("div", { className: "h-[14px] w-[27px] leading-[12.5px] py-[1px] px-[3px] uppercase text-[10px] text-black-primary/[0.7] bg-black-primary/[0.13] font-semibold rounded-[2px] text-center", children: "APP" }),
|
|
156
156
|
/* @__PURE__ */ jsx("div", { className: "text-xs text-black-secondary uppercase leading-[17.6px]", children: dateToTime(time) })
|
|
@@ -166,7 +166,7 @@ var ImageElement = (props) => {
|
|
|
166
166
|
{
|
|
167
167
|
src: image_url,
|
|
168
168
|
alt: alt_text,
|
|
169
|
-
className: "w-[88px] h-[88px] rounded-lg overflow-hidden object-cover"
|
|
169
|
+
className: "w-[88px] h-[88px] rounded-lg overflow-hidden object-cover slack_blocks_to_jsx__image_element"
|
|
170
170
|
}
|
|
171
171
|
) });
|
|
172
172
|
};
|
|
@@ -218,7 +218,7 @@ var ButtonElement = (props) => {
|
|
|
218
218
|
type: "button",
|
|
219
219
|
id: action_id,
|
|
220
220
|
"aria-label": accessibility_label,
|
|
221
|
-
className: `px-2 pt-0 pb-[1px] text-small h-[28px] min-w-[56px] border rounded whitespace-nowrap font-semibold
|
|
221
|
+
className: `px-2 pt-0 pb-[1px] text-small h-[28px] min-w-[56px] border rounded whitespace-nowrap font-semibold slack_blocks_to_jsx__button_element ${style === "primary" ? "border-green-primary.3 text-green-primary" : style === "danger" ? "border-red-primary.3 text-red-primary" : "border-black-primary.3 text-black-primary"}`,
|
|
222
222
|
onClick: () => {
|
|
223
223
|
if (url) {
|
|
224
224
|
window.open(url, "_blank");
|
|
@@ -359,7 +359,7 @@ var CheckboxesElement = (props) => {
|
|
|
359
359
|
input_ref.current.focus();
|
|
360
360
|
}
|
|
361
361
|
}, [focus_on_load]);
|
|
362
|
-
return /* @__PURE__ */ jsx6("div", { id: action_id, className: "my-1 flex w-full
|
|
362
|
+
return /* @__PURE__ */ jsx6("div", { id: action_id, className: "my-1 flex w-full slack_blocks_to_jsx__checkboxes_element", children: /* @__PURE__ */ jsx6("fieldset", { className: "flex flex-col gap-2", children: options.map((option, i) => {
|
|
363
363
|
const { text, value, description } = option;
|
|
364
364
|
return /* @__PURE__ */ jsxs3(
|
|
365
365
|
"label",
|
|
@@ -423,34 +423,42 @@ var PlaintTextInput = (props) => {
|
|
|
423
423
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
424
424
|
};
|
|
425
425
|
}, []);
|
|
426
|
-
return /* @__PURE__ */ jsxs4(
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
426
|
+
return /* @__PURE__ */ jsxs4(
|
|
427
|
+
"div",
|
|
428
|
+
{
|
|
429
|
+
id: action_id,
|
|
430
|
+
className: "relative text-small w-full slack_blocks_to_jsx__plain_text_input_element",
|
|
431
|
+
tabIndex: 0,
|
|
432
|
+
children: [
|
|
433
|
+
!value && placeholder && /* @__PURE__ */ jsx7("div", { className: "absolute left-2 top-2 text-black-primary.3", children: /* @__PURE__ */ jsx7(TextObject, { data: placeholder }) }),
|
|
434
|
+
!value && !placeholder && /* @__PURE__ */ jsx7("div", { className: "absolute left-2 top-2 text-black-primary.3", children: /* @__PURE__ */ jsx7(
|
|
435
|
+
TextObject,
|
|
436
|
+
{
|
|
437
|
+
data: {
|
|
438
|
+
type: "plain_text",
|
|
439
|
+
text: "Write something"
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
) }),
|
|
443
|
+
/* @__PURE__ */ jsx7(
|
|
444
|
+
"textarea",
|
|
445
|
+
{
|
|
446
|
+
value,
|
|
447
|
+
onChange: (e) => setValue(e.target.value),
|
|
448
|
+
className: "w-full focus:outline-none rounded border border-black-primary.3 p-2",
|
|
449
|
+
minLength: min_length,
|
|
450
|
+
maxLength: max_length,
|
|
451
|
+
style: {
|
|
452
|
+
maxHeight: "200px",
|
|
453
|
+
minHeight: "80px",
|
|
454
|
+
height: "100px"
|
|
455
|
+
},
|
|
456
|
+
"aria-label": "Select an item"
|
|
457
|
+
}
|
|
458
|
+
)
|
|
459
|
+
]
|
|
460
|
+
}
|
|
461
|
+
);
|
|
454
462
|
};
|
|
455
463
|
|
|
456
464
|
// src/components/elements/users_select_element.tsx
|
|
@@ -484,7 +492,7 @@ var UsersSelectElement = (props) => {
|
|
|
484
492
|
"div",
|
|
485
493
|
{
|
|
486
494
|
id: action_id,
|
|
487
|
-
className: "py-1 px-2 h-7 min-h-[28px] relative flex items-center justify-between rounded text-small w-[190px] border border-black-primary.3",
|
|
495
|
+
className: "py-1 px-2 h-7 min-h-[28px] relative flex items-center justify-between rounded text-small w-[190px] border border-black-primary.3 slack_blocks_to_jsx__users_select_element",
|
|
488
496
|
tabIndex: 0,
|
|
489
497
|
children: [
|
|
490
498
|
visible && /* @__PURE__ */ jsx8(
|
|
@@ -772,6 +780,7 @@ var RichTextSectionBroadcast = (props) => {
|
|
|
772
780
|
className: `
|
|
773
781
|
inline-block
|
|
774
782
|
slack_broadcast
|
|
783
|
+
slack_blocks_to_jsx__rich_text_section_element_broadcast
|
|
775
784
|
${(style == null ? void 0 : style.italic) ? "italic" : ""}
|
|
776
785
|
${(style == null ? void 0 : style.strike) ? "line-through" : ""}
|
|
777
786
|
${(style == null ? void 0 : style.bold) ? "font-medium" : ""}
|
|
@@ -799,6 +808,7 @@ var RichTextSectionChannel = (props) => {
|
|
|
799
808
|
className: `
|
|
800
809
|
inline-block
|
|
801
810
|
slack_channel
|
|
811
|
+
slack_blocks_to_jsx__rich_text_section_element_channel
|
|
802
812
|
${(style == null ? void 0 : style.italic) ? "italic" : ""}
|
|
803
813
|
${(style == null ? void 0 : style.strike) ? "line-through" : ""}
|
|
804
814
|
${(style == null ? void 0 : style.bold) ? "font-medium" : ""}
|
|
@@ -818,7 +828,7 @@ import { jsx as jsx16 } from "react/jsx-runtime";
|
|
|
818
828
|
var RichTextSectionEmoji = (props) => {
|
|
819
829
|
const { name } = props;
|
|
820
830
|
const { hooks } = useGlobalData();
|
|
821
|
-
return /* @__PURE__ */ jsx16("span", { children: hooks.emoji ? hooks.emoji(name) : parseEmojis(`:${name}:`) });
|
|
831
|
+
return /* @__PURE__ */ jsx16("span", { className: "slack_blocks_to_jsx__rich_text_section_element_emoji", children: hooks.emoji ? hooks.emoji(name) : parseEmojis(`:${name}:`) });
|
|
822
832
|
};
|
|
823
833
|
|
|
824
834
|
// src/components/blocks/rich_text/rich_text_section_user.tsx
|
|
@@ -835,6 +845,7 @@ var RichTextSectionUser = (props) => {
|
|
|
835
845
|
className: `
|
|
836
846
|
inline-block
|
|
837
847
|
slack_user
|
|
848
|
+
slack_blocks_to_jsx__rich_text_section_element_user
|
|
838
849
|
${(style == null ? void 0 : style.italic) ? "italic" : ""}
|
|
839
850
|
${(style == null ? void 0 : style.strike) ? "line-through" : ""}
|
|
840
851
|
${(style == null ? void 0 : style.bold) ? "font-medium" : ""}
|
|
@@ -863,6 +874,7 @@ var RichTextSectionUserGroup = (props) => {
|
|
|
863
874
|
className: `
|
|
864
875
|
inline-block
|
|
865
876
|
slack_user_group
|
|
877
|
+
slack_blocks_to_jsx__rich_text_section_element_user_group
|
|
866
878
|
${(style == null ? void 0 : style.italic) ? "italic" : ""}
|
|
867
879
|
${(style == null ? void 0 : style.strike) ? "line-through" : ""}
|
|
868
880
|
${(style == null ? void 0 : style.bold) ? "font-medium" : ""}
|
|
@@ -892,6 +904,7 @@ var RichTextSectionElement = (props) => {
|
|
|
892
904
|
"span",
|
|
893
905
|
{
|
|
894
906
|
className: `
|
|
907
|
+
slack_blocks_to_jsx__rich_text_section_element_text
|
|
895
908
|
${(style == null ? void 0 : style.italic) ? "italic" : ""}
|
|
896
909
|
${(style == null ? void 0 : style.strike) ? "line-through" : ""}
|
|
897
910
|
${(style == null ? void 0 : style.code) ? "slack_inline_code" : ""}
|
|
@@ -910,6 +923,7 @@ var RichTextSectionElement = (props) => {
|
|
|
910
923
|
rel: "noreferrer noopener",
|
|
911
924
|
href: url,
|
|
912
925
|
className: `
|
|
926
|
+
slack_blocks_to_jsx__rich_text_section_element_link
|
|
913
927
|
text-blue-primary hover:underline underline-offset-4
|
|
914
928
|
${(style == null ? void 0 : style.italic) ? "italic" : ""}
|
|
915
929
|
${(style == null ? void 0 : style.strike) ? "line-through" : ""}
|
|
@@ -935,7 +949,7 @@ var Element = (props) => {
|
|
|
935
949
|
const { element } = props;
|
|
936
950
|
if (element.type === "rich_text_list") {
|
|
937
951
|
const { elements, style, border = 0, indent, offset } = element;
|
|
938
|
-
return /* @__PURE__ */ jsxs9("div", { className: "flex gap-2", children: [
|
|
952
|
+
return /* @__PURE__ */ jsxs9("div", { className: "flex gap-2 slack_blocks_to_jsx__rich_text_list_element", children: [
|
|
939
953
|
border === 1 && /* @__PURE__ */ jsx20("div", { className: "w-1 rounded bg-gray-primary self-stretch" }),
|
|
940
954
|
/* @__PURE__ */ jsx20(RichTextListWrapper, { element, className: `list-none`, children: elements.map((el, i) => {
|
|
941
955
|
return /* @__PURE__ */ jsxs9(
|
|
@@ -973,7 +987,7 @@ var Element = (props) => {
|
|
|
973
987
|
}
|
|
974
988
|
if (element.type === "rich_text_preformatted") {
|
|
975
989
|
const { elements, border } = element;
|
|
976
|
-
return /* @__PURE__ */ jsxs9("code", { className: "flex gap-2 w-full", children: [
|
|
990
|
+
return /* @__PURE__ */ jsxs9("code", { className: "flex gap-2 w-full slack_blocks_to_jsx__rich_text_preformatted_element", children: [
|
|
977
991
|
border === 1 && /* @__PURE__ */ jsx20("div", { className: "w-1 rounded bg-gray-primary self-stretch" }),
|
|
978
992
|
/* @__PURE__ */ jsx20(
|
|
979
993
|
"pre",
|
|
@@ -992,7 +1006,7 @@ var Element = (props) => {
|
|
|
992
1006
|
}
|
|
993
1007
|
if (element.type === "rich_text_quote") {
|
|
994
1008
|
const { elements, border } = element;
|
|
995
|
-
return /* @__PURE__ */ jsxs9("blockquote", { className: "flex gap-2", children: [
|
|
1009
|
+
return /* @__PURE__ */ jsxs9("blockquote", { className: "flex gap-2 slack_blocks_to_jsx__rich_text_quote_element", children: [
|
|
996
1010
|
border === 1 && /* @__PURE__ */ jsx20("div", { className: "w-1 rounded bg-gray-primary self-stretch" }),
|
|
997
1011
|
elements.map((el, i) => {
|
|
998
1012
|
return /* @__PURE__ */ jsx20(RichTextSectionElement, { element: el }, `${el.type}__${i}`);
|
|
@@ -1001,7 +1015,7 @@ var Element = (props) => {
|
|
|
1001
1015
|
}
|
|
1002
1016
|
if (element.type === "rich_text_section") {
|
|
1003
1017
|
const { elements } = element;
|
|
1004
|
-
return /* @__PURE__ */ jsx20("div", { className: "inline-block", children: elements.map((el, i) => {
|
|
1018
|
+
return /* @__PURE__ */ jsx20("div", { className: "inline-block slack_blocks_to_jsx__rich_text_section_element", children: elements.map((el, i) => {
|
|
1005
1019
|
return /* @__PURE__ */ jsx20(RichTextSectionElement, { element: el }, `${el.type}__${i}`);
|
|
1006
1020
|
}) });
|
|
1007
1021
|
}
|
|
@@ -1115,7 +1129,7 @@ var getElementComponent = (element) => {
|
|
|
1115
1129
|
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
1116
1130
|
var BlockWrapper = (props) => {
|
|
1117
1131
|
const { children } = props;
|
|
1118
|
-
return /* @__PURE__ */ jsx23("div", { className: "text-base break-words font-normal", children });
|
|
1132
|
+
return /* @__PURE__ */ jsx23("div", { className: "text-base slack_blocks_to_jsx--block_wrapper break-words font-normal", children });
|
|
1119
1133
|
};
|
|
1120
1134
|
|
|
1121
1135
|
// src/message.tsx
|
|
@@ -1132,7 +1146,8 @@ var Message = (props) => {
|
|
|
1132
1146
|
showBlockKitDebug = false,
|
|
1133
1147
|
unstyled = false,
|
|
1134
1148
|
data = {},
|
|
1135
|
-
hooks = {}
|
|
1149
|
+
hooks = {},
|
|
1150
|
+
withoutWrapper = false
|
|
1136
1151
|
} = props;
|
|
1137
1152
|
const { setChannels, setUsers, setHooks } = useGlobalData();
|
|
1138
1153
|
useEffect5(() => {
|
|
@@ -1143,6 +1158,22 @@ var Message = (props) => {
|
|
|
1143
1158
|
if (hooks)
|
|
1144
1159
|
setHooks(hooks);
|
|
1145
1160
|
}, [data]);
|
|
1161
|
+
if (withoutWrapper) {
|
|
1162
|
+
return /* @__PURE__ */ jsx24(
|
|
1163
|
+
"div",
|
|
1164
|
+
{
|
|
1165
|
+
id: "slack_blocks_to_jsx",
|
|
1166
|
+
className: `slack_blocks_to_jsx relative flex gap-2 w-full max-w-[600px] ${unstyled ? "styles_disabled" : "styles_enabled"} ${className}`,
|
|
1167
|
+
style,
|
|
1168
|
+
children: blocks.map((block, i) => {
|
|
1169
|
+
const element = getBlockComponent(block);
|
|
1170
|
+
if (!element)
|
|
1171
|
+
return null;
|
|
1172
|
+
return /* @__PURE__ */ jsx24(BlockWrapper, { children: element }, i);
|
|
1173
|
+
})
|
|
1174
|
+
}
|
|
1175
|
+
);
|
|
1176
|
+
}
|
|
1146
1177
|
return /* @__PURE__ */ jsx24("div", { id: "slack_blocks_to_jsx", children: /* @__PURE__ */ jsxs11(
|
|
1147
1178
|
"section",
|
|
1148
1179
|
{
|
|
@@ -1164,7 +1195,7 @@ var Message = (props) => {
|
|
|
1164
1195
|
/* @__PURE__ */ jsx24("div", { className: "shrink-0", children: /* @__PURE__ */ jsx24("img", { src: logo, className: "w-9 h-9", alt: name }) }),
|
|
1165
1196
|
/* @__PURE__ */ jsxs11("div", { className: "flex flex-col w-full", children: [
|
|
1166
1197
|
/* @__PURE__ */ jsx24(Header, { name, time }),
|
|
1167
|
-
/* @__PURE__ */ jsx24("div", { children: blocks.map((block, i) => {
|
|
1198
|
+
/* @__PURE__ */ jsx24("div", { className: "slack_blocks_to_jsx--blocks", children: blocks.map((block, i) => {
|
|
1168
1199
|
const element = getBlockComponent(block);
|
|
1169
1200
|
if (!element)
|
|
1170
1201
|
return null;
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -1,18 +1,118 @@
|
|
|
1
|
-
# Slack Blocks to JSX
|
|
1
|
+
# Slack Blocks to JSX Documentation
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## Overview
|
|
4
|
+
The `slack-blocks-to-jsx` package allows you to render Slack blocks in React with styles that closely mimic how they are displayed in Slack. This library converts Slack's block kit components into JSX components, maintaining the visual fidelity and interactive elements.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
**🚨 Quickly test out the libray on online playground**: https://slack-block-to-jsx-playground.vercel.app/
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
3. Import the component and use it `import { Message } from "slack-blocks-to-jsx"`
|
|
10
|
-
4. (optional) import the Block type to define the blocks for better type safety :)
|
|
8
|
+
## Installation
|
|
9
|
+
To use this package in your project, install it via npm:
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
```bash
|
|
12
|
+
npm install slack-blocks-to-jsx
|
|
13
|
+
```
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
Or using yarn:
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
```bash
|
|
18
|
+
yarn add slack-blocks-to-jsx
|
|
19
|
+
```
|
|
17
20
|
|
|
18
|
-
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
### Importing Styles
|
|
24
|
+
Import the necessary CSS file in your entry point to ensure the styles are applied:
|
|
25
|
+
|
|
26
|
+
```javascript
|
|
27
|
+
import "slack-blocks-to-jsx/dist/style.css";
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Using Components
|
|
31
|
+
Import the `Message` component from the package and use it to render your Slack blocks:
|
|
32
|
+
|
|
33
|
+
```javascript
|
|
34
|
+
import { Message } from "slack-blocks-to-jsx";
|
|
35
|
+
|
|
36
|
+
const blocks = [...]; // your Slack blocks data
|
|
37
|
+
|
|
38
|
+
<Message time={new Date()} name="Your Company" logo="logo_url" blocks={blocks} />
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Types
|
|
42
|
+
For better type safety, you can import the `Block` type:
|
|
43
|
+
|
|
44
|
+
```javascript
|
|
45
|
+
import type { Block } from "slack-blocks-to-jsx";
|
|
46
|
+
|
|
47
|
+
const blocks: Block[] = [...]; // your Slack blocks data
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Components
|
|
51
|
+
|
|
52
|
+
### `Message`
|
|
53
|
+
This is the main component that renders the entire Slack message. It supports various props to customize the appearance and behavior:
|
|
54
|
+
|
|
55
|
+
- `blocks`: Array of Slack block objects.
|
|
56
|
+
- `logo`: URL of the logo to display.
|
|
57
|
+
- `name`: Name of the sender.
|
|
58
|
+
- `time?`: Timestamp for the message.
|
|
59
|
+
- `className?`, `style?`: Standard React styling props.
|
|
60
|
+
- `unstyled?`: If true, disables all included styles. Default to false.
|
|
61
|
+
- `withoutWrapper?`: If true, renders only the Slack blocks without any wrapper. Default to false.
|
|
62
|
+
- `hooks?`: custom handlers for user, channel, broadcast, usergroup, emoji etc.
|
|
63
|
+
- `data?`: optionally pass an array or users, channels and user groups to automatically be replaced with the user, channel and user group mentions.
|
|
64
|
+
- `showBlockKitDebug?`: Show a link to open the message in the Slack Block Kit Builder, for debugging purposes. Defaults to false.
|
|
65
|
+
|
|
66
|
+
### Block Components
|
|
67
|
+
Each Slack block type has a corresponding component:
|
|
68
|
+
|
|
69
|
+
- `Section` (✅ supported)
|
|
70
|
+
- `Divider` (✅ supported)
|
|
71
|
+
- `Image` (✅ supported)
|
|
72
|
+
- `Context` (✅ supported)
|
|
73
|
+
- `Actions` (🟨 partially supported)
|
|
74
|
+
- `File` (❌ not supported yet)
|
|
75
|
+
- `Header` (❌ not supported yet)
|
|
76
|
+
- `Input` (🟨 partially supported)
|
|
77
|
+
- `RichText` (✅ supported)
|
|
78
|
+
- `Video` (❌ not supported yet)
|
|
79
|
+
|
|
80
|
+
If you want a support of a particular block or element which is not supported yet so please raise a github issue or mail me at codeemash@gmail.com. I will try to push it asap.
|
|
81
|
+
|
|
82
|
+
## Customization
|
|
83
|
+
You can handle custom rendering and interactions using the `hooks` prop in the `Message` component. This allows you to define custom behavior for user mentions, channels, and other interactive elements. You can also override default styling. Here are the classes structure to understand to override any block styling.
|
|
84
|
+
|
|
85
|
+
`.slack_blocks_to_jsx`: Main Wrapper
|
|
86
|
+
`.slack_blocks_to_jsx--header`: Header (name and time)
|
|
87
|
+
`.slack_blocks_to_jsx--blocks`: blocks array mapping wrapper
|
|
88
|
+
`.slack_blocks_to_jsx--block_wrapper`: wrapper around every block
|
|
89
|
+
`.slack_blocks_to_jsx__divider`: Divider Block
|
|
90
|
+
`.slack_blocks_to_jsx__section`: Section Block
|
|
91
|
+
`.slack_blocks_to_jsx__image`: Image Block
|
|
92
|
+
`.slack_blocks_to_jsx__context`: Context Block
|
|
93
|
+
`.slack_blocks_to_jsx__actions`: Actions Block
|
|
94
|
+
`.slack_blocks_to_jsx__input`: Input Block
|
|
95
|
+
`.slack_blocks_to_jsx__rich_text`: Rich Text Block
|
|
96
|
+
`.slack_blocks_to_jsx__rich_text_list_element`: Rich Text Block List Element
|
|
97
|
+
`.slack_blocks_to_jsx__rich_text_preformatted_element`: Rich Text Block Preformatted Element
|
|
98
|
+
`.slack_blocks_to_jsx__rich_text_quote_element`: Rich Text Block Element Quote Element
|
|
99
|
+
`.slack_blocks_to_jsx__rich_text_section_element`: Rich Text Block Section Element
|
|
100
|
+
|
|
101
|
+
...as so on (all the other classes will be similar too, for example `.slack_blocks_to_jsx__rich_text_section_element_user` for Rich Text Block Section Element User)
|
|
102
|
+
|
|
103
|
+
If you want any other customization so please raise a github issue or mail me at codeemash@gmail.com. I will try to push it asap if it aligns with the library development vision.
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
## Development and Contribution
|
|
107
|
+
The project is open-source, and contributions are welcome. If you encounter any issues or want to suggest improvements, please file an issue on the GitHub repository:
|
|
108
|
+
|
|
109
|
+
[GitHub Repository Issues](https://github.com/themashcodee/slack-blocks-to-jsx/issues)
|
|
110
|
+
|
|
111
|
+
## License
|
|
112
|
+
The project is licensed under the MIT license, allowing free use, modification, and distribution.
|
|
113
|
+
|
|
114
|
+
## Support
|
|
115
|
+
|
|
116
|
+
If you like my work, you can buy me a coffee! 😊
|
|
117
|
+
|
|
118
|
+
[](https://www.buymeacoffee.com/themashcodee)
|