@tightknitai/block-kitchen 0.10.24 → 0.10.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.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(PaletteItem, { variant: v, onAdd: () => onAddBlock(v.factory()), mode: variant }, v.id))
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(PaletteItem, { variant: v, onAdd: () => onAddBlock(v.factory()), mode: variant }, v.id)) }) : null
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
  }
@@ -4421,7 +4487,11 @@ function PaletteItem({
4421
4487
  ...listeners,
4422
4488
  children: [
4423
4489
  /* @__PURE__ */ jsx(GripVertical, { className: "h-3.5 w-3.5 shrink-0" }),
4424
- /* @__PURE__ */ jsx("span", { className: "truncate", children: variant.label })
4490
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: variant.label }),
4491
+ variant.badge ? /* @__PURE__ */ jsxs(Fragment, { children: [
4492
+ " ",
4493
+ /* @__PURE__ */ jsx(VariantBadge, { badge: variant.badge })
4494
+ ] }) : null
4425
4495
  ]
4426
4496
  }
4427
4497
  ),
@@ -4439,6 +4509,48 @@ function PaletteItem({
4439
4509
  }
4440
4510
  );
4441
4511
  }
4512
+ function LockedPaletteItem({
4513
+ variant,
4514
+ isSheet,
4515
+ onPicked
4516
+ }) {
4517
+ const select = variant.onLockedSelect;
4518
+ const className = cn(
4519
+ "flex w-full items-center text-left text-muted-foreground",
4520
+ isSheet ? "min-h-11 gap-3 rounded-md px-3 py-2 text-sm font-medium" : "gap-2 rounded px-2 py-1 text-sm"
4521
+ );
4522
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [
4523
+ /* @__PURE__ */ jsx(Lock, { "aria-hidden": true, className: cn("shrink-0", isSheet ? "h-4 w-4" : "h-3.5 w-3.5") }),
4524
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: variant.label }),
4525
+ variant.badge ? /* @__PURE__ */ jsx(VariantBadge, { badge: variant.badge }) : null
4526
+ ] });
4527
+ if (!select) {
4528
+ return /* @__PURE__ */ jsx("div", { "aria-disabled": "true", className, children: content });
4529
+ }
4530
+ return /* @__PURE__ */ jsx(
4531
+ "button",
4532
+ {
4533
+ type: "button",
4534
+ "aria-label": `${variant.label} (locked${variant.badge ? `, ${variant.badge.label}` : ""})`,
4535
+ onClick: () => {
4536
+ onPicked?.();
4537
+ select();
4538
+ },
4539
+ className: cn(
4540
+ className,
4541
+ "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"
4542
+ ),
4543
+ children: content
4544
+ }
4545
+ );
4546
+ }
4547
+ function VariantBadge({ badge }) {
4548
+ const Icon = badge.icon;
4549
+ return /* @__PURE__ */ jsxs("span", { className: "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", children: [
4550
+ Icon ? /* @__PURE__ */ jsx(Icon, { "aria-hidden": true, className: "h-2.5 w-2.5 shrink-0" }) : null,
4551
+ badge.label
4552
+ ] });
4553
+ }
4442
4554
  function SendDialog({
4443
4555
  open,
4444
4556
  onOpenChange,
@@ -6258,7 +6370,7 @@ function MentionPicker({
6258
6370
  const listRef = useRef(null);
6259
6371
  const listboxId = useId();
6260
6372
  const activeOptionId = items[activeIndex] ? `${listboxId}-${activeIndex}` : void 0;
6261
- useEffect(() => {
6373
+ useLayoutEffect(() => {
6262
6374
  const root = editor.view.dom;
6263
6375
  root.setAttribute("role", "combobox");
6264
6376
  root.setAttribute("aria-autocomplete", "list");
@@ -6277,7 +6389,7 @@ function MentionPicker({
6277
6389
  root.removeAttribute("aria-activedescendant");
6278
6390
  };
6279
6391
  }, [activeOptionId, editor, listboxId]);
6280
- useEffect(() => {
6392
+ useLayoutEffect(() => {
6281
6393
  keyHandlerRef.current = (event) => {
6282
6394
  if (event.key === "ArrowDown" || event.key === "ArrowUp") {
6283
6395
  if (items.length > 0) {
@@ -10367,13 +10479,15 @@ function BlockEditor({
10367
10479
  onChange,
10368
10480
  onDone
10369
10481
  }) {
10482
+ const custom = useCustomBlockEditor(block);
10483
+ const CustomForm = custom?.component;
10370
10484
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
10371
10485
  /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs("h3", { className: "text-sm font-semibold text-foreground", children: [
10372
10486
  "Edit ",
10373
- labelForBlockType(block.type)
10487
+ custom ? custom.label : labelForBlockType(block.type)
10374
10488
  ] }) }),
10375
10489
  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),
10490
+ CustomForm ? /* @__PURE__ */ jsx(CustomForm, { block, onChange }) : dispatch(block, onChange),
10377
10491
  /* @__PURE__ */ jsx(
10378
10492
  AdvancedIdField,
10379
10493
  {
@@ -10544,6 +10658,122 @@ function BlockRow({
10544
10658
  ) })
10545
10659
  ] });
10546
10660
  const adornment = position && renderBlockAdornment?.(position);
10661
+ const hoverChrome = /* @__PURE__ */ jsxs(Fragment, { children: [
10662
+ /* @__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] }),
10663
+ /* @__PURE__ */ jsxs(
10664
+ "div",
10665
+ {
10666
+ className: cn(
10667
+ // Hidden on mobile in favor of the inline row below; on desktop
10668
+ // reveal on hover, on keyboard focus inside the row (so Tab-stops on
10669
+ // the floating buttons themselves keep them visible), and when there
10670
+ // are validation errors worth surfacing immediately.
10671
+ // :focus-visible, not :focus-within — a drag leaves pointer focus on
10672
+ // the block, which would otherwise pin the toolbar open until a click.
10673
+ "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",
10674
+ hasErrors ? "opacity-100" : "opacity-0 group-hover:opacity-100 group-has-[:focus-visible]:opacity-100"
10675
+ ),
10676
+ children: [
10677
+ hasErrors ? /* @__PURE__ */ jsxs(Tooltip, { children: [
10678
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
10679
+ "button",
10680
+ {
10681
+ type: "button",
10682
+ "aria-label": `Show ${errors.length} validation ${errors.length === 1 ? "issue" : "issues"}`,
10683
+ onClick: () => onOpenChange?.(true),
10684
+ 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",
10685
+ children: /* @__PURE__ */ jsx(AlertTriangle, { className: "h-3.5 w-3.5" })
10686
+ }
10687
+ ) }),
10688
+ /* @__PURE__ */ jsx(TooltipContent, { side: "top", align: "end", children: /* @__PURE__ */ jsxs("ul", { className: "flex flex-col gap-0.5", children: [
10689
+ errors.slice(0, 4).map((err, i) => /* @__PURE__ */ jsx("li", { children: err }, i)),
10690
+ errors.length > 4 ? /* @__PURE__ */ jsxs("li", { className: "text-muted-foreground", children: [
10691
+ "and ",
10692
+ errors.length - 4,
10693
+ " more"
10694
+ ] }) : null
10695
+ ] }) })
10696
+ ] }) : null,
10697
+ onReorder && typeof index === "number" && typeof total === "number" ? /* @__PURE__ */ jsxs(Fragment, { children: [
10698
+ /* @__PURE__ */ jsxs(Tooltip, { children: [
10699
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
10700
+ "button",
10701
+ {
10702
+ type: "button",
10703
+ "aria-label": "Move block up",
10704
+ disabled: index === 0,
10705
+ onClick: () => onReorder(builderBlock.id, index - 1),
10706
+ 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",
10707
+ children: /* @__PURE__ */ jsx(ArrowUp, { className: "h-3.5 w-3.5" })
10708
+ }
10709
+ ) }),
10710
+ /* @__PURE__ */ jsx(TooltipContent, { side: "top", children: "Move up" })
10711
+ ] }),
10712
+ /* @__PURE__ */ jsxs(Tooltip, { children: [
10713
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
10714
+ "button",
10715
+ {
10716
+ type: "button",
10717
+ "aria-label": "Move block down",
10718
+ disabled: index >= total - 1,
10719
+ onClick: () => onReorder(builderBlock.id, index + 1),
10720
+ 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",
10721
+ children: /* @__PURE__ */ jsx(ArrowDown, { className: "h-3.5 w-3.5" })
10722
+ }
10723
+ ) }),
10724
+ /* @__PURE__ */ jsx(TooltipContent, { side: "top", children: "Move down" })
10725
+ ] })
10726
+ ] }) : null,
10727
+ /* @__PURE__ */ jsx(BlockActionButtons, { actions: blockActions, position, variant: "toolbar" }),
10728
+ /* @__PURE__ */ jsxs(Tooltip, { children: [
10729
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
10730
+ "button",
10731
+ {
10732
+ type: "button",
10733
+ "aria-label": "Edit block",
10734
+ onClick: () => {
10735
+ if (isRichText) {
10736
+ setInlineEditing(true);
10737
+ } else {
10738
+ onOpenChange?.(true);
10739
+ }
10740
+ },
10741
+ 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",
10742
+ children: /* @__PURE__ */ jsx(Pencil, { className: "h-3.5 w-3.5" })
10743
+ }
10744
+ ) }),
10745
+ /* @__PURE__ */ jsx(TooltipContent, { side: "top", children: "Edit" })
10746
+ ] }),
10747
+ /* @__PURE__ */ jsxs(Tooltip, { children: [
10748
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
10749
+ "button",
10750
+ {
10751
+ type: "button",
10752
+ "aria-label": "Duplicate block",
10753
+ onClick: () => onDuplicate(builderBlock.id),
10754
+ 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",
10755
+ children: /* @__PURE__ */ jsx(Copy, { className: "h-3.5 w-3.5" })
10756
+ }
10757
+ ) }),
10758
+ /* @__PURE__ */ jsx(TooltipContent, { side: "top", children: "Duplicate" })
10759
+ ] }),
10760
+ /* @__PURE__ */ jsxs(Tooltip, { children: [
10761
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
10762
+ "button",
10763
+ {
10764
+ type: "button",
10765
+ "aria-label": "Delete block",
10766
+ onClick: () => onDelete(builderBlock.id),
10767
+ 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",
10768
+ children: /* @__PURE__ */ jsx(Trash2, { className: "h-3.5 w-3.5" })
10769
+ }
10770
+ ) }),
10771
+ /* @__PURE__ */ jsx(TooltipContent, { side: "top", children: "Delete" })
10772
+ ] })
10773
+ ]
10774
+ }
10775
+ )
10776
+ ] });
10547
10777
  return /* @__PURE__ */ jsxs(
10548
10778
  "div",
10549
10779
  {
@@ -10561,126 +10791,16 @@ function BlockRow({
10561
10791
  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
10792
  }
10563
10793
  ) : null,
10564
- /* @__PURE__ */ jsxs("div", { className: "relative w-full", children: [
10565
- renderBlockAdornment ? /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
10566
- /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: body }),
10567
- adornment != null && adornment !== false ? /* @__PURE__ */ jsx("div", { className: "shrink-0", children: adornment }) : null
10568
- ] }) : body,
10569
- /* @__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] }),
10570
- /* @__PURE__ */ jsxs(
10571
- "div",
10572
- {
10573
- className: cn(
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
- ] }),
10794
+ /* @__PURE__ */ jsx("div", { className: "relative w-full", children: renderBlockAdornment ? /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
10795
+ /* @__PURE__ */ jsxs("div", { className: "relative min-w-0 flex-1", children: [
10796
+ body,
10797
+ hoverChrome
10798
+ ] }),
10799
+ adornment != null && adornment !== false ? /* @__PURE__ */ jsx("div", { className: "shrink-0", children: adornment }) : null
10800
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
10801
+ body,
10802
+ hoverChrome
10803
+ ] }) }),
10684
10804
  /* @__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
10805
  /* @__PURE__ */ jsx("span", { className: "truncate text-[11px] font-medium text-muted-foreground", children: BLOCK_TYPE_LABELS[builderBlock.block.type] }),
