@tightknitai/block-kitchen 0.10.24 → 0.10.26
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 +81 -6
- package/dist/helpers.d.cts +2 -2
- package/dist/helpers.d.ts +2 -2
- package/dist/index.cjs +365 -193
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +367 -195
- package/dist/index.js.map +1 -1
- package/dist/{palette-Bup6i-9c.d.cts → palette-Cnz2jz8O.d.cts} +74 -1
- package/dist/{palette-Bup6i-9c.d.ts → palette-Cnz2jz8O.d.ts} +74 -1
- package/dist/palette.cjs.map +1 -1
- package/dist/palette.d.cts +1 -1
- package/dist/palette.d.ts +1 -1
- package/dist/palette.js.map +1 -1
- package/dist/styles.css +2 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1817,6 +1817,35 @@ function labelForBlockType(type) {
|
|
|
1817
1817
|
return "Data Table";
|
|
1818
1818
|
}
|
|
1819
1819
|
}
|
|
1820
|
+
function historyShortcutOf(event) {
|
|
1821
|
+
if (!(event.metaKey || event.ctrlKey) || event.altKey) {
|
|
1822
|
+
return null;
|
|
1823
|
+
}
|
|
1824
|
+
const key = event.key.toLowerCase();
|
|
1825
|
+
if (key === "z") {
|
|
1826
|
+
return event.shiftKey ? "redo" : "undo";
|
|
1827
|
+
}
|
|
1828
|
+
return key === "y" ? "redo" : null;
|
|
1829
|
+
}
|
|
1830
|
+
function isTextEditingTarget(target) {
|
|
1831
|
+
if (!(target instanceof HTMLElement)) {
|
|
1832
|
+
return false;
|
|
1833
|
+
}
|
|
1834
|
+
return target.isContentEditable || // jsdom has no `isContentEditable`, so check the attribute too.
|
|
1835
|
+
target.closest('[contenteditable=""], [contenteditable="true"], [contenteditable="plaintext-only"]') !== null || ["INPUT", "TEXTAREA", "SELECT"].includes(target.tagName);
|
|
1836
|
+
}
|
|
1837
|
+
function isApplePlatform() {
|
|
1838
|
+
if (typeof navigator === "undefined") {
|
|
1839
|
+
return false;
|
|
1840
|
+
}
|
|
1841
|
+
const { userAgentData } = navigator;
|
|
1842
|
+
return /mac|iphone|ipad|ipod/i.test(userAgentData?.platform ?? navigator.platform ?? "");
|
|
1843
|
+
}
|
|
1844
|
+
var subscribeToNothing = () => () => {
|
|
1845
|
+
};
|
|
1846
|
+
function useIsApplePlatform() {
|
|
1847
|
+
return React.useSyncExternalStore(subscribeToNothing, isApplePlatform, () => false);
|
|
1848
|
+
}
|
|
1820
1849
|
var Sheet = DialogPrimitive__namespace.Root;
|
|
1821
1850
|
var SheetOverlay = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1822
1851
|
DialogPrimitive__namespace.Overlay,
|
|
@@ -1898,6 +1927,16 @@ function useIsMobile() {
|
|
|
1898
1927
|
}, []);
|
|
1899
1928
|
return isMobile;
|
|
1900
1929
|
}
|
|
1930
|
+
var BlockEditorsContext = React.createContext([]);
|
|
1931
|
+
function BlockEditorsProvider({
|
|
1932
|
+
blockEditors,
|
|
1933
|
+
children
|
|
1934
|
+
}) {
|
|
1935
|
+
return /* @__PURE__ */ jsxRuntime.jsx(BlockEditorsContext.Provider, { value: blockEditors ?? [], children });
|
|
1936
|
+
}
|
|
1937
|
+
function useCustomBlockEditor(block) {
|
|
1938
|
+
return React.useContext(BlockEditorsContext).find((editor) => editor.match(block));
|
|
1939
|
+
}
|
|
1901
1940
|
var EMPTY = {
|
|
1902
1941
|
customEmojis: [],
|
|
1903
1942
|
byName: /* @__PURE__ */ new Map()
|
|
@@ -4239,6 +4278,7 @@ function Palette({
|
|
|
4239
4278
|
mode = "advanced",
|
|
4240
4279
|
defaultAdvanced = false,
|
|
4241
4280
|
onAdvancedChange,
|
|
4281
|
+
onLockedPicked,
|
|
4242
4282
|
variant = "aside"
|
|
4243
4283
|
}) {
|
|
4244
4284
|
const [query, setQuery] = React.useState("");
|
|
@@ -4332,7 +4372,16 @@ function Palette({
|
|
|
4332
4372
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-col", isSheet ? "px-2 pb-6" : "p-3"), children: !advanced ? (
|
|
4333
4373
|
// Simple mode: a flat list, no section headings — with this few
|
|
4334
4374
|
// rows the headings would outnumber the blocks under them.
|
|
4335
|
-
basics.map((v) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
4375
|
+
basics.map((v) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
4376
|
+
PaletteItem,
|
|
4377
|
+
{
|
|
4378
|
+
variant: v,
|
|
4379
|
+
onAdd: () => onAddBlock(v.factory()),
|
|
4380
|
+
onLockedPicked,
|
|
4381
|
+
mode: variant
|
|
4382
|
+
},
|
|
4383
|
+
v.id
|
|
4384
|
+
))
|
|
4336
4385
|
) : 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(
|
|
4337
4386
|
PaletteSection,
|
|
4338
4387
|
{
|
|
@@ -4340,6 +4389,7 @@ function Palette({
|
|
|
4340
4389
|
defaultOpen: isDefaultOpen(section.name, defaultOpenSections),
|
|
4341
4390
|
forceOpen: queryActive,
|
|
4342
4391
|
onAddBlock,
|
|
4392
|
+
onLockedPicked,
|
|
4343
4393
|
variant
|
|
4344
4394
|
},
|
|
4345
4395
|
section.name
|
|
@@ -4371,6 +4421,7 @@ function PaletteSection({
|
|
|
4371
4421
|
defaultOpen,
|
|
4372
4422
|
forceOpen,
|
|
4373
4423
|
onAddBlock,
|
|
4424
|
+
onLockedPicked,
|
|
4374
4425
|
variant = "aside"
|
|
4375
4426
|
}) {
|
|
4376
4427
|
const [open, setOpen] = React.useState(defaultOpen);
|
|
@@ -4402,18 +4453,32 @@ function PaletteSection({
|
|
|
4402
4453
|
]
|
|
4403
4454
|
}
|
|
4404
4455
|
),
|
|
4405
|
-
isOpen ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-0.5 flex flex-col", children: section.variants.map((v) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
4456
|
+
isOpen ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-0.5 flex flex-col", children: section.variants.map((v) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
4457
|
+
PaletteItem,
|
|
4458
|
+
{
|
|
4459
|
+
variant: v,
|
|
4460
|
+
onAdd: () => onAddBlock(v.factory()),
|
|
4461
|
+
onLockedPicked,
|
|
4462
|
+
mode: variant
|
|
4463
|
+
},
|
|
4464
|
+
v.id
|
|
4465
|
+
)) }) : null
|
|
4406
4466
|
] });
|
|
4407
4467
|
}
|
|
4408
4468
|
function PaletteItem({
|
|
4409
4469
|
variant,
|
|
4410
4470
|
onAdd,
|
|
4471
|
+
onLockedPicked,
|
|
4411
4472
|
mode = "aside"
|
|
4412
4473
|
}) {
|
|
4413
4474
|
const { attributes, listeners, setNodeRef, setActivatorNodeRef, isDragging } = core.useDraggable({
|
|
4414
|
-
id: `${PALETTE_DRAG_PREFIX}${variant.id}
|
|
4475
|
+
id: `${PALETTE_DRAG_PREFIX}${variant.id}`,
|
|
4476
|
+
disabled: variant.locked
|
|
4415
4477
|
});
|
|
4416
4478
|
const isSheet = mode === "sheet";
|
|
4479
|
+
if (variant.locked) {
|
|
4480
|
+
return /* @__PURE__ */ jsxRuntime.jsx(LockedPaletteItem, { variant, isSheet, onPicked: onLockedPicked });
|
|
4481
|
+
}
|
|
4417
4482
|
if (isSheet) {
|
|
4418
4483
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4419
4484
|
"button",
|
|
@@ -4428,6 +4493,7 @@ function PaletteItem({
|
|
|
4428
4493
|
),
|
|
4429
4494
|
children: [
|
|
4430
4495
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate", children: variant.label }),
|
|
4496
|
+
variant.badge ? /* @__PURE__ */ jsxRuntime.jsx(VariantBadge, { badge: variant.badge }) : null,
|
|
4431
4497
|
/* @__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" }) })
|
|
4432
4498
|
]
|
|
4433
4499
|
}
|
|
@@ -4438,7 +4504,7 @@ function PaletteItem({
|
|
|
4438
4504
|
{
|
|
4439
4505
|
ref: setNodeRef,
|
|
4440
4506
|
className: cn(
|
|
4441
|
-
"group flex items-
|
|
4507
|
+
"group flex items-start gap-2 rounded px-2 py-1 text-sm text-muted-foreground transition-colors hover:bg-accent hover:text-foreground has-[:focus-visible]:bg-accent has-[:focus-visible]:text-foreground",
|
|
4442
4508
|
isDragging && "opacity-50"
|
|
4443
4509
|
),
|
|
4444
4510
|
children: [
|
|
@@ -4446,12 +4512,12 @@ function PaletteItem({
|
|
|
4446
4512
|
"div",
|
|
4447
4513
|
{
|
|
4448
4514
|
ref: setActivatorNodeRef,
|
|
4449
|
-
className: "-my-1 flex min-w-0 flex-1 cursor-grab items-
|
|
4515
|
+
className: "-my-1 flex min-w-0 flex-1 cursor-grab items-start gap-2 rounded py-1 active:cursor-grabbing focus-visible:outline-none",
|
|
4450
4516
|
...attributes,
|
|
4451
4517
|
...listeners,
|
|
4452
4518
|
children: [
|
|
4453
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.GripVertical, { className: "h-3.5 w-3.5 shrink-0" }),
|
|
4454
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4519
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.GripVertical, { className: "mt-[3px] h-3.5 w-3.5 shrink-0" }),
|
|
4520
|
+
/* @__PURE__ */ jsxRuntime.jsx(RailLabel, { variant })
|
|
4455
4521
|
]
|
|
4456
4522
|
}
|
|
4457
4523
|
),
|
|
@@ -4469,6 +4535,69 @@ function PaletteItem({
|
|
|
4469
4535
|
}
|
|
4470
4536
|
);
|
|
4471
4537
|
}
|
|
4538
|
+
function LockedPaletteItem({
|
|
4539
|
+
variant,
|
|
4540
|
+
isSheet,
|
|
4541
|
+
onPicked
|
|
4542
|
+
}) {
|
|
4543
|
+
const select = variant.onLockedSelect;
|
|
4544
|
+
const className = cn(
|
|
4545
|
+
"flex w-full text-left text-muted-foreground",
|
|
4546
|
+
isSheet ? "min-h-11 items-center gap-3 rounded-md px-3 py-2 text-sm font-medium" : "items-start gap-2 rounded px-2 py-1 text-sm"
|
|
4547
|
+
);
|
|
4548
|
+
const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4549
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Lock, { "aria-hidden": true, className: cn("shrink-0", isSheet ? "h-4 w-4" : "mt-[3px] h-3.5 w-3.5") }),
|
|
4550
|
+
isSheet ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4551
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate", children: variant.label }),
|
|
4552
|
+
variant.badge ? /* @__PURE__ */ jsxRuntime.jsx(VariantBadge, { badge: variant.badge }) : null
|
|
4553
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx(RailLabel, { variant })
|
|
4554
|
+
] });
|
|
4555
|
+
if (!select) {
|
|
4556
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { "aria-disabled": "true", className, children: content });
|
|
4557
|
+
}
|
|
4558
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4559
|
+
"button",
|
|
4560
|
+
{
|
|
4561
|
+
type: "button",
|
|
4562
|
+
"aria-label": `${variant.label} (locked${variant.badge ? `, ${variant.badge.label}` : ""})`,
|
|
4563
|
+
onClick: () => {
|
|
4564
|
+
onPicked?.();
|
|
4565
|
+
select();
|
|
4566
|
+
},
|
|
4567
|
+
className: cn(
|
|
4568
|
+
className,
|
|
4569
|
+
"cursor-pointer appearance-none border-0 bg-transparent transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
4570
|
+
),
|
|
4571
|
+
children: content
|
|
4572
|
+
}
|
|
4573
|
+
);
|
|
4574
|
+
}
|
|
4575
|
+
function RailLabel({ variant }) {
|
|
4576
|
+
if (!variant.badge) {
|
|
4577
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: variant.label });
|
|
4578
|
+
}
|
|
4579
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-col items-start gap-0.5", children: [
|
|
4580
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "max-w-full truncate", children: variant.label }),
|
|
4581
|
+
" ",
|
|
4582
|
+
/* @__PURE__ */ jsxRuntime.jsx(VariantBadge, { badge: variant.badge })
|
|
4583
|
+
] });
|
|
4584
|
+
}
|
|
4585
|
+
function VariantBadge({ badge }) {
|
|
4586
|
+
const Icon = badge.icon;
|
|
4587
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4588
|
+
"span",
|
|
4589
|
+
{
|
|
4590
|
+
className: cn(
|
|
4591
|
+
"inline-flex shrink-0 items-center gap-1 rounded-full border bg-background px-1.5 text-[10px] font-medium leading-4 text-muted-foreground",
|
|
4592
|
+
badge.className
|
|
4593
|
+
),
|
|
4594
|
+
children: [
|
|
4595
|
+
Icon ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { "aria-hidden": true, className: "h-2.5 w-2.5 shrink-0" }) : null,
|
|
4596
|
+
badge.label
|
|
4597
|
+
]
|
|
4598
|
+
}
|
|
4599
|
+
);
|
|
4600
|
+
}
|
|
4472
4601
|
function SendDialog({
|
|
4473
4602
|
open,
|
|
4474
4603
|
onOpenChange,
|
|
@@ -6288,7 +6417,7 @@ function MentionPicker({
|
|
|
6288
6417
|
const listRef = React.useRef(null);
|
|
6289
6418
|
const listboxId = React.useId();
|
|
6290
6419
|
const activeOptionId = items[activeIndex] ? `${listboxId}-${activeIndex}` : void 0;
|
|
6291
|
-
React.
|
|
6420
|
+
React.useLayoutEffect(() => {
|
|
6292
6421
|
const root = editor.view.dom;
|
|
6293
6422
|
root.setAttribute("role", "combobox");
|
|
6294
6423
|
root.setAttribute("aria-autocomplete", "list");
|
|
@@ -6307,7 +6436,7 @@ function MentionPicker({
|
|
|
6307
6436
|
root.removeAttribute("aria-activedescendant");
|
|
6308
6437
|
};
|
|
6309
6438
|
}, [activeOptionId, editor, listboxId]);
|
|
6310
|
-
React.
|
|
6439
|
+
React.useLayoutEffect(() => {
|
|
6311
6440
|
keyHandlerRef.current = (event) => {
|
|
6312
6441
|
if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
|
6313
6442
|
if (items.length > 0) {
|
|
@@ -10397,13 +10526,15 @@ function BlockEditor({
|
|
|
10397
10526
|
onChange,
|
|
10398
10527
|
onDone
|
|
10399
10528
|
}) {
|
|
10529
|
+
const custom = useCustomBlockEditor(block);
|
|
10530
|
+
const CustomForm = custom?.component;
|
|
10400
10531
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
10401
10532
|
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs("h3", { className: "text-sm font-semibold text-foreground", children: [
|
|
10402
10533
|
"Edit ",
|
|
10403
|
-
labelForBlockType(block.type)
|
|
10534
|
+
custom ? custom.label : labelForBlockType(block.type)
|
|
10404
10535
|
] }) }),
|
|
10405
10536
|
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,
|
|
10406
|
-
dispatch(block, onChange),
|
|
10537
|
+
CustomForm ? /* @__PURE__ */ jsxRuntime.jsx(CustomForm, { block, onChange }) : dispatch(block, onChange),
|
|
10407
10538
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
10408
10539
|
AdvancedIdField,
|
|
10409
10540
|
{
|
|
@@ -10574,6 +10705,122 @@ function BlockRow({
|
|
|
10574
10705
|
) })
|
|
10575
10706
|
] });
|
|
10576
10707
|
const adornment = position && renderBlockAdornment?.(position);
|
|
10708
|
+
const hoverChrome = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
10709
|
+
/* @__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] }),
|
|
10710
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
10711
|
+
"div",
|
|
10712
|
+
{
|
|
10713
|
+
className: cn(
|
|
10714
|
+
// Hidden on mobile in favor of the inline row below; on desktop
|
|
10715
|
+
// reveal on hover, on keyboard focus inside the row (so Tab-stops on
|
|
10716
|
+
// the floating buttons themselves keep them visible), and when there
|
|
10717
|
+
// are validation errors worth surfacing immediately.
|
|
10718
|
+
// :focus-visible, not :focus-within — a drag leaves pointer focus on
|
|
10719
|
+
// the block, which would otherwise pin the toolbar open until a click.
|
|
10720
|
+
"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",
|
|
10721
|
+
hasErrors ? "opacity-100" : "opacity-0 group-hover:opacity-100 group-has-[:focus-visible]:opacity-100"
|
|
10722
|
+
),
|
|
10723
|
+
children: [
|
|
10724
|
+
hasErrors ? /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
10725
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
10726
|
+
"button",
|
|
10727
|
+
{
|
|
10728
|
+
type: "button",
|
|
10729
|
+
"aria-label": `Show ${errors.length} validation ${errors.length === 1 ? "issue" : "issues"}`,
|
|
10730
|
+
onClick: () => onOpenChange?.(true),
|
|
10731
|
+
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",
|
|
10732
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-3.5 w-3.5" })
|
|
10733
|
+
}
|
|
10734
|
+
) }),
|
|
10735
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", align: "end", children: /* @__PURE__ */ jsxRuntime.jsxs("ul", { className: "flex flex-col gap-0.5", children: [
|
|
10736
|
+
errors.slice(0, 4).map((err, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: err }, i)),
|
|
10737
|
+
errors.length > 4 ? /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "text-muted-foreground", children: [
|
|
10738
|
+
"and ",
|
|
10739
|
+
errors.length - 4,
|
|
10740
|
+
" more"
|
|
10741
|
+
] }) : null
|
|
10742
|
+
] }) })
|
|
10743
|
+
] }) : null,
|
|
10744
|
+
onReorder && typeof index === "number" && typeof total === "number" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
10745
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
10746
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
10747
|
+
"button",
|
|
10748
|
+
{
|
|
10749
|
+
type: "button",
|
|
10750
|
+
"aria-label": "Move block up",
|
|
10751
|
+
disabled: index === 0,
|
|
10752
|
+
onClick: () => onReorder(builderBlock.id, index - 1),
|
|
10753
|
+
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",
|
|
10754
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, { className: "h-3.5 w-3.5" })
|
|
10755
|
+
}
|
|
10756
|
+
) }),
|
|
10757
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", children: "Move up" })
|
|
10758
|
+
] }),
|
|
10759
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
10760
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
10761
|
+
"button",
|
|
10762
|
+
{
|
|
10763
|
+
type: "button",
|
|
10764
|
+
"aria-label": "Move block down",
|
|
10765
|
+
disabled: index >= total - 1,
|
|
10766
|
+
onClick: () => onReorder(builderBlock.id, index + 1),
|
|
10767
|
+
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",
|
|
10768
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDown, { className: "h-3.5 w-3.5" })
|
|
10769
|
+
}
|
|
10770
|
+
) }),
|
|
10771
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", children: "Move down" })
|
|
10772
|
+
] })
|
|
10773
|
+
] }) : null,
|
|
10774
|
+
/* @__PURE__ */ jsxRuntime.jsx(BlockActionButtons, { actions: blockActions, position, variant: "toolbar" }),
|
|
10775
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
10776
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
10777
|
+
"button",
|
|
10778
|
+
{
|
|
10779
|
+
type: "button",
|
|
10780
|
+
"aria-label": "Edit block",
|
|
10781
|
+
onClick: () => {
|
|
10782
|
+
if (isRichText) {
|
|
10783
|
+
setInlineEditing(true);
|
|
10784
|
+
} else {
|
|
10785
|
+
onOpenChange?.(true);
|
|
10786
|
+
}
|
|
10787
|
+
},
|
|
10788
|
+
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",
|
|
10789
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "h-3.5 w-3.5" })
|
|
10790
|
+
}
|
|
10791
|
+
) }),
|
|
10792
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", children: "Edit" })
|
|
10793
|
+
] }),
|
|
10794
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
10795
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
10796
|
+
"button",
|
|
10797
|
+
{
|
|
10798
|
+
type: "button",
|
|
10799
|
+
"aria-label": "Duplicate block",
|
|
10800
|
+
onClick: () => onDuplicate(builderBlock.id),
|
|
10801
|
+
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",
|
|
10802
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { className: "h-3.5 w-3.5" })
|
|
10803
|
+
}
|
|
10804
|
+
) }),
|
|
10805
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", children: "Duplicate" })
|
|
10806
|
+
] }),
|
|
10807
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
10808
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
10809
|
+
"button",
|
|
10810
|
+
{
|
|
10811
|
+
type: "button",
|
|
10812
|
+
"aria-label": "Delete block",
|
|
10813
|
+
onClick: () => onDelete(builderBlock.id),
|
|
10814
|
+
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",
|
|
10815
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-3.5 w-3.5" })
|
|
10816
|
+
}
|
|
10817
|
+
) }),
|
|
10818
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", children: "Delete" })
|
|
10819
|
+
] })
|
|
10820
|
+
]
|
|
10821
|
+
}
|
|
10822
|
+
)
|
|
10823
|
+
] });
|
|
10577
10824
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
10578
10825
|
"div",
|
|
10579
10826
|
{
|
|
@@ -10591,126 +10838,16 @@ function BlockRow({
|
|
|
10591
10838
|
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)]" })
|
|
10592
10839
|
}
|
|
10593
10840
|
) : null,
|
|
10594
|
-
/* @__PURE__ */ jsxRuntime.
|
|
10595
|
-
|
|
10596
|
-
|
|
10597
|
-
|
|
10598
|
-
] })
|
|
10599
|
-
/* @__PURE__ */ jsxRuntime.jsx("
|
|
10600
|
-
|
|
10601
|
-
|
|
10602
|
-
|
|
10603
|
-
|
|
10604
|
-
// Hidden on mobile in favor of the inline row below; on desktop
|
|
10605
|
-
// reveal on hover, on keyboard focus inside the row (so Tab-stops on
|
|
10606
|
-
// the floating buttons themselves keep them visible), and when there
|
|
10607
|
-
// are validation errors worth surfacing immediately.
|
|
10608
|
-
// :focus-visible, not :focus-within — a drag leaves pointer focus on
|
|
10609
|
-
// the block, which would otherwise pin the toolbar open until a click.
|
|
10610
|
-
"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",
|
|
10611
|
-
hasErrors ? "opacity-100" : "opacity-0 group-hover:opacity-100 group-has-[:focus-visible]:opacity-100"
|
|
10612
|
-
),
|
|
10613
|
-
children: [
|
|
10614
|
-
hasErrors ? /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
10615
|
-
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
10616
|
-
"button",
|
|
10617
|
-
{
|
|
10618
|
-
type: "button",
|
|
10619
|
-
"aria-label": `Show ${errors.length} validation ${errors.length === 1 ? "issue" : "issues"}`,
|
|
10620
|
-
onClick: () => onOpenChange?.(true),
|
|
10621
|
-
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",
|
|
10622
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-3.5 w-3.5" })
|
|
10623
|
-
}
|
|
10624
|
-
) }),
|
|
10625
|
-
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", align: "end", children: /* @__PURE__ */ jsxRuntime.jsxs("ul", { className: "flex flex-col gap-0.5", children: [
|
|
10626
|
-
errors.slice(0, 4).map((err, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: err }, i)),
|
|
10627
|
-
errors.length > 4 ? /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "text-muted-foreground", children: [
|
|
10628
|
-
"and ",
|
|
10629
|
-
errors.length - 4,
|
|
10630
|
-
" more"
|
|
10631
|
-
] }) : null
|
|
10632
|
-
] }) })
|
|
10633
|
-
] }) : null,
|
|
10634
|
-
onReorder && typeof index === "number" && typeof total === "number" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
10635
|
-
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
10636
|
-
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
10637
|
-
"button",
|
|
10638
|
-
{
|
|
10639
|
-
type: "button",
|
|
10640
|
-
"aria-label": "Move block up",
|
|
10641
|
-
disabled: index === 0,
|
|
10642
|
-
onClick: () => onReorder(builderBlock.id, index - 1),
|
|
10643
|
-
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",
|
|
10644
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, { className: "h-3.5 w-3.5" })
|
|
10645
|
-
}
|
|
10646
|
-
) }),
|
|
10647
|
-
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", children: "Move up" })
|
|
10648
|
-
] }),
|
|
10649
|
-
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
10650
|
-
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
10651
|
-
"button",
|
|
10652
|
-
{
|
|
10653
|
-
type: "button",
|
|
10654
|
-
"aria-label": "Move block down",
|
|
10655
|
-
disabled: index >= total - 1,
|
|
10656
|
-
onClick: () => onReorder(builderBlock.id, index + 1),
|
|
10657
|
-
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",
|
|
10658
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDown, { className: "h-3.5 w-3.5" })
|
|
10659
|
-
}
|
|
10660
|
-
) }),
|
|
10661
|
-
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", children: "Move down" })
|
|
10662
|
-
] })
|
|
10663
|
-
] }) : null,
|
|
10664
|
-
/* @__PURE__ */ jsxRuntime.jsx(BlockActionButtons, { actions: blockActions, position, variant: "toolbar" }),
|
|
10665
|
-
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
10666
|
-
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
10667
|
-
"button",
|
|
10668
|
-
{
|
|
10669
|
-
type: "button",
|
|
10670
|
-
"aria-label": "Edit block",
|
|
10671
|
-
onClick: () => {
|
|
10672
|
-
if (isRichText) {
|
|
10673
|
-
setInlineEditing(true);
|
|
10674
|
-
} else {
|
|
10675
|
-
onOpenChange?.(true);
|
|
10676
|
-
}
|
|
10677
|
-
},
|
|
10678
|
-
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",
|
|
10679
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "h-3.5 w-3.5" })
|
|
10680
|
-
}
|
|
10681
|
-
) }),
|
|
10682
|
-
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", children: "Edit" })
|
|
10683
|
-
] }),
|
|
10684
|
-
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
10685
|
-
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
10686
|
-
"button",
|
|
10687
|
-
{
|
|
10688
|
-
type: "button",
|
|
10689
|
-
"aria-label": "Duplicate block",
|
|
10690
|
-
onClick: () => onDuplicate(builderBlock.id),
|
|
10691
|
-
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",
|
|
10692
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { className: "h-3.5 w-3.5" })
|
|
10693
|
-
}
|
|
10694
|
-
) }),
|
|
10695
|
-
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", children: "Duplicate" })
|
|
10696
|
-
] }),
|
|
10697
|
-
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
10698
|
-
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
10699
|
-
"button",
|
|
10700
|
-
{
|
|
10701
|
-
type: "button",
|
|
10702
|
-
"aria-label": "Delete block",
|
|
10703
|
-
onClick: () => onDelete(builderBlock.id),
|
|
10704
|
-
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",
|
|
10705
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-3.5 w-3.5" })
|
|
10706
|
-
}
|
|
10707
|
-
) }),
|
|
10708
|
-
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", children: "Delete" })
|
|
10709
|
-
] })
|
|
10710
|
-
]
|
|
10711
|
-
}
|
|
10712
|
-
)
|
|
10713
|
-
] }),
|
|
10841
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative w-full", children: renderBlockAdornment ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2", children: [
|
|
10842
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative min-w-0 flex-1", children: [
|
|
10843
|
+
body,
|
|
10844
|
+
hoverChrome
|
|
10845
|
+
] }),
|
|
10846
|
+
adornment != null && adornment !== false ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: adornment }) : null
|
|
10847
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
10848
|
+
body,
|
|
10849
|
+
hoverChrome
|
|
10850
|
+
] }) }),
|
|
10714
10851
|
/* @__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: [
|
|
10715
10852
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-[11px] font-medium text-muted-foreground", children: BLOCK_TYPE_LABELS[builderBlock.block.type] }),
|
|
10716
10853
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
@@ -10915,6 +11052,45 @@ function ContainerRow({
|
|
|
10915
11052
|
]
|
|
10916
11053
|
}
|
|
10917
11054
|
);
|
|
11055
|
+
const toolbar = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11056
|
+
"div",
|
|
11057
|
+
{
|
|
11058
|
+
className: cn(
|
|
11059
|
+
"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",
|
|
11060
|
+
hasErrors ? "opacity-100" : "opacity-0 group-hover/container:opacity-100 group-has-[:focus-visible]/container:opacity-100"
|
|
11061
|
+
),
|
|
11062
|
+
children: [
|
|
11063
|
+
hasErrors ? /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
11064
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
11065
|
+
"button",
|
|
11066
|
+
{
|
|
11067
|
+
type: "button",
|
|
11068
|
+
"aria-label": `Show ${errors.length} validation ${errors.length === 1 ? "issue" : "issues"}`,
|
|
11069
|
+
onClick: () => onOpenBlockChange?.(id),
|
|
11070
|
+
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",
|
|
11071
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-3.5 w-3.5" })
|
|
11072
|
+
}
|
|
11073
|
+
) }),
|
|
11074
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", align: "end", children: /* @__PURE__ */ jsxRuntime.jsxs("ul", { className: "flex flex-col gap-0.5", children: [
|
|
11075
|
+
errors.slice(0, 4).map((err, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: err }, i)),
|
|
11076
|
+
errors.length > 4 ? /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "text-muted-foreground", children: [
|
|
11077
|
+
"and ",
|
|
11078
|
+
errors.length - 4,
|
|
11079
|
+
" more"
|
|
11080
|
+
] }) : null
|
|
11081
|
+
] }) })
|
|
11082
|
+
] }) : null,
|
|
11083
|
+
onReorder && typeof index === "number" && typeof total === "number" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
11084
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToolbarButton2, { label: "Move up", disabled: index === 0, onClick: () => onReorder(id, index - 1), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, { className: "h-3.5 w-3.5" }) }),
|
|
11085
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToolbarButton2, { label: "Move down", disabled: index >= total - 1, onClick: () => onReorder(id, index + 1), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDown, { className: "h-3.5 w-3.5" }) })
|
|
11086
|
+
] }) : null,
|
|
11087
|
+
/* @__PURE__ */ jsxRuntime.jsx(BlockActionButtons, { actions: blockActions, position, variant: "toolbar" }),
|
|
11088
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToolbarButton2, { label: "Edit", onClick: () => onOpenBlockChange?.(id), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "h-3.5 w-3.5" }) }),
|
|
11089
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToolbarButton2, { label: "Duplicate", onClick: () => onDuplicate(id), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { className: "h-3.5 w-3.5" }) }),
|
|
11090
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToolbarButton2, { label: "Delete", destructive: true, onClick: () => onDelete(id), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-3.5 w-3.5" }) })
|
|
11091
|
+
]
|
|
11092
|
+
}
|
|
11093
|
+
);
|
|
10918
11094
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
10919
11095
|
"div",
|
|
10920
11096
|
{
|
|
@@ -10924,48 +11100,15 @@ function ContainerRow({
|
|
|
10924
11100
|
className: cn("group/container relative mb-2 last:mb-0 hover:z-10", isDragging && "opacity-40"),
|
|
10925
11101
|
children: [
|
|
10926
11102
|
renderBlockAdornment ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2", children: [
|
|
10927
|
-
/* @__PURE__ */ jsxRuntime.
|
|
11103
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative min-w-0 flex-1", children: [
|
|
11104
|
+
card,
|
|
11105
|
+
toolbar
|
|
11106
|
+
] }),
|
|
10928
11107
|
adornment != null && adornment !== false ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: adornment }) : null
|
|
10929
|
-
] }) :
|
|
10930
|
-
|
|
10931
|
-
|
|
10932
|
-
|
|
10933
|
-
className: cn(
|
|
10934
|
-
"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",
|
|
10935
|
-
hasErrors ? "opacity-100" : "opacity-0 group-hover/container:opacity-100 group-has-[:focus-visible]/container:opacity-100"
|
|
10936
|
-
),
|
|
10937
|
-
children: [
|
|
10938
|
-
hasErrors ? /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
10939
|
-
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
10940
|
-
"button",
|
|
10941
|
-
{
|
|
10942
|
-
type: "button",
|
|
10943
|
-
"aria-label": `Show ${errors.length} validation ${errors.length === 1 ? "issue" : "issues"}`,
|
|
10944
|
-
onClick: () => onOpenBlockChange?.(id),
|
|
10945
|
-
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",
|
|
10946
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-3.5 w-3.5" })
|
|
10947
|
-
}
|
|
10948
|
-
) }),
|
|
10949
|
-
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", align: "end", children: /* @__PURE__ */ jsxRuntime.jsxs("ul", { className: "flex flex-col gap-0.5", children: [
|
|
10950
|
-
errors.slice(0, 4).map((err, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: err }, i)),
|
|
10951
|
-
errors.length > 4 ? /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "text-muted-foreground", children: [
|
|
10952
|
-
"and ",
|
|
10953
|
-
errors.length - 4,
|
|
10954
|
-
" more"
|
|
10955
|
-
] }) : null
|
|
10956
|
-
] }) })
|
|
10957
|
-
] }) : null,
|
|
10958
|
-
onReorder && typeof index === "number" && typeof total === "number" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
10959
|
-
/* @__PURE__ */ jsxRuntime.jsx(ToolbarButton2, { label: "Move up", disabled: index === 0, onClick: () => onReorder(id, index - 1), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, { className: "h-3.5 w-3.5" }) }),
|
|
10960
|
-
/* @__PURE__ */ jsxRuntime.jsx(ToolbarButton2, { label: "Move down", disabled: index >= total - 1, onClick: () => onReorder(id, index + 1), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDown, { className: "h-3.5 w-3.5" }) })
|
|
10961
|
-
] }) : null,
|
|
10962
|
-
/* @__PURE__ */ jsxRuntime.jsx(BlockActionButtons, { actions: blockActions, position, variant: "toolbar" }),
|
|
10963
|
-
/* @__PURE__ */ jsxRuntime.jsx(ToolbarButton2, { label: "Edit", onClick: () => onOpenBlockChange?.(id), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "h-3.5 w-3.5" }) }),
|
|
10964
|
-
/* @__PURE__ */ jsxRuntime.jsx(ToolbarButton2, { label: "Duplicate", onClick: () => onDuplicate(id), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { className: "h-3.5 w-3.5" }) }),
|
|
10965
|
-
/* @__PURE__ */ jsxRuntime.jsx(ToolbarButton2, { label: "Delete", destructive: true, onClick: () => onDelete(id), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-3.5 w-3.5" }) })
|
|
10966
|
-
]
|
|
10967
|
-
}
|
|
10968
|
-
),
|
|
11108
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
11109
|
+
card,
|
|
11110
|
+
toolbar
|
|
11111
|
+
] }),
|
|
10969
11112
|
/* @__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: [
|
|
10970
11113
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-[11px] font-medium text-muted-foreground", children: "Container" }),
|
|
10971
11114
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
@@ -11382,6 +11525,7 @@ function Toolbar2({
|
|
|
11382
11525
|
canRedo = false,
|
|
11383
11526
|
onUndo,
|
|
11384
11527
|
onRedo,
|
|
11528
|
+
undoRedoShortcuts = true,
|
|
11385
11529
|
onClear,
|
|
11386
11530
|
onOpenJson,
|
|
11387
11531
|
onOpenIssues,
|
|
@@ -11415,6 +11559,7 @@ function Toolbar2({
|
|
|
11415
11559
|
const showSurfaceControl = surfaceOptions.length > 1;
|
|
11416
11560
|
const docsHref = docsLink === false ? null : docsLink?.href ?? DEFAULT_DOCS_HREF;
|
|
11417
11561
|
const docsLabel = docsLink === false ? null : docsLink?.label ?? DEFAULT_DOCS_LABEL;
|
|
11562
|
+
const isApple = useIsApplePlatform();
|
|
11418
11563
|
const [surfaceMenuOpen, setSurfaceMenuOpen] = React.useState(false);
|
|
11419
11564
|
const [themeMenuOpen, setThemeMenuOpen] = React.useState(false);
|
|
11420
11565
|
const [sendMenuOpen, setSendMenuOpen] = React.useState(false);
|
|
@@ -11505,7 +11650,8 @@ function Toolbar2({
|
|
|
11505
11650
|
onClick: onUndo,
|
|
11506
11651
|
disabled: !canUndo,
|
|
11507
11652
|
"aria-label": "Undo",
|
|
11508
|
-
|
|
11653
|
+
"aria-keyshortcuts": undoRedoShortcuts ? "Control+Z Meta+Z" : void 0,
|
|
11654
|
+
title: undoRedoShortcuts ? `Undo (${isApple ? "\u2318Z" : "Ctrl+Z"})` : "Undo",
|
|
11509
11655
|
className: "px-2",
|
|
11510
11656
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Undo2, { className: "h-3.5 w-3.5" })
|
|
11511
11657
|
}
|
|
@@ -11519,7 +11665,8 @@ function Toolbar2({
|
|
|
11519
11665
|
onClick: onRedo,
|
|
11520
11666
|
disabled: !canRedo,
|
|
11521
11667
|
"aria-label": "Redo",
|
|
11522
|
-
|
|
11668
|
+
"aria-keyshortcuts": undoRedoShortcuts ? "Control+Shift+Z Meta+Shift+Z Control+Y" : void 0,
|
|
11669
|
+
title: undoRedoShortcuts ? `Redo (${isApple ? "\u21E7\u2318Z" : "Ctrl+Shift+Z"})` : "Redo",
|
|
11523
11670
|
className: "px-2",
|
|
11524
11671
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Redo2, { className: "h-3.5 w-3.5" })
|
|
11525
11672
|
}
|
|
@@ -11868,6 +12015,7 @@ function BlockKitchen(props) {
|
|
|
11868
12015
|
previewHooks,
|
|
11869
12016
|
blockActions,
|
|
11870
12017
|
renderBlockAdornment,
|
|
12018
|
+
blockEditors,
|
|
11871
12019
|
customEmojis,
|
|
11872
12020
|
mentions,
|
|
11873
12021
|
loadChannels,
|
|
@@ -11893,7 +12041,8 @@ function BlockKitchen(props) {
|
|
|
11893
12041
|
previewTheme: controlledPreviewTheme,
|
|
11894
12042
|
sendButtonLabel,
|
|
11895
12043
|
confirmSendLabel,
|
|
11896
|
-
theme
|
|
12044
|
+
theme,
|
|
12045
|
+
undoRedoShortcuts = true
|
|
11897
12046
|
// Widen the all-or-nothing union so the branch-specific props
|
|
11898
12047
|
// destructure as independent optionals: untyped JS consumers can still
|
|
11899
12048
|
// pass partial wiring (handled by the runtime guards below), and the
|
|
@@ -12073,7 +12222,7 @@ function BlockKitchen(props) {
|
|
|
12073
12222
|
const variantId = parsePaletteDragId(active.id);
|
|
12074
12223
|
if (variantId) {
|
|
12075
12224
|
const variant = variantById.get(variantId);
|
|
12076
|
-
if (!variant) {
|
|
12225
|
+
if (!variant || variant.locked) {
|
|
12077
12226
|
return;
|
|
12078
12227
|
}
|
|
12079
12228
|
if (target.kind === "container") {
|
|
@@ -12092,30 +12241,47 @@ function BlockKitchen(props) {
|
|
|
12092
12241
|
const handleDragCancel = React.useCallback(() => {
|
|
12093
12242
|
setActivePaletteVariantId(null);
|
|
12094
12243
|
}, []);
|
|
12095
|
-
const
|
|
12244
|
+
const runHistoryShortcut = React.useCallback(
|
|
12096
12245
|
(event) => {
|
|
12097
|
-
|
|
12098
|
-
|
|
12099
|
-
}
|
|
12100
|
-
const key = event.key.toLowerCase();
|
|
12101
|
-
const isUndo = key === "z" && !event.shiftKey;
|
|
12102
|
-
const isRedo = key === "y" || key === "z" && event.shiftKey;
|
|
12103
|
-
if (!isUndo && !isRedo) {
|
|
12246
|
+
const action = historyShortcutOf(event);
|
|
12247
|
+
if (!undoRedoShortcuts || !action || event.defaultPrevented || isTextEditingTarget(event.target)) {
|
|
12104
12248
|
return;
|
|
12105
12249
|
}
|
|
12106
|
-
|
|
12107
|
-
if (target && (target.isContentEditable || ["INPUT", "TEXTAREA", "SELECT"].includes(target.tagName))) {
|
|
12250
|
+
if (action === "undo" ? !canUndo : !canRedo) {
|
|
12108
12251
|
return;
|
|
12109
12252
|
}
|
|
12110
12253
|
event.preventDefault();
|
|
12111
|
-
if (
|
|
12112
|
-
if (canRedo) redo();
|
|
12113
|
-
} else if (canUndo) {
|
|
12254
|
+
if (action === "undo") {
|
|
12114
12255
|
undo();
|
|
12256
|
+
} else {
|
|
12257
|
+
redo();
|
|
12115
12258
|
}
|
|
12116
12259
|
},
|
|
12117
|
-
[canRedo, canUndo, redo, undo]
|
|
12260
|
+
[canRedo, canUndo, redo, undo, undoRedoShortcuts]
|
|
12118
12261
|
);
|
|
12262
|
+
const rootRef = React.useRef(null);
|
|
12263
|
+
const lastClickInBuilderRef = React.useRef(false);
|
|
12264
|
+
React.useEffect(() => {
|
|
12265
|
+
if (!undoRedoShortcuts) {
|
|
12266
|
+
return;
|
|
12267
|
+
}
|
|
12268
|
+
const onPointerDown = () => {
|
|
12269
|
+
lastClickInBuilderRef.current = false;
|
|
12270
|
+
};
|
|
12271
|
+
const onKeyDown = (event) => {
|
|
12272
|
+
const root = rootRef.current;
|
|
12273
|
+
const focusAroundBuilder = event.target instanceof Node && root !== null && event.target.contains(root);
|
|
12274
|
+
if (focusAroundBuilder && lastClickInBuilderRef.current) {
|
|
12275
|
+
runHistoryShortcut(event);
|
|
12276
|
+
}
|
|
12277
|
+
};
|
|
12278
|
+
window.addEventListener("pointerdown", onPointerDown, true);
|
|
12279
|
+
window.addEventListener("keydown", onKeyDown);
|
|
12280
|
+
return () => {
|
|
12281
|
+
window.removeEventListener("pointerdown", onPointerDown, true);
|
|
12282
|
+
window.removeEventListener("keydown", onKeyDown);
|
|
12283
|
+
};
|
|
12284
|
+
}, [runHistoryShortcut, undoRedoShortcuts]);
|
|
12119
12285
|
const activePaletteVariant = activePaletteVariantId ? variantById.get(activePaletteVariantId) : null;
|
|
12120
12286
|
const blockPayloads = blocks.map((b) => b.block);
|
|
12121
12287
|
return /* @__PURE__ */ jsxRuntime.jsx(BrandThemeScope, { theme, children: /* @__PURE__ */ jsxRuntime.jsx(CustomEmojiProvider, { customEmojis, children: /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -12130,8 +12296,12 @@ function BlockKitchen(props) {
|
|
|
12130
12296
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
12131
12297
|
"div",
|
|
12132
12298
|
{
|
|
12299
|
+
ref: rootRef,
|
|
12133
12300
|
className: "bk-root flex h-full max-h-[var(--bk-max-height,100svh)] w-full flex-col overflow-hidden rounded-md border bg-background text-foreground",
|
|
12134
|
-
onKeyDown:
|
|
12301
|
+
onKeyDown: runHistoryShortcut,
|
|
12302
|
+
onPointerDownCapture: () => {
|
|
12303
|
+
lastClickInBuilderRef.current = true;
|
|
12304
|
+
},
|
|
12135
12305
|
children: [
|
|
12136
12306
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
12137
12307
|
Toolbar2,
|
|
@@ -12140,6 +12310,7 @@ function BlockKitchen(props) {
|
|
|
12140
12310
|
canRedo,
|
|
12141
12311
|
onUndo: undo,
|
|
12142
12312
|
onRedo: redo,
|
|
12313
|
+
undoRedoShortcuts,
|
|
12143
12314
|
onClear: () => replaceAll([]),
|
|
12144
12315
|
onOpenJson: () => setJsonOpen(true),
|
|
12145
12316
|
onOpenIssues: () => setIssuesOpen(true),
|
|
@@ -12230,7 +12401,7 @@ function BlockKitchen(props) {
|
|
|
12230
12401
|
}
|
|
12231
12402
|
)
|
|
12232
12403
|
] }),
|
|
12233
|
-
/* @__PURE__ */ jsxRuntime.jsx(MentionsProvider, { mentions, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
12404
|
+
/* @__PURE__ */ jsxRuntime.jsx(MentionsProvider, { mentions, children: /* @__PURE__ */ jsxRuntime.jsx(BlockEditorsProvider, { blockEditors, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
12234
12405
|
Surface,
|
|
12235
12406
|
{
|
|
12236
12407
|
blocks,
|
|
@@ -12252,7 +12423,7 @@ function BlockKitchen(props) {
|
|
|
12252
12423
|
blockActions,
|
|
12253
12424
|
renderBlockAdornment
|
|
12254
12425
|
}
|
|
12255
|
-
) })
|
|
12426
|
+
) }) })
|
|
12256
12427
|
] })
|
|
12257
12428
|
]
|
|
12258
12429
|
}
|
|
@@ -12283,6 +12454,7 @@ function BlockKitchen(props) {
|
|
|
12283
12454
|
addBlock(block);
|
|
12284
12455
|
setPaletteOpen(false);
|
|
12285
12456
|
},
|
|
12457
|
+
onLockedPicked: () => setPaletteOpen(false),
|
|
12286
12458
|
sections: paletteSections,
|
|
12287
12459
|
mode: paletteMode,
|
|
12288
12460
|
showSearch: showPaletteSearch,
|