@tightknitai/block-kitchen 0.10.8 → 0.10.10
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.cjs +311 -51
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +314 -54
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useSensors, useSensor, PointerSensor, TouchSensor, KeyboardSensor, pointerWithin, closestCenter, DndContext, DragOverlay, useDroppable, useDraggable } from '@dnd-kit/core';
|
|
2
2
|
import { sortableKeyboardCoordinates, SortableContext, verticalListSortingStrategy, useSortable } from '@dnd-kit/sortable';
|
|
3
|
-
import { X, Circle, Sparkles, FileText, AlignLeft, MousePointerClick, TextCursorInput, LayoutTemplate, Bell, Pilcrow, Image, Video, GalleryHorizontal, Table, ChartColumnBig, Container, Loader2, ExternalLink, AlertTriangle, ChevronRight, ChevronLeft, GripVertical, Sun, Moon, MessageSquare, AppWindow, Home, Plus, ChevronDown, BookOpen, Undo2, Redo2, Trash2, Code2, Pencil, Send, Search,
|
|
3
|
+
import { X, Circle, Sparkles, FileText, AlignLeft, MousePointerClick, TextCursorInput, LayoutTemplate, Bell, Pilcrow, Image, Video, GalleryHorizontal, Table, ChartColumnBig, Container, Loader2, ExternalLink, AlertTriangle, ChevronRight, ChevronLeft, GripVertical, ChevronsUpDown, Check, Sun, Moon, MessageSquare, AppWindow, Home, Plus, ChevronDown, BookOpen, Undo2, Redo2, Trash2, Code2, Pencil, Send, Search, Copy, Info, CheckCircle2, LayoutGrid, ArrowUp, ArrowDown, Type, Bold, Italic, Strikethrough, Underline, Code, List, ListOrdered, Quote, Smile, Link as Link$1 } from 'lucide-react';
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import { createContext, useState, useRef, useEffect, useCallback, useMemo, useId, useContext } from 'react';
|
|
6
6
|
import { clsx } from 'clsx';
|
|
@@ -13,16 +13,21 @@ import { nanoid } from 'nanoid';
|
|
|
13
13
|
import { Slot } from '@radix-ui/react-slot';
|
|
14
14
|
import { cva } from 'class-variance-authority';
|
|
15
15
|
import * as LabelPrimitive from '@radix-ui/react-label';
|
|
16
|
+
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
16
17
|
import 'slack-blocks-to-jsx/dist/style.css';
|
|
17
18
|
import { Message } from 'slack-blocks-to-jsx';
|
|
18
19
|
import { CSS } from '@dnd-kit/utilities';
|
|
19
|
-
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
20
20
|
import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
|
|
21
21
|
import Link from '@tiptap/extension-link';
|
|
22
|
-
import { Node, ReactNodeViewRenderer, mergeAttributes, NodeViewWrapper, useEditor, EditorContent } from '@tiptap/react';
|
|
22
|
+
import { Node as Node$1, ReactNodeViewRenderer, mergeAttributes, NodeViewWrapper, useEditor, EditorContent } from '@tiptap/react';
|
|
23
23
|
import StarterKit from '@tiptap/starter-kit';
|
|
24
24
|
|
|
25
25
|
// src/components/block-kitchen.tsx
|
|
26
|
+
|
|
27
|
+
// src/lib/channel-label.ts
|
|
28
|
+
function channelLabel(name) {
|
|
29
|
+
return `# ${name}`;
|
|
30
|
+
}
|
|
26
31
|
function cn(...inputs) {
|
|
27
32
|
return twMerge(clsx(inputs));
|
|
28
33
|
}
|
|
@@ -3035,6 +3040,220 @@ var Label = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ j
|
|
|
3035
3040
|
}
|
|
3036
3041
|
));
|
|
3037
3042
|
Label.displayName = LabelPrimitive.Root.displayName;
|
|
3043
|
+
var Popover = PopoverPrimitive.Root;
|
|
3044
|
+
var PopoverTrigger = PopoverPrimitive.Trigger;
|
|
3045
|
+
var PopoverAnchor = PopoverPrimitive.Anchor;
|
|
3046
|
+
var PopoverContent = React.forwardRef(({ className, align = "start", sideOffset = 8, collisionPadding = 16, ...props }, ref) => /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
3047
|
+
PopoverPrimitive.Content,
|
|
3048
|
+
{
|
|
3049
|
+
ref,
|
|
3050
|
+
align,
|
|
3051
|
+
sideOffset,
|
|
3052
|
+
collisionPadding,
|
|
3053
|
+
className: cn(
|
|
3054
|
+
"bk-portal-content z-50 max-h-[var(--radix-popover-content-available-height)] w-80 overflow-y-auto rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none",
|
|
3055
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
3056
|
+
className
|
|
3057
|
+
),
|
|
3058
|
+
...props
|
|
3059
|
+
}
|
|
3060
|
+
) }));
|
|
3061
|
+
PopoverContent.displayName = PopoverPrimitive.Content.displayName;
|
|
3062
|
+
function matchesQuery(name, query) {
|
|
3063
|
+
const needle = query.replace(/^\s*#\s*/, "").trim().toLowerCase();
|
|
3064
|
+
return needle === "" || name.toLowerCase().includes(needle);
|
|
3065
|
+
}
|
|
3066
|
+
function ChannelCombobox({
|
|
3067
|
+
id,
|
|
3068
|
+
channels,
|
|
3069
|
+
value,
|
|
3070
|
+
onChange,
|
|
3071
|
+
placeholder = "Search channels\u2026",
|
|
3072
|
+
className
|
|
3073
|
+
}) {
|
|
3074
|
+
const [open, setOpen] = useState(false);
|
|
3075
|
+
const [query, setQuery] = useState("");
|
|
3076
|
+
const [activeIndex, setActiveIndex] = useState(-1);
|
|
3077
|
+
const inputRef = useRef(null);
|
|
3078
|
+
const listRef = useRef(null);
|
|
3079
|
+
const domId = useId();
|
|
3080
|
+
const listboxId = `${domId}-listbox`;
|
|
3081
|
+
const optionDomId = (index) => `${domId}-option-${index}`;
|
|
3082
|
+
const selected = channels.find((c) => c.id === value) ?? null;
|
|
3083
|
+
const filtered = useMemo(
|
|
3084
|
+
() => open ? channels.filter((c) => matchesQuery(c.name, query)) : channels,
|
|
3085
|
+
[channels, open, query]
|
|
3086
|
+
);
|
|
3087
|
+
const inputValue = open ? query : selected ? channelLabel(selected.name) : "";
|
|
3088
|
+
useEffect(() => {
|
|
3089
|
+
if (!open) {
|
|
3090
|
+
setActiveIndex(-1);
|
|
3091
|
+
return;
|
|
3092
|
+
}
|
|
3093
|
+
setActiveIndex((prev) => {
|
|
3094
|
+
if (prev >= 0 && prev < filtered.length) {
|
|
3095
|
+
return prev;
|
|
3096
|
+
}
|
|
3097
|
+
const selectedIndex = filtered.findIndex((c) => c.id === value);
|
|
3098
|
+
return selectedIndex >= 0 ? selectedIndex : filtered.length > 0 ? 0 : -1;
|
|
3099
|
+
});
|
|
3100
|
+
}, [open, filtered, value]);
|
|
3101
|
+
useEffect(() => {
|
|
3102
|
+
if (!open || activeIndex < 0) {
|
|
3103
|
+
return;
|
|
3104
|
+
}
|
|
3105
|
+
const row = listRef.current?.querySelectorAll('[role="option"]')[activeIndex];
|
|
3106
|
+
row?.scrollIntoView?.({ block: "nearest" });
|
|
3107
|
+
}, [open, activeIndex]);
|
|
3108
|
+
const openList = () => {
|
|
3109
|
+
setQuery("");
|
|
3110
|
+
setOpen(true);
|
|
3111
|
+
};
|
|
3112
|
+
const closeList = () => {
|
|
3113
|
+
setOpen(false);
|
|
3114
|
+
setQuery("");
|
|
3115
|
+
};
|
|
3116
|
+
const commit = (channel) => {
|
|
3117
|
+
onChange(channel.id);
|
|
3118
|
+
closeList();
|
|
3119
|
+
inputRef.current?.focus();
|
|
3120
|
+
};
|
|
3121
|
+
const moveActive = (delta) => {
|
|
3122
|
+
if (!open) {
|
|
3123
|
+
openList();
|
|
3124
|
+
return;
|
|
3125
|
+
}
|
|
3126
|
+
if (filtered.length === 0) {
|
|
3127
|
+
return;
|
|
3128
|
+
}
|
|
3129
|
+
setActiveIndex((prev) => {
|
|
3130
|
+
const next = prev + delta;
|
|
3131
|
+
return next < 0 ? filtered.length - 1 : next >= filtered.length ? 0 : next;
|
|
3132
|
+
});
|
|
3133
|
+
};
|
|
3134
|
+
const handleKeyDown = (e) => {
|
|
3135
|
+
switch (e.key) {
|
|
3136
|
+
case "ArrowDown":
|
|
3137
|
+
e.preventDefault();
|
|
3138
|
+
moveActive(1);
|
|
3139
|
+
break;
|
|
3140
|
+
case "ArrowUp":
|
|
3141
|
+
e.preventDefault();
|
|
3142
|
+
moveActive(-1);
|
|
3143
|
+
break;
|
|
3144
|
+
case "Home":
|
|
3145
|
+
if (open && filtered.length > 0) {
|
|
3146
|
+
e.preventDefault();
|
|
3147
|
+
setActiveIndex(0);
|
|
3148
|
+
}
|
|
3149
|
+
break;
|
|
3150
|
+
case "End":
|
|
3151
|
+
if (open && filtered.length > 0) {
|
|
3152
|
+
e.preventDefault();
|
|
3153
|
+
setActiveIndex(filtered.length - 1);
|
|
3154
|
+
}
|
|
3155
|
+
break;
|
|
3156
|
+
case "Enter": {
|
|
3157
|
+
if (!open) {
|
|
3158
|
+
break;
|
|
3159
|
+
}
|
|
3160
|
+
e.preventDefault();
|
|
3161
|
+
const active = filtered[activeIndex];
|
|
3162
|
+
if (active) {
|
|
3163
|
+
commit(active);
|
|
3164
|
+
}
|
|
3165
|
+
break;
|
|
3166
|
+
}
|
|
3167
|
+
case "Escape":
|
|
3168
|
+
if (open) {
|
|
3169
|
+
e.stopPropagation();
|
|
3170
|
+
closeList();
|
|
3171
|
+
}
|
|
3172
|
+
break;
|
|
3173
|
+
case "Tab":
|
|
3174
|
+
if (open) {
|
|
3175
|
+
closeList();
|
|
3176
|
+
}
|
|
3177
|
+
break;
|
|
3178
|
+
}
|
|
3179
|
+
};
|
|
3180
|
+
return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: (next) => next ? openList() : closeList(), children: [
|
|
3181
|
+
/* @__PURE__ */ jsx(PopoverAnchor, { asChild: true, children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
3182
|
+
/* @__PURE__ */ jsx(
|
|
3183
|
+
Input,
|
|
3184
|
+
{
|
|
3185
|
+
ref: inputRef,
|
|
3186
|
+
id,
|
|
3187
|
+
role: "combobox",
|
|
3188
|
+
"aria-expanded": open,
|
|
3189
|
+
"aria-controls": listboxId,
|
|
3190
|
+
"aria-autocomplete": "list",
|
|
3191
|
+
"aria-activedescendant": open && activeIndex >= 0 ? optionDomId(activeIndex) : void 0,
|
|
3192
|
+
autoComplete: "off",
|
|
3193
|
+
spellCheck: false,
|
|
3194
|
+
value: inputValue,
|
|
3195
|
+
placeholder,
|
|
3196
|
+
onChange: (e) => {
|
|
3197
|
+
setQuery(e.target.value);
|
|
3198
|
+
setOpen(true);
|
|
3199
|
+
},
|
|
3200
|
+
onKeyDown: handleKeyDown,
|
|
3201
|
+
onClick: () => open ? closeList() : openList(),
|
|
3202
|
+
className: cn("pr-9", className)
|
|
3203
|
+
}
|
|
3204
|
+
),
|
|
3205
|
+
/* @__PURE__ */ jsx(
|
|
3206
|
+
ChevronsUpDown,
|
|
3207
|
+
{
|
|
3208
|
+
"aria-hidden": true,
|
|
3209
|
+
className: "pointer-events-none absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground"
|
|
3210
|
+
}
|
|
3211
|
+
)
|
|
3212
|
+
] }) }),
|
|
3213
|
+
/* @__PURE__ */ jsx(
|
|
3214
|
+
PopoverContent,
|
|
3215
|
+
{
|
|
3216
|
+
ref: listRef,
|
|
3217
|
+
onOpenAutoFocus: (e) => e.preventDefault(),
|
|
3218
|
+
onCloseAutoFocus: (e) => e.preventDefault(),
|
|
3219
|
+
onInteractOutside: (e) => {
|
|
3220
|
+
if (e.target instanceof Node && inputRef.current?.contains(e.target)) {
|
|
3221
|
+
e.preventDefault();
|
|
3222
|
+
}
|
|
3223
|
+
},
|
|
3224
|
+
sideOffset: 4,
|
|
3225
|
+
className: "max-h-[min(15rem,var(--radix-popover-content-available-height))] w-[var(--radix-popover-trigger-width)] min-w-48 p-1",
|
|
3226
|
+
children: /* @__PURE__ */ jsx("div", { role: "listbox", id: listboxId, "aria-label": "Channels", children: filtered.length === 0 ? /* @__PURE__ */ jsx("p", { className: "px-2 py-3 text-center text-xs text-muted-foreground", children: "No channels match that search." }) : filtered.map((channel, index) => {
|
|
3227
|
+
const isSelected = channel.id === value;
|
|
3228
|
+
return (
|
|
3229
|
+
// biome-ignore lint/a11y/useFocusableInteractive: options in an aria-activedescendant combobox must stay unfocusable — focus belongs to the input, which is what makes typing filter the list.
|
|
3230
|
+
// biome-ignore lint/a11y/useKeyWithClickEvents: the keyboard path lives on that same input, which drives this list via aria-activedescendant.
|
|
3231
|
+
/* @__PURE__ */ jsxs(
|
|
3232
|
+
"div",
|
|
3233
|
+
{
|
|
3234
|
+
id: optionDomId(index),
|
|
3235
|
+
role: "option",
|
|
3236
|
+
"aria-selected": isSelected,
|
|
3237
|
+
onPointerDown: (e) => e.preventDefault(),
|
|
3238
|
+
onClick: () => commit(channel),
|
|
3239
|
+
onMouseMove: () => setActiveIndex(index),
|
|
3240
|
+
className: cn(
|
|
3241
|
+
"flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm text-foreground",
|
|
3242
|
+
index === activeIndex && "bg-accent"
|
|
3243
|
+
),
|
|
3244
|
+
children: [
|
|
3245
|
+
/* @__PURE__ */ jsx(Check, { className: cn("h-3.5 w-3.5 shrink-0", isSelected ? "opacity-100" : "opacity-0") }),
|
|
3246
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: channelLabel(channel.name) })
|
|
3247
|
+
]
|
|
3248
|
+
},
|
|
3249
|
+
channel.id
|
|
3250
|
+
)
|
|
3251
|
+
);
|
|
3252
|
+
}) })
|
|
3253
|
+
}
|
|
3254
|
+
)
|
|
3255
|
+
] });
|
|
3256
|
+
}
|
|
3038
3257
|
function SlackBlockPreview({
|
|
3039
3258
|
block,
|
|
3040
3259
|
hooks,
|
|
@@ -3514,20 +3733,14 @@ function LoadMessageDialog({
|
|
|
3514
3733
|
channels === null && !channelsError && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Loading channels\u2026" }),
|
|
3515
3734
|
channelsError && /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive", children: channelsError }),
|
|
3516
3735
|
channels && channels.length === 0 && !channelsError && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "No public channels available." }),
|
|
3517
|
-
channels && channels.length > 0 && /* @__PURE__ */
|
|
3518
|
-
|
|
3736
|
+
channels && channels.length > 0 && /* @__PURE__ */ jsx(
|
|
3737
|
+
ChannelCombobox,
|
|
3519
3738
|
{
|
|
3520
3739
|
id: "recent-channel-picker",
|
|
3740
|
+
channels,
|
|
3521
3741
|
value: channelId,
|
|
3522
|
-
onChange:
|
|
3523
|
-
|
|
3524
|
-
children: [
|
|
3525
|
-
/* @__PURE__ */ jsx("option", { value: "", disabled: true, children: "Select a channel\u2026" }),
|
|
3526
|
-
channels.map((c) => /* @__PURE__ */ jsxs("option", { value: c.id, children: [
|
|
3527
|
-
"#",
|
|
3528
|
-
c.name
|
|
3529
|
-
] }, c.id))
|
|
3530
|
-
]
|
|
3742
|
+
onChange: setChannelId,
|
|
3743
|
+
placeholder: "Select a channel\u2026"
|
|
3531
3744
|
}
|
|
3532
3745
|
)
|
|
3533
3746
|
] }),
|
|
@@ -3721,7 +3934,7 @@ function PreviewPane({
|
|
|
3721
3934
|
return /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 shrink-0 flex-col gap-2 lg:min-h-0 lg:flex-1", children: [
|
|
3722
3935
|
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 flex-wrap items-center gap-2", children: [
|
|
3723
3936
|
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium uppercase tracking-wide text-muted-foreground", children: "Preview" }),
|
|
3724
|
-
target?.channelName || target?.channelId ? /* @__PURE__ */ jsx("span", { className: "rounded border px-1.5 py-px text-[10px] font-medium text-muted-foreground", children: target.channelName ?
|
|
3937
|
+
target?.channelName || target?.channelId ? /* @__PURE__ */ jsx("span", { className: "rounded border px-1.5 py-px text-[10px] font-medium text-muted-foreground", children: target.channelName ? channelLabel(target.channelName) : target.channelId }) : null,
|
|
3725
3938
|
target?.editableVia ? /* @__PURE__ */ jsxs("span", { className: "rounded border px-1.5 py-px text-[10px] font-medium uppercase tracking-wide text-muted-foreground", children: [
|
|
3726
3939
|
"Editable as ",
|
|
3727
3940
|
editableLabel(target.editableVia)
|
|
@@ -4177,19 +4390,7 @@ function SendDialog({
|
|
|
4177
4390
|
channels === null && !channelsError && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Loading channels\u2026" }),
|
|
4178
4391
|
channelsError && /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive", children: channelsError }),
|
|
4179
4392
|
channels && channels.length === 0 && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "No public channels available." }),
|
|
4180
|
-
channels && channels.length > 0 && /* @__PURE__ */ jsx(
|
|
4181
|
-
"select",
|
|
4182
|
-
{
|
|
4183
|
-
id: "channel-picker",
|
|
4184
|
-
value: channelId,
|
|
4185
|
-
onChange: (e) => setChannelId(e.target.value),
|
|
4186
|
-
className: "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",
|
|
4187
|
-
children: channels.map((c) => /* @__PURE__ */ jsxs("option", { value: c.id, children: [
|
|
4188
|
-
"#",
|
|
4189
|
-
c.name
|
|
4190
|
-
] }, c.id))
|
|
4191
|
-
}
|
|
4192
|
-
)
|
|
4393
|
+
channels && channels.length > 0 && /* @__PURE__ */ jsx(ChannelCombobox, { id: "channel-picker", channels, value: channelId, onChange: setChannelId })
|
|
4193
4394
|
] }),
|
|
4194
4395
|
renderSendExtras ? /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1.5", children: renderSendExtras({
|
|
4195
4396
|
channelId: channelId || null,
|
|
@@ -4232,24 +4433,6 @@ function SendDialog({
|
|
|
4232
4433
|
] })
|
|
4233
4434
|
] }) });
|
|
4234
4435
|
}
|
|
4235
|
-
var Popover = PopoverPrimitive.Root;
|
|
4236
|
-
var PopoverTrigger = PopoverPrimitive.Trigger;
|
|
4237
|
-
var PopoverContent = React.forwardRef(({ className, align = "start", sideOffset = 8, collisionPadding = 16, ...props }, ref) => /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
4238
|
-
PopoverPrimitive.Content,
|
|
4239
|
-
{
|
|
4240
|
-
ref,
|
|
4241
|
-
align,
|
|
4242
|
-
sideOffset,
|
|
4243
|
-
collisionPadding,
|
|
4244
|
-
className: cn(
|
|
4245
|
-
"bk-portal-content z-50 max-h-[var(--radix-popover-content-available-height)] w-80 overflow-y-auto rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none",
|
|
4246
|
-
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
4247
|
-
className
|
|
4248
|
-
),
|
|
4249
|
-
...props
|
|
4250
|
-
}
|
|
4251
|
-
) }));
|
|
4252
|
-
PopoverContent.displayName = PopoverPrimitive.Content.displayName;
|
|
4253
4436
|
var RadioGroup = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(RadioGroupPrimitive.Root, { className: cn("grid gap-2", className), ...props, ref }));
|
|
4254
4437
|
RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
|
|
4255
4438
|
var RadioGroupItem = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
@@ -6082,12 +6265,44 @@ function HeaderEditor({ block, onChange }) {
|
|
|
6082
6265
|
] });
|
|
6083
6266
|
}
|
|
6084
6267
|
function ImageEditor({ block, onChange }) {
|
|
6085
|
-
|
|
6086
|
-
return /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "This image references a Slack file. Not editable in the visual builder." });
|
|
6087
|
-
}
|
|
6268
|
+
const source = "slack_file" in block ? "slack_file" : "url";
|
|
6088
6269
|
const titleText = block.title?.text ?? "";
|
|
6270
|
+
const setSource = (next) => {
|
|
6271
|
+
if (next === source) {
|
|
6272
|
+
return;
|
|
6273
|
+
}
|
|
6274
|
+
if (next === "url") {
|
|
6275
|
+
const { slack_file: _omit, ...rest } = block;
|
|
6276
|
+
onChange({ image_url: "", ...rest });
|
|
6277
|
+
} else {
|
|
6278
|
+
const { image_url: _omit, ...rest } = block;
|
|
6279
|
+
onChange({ slack_file: { id: "" }, ...rest });
|
|
6280
|
+
}
|
|
6281
|
+
};
|
|
6089
6282
|
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
6090
|
-
/* @__PURE__ */ jsx(
|
|
6283
|
+
/* @__PURE__ */ jsx(
|
|
6284
|
+
EditorField,
|
|
6285
|
+
{
|
|
6286
|
+
label: "Image source",
|
|
6287
|
+
help: "Where the image comes from: a public URL, or a file already uploaded to your Slack workspace.",
|
|
6288
|
+
children: /* @__PURE__ */ jsx(
|
|
6289
|
+
RadioGroup,
|
|
6290
|
+
{
|
|
6291
|
+
value: source,
|
|
6292
|
+
onValueChange: (v) => setSource(v),
|
|
6293
|
+
className: "flex flex-row flex-wrap gap-3",
|
|
6294
|
+
children: [
|
|
6295
|
+
["url", "Public URL"],
|
|
6296
|
+
["slack_file", "Slack file"]
|
|
6297
|
+
].map(([value, label]) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
6298
|
+
/* @__PURE__ */ jsx(RadioGroupItem, { value, id: `img-source-${value}` }),
|
|
6299
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: `img-source-${value}`, className: "text-xs", children: label })
|
|
6300
|
+
] }, value))
|
|
6301
|
+
}
|
|
6302
|
+
)
|
|
6303
|
+
}
|
|
6304
|
+
),
|
|
6305
|
+
"slack_file" in block ? /* @__PURE__ */ jsx(SlackFileFields, { block, onChange }) : /* @__PURE__ */ jsx(EditorField, { label: "Image URL", help: "A publicly accessible image URL (PNG, JPG, GIF).", htmlFor: "img-url", children: /* @__PURE__ */ jsx(
|
|
6091
6306
|
Input,
|
|
6092
6307
|
{
|
|
6093
6308
|
id: "img-url",
|
|
@@ -6131,6 +6346,51 @@ function ImageEditor({ block, onChange }) {
|
|
|
6131
6346
|
) })
|
|
6132
6347
|
] });
|
|
6133
6348
|
}
|
|
6349
|
+
function SlackFileFields({
|
|
6350
|
+
block,
|
|
6351
|
+
onChange
|
|
6352
|
+
}) {
|
|
6353
|
+
const fileId = "id" in block.slack_file ? block.slack_file.id : "";
|
|
6354
|
+
const fileUrl = "url" in block.slack_file ? block.slack_file.url : "";
|
|
6355
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6356
|
+
/* @__PURE__ */ jsx("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "References a file already uploaded to your Slack workspace. The preview can't render workspace files \u2014 switch the source to Public URL to see the image here." }),
|
|
6357
|
+
/* @__PURE__ */ jsx(
|
|
6358
|
+
EditorField,
|
|
6359
|
+
{
|
|
6360
|
+
label: "File ID",
|
|
6361
|
+
help: "The Slack file's ID. Slack accepts an ID or a URL, not both, so filling this clears File URL.",
|
|
6362
|
+
htmlFor: "img-file-id",
|
|
6363
|
+
children: /* @__PURE__ */ jsx(
|
|
6364
|
+
Input,
|
|
6365
|
+
{
|
|
6366
|
+
id: "img-file-id",
|
|
6367
|
+
value: fileId,
|
|
6368
|
+
placeholder: "e.g. F0123456789",
|
|
6369
|
+
onChange: (e) => onChange({ ...block, slack_file: { id: e.target.value } })
|
|
6370
|
+
}
|
|
6371
|
+
)
|
|
6372
|
+
}
|
|
6373
|
+
),
|
|
6374
|
+
/* @__PURE__ */ jsx(
|
|
6375
|
+
EditorField,
|
|
6376
|
+
{
|
|
6377
|
+
label: "File URL",
|
|
6378
|
+
help: "The file's Slack-hosted URL. Filling this clears File ID.",
|
|
6379
|
+
htmlFor: "img-file-url",
|
|
6380
|
+
children: /* @__PURE__ */ jsx(
|
|
6381
|
+
Input,
|
|
6382
|
+
{
|
|
6383
|
+
id: "img-file-url",
|
|
6384
|
+
type: "url",
|
|
6385
|
+
value: fileUrl,
|
|
6386
|
+
placeholder: "e.g. https://files.slack.com/files-pri/T0123-F0123/image.png",
|
|
6387
|
+
onChange: (e) => onChange({ ...block, slack_file: { url: e.target.value } })
|
|
6388
|
+
}
|
|
6389
|
+
)
|
|
6390
|
+
}
|
|
6391
|
+
)
|
|
6392
|
+
] });
|
|
6393
|
+
}
|
|
6134
6394
|
function InputEditor({ block, onChange }) {
|
|
6135
6395
|
const updateElement = (next) => {
|
|
6136
6396
|
onChange({ ...block, element: next });
|
|
@@ -7438,7 +7698,7 @@ function EmojiNodeView({ node }) {
|
|
|
7438
7698
|
}
|
|
7439
7699
|
) : /* @__PURE__ */ jsx("span", { "aria-label": label, role: "img", children: unicode ? codepointsToGlyph(unicode) : label }) });
|
|
7440
7700
|
}
|
|
7441
|
-
var EmojiNode = Node.create({
|
|
7701
|
+
var EmojiNode = Node$1.create({
|
|
7442
7702
|
name: "emoji",
|
|
7443
7703
|
group: "inline",
|
|
7444
7704
|
inline: true,
|
|
@@ -10371,7 +10631,7 @@ function UpdateDialog({
|
|
|
10371
10631
|
setStatus({ kind: "error", error: e instanceof Error ? e.message : "Update failed." });
|
|
10372
10632
|
}
|
|
10373
10633
|
};
|
|
10374
|
-
const
|
|
10634
|
+
const channelText = target.channelName ? channelLabel(target.channelName) : target.channelId;
|
|
10375
10635
|
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(DialogContent, { className: "w-[calc(100vw-1.5rem)] max-w-lg rounded-lg", children: [
|
|
10376
10636
|
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
10377
10637
|
/* @__PURE__ */ jsx(DialogTitle, { children: "Update message" }),
|
|
@@ -10380,7 +10640,7 @@ function UpdateDialog({
|
|
|
10380
10640
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
10381
10641
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
10382
10642
|
/* @__PURE__ */ jsx(Label, { children: "Channel" }),
|
|
10383
|
-
/* @__PURE__ */ jsx("p", { className: "flex h-9 items-center rounded-md border border-input bg-muted px-3 text-sm text-muted-foreground", children:
|
|
10643
|
+
/* @__PURE__ */ jsx("p", { className: "flex h-9 items-center rounded-md border border-input bg-muted px-3 text-sm text-muted-foreground", children: channelText })
|
|
10384
10644
|
] }),
|
|
10385
10645
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
10386
10646
|
/* @__PURE__ */ jsx(Label, { children: "Posting as" }),
|
|
@@ -10746,7 +11006,7 @@ function BlockKitchen(props) {
|
|
|
10746
11006
|
loadEnabled,
|
|
10747
11007
|
updateEnabled: Boolean(onUpdate),
|
|
10748
11008
|
editBadge: activeEditTarget ? {
|
|
10749
|
-
channelLabel: activeEditTarget.channelName ?
|
|
11009
|
+
channelLabel: activeEditTarget.channelName ? channelLabel(activeEditTarget.channelName) : activeEditTarget.channelId,
|
|
10750
11010
|
ts: activeEditTarget.ts
|
|
10751
11011
|
} : null,
|
|
10752
11012
|
onOpenLoad: () => setLoadOpen(true),
|