@tightknitai/block-kitchen 0.9.8 → 0.9.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/README.md +176 -5
- package/dist/helpers.d.cts +2 -2
- package/dist/helpers.d.ts +2 -2
- package/dist/index.cjs +190 -58
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +83 -3
- package/dist/index.d.ts +83 -3
- package/dist/index.js +190 -61
- package/dist/index.js.map +1 -1
- package/dist/{palette-CKP8CK5Z.d.cts → palette-Duj901T6.d.cts} +188 -27
- package/dist/{palette-CKP8CK5Z.d.ts → palette-Duj901T6.d.ts} +188 -27
- package/dist/palette.d.cts +1 -1
- package/dist/palette.d.ts +1 -1
- package/dist/styles.css +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
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, GripVertical, Sun, Moon, MessageSquare, AppWindow, Home, MailSearch, Plus, ChevronDown, BookOpen,
|
|
3
|
+
import { X, Circle, Sparkles, FileText, AlignLeft, MousePointerClick, TextCursorInput, LayoutTemplate, Bell, Pilcrow, Image, Video, GalleryHorizontal, Table, ChartColumnBig, Container, Loader2, ExternalLink, AlertTriangle, GripVertical, Sun, Moon, MessageSquare, AppWindow, Home, MailSearch, Plus, ChevronDown, BookOpen, Trash2, Code2, Pencil, Send, Search, Check, Copy, Info, CheckCircle2, ChevronRight, LayoutGrid, ArrowUp, ArrowDown, Type, Bold, Italic, Strikethrough, Underline, Code, List, ListOrdered, Quote, Undo2, Redo2, Smile, Link as Link$1 } from 'lucide-react';
|
|
4
4
|
import * as React from 'react';
|
|
5
|
-
import { createContext,
|
|
5
|
+
import { createContext, useState, useRef, useEffect, useCallback, useMemo, useId, useContext } from 'react';
|
|
6
6
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
7
7
|
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
8
8
|
import { clsx } from 'clsx';
|
|
@@ -2015,6 +2015,7 @@ function computeValidation(blocks, surface) {
|
|
|
2015
2015
|
const grouped = groupValidatorErrors(result.errors, blocks);
|
|
2016
2016
|
return {
|
|
2017
2017
|
valid: result.valid,
|
|
2018
|
+
errors: result.errors,
|
|
2018
2019
|
byBlockId: grouped.byBlockId,
|
|
2019
2020
|
general: grouped.general,
|
|
2020
2021
|
total: grouped.total
|
|
@@ -2610,6 +2611,38 @@ function unwrapBlocksInput(parsed) {
|
|
|
2610
2611
|
}
|
|
2611
2612
|
return null;
|
|
2612
2613
|
}
|
|
2614
|
+
var buttonVariants = cva(
|
|
2615
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium cursor-pointer transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
2616
|
+
{
|
|
2617
|
+
variants: {
|
|
2618
|
+
variant: {
|
|
2619
|
+
default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
|
|
2620
|
+
destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
|
|
2621
|
+
outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
|
|
2622
|
+
secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
|
|
2623
|
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
2624
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
2625
|
+
},
|
|
2626
|
+
size: {
|
|
2627
|
+
default: "h-9 px-4 py-2",
|
|
2628
|
+
sm: "h-8 rounded-md px-3 text-xs",
|
|
2629
|
+
lg: "h-10 rounded-md px-8",
|
|
2630
|
+
icon: "h-9 w-9"
|
|
2631
|
+
}
|
|
2632
|
+
},
|
|
2633
|
+
defaultVariants: {
|
|
2634
|
+
variant: "default",
|
|
2635
|
+
size: "default"
|
|
2636
|
+
}
|
|
2637
|
+
}
|
|
2638
|
+
);
|
|
2639
|
+
var Button = React.forwardRef(
|
|
2640
|
+
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
2641
|
+
const Comp = asChild ? Slot : "button";
|
|
2642
|
+
return /* @__PURE__ */ jsx(Comp, { className: cn(buttonVariants({ variant, size, className })), ref, ...props });
|
|
2643
|
+
}
|
|
2644
|
+
);
|
|
2645
|
+
Button.displayName = "Button";
|
|
2613
2646
|
var MAX_JSON_BYTES = 1024 * 1024;
|
|
2614
2647
|
function JsonDrawer({
|
|
2615
2648
|
open,
|
|
@@ -2621,19 +2654,23 @@ function JsonDrawer({
|
|
|
2621
2654
|
const [parseError, setParseError] = useState(null);
|
|
2622
2655
|
const [validationErrors, setValidationErrors] = useState([]);
|
|
2623
2656
|
const [copied, setCopied] = useState(false);
|
|
2657
|
+
const [accepted, setAccepted] = useState(false);
|
|
2624
2658
|
const textareaRef = useRef(null);
|
|
2625
2659
|
const gutterRef = useRef(null);
|
|
2626
2660
|
const copyResetRef = useRef(null);
|
|
2661
|
+
const acceptResetRef = useRef(null);
|
|
2627
2662
|
const blocksRef = useRef(blocks);
|
|
2628
2663
|
useEffect(() => {
|
|
2629
2664
|
blocksRef.current = blocks;
|
|
2630
2665
|
});
|
|
2631
2666
|
useEffect(() => {
|
|
2632
2667
|
if (open) {
|
|
2633
|
-
|
|
2668
|
+
const current = blocksRef.current;
|
|
2669
|
+
setValue(current.length === 0 ? "" : JSON.stringify(current, null, 2));
|
|
2634
2670
|
setParseError(null);
|
|
2635
2671
|
setValidationErrors([]);
|
|
2636
2672
|
setCopied(false);
|
|
2673
|
+
setAccepted(false);
|
|
2637
2674
|
}
|
|
2638
2675
|
}, [open]);
|
|
2639
2676
|
useEffect(
|
|
@@ -2641,6 +2678,9 @@ function JsonDrawer({
|
|
|
2641
2678
|
if (copyResetRef.current) {
|
|
2642
2679
|
clearTimeout(copyResetRef.current);
|
|
2643
2680
|
}
|
|
2681
|
+
if (acceptResetRef.current) {
|
|
2682
|
+
clearTimeout(acceptResetRef.current);
|
|
2683
|
+
}
|
|
2644
2684
|
},
|
|
2645
2685
|
[]
|
|
2646
2686
|
);
|
|
@@ -2661,6 +2701,17 @@ function JsonDrawer({
|
|
|
2661
2701
|
setValidationErrors([]);
|
|
2662
2702
|
return;
|
|
2663
2703
|
}
|
|
2704
|
+
if (next.trim() === "") {
|
|
2705
|
+
setParseError(null);
|
|
2706
|
+
setValidationErrors([]);
|
|
2707
|
+
onApply([]);
|
|
2708
|
+
setAccepted(true);
|
|
2709
|
+
if (acceptResetRef.current) {
|
|
2710
|
+
clearTimeout(acceptResetRef.current);
|
|
2711
|
+
}
|
|
2712
|
+
acceptResetRef.current = setTimeout(() => setAccepted(false), 1800);
|
|
2713
|
+
return;
|
|
2714
|
+
}
|
|
2664
2715
|
let parsed;
|
|
2665
2716
|
try {
|
|
2666
2717
|
parsed = JSON.parse(next);
|
|
@@ -2677,6 +2728,11 @@ function JsonDrawer({
|
|
|
2677
2728
|
}
|
|
2678
2729
|
setParseError(null);
|
|
2679
2730
|
onApply(blocks2);
|
|
2731
|
+
setAccepted(true);
|
|
2732
|
+
if (acceptResetRef.current) {
|
|
2733
|
+
clearTimeout(acceptResetRef.current);
|
|
2734
|
+
}
|
|
2735
|
+
acceptResetRef.current = setTimeout(() => setAccepted(false), 1800);
|
|
2680
2736
|
const result = validateBlockKit(blocks2, {
|
|
2681
2737
|
target: "blocks",
|
|
2682
2738
|
surface: "message"
|
|
@@ -2701,16 +2757,30 @@ function JsonDrawer({
|
|
|
2701
2757
|
/* @__PURE__ */ jsx(SheetDescription, { children: "Edits update the preview as you type. Parse errors show below." })
|
|
2702
2758
|
] }),
|
|
2703
2759
|
/* @__PURE__ */ jsxs("div", { className: "relative flex flex-1 overflow-hidden rounded-md border border-input bg-muted/30 shadow-sm focus-within:ring-1 focus-within:ring-ring", children: [
|
|
2704
|
-
/* @__PURE__ */
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2760
|
+
/* @__PURE__ */ jsxs("div", { className: "absolute right-2 top-2 z-10 flex items-center gap-1.5", children: [
|
|
2761
|
+
/* @__PURE__ */ jsxs(
|
|
2762
|
+
"div",
|
|
2763
|
+
{
|
|
2764
|
+
role: "status",
|
|
2765
|
+
"aria-hidden": !accepted,
|
|
2766
|
+
className: `pointer-events-none flex items-center justify-center rounded-md bg-background/80 p-1.5 shadow-sm backdrop-blur transition-opacity duration-300 ${accepted ? "opacity-100" : "opacity-0"}`,
|
|
2767
|
+
children: [
|
|
2768
|
+
/* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5 text-emerald-600" }),
|
|
2769
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "Input accepted" })
|
|
2770
|
+
]
|
|
2771
|
+
}
|
|
2772
|
+
),
|
|
2773
|
+
/* @__PURE__ */ jsx(
|
|
2774
|
+
"button",
|
|
2775
|
+
{
|
|
2776
|
+
type: "button",
|
|
2777
|
+
onClick: handleCopy,
|
|
2778
|
+
"aria-label": copied ? "Copied to clipboard" : "Copy JSON",
|
|
2779
|
+
className: "inline-flex items-center justify-center rounded-md border border-input bg-background/80 p-1.5 text-muted-foreground shadow-sm backdrop-blur transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
2780
|
+
children: copied ? /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5 text-emerald-600" }) : /* @__PURE__ */ jsx(Copy, { className: "h-3.5 w-3.5" })
|
|
2781
|
+
}
|
|
2782
|
+
)
|
|
2783
|
+
] }),
|
|
2714
2784
|
/* @__PURE__ */ jsx(
|
|
2715
2785
|
"div",
|
|
2716
2786
|
{
|
|
@@ -2747,41 +2817,10 @@ function JsonDrawer({
|
|
|
2747
2817
|
" more"
|
|
2748
2818
|
] })
|
|
2749
2819
|
] })
|
|
2750
|
-
] })
|
|
2820
|
+
] }),
|
|
2821
|
+
/* @__PURE__ */ jsx("div", { className: "flex shrink-0 justify-end", children: /* @__PURE__ */ jsx(Button, { type: "button", onClick: () => onOpenChange(false), children: "Done" }) })
|
|
2751
2822
|
] }) });
|
|
2752
2823
|
}
|
|
2753
|
-
var buttonVariants = cva(
|
|
2754
|
-
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium cursor-pointer transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
2755
|
-
{
|
|
2756
|
-
variants: {
|
|
2757
|
-
variant: {
|
|
2758
|
-
default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
|
|
2759
|
-
destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
|
|
2760
|
-
outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
|
|
2761
|
-
secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
|
|
2762
|
-
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
2763
|
-
link: "text-primary underline-offset-4 hover:underline"
|
|
2764
|
-
},
|
|
2765
|
-
size: {
|
|
2766
|
-
default: "h-9 px-4 py-2",
|
|
2767
|
-
sm: "h-8 rounded-md px-3 text-xs",
|
|
2768
|
-
lg: "h-10 rounded-md px-8",
|
|
2769
|
-
icon: "h-9 w-9"
|
|
2770
|
-
}
|
|
2771
|
-
},
|
|
2772
|
-
defaultVariants: {
|
|
2773
|
-
variant: "default",
|
|
2774
|
-
size: "default"
|
|
2775
|
-
}
|
|
2776
|
-
}
|
|
2777
|
-
);
|
|
2778
|
-
var Button = React.forwardRef(
|
|
2779
|
-
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
2780
|
-
const Comp = asChild ? Slot : "button";
|
|
2781
|
-
return /* @__PURE__ */ jsx(Comp, { className: cn(buttonVariants({ variant, size, className })), ref, ...props });
|
|
2782
|
-
}
|
|
2783
|
-
);
|
|
2784
|
-
Button.displayName = "Button";
|
|
2785
2824
|
var Dialog = DialogPrimitive.Root;
|
|
2786
2825
|
var DialogPortal = DialogPrimitive.Portal;
|
|
2787
2826
|
var DialogOverlay = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
@@ -3494,6 +3533,7 @@ function SendDialog({
|
|
|
3494
3533
|
loadChannels,
|
|
3495
3534
|
loadSendAsUserStatus,
|
|
3496
3535
|
onSend,
|
|
3536
|
+
renderSendExtras,
|
|
3497
3537
|
confirmSendLabel = "Send",
|
|
3498
3538
|
errorCount,
|
|
3499
3539
|
onShowIssues
|
|
@@ -3503,6 +3543,10 @@ function SendDialog({
|
|
|
3503
3543
|
const [channelId, setChannelId] = useState("");
|
|
3504
3544
|
const [sendAs, setSendAs] = useState("bot");
|
|
3505
3545
|
const [status, setStatus] = useState({ kind: "idle" });
|
|
3546
|
+
const [extras, setExtrasState] = useState({});
|
|
3547
|
+
const setExtras = useCallback((patch) => {
|
|
3548
|
+
setExtrasState((prev) => ({ ...prev, ...patch }));
|
|
3549
|
+
}, []);
|
|
3506
3550
|
const { userStatus, polling, startSignIn } = useSlackSignIn(loadSendAsUserStatus, { open, enabled: true });
|
|
3507
3551
|
const loadChannelsRef = useRef(loadChannels);
|
|
3508
3552
|
useEffect(() => {
|
|
@@ -3517,6 +3561,7 @@ function SendDialog({
|
|
|
3517
3561
|
setChannelsError(null);
|
|
3518
3562
|
setChannelId("");
|
|
3519
3563
|
setSendAs("bot");
|
|
3564
|
+
setExtrasState({});
|
|
3520
3565
|
let cancelled = false;
|
|
3521
3566
|
loadChannelsRef.current().then((list) => {
|
|
3522
3567
|
if (cancelled) {
|
|
@@ -3544,7 +3589,10 @@ function SendDialog({
|
|
|
3544
3589
|
const result = await onSend({
|
|
3545
3590
|
channelId,
|
|
3546
3591
|
blocks: toSlackBlocks(blocks),
|
|
3547
|
-
sendAsUser: sendAs === "user"
|
|
3592
|
+
sendAsUser: sendAs === "user",
|
|
3593
|
+
// Only introduce the key when the extras slot is wired, so existing
|
|
3594
|
+
// consumers never see a new payload field.
|
|
3595
|
+
...renderSendExtras ? { extras } : {}
|
|
3548
3596
|
});
|
|
3549
3597
|
if (result.ok) {
|
|
3550
3598
|
setStatus({ kind: "idle" });
|
|
@@ -3611,6 +3659,12 @@ function SendDialog({
|
|
|
3611
3659
|
}
|
|
3612
3660
|
)
|
|
3613
3661
|
] }),
|
|
3662
|
+
renderSendExtras ? /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1.5", children: renderSendExtras({
|
|
3663
|
+
channelId: channelId || null,
|
|
3664
|
+
sendAsUser: sendAs === "user",
|
|
3665
|
+
extras,
|
|
3666
|
+
setExtras
|
|
3667
|
+
}) }) : null,
|
|
3614
3668
|
errorCount > 0 ? /* @__PURE__ */ jsxs(
|
|
3615
3669
|
"button",
|
|
3616
3670
|
{
|
|
@@ -9357,6 +9411,8 @@ function Toolbar2({
|
|
|
9357
9411
|
showThemeControl = true,
|
|
9358
9412
|
docsLink,
|
|
9359
9413
|
errorCount,
|
|
9414
|
+
showSend = true,
|
|
9415
|
+
primaryAction,
|
|
9360
9416
|
sendButtonLabel = "Review & send",
|
|
9361
9417
|
editingEnabled = false,
|
|
9362
9418
|
editBadge,
|
|
@@ -9491,7 +9547,24 @@ function Toolbar2({
|
|
|
9491
9547
|
/* @__PURE__ */ jsx(Code2, { className: "h-3.5 w-3.5" }),
|
|
9492
9548
|
/* @__PURE__ */ jsx("span", { className: "hidden md:inline", children: "View JSON" })
|
|
9493
9549
|
] }),
|
|
9494
|
-
|
|
9550
|
+
!showSend ? primaryAction ? (
|
|
9551
|
+
// Compose-only mode with a host-owned primary action: same
|
|
9552
|
+
// placement and styling as the built-in send button. No icon —
|
|
9553
|
+
// the action's meaning is the host's, so the label always shows
|
|
9554
|
+
// (the send button can collapse to its icon on small screens;
|
|
9555
|
+
// an icon-less button can't).
|
|
9556
|
+
/* @__PURE__ */ jsx(
|
|
9557
|
+
Button,
|
|
9558
|
+
{
|
|
9559
|
+
type: "button",
|
|
9560
|
+
size: "sm",
|
|
9561
|
+
onClick: primaryAction.onClick,
|
|
9562
|
+
disabled: primaryAction.disabled,
|
|
9563
|
+
"aria-label": primaryAction.label,
|
|
9564
|
+
children: /* @__PURE__ */ jsx("span", { children: primaryAction.label })
|
|
9565
|
+
}
|
|
9566
|
+
)
|
|
9567
|
+
) : null : editBadge ? (
|
|
9495
9568
|
// A message is loaded: split button. Main action updates it in
|
|
9496
9569
|
// place; the menu also offers posting the blocks as a new message.
|
|
9497
9570
|
/* @__PURE__ */ jsxs("div", { className: "flex items-stretch", children: [
|
|
@@ -9734,12 +9807,15 @@ function BlockKitchen(props) {
|
|
|
9734
9807
|
workspaceName,
|
|
9735
9808
|
initialBlocks,
|
|
9736
9809
|
onChange,
|
|
9810
|
+
onValidationChange,
|
|
9737
9811
|
previewHooks,
|
|
9738
9812
|
customEmojis,
|
|
9739
9813
|
loadChannels,
|
|
9740
9814
|
loadSendAsUserStatus,
|
|
9741
9815
|
onSend,
|
|
9816
|
+
renderSendExtras,
|
|
9742
9817
|
editing,
|
|
9818
|
+
primaryAction,
|
|
9743
9819
|
loadButtonLabel,
|
|
9744
9820
|
updateButtonLabel,
|
|
9745
9821
|
confirmUpdateLabel,
|
|
@@ -9756,6 +9832,13 @@ function BlockKitchen(props) {
|
|
|
9756
9832
|
sendButtonLabel,
|
|
9757
9833
|
confirmSendLabel,
|
|
9758
9834
|
theme
|
|
9835
|
+
// Widen the all-or-nothing union so the branch-specific props
|
|
9836
|
+
// destructure as independent optionals: untyped JS consumers can still
|
|
9837
|
+
// pass partial wiring (handled by the runtime guards below), and the
|
|
9838
|
+
// correlated-union narrowing would otherwise flag those guards as
|
|
9839
|
+
// "always true". `primaryAction` is pulled from the compose-only branch
|
|
9840
|
+
// (where it carries a real type) rather than the send branch's
|
|
9841
|
+
// `undefined` pin, which would collapse the intersection to `undefined`.
|
|
9759
9842
|
} = props;
|
|
9760
9843
|
const paletteSections = useMemo(() => {
|
|
9761
9844
|
const sections = palette ?? defaultPalette;
|
|
@@ -9774,13 +9857,36 @@ function BlockKitchen(props) {
|
|
|
9774
9857
|
}, [palette, disabledBlockTypes]);
|
|
9775
9858
|
const variantById = useMemo(() => buildVariantById(paletteSections), [paletteSections]);
|
|
9776
9859
|
const allowedSurfaces = allowedSurfacesProp && allowedSurfacesProp.length > 0 ? allowedSurfacesProp : ["message"];
|
|
9777
|
-
const
|
|
9860
|
+
const sendEnabled = Boolean(loadChannels && loadSendAsUserStatus && onSend);
|
|
9861
|
+
const editingConfig = sendEnabled ? editing : void 0;
|
|
9862
|
+
const seededBlocks = editingConfig?.initialTarget?.blocks ?? initialBlocks;
|
|
9778
9863
|
useEffect(() => {
|
|
9779
|
-
if (
|
|
9864
|
+
if (editingConfig?.initialTarget && initialBlocks) {
|
|
9780
9865
|
console.warn(
|
|
9781
9866
|
"[BlockKitchen] Both `initialBlocks` and `editing.initialTarget` were provided; using the target\u2019s blocks and ignoring `initialBlocks`."
|
|
9782
9867
|
);
|
|
9783
9868
|
}
|
|
9869
|
+
const sendPropsProvided = [loadChannels, loadSendAsUserStatus, onSend].filter(Boolean).length;
|
|
9870
|
+
if (sendPropsProvided > 0 && sendPropsProvided < 3) {
|
|
9871
|
+
console.warn(
|
|
9872
|
+
"[BlockKitchen] Partial send wiring: `loadChannels`, `loadSendAsUserStatus`, and `onSend` are all-or-nothing. The send button is hidden until all three are provided."
|
|
9873
|
+
);
|
|
9874
|
+
}
|
|
9875
|
+
if (editing && !sendEnabled) {
|
|
9876
|
+
console.warn(
|
|
9877
|
+
"[BlockKitchen] `editing` requires the send integration (`loadChannels`, `loadSendAsUserStatus`, `onSend`); ignoring `editing`."
|
|
9878
|
+
);
|
|
9879
|
+
}
|
|
9880
|
+
if (renderSendExtras && !sendEnabled) {
|
|
9881
|
+
console.warn(
|
|
9882
|
+
"[BlockKitchen] `renderSendExtras` extends the built-in send dialog, which requires the send integration (`loadChannels`, `loadSendAsUserStatus`, `onSend`); ignoring `renderSendExtras`."
|
|
9883
|
+
);
|
|
9884
|
+
}
|
|
9885
|
+
if (primaryAction && sendEnabled) {
|
|
9886
|
+
console.warn(
|
|
9887
|
+
"[BlockKitchen] `primaryAction` is only available in compose-only mode \u2014 with the send integration wired, the built-in Send/Update flow owns the toolbar\u2019s primary action; ignoring `primaryAction`."
|
|
9888
|
+
);
|
|
9889
|
+
}
|
|
9784
9890
|
}, []);
|
|
9785
9891
|
const { blocks, addBlock, addChild, updateBlock, removeBlock, duplicateBlock, reorderBlock, moveBlock, replaceAll } = useBlockKitchenState({ initialBlocks: seededBlocks, onChange });
|
|
9786
9892
|
const childParentById = useMemo(() => {
|
|
@@ -9798,8 +9904,8 @@ function BlockKitchen(props) {
|
|
|
9798
9904
|
const [sendOpen, setSendOpen] = useState(false);
|
|
9799
9905
|
const [updateOpen, setUpdateOpen] = useState(false);
|
|
9800
9906
|
const [loadOpen, setLoadOpen] = useState(false);
|
|
9801
|
-
const [editTarget, setEditTarget] = useState(() =>
|
|
9802
|
-
const activeEditTarget =
|
|
9907
|
+
const [editTarget, setEditTarget] = useState(() => editingConfig?.initialTarget ?? null);
|
|
9908
|
+
const activeEditTarget = editingConfig ? editTarget : null;
|
|
9803
9909
|
const [issuesOpen, setIssuesOpen] = useState(false);
|
|
9804
9910
|
const [paletteOpen, setPaletteOpen] = useState(false);
|
|
9805
9911
|
const [openBlockId, setOpenBlockId] = useState(null);
|
|
@@ -9817,6 +9923,22 @@ function BlockKitchen(props) {
|
|
|
9817
9923
|
return { emoji: makeEmojiHook(byName), ...previewHooks };
|
|
9818
9924
|
}, [customEmojis, previewHooks]);
|
|
9819
9925
|
const validation = useBlockKitValidation(blocks, "message");
|
|
9926
|
+
const validationSummary = useMemo(
|
|
9927
|
+
() => ({ valid: validation.valid, errorCount: validation.total, errors: validation.errors }),
|
|
9928
|
+
[validation]
|
|
9929
|
+
);
|
|
9930
|
+
const lastNotifiedValidationRef = useRef(null);
|
|
9931
|
+
useEffect(() => {
|
|
9932
|
+
if (!onValidationChange) {
|
|
9933
|
+
return;
|
|
9934
|
+
}
|
|
9935
|
+
const key = JSON.stringify([validationSummary.valid, validationSummary.errorCount, ...validationSummary.errors]);
|
|
9936
|
+
if (lastNotifiedValidationRef.current === key) {
|
|
9937
|
+
return;
|
|
9938
|
+
}
|
|
9939
|
+
lastNotifiedValidationRef.current = key;
|
|
9940
|
+
onValidationChange(validationSummary);
|
|
9941
|
+
}, [validationSummary, onValidationChange]);
|
|
9820
9942
|
const sensors = useSensors(
|
|
9821
9943
|
useSensor(PointerSensor, { activationConstraint: { distance: 4 } }),
|
|
9822
9944
|
useSensor(TouchSensor, { activationConstraint: { delay: 150, tolerance: 8 } }),
|
|
@@ -9920,8 +10042,14 @@ function BlockKitchen(props) {
|
|
|
9920
10042
|
allowedSurfaces,
|
|
9921
10043
|
showThemeControl: isPreviewThemeControlled ? false : showThemeControl,
|
|
9922
10044
|
docsLink,
|
|
10045
|
+
showSend: sendEnabled,
|
|
10046
|
+
primaryAction: !sendEnabled && primaryAction ? {
|
|
10047
|
+
label: primaryAction.label,
|
|
10048
|
+
onClick: () => primaryAction.onClick({ blocks: blockPayloads, validation: validationSummary }),
|
|
10049
|
+
disabled: primaryAction.disableWhenInvalid ? !validationSummary.valid : false
|
|
10050
|
+
} : null,
|
|
9923
10051
|
sendButtonLabel,
|
|
9924
|
-
editingEnabled: !!
|
|
10052
|
+
editingEnabled: !!editingConfig,
|
|
9925
10053
|
editBadge: activeEditTarget ? {
|
|
9926
10054
|
channelLabel: activeEditTarget.channelName ? `#${activeEditTarget.channelName}` : activeEditTarget.channelId,
|
|
9927
10055
|
ts: activeEditTarget.ts
|
|
@@ -10003,7 +10131,7 @@ function BlockKitchen(props) {
|
|
|
10003
10131
|
}
|
|
10004
10132
|
) }),
|
|
10005
10133
|
/* @__PURE__ */ jsx(JsonDrawer, { open: jsonOpen, onOpenChange: setJsonOpen, blocks: blockPayloads, onApply: replaceAll }),
|
|
10006
|
-
/* @__PURE__ */ jsx(
|
|
10134
|
+
loadChannels && loadSendAsUserStatus && onSend ? /* @__PURE__ */ jsx(
|
|
10007
10135
|
SendDialog,
|
|
10008
10136
|
{
|
|
10009
10137
|
open: sendOpen,
|
|
@@ -10012,6 +10140,7 @@ function BlockKitchen(props) {
|
|
|
10012
10140
|
loadChannels,
|
|
10013
10141
|
loadSendAsUserStatus,
|
|
10014
10142
|
onSend,
|
|
10143
|
+
renderSendExtras,
|
|
10015
10144
|
confirmSendLabel,
|
|
10016
10145
|
errorCount: validation.total,
|
|
10017
10146
|
onShowIssues: () => {
|
|
@@ -10019,8 +10148,8 @@ function BlockKitchen(props) {
|
|
|
10019
10148
|
setIssuesOpen(true);
|
|
10020
10149
|
}
|
|
10021
10150
|
}
|
|
10022
|
-
),
|
|
10023
|
-
activeEditTarget &&
|
|
10151
|
+
) : null,
|
|
10152
|
+
activeEditTarget && editingConfig && loadSendAsUserStatus ? /* @__PURE__ */ jsx(
|
|
10024
10153
|
UpdateDialog,
|
|
10025
10154
|
{
|
|
10026
10155
|
open: updateOpen,
|
|
@@ -10028,7 +10157,7 @@ function BlockKitchen(props) {
|
|
|
10028
10157
|
target: activeEditTarget,
|
|
10029
10158
|
blocks: blockPayloads,
|
|
10030
10159
|
loadSendAsUserStatus,
|
|
10031
|
-
onUpdate:
|
|
10160
|
+
onUpdate: editingConfig.onUpdate,
|
|
10032
10161
|
confirmUpdateLabel,
|
|
10033
10162
|
errorCount: validation.total,
|
|
10034
10163
|
onShowIssues: () => {
|
|
@@ -10037,13 +10166,13 @@ function BlockKitchen(props) {
|
|
|
10037
10166
|
}
|
|
10038
10167
|
}
|
|
10039
10168
|
) : null,
|
|
10040
|
-
|
|
10169
|
+
editingConfig && loadChannels ? /* @__PURE__ */ jsx(
|
|
10041
10170
|
LoadMessageDialog,
|
|
10042
10171
|
{
|
|
10043
10172
|
open: loadOpen,
|
|
10044
10173
|
onOpenChange: setLoadOpen,
|
|
10045
|
-
onLoadMessage:
|
|
10046
|
-
loadRecentMessages:
|
|
10174
|
+
onLoadMessage: editingConfig.onLoadMessage,
|
|
10175
|
+
loadRecentMessages: editingConfig.loadRecentMessages,
|
|
10047
10176
|
loadChannels,
|
|
10048
10177
|
onLoaded: (result) => {
|
|
10049
10178
|
replaceAll(result.blocks);
|
|
@@ -10237,6 +10366,6 @@ function fromBase64Url(b64url) {
|
|
|
10237
10366
|
return b64 + "=".repeat(padLen);
|
|
10238
10367
|
}
|
|
10239
10368
|
|
|
10240
|
-
export { BlockKitchen, TemplatePicker, decodeBlocksFromString, defaultPalette, encodeBlocksToString, extraAlertVariant, legacyInputVariants, toSlackBlocks };
|
|
10369
|
+
export { BlockKitchen, SendDialog, SlackSignInButton, TemplatePicker, decodeBlocksFromString, defaultPalette, encodeBlocksToString, extraAlertVariant, legacyInputVariants, toSlackBlocks, useSlackSignIn };
|
|
10241
10370
|
//# sourceMappingURL=index.js.map
|
|
10242
10371
|
//# sourceMappingURL=index.js.map
|