@chaibuilder/sdk 2.2.7 → 2.2.8

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/core.d.ts CHANGED
@@ -529,7 +529,7 @@ export declare const useCanvasZoom: () => [number, (args_0: number | RESET | ((p
529
529
  */
530
530
  export declare const useCodeEditor: () => [CodeEditorProps, never];
531
531
 
532
- export declare const useCopyBlockIds: () => [Array<string>, (blockIds: Array<string>) => void];
532
+ export declare const useCopyBlockIds: () => [Array<string>, (blockIds: Array<string>, clonePartialBlocks?: boolean) => void, (blockIds: Array<string>) => boolean];
533
533
 
534
534
  export declare const useCopyToClipboard: () => [CopiedValue, CopyFn];
535
535
 
package/dist/core.js CHANGED
@@ -2359,7 +2359,7 @@ const getBlockWithChildren = (o, r) => {
2359
2359
  },
2360
2360
  [o]
2361
2361
  );
2362
- }, partialBlocksStoreAtom = atom({}), partialBlocksLoadingStateAtom = atom({}), usePartailBlocksStore = () => {
2362
+ }, partialBlocksStoreAtom = atom({}), partialBlocksLoadingStateAtom = atom({}), usePartialBlocksStore = () => {
2363
2363
  const [o, r] = useAtom$1(partialBlocksStoreAtom), n = useCallback((l) => get(o, l, []), [o]), a = useCallback(() => r({}), [r]);
2364
2364
  return { getPartailBlocks: n, reset: a };
2365
2365
  }, useWatchPartailBlocks = () => {
@@ -2400,7 +2400,7 @@ const getBlockWithChildren = (o, r) => {
2400
2400
  c();
2401
2401
  }, []), { data: l, isLoading: o, refetch: c, error: n };
2402
2402
  }, useBuilderReset = () => {
2403
- const { clear: o } = useUndoManager(), [, r] = useSelectedBlockIds(), { clearHighlight: n } = useBlockHighlight(), [, a] = useSelectedStylingBlocks(), [, l] = useAtom$1(aiAssistantActiveAtom), { reset: i } = usePartailBlocksStore(), { setSaveState: d } = useSavePage();
2403
+ const { clear: o } = useUndoManager(), [, r] = useSelectedBlockIds(), { clearHighlight: n } = useBlockHighlight(), [, a] = useSelectedStylingBlocks(), [, l] = useAtom$1(aiAssistantActiveAtom), { reset: i } = usePartialBlocksStore(), { setSaveState: d } = useSavePage();
2404
2404
  return () => {
2405
2405
  r([]), a([]), n(), o(), l(!1), i(), d("SAVED");
2406
2406
  };
@@ -2412,14 +2412,44 @@ const getBlockWithChildren = (o, r) => {
2412
2412
  [r, n]
2413
2413
  );
2414
2414
  return [o, a];
2415
- }, copiedBlockIdsAtom = atom([]), useCopyBlockIds = () => {
2416
- const [o, r] = useAtom$1(copiedBlockIdsAtom), n = useSetAtom$1(cutBlockIdsAtom), a = useCallback(
2417
- async (l) => {
2418
- r(l), n([]), toast.success("Blocks copied");
2415
+ }, copiedBlockIdsAtom = atom([]), useCopyBlocks = () => {
2416
+ const [o] = useBlocksStore(), [r, n] = useAtom$1(copiedBlockIdsAtom), a = useSetAtom$1(cutBlockIdsAtom), { getPartailBlocks: l } = usePartialBlocksStore(), i = useCallback(
2417
+ (c) => c.some((p) => getDuplicatedBlocks(o, p, null).some((g) => g._type === "PartialBlock" || g._type === "GlobalBlock")),
2418
+ [o]
2419
+ ), d = useCallback(
2420
+ async (c, p = !1) => {
2421
+ try {
2422
+ n(c), a([]);
2423
+ const u = {
2424
+ _chai_copied_blocks: c.flatMap((g) => {
2425
+ const f = getDuplicatedBlocks(o, g, null);
2426
+ if (!p)
2427
+ return f;
2428
+ let m = [];
2429
+ for (const h of f)
2430
+ if (h._type === "PartialBlock" || h._type === "GlobalBlock") {
2431
+ const x = l(h.partialBlockId);
2432
+ set(x, "0._parent", h._parent), m = [...m, ...x];
2433
+ } else
2434
+ m.push(h);
2435
+ return m;
2436
+ })
2437
+ };
2438
+ if (!navigator.clipboard) {
2439
+ toast.error("Clipboard not available.");
2440
+ return;
2441
+ }
2442
+ toast.promise(navigator.clipboard.writeText(JSON.stringify(u)), {
2443
+ success: "Blocks copied successfully",
2444
+ error: "Failed to copy blocks to clipboard"
2445
+ });
2446
+ } catch (u) {
2447
+ toast.error("Failed to copy blocks to clipboard"), console.error("Failed to copy blocks to clipboard:", u);
2448
+ }
2419
2449
  },
2420
- [r, n]
2450
+ [n, a]
2421
2451
  );
2422
- return [o, a];
2452
+ return [r, d, i];
2423
2453
  }, useCopyToClipboard = () => {
2424
2454
  const [o, r] = useState(null), n = useCallback(async (a) => {
2425
2455
  if (!(navigator != null && navigator.clipboard))
@@ -2509,25 +2539,64 @@ const getBlockWithChildren = (o, r) => {
2509
2539
  [r, o]
2510
2540
  );
2511
2541
  }, usePasteBlocks = () => {
2512
- const [o, r] = useCutBlockIds(), [n] = useCopyBlockIds(), a = useMoveCutBlocks(), l = useDuplicateBlocks(), i = useCanPaste();
2542
+ const [o, r] = useCutBlockIds(), n = useMoveCutBlocks(), { addPredefinedBlock: a } = useAddBlock(), l = useCanPaste();
2513
2543
  return {
2514
2544
  canPaste: useCallback(
2515
- async (c) => o.length > 0 ? i(o, c) : !1,
2516
- [i, o]
2545
+ async (d) => {
2546
+ if (o.length > 0)
2547
+ return l(o, d);
2548
+ try {
2549
+ const c = await navigator.clipboard.readText();
2550
+ if (c) {
2551
+ const p = JSON.parse(c);
2552
+ return has(p, "_chai_copied_blocks");
2553
+ }
2554
+ } catch {
2555
+ return !1;
2556
+ }
2557
+ return !1;
2558
+ },
2559
+ [l, o]
2517
2560
  ),
2518
2561
  pasteBlocks: useCallback(
2519
- async (c) => {
2520
- const p = Array.isArray(c) ? c[0] : c;
2521
- if (!isEmpty(o)) {
2522
- a(o, c), r([]);
2562
+ async (d) => {
2563
+ const c = Array.isArray(d) ? d[0] : d;
2564
+ if (!(navigator != null && navigator.permissions)) {
2565
+ toast.error("Cannot check clipboard permissions.");
2566
+ return;
2567
+ }
2568
+ try {
2569
+ if ((await navigator.permissions.query({ name: "clipboard-read" })).state === "denied") {
2570
+ toast.error("Clipboard paste permission denied. Please allow clipboard access.");
2571
+ return;
2572
+ }
2573
+ } catch {
2574
+ toast.error("Failed to check clipboard permissions. Please allow clipboard access.");
2523
2575
  return;
2524
2576
  }
2525
- if (!isEmpty(n)) {
2526
- l(n, p);
2577
+ if (!isEmpty(o)) {
2578
+ n(o, d), r([]), await navigator.clipboard.writeText("");
2527
2579
  return;
2528
2580
  }
2581
+ toast.promise(
2582
+ async () => {
2583
+ const p = await navigator.clipboard.readText();
2584
+ if (p) {
2585
+ const u = JSON.parse(p);
2586
+ if (has(u, "_chai_copied_blocks"))
2587
+ a(u._chai_copied_blocks, c === "root" ? null : c);
2588
+ else
2589
+ throw new Error("Nothing to paste");
2590
+ } else
2591
+ throw new Error("Nothing to paste");
2592
+ },
2593
+ {
2594
+ success: () => "Blocks pasted successfully",
2595
+ error: () => "Nothing to paste"
2596
+ }
2597
+ );
2529
2598
  },
2530
- [o, a, r]
2599
+ [o, n, r]
2531
2600
  )
2532
2601
  };
2533
2602
  }, previewModeAtom = atom(!1), usePreviewMode = () => {
@@ -2878,7 +2947,7 @@ z(Frame, "defaultProps", {
2878
2947
  initialContent: '<!DOCTYPE html><html><head></head><body><div class="frame-root"></div></body></html>'
2879
2948
  });
2880
2949
  const ChaiFrame = React__default.forwardRef((o, r) => /* @__PURE__ */ jsx(Frame, { ...o, forwardedRef: r })), useKeyEventWatcher = (o) => {
2881
- const [r, n] = useSelectedBlockIds(), a = useSelectedBlock(), l = useRemoveBlocks(), i = useDuplicateBlocks(), { undo: d, redo: c } = useUndoManager(), [, p] = useCutBlockIds(), [, u] = useCopyBlockIds(), { canPaste: g, pasteBlocks: f } = usePasteBlocks(), m = o ? { document: o } : {};
2950
+ const [r, n] = useSelectedBlockIds(), a = useSelectedBlock(), l = useRemoveBlocks(), i = useDuplicateBlocks(), { undo: d, redo: c } = useUndoManager(), [, p] = useCutBlockIds(), [, u] = useCopyBlocks(), { canPaste: g, pasteBlocks: f } = usePasteBlocks(), m = o ? { document: o } : {};
2882
2951
  useHotkeys("ctrl+z,command+z", () => d(), {}, [d]), useHotkeys("ctrl+y,command+y", () => c(), {}, [c]), useHotkeys("ctrl+x,command+x", () => p(r), {}, [r, p]), useHotkeys("ctrl+c,command+c", () => u(r), {}, [r, u]), useHotkeys(
2883
2952
  "ctrl+v,command+v",
2884
2953
  () => {
@@ -3256,7 +3325,7 @@ const useHandleCanvasDblClick = (o, r) => {
3256
3325
  })
3257
3326
  }) });
3258
3327
  }, PartialBlocksRenderer = ({ partialBlockId: o }) => {
3259
- const { getPartailBlocks: r } = usePartailBlocksStore(), n = useMemo(() => r(o), [r, o]), a = useMemo(() => splitAtom(atom(n)), [n]);
3328
+ const { getPartailBlocks: r } = usePartialBlocksStore(), n = useMemo(() => r(o), [r, o]), a = useMemo(() => splitAtom(atom(n)), [n]);
3260
3329
  return isEmpty(n) ? null : /* @__PURE__ */ jsx(BlocksRenderer, { splitAtoms: a, blocks: n });
3261
3330
  }, BlocksRenderer = ({
3262
3331
  blocks: o,
@@ -3389,7 +3458,7 @@ const useHandleCanvasDblClick = (o, r) => {
3389
3458
  }, FallbackError = () => /* @__PURE__ */ jsx("div", { className: "h-full w-full rounded-md bg-red-200 p-4 text-red-500", children: /* @__PURE__ */ jsxs("div", { className: "flex h-full w-full flex-col items-center justify-center", children: [
3390
3459
  /* @__PURE__ */ jsx("p", { className: "font-semibold", children: "Oops! Something went wrong." }),
3391
3460
  /* @__PURE__ */ jsx("p", { children: "Please try again." })
3392
- ] }) }), CodeEditor$1 = React__default.lazy(() => import("./code-editor-HKrlrH8b.js")), CanvasArea = () => {
3461
+ ] }) }), CodeEditor$1 = React__default.lazy(() => import("./code-editor-QVi542cK.js")), CanvasArea = () => {
3393
3462
  const [o] = useCodeEditor(), r = useBuilderProp("onError", noop);
3394
3463
  return /* @__PURE__ */ jsx("div", { className: "flex h-full max-h-full w-full flex-1 flex-col", children: /* @__PURE__ */ jsxs("div", { className: "relative flex h-full max-h-full flex-col overflow-hidden bg-gray-100/40 px-2", children: [
3395
3464
  /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Skeleton, { className: "h-full" }), children: /* @__PURE__ */ jsx(ErrorBoundary, { fallback: /* @__PURE__ */ jsx(FallbackError, {}), onError: r, children: /* @__PURE__ */ jsx(StaticCanvas, {}) }) }),
@@ -6982,28 +7051,45 @@ const registerChaiSaveToLibrary = (o) => {
6982
7051
  " ",
6983
7052
  o("Unlink from library")
6984
7053
  ] });
6985
- }, CopyPasteBlocks = () => {
6986
- const [o] = useBlocksStore(), [r] = useSelectedBlockIds(), { pasteBlocks: n } = usePasteBlocks(), [, a] = useCopyBlockIds(), { t: l } = useTranslation(), i = useSelectedBlock(), d = useCallback(() => {
6987
- const c = r.map((p) => {
6988
- const u = o.find((g) => g._id === p);
7054
+ }, CANNOT_COPY_BLOCKS = !navigator.clipboard, CopyPasteBlocks = () => {
7055
+ const [o] = useBlocksStore(), [r] = useSelectedBlockIds(), { pasteBlocks: n } = usePasteBlocks(), [, a, l] = useCopyBlocks(), { t: i } = useTranslation(), d = useSelectedBlock(), c = useCallback(() => {
7056
+ const p = r.map((u) => {
7057
+ const g = o.find((f) => f._id === u);
6989
7058
  return {
6990
- id: p,
6991
- data: u
7059
+ id: u,
7060
+ data: g
6992
7061
  };
6993
7062
  });
6994
- a(c.map((p) => p.id));
6995
- }, [r, o, a]);
7063
+ l(p.map((u) => u.id)) ? toast.warning("Partial blocks detected. Clone partial blocks?", {
7064
+ cancel: {
7065
+ label: i("No"),
7066
+ onClick: () => {
7067
+ a(p.map((u) => u.id)), toast.dismiss();
7068
+ }
7069
+ },
7070
+ action: {
7071
+ label: i("Yes"),
7072
+ onClick: () => {
7073
+ a(
7074
+ p.map((u) => u.id),
7075
+ !0
7076
+ ), toast.dismiss();
7077
+ }
7078
+ },
7079
+ position: "top-center"
7080
+ }) : a(p.map((u) => u.id));
7081
+ }, [r, o, a, l]);
6996
7082
  return /* @__PURE__ */ jsxs(Fragment, { children: [
6997
- /* @__PURE__ */ jsxs(
7083
+ !CANNOT_COPY_BLOCKS && /* @__PURE__ */ jsxs(
6998
7084
  DropdownMenuItem,
6999
7085
  {
7000
- disabled: !canDuplicateBlock(i == null ? void 0 : i._type),
7001
- onClick: d,
7086
+ disabled: !canDuplicateBlock(d == null ? void 0 : d._type),
7087
+ onClick: c,
7002
7088
  className: "flex items-center gap-x-4 text-xs",
7003
7089
  children: [
7004
7090
  /* @__PURE__ */ jsx(CopyIcon, {}),
7005
7091
  " ",
7006
- l("Copy")
7092
+ i("Copy")
7007
7093
  ]
7008
7094
  }
7009
7095
  ),
@@ -7017,7 +7103,7 @@ const registerChaiSaveToLibrary = (o) => {
7017
7103
  children: [
7018
7104
  /* @__PURE__ */ jsx(CardStackIcon, {}),
7019
7105
  " ",
7020
- l("Paste")
7106
+ i("Paste")
7021
7107
  ]
7022
7108
  }
7023
7109
  )
@@ -7315,7 +7401,35 @@ const Input = ({ node: o }) => {
7315
7401
  ]
7316
7402
  }
7317
7403
  ) });
7318
- }), useCanMove = () => {
7404
+ }), PasteAtRootContextMenu = ({ parentContext: o, setParentContext: r }) => {
7405
+ const { t: n } = useTranslation(), { canPaste: a, pasteBlocks: l } = usePasteBlocks();
7406
+ return useEffect(() => {
7407
+ a("root") || r(null);
7408
+ }, [a("root")]), !o || !a("root") ? null : /* @__PURE__ */ jsx("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsxs(DropdownMenu, { open: !0, onOpenChange: () => r(null), children: [
7409
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { className: "hidden" }),
7410
+ /* @__PURE__ */ jsx(
7411
+ DropdownMenuContent,
7412
+ {
7413
+ className: "absolute w-28 p-1 text-xs",
7414
+ style: { top: o.y, left: o.x },
7415
+ children: /* @__PURE__ */ jsxs(
7416
+ DropdownMenuItem,
7417
+ {
7418
+ className: "flex items-center gap-x-4 text-xs",
7419
+ onClick: () => {
7420
+ l("root"), r(null);
7421
+ },
7422
+ children: [
7423
+ /* @__PURE__ */ jsx(CardStackIcon, {}),
7424
+ " ",
7425
+ n("Paste")
7426
+ ]
7427
+ }
7428
+ )
7429
+ }
7430
+ )
7431
+ ] }) });
7432
+ }, useCanMove = () => {
7319
7433
  const [o] = useBlocksStore();
7320
7434
  return (r, n) => {
7321
7435
  var i;
@@ -7415,7 +7529,7 @@ const Input = ({ node: o }) => {
7415
7529
  /* @__PURE__ */ jsx("div", { className: cn$1("flex h-full select-none flex-col space-y-1"), onClick: () => clearSelection(), children: /* @__PURE__ */ jsxs(
7416
7530
  "div",
7417
7531
  {
7418
- id: "outline-view",
7532
+ id: "outline-view ",
7419
7533
  className: "no-scrollbar h-full overflow-y-auto text-sm",
7420
7534
  onKeyDown: (o) => {
7421
7535
  treeRef.current.isEditing || handleKeyDown(o);
@@ -7486,7 +7600,8 @@ const Input = ({ node: o }) => {
7486
7600
  ]
7487
7601
  }
7488
7602
  ) }),
7489
- /* @__PURE__ */ jsx(SaveToLibraryModal, {})
7603
+ /* @__PURE__ */ jsx(SaveToLibraryModal, {}),
7604
+ /* @__PURE__ */ jsx(PasteAtRootContextMenu, { parentContext, setParentContext })
7490
7605
  ] });
7491
7606
  }, BorderRadiusInput = ({ value: o, onChange: r, disabled: n }) => {
7492
7607
  const a = debounce((l) => r(l), 200);
@@ -9483,7 +9598,7 @@ export {
9483
9598
  useCanvasDisplayWidth,
9484
9599
  useCanvasZoom,
9485
9600
  useCodeEditor,
9486
- useCopyBlockIds,
9601
+ useCopyBlocks as useCopyBlockIds,
9487
9602
  useCopyToClipboard,
9488
9603
  useCurrentPage,
9489
9604
  useCutBlockIds,
@@ -9494,7 +9609,7 @@ export {
9494
9609
  useLanguages,
9495
9610
  useLibraryBlocks,
9496
9611
  useMediaManagerComponent,
9497
- usePartailBlocksStore,
9612
+ usePartialBlocksStore as usePartailBlocksStore,
9498
9613
  usePartialBlocksList,
9499
9614
  usePasteBlocks,
9500
9615
  usePermissions,
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "author": "Suraj Air",
6
6
  "license": "BSD-3-Clause",
7
7
  "homepage": "https://chaibuilder.com",
8
- "version": "2.2.7",
8
+ "version": "2.2.8",
9
9
  "type": "module",
10
10
  "repository": {
11
11
  "type": "git",
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),n=require("./core.cjs");require("lodash-es");require("clsx");require("tailwind-merge");require("tree-model");const c=require("react");require("jotai");require("@chaibuilder/runtime");const C=require("react-i18next"),v=require("./sooner-AJ7QkeLS.cjs"),j=require("@radix-ui/react-icons"),q=require("@react-hookz/web"),d=o=>{const s=document.createElement("div");return s.innerHTML=o,s.innerHTML};function g(){const{t:o}=C.useTranslation(),[s,x]=c.useState(!1),[i,m]=c.useState(""),[t,a]=n.useCodeEditor(),[u]=n.useSelectedBlockIds(),b=n.useUpdateBlocksProps(),f=n.useUpdateBlocksPropsRealtime(),h=q.useThrottledCallback(l=>{const r=d(l);f([t.blockId],{[t.blockProp]:r})},[],300),p=c.useCallback(()=>{if(s){const l=d(i);b([t.blockId],{[t.blockProp]:l})}},[s,i]);c.useEffect(()=>{u.includes(t==null?void 0:t.blockId)||(p(),a(null))},[u]);const k=()=>{a(null)};return e.jsxs("div",{className:"h-full rounded-t-lg border-t-4 border-black bg-black text-white",children:[e.jsx("button",{onClick:k,className:"fixed inset-0 z-[100000] cursor-default bg-gray-400/20"}),e.jsxs("div",{className:"relative z-[100001] h-full w-full flex-col gap-y-1",children:[e.jsxs("div",{className:"-mt-1 flex items-center justify-between px-2 py-2",children:[e.jsxs("h3",{className:"space-x-3 text-sm font-semibold",children:[e.jsx("span",{children:o("HTML Code Editor |")}),e.jsx("span",{className:"text-xs text-gray-400",children:o("Scripts will be only executed in preview and live mode.")})]}),e.jsx("div",{className:"flex gap-x-2",children:e.jsx(v.Button,{onClick:()=>a(null),size:"sm",variant:"destructive",className:"h-6 w-fit",children:e.jsx(j.Cross2Icon,{})})})]}),e.jsx("textarea",{className:"h-full w-full bg-black p-2 font-mono text-xs text-white/90",value:i||t.initialCode,onChange:l=>{const r=l.target.value;x(!0),m(r),h(r)}})]})]})}exports.default=g;