@tightknitai/block-kitchen 0.6.1-alpha.0 → 0.8.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/README.md +122 -3
- package/dist/helpers.cjs +171 -0
- package/dist/helpers.cjs.map +1 -0
- package/dist/helpers.d.cts +38 -0
- package/dist/helpers.d.ts +38 -0
- package/dist/helpers.js +167 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.cjs +1374 -422
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -610
- package/dist/index.d.ts +6 -610
- package/dist/index.js +1312 -360
- package/dist/index.js.map +1 -1
- package/dist/palette-CTUROcUC.d.cts +674 -0
- package/dist/palette-CTUROcUC.d.ts +674 -0
- package/dist/palette.cjs +1386 -0
- package/dist/palette.cjs.map +1 -0
- package/dist/palette.d.cts +3 -0
- package/dist/palette.d.ts +3 -0
- package/dist/palette.js +1381 -0
- package/dist/palette.js.map +1 -0
- package/dist/styles.css +1 -1
- package/package.json +26 -9
package/dist/index.cjs
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var core = require('@dnd-kit/core');
|
|
4
|
+
var sortable = require('@dnd-kit/sortable');
|
|
4
5
|
var lucideReact = require('lucide-react');
|
|
5
|
-
var
|
|
6
|
-
var
|
|
6
|
+
var React = require('react');
|
|
7
|
+
var DialogPrimitive = require('@radix-ui/react-dialog');
|
|
7
8
|
var clsx = require('clsx');
|
|
8
9
|
var tailwindMerge = require('tailwind-merge');
|
|
9
10
|
var jsxRuntime = require('react/jsx-runtime');
|
|
11
|
+
var TooltipPrimitive = require('@radix-ui/react-tooltip');
|
|
10
12
|
var slackBlockKitValidator = require('@tightknitai/slack-block-kit-validator');
|
|
11
13
|
var nanoid = require('nanoid');
|
|
12
|
-
var DialogPrimitive = require('@radix-ui/react-dialog');
|
|
13
14
|
var reactSlot = require('@radix-ui/react-slot');
|
|
14
15
|
var classVarianceAuthority = require('class-variance-authority');
|
|
15
16
|
var LabelPrimitive = require('@radix-ui/react-label');
|
|
16
|
-
var sortable = require('@dnd-kit/sortable');
|
|
17
17
|
var utilities = require('@dnd-kit/utilities');
|
|
18
18
|
var PopoverPrimitive = require('@radix-ui/react-popover');
|
|
19
19
|
var RadioGroupPrimitive = require('@radix-ui/react-radio-group');
|
|
@@ -43,9 +43,9 @@ function _interopNamespace(e) {
|
|
|
43
43
|
return Object.freeze(n);
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
var
|
|
47
|
-
var TooltipPrimitive__namespace = /*#__PURE__*/_interopNamespace(TooltipPrimitive);
|
|
46
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
48
47
|
var DialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(DialogPrimitive);
|
|
48
|
+
var TooltipPrimitive__namespace = /*#__PURE__*/_interopNamespace(TooltipPrimitive);
|
|
49
49
|
var LabelPrimitive__namespace = /*#__PURE__*/_interopNamespace(LabelPrimitive);
|
|
50
50
|
var PopoverPrimitive__namespace = /*#__PURE__*/_interopNamespace(PopoverPrimitive);
|
|
51
51
|
var RadioGroupPrimitive__namespace = /*#__PURE__*/_interopNamespace(RadioGroupPrimitive);
|
|
@@ -105,6 +105,66 @@ var defaultPalette = [
|
|
|
105
105
|
}
|
|
106
106
|
]
|
|
107
107
|
})
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
id: "agents_plan",
|
|
111
|
+
label: "Plan",
|
|
112
|
+
factory: () => ({
|
|
113
|
+
type: "plan",
|
|
114
|
+
title: "Investigating the issue",
|
|
115
|
+
tasks: [
|
|
116
|
+
{
|
|
117
|
+
type: "task_card",
|
|
118
|
+
task_id: "task_1",
|
|
119
|
+
title: "Read the bug report",
|
|
120
|
+
status: "complete"
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
type: "task_card",
|
|
124
|
+
task_id: "task_2",
|
|
125
|
+
title: "Reproduce the error locally",
|
|
126
|
+
status: "in_progress"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
type: "task_card",
|
|
130
|
+
task_id: "task_3",
|
|
131
|
+
title: "Identify the root cause",
|
|
132
|
+
status: "pending"
|
|
133
|
+
}
|
|
134
|
+
]
|
|
135
|
+
})
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
id: "agents_task_card",
|
|
139
|
+
label: "Task card",
|
|
140
|
+
factory: () => ({
|
|
141
|
+
type: "task_card",
|
|
142
|
+
task_id: "task_1",
|
|
143
|
+
title: "Summarize the latest release notes",
|
|
144
|
+
status: "in_progress"
|
|
145
|
+
})
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
id: "agents_task_card_with_sources",
|
|
149
|
+
label: "Task card with sources",
|
|
150
|
+
factory: () => ({
|
|
151
|
+
type: "task_card",
|
|
152
|
+
task_id: "task_2",
|
|
153
|
+
title: "Cite supporting docs",
|
|
154
|
+
status: "complete",
|
|
155
|
+
sources: [
|
|
156
|
+
{
|
|
157
|
+
type: "url",
|
|
158
|
+
url: "https://example.com/runbook",
|
|
159
|
+
text: "Runbook"
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
type: "url",
|
|
163
|
+
url: "https://example.com/changelog",
|
|
164
|
+
text: "Changelog"
|
|
165
|
+
}
|
|
166
|
+
]
|
|
167
|
+
})
|
|
108
168
|
}
|
|
109
169
|
]
|
|
110
170
|
},
|
|
@@ -660,6 +720,71 @@ var defaultPalette = [
|
|
|
660
720
|
}
|
|
661
721
|
]
|
|
662
722
|
},
|
|
723
|
+
{
|
|
724
|
+
name: "Alert",
|
|
725
|
+
icon: lucideReact.Bell,
|
|
726
|
+
variants: [
|
|
727
|
+
{
|
|
728
|
+
id: "alert_default",
|
|
729
|
+
label: "Default",
|
|
730
|
+
factory: () => ({
|
|
731
|
+
type: "alert",
|
|
732
|
+
text: {
|
|
733
|
+
type: "mrkdwn",
|
|
734
|
+
text: "A neutral alert message."
|
|
735
|
+
}
|
|
736
|
+
})
|
|
737
|
+
},
|
|
738
|
+
{
|
|
739
|
+
id: "alert_info",
|
|
740
|
+
label: "Info",
|
|
741
|
+
factory: () => ({
|
|
742
|
+
type: "alert",
|
|
743
|
+
level: "info",
|
|
744
|
+
text: {
|
|
745
|
+
type: "mrkdwn",
|
|
746
|
+
text: "FYI: the build finished in 42 seconds."
|
|
747
|
+
}
|
|
748
|
+
})
|
|
749
|
+
},
|
|
750
|
+
{
|
|
751
|
+
id: "alert_warning",
|
|
752
|
+
label: "Warning",
|
|
753
|
+
factory: () => ({
|
|
754
|
+
type: "alert",
|
|
755
|
+
level: "warning",
|
|
756
|
+
text: {
|
|
757
|
+
type: "mrkdwn",
|
|
758
|
+
text: "Heads up: this action cannot be undone."
|
|
759
|
+
}
|
|
760
|
+
})
|
|
761
|
+
},
|
|
762
|
+
{
|
|
763
|
+
id: "alert_error",
|
|
764
|
+
label: "Error",
|
|
765
|
+
factory: () => ({
|
|
766
|
+
type: "alert",
|
|
767
|
+
level: "error",
|
|
768
|
+
text: {
|
|
769
|
+
type: "mrkdwn",
|
|
770
|
+
text: "Something went wrong. Please try again."
|
|
771
|
+
}
|
|
772
|
+
})
|
|
773
|
+
},
|
|
774
|
+
{
|
|
775
|
+
id: "alert_success",
|
|
776
|
+
label: "Success",
|
|
777
|
+
factory: () => ({
|
|
778
|
+
type: "alert",
|
|
779
|
+
level: "success",
|
|
780
|
+
text: {
|
|
781
|
+
type: "mrkdwn",
|
|
782
|
+
text: "Your changes have been saved."
|
|
783
|
+
}
|
|
784
|
+
})
|
|
785
|
+
}
|
|
786
|
+
]
|
|
787
|
+
},
|
|
663
788
|
{
|
|
664
789
|
name: "Rich Text",
|
|
665
790
|
icon: lucideReact.Pilcrow,
|
|
@@ -710,6 +835,43 @@ var defaultPalette = [
|
|
|
710
835
|
}
|
|
711
836
|
]
|
|
712
837
|
},
|
|
838
|
+
{
|
|
839
|
+
name: "Video",
|
|
840
|
+
icon: lucideReact.Video,
|
|
841
|
+
variants: [
|
|
842
|
+
{
|
|
843
|
+
id: "video_basic",
|
|
844
|
+
label: "Basic",
|
|
845
|
+
factory: () => ({
|
|
846
|
+
type: "video",
|
|
847
|
+
alt_text: "A short demo video",
|
|
848
|
+
title: { type: "plain_text", text: "Product demo", emoji: true },
|
|
849
|
+
thumbnail_url: "https://placehold.co/600x340?text=Video",
|
|
850
|
+
video_url: "https://www.youtube.com/embed/dQw4w9WgXcQ"
|
|
851
|
+
})
|
|
852
|
+
},
|
|
853
|
+
{
|
|
854
|
+
id: "video_with_metadata",
|
|
855
|
+
label: "With metadata",
|
|
856
|
+
factory: () => ({
|
|
857
|
+
type: "video",
|
|
858
|
+
alt_text: "A short demo video",
|
|
859
|
+
title: { type: "plain_text", text: "Product demo", emoji: true },
|
|
860
|
+
title_url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
|
|
861
|
+
thumbnail_url: "https://placehold.co/600x340?text=Video",
|
|
862
|
+
video_url: "https://www.youtube.com/embed/dQw4w9WgXcQ",
|
|
863
|
+
author_name: "Acme",
|
|
864
|
+
description: {
|
|
865
|
+
type: "plain_text",
|
|
866
|
+
text: "A short walkthrough of the new release.",
|
|
867
|
+
emoji: true
|
|
868
|
+
},
|
|
869
|
+
provider_name: "YouTube",
|
|
870
|
+
provider_icon_url: "https://placehold.co/16x16?text=YT"
|
|
871
|
+
})
|
|
872
|
+
}
|
|
873
|
+
]
|
|
874
|
+
},
|
|
713
875
|
{
|
|
714
876
|
name: "Card and Carousel",
|
|
715
877
|
icon: lucideReact.GalleryHorizontal,
|
|
@@ -1295,15 +1457,69 @@ function labelForBlockType(type) {
|
|
|
1295
1457
|
return "Context Actions";
|
|
1296
1458
|
case "input":
|
|
1297
1459
|
return "Input";
|
|
1460
|
+
case "video":
|
|
1461
|
+
return "Video";
|
|
1462
|
+
case "plan":
|
|
1463
|
+
return "Plan";
|
|
1464
|
+
case "task_card":
|
|
1465
|
+
return "Task Card";
|
|
1298
1466
|
}
|
|
1299
1467
|
}
|
|
1300
1468
|
function cn(...inputs) {
|
|
1301
1469
|
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
1302
1470
|
}
|
|
1471
|
+
var Sheet = DialogPrimitive__namespace.Root;
|
|
1472
|
+
var SheetOverlay = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1473
|
+
DialogPrimitive__namespace.Overlay,
|
|
1474
|
+
{
|
|
1475
|
+
ref,
|
|
1476
|
+
className: cn(
|
|
1477
|
+
"bk-portal-content fixed inset-0 z-50 bg-black/50 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
1478
|
+
className
|
|
1479
|
+
),
|
|
1480
|
+
...props
|
|
1481
|
+
}
|
|
1482
|
+
));
|
|
1483
|
+
SheetOverlay.displayName = DialogPrimitive__namespace.Overlay.displayName;
|
|
1484
|
+
var SHEET_SIDE_CLASSES = {
|
|
1485
|
+
right: "inset-y-0 right-0 h-full w-full max-w-md border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right",
|
|
1486
|
+
left: "inset-y-0 left-0 h-full w-full max-w-md border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left",
|
|
1487
|
+
top: "inset-x-0 top-0 w-full border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
|
|
1488
|
+
bottom: "inset-x-0 bottom-0 w-full rounded-t-xl border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom"
|
|
1489
|
+
};
|
|
1490
|
+
var SheetContent = React__namespace.forwardRef(
|
|
1491
|
+
({ className, children, side = "right", hideClose = false, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(DialogPrimitive__namespace.Portal, { children: [
|
|
1492
|
+
/* @__PURE__ */ jsxRuntime.jsx(SheetOverlay, {}),
|
|
1493
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1494
|
+
DialogPrimitive__namespace.Content,
|
|
1495
|
+
{
|
|
1496
|
+
ref,
|
|
1497
|
+
className: cn(
|
|
1498
|
+
"bk-portal-content fixed z-50 flex flex-col gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
1499
|
+
SHEET_SIDE_CLASSES[side],
|
|
1500
|
+
className
|
|
1501
|
+
),
|
|
1502
|
+
...props,
|
|
1503
|
+
children: [
|
|
1504
|
+
children,
|
|
1505
|
+
hideClose ? null : /* @__PURE__ */ jsxRuntime.jsxs(DialogPrimitive__namespace.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none", children: [
|
|
1506
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" }),
|
|
1507
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close" })
|
|
1508
|
+
] })
|
|
1509
|
+
]
|
|
1510
|
+
}
|
|
1511
|
+
)
|
|
1512
|
+
] })
|
|
1513
|
+
);
|
|
1514
|
+
SheetContent.displayName = DialogPrimitive__namespace.Content.displayName;
|
|
1515
|
+
var SheetTitle = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Title, { ref, className: cn("text-lg font-semibold text-foreground", className), ...props }));
|
|
1516
|
+
SheetTitle.displayName = DialogPrimitive__namespace.Title.displayName;
|
|
1517
|
+
var SheetDescription = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
|
|
1518
|
+
SheetDescription.displayName = DialogPrimitive__namespace.Description.displayName;
|
|
1303
1519
|
var TooltipProvider = TooltipPrimitive__namespace.Provider;
|
|
1304
1520
|
var Tooltip = TooltipPrimitive__namespace.Root;
|
|
1305
1521
|
var TooltipTrigger = TooltipPrimitive__namespace.Trigger;
|
|
1306
|
-
var TooltipContent =
|
|
1522
|
+
var TooltipContent = React__namespace.forwardRef(({ className, sideOffset = 6, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1307
1523
|
TooltipPrimitive__namespace.Content,
|
|
1308
1524
|
{
|
|
1309
1525
|
ref,
|
|
@@ -1317,6 +1533,22 @@ var TooltipContent = React2__namespace.forwardRef(({ className, sideOffset = 6,
|
|
|
1317
1533
|
}
|
|
1318
1534
|
) }));
|
|
1319
1535
|
TooltipContent.displayName = TooltipPrimitive__namespace.Content.displayName;
|
|
1536
|
+
var MOBILE_BREAKPOINT_PX = 768;
|
|
1537
|
+
function useIsMobile() {
|
|
1538
|
+
const [isMobile, setIsMobile] = React.useState(() => {
|
|
1539
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return false;
|
|
1540
|
+
return window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT_PX - 1}px)`).matches;
|
|
1541
|
+
});
|
|
1542
|
+
React.useEffect(() => {
|
|
1543
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
1544
|
+
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT_PX - 1}px)`);
|
|
1545
|
+
const onChange = (e) => setIsMobile(e.matches);
|
|
1546
|
+
setIsMobile(mql.matches);
|
|
1547
|
+
mql.addEventListener("change", onChange);
|
|
1548
|
+
return () => mql.removeEventListener("change", onChange);
|
|
1549
|
+
}, []);
|
|
1550
|
+
return isMobile;
|
|
1551
|
+
}
|
|
1320
1552
|
|
|
1321
1553
|
// src/lib/error-grouping.ts
|
|
1322
1554
|
function toValidatorSurface(surface) {
|
|
@@ -1497,9 +1729,9 @@ function computeValidation(blocks, surface) {
|
|
|
1497
1729
|
};
|
|
1498
1730
|
}
|
|
1499
1731
|
function useBlockKitValidation(blocks, surface) {
|
|
1500
|
-
const [state, setState] =
|
|
1501
|
-
const isFirstRunRef =
|
|
1502
|
-
|
|
1732
|
+
const [state, setState] = React.useState(() => computeValidation(blocks, surface));
|
|
1733
|
+
const isFirstRunRef = React.useRef(true);
|
|
1734
|
+
React.useEffect(() => {
|
|
1503
1735
|
if (isFirstRunRef.current) {
|
|
1504
1736
|
isFirstRunRef.current = false;
|
|
1505
1737
|
return;
|
|
@@ -1518,20 +1750,20 @@ function useBlockKitchenState({
|
|
|
1518
1750
|
initialBlocks,
|
|
1519
1751
|
onChange
|
|
1520
1752
|
} = {}) {
|
|
1521
|
-
const [blocks, setBlocks] =
|
|
1522
|
-
const onChangeRef =
|
|
1523
|
-
|
|
1753
|
+
const [blocks, setBlocks] = React.useState(() => (initialBlocks ?? []).map(wrap));
|
|
1754
|
+
const onChangeRef = React.useRef(onChange);
|
|
1755
|
+
React.useEffect(() => {
|
|
1524
1756
|
onChangeRef.current = onChange;
|
|
1525
1757
|
}, [onChange]);
|
|
1526
|
-
const isFirstRunRef =
|
|
1527
|
-
|
|
1758
|
+
const isFirstRunRef = React.useRef(true);
|
|
1759
|
+
React.useEffect(() => {
|
|
1528
1760
|
if (isFirstRunRef.current) {
|
|
1529
1761
|
isFirstRunRef.current = false;
|
|
1530
1762
|
return;
|
|
1531
1763
|
}
|
|
1532
1764
|
onChangeRef.current?.(blocks.map((b) => b.block));
|
|
1533
1765
|
}, [blocks]);
|
|
1534
|
-
const addBlock =
|
|
1766
|
+
const addBlock = React.useCallback((block, atIndex) => {
|
|
1535
1767
|
setBlocks((prev) => {
|
|
1536
1768
|
const next = [...prev];
|
|
1537
1769
|
const inserted = wrap(block);
|
|
@@ -1540,13 +1772,13 @@ function useBlockKitchenState({
|
|
|
1540
1772
|
return next;
|
|
1541
1773
|
});
|
|
1542
1774
|
}, []);
|
|
1543
|
-
const updateBlock =
|
|
1775
|
+
const updateBlock = React.useCallback((id, block) => {
|
|
1544
1776
|
setBlocks((prev) => prev.map((b) => b.id === id ? { ...b, block } : b));
|
|
1545
1777
|
}, []);
|
|
1546
|
-
const removeBlock =
|
|
1778
|
+
const removeBlock = React.useCallback((id) => {
|
|
1547
1779
|
setBlocks((prev) => prev.filter((b) => b.id !== id));
|
|
1548
1780
|
}, []);
|
|
1549
|
-
const duplicateBlock =
|
|
1781
|
+
const duplicateBlock = React.useCallback((id) => {
|
|
1550
1782
|
setBlocks((prev) => {
|
|
1551
1783
|
const idx = prev.findIndex((b) => b.id === id);
|
|
1552
1784
|
if (idx === -1) {
|
|
@@ -1558,7 +1790,7 @@ function useBlockKitchenState({
|
|
|
1558
1790
|
return next;
|
|
1559
1791
|
});
|
|
1560
1792
|
}, []);
|
|
1561
|
-
const reorderBlock =
|
|
1793
|
+
const reorderBlock = React.useCallback((fromId, toIndex) => {
|
|
1562
1794
|
setBlocks((prev) => {
|
|
1563
1795
|
const fromIndex = prev.findIndex((b) => b.id === fromId);
|
|
1564
1796
|
if (fromIndex === -1) {
|
|
@@ -1571,7 +1803,7 @@ function useBlockKitchenState({
|
|
|
1571
1803
|
return next;
|
|
1572
1804
|
});
|
|
1573
1805
|
}, []);
|
|
1574
|
-
const replaceAll =
|
|
1806
|
+
const replaceAll = React.useCallback((newBlocks) => {
|
|
1575
1807
|
setBlocks(newBlocks.map(wrap));
|
|
1576
1808
|
}, []);
|
|
1577
1809
|
return {
|
|
@@ -1877,9 +2109,9 @@ function toCssDeclarations(vars) {
|
|
|
1877
2109
|
return entries.map(([name, value]) => `${name}: ${value};`).join(" ");
|
|
1878
2110
|
}
|
|
1879
2111
|
function BrandThemeScope({ theme, children }) {
|
|
1880
|
-
const rawId =
|
|
1881
|
-
const scopeId =
|
|
1882
|
-
const resolved =
|
|
2112
|
+
const rawId = React.useId();
|
|
2113
|
+
const scopeId = React.useMemo(() => `bk-${rawId.replace(/[:]/g, "")}`, [rawId]);
|
|
2114
|
+
const resolved = React.useMemo(() => resolveBrandTheme(theme), [theme]);
|
|
1883
2115
|
const hasLight = Object.keys(resolved.light).length > 0;
|
|
1884
2116
|
const hasDark = Object.keys(resolved.dark).length > 0;
|
|
1885
2117
|
if (!hasLight && !hasDark) {
|
|
@@ -1900,45 +2132,6 @@ function BrandThemeScope({ theme, children }) {
|
|
|
1900
2132
|
/* @__PURE__ */ jsxRuntime.jsx("div", { "data-bk-scope": scopeId, style: { display: "contents" }, children })
|
|
1901
2133
|
] });
|
|
1902
2134
|
}
|
|
1903
|
-
var Sheet = DialogPrimitive__namespace.Root;
|
|
1904
|
-
var SheetOverlay = React2__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1905
|
-
DialogPrimitive__namespace.Overlay,
|
|
1906
|
-
{
|
|
1907
|
-
ref,
|
|
1908
|
-
className: cn(
|
|
1909
|
-
"bk-portal-content fixed inset-0 z-50 bg-black/50 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
1910
|
-
className
|
|
1911
|
-
),
|
|
1912
|
-
...props
|
|
1913
|
-
}
|
|
1914
|
-
));
|
|
1915
|
-
SheetOverlay.displayName = DialogPrimitive__namespace.Overlay.displayName;
|
|
1916
|
-
var SheetContent = React2__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(DialogPrimitive__namespace.Portal, { children: [
|
|
1917
|
-
/* @__PURE__ */ jsxRuntime.jsx(SheetOverlay, {}),
|
|
1918
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1919
|
-
DialogPrimitive__namespace.Content,
|
|
1920
|
-
{
|
|
1921
|
-
ref,
|
|
1922
|
-
className: cn(
|
|
1923
|
-
"bk-portal-content fixed inset-y-0 right-0 z-50 flex h-full w-full max-w-md flex-col gap-4 border-l bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right",
|
|
1924
|
-
className
|
|
1925
|
-
),
|
|
1926
|
-
...props,
|
|
1927
|
-
children: [
|
|
1928
|
-
children,
|
|
1929
|
-
/* @__PURE__ */ jsxRuntime.jsxs(DialogPrimitive__namespace.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none", children: [
|
|
1930
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" }),
|
|
1931
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close" })
|
|
1932
|
-
] })
|
|
1933
|
-
]
|
|
1934
|
-
}
|
|
1935
|
-
)
|
|
1936
|
-
] }));
|
|
1937
|
-
SheetContent.displayName = DialogPrimitive__namespace.Content.displayName;
|
|
1938
|
-
var SheetTitle = React2__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Title, { ref, className: cn("text-lg font-semibold text-foreground", className), ...props }));
|
|
1939
|
-
SheetTitle.displayName = DialogPrimitive__namespace.Title.displayName;
|
|
1940
|
-
var SheetDescription = React2__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
|
|
1941
|
-
SheetDescription.displayName = DialogPrimitive__namespace.Description.displayName;
|
|
1942
2135
|
function IssuesSheet({
|
|
1943
2136
|
open,
|
|
1944
2137
|
onOpenChange,
|
|
@@ -1953,7 +2146,7 @@ function IssuesSheet({
|
|
|
1953
2146
|
}
|
|
1954
2147
|
return { block, idx, errors };
|
|
1955
2148
|
}).filter(Boolean);
|
|
1956
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Sheet, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(SheetContent, { className: "flex flex-col gap-3 sm:max-w-md", children: [
|
|
2149
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Sheet, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(SheetContent, { className: "flex w-full max-w-full flex-col gap-3 sm:max-w-md", children: [
|
|
1957
2150
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1958
2151
|
/* @__PURE__ */ jsxRuntime.jsxs(SheetTitle, { className: "flex items-center gap-2", children: [
|
|
1959
2152
|
validation.total === 0 ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCircle2, { className: "h-4 w-4 text-emerald-600" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-4 w-4 text-destructive" }),
|
|
@@ -2003,16 +2196,16 @@ function JsonDrawer({
|
|
|
2003
2196
|
blocks,
|
|
2004
2197
|
onApply
|
|
2005
2198
|
}) {
|
|
2006
|
-
const [value, setValue] =
|
|
2007
|
-
const [parseError, setParseError] =
|
|
2008
|
-
const [validationErrors, setValidationErrors] =
|
|
2009
|
-
const textareaRef =
|
|
2010
|
-
const gutterRef =
|
|
2011
|
-
const blocksRef =
|
|
2012
|
-
|
|
2199
|
+
const [value, setValue] = React.useState("");
|
|
2200
|
+
const [parseError, setParseError] = React.useState(null);
|
|
2201
|
+
const [validationErrors, setValidationErrors] = React.useState([]);
|
|
2202
|
+
const textareaRef = React.useRef(null);
|
|
2203
|
+
const gutterRef = React.useRef(null);
|
|
2204
|
+
const blocksRef = React.useRef(blocks);
|
|
2205
|
+
React.useEffect(() => {
|
|
2013
2206
|
blocksRef.current = blocks;
|
|
2014
2207
|
});
|
|
2015
|
-
|
|
2208
|
+
React.useEffect(() => {
|
|
2016
2209
|
if (open) {
|
|
2017
2210
|
setValue(JSON.stringify(blocksRef.current, null, 2));
|
|
2018
2211
|
setParseError(null);
|
|
@@ -2047,7 +2240,7 @@ function JsonDrawer({
|
|
|
2047
2240
|
});
|
|
2048
2241
|
setValidationErrors(result.valid ? [] : result.errors);
|
|
2049
2242
|
};
|
|
2050
|
-
const lineCount =
|
|
2243
|
+
const lineCount = React.useMemo(() => {
|
|
2051
2244
|
if (!value) {
|
|
2052
2245
|
return 1;
|
|
2053
2246
|
}
|
|
@@ -2059,8 +2252,8 @@ function JsonDrawer({
|
|
|
2059
2252
|
}
|
|
2060
2253
|
return n;
|
|
2061
2254
|
}, [value]);
|
|
2062
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Sheet, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(SheetContent, { className: "flex flex-col gap-3 sm:max-w-xl", children: [
|
|
2063
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
2255
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Sheet, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(SheetContent, { className: "flex w-full max-w-full flex-col gap-3 sm:max-w-xl", children: [
|
|
2256
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 pr-8", children: [
|
|
2064
2257
|
/* @__PURE__ */ jsxRuntime.jsx(SheetTitle, { children: "Block Kit JSON" }),
|
|
2065
2258
|
/* @__PURE__ */ jsxRuntime.jsx(SheetDescription, { children: "Edits update the preview as you type. Parse errors show below." })
|
|
2066
2259
|
] }),
|
|
@@ -2078,6 +2271,7 @@ function JsonDrawer({
|
|
|
2078
2271
|
"textarea",
|
|
2079
2272
|
{
|
|
2080
2273
|
ref: textareaRef,
|
|
2274
|
+
"aria-label": "Block Kit JSON",
|
|
2081
2275
|
value,
|
|
2082
2276
|
onChange: (e) => handleChange(e.target.value),
|
|
2083
2277
|
onScroll: (e) => {
|
|
@@ -2103,7 +2297,7 @@ function JsonDrawer({
|
|
|
2103
2297
|
] })
|
|
2104
2298
|
] }) });
|
|
2105
2299
|
}
|
|
2106
|
-
var Input =
|
|
2300
|
+
var Input = React__namespace.forwardRef(
|
|
2107
2301
|
({ className, type, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2108
2302
|
"input",
|
|
2109
2303
|
{
|
|
@@ -2150,51 +2344,82 @@ function Palette({
|
|
|
2150
2344
|
sections,
|
|
2151
2345
|
defaultOpenSections = true,
|
|
2152
2346
|
showSearch = true,
|
|
2153
|
-
searchPlaceholder = "Search blocks\u2026"
|
|
2347
|
+
searchPlaceholder = "Search blocks\u2026",
|
|
2348
|
+
variant = "aside"
|
|
2154
2349
|
}) {
|
|
2155
|
-
const [query, setQuery] =
|
|
2156
|
-
const visibleSections =
|
|
2350
|
+
const [query, setQuery] = React.useState("");
|
|
2351
|
+
const visibleSections = React.useMemo(
|
|
2157
2352
|
() => showSearch ? filterSections(sections, query) : sections,
|
|
2158
2353
|
[sections, query, showSearch]
|
|
2159
2354
|
);
|
|
2160
2355
|
const queryActive = showSearch && query.trim().length > 0;
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
"
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2356
|
+
const isSheet = variant === "sheet";
|
|
2357
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2358
|
+
"aside",
|
|
2359
|
+
{
|
|
2360
|
+
className: cn(
|
|
2361
|
+
"flex min-h-0 flex-col overflow-x-hidden overflow-y-auto",
|
|
2362
|
+
isSheet ? "w-full flex-1 bg-background" : "w-72 shrink-0 border-r bg-muted/20"
|
|
2363
|
+
),
|
|
2364
|
+
children: [
|
|
2365
|
+
showSearch ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2366
|
+
"div",
|
|
2367
|
+
{
|
|
2368
|
+
className: cn(
|
|
2369
|
+
"sticky top-0 z-10 border-b px-3 pt-3 pb-2 backdrop-blur",
|
|
2370
|
+
isSheet ? "bg-background" : "bg-muted/20"
|
|
2371
|
+
),
|
|
2372
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
2373
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2374
|
+
lucideReact.Search,
|
|
2375
|
+
{
|
|
2376
|
+
className: cn(
|
|
2377
|
+
"pointer-events-none absolute left-2 top-1/2 -translate-y-1/2 text-muted-foreground",
|
|
2378
|
+
isSheet ? "h-4 w-4" : "h-3.5 w-3.5"
|
|
2379
|
+
)
|
|
2380
|
+
}
|
|
2381
|
+
),
|
|
2382
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2383
|
+
Input,
|
|
2384
|
+
{
|
|
2385
|
+
type: "search",
|
|
2386
|
+
value: query,
|
|
2387
|
+
onChange: (e) => setQuery(e.target.value),
|
|
2388
|
+
placeholder: searchPlaceholder,
|
|
2389
|
+
"aria-label": searchPlaceholder,
|
|
2390
|
+
className: cn(isSheet ? "h-10 pl-8 text-base" : "h-8 pl-7 text-sm")
|
|
2391
|
+
}
|
|
2392
|
+
)
|
|
2393
|
+
] })
|
|
2394
|
+
}
|
|
2395
|
+
) : null,
|
|
2396
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-col", isSheet ? "px-2 pb-6" : "p-3"), children: visibleSections.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "px-1 py-2 text-xs text-muted-foreground", children: "No blocks match." }) : visibleSections.map((section) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2397
|
+
PaletteSection,
|
|
2398
|
+
{
|
|
2399
|
+
section,
|
|
2400
|
+
defaultOpen: isDefaultOpen(section.name, defaultOpenSections),
|
|
2401
|
+
forceOpen: queryActive,
|
|
2402
|
+
onAddBlock,
|
|
2403
|
+
variant
|
|
2404
|
+
},
|
|
2405
|
+
section.name
|
|
2406
|
+
)) })
|
|
2407
|
+
]
|
|
2408
|
+
}
|
|
2409
|
+
);
|
|
2187
2410
|
}
|
|
2188
2411
|
function PaletteSection({
|
|
2189
2412
|
section,
|
|
2190
2413
|
defaultOpen,
|
|
2191
2414
|
forceOpen,
|
|
2192
|
-
onAddBlock
|
|
2415
|
+
onAddBlock,
|
|
2416
|
+
variant = "aside"
|
|
2193
2417
|
}) {
|
|
2194
|
-
const [open, setOpen] =
|
|
2418
|
+
const [open, setOpen] = React.useState(defaultOpen);
|
|
2195
2419
|
const Icon = section.icon;
|
|
2196
2420
|
const isOpen = open || forceOpen;
|
|
2197
2421
|
const Caret = isOpen ? lucideReact.ChevronDown : lucideReact.ChevronRight;
|
|
2422
|
+
const isSheet = variant === "sheet";
|
|
2198
2423
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 flex flex-col first:mt-0", children: [
|
|
2199
2424
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2200
2425
|
"button",
|
|
@@ -2202,21 +2427,54 @@ function PaletteSection({
|
|
|
2202
2427
|
type: "button",
|
|
2203
2428
|
"aria-expanded": isOpen,
|
|
2204
2429
|
onClick: () => setOpen((v) => !v),
|
|
2205
|
-
className:
|
|
2430
|
+
className: cn(
|
|
2431
|
+
"flex cursor-pointer appearance-none items-center gap-1.5 rounded border-0 bg-transparent text-left transition-colors hover:bg-accent focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
2432
|
+
isSheet ? "px-2 py-2 min-h-10" : "px-1 py-1"
|
|
2433
|
+
),
|
|
2206
2434
|
children: [
|
|
2207
|
-
/* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "
|
|
2208
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2209
|
-
|
|
2435
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icon, { className: cn("shrink-0 text-muted-foreground", isSheet ? "h-5 w-5" : "h-4 w-4") }),
|
|
2436
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2437
|
+
"span",
|
|
2438
|
+
{
|
|
2439
|
+
className: cn("min-w-0 flex-1 truncate font-semibold text-foreground", isSheet ? "text-sm" : "text-[13px]"),
|
|
2440
|
+
children: section.name
|
|
2441
|
+
}
|
|
2442
|
+
),
|
|
2443
|
+
/* @__PURE__ */ jsxRuntime.jsx(Caret, { className: cn("shrink-0 text-muted-foreground", isSheet ? "h-4 w-4" : "h-3.5 w-3.5") })
|
|
2210
2444
|
]
|
|
2211
2445
|
}
|
|
2212
2446
|
),
|
|
2213
|
-
isOpen ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-0.5 flex flex-col", children: section.variants.map((
|
|
2447
|
+
isOpen ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-0.5 flex flex-col", children: section.variants.map((v) => /* @__PURE__ */ jsxRuntime.jsx(PaletteItem, { variant: v, onAdd: () => onAddBlock(v.factory()), mode: variant }, v.id)) }) : null
|
|
2214
2448
|
] });
|
|
2215
2449
|
}
|
|
2216
|
-
function PaletteItem({
|
|
2450
|
+
function PaletteItem({
|
|
2451
|
+
variant,
|
|
2452
|
+
onAdd,
|
|
2453
|
+
mode = "aside"
|
|
2454
|
+
}) {
|
|
2217
2455
|
const { attributes, listeners, setNodeRef, setActivatorNodeRef, isDragging } = core.useDraggable({
|
|
2218
2456
|
id: `${PALETTE_DRAG_PREFIX}${variant.id}`
|
|
2219
2457
|
});
|
|
2458
|
+
const isSheet = mode === "sheet";
|
|
2459
|
+
if (isSheet) {
|
|
2460
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2461
|
+
"button",
|
|
2462
|
+
{
|
|
2463
|
+
ref: setNodeRef,
|
|
2464
|
+
type: "button",
|
|
2465
|
+
"aria-label": `Add ${variant.label}`,
|
|
2466
|
+
onClick: onAdd,
|
|
2467
|
+
className: cn(
|
|
2468
|
+
"group flex w-full min-h-11 cursor-pointer items-center gap-3 rounded-md border border-transparent bg-background px-3 py-2 text-left text-sm font-medium text-foreground transition-colors hover:border-border hover:bg-accent active:bg-accent focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
2469
|
+
isDragging && "opacity-50"
|
|
2470
|
+
),
|
|
2471
|
+
children: [
|
|
2472
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-md bg-muted text-muted-foreground transition-colors group-hover:bg-primary/10 group-hover:text-primary", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4" }) }),
|
|
2473
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate", children: variant.label })
|
|
2474
|
+
]
|
|
2475
|
+
}
|
|
2476
|
+
);
|
|
2477
|
+
}
|
|
2220
2478
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2221
2479
|
"div",
|
|
2222
2480
|
{
|
|
@@ -2278,7 +2536,7 @@ var buttonVariants = classVarianceAuthority.cva(
|
|
|
2278
2536
|
}
|
|
2279
2537
|
}
|
|
2280
2538
|
);
|
|
2281
|
-
var Button =
|
|
2539
|
+
var Button = React__namespace.forwardRef(
|
|
2282
2540
|
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
2283
2541
|
const Comp = asChild ? reactSlot.Slot : "button";
|
|
2284
2542
|
return /* @__PURE__ */ jsxRuntime.jsx(Comp, { className: cn(buttonVariants({ variant, size, className })), ref, ...props });
|
|
@@ -2287,7 +2545,7 @@ var Button = React2__namespace.forwardRef(
|
|
|
2287
2545
|
Button.displayName = "Button";
|
|
2288
2546
|
var Dialog = DialogPrimitive__namespace.Root;
|
|
2289
2547
|
var DialogPortal = DialogPrimitive__namespace.Portal;
|
|
2290
|
-
var DialogOverlay =
|
|
2548
|
+
var DialogOverlay = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2291
2549
|
DialogPrimitive__namespace.Overlay,
|
|
2292
2550
|
{
|
|
2293
2551
|
ref,
|
|
@@ -2299,7 +2557,7 @@ var DialogOverlay = React2__namespace.forwardRef(({ className, ...props }, ref)
|
|
|
2299
2557
|
}
|
|
2300
2558
|
));
|
|
2301
2559
|
DialogOverlay.displayName = DialogPrimitive__namespace.Overlay.displayName;
|
|
2302
|
-
var DialogContent =
|
|
2560
|
+
var DialogContent = React__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(DialogPortal, { children: [
|
|
2303
2561
|
/* @__PURE__ */ jsxRuntime.jsx(DialogOverlay, {}),
|
|
2304
2562
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2305
2563
|
DialogPrimitive__namespace.Content,
|
|
@@ -2327,7 +2585,7 @@ function DialogHeader({ className, ...props }) {
|
|
|
2327
2585
|
function DialogFooter({ className, ...props }) {
|
|
2328
2586
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className), ...props });
|
|
2329
2587
|
}
|
|
2330
|
-
var DialogTitle =
|
|
2588
|
+
var DialogTitle = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2331
2589
|
DialogPrimitive__namespace.Title,
|
|
2332
2590
|
{
|
|
2333
2591
|
ref,
|
|
@@ -2336,9 +2594,9 @@ var DialogTitle = React2__namespace.forwardRef(({ className, ...props }, ref) =>
|
|
|
2336
2594
|
}
|
|
2337
2595
|
));
|
|
2338
2596
|
DialogTitle.displayName = DialogPrimitive__namespace.Title.displayName;
|
|
2339
|
-
var DialogDescription =
|
|
2597
|
+
var DialogDescription = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
|
|
2340
2598
|
DialogDescription.displayName = DialogPrimitive__namespace.Description.displayName;
|
|
2341
|
-
var Label =
|
|
2599
|
+
var Label = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2342
2600
|
LabelPrimitive__namespace.Root,
|
|
2343
2601
|
{
|
|
2344
2602
|
ref,
|
|
@@ -2357,22 +2615,22 @@ function SendDialog({
|
|
|
2357
2615
|
errorCount,
|
|
2358
2616
|
onShowIssues
|
|
2359
2617
|
}) {
|
|
2360
|
-
const [channels, setChannels] =
|
|
2361
|
-
const [channelsError, setChannelsError] =
|
|
2362
|
-
const [channelId, setChannelId] =
|
|
2363
|
-
const [userStatus, setUserStatus] =
|
|
2364
|
-
const [sendAs, setSendAs] =
|
|
2365
|
-
const [status, setStatus] =
|
|
2366
|
-
const loadChannelsRef =
|
|
2367
|
-
const loadSendAsUserStatusRef =
|
|
2368
|
-
|
|
2618
|
+
const [channels, setChannels] = React.useState(null);
|
|
2619
|
+
const [channelsError, setChannelsError] = React.useState(null);
|
|
2620
|
+
const [channelId, setChannelId] = React.useState("");
|
|
2621
|
+
const [userStatus, setUserStatus] = React.useState(null);
|
|
2622
|
+
const [sendAs, setSendAs] = React.useState("bot");
|
|
2623
|
+
const [status, setStatus] = React.useState({ kind: "idle" });
|
|
2624
|
+
const loadChannelsRef = React.useRef(loadChannels);
|
|
2625
|
+
const loadSendAsUserStatusRef = React.useRef(loadSendAsUserStatus);
|
|
2626
|
+
React.useEffect(() => {
|
|
2369
2627
|
loadChannelsRef.current = loadChannels;
|
|
2370
2628
|
loadSendAsUserStatusRef.current = loadSendAsUserStatus;
|
|
2371
2629
|
});
|
|
2372
|
-
const refreshSendAsUser =
|
|
2630
|
+
const refreshSendAsUser = React.useCallback(() => {
|
|
2373
2631
|
loadSendAsUserStatusRef.current().then(setUserStatus).catch(() => setUserStatus({ canSendAsUser: false }));
|
|
2374
2632
|
}, []);
|
|
2375
|
-
|
|
2633
|
+
React.useEffect(() => {
|
|
2376
2634
|
if (!open) {
|
|
2377
2635
|
return;
|
|
2378
2636
|
}
|
|
@@ -2400,7 +2658,7 @@ function SendDialog({
|
|
|
2400
2658
|
cancelled = true;
|
|
2401
2659
|
};
|
|
2402
2660
|
}, [open, refreshSendAsUser]);
|
|
2403
|
-
|
|
2661
|
+
React.useEffect(() => {
|
|
2404
2662
|
if (!open) {
|
|
2405
2663
|
return;
|
|
2406
2664
|
}
|
|
@@ -2437,7 +2695,7 @@ function SendDialog({
|
|
|
2437
2695
|
});
|
|
2438
2696
|
}
|
|
2439
2697
|
};
|
|
2440
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { children: [
|
|
2698
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "w-[calc(100vw-1.5rem)] max-w-lg rounded-lg", children: [
|
|
2441
2699
|
/* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { children: [
|
|
2442
2700
|
/* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Send to Slack" }),
|
|
2443
2701
|
/* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: "Pick a channel and choose who to post as." })
|
|
@@ -2535,7 +2793,7 @@ function SendDialog({
|
|
|
2535
2793
|
}
|
|
2536
2794
|
var Popover = PopoverPrimitive__namespace.Root;
|
|
2537
2795
|
var PopoverTrigger = PopoverPrimitive__namespace.Trigger;
|
|
2538
|
-
var PopoverContent =
|
|
2796
|
+
var PopoverContent = React__namespace.forwardRef(({ className, align = "start", sideOffset = 8, collisionPadding = 16, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(PopoverPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2539
2797
|
PopoverPrimitive__namespace.Content,
|
|
2540
2798
|
{
|
|
2541
2799
|
ref,
|
|
@@ -2551,9 +2809,9 @@ var PopoverContent = React2__namespace.forwardRef(({ className, align = "start",
|
|
|
2551
2809
|
}
|
|
2552
2810
|
) }));
|
|
2553
2811
|
PopoverContent.displayName = PopoverPrimitive__namespace.Content.displayName;
|
|
2554
|
-
var RadioGroup =
|
|
2812
|
+
var RadioGroup = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(RadioGroupPrimitive__namespace.Root, { className: cn("grid gap-2", className), ...props, ref }));
|
|
2555
2813
|
RadioGroup.displayName = RadioGroupPrimitive__namespace.Root.displayName;
|
|
2556
|
-
var RadioGroupItem =
|
|
2814
|
+
var RadioGroupItem = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2557
2815
|
RadioGroupPrimitive__namespace.Item,
|
|
2558
2816
|
{
|
|
2559
2817
|
ref,
|
|
@@ -2685,7 +2943,7 @@ function ActionsEditor({ block, onChange }) {
|
|
|
2685
2943
|
] })
|
|
2686
2944
|
] });
|
|
2687
2945
|
}
|
|
2688
|
-
var Textarea =
|
|
2946
|
+
var Textarea = React__namespace.forwardRef(
|
|
2689
2947
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2690
2948
|
"textarea",
|
|
2691
2949
|
{
|
|
@@ -3715,7 +3973,14 @@ function PlainTextInputEditor({
|
|
|
3715
3973
|
}) {
|
|
3716
3974
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3717
3975
|
/* @__PURE__ */ jsxRuntime.jsx(ActionIdField, { element, onChange }),
|
|
3718
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3976
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3977
|
+
PlaceholderField,
|
|
3978
|
+
{
|
|
3979
|
+
element,
|
|
3980
|
+
onChange,
|
|
3981
|
+
example: element.multiline ? "e.g. Enter a longer description" : "e.g. Enter some text"
|
|
3982
|
+
}
|
|
3983
|
+
),
|
|
3719
3984
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3720
3985
|
EditorField,
|
|
3721
3986
|
{
|
|
@@ -3777,7 +4042,7 @@ function PlainTextInputEditor({
|
|
|
3777
4042
|
function EmailInputEditor({ element, onChange }) {
|
|
3778
4043
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3779
4044
|
/* @__PURE__ */ jsxRuntime.jsx(ActionIdField, { element, onChange }),
|
|
3780
|
-
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange }),
|
|
4045
|
+
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange, example: "e.g. name@example.com" }),
|
|
3781
4046
|
/* @__PURE__ */ jsxRuntime.jsx(EditorField, { label: "Initial value", help: "Pre-filled email address.", htmlFor: "email-initial", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3782
4047
|
Input,
|
|
3783
4048
|
{
|
|
@@ -3792,7 +4057,7 @@ function EmailInputEditor({ element, onChange }) {
|
|
|
3792
4057
|
function URLInputEditor({ element, onChange }) {
|
|
3793
4058
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3794
4059
|
/* @__PURE__ */ jsxRuntime.jsx(ActionIdField, { element, onChange }),
|
|
3795
|
-
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange }),
|
|
4060
|
+
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange, example: "e.g. https://example.com" }),
|
|
3796
4061
|
/* @__PURE__ */ jsxRuntime.jsx(EditorField, { label: "Initial value", help: "Pre-filled URL.", htmlFor: "url-initial", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3797
4062
|
Input,
|
|
3798
4063
|
{
|
|
@@ -3807,7 +4072,7 @@ function URLInputEditor({ element, onChange }) {
|
|
|
3807
4072
|
function NumberInputEditor({ element, onChange }) {
|
|
3808
4073
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3809
4074
|
/* @__PURE__ */ jsxRuntime.jsx(ActionIdField, { element, onChange }),
|
|
3810
|
-
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange }),
|
|
4075
|
+
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange, example: "e.g. 0" }),
|
|
3811
4076
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3812
4077
|
CheckboxField,
|
|
3813
4078
|
{
|
|
@@ -3860,7 +4125,7 @@ function NumberInputEditor({ element, onChange }) {
|
|
|
3860
4125
|
function DatepickerEditor({ element, onChange }) {
|
|
3861
4126
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3862
4127
|
/* @__PURE__ */ jsxRuntime.jsx(ActionIdField, { element, onChange }),
|
|
3863
|
-
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange }),
|
|
4128
|
+
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange, example: "e.g. Select a date" }),
|
|
3864
4129
|
/* @__PURE__ */ jsxRuntime.jsx(EditorField, { label: "Initial date", help: "YYYY-MM-DD. Pre-selected on load.", htmlFor: "date-initial", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3865
4130
|
Input,
|
|
3866
4131
|
{
|
|
@@ -3875,7 +4140,7 @@ function DatepickerEditor({ element, onChange }) {
|
|
|
3875
4140
|
function TimepickerEditor({ element, onChange }) {
|
|
3876
4141
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3877
4142
|
/* @__PURE__ */ jsxRuntime.jsx(ActionIdField, { element, onChange }),
|
|
3878
|
-
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange }),
|
|
4143
|
+
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange, example: "e.g. Select a time" }),
|
|
3879
4144
|
/* @__PURE__ */ jsxRuntime.jsx(EditorField, { label: "Initial time", help: "HH:mm in 24-hour clock.", htmlFor: "time-initial", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3880
4145
|
Input,
|
|
3881
4146
|
{
|
|
@@ -3928,7 +4193,7 @@ function DateTimepickerEditor({
|
|
|
3928
4193
|
function StaticSelectEditor({ element, onChange }) {
|
|
3929
4194
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3930
4195
|
/* @__PURE__ */ jsxRuntime.jsx(ActionIdField, { element, onChange }),
|
|
3931
|
-
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange }),
|
|
4196
|
+
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange, example: "e.g. Choose one" }),
|
|
3932
4197
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3933
4198
|
PlainTextOptionsField,
|
|
3934
4199
|
{
|
|
@@ -3944,7 +4209,7 @@ function MultiStaticSelectEditor({
|
|
|
3944
4209
|
}) {
|
|
3945
4210
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3946
4211
|
/* @__PURE__ */ jsxRuntime.jsx(ActionIdField, { element, onChange }),
|
|
3947
|
-
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange }),
|
|
4212
|
+
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange, example: "e.g. Choose one or more" }),
|
|
3948
4213
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3949
4214
|
PlainTextOptionsField,
|
|
3950
4215
|
{
|
|
@@ -3958,7 +4223,7 @@ function MultiStaticSelectEditor({
|
|
|
3958
4223
|
function UsersSelectEditor({ element, onChange }) {
|
|
3959
4224
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3960
4225
|
/* @__PURE__ */ jsxRuntime.jsx(ActionIdField, { element, onChange }),
|
|
3961
|
-
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange }),
|
|
4226
|
+
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange, example: "e.g. Select a user" }),
|
|
3962
4227
|
/* @__PURE__ */ jsxRuntime.jsx(EditorField, { label: "Initial user ID", help: "Optional. Pre-selects this Slack user.", htmlFor: "users-initial", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3963
4228
|
Input,
|
|
3964
4229
|
{
|
|
@@ -3976,7 +4241,7 @@ function MultiUsersSelectEditor({
|
|
|
3976
4241
|
}) {
|
|
3977
4242
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3978
4243
|
/* @__PURE__ */ jsxRuntime.jsx(ActionIdField, { element, onChange }),
|
|
3979
|
-
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange }),
|
|
4244
|
+
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange, example: "e.g. Select users" }),
|
|
3980
4245
|
/* @__PURE__ */ jsxRuntime.jsx(MaxSelectedField, { element, onChange })
|
|
3981
4246
|
] });
|
|
3982
4247
|
}
|
|
@@ -3986,7 +4251,7 @@ function ChannelsSelectEditor({
|
|
|
3986
4251
|
}) {
|
|
3987
4252
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3988
4253
|
/* @__PURE__ */ jsxRuntime.jsx(ActionIdField, { element, onChange }),
|
|
3989
|
-
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange }),
|
|
4254
|
+
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange, example: "e.g. Select a channel" }),
|
|
3990
4255
|
/* @__PURE__ */ jsxRuntime.jsx(EditorField, { label: "Initial channel ID", help: "Optional. Pre-selects this channel.", htmlFor: "channels-initial", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3991
4256
|
Input,
|
|
3992
4257
|
{
|
|
@@ -4007,7 +4272,7 @@ function MultiChannelsSelectEditor({
|
|
|
4007
4272
|
}) {
|
|
4008
4273
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4009
4274
|
/* @__PURE__ */ jsxRuntime.jsx(ActionIdField, { element, onChange }),
|
|
4010
|
-
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange }),
|
|
4275
|
+
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange, example: "e.g. Select channels" }),
|
|
4011
4276
|
/* @__PURE__ */ jsxRuntime.jsx(MaxSelectedField, { element, onChange })
|
|
4012
4277
|
] });
|
|
4013
4278
|
}
|
|
@@ -4017,7 +4282,7 @@ function ConversationsSelectEditor({
|
|
|
4017
4282
|
}) {
|
|
4018
4283
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4019
4284
|
/* @__PURE__ */ jsxRuntime.jsx(ActionIdField, { element, onChange }),
|
|
4020
|
-
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange }),
|
|
4285
|
+
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange, example: "e.g. Select a conversation" }),
|
|
4021
4286
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4022
4287
|
EditorField,
|
|
4023
4288
|
{
|
|
@@ -4059,7 +4324,7 @@ function MultiConversationsSelectEditor({
|
|
|
4059
4324
|
}) {
|
|
4060
4325
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4061
4326
|
/* @__PURE__ */ jsxRuntime.jsx(ActionIdField, { element, onChange }),
|
|
4062
|
-
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange }),
|
|
4327
|
+
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange, example: "e.g. Select conversations" }),
|
|
4063
4328
|
/* @__PURE__ */ jsxRuntime.jsx(MaxSelectedField, { element, onChange }),
|
|
4064
4329
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4065
4330
|
CheckboxField,
|
|
@@ -4082,7 +4347,7 @@ function ExternalSelectEditor({
|
|
|
4082
4347
|
}) {
|
|
4083
4348
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4084
4349
|
/* @__PURE__ */ jsxRuntime.jsx(ActionIdField, { element, onChange }),
|
|
4085
|
-
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange }),
|
|
4350
|
+
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange, example: "e.g. Choose one" }),
|
|
4086
4351
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4087
4352
|
EditorField,
|
|
4088
4353
|
{
|
|
@@ -4112,7 +4377,7 @@ function MultiExternalSelectEditor({
|
|
|
4112
4377
|
}) {
|
|
4113
4378
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4114
4379
|
/* @__PURE__ */ jsxRuntime.jsx(ActionIdField, { element, onChange }),
|
|
4115
|
-
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange }),
|
|
4380
|
+
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange, example: "e.g. Choose one or more" }),
|
|
4116
4381
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4117
4382
|
EditorField,
|
|
4118
4383
|
{
|
|
@@ -4167,7 +4432,7 @@ function RichTextInputEditor({
|
|
|
4167
4432
|
}) {
|
|
4168
4433
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4169
4434
|
/* @__PURE__ */ jsxRuntime.jsx(ActionIdField, { element, onChange }),
|
|
4170
|
-
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange }),
|
|
4435
|
+
/* @__PURE__ */ jsxRuntime.jsx(PlaceholderField, { element, onChange, example: "e.g. Type something" }),
|
|
4171
4436
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "Edit the initial rich-text value via the View JSON drawer." })
|
|
4172
4437
|
] });
|
|
4173
4438
|
}
|
|
@@ -4236,13 +4501,14 @@ function ActionIdField({
|
|
|
4236
4501
|
}
|
|
4237
4502
|
);
|
|
4238
4503
|
}
|
|
4239
|
-
function PlaceholderField({ element, onChange }) {
|
|
4504
|
+
function PlaceholderField({ element, onChange, example = "e.g. Type a hint" }) {
|
|
4240
4505
|
return /* @__PURE__ */ jsxRuntime.jsx(EditorField, { label: "Placeholder", help: "Greyed-out hint shown when the input is empty.", htmlFor: "placeholder", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4241
4506
|
Input,
|
|
4242
4507
|
{
|
|
4243
4508
|
id: "placeholder",
|
|
4244
4509
|
value: element.placeholder?.text ?? "",
|
|
4245
4510
|
maxLength: 150,
|
|
4511
|
+
placeholder: example,
|
|
4246
4512
|
onChange: (e) => onChange({
|
|
4247
4513
|
...element,
|
|
4248
4514
|
placeholder: e.target.value ? { type: "plain_text", text: e.target.value, emoji: true } : void 0
|
|
@@ -4390,6 +4656,96 @@ function MarkdownEditor({ block, onChange }) {
|
|
|
4390
4656
|
}
|
|
4391
4657
|
);
|
|
4392
4658
|
}
|
|
4659
|
+
var STATUSES = ["pending", "in_progress", "complete", "error"];
|
|
4660
|
+
function PlanEditor({ block, onChange }) {
|
|
4661
|
+
const titleText = typeof block.title === "string" ? block.title : block.title?.text ?? "";
|
|
4662
|
+
const tasks = block.tasks ?? [];
|
|
4663
|
+
const updateTask = (idx, change) => {
|
|
4664
|
+
onChange({
|
|
4665
|
+
...block,
|
|
4666
|
+
tasks: tasks.map((t, i) => i === idx ? { ...t, ...change } : t)
|
|
4667
|
+
});
|
|
4668
|
+
};
|
|
4669
|
+
const removeTask = (idx) => {
|
|
4670
|
+
const next = tasks.filter((_, i) => i !== idx);
|
|
4671
|
+
onChange({ ...block, tasks: next.length > 0 ? next : void 0 });
|
|
4672
|
+
};
|
|
4673
|
+
const addTask = () => {
|
|
4674
|
+
onChange({
|
|
4675
|
+
...block,
|
|
4676
|
+
tasks: [
|
|
4677
|
+
...tasks,
|
|
4678
|
+
{
|
|
4679
|
+
type: "task_card",
|
|
4680
|
+
task_id: `task_${nanoid.nanoid(6)}`,
|
|
4681
|
+
title: "New step",
|
|
4682
|
+
status: "pending"
|
|
4683
|
+
}
|
|
4684
|
+
]
|
|
4685
|
+
});
|
|
4686
|
+
};
|
|
4687
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
4688
|
+
/* @__PURE__ */ jsxRuntime.jsx(EditorField, { label: "Title", help: "Heading shown above the task list.", htmlFor: "plan-title", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4689
|
+
Input,
|
|
4690
|
+
{
|
|
4691
|
+
id: "plan-title",
|
|
4692
|
+
value: titleText,
|
|
4693
|
+
placeholder: "e.g. Investigating the issue",
|
|
4694
|
+
onChange: (e) => onChange({ ...block, title: e.target.value })
|
|
4695
|
+
}
|
|
4696
|
+
) }),
|
|
4697
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 rounded-md border bg-muted/20 p-3", children: [
|
|
4698
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-foreground", children: "Tasks" }),
|
|
4699
|
+
tasks.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "No tasks. Add one to render a checklist beneath the title." }) : null,
|
|
4700
|
+
tasks.map((task, idx) => {
|
|
4701
|
+
const status = task.status ?? "pending";
|
|
4702
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 rounded border bg-background p-2", children: [
|
|
4703
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
4704
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs font-medium text-foreground", children: [
|
|
4705
|
+
"Task ",
|
|
4706
|
+
idx + 1
|
|
4707
|
+
] }),
|
|
4708
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4709
|
+
"button",
|
|
4710
|
+
{
|
|
4711
|
+
type: "button",
|
|
4712
|
+
"aria-label": "Remove task",
|
|
4713
|
+
onClick: () => removeTask(idx),
|
|
4714
|
+
className: "rounded p-1 text-muted-foreground hover:bg-destructive/10 hover:text-destructive",
|
|
4715
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-3.5 w-3.5" })
|
|
4716
|
+
}
|
|
4717
|
+
)
|
|
4718
|
+
] }),
|
|
4719
|
+
/* @__PURE__ */ jsxRuntime.jsx(EditorField, { label: "Title", htmlFor: `plan-task-title-${idx}`, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4720
|
+
Input,
|
|
4721
|
+
{
|
|
4722
|
+
id: `plan-task-title-${idx}`,
|
|
4723
|
+
value: task.title,
|
|
4724
|
+
placeholder: "e.g. Reproduce the error locally",
|
|
4725
|
+
onChange: (e) => updateTask(idx, { title: e.target.value })
|
|
4726
|
+
}
|
|
4727
|
+
) }),
|
|
4728
|
+
/* @__PURE__ */ jsxRuntime.jsx(EditorField, { label: "Status", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4729
|
+
RadioGroup,
|
|
4730
|
+
{
|
|
4731
|
+
value: status,
|
|
4732
|
+
onValueChange: (v) => updateTask(idx, { status: v }),
|
|
4733
|
+
className: "flex flex-row flex-wrap gap-3",
|
|
4734
|
+
children: STATUSES.map((s) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
4735
|
+
/* @__PURE__ */ jsxRuntime.jsx(RadioGroupItem, { value: s, id: `plan-task-status-${idx}-${s}` }),
|
|
4736
|
+
/* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: `plan-task-status-${idx}-${s}`, className: "text-xs capitalize", children: s.replace("_", " ") })
|
|
4737
|
+
] }, s))
|
|
4738
|
+
}
|
|
4739
|
+
) })
|
|
4740
|
+
] }, idx);
|
|
4741
|
+
}),
|
|
4742
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", size: "sm", onClick: addTask, className: "self-start", children: [
|
|
4743
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3.5 w-3.5" }),
|
|
4744
|
+
" Add task"
|
|
4745
|
+
] })
|
|
4746
|
+
] })
|
|
4747
|
+
] });
|
|
4748
|
+
}
|
|
4393
4749
|
|
|
4394
4750
|
// src/lib/rich-text-tiptap.ts
|
|
4395
4751
|
var SUPPORTED_BLOCK_KINDS = /* @__PURE__ */ new Set([
|
|
@@ -5275,8 +5631,8 @@ function LossyBanner({ reasons }) {
|
|
|
5275
5631
|
] });
|
|
5276
5632
|
}
|
|
5277
5633
|
function RichTextWysiwygEditor({ block, onChange }) {
|
|
5278
|
-
const lastEmittedRef =
|
|
5279
|
-
const handleUpdate =
|
|
5634
|
+
const lastEmittedRef = React.useRef(null);
|
|
5635
|
+
const handleUpdate = React.useCallback(
|
|
5280
5636
|
(editor2) => {
|
|
5281
5637
|
const next = proseMirrorToRichText(editor2.getJSON());
|
|
5282
5638
|
lastEmittedRef.current = next;
|
|
@@ -5314,7 +5670,7 @@ function RichTextWysiwygEditor({ block, onChange }) {
|
|
|
5314
5670
|
},
|
|
5315
5671
|
onUpdate: ({ editor: ed }) => handleUpdate(ed)
|
|
5316
5672
|
});
|
|
5317
|
-
|
|
5673
|
+
React.useEffect(() => {
|
|
5318
5674
|
if (!editor) {
|
|
5319
5675
|
return;
|
|
5320
5676
|
}
|
|
@@ -5463,10 +5819,10 @@ function Divider() {
|
|
|
5463
5819
|
function LinkPopover({ editor }) {
|
|
5464
5820
|
const active = editor.isActive("link");
|
|
5465
5821
|
const currentHref = editor.getAttributes("link").href ?? "";
|
|
5466
|
-
const [open, setOpen] =
|
|
5467
|
-
const [url, setUrl] =
|
|
5468
|
-
const [error, setError] =
|
|
5469
|
-
|
|
5822
|
+
const [open, setOpen] = React.useState(false);
|
|
5823
|
+
const [url, setUrl] = React.useState(currentHref);
|
|
5824
|
+
const [error, setError] = React.useState(null);
|
|
5825
|
+
React.useEffect(() => {
|
|
5470
5826
|
if (open) {
|
|
5471
5827
|
setUrl(currentHref);
|
|
5472
5828
|
setError(null);
|
|
@@ -5880,21 +6236,260 @@ function TableEditor({ block, onChange }) {
|
|
|
5880
6236
|
] })
|
|
5881
6237
|
] });
|
|
5882
6238
|
}
|
|
5883
|
-
|
|
5884
|
-
|
|
5885
|
-
|
|
5886
|
-
|
|
5887
|
-
|
|
5888
|
-
|
|
5889
|
-
|
|
5890
|
-
|
|
5891
|
-
|
|
5892
|
-
|
|
5893
|
-
|
|
5894
|
-
|
|
5895
|
-
|
|
5896
|
-
|
|
5897
|
-
|
|
6239
|
+
var STATUSES2 = ["pending", "in_progress", "complete", "error"];
|
|
6240
|
+
function TaskCardEditor({ block, onChange }) {
|
|
6241
|
+
const status = block.status ?? "pending";
|
|
6242
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
6243
|
+
/* @__PURE__ */ jsxRuntime.jsx(EditorField, { label: "Title", help: "Short label shown at the top of the card.", htmlFor: "task-card-title", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6244
|
+
Input,
|
|
6245
|
+
{
|
|
6246
|
+
id: "task-card-title",
|
|
6247
|
+
value: block.title,
|
|
6248
|
+
placeholder: "e.g. Reproduce the bug locally",
|
|
6249
|
+
onChange: (e) => onChange({ ...block, title: e.target.value })
|
|
6250
|
+
}
|
|
6251
|
+
) }),
|
|
6252
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6253
|
+
EditorField,
|
|
6254
|
+
{
|
|
6255
|
+
label: "Task ID",
|
|
6256
|
+
help: "Stable identifier you can reference from interaction payloads.",
|
|
6257
|
+
htmlFor: "task-card-id",
|
|
6258
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6259
|
+
Input,
|
|
6260
|
+
{
|
|
6261
|
+
id: "task-card-id",
|
|
6262
|
+
value: block.task_id,
|
|
6263
|
+
placeholder: "e.g. task_1",
|
|
6264
|
+
onChange: (e) => onChange({ ...block, task_id: e.target.value })
|
|
6265
|
+
}
|
|
6266
|
+
)
|
|
6267
|
+
}
|
|
6268
|
+
),
|
|
6269
|
+
/* @__PURE__ */ jsxRuntime.jsx(EditorField, { label: "Status", help: "Slack renders a matching status chip on the card.", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6270
|
+
RadioGroup,
|
|
6271
|
+
{
|
|
6272
|
+
value: status,
|
|
6273
|
+
onValueChange: (v) => onChange({ ...block, status: v }),
|
|
6274
|
+
className: "flex flex-row flex-wrap gap-3",
|
|
6275
|
+
children: STATUSES2.map((s) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
6276
|
+
/* @__PURE__ */ jsxRuntime.jsx(RadioGroupItem, { value: s, id: `task-card-status-${s}` }),
|
|
6277
|
+
/* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: `task-card-status-${s}`, className: "text-xs capitalize", children: s.replace("_", " ") })
|
|
6278
|
+
] }, s))
|
|
6279
|
+
}
|
|
6280
|
+
) }),
|
|
6281
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6282
|
+
SourcesField,
|
|
6283
|
+
{
|
|
6284
|
+
sources: block.sources ?? [],
|
|
6285
|
+
onChange: (next) => onChange({ ...block, sources: next.length > 0 ? next : void 0 })
|
|
6286
|
+
}
|
|
6287
|
+
)
|
|
6288
|
+
] });
|
|
6289
|
+
}
|
|
6290
|
+
function SourcesField({
|
|
6291
|
+
sources,
|
|
6292
|
+
onChange
|
|
6293
|
+
}) {
|
|
6294
|
+
const update = (idx, change) => {
|
|
6295
|
+
onChange(sources.map((s, i) => i === idx ? { ...s, ...change } : s));
|
|
6296
|
+
};
|
|
6297
|
+
const removeAt = (idx) => onChange(sources.filter((_, i) => i !== idx));
|
|
6298
|
+
const addSource = () => {
|
|
6299
|
+
onChange([...sources, { type: "url", url: "", text: "" }]);
|
|
6300
|
+
};
|
|
6301
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 rounded-md border bg-muted/20 p-3", children: [
|
|
6302
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-foreground", children: "Sources" }),
|
|
6303
|
+
sources.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "No sources. Add one to cite a document or link beneath the card." }) : null,
|
|
6304
|
+
sources.map((src, idx) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 rounded border bg-background p-2", children: [
|
|
6305
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
6306
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs font-medium text-foreground", children: [
|
|
6307
|
+
"Source ",
|
|
6308
|
+
idx + 1
|
|
6309
|
+
] }),
|
|
6310
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6311
|
+
"button",
|
|
6312
|
+
{
|
|
6313
|
+
type: "button",
|
|
6314
|
+
"aria-label": "Remove source",
|
|
6315
|
+
onClick: () => removeAt(idx),
|
|
6316
|
+
className: "rounded p-1 text-muted-foreground hover:bg-destructive/10 hover:text-destructive",
|
|
6317
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-3.5 w-3.5" })
|
|
6318
|
+
}
|
|
6319
|
+
)
|
|
6320
|
+
] }),
|
|
6321
|
+
/* @__PURE__ */ jsxRuntime.jsx(EditorField, { label: "Label", htmlFor: `task-card-source-text-${idx}`, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6322
|
+
Input,
|
|
6323
|
+
{
|
|
6324
|
+
id: `task-card-source-text-${idx}`,
|
|
6325
|
+
value: src.text,
|
|
6326
|
+
placeholder: "e.g. Runbook",
|
|
6327
|
+
onChange: (e) => update(idx, { text: e.target.value })
|
|
6328
|
+
}
|
|
6329
|
+
) }),
|
|
6330
|
+
/* @__PURE__ */ jsxRuntime.jsx(EditorField, { label: "URL", htmlFor: `task-card-source-url-${idx}`, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6331
|
+
Input,
|
|
6332
|
+
{
|
|
6333
|
+
id: `task-card-source-url-${idx}`,
|
|
6334
|
+
type: "url",
|
|
6335
|
+
value: src.url,
|
|
6336
|
+
placeholder: "e.g. https://example.com/runbook",
|
|
6337
|
+
onChange: (e) => update(idx, { url: e.target.value })
|
|
6338
|
+
}
|
|
6339
|
+
) })
|
|
6340
|
+
] }, idx)),
|
|
6341
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", size: "sm", onClick: addSource, className: "self-start", children: [
|
|
6342
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3.5 w-3.5" }),
|
|
6343
|
+
" Add source"
|
|
6344
|
+
] })
|
|
6345
|
+
] });
|
|
6346
|
+
}
|
|
6347
|
+
function VideoEditor({ block, onChange }) {
|
|
6348
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
6349
|
+
/* @__PURE__ */ jsxRuntime.jsx(EditorField, { label: "Title", help: "Up to 199 characters. Shown above the embedded player.", htmlFor: "video-title", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6350
|
+
Input,
|
|
6351
|
+
{
|
|
6352
|
+
id: "video-title",
|
|
6353
|
+
value: block.title?.text ?? "",
|
|
6354
|
+
maxLength: 199,
|
|
6355
|
+
placeholder: "e.g. Product demo",
|
|
6356
|
+
onChange: (e) => onChange({
|
|
6357
|
+
...block,
|
|
6358
|
+
title: { type: "plain_text", text: e.target.value, emoji: true }
|
|
6359
|
+
})
|
|
6360
|
+
}
|
|
6361
|
+
) }),
|
|
6362
|
+
/* @__PURE__ */ jsxRuntime.jsx(EditorField, { label: "Alt text", help: "Tooltip for the video. Required for accessibility.", htmlFor: "video-alt", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6363
|
+
Input,
|
|
6364
|
+
{
|
|
6365
|
+
id: "video-alt",
|
|
6366
|
+
value: block.alt_text ?? "",
|
|
6367
|
+
placeholder: "e.g. A short walkthrough of the new release",
|
|
6368
|
+
onChange: (e) => onChange({ ...block, alt_text: e.target.value })
|
|
6369
|
+
}
|
|
6370
|
+
) }),
|
|
6371
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6372
|
+
EditorField,
|
|
6373
|
+
{
|
|
6374
|
+
label: "Video URL",
|
|
6375
|
+
help: "HTTPS embed URL. Must match an unfurl domain on your Slack app.",
|
|
6376
|
+
htmlFor: "video-url",
|
|
6377
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6378
|
+
Input,
|
|
6379
|
+
{
|
|
6380
|
+
id: "video-url",
|
|
6381
|
+
type: "url",
|
|
6382
|
+
value: block.video_url ?? "",
|
|
6383
|
+
placeholder: "e.g. https://www.youtube.com/embed/dQw4w9WgXcQ",
|
|
6384
|
+
onChange: (e) => onChange({ ...block, video_url: e.target.value })
|
|
6385
|
+
}
|
|
6386
|
+
)
|
|
6387
|
+
}
|
|
6388
|
+
),
|
|
6389
|
+
/* @__PURE__ */ jsxRuntime.jsx(EditorField, { label: "Thumbnail URL", help: "Preview image shown before the video loads.", htmlFor: "video-thumbnail", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6390
|
+
Input,
|
|
6391
|
+
{
|
|
6392
|
+
id: "video-thumbnail",
|
|
6393
|
+
type: "url",
|
|
6394
|
+
value: block.thumbnail_url ?? "",
|
|
6395
|
+
placeholder: "e.g. https://example.com/thumb.png",
|
|
6396
|
+
onChange: (e) => onChange({ ...block, thumbnail_url: e.target.value })
|
|
6397
|
+
}
|
|
6398
|
+
) }),
|
|
6399
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6400
|
+
EditorField,
|
|
6401
|
+
{
|
|
6402
|
+
label: "Title link URL",
|
|
6403
|
+
help: "Optional. HTTPS link the title text opens (the non-embed page).",
|
|
6404
|
+
htmlFor: "video-title-url",
|
|
6405
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6406
|
+
Input,
|
|
6407
|
+
{
|
|
6408
|
+
id: "video-title-url",
|
|
6409
|
+
type: "url",
|
|
6410
|
+
value: block.title_url ?? "",
|
|
6411
|
+
placeholder: "e.g. https://www.youtube.com/watch?v=dQw4w9WgXcQ",
|
|
6412
|
+
onChange: (e) => onChange({ ...block, title_url: e.target.value || void 0 })
|
|
6413
|
+
}
|
|
6414
|
+
)
|
|
6415
|
+
}
|
|
6416
|
+
),
|
|
6417
|
+
/* @__PURE__ */ jsxRuntime.jsx(EditorField, { label: "Description", help: "Optional. Up to 199 characters.", htmlFor: "video-description", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6418
|
+
Textarea,
|
|
6419
|
+
{
|
|
6420
|
+
id: "video-description",
|
|
6421
|
+
value: block.description?.text ?? "",
|
|
6422
|
+
maxLength: 199,
|
|
6423
|
+
rows: 2,
|
|
6424
|
+
placeholder: "e.g. A short walkthrough of the new release.",
|
|
6425
|
+
onChange: (e) => onChange({
|
|
6426
|
+
...block,
|
|
6427
|
+
description: e.target.value ? { type: "plain_text", text: e.target.value, emoji: true } : void 0
|
|
6428
|
+
})
|
|
6429
|
+
}
|
|
6430
|
+
) }),
|
|
6431
|
+
/* @__PURE__ */ jsxRuntime.jsx(EditorField, { label: "Author name", help: "Optional. Up to 49 characters.", htmlFor: "video-author", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6432
|
+
Input,
|
|
6433
|
+
{
|
|
6434
|
+
id: "video-author",
|
|
6435
|
+
value: block.author_name ?? "",
|
|
6436
|
+
maxLength: 49,
|
|
6437
|
+
placeholder: "e.g. Acme",
|
|
6438
|
+
onChange: (e) => onChange({ ...block, author_name: e.target.value || void 0 })
|
|
6439
|
+
}
|
|
6440
|
+
) }),
|
|
6441
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6442
|
+
EditorField,
|
|
6443
|
+
{
|
|
6444
|
+
label: "Provider name",
|
|
6445
|
+
help: "Optional. Originating service (e.g. YouTube, Vimeo).",
|
|
6446
|
+
htmlFor: "video-provider-name",
|
|
6447
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6448
|
+
Input,
|
|
6449
|
+
{
|
|
6450
|
+
id: "video-provider-name",
|
|
6451
|
+
value: block.provider_name ?? "",
|
|
6452
|
+
placeholder: "e.g. YouTube",
|
|
6453
|
+
onChange: (e) => onChange({ ...block, provider_name: e.target.value || void 0 })
|
|
6454
|
+
}
|
|
6455
|
+
)
|
|
6456
|
+
}
|
|
6457
|
+
),
|
|
6458
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6459
|
+
EditorField,
|
|
6460
|
+
{
|
|
6461
|
+
label: "Provider icon URL",
|
|
6462
|
+
help: "Optional. Small icon shown next to the provider name.",
|
|
6463
|
+
htmlFor: "video-provider-icon",
|
|
6464
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6465
|
+
Input,
|
|
6466
|
+
{
|
|
6467
|
+
id: "video-provider-icon",
|
|
6468
|
+
type: "url",
|
|
6469
|
+
value: block.provider_icon_url ?? "",
|
|
6470
|
+
placeholder: "e.g. https://example.com/youtube-favicon.png",
|
|
6471
|
+
onChange: (e) => onChange({ ...block, provider_icon_url: e.target.value || void 0 })
|
|
6472
|
+
}
|
|
6473
|
+
)
|
|
6474
|
+
}
|
|
6475
|
+
)
|
|
6476
|
+
] });
|
|
6477
|
+
}
|
|
6478
|
+
function BlockEditor({
|
|
6479
|
+
block,
|
|
6480
|
+
errors,
|
|
6481
|
+
onChange
|
|
6482
|
+
}) {
|
|
6483
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
6484
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs("h3", { className: "text-sm font-semibold text-foreground", children: [
|
|
6485
|
+
"Edit ",
|
|
6486
|
+
labelForBlockType(block.type)
|
|
6487
|
+
] }) }),
|
|
6488
|
+
errors && errors.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "flex flex-col gap-0.5 rounded-md border border-destructive/30 bg-destructive/5 p-2 text-xs text-destructive", children: errors.map((err, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: err }, i)) }) : null,
|
|
6489
|
+
dispatch(block, onChange)
|
|
6490
|
+
] });
|
|
6491
|
+
}
|
|
6492
|
+
function dispatch(block, onChange) {
|
|
5898
6493
|
switch (block.type) {
|
|
5899
6494
|
case "section":
|
|
5900
6495
|
return /* @__PURE__ */ jsxRuntime.jsx(SectionEditor, { block, onChange: (next) => onChange(next) });
|
|
@@ -5924,6 +6519,12 @@ function dispatch(block, onChange) {
|
|
|
5924
6519
|
return /* @__PURE__ */ jsxRuntime.jsx(ContextActionsEditor, { block, onChange: (next) => onChange(next) });
|
|
5925
6520
|
case "input":
|
|
5926
6521
|
return /* @__PURE__ */ jsxRuntime.jsx(InputEditor, { block, onChange: (next) => onChange(next) });
|
|
6522
|
+
case "video":
|
|
6523
|
+
return /* @__PURE__ */ jsxRuntime.jsx(VideoEditor, { block, onChange: (next) => onChange(next) });
|
|
6524
|
+
case "plan":
|
|
6525
|
+
return /* @__PURE__ */ jsxRuntime.jsx(PlanEditor, { block, onChange: (next) => onChange(next) });
|
|
6526
|
+
case "task_card":
|
|
6527
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TaskCardEditor, { block, onChange: (next) => onChange(next) });
|
|
5927
6528
|
default:
|
|
5928
6529
|
return null;
|
|
5929
6530
|
}
|
|
@@ -5933,9 +6534,9 @@ function SlackBlockPreview({
|
|
|
5933
6534
|
hooks,
|
|
5934
6535
|
theme = "light"
|
|
5935
6536
|
}) {
|
|
5936
|
-
const rootRef =
|
|
5937
|
-
const safeBlock =
|
|
5938
|
-
|
|
6537
|
+
const rootRef = React.useRef(null);
|
|
6538
|
+
const safeBlock = React.useMemo(() => sanitizeBlock(block), [block]);
|
|
6539
|
+
React.useEffect(() => {
|
|
5939
6540
|
const root = rootRef.current;
|
|
5940
6541
|
if (!root) return;
|
|
5941
6542
|
for (const wrapper of root.querySelectorAll(
|
|
@@ -5996,7 +6597,10 @@ var BLOCK_TYPE_LABELS = {
|
|
|
5996
6597
|
card: "Card",
|
|
5997
6598
|
carousel: "Carousel",
|
|
5998
6599
|
context_actions: "Context Actions",
|
|
5999
|
-
input: "Input"
|
|
6600
|
+
input: "Input",
|
|
6601
|
+
video: "Video",
|
|
6602
|
+
plan: "Plan",
|
|
6603
|
+
task_card: "Task Card"
|
|
6000
6604
|
};
|
|
6001
6605
|
function BlockRow({
|
|
6002
6606
|
builderBlock,
|
|
@@ -6008,6 +6612,9 @@ function BlockRow({
|
|
|
6008
6612
|
onUpdate,
|
|
6009
6613
|
onDuplicate,
|
|
6010
6614
|
onDelete,
|
|
6615
|
+
index,
|
|
6616
|
+
total,
|
|
6617
|
+
onReorder,
|
|
6011
6618
|
isPaletteDrag = false
|
|
6012
6619
|
}) {
|
|
6013
6620
|
const { attributes, listeners, setNodeRef, transform, transition, isDragging, isOver } = sortable.useSortable({
|
|
@@ -6020,154 +6627,253 @@ function BlockRow({
|
|
|
6020
6627
|
};
|
|
6021
6628
|
const hasErrors = !!errors && errors.length > 0;
|
|
6022
6629
|
const isRichText = builderBlock.block.type === "rich_text";
|
|
6023
|
-
const [inlineEditing, setInlineEditing] =
|
|
6630
|
+
const [inlineEditing, setInlineEditing] = React.useState(false);
|
|
6024
6631
|
const showDropIndicator = isPaletteDrag && isOver;
|
|
6025
6632
|
const preview = /* @__PURE__ */ jsxRuntime.jsx(SlackBlockPreview, { block: builderBlock.block, hooks: previewHooks, theme: previewTheme });
|
|
6026
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6027
|
-
|
|
6028
|
-
|
|
6029
|
-
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
|
|
6034
|
-
) : null,
|
|
6035
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full", children: [
|
|
6036
|
-
isRichText && inlineEditing ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6037
|
-
RichTextInlineEditor,
|
|
6038
|
-
{
|
|
6039
|
-
block: builderBlock.block,
|
|
6040
|
-
onSave: (next) => {
|
|
6041
|
-
onUpdate(builderBlock.id, next);
|
|
6042
|
-
setInlineEditing(false);
|
|
6043
|
-
},
|
|
6044
|
-
onCancel: () => setInlineEditing(false)
|
|
6045
|
-
}
|
|
6046
|
-
) : isRichText ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6047
|
-
"button",
|
|
6048
|
-
{
|
|
6049
|
-
type: "button",
|
|
6050
|
-
"aria-label": "Edit block",
|
|
6051
|
-
onClick: () => setInlineEditing(true),
|
|
6052
|
-
...attributes,
|
|
6053
|
-
...listeners,
|
|
6054
|
-
className: cn(
|
|
6055
|
-
"block w-full cursor-grab rounded-sm border-0 bg-transparent p-0 text-left transition-shadow hover:shadow-md focus-visible:ring-1 focus-visible:ring-ring active:cursor-grabbing",
|
|
6056
|
-
hasErrors ? "ring-1 ring-destructive/60 hover:ring-destructive" : "hover:ring-1 hover:ring-border"
|
|
6057
|
-
),
|
|
6058
|
-
children: preview
|
|
6059
|
-
}
|
|
6060
|
-
) : /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: isOpen, onOpenChange, children: [
|
|
6061
|
-
/* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6633
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6634
|
+
"div",
|
|
6635
|
+
{
|
|
6636
|
+
ref: setNodeRef,
|
|
6637
|
+
style,
|
|
6638
|
+
className: cn("group relative mb-2 last:mb-0 hover:z-10 md:mb-0", isDragging && "opacity-40"),
|
|
6639
|
+
children: [
|
|
6640
|
+
showDropIndicator ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6062
6641
|
"div",
|
|
6063
6642
|
{
|
|
6064
|
-
|
|
6065
|
-
|
|
6066
|
-
"
|
|
6067
|
-
...sortableA11yAttrs,
|
|
6068
|
-
...listeners,
|
|
6069
|
-
className: cn(
|
|
6070
|
-
"block w-full cursor-grab rounded-sm transition-shadow hover:shadow-md focus-visible:ring-1 focus-visible:ring-ring active:cursor-grabbing",
|
|
6071
|
-
hasErrors ? "ring-1 ring-destructive/60 hover:ring-destructive" : "hover:ring-1 hover:ring-border"
|
|
6072
|
-
),
|
|
6073
|
-
children: preview
|
|
6643
|
+
"aria-hidden": "true",
|
|
6644
|
+
className: "-top-1 pointer-events-none absolute right-0 left-0 z-20 h-0.5 rounded-full bg-primary",
|
|
6645
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "-left-1 -top-[3px] absolute h-2 w-2 rounded-full bg-primary shadow-[0_0_0_2px_var(--color-background)]" })
|
|
6074
6646
|
}
|
|
6075
|
-
)
|
|
6076
|
-
/* @__PURE__ */ jsxRuntime.
|
|
6077
|
-
|
|
6078
|
-
|
|
6079
|
-
|
|
6080
|
-
|
|
6081
|
-
|
|
6082
|
-
|
|
6083
|
-
|
|
6084
|
-
|
|
6085
|
-
|
|
6086
|
-
|
|
6087
|
-
|
|
6088
|
-
|
|
6089
|
-
|
|
6090
|
-
|
|
6091
|
-
|
|
6092
|
-
|
|
6093
|
-
|
|
6094
|
-
|
|
6095
|
-
|
|
6096
|
-
"
|
|
6097
|
-
|
|
6098
|
-
|
|
6099
|
-
|
|
6100
|
-
|
|
6101
|
-
|
|
6102
|
-
|
|
6103
|
-
|
|
6104
|
-
|
|
6105
|
-
|
|
6106
|
-
|
|
6107
|
-
|
|
6108
|
-
|
|
6109
|
-
|
|
6110
|
-
|
|
6111
|
-
|
|
6112
|
-
|
|
6113
|
-
|
|
6114
|
-
|
|
6115
|
-
|
|
6116
|
-
|
|
6117
|
-
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
6121
|
-
|
|
6122
|
-
|
|
6123
|
-
|
|
6124
|
-
|
|
6647
|
+
) : null,
|
|
6648
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full", children: [
|
|
6649
|
+
isRichText && inlineEditing ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6650
|
+
RichTextInlineEditor,
|
|
6651
|
+
{
|
|
6652
|
+
block: builderBlock.block,
|
|
6653
|
+
onSave: (next) => {
|
|
6654
|
+
onUpdate(builderBlock.id, next);
|
|
6655
|
+
setInlineEditing(false);
|
|
6656
|
+
},
|
|
6657
|
+
onCancel: () => setInlineEditing(false)
|
|
6658
|
+
}
|
|
6659
|
+
) : isRichText ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6660
|
+
"button",
|
|
6661
|
+
{
|
|
6662
|
+
type: "button",
|
|
6663
|
+
"aria-label": "Edit block",
|
|
6664
|
+
onClick: () => setInlineEditing(true),
|
|
6665
|
+
...attributes,
|
|
6666
|
+
...listeners,
|
|
6667
|
+
className: cn(
|
|
6668
|
+
"block w-full cursor-grab rounded-sm border-0 bg-transparent p-0 text-left transition-shadow hover:shadow-md focus-visible:ring-1 focus-visible:ring-ring active:cursor-grabbing",
|
|
6669
|
+
hasErrors ? "ring-1 ring-destructive/60 hover:ring-destructive" : "hover:ring-1 hover:ring-border"
|
|
6670
|
+
),
|
|
6671
|
+
children: preview
|
|
6672
|
+
}
|
|
6673
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: isOpen, onOpenChange, children: [
|
|
6674
|
+
/* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6675
|
+
"div",
|
|
6676
|
+
{
|
|
6677
|
+
role: "button",
|
|
6678
|
+
tabIndex: 0,
|
|
6679
|
+
"aria-label": "Edit block",
|
|
6680
|
+
...sortableA11yAttrs,
|
|
6681
|
+
...listeners,
|
|
6682
|
+
onKeyDown: (e) => {
|
|
6683
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
6684
|
+
e.preventDefault();
|
|
6685
|
+
onOpenChange?.(!isOpen);
|
|
6686
|
+
}
|
|
6687
|
+
},
|
|
6688
|
+
className: cn(
|
|
6689
|
+
"block w-full cursor-grab rounded-sm transition-shadow hover:shadow-md focus-visible:ring-1 focus-visible:ring-ring active:cursor-grabbing",
|
|
6690
|
+
hasErrors ? "ring-1 ring-destructive/60 hover:ring-destructive" : "hover:ring-1 hover:ring-border"
|
|
6691
|
+
),
|
|
6692
|
+
children: preview
|
|
6693
|
+
}
|
|
6694
|
+
) }),
|
|
6695
|
+
/* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { className: "w-[min(32rem,calc(100vw-1.5rem))] sm:w-[32rem]", align: "start", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6696
|
+
BlockEditor,
|
|
6697
|
+
{
|
|
6698
|
+
block: builderBlock.block,
|
|
6699
|
+
errors,
|
|
6700
|
+
onChange: (next) => onUpdate(builderBlock.id, next)
|
|
6701
|
+
}
|
|
6702
|
+
) })
|
|
6703
|
+
] }),
|
|
6704
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "-translate-x-1/2 pointer-events-none absolute bottom-full left-1/2 z-10 hidden bg-background px-1.5 text-[11px] text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100 md:block", children: BLOCK_TYPE_LABELS[builderBlock.block.type] }),
|
|
6705
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
6706
|
+
"div",
|
|
6707
|
+
{
|
|
6708
|
+
className: cn(
|
|
6709
|
+
// Hidden on mobile in favor of the inline row below; on desktop
|
|
6710
|
+
// reveal on hover, on focus inside the row (so Tab-stops on the
|
|
6711
|
+
// floating buttons themselves keep them visible), and when there
|
|
6712
|
+
// are validation errors worth surfacing immediately.
|
|
6713
|
+
"absolute -top-3 right-2 z-10 hidden items-center gap-0.5 rounded-md border bg-background p-0.5 shadow-sm transition-opacity md:flex",
|
|
6714
|
+
hasErrors ? "opacity-100" : "opacity-0 group-hover:opacity-100 group-focus-within:opacity-100"
|
|
6715
|
+
),
|
|
6716
|
+
children: [
|
|
6717
|
+
hasErrors ? /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
6718
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6719
|
+
"button",
|
|
6720
|
+
{
|
|
6721
|
+
type: "button",
|
|
6722
|
+
"aria-label": `Show ${errors.length} validation ${errors.length === 1 ? "issue" : "issues"}`,
|
|
6723
|
+
onClick: () => onOpenChange?.(true),
|
|
6724
|
+
className: "flex h-6 w-6 items-center justify-center rounded text-destructive hover:bg-destructive/10 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
6725
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-3.5 w-3.5" })
|
|
6125
6726
|
}
|
|
6126
|
-
},
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
|
|
6130
|
-
|
|
6131
|
-
|
|
6132
|
-
|
|
6133
|
-
|
|
6134
|
-
|
|
6135
|
-
|
|
6136
|
-
{
|
|
6137
|
-
|
|
6138
|
-
|
|
6139
|
-
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
|
|
6145
|
-
|
|
6146
|
-
|
|
6147
|
-
|
|
6148
|
-
|
|
6149
|
-
|
|
6150
|
-
|
|
6151
|
-
|
|
6152
|
-
|
|
6153
|
-
|
|
6154
|
-
|
|
6155
|
-
|
|
6156
|
-
|
|
6157
|
-
|
|
6158
|
-
|
|
6159
|
-
|
|
6160
|
-
|
|
6161
|
-
|
|
6162
|
-
|
|
6163
|
-
|
|
6727
|
+
) }),
|
|
6728
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", align: "end", children: /* @__PURE__ */ jsxRuntime.jsxs("ul", { className: "flex flex-col gap-0.5", children: [
|
|
6729
|
+
errors.slice(0, 4).map((err, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: err }, i)),
|
|
6730
|
+
errors.length > 4 ? /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "text-muted-foreground", children: [
|
|
6731
|
+
"and ",
|
|
6732
|
+
errors.length - 4,
|
|
6733
|
+
" more"
|
|
6734
|
+
] }) : null
|
|
6735
|
+
] }) })
|
|
6736
|
+
] }) : null,
|
|
6737
|
+
onReorder && typeof index === "number" && typeof total === "number" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
6738
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
6739
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6740
|
+
"button",
|
|
6741
|
+
{
|
|
6742
|
+
type: "button",
|
|
6743
|
+
"aria-label": "Move block up",
|
|
6744
|
+
disabled: index === 0,
|
|
6745
|
+
onClick: () => onReorder(builderBlock.id, index - 1),
|
|
6746
|
+
className: "flex h-6 w-6 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:bg-transparent disabled:hover:text-muted-foreground",
|
|
6747
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, { className: "h-3.5 w-3.5" })
|
|
6748
|
+
}
|
|
6749
|
+
) }),
|
|
6750
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", children: "Move up" })
|
|
6751
|
+
] }),
|
|
6752
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
6753
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6754
|
+
"button",
|
|
6755
|
+
{
|
|
6756
|
+
type: "button",
|
|
6757
|
+
"aria-label": "Move block down",
|
|
6758
|
+
disabled: index >= total - 1,
|
|
6759
|
+
onClick: () => onReorder(builderBlock.id, index + 1),
|
|
6760
|
+
className: "flex h-6 w-6 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:bg-transparent disabled:hover:text-muted-foreground",
|
|
6761
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDown, { className: "h-3.5 w-3.5" })
|
|
6762
|
+
}
|
|
6763
|
+
) }),
|
|
6764
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", children: "Move down" })
|
|
6765
|
+
] })
|
|
6766
|
+
] }) : null,
|
|
6767
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
6768
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6769
|
+
"button",
|
|
6770
|
+
{
|
|
6771
|
+
type: "button",
|
|
6772
|
+
"aria-label": "Edit block",
|
|
6773
|
+
onClick: () => {
|
|
6774
|
+
if (isRichText) {
|
|
6775
|
+
setInlineEditing(true);
|
|
6776
|
+
} else {
|
|
6777
|
+
onOpenChange?.(true);
|
|
6778
|
+
}
|
|
6779
|
+
},
|
|
6780
|
+
className: "flex h-6 w-6 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
6781
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "h-3.5 w-3.5" })
|
|
6782
|
+
}
|
|
6783
|
+
) }),
|
|
6784
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", children: "Edit" })
|
|
6785
|
+
] }),
|
|
6786
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
6787
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6788
|
+
"button",
|
|
6789
|
+
{
|
|
6790
|
+
type: "button",
|
|
6791
|
+
"aria-label": "Duplicate block",
|
|
6792
|
+
onClick: () => onDuplicate(builderBlock.id),
|
|
6793
|
+
className: "flex h-6 w-6 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
6794
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { className: "h-3.5 w-3.5" })
|
|
6795
|
+
}
|
|
6796
|
+
) }),
|
|
6797
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", children: "Duplicate" })
|
|
6798
|
+
] }),
|
|
6799
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
6800
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6801
|
+
"button",
|
|
6802
|
+
{
|
|
6803
|
+
type: "button",
|
|
6804
|
+
"aria-label": "Delete block",
|
|
6805
|
+
onClick: () => onDelete(builderBlock.id),
|
|
6806
|
+
className: "flex h-6 w-6 items-center justify-center rounded text-muted-foreground hover:bg-destructive/10 hover:text-destructive focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
6807
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-3.5 w-3.5" })
|
|
6808
|
+
}
|
|
6809
|
+
) }),
|
|
6810
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", children: "Delete" })
|
|
6811
|
+
] })
|
|
6812
|
+
]
|
|
6813
|
+
}
|
|
6814
|
+
)
|
|
6815
|
+
] }),
|
|
6816
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1 flex items-center justify-between gap-2 rounded-md border border-dashed bg-muted/40 px-2 py-1 md:hidden", children: [
|
|
6817
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-[11px] font-medium text-muted-foreground", children: BLOCK_TYPE_LABELS[builderBlock.block.type] }),
|
|
6818
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
6819
|
+
hasErrors ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6820
|
+
"button",
|
|
6821
|
+
{
|
|
6822
|
+
type: "button",
|
|
6823
|
+
"aria-label": `Show ${errors.length} validation ${errors.length === 1 ? "issue" : "issues"}`,
|
|
6824
|
+
onClick: () => onOpenChange?.(true),
|
|
6825
|
+
className: "flex h-9 w-9 items-center justify-center rounded text-destructive hover:bg-destructive/10",
|
|
6826
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-4 w-4" })
|
|
6827
|
+
}
|
|
6828
|
+
) : null,
|
|
6829
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6830
|
+
"button",
|
|
6831
|
+
{
|
|
6832
|
+
type: "button",
|
|
6833
|
+
"aria-label": "Edit block",
|
|
6834
|
+
onClick: () => {
|
|
6835
|
+
if (isRichText) {
|
|
6836
|
+
setInlineEditing(true);
|
|
6837
|
+
} else {
|
|
6838
|
+
onOpenChange?.(true);
|
|
6839
|
+
}
|
|
6840
|
+
},
|
|
6841
|
+
className: "flex h-9 w-9 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground",
|
|
6842
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "h-4 w-4" })
|
|
6843
|
+
}
|
|
6844
|
+
),
|
|
6845
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6846
|
+
"button",
|
|
6847
|
+
{
|
|
6848
|
+
type: "button",
|
|
6849
|
+
"aria-label": "Duplicate block",
|
|
6850
|
+
onClick: () => onDuplicate(builderBlock.id),
|
|
6851
|
+
className: "flex h-9 w-9 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground",
|
|
6852
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { className: "h-4 w-4" })
|
|
6853
|
+
}
|
|
6854
|
+
),
|
|
6855
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6856
|
+
"button",
|
|
6857
|
+
{
|
|
6858
|
+
type: "button",
|
|
6859
|
+
"aria-label": "Delete block",
|
|
6860
|
+
onClick: () => onDelete(builderBlock.id),
|
|
6861
|
+
className: "flex h-9 w-9 items-center justify-center rounded text-muted-foreground hover:bg-destructive/10 hover:text-destructive",
|
|
6862
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-4 w-4" })
|
|
6863
|
+
}
|
|
6864
|
+
)
|
|
6865
|
+
] })
|
|
6866
|
+
] })
|
|
6867
|
+
]
|
|
6868
|
+
}
|
|
6869
|
+
);
|
|
6164
6870
|
}
|
|
6165
6871
|
function RichTextInlineEditor({
|
|
6166
6872
|
block,
|
|
6167
6873
|
onSave,
|
|
6168
6874
|
onCancel
|
|
6169
6875
|
}) {
|
|
6170
|
-
const [draft, setDraft] =
|
|
6876
|
+
const [draft, setDraft] = React.useState(block);
|
|
6171
6877
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6172
6878
|
"div",
|
|
6173
6879
|
{
|
|
@@ -6201,7 +6907,9 @@ function Surface({
|
|
|
6201
6907
|
onUpdate,
|
|
6202
6908
|
onDuplicate,
|
|
6203
6909
|
onDelete,
|
|
6204
|
-
|
|
6910
|
+
onReorder,
|
|
6911
|
+
isPaletteDrag = false,
|
|
6912
|
+
onOpenPalette
|
|
6205
6913
|
}) {
|
|
6206
6914
|
const { setNodeRef, isOver } = core.useDroppable({ id: SURFACE_DROPPABLE_ID });
|
|
6207
6915
|
const isDark = previewTheme === "dark";
|
|
@@ -6211,13 +6919,13 @@ function Surface({
|
|
|
6211
6919
|
{
|
|
6212
6920
|
ref: setNodeRef,
|
|
6213
6921
|
className: cn(
|
|
6214
|
-
"flex min-h-[
|
|
6922
|
+
"flex min-h-[180px] flex-col px-3 py-2 transition-colors sm:min-h-[240px] sm:px-5",
|
|
6215
6923
|
isDark ? "bg-[#1a1d21]" : "bg-white",
|
|
6216
6924
|
isPaletteDrag && (isDark ? "bg-[#22262c] outline-2 outline-primary/40 -outline-offset-2 outline-dashed" : "bg-[#f5f8ff] outline-2 outline-primary/40 -outline-offset-2 outline-dashed"),
|
|
6217
6925
|
isPaletteDrag && isOver && (isDark ? "bg-[#2c3036]" : "bg-[#eaf0ff]")
|
|
6218
6926
|
),
|
|
6219
|
-
children: blocks.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(EmptyState, { isDark, isPaletteDrag, isOver }) : /* @__PURE__ */ jsxRuntime.jsxs(sortable.SortableContext, { items: blocks.map((b) => b.id), strategy: sortable.verticalListSortingStrategy, children: [
|
|
6220
|
-
blocks.map((block) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6927
|
+
children: blocks.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(EmptyState, { isDark, isPaletteDrag, isOver, onOpenPalette }) : /* @__PURE__ */ jsxRuntime.jsxs(sortable.SortableContext, { items: blocks.map((b) => b.id), strategy: sortable.verticalListSortingStrategy, children: [
|
|
6928
|
+
blocks.map((block, idx) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6221
6929
|
BlockRow,
|
|
6222
6930
|
{
|
|
6223
6931
|
builderBlock: block,
|
|
@@ -6229,6 +6937,9 @@ function Surface({
|
|
|
6229
6937
|
onUpdate,
|
|
6230
6938
|
onDuplicate,
|
|
6231
6939
|
onDelete,
|
|
6940
|
+
index: idx,
|
|
6941
|
+
total: blocks.length,
|
|
6942
|
+
onReorder,
|
|
6232
6943
|
isPaletteDrag
|
|
6233
6944
|
},
|
|
6234
6945
|
block.id
|
|
@@ -6237,7 +6948,14 @@ function Surface({
|
|
|
6237
6948
|
] })
|
|
6238
6949
|
}
|
|
6239
6950
|
);
|
|
6240
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6951
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6952
|
+
"main",
|
|
6953
|
+
{
|
|
6954
|
+
"aria-label": "Block preview",
|
|
6955
|
+
className: cn("flex min-w-0 flex-1 flex-col overflow-y-auto bg-muted p-3 sm:p-6"),
|
|
6956
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto w-full max-w-2xl", children: previewSurface === "modal" ? /* @__PURE__ */ jsxRuntime.jsx(ModalFrame, { isDark, children: blocksList }) : previewSurface === "app_home" ? /* @__PURE__ */ jsxRuntime.jsx(AppHomeFrame, { workspaceName, isDark, children: blocksList }) : /* @__PURE__ */ jsxRuntime.jsx(MessageFrame, { workspaceName, isDark, children: blocksList }) })
|
|
6957
|
+
}
|
|
6958
|
+
);
|
|
6241
6959
|
}
|
|
6242
6960
|
function MessageFrame({
|
|
6243
6961
|
workspaceName,
|
|
@@ -6307,13 +7025,12 @@ function ModalFrame({ isDark, children }) {
|
|
|
6307
7025
|
children: [
|
|
6308
7026
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: cn("text-base font-bold", isDark ? "text-white" : "text-[#1d1c1d]"), children: "Modal title" }),
|
|
6309
7027
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6310
|
-
"
|
|
7028
|
+
"span",
|
|
6311
7029
|
{
|
|
6312
|
-
|
|
6313
|
-
"aria-label": "Close",
|
|
7030
|
+
"aria-hidden": "true",
|
|
6314
7031
|
className: cn(
|
|
6315
7032
|
"flex h-6 w-6 items-center justify-center rounded",
|
|
6316
|
-
isDark ? "text-white/60
|
|
7033
|
+
isDark ? "text-white/60" : "text-[#616061]"
|
|
6317
7034
|
),
|
|
6318
7035
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" })
|
|
6319
7036
|
}
|
|
@@ -6325,30 +7042,23 @@ function ModalFrame({ isDark, children }) {
|
|
|
6325
7042
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
6326
7043
|
"div",
|
|
6327
7044
|
{
|
|
7045
|
+
"aria-hidden": "true",
|
|
6328
7046
|
className: cn(
|
|
6329
7047
|
"flex items-center justify-end gap-2 border-t px-5 py-3",
|
|
6330
7048
|
isDark ? "border-[#2c2d30]" : "border-[#e8e8e8]"
|
|
6331
7049
|
),
|
|
6332
7050
|
children: [
|
|
6333
7051
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6334
|
-
"
|
|
7052
|
+
"span",
|
|
6335
7053
|
{
|
|
6336
|
-
type: "button",
|
|
6337
7054
|
className: cn(
|
|
6338
|
-
"
|
|
6339
|
-
isDark ? "border-white/20 bg-transparent text-white
|
|
7055
|
+
"rounded-sm border px-3 py-1.5 text-sm font-medium",
|
|
7056
|
+
isDark ? "border-white/20 bg-transparent text-white" : "border-[#e8e8e8] bg-white text-[#1d1c1d]"
|
|
6340
7057
|
),
|
|
6341
7058
|
children: "Cancel"
|
|
6342
7059
|
}
|
|
6343
7060
|
),
|
|
6344
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6345
|
-
"button",
|
|
6346
|
-
{
|
|
6347
|
-
type: "button",
|
|
6348
|
-
className: "cursor-pointer rounded-sm bg-[#007a5a] px-3 py-1.5 text-sm font-bold text-white hover:bg-[#148567]",
|
|
6349
|
-
children: "Submit"
|
|
6350
|
-
}
|
|
6351
|
-
)
|
|
7061
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded-sm bg-[#007a5a] px-3 py-1.5 text-sm font-bold text-white", children: "Submit" })
|
|
6352
7062
|
]
|
|
6353
7063
|
}
|
|
6354
7064
|
)
|
|
@@ -6417,7 +7127,12 @@ function AppHomeFrame({
|
|
|
6417
7127
|
}
|
|
6418
7128
|
);
|
|
6419
7129
|
}
|
|
6420
|
-
function EmptyState({
|
|
7130
|
+
function EmptyState({
|
|
7131
|
+
isDark,
|
|
7132
|
+
isPaletteDrag,
|
|
7133
|
+
isOver,
|
|
7134
|
+
onOpenPalette
|
|
7135
|
+
}) {
|
|
6421
7136
|
const active = isPaletteDrag && isOver;
|
|
6422
7137
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6423
7138
|
"div",
|
|
@@ -6437,7 +7152,7 @@ function EmptyState({ isDark, isPaletteDrag, isOver }) {
|
|
|
6437
7152
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.LayoutGrid, { className: "h-6 w-6" })
|
|
6438
7153
|
}
|
|
6439
7154
|
),
|
|
6440
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-
|
|
7155
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
6441
7156
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6442
7157
|
"p",
|
|
6443
7158
|
{
|
|
@@ -6448,8 +7163,23 @@ function EmptyState({ isDark, isPaletteDrag, isOver }) {
|
|
|
6448
7163
|
children: active ? "Drop to add block" : "Start adding blocks!"
|
|
6449
7164
|
}
|
|
6450
7165
|
),
|
|
6451
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs", children: active ? "Release to insert it here." :
|
|
6452
|
-
|
|
7166
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs", children: active ? "Release to insert it here." : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
7167
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden md:inline", children: "Drag a block from the left, or click one to add it here." }),
|
|
7168
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "md:hidden", children: "Tap \u201CAdd a block\u201D below to get started." })
|
|
7169
|
+
] }) })
|
|
7170
|
+
] }),
|
|
7171
|
+
!active && onOpenPalette ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7172
|
+
"button",
|
|
7173
|
+
{
|
|
7174
|
+
type: "button",
|
|
7175
|
+
onClick: onOpenPalette,
|
|
7176
|
+
className: "inline-flex min-h-11 items-center gap-2 rounded-full bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground shadow-sm transition-colors hover:bg-primary/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring md:hidden",
|
|
7177
|
+
children: [
|
|
7178
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4" }),
|
|
7179
|
+
"Add a block"
|
|
7180
|
+
]
|
|
7181
|
+
}
|
|
7182
|
+
) : null
|
|
6453
7183
|
]
|
|
6454
7184
|
}
|
|
6455
7185
|
);
|
|
@@ -6473,6 +7203,7 @@ function Toolbar2({
|
|
|
6473
7203
|
onOpenJson,
|
|
6474
7204
|
onOpenIssues,
|
|
6475
7205
|
onOpenSend,
|
|
7206
|
+
onOpenPalette,
|
|
6476
7207
|
canSend,
|
|
6477
7208
|
canClear,
|
|
6478
7209
|
previewTheme,
|
|
@@ -6490,61 +7221,63 @@ function Toolbar2({
|
|
|
6490
7221
|
const showSurfaceControl = surfaceOptions.length > 1;
|
|
6491
7222
|
const docsHref = docsLink === false ? null : docsLink?.href ?? DEFAULT_DOCS_HREF;
|
|
6492
7223
|
const docsLabel = docsLink === false ? null : docsLink?.label ?? DEFAULT_DOCS_LABEL;
|
|
6493
|
-
|
|
6494
|
-
|
|
6495
|
-
|
|
6496
|
-
|
|
7224
|
+
const [surfaceMenuOpen, setSurfaceMenuOpen] = React.useState(false);
|
|
7225
|
+
const [themeMenuOpen, setThemeMenuOpen] = React.useState(false);
|
|
7226
|
+
const [moreMenuOpen, setMoreMenuOpen] = React.useState(false);
|
|
7227
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-between gap-x-2 gap-y-1 border-b bg-background px-2 py-1.5 sm:px-3 sm:py-2", children: [
|
|
7228
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-1 sm:gap-2", children: [
|
|
7229
|
+
onOpenPalette ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7230
|
+
Button,
|
|
7231
|
+
{
|
|
7232
|
+
type: "button",
|
|
7233
|
+
variant: "ghost",
|
|
7234
|
+
size: "sm",
|
|
7235
|
+
onClick: onOpenPalette,
|
|
7236
|
+
className: "md:hidden",
|
|
7237
|
+
"aria-label": "Add a block",
|
|
7238
|
+
children: [
|
|
7239
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4" }),
|
|
7240
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Blocks" })
|
|
7241
|
+
]
|
|
7242
|
+
}
|
|
7243
|
+
) : null,
|
|
7244
|
+
showSurfaceControl ? /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: surfaceMenuOpen, onOpenChange: setSurfaceMenuOpen, children: [
|
|
7245
|
+
/* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", variant: "ghost", size: "sm", "aria-label": `Preview surface: ${activeSurface.label}`, children: [
|
|
6497
7246
|
/* @__PURE__ */ jsxRuntime.jsx(activeSurface.Icon, { className: "h-3.5 w-3.5" }),
|
|
6498
|
-
activeSurface.label,
|
|
7247
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline", children: activeSurface.label }),
|
|
6499
7248
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-3.5 w-3.5 opacity-60" })
|
|
6500
7249
|
] }) }),
|
|
6501
|
-
/* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { align: "start", className: "w-36 p-1", children:
|
|
6502
|
-
|
|
6503
|
-
|
|
6504
|
-
"
|
|
6505
|
-
|
|
6506
|
-
|
|
6507
|
-
|
|
6508
|
-
|
|
6509
|
-
|
|
6510
|
-
|
|
6511
|
-
|
|
6512
|
-
|
|
6513
|
-
/* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "h-3.5 w-3.5" }),
|
|
6514
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1", children: label }),
|
|
6515
|
-
isActive ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3.5 w-3.5" }) : null
|
|
6516
|
-
]
|
|
6517
|
-
},
|
|
6518
|
-
value
|
|
6519
|
-
);
|
|
6520
|
-
}) })
|
|
7250
|
+
/* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { align: "start", className: "w-36 p-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7251
|
+
Menu,
|
|
7252
|
+
{
|
|
7253
|
+
ariaLabel: "Preview surface",
|
|
7254
|
+
options: surfaceOptions,
|
|
7255
|
+
value: previewSurface,
|
|
7256
|
+
onChange: (next) => {
|
|
7257
|
+
onPreviewSurfaceChange(next);
|
|
7258
|
+
setSurfaceMenuOpen(false);
|
|
7259
|
+
}
|
|
7260
|
+
}
|
|
7261
|
+
) })
|
|
6521
7262
|
] }) : null,
|
|
6522
|
-
showThemeControl ? /* @__PURE__ */ jsxRuntime.jsxs(Popover, { children: [
|
|
6523
|
-
/* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", variant: "ghost", size: "sm", children: [
|
|
7263
|
+
showThemeControl ? /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: themeMenuOpen, onOpenChange: setThemeMenuOpen, children: [
|
|
7264
|
+
/* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", variant: "ghost", size: "sm", "aria-label": `Preview theme: ${activeTheme.label}`, children: [
|
|
6524
7265
|
/* @__PURE__ */ jsxRuntime.jsx(activeTheme.Icon, { className: "h-3.5 w-3.5" }),
|
|
6525
|
-
activeTheme.label,
|
|
7266
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline", children: activeTheme.label }),
|
|
6526
7267
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-3.5 w-3.5 opacity-60" })
|
|
6527
7268
|
] }) }),
|
|
6528
|
-
/* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { align: "start", className: "w-32 p-1", children:
|
|
6529
|
-
|
|
6530
|
-
|
|
6531
|
-
"
|
|
6532
|
-
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
/* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "h-3.5 w-3.5" }),
|
|
6541
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1", children: label }),
|
|
6542
|
-
isActive ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3.5 w-3.5" }) : null
|
|
6543
|
-
]
|
|
6544
|
-
},
|
|
6545
|
-
value
|
|
6546
|
-
);
|
|
6547
|
-
}) })
|
|
7269
|
+
/* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { align: "start", className: "w-32 p-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7270
|
+
Menu,
|
|
7271
|
+
{
|
|
7272
|
+
ariaLabel: "Preview theme",
|
|
7273
|
+
options: THEME_OPTIONS,
|
|
7274
|
+
value: previewTheme,
|
|
7275
|
+
onChange: (next) => {
|
|
7276
|
+
onPreviewThemeChange(next);
|
|
7277
|
+
setThemeMenuOpen(false);
|
|
7278
|
+
}
|
|
7279
|
+
}
|
|
7280
|
+
) })
|
|
6548
7281
|
] }) : null,
|
|
6549
7282
|
docsHref ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6550
7283
|
"a",
|
|
@@ -6552,7 +7285,8 @@ function Toolbar2({
|
|
|
6552
7285
|
href: docsHref,
|
|
6553
7286
|
target: "_blank",
|
|
6554
7287
|
rel: "noreferrer noopener",
|
|
6555
|
-
className: "
|
|
7288
|
+
className: "hidden h-8 items-center gap-1.5 rounded-md px-2 py-1 text-sm text-muted-foreground no-underline transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring sm:inline-flex",
|
|
7289
|
+
"aria-label": `${docsLabel} (opens in a new tab)`,
|
|
6556
7290
|
children: [
|
|
6557
7291
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.BookOpen, { className: "h-3.5 w-3.5" }),
|
|
6558
7292
|
docsLabel,
|
|
@@ -6561,7 +7295,7 @@ function Toolbar2({
|
|
|
6561
7295
|
}
|
|
6562
7296
|
) : null
|
|
6563
7297
|
] }),
|
|
6564
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
7298
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 sm:gap-2", children: [
|
|
6565
7299
|
errorCount > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6566
7300
|
Button,
|
|
6567
7301
|
{
|
|
@@ -6570,11 +7304,14 @@ function Toolbar2({
|
|
|
6570
7304
|
size: "sm",
|
|
6571
7305
|
onClick: onOpenIssues,
|
|
6572
7306
|
className: "text-destructive hover:text-destructive",
|
|
7307
|
+
"aria-label": `${errorCount} ${errorCount === 1 ? "issue" : "issues"}`,
|
|
6573
7308
|
children: [
|
|
6574
7309
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-3.5 w-3.5" }),
|
|
6575
|
-
|
|
6576
|
-
|
|
6577
|
-
|
|
7310
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
7311
|
+
errorCount,
|
|
7312
|
+
" ",
|
|
7313
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline", children: errorCount === 1 ? "issue" : "issues" })
|
|
7314
|
+
] })
|
|
6578
7315
|
]
|
|
6579
7316
|
}
|
|
6580
7317
|
) : null,
|
|
@@ -6586,24 +7323,188 @@ function Toolbar2({
|
|
|
6586
7323
|
size: "sm",
|
|
6587
7324
|
onClick: onClear,
|
|
6588
7325
|
disabled: !canClear,
|
|
6589
|
-
className: "hover:bg-destructive/10 hover:text-destructive",
|
|
7326
|
+
className: "hidden hover:bg-destructive/10 hover:text-destructive sm:inline-flex",
|
|
7327
|
+
"aria-label": "Clear all blocks",
|
|
6590
7328
|
children: [
|
|
6591
7329
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-3.5 w-3.5" }),
|
|
6592
7330
|
"Clear"
|
|
6593
7331
|
]
|
|
6594
7332
|
}
|
|
6595
7333
|
),
|
|
6596
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
6597
|
-
|
|
6598
|
-
|
|
7334
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7335
|
+
Button,
|
|
7336
|
+
{
|
|
7337
|
+
type: "button",
|
|
7338
|
+
variant: "ghost",
|
|
7339
|
+
size: "sm",
|
|
7340
|
+
onClick: onOpenJson,
|
|
7341
|
+
"aria-label": "View JSON",
|
|
7342
|
+
className: "hidden sm:inline-flex",
|
|
7343
|
+
children: [
|
|
7344
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Code2, { className: "h-3.5 w-3.5" }),
|
|
7345
|
+
"View JSON"
|
|
7346
|
+
]
|
|
7347
|
+
}
|
|
7348
|
+
),
|
|
7349
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: moreMenuOpen, onOpenChange: setMoreMenuOpen, children: [
|
|
7350
|
+
/* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7351
|
+
Button,
|
|
7352
|
+
{
|
|
7353
|
+
type: "button",
|
|
7354
|
+
variant: "ghost",
|
|
7355
|
+
size: "sm",
|
|
7356
|
+
"aria-label": "More actions",
|
|
7357
|
+
"aria-haspopup": "menu",
|
|
7358
|
+
className: "px-2 sm:hidden",
|
|
7359
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MoreHorizontal, { className: "h-3.5 w-3.5" })
|
|
7360
|
+
}
|
|
7361
|
+
) }),
|
|
7362
|
+
/* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { align: "end", className: "w-44 p-1", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "menu", "aria-label": "More actions", className: "flex flex-col", children: [
|
|
7363
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7364
|
+
ActionMenuItem,
|
|
7365
|
+
{
|
|
7366
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-3.5 w-3.5" }),
|
|
7367
|
+
onSelect: () => {
|
|
7368
|
+
setMoreMenuOpen(false);
|
|
7369
|
+
onClear();
|
|
7370
|
+
},
|
|
7371
|
+
disabled: !canClear,
|
|
7372
|
+
tone: "destructive",
|
|
7373
|
+
children: "Clear"
|
|
7374
|
+
}
|
|
7375
|
+
),
|
|
7376
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7377
|
+
ActionMenuItem,
|
|
7378
|
+
{
|
|
7379
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Code2, { className: "h-3.5 w-3.5" }),
|
|
7380
|
+
onSelect: () => {
|
|
7381
|
+
setMoreMenuOpen(false);
|
|
7382
|
+
onOpenJson();
|
|
7383
|
+
},
|
|
7384
|
+
children: "View JSON"
|
|
7385
|
+
}
|
|
7386
|
+
),
|
|
7387
|
+
docsHref ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
7388
|
+
ActionMenuLink,
|
|
7389
|
+
{
|
|
7390
|
+
href: docsHref,
|
|
7391
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BookOpen, { className: "h-3.5 w-3.5" }),
|
|
7392
|
+
trailingIcon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-3 w-3 opacity-50" }),
|
|
7393
|
+
onSelect: () => setMoreMenuOpen(false),
|
|
7394
|
+
children: docsLabel
|
|
7395
|
+
}
|
|
7396
|
+
) : null
|
|
7397
|
+
] }) })
|
|
6599
7398
|
] }),
|
|
6600
|
-
/* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", size: "sm", onClick: onOpenSend, disabled: !canSend, children: [
|
|
7399
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", size: "sm", onClick: onOpenSend, disabled: !canSend, "aria-label": "Send", children: [
|
|
6601
7400
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "h-3.5 w-3.5" }),
|
|
6602
|
-
"Send"
|
|
7401
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline", children: "Send" })
|
|
6603
7402
|
] })
|
|
6604
7403
|
] })
|
|
6605
7404
|
] });
|
|
6606
7405
|
}
|
|
7406
|
+
function Menu({
|
|
7407
|
+
ariaLabel,
|
|
7408
|
+
options,
|
|
7409
|
+
value,
|
|
7410
|
+
onChange
|
|
7411
|
+
}) {
|
|
7412
|
+
const itemsRef = React.useRef([]);
|
|
7413
|
+
const moveFocus = (from, delta) => {
|
|
7414
|
+
const len = options.length;
|
|
7415
|
+
if (len === 0) return;
|
|
7416
|
+
const next = (from + delta + len) % len;
|
|
7417
|
+
itemsRef.current[next]?.focus();
|
|
7418
|
+
};
|
|
7419
|
+
const handleKeyDown = (e, idx) => {
|
|
7420
|
+
if (e.key === "ArrowDown") {
|
|
7421
|
+
e.preventDefault();
|
|
7422
|
+
moveFocus(idx, 1);
|
|
7423
|
+
} else if (e.key === "ArrowUp") {
|
|
7424
|
+
e.preventDefault();
|
|
7425
|
+
moveFocus(idx, -1);
|
|
7426
|
+
} else if (e.key === "Home") {
|
|
7427
|
+
e.preventDefault();
|
|
7428
|
+
itemsRef.current[0]?.focus();
|
|
7429
|
+
} else if (e.key === "End") {
|
|
7430
|
+
e.preventDefault();
|
|
7431
|
+
itemsRef.current[options.length - 1]?.focus();
|
|
7432
|
+
}
|
|
7433
|
+
};
|
|
7434
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { role: "menu", "aria-label": ariaLabel, className: "flex flex-col", children: options.map(({ value: optValue, label, Icon }, idx) => {
|
|
7435
|
+
const isActive = optValue === value;
|
|
7436
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7437
|
+
"button",
|
|
7438
|
+
{
|
|
7439
|
+
ref: (el) => {
|
|
7440
|
+
itemsRef.current[idx] = el;
|
|
7441
|
+
},
|
|
7442
|
+
type: "button",
|
|
7443
|
+
role: "menuitemradio",
|
|
7444
|
+
"aria-checked": isActive,
|
|
7445
|
+
onClick: () => onChange(optValue),
|
|
7446
|
+
onKeyDown: (e) => handleKeyDown(e, idx),
|
|
7447
|
+
className: cn(
|
|
7448
|
+
"flex w-full cursor-pointer items-center gap-2 rounded px-2 py-1.5 text-left text-sm hover:bg-accent hover:text-foreground focus-visible:bg-accent focus-visible:text-foreground focus-visible:outline-none",
|
|
7449
|
+
isActive ? "text-foreground" : "text-muted-foreground"
|
|
7450
|
+
),
|
|
7451
|
+
children: [
|
|
7452
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "h-3.5 w-3.5" }),
|
|
7453
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1", children: label }),
|
|
7454
|
+
isActive ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3.5 w-3.5" }) : null
|
|
7455
|
+
]
|
|
7456
|
+
},
|
|
7457
|
+
optValue
|
|
7458
|
+
);
|
|
7459
|
+
}) });
|
|
7460
|
+
}
|
|
7461
|
+
var ACTION_ITEM_BASE = "flex w-full cursor-pointer items-center gap-2 rounded px-2 py-1.5 text-left text-sm text-muted-foreground no-underline transition-colors hover:bg-accent hover:text-foreground focus-visible:bg-accent focus-visible:text-foreground focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50";
|
|
7462
|
+
function ActionMenuItem({
|
|
7463
|
+
icon,
|
|
7464
|
+
children,
|
|
7465
|
+
onSelect,
|
|
7466
|
+
disabled,
|
|
7467
|
+
tone
|
|
7468
|
+
}) {
|
|
7469
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7470
|
+
"button",
|
|
7471
|
+
{
|
|
7472
|
+
type: "button",
|
|
7473
|
+
role: "menuitem",
|
|
7474
|
+
onClick: onSelect,
|
|
7475
|
+
disabled,
|
|
7476
|
+
className: cn(ACTION_ITEM_BASE, tone === "destructive" && "hover:bg-destructive/10 hover:text-destructive"),
|
|
7477
|
+
children: [
|
|
7478
|
+
icon,
|
|
7479
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1", children })
|
|
7480
|
+
]
|
|
7481
|
+
}
|
|
7482
|
+
);
|
|
7483
|
+
}
|
|
7484
|
+
function ActionMenuLink({
|
|
7485
|
+
href,
|
|
7486
|
+
icon,
|
|
7487
|
+
trailingIcon,
|
|
7488
|
+
children,
|
|
7489
|
+
onSelect
|
|
7490
|
+
}) {
|
|
7491
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7492
|
+
"a",
|
|
7493
|
+
{
|
|
7494
|
+
role: "menuitem",
|
|
7495
|
+
href,
|
|
7496
|
+
target: "_blank",
|
|
7497
|
+
rel: "noreferrer noopener",
|
|
7498
|
+
onClick: onSelect,
|
|
7499
|
+
className: ACTION_ITEM_BASE,
|
|
7500
|
+
children: [
|
|
7501
|
+
icon,
|
|
7502
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1", children }),
|
|
7503
|
+
trailingIcon
|
|
7504
|
+
]
|
|
7505
|
+
}
|
|
7506
|
+
);
|
|
7507
|
+
}
|
|
6607
7508
|
function BlockKitchen(props) {
|
|
6608
7509
|
const {
|
|
6609
7510
|
workspaceName,
|
|
@@ -6614,6 +7515,7 @@ function BlockKitchen(props) {
|
|
|
6614
7515
|
loadSendAsUserStatus,
|
|
6615
7516
|
onSend,
|
|
6616
7517
|
palette,
|
|
7518
|
+
disabledBlockTypes,
|
|
6617
7519
|
showPaletteSearch,
|
|
6618
7520
|
paletteSearchPlaceholder,
|
|
6619
7521
|
defaultOpenSections,
|
|
@@ -6623,22 +7525,42 @@ function BlockKitchen(props) {
|
|
|
6623
7525
|
defaultPreviewTheme = "light",
|
|
6624
7526
|
theme
|
|
6625
7527
|
} = props;
|
|
6626
|
-
const paletteSections =
|
|
6627
|
-
|
|
7528
|
+
const paletteSections = React.useMemo(() => {
|
|
7529
|
+
const sections = palette ?? defaultPalette;
|
|
7530
|
+
if (!disabledBlockTypes || disabledBlockTypes.length === 0) {
|
|
7531
|
+
return sections;
|
|
7532
|
+
}
|
|
7533
|
+
const blocked = new Set(disabledBlockTypes);
|
|
7534
|
+
const filtered = [];
|
|
7535
|
+
for (const section of sections) {
|
|
7536
|
+
const variants = section.variants.filter((variant) => !blocked.has(variant.factory().type));
|
|
7537
|
+
if (variants.length > 0) {
|
|
7538
|
+
filtered.push({ ...section, variants });
|
|
7539
|
+
}
|
|
7540
|
+
}
|
|
7541
|
+
return filtered;
|
|
7542
|
+
}, [palette, disabledBlockTypes]);
|
|
7543
|
+
const variantById = React.useMemo(() => buildVariantById(paletteSections), [paletteSections]);
|
|
6628
7544
|
const allowedSurfaces = allowedSurfacesProp && allowedSurfacesProp.length > 0 ? allowedSurfacesProp : ["message"];
|
|
6629
7545
|
const { blocks, addBlock, updateBlock, removeBlock, duplicateBlock, reorderBlock, replaceAll } = useBlockKitchenState(
|
|
6630
7546
|
{ initialBlocks, onChange }
|
|
6631
7547
|
);
|
|
6632
|
-
const [jsonOpen, setJsonOpen] =
|
|
6633
|
-
const [sendOpen, setSendOpen] =
|
|
6634
|
-
const [issuesOpen, setIssuesOpen] =
|
|
6635
|
-
const [
|
|
6636
|
-
const [
|
|
6637
|
-
const [
|
|
6638
|
-
const [
|
|
7548
|
+
const [jsonOpen, setJsonOpen] = React.useState(false);
|
|
7549
|
+
const [sendOpen, setSendOpen] = React.useState(false);
|
|
7550
|
+
const [issuesOpen, setIssuesOpen] = React.useState(false);
|
|
7551
|
+
const [paletteOpen, setPaletteOpen] = React.useState(false);
|
|
7552
|
+
const [openBlockId, setOpenBlockId] = React.useState(null);
|
|
7553
|
+
const [previewTheme, setPreviewTheme] = React.useState(defaultPreviewTheme);
|
|
7554
|
+
const [previewSurface, setPreviewSurface] = React.useState(allowedSurfaces[0]);
|
|
7555
|
+
const [activePaletteVariantId, setActivePaletteVariantId] = React.useState(null);
|
|
7556
|
+
const isMobile = useIsMobile();
|
|
6639
7557
|
const validation = useBlockKitValidation(blocks, "message");
|
|
6640
|
-
const sensors = core.useSensors(
|
|
6641
|
-
|
|
7558
|
+
const sensors = core.useSensors(
|
|
7559
|
+
core.useSensor(core.PointerSensor, { activationConstraint: { distance: 4 } }),
|
|
7560
|
+
core.useSensor(core.TouchSensor, { activationConstraint: { delay: 150, tolerance: 8 } }),
|
|
7561
|
+
core.useSensor(core.KeyboardSensor, { coordinateGetter: sortable.sortableKeyboardCoordinates })
|
|
7562
|
+
);
|
|
7563
|
+
const collisionDetection = React.useCallback((args) => {
|
|
6642
7564
|
const pointerHits = core.pointerWithin(args);
|
|
6643
7565
|
if (pointerHits.length > 0) {
|
|
6644
7566
|
const blockHit = pointerHits.find((c) => c.id !== SURFACE_DROPPABLE_ID);
|
|
@@ -6646,11 +7568,11 @@ function BlockKitchen(props) {
|
|
|
6646
7568
|
}
|
|
6647
7569
|
return core.closestCenter(args);
|
|
6648
7570
|
}, []);
|
|
6649
|
-
const handleDragStart =
|
|
7571
|
+
const handleDragStart = React.useCallback((event) => {
|
|
6650
7572
|
const variantId = parsePaletteDragId(event.active.id);
|
|
6651
7573
|
setActivePaletteVariantId(variantId);
|
|
6652
7574
|
}, []);
|
|
6653
|
-
const handleDragEnd =
|
|
7575
|
+
const handleDragEnd = React.useCallback(
|
|
6654
7576
|
(event) => {
|
|
6655
7577
|
setActivePaletteVariantId(null);
|
|
6656
7578
|
const { active, over } = event;
|
|
@@ -6676,7 +7598,7 @@ function BlockKitchen(props) {
|
|
|
6676
7598
|
},
|
|
6677
7599
|
[addBlock, blocks, reorderBlock, variantById]
|
|
6678
7600
|
);
|
|
6679
|
-
const handleDragCancel =
|
|
7601
|
+
const handleDragCancel = React.useCallback(() => {
|
|
6680
7602
|
setActivePaletteVariantId(null);
|
|
6681
7603
|
}, []);
|
|
6682
7604
|
const activePaletteVariant = activePaletteVariantId ? variantById.get(activePaletteVariantId) : null;
|
|
@@ -6690,7 +7612,7 @@ function BlockKitchen(props) {
|
|
|
6690
7612
|
onDragEnd: handleDragEnd,
|
|
6691
7613
|
onDragCancel: handleDragCancel,
|
|
6692
7614
|
children: [
|
|
6693
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bk-root flex h-full w-full flex-col rounded-md border bg-background text-foreground", children: [
|
|
7615
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bk-root flex h-full w-full flex-col overflow-hidden rounded-md border bg-background text-foreground", children: [
|
|
6694
7616
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6695
7617
|
Toolbar2,
|
|
6696
7618
|
{
|
|
@@ -6698,6 +7620,7 @@ function BlockKitchen(props) {
|
|
|
6698
7620
|
onOpenJson: () => setJsonOpen(true),
|
|
6699
7621
|
onOpenIssues: () => setIssuesOpen(true),
|
|
6700
7622
|
onOpenSend: () => setSendOpen(true),
|
|
7623
|
+
onOpenPalette: () => setPaletteOpen(true),
|
|
6701
7624
|
canSend: blocks.length > 0,
|
|
6702
7625
|
canClear: blocks.length > 0,
|
|
6703
7626
|
errorCount: validation.total,
|
|
@@ -6711,7 +7634,7 @@ function BlockKitchen(props) {
|
|
|
6711
7634
|
}
|
|
6712
7635
|
),
|
|
6713
7636
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-1 items-stretch", children: [
|
|
6714
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7637
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden min-h-0 md:flex", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6715
7638
|
Palette,
|
|
6716
7639
|
{
|
|
6717
7640
|
onAddBlock: (block) => addBlock(block),
|
|
@@ -6720,7 +7643,7 @@ function BlockKitchen(props) {
|
|
|
6720
7643
|
searchPlaceholder: paletteSearchPlaceholder,
|
|
6721
7644
|
defaultOpenSections
|
|
6722
7645
|
}
|
|
6723
|
-
),
|
|
7646
|
+
) }),
|
|
6724
7647
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6725
7648
|
Surface,
|
|
6726
7649
|
{
|
|
@@ -6735,7 +7658,9 @@ function BlockKitchen(props) {
|
|
|
6735
7658
|
onUpdate: updateBlock,
|
|
6736
7659
|
onDuplicate: duplicateBlock,
|
|
6737
7660
|
onDelete: removeBlock,
|
|
6738
|
-
|
|
7661
|
+
onReorder: reorderBlock,
|
|
7662
|
+
isPaletteDrag: activePaletteVariant !== null,
|
|
7663
|
+
onOpenPalette: () => setPaletteOpen(true)
|
|
6739
7664
|
}
|
|
6740
7665
|
)
|
|
6741
7666
|
] })
|
|
@@ -6744,6 +7669,33 @@ function BlockKitchen(props) {
|
|
|
6744
7669
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.GripVertical, { className: "h-3 w-3 shrink-0" }),
|
|
6745
7670
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: activePaletteVariant.label })
|
|
6746
7671
|
] }) : null }),
|
|
7672
|
+
/* @__PURE__ */ jsxRuntime.jsx(Sheet, { open: paletteOpen && isMobile, onOpenChange: setPaletteOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7673
|
+
SheetContent,
|
|
7674
|
+
{
|
|
7675
|
+
side: "bottom",
|
|
7676
|
+
className: "bk-portal-content flex h-[85svh] max-h-[85svh] flex-col gap-3 p-0 sm:max-w-none",
|
|
7677
|
+
children: [
|
|
7678
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 px-4 pt-5", children: [
|
|
7679
|
+
/* @__PURE__ */ jsxRuntime.jsx(SheetTitle, { children: "Add a block" }),
|
|
7680
|
+
/* @__PURE__ */ jsxRuntime.jsx(SheetDescription, { children: "Tap a block to add it to the bottom of your draft." })
|
|
7681
|
+
] }),
|
|
7682
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-h-0 flex-1 flex-col", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7683
|
+
Palette,
|
|
7684
|
+
{
|
|
7685
|
+
onAddBlock: (block) => {
|
|
7686
|
+
addBlock(block);
|
|
7687
|
+
setPaletteOpen(false);
|
|
7688
|
+
},
|
|
7689
|
+
sections: paletteSections,
|
|
7690
|
+
showSearch: showPaletteSearch,
|
|
7691
|
+
searchPlaceholder: paletteSearchPlaceholder,
|
|
7692
|
+
defaultOpenSections,
|
|
7693
|
+
variant: "sheet"
|
|
7694
|
+
}
|
|
7695
|
+
) })
|
|
7696
|
+
]
|
|
7697
|
+
}
|
|
7698
|
+
) }),
|
|
6747
7699
|
/* @__PURE__ */ jsxRuntime.jsx(JsonDrawer, { open: jsonOpen, onOpenChange: setJsonOpen, blocks: blockPayloads, onApply: replaceAll }),
|
|
6748
7700
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6749
7701
|
SendDialog,
|
|
@@ -6876,11 +7828,11 @@ function TemplatePicker({
|
|
|
6876
7828
|
}) {
|
|
6877
7829
|
const visible = surface ? templates.filter((t) => t.surface === surface) : templates;
|
|
6878
7830
|
const { grouped, sections } = groupByCategory(visible);
|
|
6879
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex h-full w-full flex-col gap-
|
|
6880
|
-
heading ? /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-
|
|
6881
|
-
visible.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-foreground/75", children: emptyLabel }) : sections.map((section) => /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "flex flex-col gap-4", children: [
|
|
7831
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex h-full w-full flex-col gap-6 overflow-y-auto bg-muted/30 p-4 sm:gap-8 sm:p-8", className), children: [
|
|
7832
|
+
heading ? /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-lg font-semibold tracking-tight text-foreground sm:text-xl", children: heading }) : null,
|
|
7833
|
+
visible.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-foreground/75", children: emptyLabel }) : sections.map((section) => /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "flex flex-col gap-3 sm:gap-4", children: [
|
|
6882
7834
|
grouped ? /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-xs font-semibold tracking-wider text-foreground/60 uppercase", children: section.category }) : null,
|
|
6883
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-[repeat(auto-fill,minmax(280px,1fr))] gap-5", children: section.templates.map((template) => /* @__PURE__ */ jsxRuntime.jsx(TemplateCard, { template, theme, onSelect }, template.id)) })
|
|
7835
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-[repeat(auto-fill,minmax(240px,1fr))] gap-4 sm:grid-cols-[repeat(auto-fill,minmax(280px,1fr))] sm:gap-5", children: section.templates.map((template) => /* @__PURE__ */ jsxRuntime.jsx(TemplateCard, { template, theme, onSelect }, template.id)) })
|
|
6884
7836
|
] }, section.category))
|
|
6885
7837
|
] });
|
|
6886
7838
|
}
|