10686
10806
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
@@ -10885,6 +11005,45 @@ function ContainerRow({
10885
11005
  ]
10886
11006
  }
10887
11007
  );
11008
+ const toolbar = /* @__PURE__ */ jsxs(
11009
+ "div",
11010
+ {
11011
+ className: cn(
11012
+ "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",
11013
+ hasErrors ? "opacity-100" : "opacity-0 group-hover/container:opacity-100 group-has-[:focus-visible]/container:opacity-100"
11014
+ ),
11015
+ children: [
11016
+ hasErrors ? /* @__PURE__ */ jsxs(Tooltip, { children: [
11017
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
11018
+ "button",
11019
+ {
11020
+ type: "button",
11021
+ "aria-label": `Show ${errors.length} validation ${errors.length === 1 ? "issue" : "issues"}`,
11022
+ onClick: () => onOpenBlockChange?.(id),
11023
+ 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",
11024
+ children: /* @__PURE__ */ jsx(AlertTriangle, { className: "h-3.5 w-3.5" })
11025
+ }
11026
+ ) }),
11027
+ /* @__PURE__ */ jsx(TooltipContent, { side: "top", align: "end", children: /* @__PURE__ */ jsxs("ul", { className: "flex flex-col gap-0.5", children: [
11028
+ errors.slice(0, 4).map((err, i) => /* @__PURE__ */ jsx("li", { children: err }, i)),
11029
+ errors.length > 4 ? /* @__PURE__ */ jsxs("li", { className: "text-muted-foreground", children: [
11030
+ "and ",
11031
+ errors.length - 4,
11032
+ " more"
11033
+ ] }) : null
11034
+ ] }) })
11035
+ ] }) : null,
11036
+ onReorder && typeof index === "number" && typeof total === "number" ? /* @__PURE__ */ jsxs(Fragment, { children: [
11037
+ /* @__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" }) }),
11038
+ /* @__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" }) })
11039
+ ] }) : null,
11040
+ /* @__PURE__ */ jsx(BlockActionButtons, { actions: blockActions, position, variant: "toolbar" }),
11041
+ /* @__PURE__ */ jsx(ToolbarButton2, { label: "Edit", onClick: () => onOpenBlockChange?.(id), children: /* @__PURE__ */ jsx(Pencil, { className: "h-3.5 w-3.5" }) }),
11042
+ /* @__PURE__ */ jsx(ToolbarButton2, { label: "Duplicate", onClick: () => onDuplicate(id), children: /* @__PURE__ */ jsx(Copy, { className: "h-3.5 w-3.5" }) }),
11043
+ /* @__PURE__ */ jsx(ToolbarButton2, { label: "Delete", destructive: true, onClick: () => onDelete(id), children: /* @__PURE__ */ jsx(Trash2, { className: "h-3.5 w-3.5" }) })
11044
+ ]
11045
+ }
11046
+ );
10888
11047
  return /* @__PURE__ */ jsxs(
10889
11048
  "div",
10890
11049
  {
@@ -10894,48 +11053,15 @@ function ContainerRow({
10894
11053
  className: cn("group/container relative mb-2 last:mb-0 hover:z-10", isDragging && "opacity-40"),
10895
11054
  children: [
10896
11055
  renderBlockAdornment ? /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
10897
- /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: card }),
11056
+ /* @__PURE__ */ jsxs("div", { className: "relative min-w-0 flex-1", children: [
11057
+ card,
11058
+ toolbar
11059
+ ] }),
10898
11060
  adornment != null && adornment !== false ? /* @__PURE__ */ jsx("div", { className: "shrink-0", children: adornment }) : null
10899
- ] }) : card,
10900
- /* @__PURE__ */ jsxs(
10901
- "div",
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
- ),
11061
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
11062
+ card,
11063
+ toolbar
11064
+ ] }),
10939
11065
  /* @__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
11066
  /* @__PURE__ */ jsx("span", { className: "truncate text-[11px] font-medium text-muted-foreground", children: "Container" }),
