@nkootstra/block-kit 0.3.3 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{index-D139DZfD.d.ts → index-DXUlQCUq.d.ts} +12 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +176 -34
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/styles.css.map +1 -1
- package/dist/transport.d.ts +1 -1
- package/dist/web-api.d.ts +1 -1
- package/package.json +1 -1
|
@@ -63,6 +63,8 @@ interface PayloadIdentity {
|
|
|
63
63
|
token?: string;
|
|
64
64
|
triggerId?: string;
|
|
65
65
|
responseUrl?: string;
|
|
66
|
+
/** Whether the app is installed org-wide on an Enterprise Grid org (`is_enterprise_install`). */
|
|
67
|
+
isEnterpriseInstall?: boolean;
|
|
66
68
|
}
|
|
67
69
|
declare const DEFAULT_IDENTITY: {
|
|
68
70
|
team: PayloadTeam | null;
|
|
@@ -71,6 +73,7 @@ declare const DEFAULT_IDENTITY: {
|
|
|
71
73
|
token: string;
|
|
72
74
|
triggerId: string;
|
|
73
75
|
responseUrl: string;
|
|
76
|
+
isEnterpriseInstall: boolean;
|
|
74
77
|
};
|
|
75
78
|
type ResolvedIdentity = typeof DEFAULT_IDENTITY;
|
|
76
79
|
/** The `message` surface's container: the message the block_actions/actions came from. */
|
|
@@ -159,10 +162,18 @@ interface BuildBlockActionsPayloadOptions {
|
|
|
159
162
|
container: Container;
|
|
160
163
|
identity?: PayloadIdentity;
|
|
161
164
|
}
|
|
165
|
+
/** The Enterprise Grid org a payload came from, as Slack names it. */
|
|
166
|
+
interface PayloadEnterprise {
|
|
167
|
+
id: string;
|
|
168
|
+
name: string;
|
|
169
|
+
}
|
|
162
170
|
interface BlockActionsPayloadBase {
|
|
163
171
|
type: "block_actions";
|
|
164
172
|
actions: BlockAction[];
|
|
165
173
|
team: PayloadTeam | null;
|
|
174
|
+
/** The team's Enterprise Grid org, or `null` outside one. */
|
|
175
|
+
enterprise: PayloadEnterprise | null;
|
|
176
|
+
is_enterprise_install: boolean;
|
|
166
177
|
user: PayloadUser;
|
|
167
178
|
token?: string;
|
|
168
179
|
response_url?: string;
|
|
@@ -940,4 +951,4 @@ declare const VALIDATION_MESSAGES: {
|
|
|
940
951
|
declare function validateView(blocks: readonly Json[] | readonly unknown[], state: StateValues): Record<string, string>;
|
|
941
952
|
//#endregion
|
|
942
953
|
export { useLiveView as $, BlockAction as A, PayloadContext as B, SlackAttachment as C, Block as Ct, elementComponents as D, Json as Dt, SlackReaction as E, ElementProps as Et, EmojiOptions as F, Surface as G, StackedView as H, LinkProps as I, SurfaceScopeValue as J, SurfaceScope as K, MentionRef as L, BlockKitProvider as M, BlockKitProviderProps as N, Element as O, ElementState as P, useContainer as Q, MessageApi as R, MessageProps as S, blockComponents as St, SlackMessageLike as T, BlockProps as Tt, StateValues as U, Resolvers as V, SubmitResult as W, ViewsApi as X, UserProfile as Y, useBlockKit as Z, HomeTabView as _, ViewResponseAction as _t, Tooltip as a, BuildViewSubmissionPayloadOptions as at, Message as b, buildViewClosedPayload as bt, TextObject as c, MessageContainer as ct, ViewProps as d, PayloadTeam as dt, BlockActionsPayload as et, Modal as f, PayloadUser as ft, HomeTabProps as g, ViewLike as gt, HomeTab as h, ViewContainer as ht, UserMentionProps as i, BuildViewClosedPayloadOptions as it, BlockKitContextValue as j, ActionContext as k, AnyView as l, OptionsResponse as lt, ModalView as m, ViewBlockActionsPayload as mt, validateView as n, BuildBlockActionsPayloadOptions as nt, TooltipProps as o, Container as ot, ModalProps as p, SuggestionOption as pt, SurfaceScopeProps as q, UserMention as r, BuildBlockSuggestionPayloadOptions as rt, Text as s, MessageBlockActionsPayload as st, VALIDATION_MESSAGES as t, BlockSuggestionPayload as tt, View as u, PayloadIdentity as ut, Mrkdwn as v, buildBlockActionsPayload as vt, SlackAttachmentField as w, Blocks as wt, MessageApp as x, buildViewSubmissionPayload as xt, MrkdwnProps as y, buildBlockSuggestionPayload as yt, MessageUpdate as z };
|
|
943
|
-
//# sourceMappingURL=index-
|
|
954
|
+
//# sourceMappingURL=index-DXUlQCUq.d.ts.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
|
|
2
|
-
import { $ as useLiveView, A as BlockAction, B as PayloadContext, C as SlackAttachment, Ct as Block, D as elementComponents, Dt as Json, E as SlackReaction, Et as ElementProps, F as EmojiOptions, G as Surface, H as StackedView, I as LinkProps, J as SurfaceScopeValue, K as SurfaceScope, L as MentionRef, M as BlockKitProvider, N as BlockKitProviderProps, O as Element, P as ElementState, Q as useContainer, R as MessageApi, S as MessageProps, St as blockComponents, T as SlackMessageLike, Tt as BlockProps, U as StateValues, V as Resolvers, W as SubmitResult, X as ViewsApi, Y as UserProfile, Z as useBlockKit, _ as HomeTabView, _t as ViewResponseAction, a as Tooltip, at as BuildViewSubmissionPayloadOptions, b as Message, bt as buildViewClosedPayload, c as TextObject, ct as MessageContainer, d as ViewProps, dt as PayloadTeam, et as BlockActionsPayload, f as Modal, ft as PayloadUser, g as HomeTabProps, gt as ViewLike, h as HomeTab, ht as ViewContainer, i as UserMentionProps, it as BuildViewClosedPayloadOptions, j as BlockKitContextValue, k as ActionContext, l as AnyView, lt as OptionsResponse, m as ModalView, mt as ViewBlockActionsPayload, n as validateView, nt as BuildBlockActionsPayloadOptions, o as TooltipProps, ot as Container, p as ModalProps, pt as SuggestionOption, q as SurfaceScopeProps, r as UserMention, rt as BuildBlockSuggestionPayloadOptions, s as Text, st as MessageBlockActionsPayload, t as VALIDATION_MESSAGES, tt as BlockSuggestionPayload, u as View, ut as PayloadIdentity, v as Mrkdwn, vt as buildBlockActionsPayload, w as SlackAttachmentField, wt as Blocks, x as MessageApp, xt as buildViewSubmissionPayload, y as MrkdwnProps, yt as buildBlockSuggestionPayload, z as MessageUpdate } from "./index-
|
|
2
|
+
import { $ as useLiveView, A as BlockAction, B as PayloadContext, C as SlackAttachment, Ct as Block, D as elementComponents, Dt as Json, E as SlackReaction, Et as ElementProps, F as EmojiOptions, G as Surface, H as StackedView, I as LinkProps, J as SurfaceScopeValue, K as SurfaceScope, L as MentionRef, M as BlockKitProvider, N as BlockKitProviderProps, O as Element, P as ElementState, Q as useContainer, R as MessageApi, S as MessageProps, St as blockComponents, T as SlackMessageLike, Tt as BlockProps, U as StateValues, V as Resolvers, W as SubmitResult, X as ViewsApi, Y as UserProfile, Z as useBlockKit, _ as HomeTabView, _t as ViewResponseAction, a as Tooltip, at as BuildViewSubmissionPayloadOptions, b as Message, bt as buildViewClosedPayload, c as TextObject, ct as MessageContainer, d as ViewProps, dt as PayloadTeam, et as BlockActionsPayload, f as Modal, ft as PayloadUser, g as HomeTabProps, gt as ViewLike, h as HomeTab, ht as ViewContainer, i as UserMentionProps, it as BuildViewClosedPayloadOptions, j as BlockKitContextValue, k as ActionContext, l as AnyView, lt as OptionsResponse, m as ModalView, mt as ViewBlockActionsPayload, n as validateView, nt as BuildBlockActionsPayloadOptions, o as TooltipProps, ot as Container, p as ModalProps, pt as SuggestionOption, q as SurfaceScopeProps, r as UserMention, rt as BuildBlockSuggestionPayloadOptions, s as Text, st as MessageBlockActionsPayload, t as VALIDATION_MESSAGES, tt as BlockSuggestionPayload, u as View, ut as PayloadIdentity, v as Mrkdwn, vt as buildBlockActionsPayload, w as SlackAttachmentField, wt as Blocks, x as MessageApp, xt as buildViewSubmissionPayload, y as MrkdwnProps, yt as buildBlockSuggestionPayload, z as MessageUpdate } from "./index-DXUlQCUq.js";
|
|
3
3
|
export { type ActionContext, type AnyView, Block, type BlockAction, type BlockActionsPayload, type BlockKitContextValue, BlockKitProvider, type BlockKitProviderProps, type BlockProps, type BlockSuggestionPayload, Blocks, type BuildBlockActionsPayloadOptions, type BuildBlockSuggestionPayloadOptions, type BuildViewClosedPayloadOptions, type BuildViewSubmissionPayloadOptions, type Container, Element, type ElementProps, type ElementState, type EmojiOptions, HomeTab, type HomeTabProps, type HomeTabView, type Json, type LinkProps, type MentionRef, Message, type MessageApi, type MessageApp, type MessageBlockActionsPayload, type MessageContainer, type MessageProps, type MessageUpdate, Modal, type ModalProps, type ModalView, Mrkdwn, type MrkdwnProps, type OptionsResponse, type PayloadContext, type PayloadIdentity, type PayloadTeam, type PayloadUser, type Resolvers, type SlackAttachment, type SlackAttachmentField, type SlackMessageLike, type SlackReaction, type StackedView, type StateValues, type SubmitResult, type SuggestionOption, type Surface, SurfaceScope, type SurfaceScopeProps, type SurfaceScopeValue, Text, type TextObject, Tooltip, type TooltipProps, UserMention, type UserMentionProps, type UserProfile, VALIDATION_MESSAGES, View, type ViewBlockActionsPayload, type ViewContainer, type ViewLike, type ViewProps, type ViewResponseAction, type ViewsApi, blockComponents, buildBlockActionsPayload, buildBlockSuggestionPayload, buildViewClosedPayload, buildViewSubmissionPayload, elementComponents, useBlockKit, useContainer, useLiveView, validateView };
|
package/dist/index.js
CHANGED
|
@@ -31,7 +31,8 @@ const DEFAULT_IDENTITY = {
|
|
|
31
31
|
apiAppId: "A00000000",
|
|
32
32
|
token: "verification-token",
|
|
33
33
|
triggerId: "000000000000.000000000000.deadbeefdeadbeefdeadbeefdeadbeef",
|
|
34
|
-
responseUrl: "https://hooks.slack.com/actions/T00000000/0000000000000/deadbeefdeadbeefdeadbeefdeadbeef"
|
|
34
|
+
responseUrl: "https://hooks.slack.com/actions/T00000000/0000000000000/deadbeefdeadbeefdeadbeefdeadbeef",
|
|
35
|
+
isEnterpriseInstall: false
|
|
35
36
|
};
|
|
36
37
|
function resolveIdentity(identity) {
|
|
37
38
|
return {
|
|
@@ -63,12 +64,66 @@ function toViewOutput(view, state, identity) {
|
|
|
63
64
|
external_id: view.external_id ?? ""
|
|
64
65
|
};
|
|
65
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* A text object as Slack echoes it back: `plain_text` gains `emoji: true` and `mrkdwn` gains
|
|
69
|
+
* `verbatim: false` unless the app set them.
|
|
70
|
+
*/
|
|
71
|
+
function normalizeText(text) {
|
|
72
|
+
if (typeof text !== "object" || text === null) return text;
|
|
73
|
+
const object = text;
|
|
74
|
+
if (object.type === "plain_text") return {
|
|
75
|
+
...text,
|
|
76
|
+
emoji: object.emoji ?? true
|
|
77
|
+
};
|
|
78
|
+
if (object.type === "mrkdwn") return {
|
|
79
|
+
...text,
|
|
80
|
+
verbatim: object.verbatim ?? false
|
|
81
|
+
};
|
|
82
|
+
return text;
|
|
83
|
+
}
|
|
84
|
+
function normalizeOption(option) {
|
|
85
|
+
if (typeof option !== "object" || option === null) return option;
|
|
86
|
+
const { text, description } = option;
|
|
87
|
+
return {
|
|
88
|
+
...option,
|
|
89
|
+
...text === void 0 ? {} : { text: normalizeText(text) },
|
|
90
|
+
...description === void 0 ? {} : { description: normalizeText(description) }
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/** An action or state entry with every text object it echoes normalized like Slack's. */
|
|
94
|
+
function normalizeEchoes(entry) {
|
|
95
|
+
const out = { ...entry };
|
|
96
|
+
if (out.text !== void 0) out.text = normalizeText(out.text);
|
|
97
|
+
if (out.placeholder !== void 0) out.placeholder = normalizeText(out.placeholder);
|
|
98
|
+
if (out.selected_option) out.selected_option = normalizeOption(out.selected_option);
|
|
99
|
+
if (Array.isArray(out.selected_options)) out.selected_options = out.selected_options.map(normalizeOption);
|
|
100
|
+
if (typeof out.confirm === "object" && out.confirm !== null) {
|
|
101
|
+
const confirm = { ...out.confirm };
|
|
102
|
+
for (const key of [
|
|
103
|
+
"title",
|
|
104
|
+
"text",
|
|
105
|
+
"confirm",
|
|
106
|
+
"deny"
|
|
107
|
+
]) if (confirm[key] !== void 0) confirm[key] = normalizeText(confirm[key]);
|
|
108
|
+
out.confirm = confirm;
|
|
109
|
+
}
|
|
110
|
+
return out;
|
|
111
|
+
}
|
|
112
|
+
function normalizeState(state) {
|
|
113
|
+
return Object.fromEntries(Object.entries(state).map(([blockId, elements]) => [blockId, Object.fromEntries(Object.entries(elements).map(([actionId, value]) => [actionId, normalizeEchoes(value)]))]));
|
|
114
|
+
}
|
|
66
115
|
function buildBlockActionsPayload({ action, state, container, identity }) {
|
|
67
116
|
const id = resolveIdentity(identity);
|
|
117
|
+
state = normalizeState(state);
|
|
68
118
|
const base = {
|
|
69
119
|
type: "block_actions",
|
|
70
|
-
actions: [action],
|
|
120
|
+
actions: [normalizeEchoes(action)],
|
|
71
121
|
team: id.team,
|
|
122
|
+
enterprise: id.team?.enterprise_id ? {
|
|
123
|
+
id: id.team.enterprise_id,
|
|
124
|
+
name: id.team.enterprise_name ?? ""
|
|
125
|
+
} : null,
|
|
126
|
+
is_enterprise_install: id.isEnterpriseInstall,
|
|
72
127
|
user: id.user,
|
|
73
128
|
token: id.token,
|
|
74
129
|
response_url: id.responseUrl,
|
|
@@ -6017,7 +6072,8 @@ function Button({ element, blockId }) {
|
|
|
6017
6072
|
},
|
|
6018
6073
|
...element.value !== void 0 ? { value: element.value } : {},
|
|
6019
6074
|
...element.url !== void 0 ? { url: element.url } : {},
|
|
6020
|
-
...element.style !== void 0 ? { style: element.style } : {}
|
|
6075
|
+
...element.style !== void 0 ? { style: element.style } : {},
|
|
6076
|
+
...element.confirm ? { confirm: element.confirm } : {}
|
|
6021
6077
|
});
|
|
6022
6078
|
if (element.url) window.open(element.url, "_blank", "noopener,noreferrer");
|
|
6023
6079
|
};
|
|
@@ -6453,7 +6509,8 @@ function DatePicker({ element, blockId }) {
|
|
|
6453
6509
|
type: "datepicker",
|
|
6454
6510
|
action_id: actionId,
|
|
6455
6511
|
block_id: blockId,
|
|
6456
|
-
selected_date: next
|
|
6512
|
+
selected_date: next,
|
|
6513
|
+
...element.initial_date !== void 0 ? { initial_date: element.initial_date } : {}
|
|
6457
6514
|
});
|
|
6458
6515
|
}
|
|
6459
6516
|
async function clear() {
|
|
@@ -6468,7 +6525,8 @@ function DatePicker({ element, blockId }) {
|
|
|
6468
6525
|
type: "datepicker",
|
|
6469
6526
|
action_id: actionId,
|
|
6470
6527
|
block_id: blockId,
|
|
6471
|
-
selected_date: null
|
|
6528
|
+
selected_date: null,
|
|
6529
|
+
...element.initial_date !== void 0 ? { initial_date: element.initial_date } : {}
|
|
6472
6530
|
});
|
|
6473
6531
|
}
|
|
6474
6532
|
return /* @__PURE__ */ jsxs("div", {
|
|
@@ -7059,19 +7117,26 @@ const FORMATTING_GROUPS = [
|
|
|
7059
7117
|
}
|
|
7060
7118
|
]
|
|
7061
7119
|
];
|
|
7062
|
-
/** The
|
|
7063
|
-
*
|
|
7120
|
+
/** The formatting bar Slack shows above a modal's rich-text editor. The editor here is plain text,
|
|
7121
|
+
* so its buttons are there to look like Slack's but marked unavailable; they dim until the editor
|
|
7122
|
+
* has focus, as Slack's do. */
|
|
7064
7123
|
function RichTextToolbar() {
|
|
7065
7124
|
return /* @__PURE__ */ jsx("div", {
|
|
7066
7125
|
className: "sbk-rich-text-input__toolbar",
|
|
7067
|
-
|
|
7068
|
-
|
|
7126
|
+
role: "toolbar",
|
|
7127
|
+
"aria-orientation": "horizontal",
|
|
7128
|
+
"aria-label": "Formatting",
|
|
7129
|
+
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", {
|
|
7130
|
+
type: "button",
|
|
7069
7131
|
className: "sbk-rich-text-input__tool",
|
|
7070
|
-
|
|
7132
|
+
"aria-label": icon.label,
|
|
7133
|
+
"aria-disabled": "true",
|
|
7134
|
+
tabIndex: -1,
|
|
7071
7135
|
children: /* @__PURE__ */ jsx("svg", {
|
|
7072
7136
|
viewBox: "0 0 20 20",
|
|
7073
7137
|
width: "18",
|
|
7074
7138
|
height: "18",
|
|
7139
|
+
"aria-hidden": "true",
|
|
7075
7140
|
children: /* @__PURE__ */ jsx("path", {
|
|
7076
7141
|
fill: "currentColor",
|
|
7077
7142
|
fillRule: icon.evenOdd ? "evenodd" : void 0,
|
|
@@ -7082,11 +7147,52 @@ function RichTextToolbar() {
|
|
|
7082
7147
|
}, icon.label))] }, group[0]?.label))
|
|
7083
7148
|
});
|
|
7084
7149
|
}
|
|
7150
|
+
/** Slack's "Aa" (show formatting) and emoji glyphs, 20-unit paths as Slack ships them. */
|
|
7151
|
+
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";
|
|
7152
|
+
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";
|
|
7153
|
+
function Glyph({ d }) {
|
|
7154
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
7155
|
+
viewBox: "0 0 20 20",
|
|
7156
|
+
width: "18",
|
|
7157
|
+
height: "18",
|
|
7158
|
+
"aria-hidden": "true",
|
|
7159
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
7160
|
+
fill: "currentColor",
|
|
7161
|
+
fillRule: "evenodd",
|
|
7162
|
+
clipRule: "evenodd",
|
|
7163
|
+
d
|
|
7164
|
+
})
|
|
7165
|
+
});
|
|
7166
|
+
}
|
|
7167
|
+
/** The row Slack draws under the editor: "Aa" shows or hides the formatting bar (underlined while
|
|
7168
|
+
* it's shown), and an emoji button, unavailable until block-kit has an emoji picker. */
|
|
7169
|
+
function RichTextComposerActions({ formatting, onToggleFormatting }) {
|
|
7170
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
7171
|
+
className: "sbk-rich-text-input__footer",
|
|
7172
|
+
role: "toolbar",
|
|
7173
|
+
"aria-orientation": "horizontal",
|
|
7174
|
+
"aria-label": "Composer actions",
|
|
7175
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
7176
|
+
type: "button",
|
|
7177
|
+
className: "sbk-rich-text-input__action sbk-rich-text-input__action--formatting",
|
|
7178
|
+
"aria-label": "Show formatting",
|
|
7179
|
+
"aria-pressed": formatting,
|
|
7180
|
+
onClick: onToggleFormatting,
|
|
7181
|
+
children: /* @__PURE__ */ jsx(Glyph, { d: FORMATTING_ICON })
|
|
7182
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
7183
|
+
type: "button",
|
|
7184
|
+
className: "sbk-rich-text-input__action",
|
|
7185
|
+
"aria-label": "Emoji",
|
|
7186
|
+
"aria-disabled": "true",
|
|
7187
|
+
tabIndex: -1,
|
|
7188
|
+
children: /* @__PURE__ */ jsx(Glyph, { d: EMOJI_ICON })
|
|
7189
|
+
})]
|
|
7190
|
+
});
|
|
7191
|
+
}
|
|
7085
7192
|
//#endregion
|
|
7086
7193
|
//#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. */
|
|
7194
|
+
/** Wraps plain text into the `rich_text` block shape Slack uses for this element's value. The
|
|
7195
|
+
* editor is plain text; Slack's formatting bar and composer row are drawn around it for parity. */
|
|
7090
7196
|
function toRichText(text) {
|
|
7091
7197
|
return {
|
|
7092
7198
|
type: "rich_text",
|
|
@@ -7115,6 +7221,8 @@ function RichTextInput({ element, blockId }) {
|
|
|
7115
7221
|
const invalid = useInvalidProps();
|
|
7116
7222
|
const actionId = element.action_id ?? "";
|
|
7117
7223
|
const initialText = fromRichText(element.initial_value);
|
|
7224
|
+
const [formatting, setFormatting] = useState(true);
|
|
7225
|
+
const [empty, setEmpty] = useState(initialText === "");
|
|
7118
7226
|
useEffect(() => {
|
|
7119
7227
|
if (element.initial_value) setValue(blockId, actionId, {
|
|
7120
7228
|
type: "rich_text_input",
|
|
@@ -7122,7 +7230,9 @@ function RichTextInput({ element, blockId }) {
|
|
|
7122
7230
|
});
|
|
7123
7231
|
}, []);
|
|
7124
7232
|
function onInput() {
|
|
7125
|
-
const
|
|
7233
|
+
const text = ref.current?.innerText ?? "";
|
|
7234
|
+
setEmpty(text.trim() === "");
|
|
7235
|
+
const richText = toRichText(text);
|
|
7126
7236
|
setValue(blockId, actionId, {
|
|
7127
7237
|
type: "rich_text_input",
|
|
7128
7238
|
rich_text_value: richText
|
|
@@ -7134,25 +7244,39 @@ function RichTextInput({ element, blockId }) {
|
|
|
7134
7244
|
rich_text_value: richText
|
|
7135
7245
|
});
|
|
7136
7246
|
}
|
|
7247
|
+
const placeholder = element.placeholder?.text;
|
|
7137
7248
|
return /* @__PURE__ */ jsxs("div", {
|
|
7138
7249
|
className: "sbk-rich-text-input",
|
|
7139
|
-
children: [
|
|
7140
|
-
|
|
7141
|
-
|
|
7142
|
-
|
|
7143
|
-
|
|
7144
|
-
|
|
7145
|
-
|
|
7146
|
-
|
|
7147
|
-
|
|
7148
|
-
|
|
7149
|
-
|
|
7150
|
-
|
|
7151
|
-
|
|
7152
|
-
|
|
7153
|
-
|
|
7154
|
-
|
|
7155
|
-
|
|
7250
|
+
children: [
|
|
7251
|
+
formatting && /* @__PURE__ */ jsx(RichTextToolbar, {}),
|
|
7252
|
+
/* @__PURE__ */ jsxs("div", {
|
|
7253
|
+
className: "sbk-rich-text-input__body",
|
|
7254
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
7255
|
+
ref,
|
|
7256
|
+
className: "sbk-rich-text-input__editor",
|
|
7257
|
+
contentEditable: true,
|
|
7258
|
+
suppressContentEditableWarning: true,
|
|
7259
|
+
role: "textbox",
|
|
7260
|
+
"aria-multiline": "true",
|
|
7261
|
+
...invalid,
|
|
7262
|
+
"aria-label": placeholder ?? actionId,
|
|
7263
|
+
onInput,
|
|
7264
|
+
style: {
|
|
7265
|
+
minHeight: element.min_lines ? `${element.min_lines * 22}px` : void 0,
|
|
7266
|
+
maxHeight: element.max_lines ? `${element.max_lines * 22}px` : void 0
|
|
7267
|
+
},
|
|
7268
|
+
children: initialText
|
|
7269
|
+
}), placeholder && empty && /* @__PURE__ */ jsx("div", {
|
|
7270
|
+
className: "sbk-rich-text-input__placeholder",
|
|
7271
|
+
"aria-hidden": "true",
|
|
7272
|
+
children: placeholder
|
|
7273
|
+
})]
|
|
7274
|
+
}),
|
|
7275
|
+
/* @__PURE__ */ jsx(RichTextComposerActions, {
|
|
7276
|
+
formatting,
|
|
7277
|
+
onToggleFormatting: () => setFormatting((shown) => !shown)
|
|
7278
|
+
})
|
|
7279
|
+
]
|
|
7156
7280
|
});
|
|
7157
7281
|
}
|
|
7158
7282
|
//#endregion
|
|
@@ -7312,7 +7436,8 @@ function Select({ element, blockId }) {
|
|
|
7312
7436
|
type: element.type,
|
|
7313
7437
|
action_id: actionId,
|
|
7314
7438
|
block_id: blockId,
|
|
7315
|
-
...fields
|
|
7439
|
+
...fields,
|
|
7440
|
+
...element.placeholder ? { placeholder: element.placeholder } : {}
|
|
7316
7441
|
});
|
|
7317
7442
|
}
|
|
7318
7443
|
function buildStateFor(next) {
|
|
@@ -7631,7 +7756,8 @@ function TimePicker({ element, blockId }) {
|
|
|
7631
7756
|
type: "timepicker",
|
|
7632
7757
|
action_id: actionId,
|
|
7633
7758
|
block_id: blockId,
|
|
7634
|
-
selected_time: next
|
|
7759
|
+
selected_time: next,
|
|
7760
|
+
...element.initial_time !== void 0 ? { initial_time: element.initial_time } : {}
|
|
7635
7761
|
});
|
|
7636
7762
|
}
|
|
7637
7763
|
const times = timeOptions();
|
|
@@ -10113,7 +10239,23 @@ function renderTopLevel(elements, ctx) {
|
|
|
10113
10239
|
i++;
|
|
10114
10240
|
}
|
|
10115
10241
|
const forest = buildListForest(run);
|
|
10116
|
-
|
|
10242
|
+
const lists = forest.map((group) => renderListGroup(group, ctx, key++, 0));
|
|
10243
|
+
if (!forest.some((group) => group.border)) {
|
|
10244
|
+
nodes.push(...lists);
|
|
10245
|
+
continue;
|
|
10246
|
+
}
|
|
10247
|
+
const quoted = [];
|
|
10248
|
+
while (i < elements.length && elements[i]?.type === "rich_text_quote") {
|
|
10249
|
+
quoted.push(/* @__PURE__ */ jsx("div", {
|
|
10250
|
+
className: "sbk-rich-text__quote-text",
|
|
10251
|
+
children: renderSectionChildren(elements[i].elements, ctx)
|
|
10252
|
+
}, key++));
|
|
10253
|
+
i++;
|
|
10254
|
+
}
|
|
10255
|
+
nodes.push(/* @__PURE__ */ jsxs("blockquote", {
|
|
10256
|
+
className: "sbk-rich-text__quote sbk-rich-text__quote--group",
|
|
10257
|
+
children: [lists, quoted]
|
|
10258
|
+
}, key++));
|
|
10117
10259
|
continue;
|
|
10118
10260
|
}
|
|
10119
10261
|
switch (el.type) {
|