@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.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useSensors, useSensor, PointerSensor, TouchSensor, KeyboardSensor, pointerWithin, closestCenter, DndContext, DragOverlay, useDroppable, useDraggable } from '@dnd-kit/core';
|
|
2
2
|
import { sortableKeyboardCoordinates, SortableContext, verticalListSortingStrategy, useSortable } from '@dnd-kit/sortable';
|
|
3
|
-
import { X, Circle, Sparkles, FileText, AlignLeft, MousePointerClick, TextCursorInput, LayoutTemplate, Bell, Pilcrow, Image, Video, GalleryHorizontal, Table, ChartColumnBig, Container, Loader2, ExternalLink, AlertTriangle, ChevronRight, ChevronLeft, GripVertical, ChevronsUpDown, Check, Sun, Moon, MessageSquare, AppWindow, Home, Plus, ChevronDown, BookOpen, Undo2, Redo2, Trash2, Code2, Pencil, Send, Search, Copy, Info, CheckCircle2, LayoutGrid, ArrowUp, ArrowDown, Type, Bold, Italic, Strikethrough, Underline, Code, AtSign, Hash, List, ListOrdered, Quote, Smile, Link as Link$1 } from 'lucide-react';
|
|
3
|
+
import { X, Circle, Sparkles, FileText, AlignLeft, MousePointerClick, TextCursorInput, LayoutTemplate, Bell, Pilcrow, Image, Video, GalleryHorizontal, Table, ChartColumnBig, Container, Loader2, ExternalLink, AlertTriangle, ChevronRight, ChevronLeft, GripVertical, ChevronsUpDown, Check, Sun, Moon, MessageSquare, AppWindow, Home, Plus, ChevronDown, BookOpen, Undo2, Redo2, Trash2, Code2, Pencil, Send, Search, Copy, Info, CheckCircle2, LayoutGrid, ArrowUp, ArrowDown, Lock, Type, Bold, Italic, Strikethrough, Underline, Code, AtSign, Hash, List, ListOrdered, Quote, Smile, Link as Link$1 } from 'lucide-react';
|
|
4
4
|
import * as React from 'react';
|
|
5
|
-
import { createContext, useContext, useState, useRef, useEffect, useCallback, useMemo, useId } from 'react';
|
|
5
|
+
import { createContext, useContext, useState, useRef, useEffect, useCallback, useMemo, useId, useSyncExternalStore, useLayoutEffect } from 'react';
|
|
6
6
|
import { clsx } from 'clsx';
|
|
7
7
|
import { twMerge } from 'tailwind-merge';
|
|
8
8
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
@@ -1787,6 +1787,35 @@ function labelForBlockType(type) {
|
|
|
1787
1787
|
return "Data Table";
|
|
1788
1788
|
}
|
|
1789
1789
|
}
|
|
1790
|
+
function historyShortcutOf(event) {
|
|
1791
|
+
if (!(event.metaKey || event.ctrlKey) || event.altKey) {
|
|
1792
|
+
return null;
|
|
1793
|
+
}
|
|
1794
|
+
const key = event.key.toLowerCase();
|
|
1795
|
+
if (key === "z") {
|
|
1796
|
+
return event.shiftKey ? "redo" : "undo";
|
|
1797
|
+
}
|
|
1798
|
+
return key === "y" ? "redo" : null;
|
|
1799
|
+
}
|
|
1800
|
+
function isTextEditingTarget(target) {
|
|
1801
|
+
if (!(target instanceof HTMLElement)) {
|
|
1802
|
+
return false;
|
|
1803
|
+
}
|
|
1804
|
+
return target.isContentEditable || // jsdom has no `isContentEditable`, so check the attribute too.
|
|
1805
|
+
target.closest('[contenteditable=""], [contenteditable="true"], [contenteditable="plaintext-only"]') !== null || ["INPUT", "TEXTAREA", "SELECT"].includes(target.tagName);
|
|
1806
|
+
}
|
|
1807
|
+
function isApplePlatform() {
|
|
1808
|
+
if (typeof navigator === "undefined") {
|
|
1809
|
+
return false;
|
|
1810
|
+
}
|
|
1811
|
+
const { userAgentData } = navigator;
|
|
1812
|
+
return /mac|iphone|ipad|ipod/i.test(userAgentData?.platform ?? navigator.platform ?? "");
|
|
1813
|
+
}
|
|
1814
|
+
var subscribeToNothing = () => () => {
|
|
1815
|
+
};
|
|
1816
|
+
function useIsApplePlatform() {
|
|
1817
|
+
return useSyncExternalStore(subscribeToNothing, isApplePlatform, () => false);
|
|
1818
|
+
}
|
|
1790
1819
|
var Sheet = DialogPrimitive.Root;
|
|
1791
1820
|
var SheetOverlay = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1792
1821
|
DialogPrimitive.Overlay,
|
|
@@ -1868,6 +1897,16 @@ function useIsMobile() {
|
|
|
1868
1897
|
}, []);
|
|
1869
1898
|
return isMobile;
|
|
1870
1899
|
}
|
|
1900
|
+
var BlockEditorsContext = createContext([]);
|
|
1901
|
+
function BlockEditorsProvider({
|
|
1902
|
+
blockEditors,
|
|
1903
|
+
children
|
|
1904
|
+
}) {
|
|
1905
|
+
return /* @__PURE__ */ jsx(BlockEditorsContext.Provider, { value: blockEditors ?? [], children });
|
|
1906
|
+
}
|
|
1907
|
+
function useCustomBlockEditor(block) {
|
|
1908
|
+
return useContext(BlockEditorsContext).find((editor) => editor.match(block));
|
|
1909
|
+
}
|
|
1871
1910
|
var EMPTY = {
|
|
1872
1911
|
customEmojis: [],
|
|
1873
1912
|
byName: /* @__PURE__ */ new Map()
|
|
@@ -4209,6 +4248,7 @@ function Palette({
|
|
|
4209
4248
|
mode = "advanced",
|
|
4210
4249
|
defaultAdvanced = false,
|
|
4211
4250
|
onAdvancedChange,
|
|
4251
|
+
onLockedPicked,
|
|
4212
4252
|
variant = "aside"
|
|
4213
4253
|
}) {
|
|
4214
4254
|
const [query, setQuery] = useState("");
|
|
@@ -4302,7 +4342,16 @@ function Palette({
|
|
|
4302
4342
|
/* @__PURE__ */ jsx("div", { className: cn("flex flex-col", isSheet ? "px-2 pb-6" : "p-3"), children: !advanced ? (
|
|
4303
4343
|
// Simple mode: a flat list, no section headings — with this few
|
|
4304
4344
|
// rows the headings would outnumber the blocks under them.
|
|
4305
|
-
basics.map((v) => /* @__PURE__ */ jsx(
|
|
4345
|
+
basics.map((v) => /* @__PURE__ */ jsx(
|
|
4346
|
+
PaletteItem,
|
|
4347
|
+
{
|
|
4348
|
+
variant: v,
|
|
4349
|
+
onAdd: () => onAddBlock(v.factory()),
|
|
4350
|
+
onLockedPicked,
|
|
4351
|
+
mode: variant
|
|
4352
|
+
},
|
|
4353
|
+
v.id
|
|
4354
|
+
))
|
|
4306
4355
|
) : visibleSections.length === 0 ? /* @__PURE__ */ jsx("p", { className: "px-1 py-2 text-xs text-muted-foreground", children: "No blocks match." }) : visibleSections.map((section) => /* @__PURE__ */ jsx(
|
|
4307
4356
|
PaletteSection,
|
|
4308
4357
|
{
|
|
@@ -4310,6 +4359,7 @@ function Palette({
|
|
|
4310
4359
|
defaultOpen: isDefaultOpen(section.name, defaultOpenSections),
|
|
4311
4360
|
forceOpen: queryActive,
|
|
4312
4361
|
onAddBlock,
|
|
4362
|
+
onLockedPicked,
|
|
4313
4363
|
variant
|
|
4314
4364
|
},
|
|
4315
4365
|
section.name
|
|
@@ -4341,6 +4391,7 @@ function PaletteSection({
|
|
|
4341
4391
|
defaultOpen,
|
|
4342
4392
|
forceOpen,
|
|
4343
4393
|
onAddBlock,
|
|
4394
|
+
onLockedPicked,
|
|
4344
4395
|
variant = "aside"
|
|
4345
4396
|
}) {
|
|
4346
4397
|
const [open, setOpen] = useState(defaultOpen);
|
|
@@ -4372,18 +4423,32 @@ function PaletteSection({
|
|
|
4372
4423
|
]
|
|
4373
4424
|
}
|
|
4374
4425
|
),
|
|
4375
|
-
isOpen ? /* @__PURE__ */ jsx("div", { className: "mt-0.5 flex flex-col", children: section.variants.map((v) => /* @__PURE__ */ jsx(
|
|
4426
|
+
isOpen ? /* @__PURE__ */ jsx("div", { className: "mt-0.5 flex flex-col", children: section.variants.map((v) => /* @__PURE__ */ jsx(
|
|
4427
|
+
PaletteItem,
|
|
4428
|
+
{
|
|
4429
|
+
variant: v,
|
|
4430
|
+
onAdd: () => onAddBlock(v.factory()),
|
|
4431
|
+
onLockedPicked,
|
|
4432
|
+
mode: variant
|
|
4433
|
+
},
|
|
4434
|
+
v.id
|
|
4435
|
+
)) }) : null
|
|
4376
4436
|
] });
|
|
4377
4437
|
}
|
|
4378
4438
|
function PaletteItem({
|
|
4379
4439
|
variant,
|
|
4380
4440
|
onAdd,
|
|
4441
|
+
onLockedPicked,
|
|
4381
4442
|
mode = "aside"
|
|
4382
4443
|
}) {
|
|
4383
4444
|
const { attributes, listeners, setNodeRef, setActivatorNodeRef, isDragging } = useDraggable({
|
|
4384
|
-
id: `${PALETTE_DRAG_PREFIX}${variant.id}
|
|
4445
|
+
id: `${PALETTE_DRAG_PREFIX}${variant.id}`,
|
|
4446
|
+
disabled: variant.locked
|
|
4385
4447
|
});
|
|
4386
4448
|
const isSheet = mode === "sheet";
|
|
4449
|
+
if (variant.locked) {
|
|
4450
|
+
return /* @__PURE__ */ jsx(LockedPaletteItem, { variant, isSheet, onPicked: onLockedPicked });
|
|
4451
|
+
}
|
|
4387
4452
|
if (isSheet) {
|
|
4388
4453
|
return /* @__PURE__ */ jsxs(
|
|
4389
4454
|
"button",
|
|
@@ -4398,6 +4463,7 @@ function PaletteItem({
|
|
|
4398
4463
|
),
|
|
4399
4464
|
children: [
|
|
4400
4465
|
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: variant.label }),
|
|
4466
|
+
variant.badge ? /* @__PURE__ */ jsx(VariantBadge, { badge: variant.badge }) : null,
|
|
4401
4467
|
/* @__PURE__ */ 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__ */ jsx(ChevronRight, { className: "h-4 w-4" }) })
|
|
4402
4468
|
]
|
|
4403
4469
|
}
|
|
@@ -4408,7 +4474,7 @@ function PaletteItem({
|
|
|
4408
4474
|
{
|
|
4409
4475
|
ref: setNodeRef,
|
|
4410
4476
|
className: cn(
|
|
4411
|
-
"group flex items-
|
|
4477
|
+
"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",
|
|
4412
4478
|
isDragging && "opacity-50"
|
|
4413
4479
|
),
|
|
4414
4480
|
children: [
|
|
@@ -4416,12 +4482,12 @@ function PaletteItem({
|
|
|
4416
4482
|
"div",
|
|
4417
4483
|
{
|
|
4418
4484
|
ref: setActivatorNodeRef,
|
|
4419
|
-
className: "-my-1 flex min-w-0 flex-1 cursor-grab items-
|
|
4485
|
+
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",
|
|
4420
4486
|
...attributes,
|
|
4421
4487
|
...listeners,
|
|
4422
4488
|
children: [
|
|
4423
|
-
/* @__PURE__ */ jsx(GripVertical, { className: "h-3.5 w-3.5 shrink-0" }),
|
|
4424
|
-
/* @__PURE__ */ jsx(
|
|
4489
|
+
/* @__PURE__ */ jsx(GripVertical, { className: "mt-[3px] h-3.5 w-3.5 shrink-0" }),
|
|
4490
|
+
/* @__PURE__ */ jsx(RailLabel, { variant })
|
|
4425
4491
|
]
|
|
4426
4492
|
}
|
|
4427
4493
|
),
|
|
@@ -4439,6 +4505,69 @@ function PaletteItem({
|
|
|
4439
4505
|
}
|
|
4440
4506
|
);
|
|
4441
4507
|
}
|
|
4508
|
+
function LockedPaletteItem({
|
|
4509
|
+
variant,
|
|
4510
|
+
isSheet,
|
|
4511
|
+
onPicked
|
|
4512
|
+
}) {
|
|
4513
|
+
const select = variant.onLockedSelect;
|
|
4514
|
+
const className = cn(
|
|
4515
|
+
"flex w-full text-left text-muted-foreground",
|
|
4516
|
+
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"
|
|
4517
|
+
);
|
|
4518
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4519
|
+
/* @__PURE__ */ jsx(Lock, { "aria-hidden": true, className: cn("shrink-0", isSheet ? "h-4 w-4" : "mt-[3px] h-3.5 w-3.5") }),
|
|
4520
|
+
isSheet ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4521
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: variant.label }),
|
|
4522
|
+
variant.badge ? /* @__PURE__ */ jsx(VariantBadge, { badge: variant.badge }) : null
|
|
4523
|
+
] }) : /* @__PURE__ */ jsx(RailLabel, { variant })
|
|
4524
|
+
] });
|
|
4525
|
+
if (!select) {
|
|
4526
|
+
return /* @__PURE__ */ jsx("div", { "aria-disabled": "true", className, children: content });
|
|
4527
|
+
}
|
|
4528
|
+
return /* @__PURE__ */ jsx(
|
|
4529
|
+
"button",
|
|
4530
|
+
{
|
|
4531
|
+
type: "button",
|
|
4532
|
+
"aria-label": `${variant.label} (locked${variant.badge ? `, ${variant.badge.label}` : ""})`,
|
|
4533
|
+
onClick: () => {
|
|
4534
|
+
onPicked?.();
|
|
4535
|
+
select();
|
|
4536
|
+
},
|
|
4537
|
+
className: cn(
|
|
4538
|
+
className,
|
|
4539
|
+
"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"
|
|
4540
|
+
),
|
|
4541
|
+
children: content
|
|
4542
|
+
}
|
|
4543
|
+
);
|
|
4544
|
+
}
|
|
4545
|
+
function RailLabel({ variant }) {
|
|
4546
|
+
if (!variant.badge) {
|
|
4547
|
+
return /* @__PURE__ */ jsx("span", { className: "truncate", children: variant.label });
|
|
4548
|
+
}
|
|
4549
|
+
return /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-col items-start gap-0.5", children: [
|
|
4550
|
+
/* @__PURE__ */ jsx("span", { className: "max-w-full truncate", children: variant.label }),
|
|
4551
|
+
" ",
|
|
4552
|
+
/* @__PURE__ */ jsx(VariantBadge, { badge: variant.badge })
|
|
4553
|
+
] });
|
|
4554
|
+
}
|
|
4555
|
+
function VariantBadge({ badge }) {
|
|
4556
|
+
const Icon = badge.icon;
|
|
4557
|
+
return /* @__PURE__ */ jsxs(
|
|
4558
|
+
"span",
|
|
4559
|
+
{
|
|
4560
|
+
className: cn(
|
|
4561
|
+
"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",
|
|
4562
|
+
badge.className
|
|
4563
|
+
),
|
|
4564
|
+
children: [
|
|
4565
|
+
Icon ? /* @__PURE__ */ jsx(Icon, { "aria-hidden": true, className: "h-2.5 w-2.5 shrink-0" }) : null,
|
|
4566
|
+
badge.label
|
|
4567
|
+
]
|
|
4568
|
+
}
|
|
4569
|
+
);
|
|
4570
|
+
}
|
|
4442
4571
|
function SendDialog({
|
|
4443
4572
|
open,
|
|
4444
4573
|
onOpenChange,
|
|
@@ -6258,7 +6387,7 @@ function MentionPicker({
|
|
|
6258
6387
|
const listRef = useRef(null);
|
|
6259
6388
|
const listboxId = useId();
|
|
6260
6389
|
const activeOptionId = items[activeIndex] ? `${listboxId}-${activeIndex}` : void 0;
|
|
6261
|
-
|
|
6390
|
+
useLayoutEffect(() => {
|
|
6262
6391
|
const root = editor.view.dom;
|
|
6263
6392
|
root.setAttribute("role", "combobox");
|
|
6264
6393
|
root.setAttribute("aria-autocomplete", "list");
|
|
@@ -6277,7 +6406,7 @@ function MentionPicker({
|
|
|
6277
6406
|
root.removeAttribute("aria-activedescendant");
|
|
6278
6407
|
};
|
|
6279
6408
|
}, [activeOptionId, editor, listboxId]);
|
|
6280
|
-
|
|
6409
|
+
useLayoutEffect(() => {
|
|
6281
6410
|
keyHandlerRef.current = (event) => {
|
|
6282
6411
|
if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
|
6283
6412
|
if (items.length > 0) {
|
|
@@ -10367,13 +10496,15 @@ function BlockEditor({
|
|
|
10367
10496
|
onChange,
|
|
10368
10497
|
onDone
|
|
10369
10498
|
}) {
|
|
10499
|
+
const custom = useCustomBlockEditor(block);
|
|
10500
|
+
const CustomForm = custom?.component;
|
|
10370
10501
|
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
10371
10502
|
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs("h3", { className: "text-sm font-semibold text-foreground", children: [
|
|
10372
10503
|
"Edit ",
|
|
10373
|
-
labelForBlockType(block.type)
|
|
10504
|
+
custom ? custom.label : labelForBlockType(block.type)
|
|
10374
10505
|
] }) }),
|
|
10375
10506
|
errors && errors.length > 0 ? /* @__PURE__ */ 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__ */ jsx("li", { children: err }, i)) }) : null,
|
|
10376
|
-
dispatch(block, onChange),
|
|
10507
|
+
CustomForm ? /* @__PURE__ */ jsx(CustomForm, { block, onChange }) : dispatch(block, onChange),
|
|
10377
10508
|
/* @__PURE__ */ jsx(
|
|
10378
10509
|
AdvancedIdField,
|
|
10379
10510
|
{
|
|
@@ -10544,6 +10675,122 @@ function BlockRow({
|
|
|
10544
10675
|
) })
|
|
10545
10676
|
] });
|
|
10546
10677
|
const adornment = position && renderBlockAdornment?.(position);
|
|
10678
|
+
const hoverChrome = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
10679
|
+
/* @__PURE__ */ 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] }),
|
|
10680
|
+
/* @__PURE__ */ jsxs(
|
|
10681
|
+
"div",
|
|
10682
|
+
{
|
|
10683
|
+
className: cn(
|
|
10684
|
+
// Hidden on mobile in favor of the inline row below; on desktop
|
|
10685
|
+
// reveal on hover, on keyboard focus inside the row (so Tab-stops on
|
|
10686
|
+
// the floating buttons themselves keep them visible), and when there
|
|
10687
|
+
// are validation errors worth surfacing immediately.
|
|
10688
|
+
// :focus-visible, not :focus-within — a drag leaves pointer focus on
|
|
10689
|
+
// the block, which would otherwise pin the toolbar open until a click.
|
|
10690
|
+
"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",
|
|
10691
|
+
hasErrors ? "opacity-100" : "opacity-0 group-hover:opacity-100 group-has-[:focus-visible]:opacity-100"
|
|
10692
|
+
),
|
|
10693
|
+
children: [
|
|
10694
|
+
hasErrors ? /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
10695
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
10696
|
+
"button",
|
|
10697
|
+
{
|
|
10698
|
+
type: "button",
|
|
10699
|
+
"aria-label": `Show ${errors.length} validation ${errors.length === 1 ? "issue" : "issues"}`,
|
|
10700
|
+
onClick: () => onOpenChange?.(true),
|
|
10701
|
+
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",
|
|
10702
|
+
children: /* @__PURE__ */ jsx(AlertTriangle, { className: "h-3.5 w-3.5" })
|
|
10703
|
+
}
|
|
10704
|
+
) }),
|
|
10705
|
+
/* @__PURE__ */ jsx(TooltipContent, { side: "top", align: "end", children: /* @__PURE__ */ jsxs("ul", { className: "flex flex-col gap-0.5", children: [
|
|
10706
|
+
errors.slice(0, 4).map((err, i) => /* @__PURE__ */ jsx("li", { children: err }, i)),
|
|
10707
|
+
errors.length > 4 ? /* @__PURE__ */ jsxs("li", { className: "text-muted-foreground", children: [
|
|
10708
|
+
"and ",
|
|
10709
|
+
errors.length - 4,
|
|
10710
|
+
" more"
|
|
10711
|
+
] }) : null
|
|
10712
|
+
] }) })
|
|
10713
|
+
] }) : null,
|
|
10714
|
+
onReorder && typeof index === "number" && typeof total === "number" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
10715
|
+
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
10716
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
10717
|
+
"button",
|
|
10718
|
+
{
|
|
10719
|
+
type: "button",
|
|
10720
|
+
"aria-label": "Move block up",
|
|
10721
|
+
disabled: index === 0,
|
|
10722
|
+
onClick: () => onReorder(builderBlock.id, index - 1),
|
|
10723
|
+
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",
|
|
10724
|
+
children: /* @__PURE__ */ jsx(ArrowUp, { className: "h-3.5 w-3.5" })
|
|
10725
|
+
}
|
|
10726
|
+
) }),
|
|
10727
|
+
/* @__PURE__ */ jsx(TooltipContent, { side: "top", children: "Move up" })
|
|
10728
|
+
] }),
|
|
10729
|
+
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
10730
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
10731
|
+
"button",
|
|
10732
|
+
{
|
|
10733
|
+
type: "button",
|
|
10734
|
+
"aria-label": "Move block down",
|
|
10735
|
+
disabled: index >= total - 1,
|
|
10736
|
+
onClick: () => onReorder(builderBlock.id, index + 1),
|
|
10737
|
+
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",
|
|
10738
|
+
children: /* @__PURE__ */ jsx(ArrowDown, { className: "h-3.5 w-3.5" })
|
|
10739
|
+
}
|
|
10740
|
+
) }),
|
|
10741
|
+
/* @__PURE__ */ jsx(TooltipContent, { side: "top", children: "Move down" })
|
|
10742
|
+
] })
|
|
10743
|
+
] }) : null,
|
|
10744
|
+
/* @__PURE__ */ jsx(BlockActionButtons, { actions: blockActions, position, variant: "toolbar" }),
|
|
10745
|
+
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
10746
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
10747
|
+
"button",
|
|
10748
|
+
{
|
|
10749
|
+
type: "button",
|
|
10750
|
+
"aria-label": "Edit block",
|
|
10751
|
+
onClick: () => {
|
|
10752
|
+
if (isRichText) {
|
|
10753
|
+
setInlineEditing(true);
|
|
10754
|
+
} else {
|
|
10755
|
+
onOpenChange?.(true);
|
|
10756
|
+
}
|
|
10757
|
+
},
|
|
10758
|
+
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",
|
|
10759
|
+
children: /* @__PURE__ */ jsx(Pencil, { className: "h-3.5 w-3.5" })
|
|
10760
|
+
}
|
|
10761
|
+
) }),
|
|
10762
|
+
/* @__PURE__ */ jsx(TooltipContent, { side: "top", children: "Edit" })
|
|
10763
|
+
] }),
|
|
10764
|
+
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
10765
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
10766
|
+
"button",
|
|
10767
|
+
{
|
|
10768
|
+
type: "button",
|
|
10769
|
+
"aria-label": "Duplicate block",
|
|
10770
|
+
onClick: () => onDuplicate(builderBlock.id),
|
|
10771
|
+
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",
|
|
10772
|
+
children: /* @__PURE__ */ jsx(Copy, { className: "h-3.5 w-3.5" })
|
|
10773
|
+
}
|
|
10774
|
+
) }),
|
|
10775
|
+
/* @__PURE__ */ jsx(TooltipContent, { side: "top", children: "Duplicate" })
|
|
10776
|
+
] }),
|
|
10777
|
+
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
10778
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
10779
|
+
"button",
|
|
10780
|
+
{
|
|
10781
|
+
type: "button",
|
|
10782
|
+
"aria-label": "Delete block",
|
|
10783
|
+
onClick: () => onDelete(builderBlock.id),
|
|
10784
|
+
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",
|
|
10785
|
+
children: /* @__PURE__ */ jsx(Trash2, { className: "h-3.5 w-3.5" })
|
|
10786
|
+
}
|
|
10787
|
+
) }),
|
|
10788
|
+
/* @__PURE__ */ jsx(TooltipContent, { side: "top", children: "Delete" })
|
|
10789
|
+
] })
|
|
10790
|
+
]
|
|
10791
|
+
}
|
|
10792
|
+
)
|
|
10793
|
+
] });
|
|
10547
10794
|
return /* @__PURE__ */ jsxs(
|
|
10548
10795
|
"div",
|
|
10549
10796
|
{
|
|
@@ -10561,126 +10808,16 @@ function BlockRow({
|
|
|
10561
10808
|
children: /* @__PURE__ */ jsx("span", { className: "-left-1 -top-[3px] absolute h-2 w-2 rounded-full bg-primary shadow-[0_0_0_2px_var(--color-background)]" })
|
|
10562
10809
|
}
|
|
10563
10810
|
) : null,
|
|
10564
|
-
/* @__PURE__ */
|
|
10565
|
-
|
|
10566
|
-
|
|
10567
|
-
|
|
10568
|
-
] })
|
|
10569
|
-
/* @__PURE__ */ jsx("
|
|
10570
|
-
|
|
10571
|
-
|
|
10572
|
-
|
|
10573
|
-
|
|
10574
|
-
// Hidden on mobile in favor of the inline row below; on desktop
|
|
10575
|
-
// reveal on hover, on keyboard focus inside the row (so Tab-stops on
|
|
10576
|
-
// the floating buttons themselves keep them visible), and when there
|
|
10577
|
-
// are validation errors worth surfacing immediately.
|
|
10578
|
-
// :focus-visible, not :focus-within — a drag leaves pointer focus on
|
|
10579
|
-
// the block, which would otherwise pin the toolbar open until a click.
|
|
10580
|
-
"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",
|
|
10581
|
-
hasErrors ? "opacity-100" : "opacity-0 group-hover:opacity-100 group-has-[:focus-visible]:opacity-100"
|
|
10582
|
-
),
|
|
10583
|
-
children: [
|
|
10584
|
-
hasErrors ? /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
10585
|
-
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
10586
|
-
"button",
|
|
10587
|
-
{
|
|
10588
|
-
type: "button",
|
|
10589
|
-
"aria-label": `Show ${errors.length} validation ${errors.length === 1 ? "issue" : "issues"}`,
|
|
10590
|
-
onClick: () => onOpenChange?.(true),
|
|
10591
|
-
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",
|
|
10592
|
-
children: /* @__PURE__ */ jsx(AlertTriangle, { className: "h-3.5 w-3.5" })
|
|
10593
|
-
}
|
|
10594
|
-
) }),
|
|
10595
|
-
/* @__PURE__ */ jsx(TooltipContent, { side: "top", align: "end", children: /* @__PURE__ */ jsxs("ul", { className: "flex flex-col gap-0.5", children: [
|
|
10596
|
-
errors.slice(0, 4).map((err, i) => /* @__PURE__ */ jsx("li", { children: err }, i)),
|
|
10597
|
-
errors.length > 4 ? /* @__PURE__ */ jsxs("li", { className: "text-muted-foreground", children: [
|
|
10598
|
-
"and ",
|
|
10599
|
-
errors.length - 4,
|
|
10600
|
-
" more"
|
|
10601
|
-
] }) : null
|
|
10602
|
-
] }) })
|
|
10603
|
-
] }) : null,
|
|
10604
|
-
onReorder && typeof index === "number" && typeof total === "number" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
10605
|
-
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
10606
|
-
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
10607
|
-
"button",
|
|
10608
|
-
{
|
|
10609
|
-
type: "button",
|
|
10610
|
-
"aria-label": "Move block up",
|
|
10611
|
-
disabled: index === 0,
|
|
10612
|
-
onClick: () => onReorder(builderBlock.id, index - 1),
|
|
10613
|
-
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",
|
|
10614
|
-
children: /* @__PURE__ */ jsx(ArrowUp, { className: "h-3.5 w-3.5" })
|
|
10615
|
-
}
|
|
10616
|
-
) }),
|
|
10617
|
-
/* @__PURE__ */ jsx(TooltipContent, { side: "top", children: "Move up" })
|
|
10618
|
-
] }),
|
|
10619
|
-
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
10620
|
-
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
10621
|
-
"button",
|
|
10622
|
-
{
|
|
10623
|
-
type: "button",
|
|
10624
|
-
"aria-label": "Move block down",
|
|
10625
|
-
disabled: index >= total - 1,
|
|
10626
|
-
onClick: () => onReorder(builderBlock.id, index + 1),
|
|
10627
|
-
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",
|
|
10628
|
-
children: /* @__PURE__ */ jsx(ArrowDown, { className: "h-3.5 w-3.5" })
|
|
10629
|
-
}
|
|
10630
|
-
) }),
|
|
10631
|
-
/* @__PURE__ */ jsx(TooltipContent, { side: "top", children: "Move down" })
|
|
10632
|
-
] })
|
|
10633
|
-
] }) : null,
|
|
10634
|
-
/* @__PURE__ */ jsx(BlockActionButtons, { actions: blockActions, position, variant: "toolbar" }),
|
|
10635
|
-
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
10636
|
-
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
10637
|
-
"button",
|
|
10638
|
-
{
|
|
10639
|
-
type: "button",
|
|
10640
|
-
"aria-label": "Edit block",
|
|
10641
|
-
onClick: () => {
|
|
10642
|
-
if (isRichText) {
|
|
10643
|
-
setInlineEditing(true);
|
|
10644
|
-
} else {
|
|
10645
|
-
onOpenChange?.(true);
|
|
10646
|
-
}
|
|
10647
|
-
},
|
|
10648
|
-
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",
|
|
10649
|
-
children: /* @__PURE__ */ jsx(Pencil, { className: "h-3.5 w-3.5" })
|
|
10650
|
-
}
|
|
10651
|
-
) }),
|
|
10652
|
-
/* @__PURE__ */ jsx(TooltipContent, { side: "top", children: "Edit" })
|
|
10653
|
-
] }),
|
|
10654
|
-
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
10655
|
-
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
10656
|
-
"button",
|
|
10657
|
-
{
|
|
10658
|
-
type: "button",
|
|
10659
|
-
"aria-label": "Duplicate block",
|
|
10660
|
-
onClick: () => onDuplicate(builderBlock.id),
|
|
10661
|
-
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",
|
|
10662
|
-
children: /* @__PURE__ */ jsx(Copy, { className: "h-3.5 w-3.5" })
|
|
10663
|
-
}
|
|
10664
|
-
) }),
|
|
10665
|
-
/* @__PURE__ */ jsx(TooltipContent, { side: "top", children: "Duplicate" })
|
|
10666
|
-
] }),
|
|
10667
|
-
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
10668
|
-
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
10669
|
-
"button",
|
|
10670
|
-
{
|
|
10671
|
-
type: "button",
|
|
10672
|
-
"aria-label": "Delete block",
|
|
10673
|
-
onClick: () => onDelete(builderBlock.id),
|
|
10674
|
-
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",
|
|
10675
|
-
children: /* @__PURE__ */ jsx(Trash2, { className: "h-3.5 w-3.5" })
|
|
10676
|
-
}
|
|
10677
|
-
) }),
|
|
10678
|
-
/* @__PURE__ */ jsx(TooltipContent, { side: "top", children: "Delete" })
|
|
10679
|
-
] })
|
|
10680
|
-
]
|
|
10681
|
-
}
|
|
10682
|
-
)
|
|
10683
|
-
] }),
|
|
10811
|
+
/* @__PURE__ */ jsx("div", { className: "relative w-full", children: renderBlockAdornment ? /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
|
|
10812
|
+
/* @__PURE__ */ jsxs("div", { className: "relative min-w-0 flex-1", children: [
|
|
10813
|
+
body,
|
|
10814
|
+
hoverChrome
|
|
10815
|
+
] }),
|
|
10816
|
+
adornment != null && adornment !== false ? /* @__PURE__ */ jsx("div", { className: "shrink-0", children: adornment }) : null
|
|
10817
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
10818
|
+
body,
|
|
10819
|
+
hoverChrome
|
|
10820
|
+
] }) }),
|
|
10684
10821
|
/* @__PURE__ */ 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: [
|
|
10685
10822
|
/* @__PURE__ */ jsx("span", { className: "truncate text-[11px] font-medium text-muted-foreground", children: BLOCK_TYPE_LABELS[builderBlock.block.type] }),
|
|
10686
10823
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
@@ -10885,6 +11022,45 @@ function ContainerRow({
|
|
|
10885
11022
|
]
|
|
10886
11023
|
}
|
|
10887
11024
|
);
|
|
11025
|
+
const toolbar = /* @__PURE__ */ jsxs(
|
|
11026
|
+
"div",
|
|
11027
|
+
{
|
|
11028
|
+
className: cn(
|
|
11029
|
+
"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",
|
|
11030
|
+
hasErrors ? "opacity-100" : "opacity-0 group-hover/container:opacity-100 group-has-[:focus-visible]/container:opacity-100"
|
|
11031
|
+
),
|
|
11032
|
+
children: [
|
|
11033
|
+
hasErrors ? /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
11034
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
11035
|
+
"button",
|
|
11036
|
+
{
|
|
11037
|
+
type: "button",
|
|
11038
|
+
"aria-label": `Show ${errors.length} validation ${errors.length === 1 ? "issue" : "issues"}`,
|
|
11039
|
+
onClick: () => onOpenBlockChange?.(id),
|
|
11040
|
+
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",
|
|
11041
|
+
children: /* @__PURE__ */ jsx(AlertTriangle, { className: "h-3.5 w-3.5" })
|
|
11042
|
+
}
|
|
11043
|
+
) }),
|
|
11044
|
+
/* @__PURE__ */ jsx(TooltipContent, { side: "top", align: "end", children: /* @__PURE__ */ jsxs("ul", { className: "flex flex-col gap-0.5", children: [
|
|
11045
|
+
errors.slice(0, 4).map((err, i) => /* @__PURE__ */ jsx("li", { children: err }, i)),
|
|
11046
|
+
errors.length > 4 ? /* @__PURE__ */ jsxs("li", { className: "text-muted-foreground", children: [
|
|
11047
|
+
"and ",
|
|
11048
|
+
errors.length - 4,
|
|
11049
|
+
" more"
|
|
11050
|
+
] }) : null
|
|
11051
|
+
] }) })
|
|
11052
|
+
] }) : null,
|
|
11053
|
+
onReorder && typeof index === "number" && typeof total === "number" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
11054
|
+
/* @__PURE__ */ jsx(ToolbarButton2, { label: "Move up", disabled: index === 0, onClick: () => onReorder(id, index - 1), children: /* @__PURE__ */ jsx(ArrowUp, { className: "h-3.5 w-3.5" }) }),
|
|
11055
|
+
/* @__PURE__ */ jsx(ToolbarButton2, { label: "Move down", disabled: index >= total - 1, onClick: () => onReorder(id, index + 1), children: /* @__PURE__ */ jsx(ArrowDown, { className: "h-3.5 w-3.5" }) })
|
|
11056
|
+
] }) : null,
|
|
11057
|
+
/* @__PURE__ */ jsx(BlockActionButtons, { actions: blockActions, position, variant: "toolbar" }),
|
|
11058
|
+
/* @__PURE__ */ jsx(ToolbarButton2, { label: "Edit", onClick: () => onOpenBlockChange?.(id), children: /* @__PURE__ */ jsx(Pencil, { className: "h-3.5 w-3.5" }) }),
|
|
11059
|
+
/* @__PURE__ */ jsx(ToolbarButton2, { label: "Duplicate", onClick: () => onDuplicate(id), children: /* @__PURE__ */ jsx(Copy, { className: "h-3.5 w-3.5" }) }),
|
|
11060
|
+
/* @__PURE__ */ jsx(ToolbarButton2, { label: "Delete", destructive: true, onClick: () => onDelete(id), children: /* @__PURE__ */ jsx(Trash2, { className: "h-3.5 w-3.5" }) })
|
|
11061
|
+
]
|
|
11062
|
+
}
|
|
11063
|
+
);
|
|
10888
11064
|
return /* @__PURE__ */ jsxs(
|
|
10889
11065
|
"div",
|
|
10890
11066
|
{
|
|
@@ -10894,48 +11070,15 @@ function ContainerRow({
|
|
|
10894
11070
|
className: cn("group/container relative mb-2 last:mb-0 hover:z-10", isDragging && "opacity-40"),
|
|
10895
11071
|
children: [
|
|
10896
11072
|
renderBlockAdornment ? /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
|
|
10897
|
-
/* @__PURE__ */
|
|
11073
|
+
/* @__PURE__ */ jsxs("div", { className: "relative min-w-0 flex-1", children: [
|
|
11074
|
+
card,
|
|
11075
|
+
toolbar
|
|
11076
|
+
] }),
|
|
10898
11077
|
adornment != null && adornment !== false ? /* @__PURE__ */ jsx("div", { className: "shrink-0", children: adornment }) : null
|
|
10899
|
-
] }) :
|
|
10900
|
-
|
|
10901
|
-
|
|
10902
|
-
|
|
10903
|
-
className: cn(
|
|
10904
|
-
"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",
|
|
10905
|
-
hasErrors ? "opacity-100" : "opacity-0 group-hover/container:opacity-100 group-has-[:focus-visible]/container:opacity-100"
|
|
10906
|
-
),
|
|
10907
|
-
children: [
|
|
10908
|
-
hasErrors ? /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
10909
|
-
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
10910
|
-
"button",
|
|
10911
|
-
{
|
|
10912
|
-
type: "button",
|
|
10913
|
-
"aria-label": `Show ${errors.length} validation ${errors.length === 1 ? "issue" : "issues"}`,
|
|
10914
|
-
onClick: () => onOpenBlockChange?.(id),
|
|
10915
|
-
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",
|
|
10916
|
-
children: /* @__PURE__ */ jsx(AlertTriangle, { className: "h-3.5 w-3.5" })
|
|
10917
|
-
}
|
|
10918
|
-
) }),
|
|
10919
|
-
/* @__PURE__ */ jsx(TooltipContent, { side: "top", align: "end", children: /* @__PURE__ */ jsxs("ul", { className: "flex flex-col gap-0.5", children: [
|
|
10920
|
-
errors.slice(0, 4).map((err, i) => /* @__PURE__ */ jsx("li", { children: err }, i)),
|
|
10921
|
-
errors.length > 4 ? /* @__PURE__ */ jsxs("li", { className: "text-muted-foreground", children: [
|
|
10922
|
-
"and ",
|
|
10923
|
-
errors.length - 4,
|
|
10924
|
-
" more"
|
|
10925
|
-
] }) : null
|
|
10926
|
-
] }) })
|
|
10927
|
-
] }) : null,
|
|
10928
|
-
onReorder && typeof index === "number" && typeof total === "number" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
10929
|
-
/* @__PURE__ */ jsx(ToolbarButton2, { label: "Move up", disabled: index === 0, onClick: () => onReorder(id, index - 1), children: /* @__PURE__ */ jsx(ArrowUp, { className: "h-3.5 w-3.5" }) }),
|
|
10930
|
-
/* @__PURE__ */ jsx(ToolbarButton2, { label: "Move down", disabled: index >= total - 1, onClick: () => onReorder(id, index + 1), children: /* @__PURE__ */ jsx(ArrowDown, { className: "h-3.5 w-3.5" }) })
|
|
10931
|
-
] }) : null,
|
|
10932
|
-
/* @__PURE__ */ jsx(BlockActionButtons, { actions: blockActions, position, variant: "toolbar" }),
|
|
10933
|
-
/* @__PURE__ */ jsx(ToolbarButton2, { label: "Edit", onClick: () => onOpenBlockChange?.(id), children: /* @__PURE__ */ jsx(Pencil, { className: "h-3.5 w-3.5" }) }),
|
|
10934
|
-
/* @__PURE__ */ jsx(ToolbarButton2, { label: "Duplicate", onClick: () => onDuplicate(id), children: /* @__PURE__ */ jsx(Copy, { className: "h-3.5 w-3.5" }) }),
|
|
10935
|
-
/* @__PURE__ */ jsx(ToolbarButton2, { label: "Delete", destructive: true, onClick: () => onDelete(id), children: /* @__PURE__ */ jsx(Trash2, { className: "h-3.5 w-3.5" }) })
|
|
10936
|
-
]
|
|
10937
|
-
}
|
|
10938
|
-
),
|
|
11078
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
11079
|
+
card,
|
|
11080
|
+
toolbar
|
|
11081
|
+
] }),
|
|
10939
11082
|
/* @__PURE__ */ 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: [
|
|
10940
11083
|
/* @__PURE__ */ jsx("span", { className: "truncate text-[11px] font-medium text-muted-foreground", children: "Container" }),
|
|
10941
11084
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
@@ -11352,6 +11495,7 @@ function Toolbar2({
|
|
|
11352
11495
|
canRedo = false,
|
|
11353
11496
|
onUndo,
|
|
11354
11497
|
onRedo,
|
|
11498
|
+
undoRedoShortcuts = true,
|
|
11355
11499
|
onClear,
|
|
11356
11500
|
onOpenJson,
|
|
11357
11501
|
onOpenIssues,
|
|
@@ -11385,6 +11529,7 @@ function Toolbar2({
|
|
|
11385
11529
|
const showSurfaceControl = surfaceOptions.length > 1;
|
|
11386
11530
|
const docsHref = docsLink === false ? null : docsLink?.href ?? DEFAULT_DOCS_HREF;
|
|
11387
11531
|
const docsLabel = docsLink === false ? null : docsLink?.label ?? DEFAULT_DOCS_LABEL;
|
|
11532
|
+
const isApple = useIsApplePlatform();
|
|
11388
11533
|
const [surfaceMenuOpen, setSurfaceMenuOpen] = useState(false);
|
|
11389
11534
|
const [themeMenuOpen, setThemeMenuOpen] = useState(false);
|
|
11390
11535
|
const [sendMenuOpen, setSendMenuOpen] = useState(false);
|
|
@@ -11475,7 +11620,8 @@ function Toolbar2({
|
|
|
11475
11620
|
onClick: onUndo,
|
|
11476
11621
|
disabled: !canUndo,
|
|
11477
11622
|
"aria-label": "Undo",
|
|
11478
|
-
|
|
11623
|
+
"aria-keyshortcuts": undoRedoShortcuts ? "Control+Z Meta+Z" : void 0,
|
|
11624
|
+
title: undoRedoShortcuts ? `Undo (${isApple ? "\u2318Z" : "Ctrl+Z"})` : "Undo",
|
|
11479
11625
|
className: "px-2",
|
|
11480
11626
|
children: /* @__PURE__ */ jsx(Undo2, { className: "h-3.5 w-3.5" })
|
|
11481
11627
|
}
|
|
@@ -11489,7 +11635,8 @@ function Toolbar2({
|
|
|
11489
11635
|
onClick: onRedo,
|
|
11490
11636
|
disabled: !canRedo,
|
|
11491
11637
|
"aria-label": "Redo",
|
|
11492
|
-
|
|
11638
|
+
"aria-keyshortcuts": undoRedoShortcuts ? "Control+Shift+Z Meta+Shift+Z Control+Y" : void 0,
|
|
11639
|
+
title: undoRedoShortcuts ? `Redo (${isApple ? "\u21E7\u2318Z" : "Ctrl+Shift+Z"})` : "Redo",
|
|
11493
11640
|
className: "px-2",
|
|
11494
11641
|
children: /* @__PURE__ */ jsx(Redo2, { className: "h-3.5 w-3.5" })
|
|
11495
11642
|
}
|
|
@@ -11838,6 +11985,7 @@ function BlockKitchen(props) {
|
|
|
11838
11985
|
previewHooks,
|
|
11839
11986
|
blockActions,
|
|
11840
11987
|
renderBlockAdornment,
|
|
11988
|
+
blockEditors,
|
|
11841
11989
|
customEmojis,
|
|
11842
11990
|
mentions,
|
|
11843
11991
|
loadChannels,
|
|
@@ -11863,7 +12011,8 @@ function BlockKitchen(props) {
|
|
|
11863
12011
|
previewTheme: controlledPreviewTheme,
|
|
11864
12012
|
sendButtonLabel,
|
|
11865
12013
|
confirmSendLabel,
|
|
11866
|
-
theme
|
|
12014
|
+
theme,
|
|
12015
|
+
undoRedoShortcuts = true
|
|
11867
12016
|
// Widen the all-or-nothing union so the branch-specific props
|
|
11868
12017
|
// destructure as independent optionals: untyped JS consumers can still
|
|
11869
12018
|
// pass partial wiring (handled by the runtime guards below), and the
|
|
@@ -12043,7 +12192,7 @@ function BlockKitchen(props) {
|
|
|
12043
12192
|
const variantId = parsePaletteDragId(active.id);
|
|
12044
12193
|
if (variantId) {
|
|
12045
12194
|
const variant = variantById.get(variantId);
|
|
12046
|
-
if (!variant) {
|
|
12195
|
+
if (!variant || variant.locked) {
|
|
12047
12196
|
return;
|
|
12048
12197
|
}
|
|
12049
12198
|
if (target.kind === "container") {
|
|
@@ -12062,30 +12211,47 @@ function BlockKitchen(props) {
|
|
|
12062
12211
|
const handleDragCancel = useCallback(() => {
|
|
12063
12212
|
setActivePaletteVariantId(null);
|
|
12064
12213
|
}, []);
|
|
12065
|
-
const
|
|
12214
|
+
const runHistoryShortcut = useCallback(
|
|
12066
12215
|
(event) => {
|
|
12067
|
-
|
|
12068
|
-
|
|
12069
|
-
}
|
|
12070
|
-
const key = event.key.toLowerCase();
|
|
12071
|
-
const isUndo = key === "z" && !event.shiftKey;
|
|
12072
|
-
const isRedo = key === "y" || key === "z" && event.shiftKey;
|
|
12073
|
-
if (!isUndo && !isRedo) {
|
|
12216
|
+
const action = historyShortcutOf(event);
|
|
12217
|
+
if (!undoRedoShortcuts || !action || event.defaultPrevented || isTextEditingTarget(event.target)) {
|
|
12074
12218
|
return;
|
|
12075
12219
|
}
|
|
12076
|
-
|
|
12077
|
-
if (target && (target.isContentEditable || ["INPUT", "TEXTAREA", "SELECT"].includes(target.tagName))) {
|
|
12220
|
+
if (action === "undo" ? !canUndo : !canRedo) {
|
|
12078
12221
|
return;
|
|
12079
12222
|
}
|
|
12080
12223
|
event.preventDefault();
|
|
12081
|
-
if (
|
|
12082
|
-
if (canRedo) redo();
|
|
12083
|
-
} else if (canUndo) {
|
|
12224
|
+
if (action === "undo") {
|
|
12084
12225
|
undo();
|
|
12226
|
+
} else {
|
|
12227
|
+
redo();
|
|
12085
12228
|
}
|
|
12086
12229
|
},
|
|
12087
|
-
[canRedo, canUndo, redo, undo]
|
|
12230
|
+
[canRedo, canUndo, redo, undo, undoRedoShortcuts]
|
|
12088
12231
|
);
|
|
12232
|
+
const rootRef = useRef(null);
|
|
12233
|
+
const lastClickInBuilderRef = useRef(false);
|
|
12234
|
+
useEffect(() => {
|
|
12235
|
+
if (!undoRedoShortcuts) {
|
|
12236
|
+
return;
|
|
12237
|
+
}
|
|
12238
|
+
const onPointerDown = () => {
|
|
12239
|
+
lastClickInBuilderRef.current = false;
|
|
12240
|
+
};
|
|
12241
|
+
const onKeyDown = (event) => {
|
|
12242
|
+
const root = rootRef.current;
|
|
12243
|
+
const focusAroundBuilder = event.target instanceof Node && root !== null && event.target.contains(root);
|
|
12244
|
+
if (focusAroundBuilder && lastClickInBuilderRef.current) {
|
|
12245
|
+
runHistoryShortcut(event);
|
|
12246
|
+
}
|
|
12247
|
+
};
|
|
12248
|
+
window.addEventListener("pointerdown", onPointerDown, true);
|
|
12249
|
+
window.addEventListener("keydown", onKeyDown);
|
|
12250
|
+
return () => {
|
|
12251
|
+
window.removeEventListener("pointerdown", onPointerDown, true);
|
|
12252
|
+
window.removeEventListener("keydown", onKeyDown);
|
|
12253
|
+
};
|
|
12254
|
+
}, [runHistoryShortcut, undoRedoShortcuts]);
|
|
12089
12255
|
const activePaletteVariant = activePaletteVariantId ? variantById.get(activePaletteVariantId) : null;
|
|
12090
12256
|
const blockPayloads = blocks.map((b) => b.block);
|
|
12091
12257
|
return /* @__PURE__ */ jsx(BrandThemeScope, { theme, children: /* @__PURE__ */ jsx(CustomEmojiProvider, { customEmojis, children: /* @__PURE__ */ jsx(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxs(
|
|
@@ -12100,8 +12266,12 @@ function BlockKitchen(props) {
|
|
|
12100
12266
|
/* @__PURE__ */ jsxs(
|
|
12101
12267
|
"div",
|
|
12102
12268
|
{
|
|
12269
|
+
ref: rootRef,
|
|
12103
12270
|
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",
|
|
12104
|
-
onKeyDown:
|
|
12271
|
+
onKeyDown: runHistoryShortcut,
|
|
12272
|
+
onPointerDownCapture: () => {
|
|
12273
|
+
lastClickInBuilderRef.current = true;
|
|
12274
|
+
},
|
|
12105
12275
|
children: [
|
|
12106
12276
|
/* @__PURE__ */ jsx(
|
|
12107
12277
|
Toolbar2,
|
|
@@ -12110,6 +12280,7 @@ function BlockKitchen(props) {
|
|
|
12110
12280
|
canRedo,
|
|
12111
12281
|
onUndo: undo,
|
|
12112
12282
|
onRedo: redo,
|
|
12283
|
+
undoRedoShortcuts,
|
|
12113
12284
|
onClear: () => replaceAll([]),
|
|
12114
12285
|
onOpenJson: () => setJsonOpen(true),
|
|
12115
12286
|
onOpenIssues: () => setIssuesOpen(true),
|
|
@@ -12200,7 +12371,7 @@ function BlockKitchen(props) {
|
|
|
12200
12371
|
}
|
|
12201
12372
|
)
|
|
12202
12373
|
] }),
|
|
12203
|
-
/* @__PURE__ */ jsx(MentionsProvider, { mentions, children: /* @__PURE__ */ jsx(
|
|
12374
|
+
/* @__PURE__ */ jsx(MentionsProvider, { mentions, children: /* @__PURE__ */ jsx(BlockEditorsProvider, { blockEditors, children: /* @__PURE__ */ jsx(
|
|
12204
12375
|
Surface,
|
|
12205
12376
|
{
|
|
12206
12377
|
blocks,
|
|
@@ -12222,7 +12393,7 @@ function BlockKitchen(props) {
|
|
|
12222
12393
|
blockActions,
|
|
12223
12394
|
renderBlockAdornment
|
|
12224
12395
|
}
|
|
12225
|
-
) })
|
|
12396
|
+
) }) })
|
|
12226
12397
|
] })
|
|
12227
12398
|
]
|
|
12228
12399
|
}
|
|
@@ -12253,6 +12424,7 @@ function BlockKitchen(props) {
|
|
|
12253
12424
|
addBlock(block);
|
|
12254
12425
|
setPaletteOpen(false);
|
|
12255
12426
|
},
|
|
12427
|
+
onLockedPicked: () => setPaletteOpen(false),
|
|
12256
12428
|
sections: paletteSections,
|
|
12257
12429
|
mode: paletteMode,
|
|
12258
12430
|
showSearch: showPaletteSearch,
|