10941
11067
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
@@ -11352,6 +11478,7 @@ function Toolbar2({
11352
11478
  canRedo = false,
11353
11479
  onUndo,
11354
11480
  onRedo,
11481
+ undoRedoShortcuts = true,
11355
11482
  onClear,
11356
11483
  onOpenJson,
11357
11484
  onOpenIssues,
@@ -11385,6 +11512,7 @@ function Toolbar2({
11385
11512
  const showSurfaceControl = surfaceOptions.length > 1;
11386
11513
  const docsHref = docsLink === false ? null : docsLink?.href ?? DEFAULT_DOCS_HREF;
11387
11514
  const docsLabel = docsLink === false ? null : docsLink?.label ?? DEFAULT_DOCS_LABEL;
11515
+ const isApple = useIsApplePlatform();
11388
11516
  const [surfaceMenuOpen, setSurfaceMenuOpen] = useState(false);
11389
11517
  const [themeMenuOpen, setThemeMenuOpen] = useState(false);
11390
11518
  const [sendMenuOpen, setSendMenuOpen] = useState(false);
@@ -11475,7 +11603,8 @@ function Toolbar2({
11475
11603
  onClick: onUndo,
11476
11604
  disabled: !canUndo,
11477
11605
  "aria-label": "Undo",
11478
- title: "Undo (Ctrl+Z)",
11606
+ "aria-keyshortcuts": undoRedoShortcuts ? "Control+Z Meta+Z" : void 0,
11607
+ title: undoRedoShortcuts ? `Undo (${isApple ? "\u2318Z" : "Ctrl+Z"})` : "Undo",
11479
11608
  className: "px-2",
11480
11609
  children: /* @__PURE__ */ jsx(Undo2, { className: "h-3.5 w-3.5" })
11481
11610
  }
@@ -11489,7 +11618,8 @@ function Toolbar2({
11489
11618
  onClick: onRedo,
11490
11619
  disabled: !canRedo,
11491
11620
  "aria-label": "Redo",
11492
- title: "Redo (Ctrl+Shift+Z)",
11621
+ "aria-keyshortcuts": undoRedoShortcuts ? "Control+Shift+Z Meta+Shift+Z Control+Y" : void 0,
11622
+ title: undoRedoShortcuts ? `Redo (${isApple ? "\u21E7\u2318Z" : "Ctrl+Shift+Z"})` : "Redo",
11493
11623
  className: "px-2",
11494
11624
  children: /* @__PURE__ */ jsx(Redo2, { className: "h-3.5 w-3.5" })
11495
11625
  }
@@ -11838,6 +11968,7 @@ function BlockKitchen(props) {
11838
11968
  previewHooks,
11839
11969
  blockActions,
11840
11970
  renderBlockAdornment,
11971
+ blockEditors,
11841
11972
  customEmojis,
11842
11973
  mentions,
11843
11974
  loadChannels,
@@ -11863,7 +11994,8 @@ function BlockKitchen(props) {
11863
11994
  previewTheme: controlledPreviewTheme,
11864
11995
  sendButtonLabel,
11865
11996
  confirmSendLabel,
11866
- theme
11997
+ theme,
11998
+ undoRedoShortcuts = true
11867
11999
  // Widen the all-or-nothing union so the branch-specific props
11868
12000
  // destructure as independent optionals: untyped JS consumers can still
11869
12001
  // pass partial wiring (handled by the runtime guards below), and the
@@ -12043,7 +12175,7 @@ function BlockKitchen(props) {
12043
12175
  const variantId = parsePaletteDragId(active.id);
12044
12176
  if (variantId) {
12045
12177
  const variant = variantById.get(variantId);
12046
- if (!variant) {
12178
+ if (!variant || variant.locked) {
12047
12179
  return;
12048
12180
  }
12049
12181
  if (target.kind === "container") {
@@ -12062,30 +12194,47 @@ function BlockKitchen(props) {
12062
12194
  const handleDragCancel = useCallback(() => {
12063
12195
  setActivePaletteVariantId(null);
12064
12196
  }, []);
12065
- const handleKeyDown = useCallback(
12197
+ const runHistoryShortcut = useCallback(
12066
12198
  (event) => {
12067
- if (!(event.metaKey || event.ctrlKey) || event.altKey) {
12068
- return;
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) {
12199
+ const action = historyShortcutOf(event);
12200
+ if (!undoRedoShortcuts || !action || event.defaultPrevented || isTextEditingTarget(event.target)) {
12074
12201
  return;
12075
12202
  }
12076
- const target = event.target;
12077
- if (target && (target.isContentEditable || ["INPUT", "TEXTAREA", "SELECT"].includes(target.tagName))) {
12203
+ if (action === "undo" ? !canUndo : !canRedo) {
12078
12204
  return;
12079
12205
  }
12080
12206
  event.preventDefault();
12081
- if (isRedo) {
12082
- if (canRedo) redo();
12083
- } else if (canUndo) {
12207
+ if (action === "undo") {
12084
12208
  undo();
12209
+ } else {
12210
+ redo();
12085
12211
  }
12086
12212
  },
12087
- [canRedo, canUndo, redo, undo]
12213
+ [canRedo, canUndo, redo, undo, undoRedoShortcuts]
12088
12214
  );
12215
+ const rootRef = useRef(null);
12216
+ const lastClickInBuilderRef = useRef(false);
12217
+ useEffect(() => {
12218
+ if (!undoRedoShortcuts) {
12219
+ return;
12220
+ }
12221
+ const onPointerDown = () => {
12222
+ lastClickInBuilderRef.current = false;
12223
+ };
12224
+ const onKeyDown = (event) => {
12225
+ const root = rootRef.current;
12226
+ const focusAroundBuilder = event.target instanceof Node && root !== null && event.target.contains(root);
12227
+ if (focusAroundBuilder && lastClickInBuilderRef.current) {
12228
+ runHistoryShortcut(event);
12229
+ }
12230
+ };
12231
+ window.addEventListener("pointerdown", onPointerDown, true);
12232
+ window.addEventListener("keydown", onKeyDown);
12233
+ return () => {
12234
+ window.removeEventListener("pointerdown", onPointerDown, true);
12235
+ window.removeEventListener("keydown", onKeyDown);
12236
+ };
12237
+ }, [runHistoryShortcut, undoRedoShortcuts]);
12089
12238
  const activePaletteVariant = activePaletteVariantId ? variantById.get(activePaletteVariantId) : null;
12090
12239
  const blockPayloads = blocks.map((b) => b.block);
12091
12240
  return /* @__PURE__ */ jsx(BrandThemeScope, { theme, children: /* @__PURE__ */ jsx(CustomEmojiProvider, { customEmojis, children: /* @__PURE__ */ jsx(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxs(
@@ -12100,8 +12249,12 @@ function BlockKitchen(props) {
12100
12249
  /* @__PURE__ */ jsxs(
12101
12250
  "div",
12102
12251
  {
12252
+ ref: rootRef,
12103
12253
  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: handleKeyDown,
12254
+ onKeyDown: runHistoryShortcut,
12255
+ onPointerDownCapture: () => {
12256
+ lastClickInBuilderRef.current = true;
12257
+ },
12105
12258
  children: [
12106
12259
  /* @__PURE__ */ jsx(
12107
12260
  Toolbar2,
@@ -12110,6 +12263,7 @@ function BlockKitchen(props) {
12110
12263
  canRedo,
12111
12264
  onUndo: undo,
12112
12265
  onRedo: redo,
12266
+ undoRedoShortcuts,
12113
12267
  onClear: () => replaceAll([]),
12114
12268
  onOpenJson: () => setJsonOpen(true),
12115
12269
  onOpenIssues: () => setIssuesOpen(true),
@@ -12200,7 +12354,7 @@ function BlockKitchen(props) {
12200
12354
  }
12201
12355
  )
12202
12356
  ] }),
12203
- /* @__PURE__ */ jsx(MentionsProvider, { mentions, children: /* @__PURE__ */ jsx(
12357
+ /* @__PURE__ */ jsx(MentionsProvider, { mentions, children: /* @__PURE__ */ jsx(BlockEditorsProvider, { blockEditors, children: /* @__PURE__ */ jsx(
12204
12358
  Surface,
12205
12359
  {
12206
12360
  blocks,
@@ -12222,7 +12376,7 @@ function BlockKitchen(props) {
12222
12376
  blockActions,
12223
12377
  renderBlockAdornment
12224
12378
  }
12225
- ) })
12379
+ ) }) })
12226
12380
  ] })
12227
12381
  ]
12228
12382
  }
@@ -12253,6 +12407,7 @@ function BlockKitchen(props) {
12253
12407
  addBlock(block);
12254
12408
  setPaletteOpen(false);
12255
12409
  },
12410
+ onLockedPicked: () => setPaletteOpen(false),
12256
12411
  sections: paletteSections,
12257
12412
  mode: paletteMode,
12258
12413
  showSearch: showPaletteSearch,