@tecof/theme-editor 0.0.34 → 0.0.35

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.mjs CHANGED
@@ -1,7 +1,12 @@
1
1
  import * as React__default from 'react';
2
2
  import React__default__default, { createContext, forwardRef, createElement, memo, useRef, useCallback, useContext, useState, useEffect, useMemo, Component, useLayoutEffect } from 'react';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
- import { blocksPlugin, outlinePlugin, fieldsPlugin, Puck, Render, FieldLabel, usePuck, ActionBar } from '@puckeditor/core';
4
+ import { blocksPlugin, outlinePlugin, fieldsPlugin, Puck, Render, usePuck, ActionBar } from '@puckeditor/core';
5
+ import { create } from 'zustand';
6
+ import { immer } from 'zustand/middleware/immer';
7
+ import { nanoid } from 'nanoid';
8
+ import * as ReactDOM from 'react-dom';
9
+ import ReactDOM__default, { createPortal } from 'react-dom';
5
10
  import { useEditor, EditorContent } from '@tiptap/react';
6
11
  import Document from '@tiptap/extension-document';
7
12
  import Paragraph from '@tiptap/extension-paragraph';
@@ -20,8 +25,6 @@ import Link3 from '@tiptap/extension-link';
20
25
  import Code2 from '@tiptap/extension-code';
21
26
  import CodeBlock from '@tiptap/extension-code-block';
22
27
  import Image3 from '@tiptap/extension-image';
23
- import * as ReactDOM from 'react-dom';
24
- import ReactDOM__default from 'react-dom';
25
28
 
26
29
  // src/components/TecofProvider.tsx
27
30
 
@@ -416,38 +419,42 @@ var ChevronDown = createLucideIcon("chevron-down", __iconNode4);
416
419
  var __iconNode5 = [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]];
417
420
  var ChevronRight = createLucideIcon("chevron-right", __iconNode5);
418
421
 
422
+ // node_modules/lucide-react/dist/esm/icons/chevron-up.js
423
+ var __iconNode6 = [["path", { d: "m18 15-6-6-6 6", key: "153udz" }]];
424
+ var ChevronUp = createLucideIcon("chevron-up", __iconNode6);
425
+
419
426
  // node_modules/lucide-react/dist/esm/icons/code.js
420
- var __iconNode6 = [
427
+ var __iconNode7 = [
421
428
  ["path", { d: "m16 18 6-6-6-6", key: "eg8j8" }],
422
429
  ["path", { d: "m8 6-6 6 6 6", key: "ppft3o" }]
423
430
  ];
424
- var Code = createLucideIcon("code", __iconNode6);
431
+ var Code = createLucideIcon("code", __iconNode7);
425
432
 
426
433
  // node_modules/lucide-react/dist/esm/icons/copy.js
427
- var __iconNode7 = [
434
+ var __iconNode8 = [
428
435
  ["rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2", key: "17jyea" }],
429
436
  ["path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2", key: "zix9uf" }]
430
437
  ];
431
- var Copy = createLucideIcon("copy", __iconNode7);
438
+ var Copy = createLucideIcon("copy", __iconNode8);
432
439
 
433
440
  // node_modules/lucide-react/dist/esm/icons/database.js
434
- var __iconNode8 = [
441
+ var __iconNode9 = [
435
442
  ["ellipse", { cx: "12", cy: "5", rx: "9", ry: "3", key: "msslwz" }],
436
443
  ["path", { d: "M3 5V19A9 3 0 0 0 21 19V5", key: "1wlel7" }],
437
444
  ["path", { d: "M3 12A9 3 0 0 0 21 12", key: "mv7ke4" }]
438
445
  ];
439
- var Database = createLucideIcon("database", __iconNode8);
446
+ var Database = createLucideIcon("database", __iconNode9);
440
447
 
441
448
  // node_modules/lucide-react/dist/esm/icons/external-link.js
442
- var __iconNode9 = [
449
+ var __iconNode10 = [
443
450
  ["path", { d: "M15 3h6v6", key: "1q9fwt" }],
444
451
  ["path", { d: "M10 14 21 3", key: "gplh6r" }],
445
452
  ["path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6", key: "a6xqqp" }]
446
453
  ];
447
- var ExternalLink = createLucideIcon("external-link", __iconNode9);
454
+ var ExternalLink = createLucideIcon("external-link", __iconNode10);
448
455
 
449
456
  // node_modules/lucide-react/dist/esm/icons/file-text.js
450
- var __iconNode10 = [
457
+ var __iconNode11 = [
451
458
  [
452
459
  "path",
453
460
  {
@@ -460,10 +467,10 @@ var __iconNode10 = [
460
467
  ["path", { d: "M16 13H8", key: "t4e002" }],
461
468
  ["path", { d: "M16 17H8", key: "z1uh3a" }]
462
469
  ];
463
- var FileText = createLucideIcon("file-text", __iconNode10);
470
+ var FileText = createLucideIcon("file-text", __iconNode11);
464
471
 
465
472
  // node_modules/lucide-react/dist/esm/icons/file.js
466
- var __iconNode11 = [
473
+ var __iconNode12 = [
467
474
  [
468
475
  "path",
469
476
  {
@@ -473,10 +480,10 @@ var __iconNode11 = [
473
480
  ],
474
481
  ["path", { d: "M14 2v5a1 1 0 0 0 1 1h5", key: "wfsgrz" }]
475
482
  ];
476
- var File2 = createLucideIcon("file", __iconNode11);
483
+ var File2 = createLucideIcon("file", __iconNode12);
477
484
 
478
485
  // node_modules/lucide-react/dist/esm/icons/folder-open.js
479
- var __iconNode12 = [
486
+ var __iconNode13 = [
480
487
  [
481
488
  "path",
482
489
  {
@@ -485,18 +492,18 @@ var __iconNode12 = [
485
492
  }
486
493
  ]
487
494
  ];
488
- var FolderOpen = createLucideIcon("folder-open", __iconNode12);
495
+ var FolderOpen = createLucideIcon("folder-open", __iconNode13);
489
496
 
490
497
  // node_modules/lucide-react/dist/esm/icons/globe.js
491
- var __iconNode13 = [
498
+ var __iconNode14 = [
492
499
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
493
500
  ["path", { d: "M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20", key: "13o1zl" }],
494
501
  ["path", { d: "M2 12h20", key: "9i4pu4" }]
495
502
  ];
496
- var Globe = createLucideIcon("globe", __iconNode13);
503
+ var Globe = createLucideIcon("globe", __iconNode14);
497
504
 
498
505
  // node_modules/lucide-react/dist/esm/icons/grip-vertical.js
499
- var __iconNode14 = [
506
+ var __iconNode15 = [
500
507
  ["circle", { cx: "9", cy: "12", r: "1", key: "1vctgf" }],
501
508
  ["circle", { cx: "9", cy: "5", r: "1", key: "hp0tcf" }],
502
509
  ["circle", { cx: "9", cy: "19", r: "1", key: "fkjjf6" }],
@@ -504,28 +511,28 @@ var __iconNode14 = [
504
511
  ["circle", { cx: "15", cy: "5", r: "1", key: "19l28e" }],
505
512
  ["circle", { cx: "15", cy: "19", r: "1", key: "f4zoj3" }]
506
513
  ];
507
- var GripVertical = createLucideIcon("grip-vertical", __iconNode14);
514
+ var GripVertical = createLucideIcon("grip-vertical", __iconNode15);
508
515
 
509
516
  // node_modules/lucide-react/dist/esm/icons/image-plus.js
510
- var __iconNode15 = [
517
+ var __iconNode16 = [
511
518
  ["path", { d: "M16 5h6", key: "1vod17" }],
512
519
  ["path", { d: "M19 2v6", key: "4bpg5p" }],
513
520
  ["path", { d: "M21 11.5V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h7.5", key: "1ue2ih" }],
514
521
  ["path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21", key: "1xmnt7" }],
515
522
  ["circle", { cx: "9", cy: "9", r: "2", key: "af1f0g" }]
516
523
  ];
517
- var ImagePlus = createLucideIcon("image-plus", __iconNode15);
524
+ var ImagePlus = createLucideIcon("image-plus", __iconNode16);
518
525
 
519
526
  // node_modules/lucide-react/dist/esm/icons/image.js
520
- var __iconNode16 = [
527
+ var __iconNode17 = [
521
528
  ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2", key: "1m3agn" }],
522
529
  ["circle", { cx: "9", cy: "9", r: "2", key: "af1f0g" }],
523
530
  ["path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21", key: "1xmnt7" }]
524
531
  ];
525
- var Image2 = createLucideIcon("image", __iconNode16);
532
+ var Image2 = createLucideIcon("image", __iconNode17);
526
533
 
527
534
  // node_modules/lucide-react/dist/esm/icons/languages.js
528
- var __iconNode17 = [
535
+ var __iconNode18 = [
529
536
  ["path", { d: "m5 8 6 6", key: "1wu5hv" }],
530
537
  ["path", { d: "m4 14 6-6 2-3", key: "1k1g8d" }],
531
538
  ["path", { d: "M2 5h12", key: "or177f" }],
@@ -533,29 +540,29 @@ var __iconNode17 = [
533
540
  ["path", { d: "m22 22-5-10-5 10", key: "don7ne" }],
534
541
  ["path", { d: "M14 18h6", key: "1m8k6r" }]
535
542
  ];
536
- var Languages = createLucideIcon("languages", __iconNode17);
543
+ var Languages = createLucideIcon("languages", __iconNode18);
537
544
 
538
545
  // node_modules/lucide-react/dist/esm/icons/link-2.js
539
- var __iconNode18 = [
546
+ var __iconNode19 = [
540
547
  ["path", { d: "M9 17H7A5 5 0 0 1 7 7h2", key: "8i5ue5" }],
541
548
  ["path", { d: "M15 7h2a5 5 0 1 1 0 10h-2", key: "1b9ql8" }],
542
549
  ["line", { x1: "8", x2: "16", y1: "12", y2: "12", key: "1jonct" }]
543
550
  ];
544
- var Link2 = createLucideIcon("link-2", __iconNode18);
551
+ var Link2 = createLucideIcon("link-2", __iconNode19);
545
552
 
546
553
  // node_modules/lucide-react/dist/esm/icons/link.js
547
- var __iconNode19 = [
554
+ var __iconNode20 = [
548
555
  ["path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71", key: "1cjeqo" }],
549
556
  ["path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71", key: "19qd67" }]
550
557
  ];
551
- var Link = createLucideIcon("link", __iconNode19);
558
+ var Link = createLucideIcon("link", __iconNode20);
552
559
 
553
560
  // node_modules/lucide-react/dist/esm/icons/loader-circle.js
554
- var __iconNode20 = [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]];
555
- var LoaderCircle = createLucideIcon("loader-circle", __iconNode20);
561
+ var __iconNode21 = [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]];
562
+ var LoaderCircle = createLucideIcon("loader-circle", __iconNode21);
556
563
 
557
564
  // node_modules/lucide-react/dist/esm/icons/pencil.js
558
- var __iconNode21 = [
565
+ var __iconNode22 = [
559
566
  [
560
567
  "path",
561
568
  {
@@ -565,72 +572,73 @@ var __iconNode21 = [
565
572
  ],
566
573
  ["path", { d: "m15 5 4 4", key: "1mk7zo" }]
567
574
  ];
568
- var Pencil = createLucideIcon("pencil", __iconNode21);
575
+ var Pencil = createLucideIcon("pencil", __iconNode22);
569
576
 
570
577
  // node_modules/lucide-react/dist/esm/icons/plus.js
571
- var __iconNode22 = [
578
+ var __iconNode23 = [
572
579
  ["path", { d: "M5 12h14", key: "1ays0h" }],
573
580
  ["path", { d: "M12 5v14", key: "s699le" }]
574
581
  ];
575
- var Plus = createLucideIcon("plus", __iconNode22);
582
+ var Plus = createLucideIcon("plus", __iconNode23);
576
583
 
577
584
  // node_modules/lucide-react/dist/esm/icons/refresh-ccw.js
578
- var __iconNode23 = [
585
+ var __iconNode24 = [
579
586
  ["path", { d: "M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8", key: "14sxne" }],
580
587
  ["path", { d: "M3 3v5h5", key: "1xhq8a" }],
581
588
  ["path", { d: "M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16", key: "1hlbsb" }],
582
589
  ["path", { d: "M16 16h5v5", key: "ccwih5" }]
583
590
  ];
584
- var RefreshCcw = createLucideIcon("refresh-ccw", __iconNode23);
591
+ var RefreshCcw = createLucideIcon("refresh-ccw", __iconNode24);
585
592
 
586
593
  // node_modules/lucide-react/dist/esm/icons/refresh-cw.js
587
- var __iconNode24 = [
594
+ var __iconNode25 = [
588
595
  ["path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8", key: "v9h5vc" }],
589
596
  ["path", { d: "M21 3v5h-5", key: "1q7to0" }],
590
597
  ["path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16", key: "3uifl3" }],
591
598
  ["path", { d: "M8 16H3v5", key: "1cv678" }]
592
599
  ];
593
- var RefreshCw = createLucideIcon("refresh-cw", __iconNode24);
600
+ var RefreshCw = createLucideIcon("refresh-cw", __iconNode25);
594
601
 
595
602
  // node_modules/lucide-react/dist/esm/icons/rotate-ccw.js
596
- var __iconNode25 = [
603
+ var __iconNode26 = [
597
604
  ["path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8", key: "1357e3" }],
598
605
  ["path", { d: "M3 3v5h5", key: "1xhq8a" }]
599
606
  ];
600
- var RotateCcw = createLucideIcon("rotate-ccw", __iconNode25);
607
+ var RotateCcw = createLucideIcon("rotate-ccw", __iconNode26);
601
608
 
602
609
  // node_modules/lucide-react/dist/esm/icons/search.js
603
- var __iconNode26 = [
610
+ var __iconNode27 = [
604
611
  ["path", { d: "m21 21-4.34-4.34", key: "14j7rj" }],
605
612
  ["circle", { cx: "11", cy: "11", r: "8", key: "4ej97u" }]
606
613
  ];
607
- var Search = createLucideIcon("search", __iconNode26);
614
+ var Search = createLucideIcon("search", __iconNode27);
608
615
 
609
616
  // node_modules/lucide-react/dist/esm/icons/trash-2.js
610
- var __iconNode27 = [
617
+ var __iconNode28 = [
611
618
  ["path", { d: "M10 11v6", key: "nco0om" }],
612
619
  ["path", { d: "M14 11v6", key: "outv1u" }],
613
620
  ["path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6", key: "miytrc" }],
614
621
  ["path", { d: "M3 6h18", key: "d0wm0j" }],
615
622
  ["path", { d: "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2", key: "e791ji" }]
616
623
  ];
617
- var Trash2 = createLucideIcon("trash-2", __iconNode27);
624
+ var Trash2 = createLucideIcon("trash-2", __iconNode28);
618
625
 
619
626
  // node_modules/lucide-react/dist/esm/icons/upload.js
620
- var __iconNode28 = [
627
+ var __iconNode29 = [
621
628
  ["path", { d: "M12 3v12", key: "1x0j5s" }],
622
629
  ["path", { d: "m17 8-5-5-5 5", key: "7q97r8" }],
623
630
  ["path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4", key: "ih7n3h" }]
624
631
  ];
625
- var Upload = createLucideIcon("upload", __iconNode28);
632
+ var Upload = createLucideIcon("upload", __iconNode29);
626
633
 
627
634
  // node_modules/lucide-react/dist/esm/icons/x.js
628
- var __iconNode29 = [
635
+ var __iconNode30 = [
629
636
  ["path", { d: "M18 6 6 18", key: "1bl5f8" }],
630
637
  ["path", { d: "m6 6 12 12", key: "d8bk6v" }]
631
638
  ];
632
- var X = createLucideIcon("x", __iconNode29);
639
+ var X = createLucideIcon("x", __iconNode30);
633
640
  var EMPTY_PAGE = { content: [], root: { props: {} }, zones: {} };
641
+ var DrawerSearchContext = createContext(null);
634
642
  var ComponentDrawerItem = ({
635
643
  name: name3,
636
644
  apiClient,
@@ -680,6 +688,56 @@ var ComponentDrawerItem = ({
680
688
  ] })
681
689
  ] });
682
690
  };
691
+ var CustomDrawer = ({ children }) => {
692
+ const context = useContext(DrawerSearchContext);
693
+ if (!context) return /* @__PURE__ */ jsx("div", { className: "tecof-drawer-list-layout", children });
694
+ const { searchQuery, setSearchQuery } = context;
695
+ return /* @__PURE__ */ jsxs("div", { className: "tecof-drawer-wrapper-layout", children: [
696
+ /* @__PURE__ */ jsx("div", { className: "tecof-drawer-search-wrapper", children: /* @__PURE__ */ jsxs("div", { className: "tecof-drawer-search-box", children: [
697
+ /* @__PURE__ */ jsx(Search, { size: 14, color: "#71717a" }),
698
+ /* @__PURE__ */ jsx(
699
+ "input",
700
+ {
701
+ type: "text",
702
+ placeholder: "Blok ara...",
703
+ value: searchQuery,
704
+ onChange: (e3) => setSearchQuery(e3.target.value),
705
+ className: "tecof-drawer-search-input"
706
+ }
707
+ ),
708
+ searchQuery && /* @__PURE__ */ jsx(
709
+ "button",
710
+ {
711
+ type: "button",
712
+ onClick: () => setSearchQuery(""),
713
+ className: "tecof-drawer-clear-btn",
714
+ title: "Temizle",
715
+ children: /* @__PURE__ */ jsx(X, { size: 14 })
716
+ }
717
+ )
718
+ ] }) }),
719
+ /* @__PURE__ */ jsx("div", { className: "tecof-drawer-list-layout", children })
720
+ ] });
721
+ };
722
+ var CustomDrawerItem = ({ children, name: name3 }) => {
723
+ const context = useContext(DrawerSearchContext);
724
+ const { apiClient } = useTecof();
725
+ if (!context) {
726
+ return /* @__PURE__ */ jsx(ComponentDrawerItem, { name: name3, apiClient, children });
727
+ }
728
+ const { searchQuery, config: config3 } = context;
729
+ const componentConfig = config3.components?.[name3];
730
+ const label = componentConfig?.label || name3;
731
+ if (searchQuery.trim()) {
732
+ const query = searchQuery.toLowerCase();
733
+ const matchesName = name3.toLowerCase().includes(query);
734
+ const matchesLabel = label.toLowerCase().includes(query);
735
+ if (!matchesName && !matchesLabel) {
736
+ return /* @__PURE__ */ jsx(Fragment, {});
737
+ }
738
+ }
739
+ return /* @__PURE__ */ jsx(ComponentDrawerItem, { name: name3, apiClient, children });
740
+ };
683
741
  var AutoFieldsOnSelect = () => {
684
742
  const { selectedItem, dispatch } = usePuck();
685
743
  const prevSelectedRef = useRef(null);
@@ -896,73 +954,41 @@ var TecofEditor = ({
896
954
  document.removeEventListener("click", handleDeselect, false);
897
955
  };
898
956
  }, [isEmbedded]);
957
+ const searchContextValue = useMemo(() => ({
958
+ searchQuery,
959
+ setSearchQuery,
960
+ config: config3
961
+ }), [searchQuery, config3]);
962
+ const plugins = useMemo(() => [
963
+ { ...blocksPlugin(), label: "Bloklar" },
964
+ { ...outlinePlugin(), label: "Anahat" },
965
+ { ...fieldsPlugin({ desktopSideBar: "right" }), label: "Alanlar" },
966
+ ...extraPlugins || []
967
+ ], [extraPlugins]);
968
+ const mergedOverrides = useMemo(() => {
969
+ return {
970
+ header: () => /* @__PURE__ */ jsx(Fragment, {}),
971
+ drawer: CustomDrawer,
972
+ drawerItem: CustomDrawerItem,
973
+ actionBar: ({ children, label }) => {
974
+ return /* @__PURE__ */ jsx(CustomActionBar, { label, children });
975
+ },
976
+ puck: ({ children }) => {
977
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
978
+ /* @__PURE__ */ jsx(AutoFieldsOnSelect, {}),
979
+ children
980
+ ] });
981
+ },
982
+ ...overrides || {}
983
+ };
984
+ }, [overrides]);
899
985
  if (loading || !initialData) {
900
986
  return /* @__PURE__ */ jsx("div", { className: `tecof-editor-loading ${className || ""}`.trim(), children: /* @__PURE__ */ jsxs("div", { className: "tecof-editor-loading-inner", children: [
901
987
  /* @__PURE__ */ jsx("div", { className: "tecof-editor-spinner" }),
902
988
  /* @__PURE__ */ jsx("p", { className: "tecof-editor-loading-text", children: "Loading editor..." })
903
989
  ] }) });
904
990
  }
905
- const plugins = [
906
- { ...blocksPlugin(), label: "Bloklar" },
907
- { ...outlinePlugin(), label: "Anahat" },
908
- { ...fieldsPlugin({ desktopSideBar: "right" }), label: "Alanlar" },
909
- ...extraPlugins || []
910
- ];
911
- const mergedOverrides = {
912
- header: () => /* @__PURE__ */ jsx(Fragment, {}),
913
- drawer: ({ children }) => {
914
- return /* @__PURE__ */ jsxs("div", { className: "tecof-drawer-wrapper-layout", children: [
915
- /* @__PURE__ */ jsx("div", { className: "tecof-drawer-search-wrapper", children: /* @__PURE__ */ jsxs("div", { className: "tecof-drawer-search-box", children: [
916
- /* @__PURE__ */ jsx(Search, { size: 14, color: "#71717a" }),
917
- /* @__PURE__ */ jsx(
918
- "input",
919
- {
920
- type: "text",
921
- placeholder: "Blok ara...",
922
- value: searchQuery,
923
- onChange: (e3) => setSearchQuery(e3.target.value),
924
- className: "tecof-drawer-search-input"
925
- }
926
- ),
927
- searchQuery && /* @__PURE__ */ jsx(
928
- "button",
929
- {
930
- type: "button",
931
- onClick: () => setSearchQuery(""),
932
- className: "tecof-drawer-clear-btn",
933
- title: "Temizle",
934
- children: /* @__PURE__ */ jsx(X, { size: 14 })
935
- }
936
- )
937
- ] }) }),
938
- /* @__PURE__ */ jsx("div", { className: "tecof-drawer-list-layout", children })
939
- ] });
940
- },
941
- drawerItem: ({ children, name: name3 }) => {
942
- const componentConfig = config3.components?.[name3];
943
- const label = componentConfig?.label || name3;
944
- if (searchQuery.trim()) {
945
- const query = searchQuery.toLowerCase();
946
- const matchesName = name3.toLowerCase().includes(query);
947
- const matchesLabel = label.toLowerCase().includes(query);
948
- if (!matchesName && !matchesLabel) {
949
- return /* @__PURE__ */ jsx(Fragment, {});
950
- }
951
- }
952
- return /* @__PURE__ */ jsx(ComponentDrawerItem, { name: name3, apiClient, children });
953
- },
954
- actionBar: ({ children, label }) => {
955
- return /* @__PURE__ */ jsx(CustomActionBar, { label, children });
956
- },
957
- puck: ({ children }) => {
958
- return /* @__PURE__ */ jsxs(Fragment, { children: [
959
- /* @__PURE__ */ jsx(AutoFieldsOnSelect, {}),
960
- children
961
- ] });
962
- },
963
- ...overrides || {}
964
- };
965
- return /* @__PURE__ */ jsxs("div", { className: `tecof-editor-wrapper ${className || ""}`.trim(), children: [
991
+ return /* @__PURE__ */ jsx(DrawerSearchContext.Provider, { value: searchContextValue, children: /* @__PURE__ */ jsxs("div", { className: `tecof-editor-wrapper ${className || ""}`.trim(), children: [
966
992
  /* @__PURE__ */ jsx(
967
993
  Puck,
968
994
  {
@@ -976,7 +1002,1414 @@ var TecofEditor = ({
976
1002
  }
977
1003
  ),
978
1004
  saving && /* @__PURE__ */ jsx("div", { className: "tecof-editor-save-indicator", children: saveStatus === "error" ? "Save failed" : "Saving..." })
979
- ] });
1005
+ ] }) });
1006
+ };
1007
+
1008
+ // src/engine/document.ts
1009
+ var EMPTY_DOCUMENT = {
1010
+ root: { props: {} },
1011
+ content: [],
1012
+ zones: {}
1013
+ };
1014
+ var parseDocument = (rawData) => {
1015
+ if (!rawData) return { ...EMPTY_DOCUMENT };
1016
+ return {
1017
+ root: rawData.root || { props: {} },
1018
+ content: rawData.content || [],
1019
+ zones: rawData.zones || {}
1020
+ };
1021
+ };
1022
+ var serializeDocument = (doc) => {
1023
+ return {
1024
+ root: doc.root,
1025
+ content: doc.content,
1026
+ zones: doc.zones
1027
+ };
1028
+ };
1029
+
1030
+ // src/engine/zones.ts
1031
+ var parseZoneKey = (zoneKey) => {
1032
+ const parts = zoneKey.split(":");
1033
+ return {
1034
+ parentId: parts[0],
1035
+ slotName: parts[1] || "default"
1036
+ };
1037
+ };
1038
+ var findNodeById = (doc, id) => {
1039
+ for (let i2 = 0; i2 < doc.content.length; i2++) {
1040
+ if (doc.content[i2].props.id === id) {
1041
+ return { node: doc.content[i2], path: { index: i2 } };
1042
+ }
1043
+ }
1044
+ for (const [zoneKey, items] of Object.entries(doc.zones)) {
1045
+ for (let i2 = 0; i2 < items.length; i2++) {
1046
+ if (items[i2].props.id === id) {
1047
+ return { node: items[i2], path: { zoneKey, index: i2 } };
1048
+ }
1049
+ }
1050
+ }
1051
+ return null;
1052
+ };
1053
+ var getDescendantZoneKeys = (zones, nodeId, acc = []) => {
1054
+ const prefix = `${nodeId}:`;
1055
+ for (const zoneKey of Object.keys(zones)) {
1056
+ if (zoneKey.startsWith(prefix)) {
1057
+ acc.push(zoneKey);
1058
+ for (const child of zones[zoneKey]) {
1059
+ getDescendantZoneKeys(zones, child.props.id, acc);
1060
+ }
1061
+ }
1062
+ }
1063
+ return acc;
1064
+ };
1065
+ var getParentId = (doc, id) => {
1066
+ const res2 = findNodeById(doc, id);
1067
+ if (!res2 || !res2.path.zoneKey) return null;
1068
+ return parseZoneKey(res2.path.zoneKey).parentId;
1069
+ };
1070
+ var getBreadcrumbs = (doc, id) => {
1071
+ const crumbs = [];
1072
+ let currentId = id;
1073
+ while (currentId) {
1074
+ const res2 = findNodeById(doc, currentId);
1075
+ if (!res2) break;
1076
+ crumbs.unshift({ id: currentId, type: res2.node.type });
1077
+ currentId = res2.path.zoneKey ? parseZoneKey(res2.path.zoneKey).parentId : null;
1078
+ }
1079
+ return crumbs;
1080
+ };
1081
+ var generateId = () => nanoid(8);
1082
+ var remapNodeIds = (node, sourceZones, idMap = /* @__PURE__ */ new Map()) => {
1083
+ const oldId = node.props.id;
1084
+ const newId = generateId();
1085
+ idMap.set(oldId, newId);
1086
+ const remappedNode = {
1087
+ ...node,
1088
+ props: {
1089
+ ...node.props,
1090
+ id: newId
1091
+ }
1092
+ };
1093
+ const newZones = {};
1094
+ const prefix = `${oldId}:`;
1095
+ for (const [zoneKey, zoneItems] of Object.entries(sourceZones)) {
1096
+ if (zoneKey.startsWith(prefix)) {
1097
+ const slotName = zoneKey.split(":")[1];
1098
+ const newZoneKey = `${newId}:${slotName}`;
1099
+ const newZoneItems = [];
1100
+ for (const item2 of zoneItems) {
1101
+ const { remappedNode: childNode, newZones: childZones } = remapNodeIds(item2, sourceZones, idMap);
1102
+ newZoneItems.push(childNode);
1103
+ Object.assign(newZones, childZones);
1104
+ }
1105
+ newZones[newZoneKey] = newZoneItems;
1106
+ }
1107
+ }
1108
+ return { remappedNode, newZones };
1109
+ };
1110
+
1111
+ // src/engine/operations.ts
1112
+ var insertNode = (draft, node, targetZoneKey, index2) => {
1113
+ if (!node.props.id) {
1114
+ node.props.id = generateId();
1115
+ }
1116
+ let list3 = targetZoneKey ? draft.zones[targetZoneKey] : draft.content;
1117
+ if (!list3) {
1118
+ list3 = [];
1119
+ if (targetZoneKey) {
1120
+ draft.zones[targetZoneKey] = list3;
1121
+ }
1122
+ }
1123
+ const insertIndex = typeof index2 === "number" ? index2 : list3.length;
1124
+ list3.splice(insertIndex, 0, node);
1125
+ };
1126
+ var removeNode = (draft, id) => {
1127
+ const result = findNodeById(draft, id);
1128
+ if (!result) return;
1129
+ const { path } = result;
1130
+ const list3 = path.zoneKey ? draft.zones[path.zoneKey] : draft.content;
1131
+ if (list3) {
1132
+ list3.splice(path.index, 1);
1133
+ }
1134
+ const descendantZoneKeys = getDescendantZoneKeys(draft.zones, id);
1135
+ for (const zoneKey of descendantZoneKeys) {
1136
+ delete draft.zones[zoneKey];
1137
+ }
1138
+ };
1139
+ var moveNode = (draft, id, targetZoneKey, targetIndex) => {
1140
+ const result = findNodeById(draft, id);
1141
+ if (!result) return;
1142
+ const { node, path: sourcePath } = result;
1143
+ const sourceList = sourcePath.zoneKey ? draft.zones[sourcePath.zoneKey] : draft.content;
1144
+ let targetList = targetZoneKey ? draft.zones[targetZoneKey] : draft.content;
1145
+ if (!targetList && targetZoneKey) {
1146
+ targetList = [];
1147
+ draft.zones[targetZoneKey] = targetList;
1148
+ }
1149
+ if (!sourceList || !targetList) return;
1150
+ sourceList.splice(sourcePath.index, 1);
1151
+ let finalIndex = targetIndex ?? targetList.length;
1152
+ if (sourcePath.zoneKey === targetZoneKey && sourcePath.index < finalIndex) {
1153
+ finalIndex -= 1;
1154
+ }
1155
+ targetList.splice(finalIndex, 0, node);
1156
+ };
1157
+ var duplicateNode = (draft, id) => {
1158
+ const result = findNodeById(draft, id);
1159
+ if (!result) return;
1160
+ const { node, path } = result;
1161
+ const { remappedNode, newZones } = remapNodeIds(node, draft.zones);
1162
+ const targetList = path.zoneKey ? draft.zones[path.zoneKey] : draft.content;
1163
+ if (targetList) {
1164
+ targetList.splice(path.index + 1, 0, remappedNode);
1165
+ }
1166
+ Object.assign(draft.zones, newZones);
1167
+ };
1168
+ var updateProps = (draft, id, patch) => {
1169
+ const result = findNodeById(draft, id);
1170
+ if (!result) return;
1171
+ Object.assign(result.node.props, patch);
1172
+ };
1173
+ var setRootProps = (draft, patch) => {
1174
+ Object.assign(draft.root.props, patch);
1175
+ };
1176
+
1177
+ // src/engine/store.ts
1178
+ var pushToHistory = (state3) => {
1179
+ state3.history.past.push(JSON.parse(JSON.stringify(state3.document)));
1180
+ state3.history.future = [];
1181
+ };
1182
+ var useEditorStore = create()(
1183
+ immer((set2) => ({
1184
+ // Initial State
1185
+ document: { ...EMPTY_DOCUMENT },
1186
+ history: {
1187
+ past: [],
1188
+ future: []
1189
+ },
1190
+ selection: {
1191
+ selectedId: null,
1192
+ hoveredId: null
1193
+ },
1194
+ viewport: "desktop",
1195
+ // Actions
1196
+ setDocument: (doc) => set2((state3) => {
1197
+ state3.document = doc;
1198
+ state3.history = { past: [], future: [] };
1199
+ state3.selection = { selectedId: null, hoveredId: null };
1200
+ }),
1201
+ selectNode: (id) => set2((state3) => {
1202
+ state3.selection.selectedId = id;
1203
+ }),
1204
+ hoverNode: (id) => set2((state3) => {
1205
+ state3.selection.hoveredId = id;
1206
+ }),
1207
+ setViewport: (viewport) => set2((state3) => {
1208
+ state3.viewport = viewport;
1209
+ }),
1210
+ insertNode: (node, targetZoneKey, index2) => set2((state3) => {
1211
+ pushToHistory(state3);
1212
+ insertNode(state3.document, node, targetZoneKey, index2);
1213
+ }),
1214
+ removeNode: (id) => set2((state3) => {
1215
+ pushToHistory(state3);
1216
+ removeNode(state3.document, id);
1217
+ if (state3.selection.selectedId === id) {
1218
+ state3.selection.selectedId = null;
1219
+ }
1220
+ }),
1221
+ moveNode: (id, targetZoneKey, index2) => set2((state3) => {
1222
+ pushToHistory(state3);
1223
+ moveNode(state3.document, id, targetZoneKey, index2);
1224
+ }),
1225
+ duplicateNode: (id) => set2((state3) => {
1226
+ pushToHistory(state3);
1227
+ duplicateNode(state3.document, id);
1228
+ }),
1229
+ updateProps: (id, patch) => set2((state3) => {
1230
+ pushToHistory(state3);
1231
+ updateProps(state3.document, id, patch);
1232
+ }),
1233
+ setRootProps: (patch) => set2((state3) => {
1234
+ pushToHistory(state3);
1235
+ setRootProps(state3.document, patch);
1236
+ }),
1237
+ undo: () => set2((state3) => {
1238
+ if (state3.history.past.length === 0) return;
1239
+ const previous = state3.history.past.pop();
1240
+ state3.history.future.push(JSON.parse(JSON.stringify(state3.document)));
1241
+ state3.document = previous;
1242
+ }),
1243
+ redo: () => set2((state3) => {
1244
+ if (state3.history.future.length === 0) return;
1245
+ const next = state3.history.future.pop();
1246
+ state3.history.past.push(JSON.parse(JSON.stringify(state3.document)));
1247
+ state3.document = next;
1248
+ })
1249
+ }))
1250
+ );
1251
+ var StudioContext = createContext(null);
1252
+ var useStudio = () => {
1253
+ const ctx = useContext(StudioContext);
1254
+ if (!ctx) {
1255
+ throw new Error("useStudio must be used within a StudioProvider");
1256
+ }
1257
+ return ctx;
1258
+ };
1259
+ var ParentNodeContext = createContext(null);
1260
+ var DropZone = ({ zone, className, style }) => {
1261
+ const parentId = useContext(ParentNodeContext);
1262
+ const zoneKey = parentId ? `${parentId}:${zone}` : zone;
1263
+ const items = useEditorStore((state3) => state3.document.zones[zoneKey] || []);
1264
+ return /* @__PURE__ */ jsx(
1265
+ "div",
1266
+ {
1267
+ className: `tecof-dropzone ${className || ""}`,
1268
+ style: { minHeight: items.length === 0 ? "40px" : void 0, ...style },
1269
+ "data-tecof-zone": zoneKey,
1270
+ children: items.map((item2, index2) => /* @__PURE__ */ jsx(NodeRenderer, { node: item2, index: index2, zoneKey }, item2.props.id))
1271
+ }
1272
+ );
1273
+ };
1274
+ var renderDropZone = ({ zone, className, style }) => {
1275
+ return /* @__PURE__ */ jsx(DropZone, { zone, className, style });
1276
+ };
1277
+ var NodeRenderer = ({ node, index: index2, zoneKey }) => {
1278
+ const { config: config3, metadata, readOnly } = useStudio();
1279
+ const componentConfig = config3.components[node.type];
1280
+ const selectNode = useEditorStore((state3) => state3.selectNode);
1281
+ const hoverNode = useEditorStore((state3) => state3.hoverNode);
1282
+ const hoveredId = useEditorStore((state3) => state3.selection.hoveredId);
1283
+ const handleMouseEnter = useCallback(
1284
+ (e3) => {
1285
+ if (readOnly) return;
1286
+ e3.stopPropagation();
1287
+ hoverNode(node.props.id);
1288
+ },
1289
+ [hoverNode, node.props.id, readOnly]
1290
+ );
1291
+ const handleMouseLeave = useCallback(
1292
+ (e3) => {
1293
+ if (readOnly) return;
1294
+ e3.stopPropagation();
1295
+ if (hoveredId === node.props.id) {
1296
+ hoverNode(null);
1297
+ }
1298
+ },
1299
+ [hoverNode, node.props.id, hoveredId, readOnly]
1300
+ );
1301
+ const handleClick = useCallback(
1302
+ (e3) => {
1303
+ if (readOnly) return;
1304
+ e3.stopPropagation();
1305
+ selectNode(node.props.id);
1306
+ const isEmbedded = typeof window !== "undefined" && window.parent !== window;
1307
+ if (isEmbedded) {
1308
+ window.parent.postMessage(
1309
+ {
1310
+ type: "puck:itemSelected",
1311
+ item: {
1312
+ type: node.type,
1313
+ id: node.props.id
1314
+ }
1315
+ },
1316
+ "*"
1317
+ );
1318
+ }
1319
+ },
1320
+ [selectNode, node.props.id, node.type, readOnly]
1321
+ );
1322
+ if (!componentConfig) {
1323
+ return /* @__PURE__ */ jsxs("div", { style: { padding: "12px", background: "#fee2e2", color: "#991b1b", fontSize: "12px", borderRadius: "4px" }, children: [
1324
+ "Bile\u015Fen bulunamad\u0131: ",
1325
+ node.type
1326
+ ] });
1327
+ }
1328
+ const componentProps = {
1329
+ ...node.props,
1330
+ puck: {
1331
+ renderDropZone,
1332
+ isEditing: !readOnly,
1333
+ metadata: {
1334
+ ...metadata || {},
1335
+ ...componentConfig.metadata || {}
1336
+ }
1337
+ },
1338
+ editMode: !readOnly
1339
+ };
1340
+ return /* @__PURE__ */ jsx(ParentNodeContext.Provider, { value: node.props.id, children: /* @__PURE__ */ jsx(
1341
+ "div",
1342
+ {
1343
+ className: "tecof-node-wrapper",
1344
+ "data-tecof-id": node.props.id,
1345
+ "data-tecof-type": node.type,
1346
+ "data-tecof-index": index2,
1347
+ "data-tecof-zone": zoneKey || "root",
1348
+ onMouseEnter: handleMouseEnter,
1349
+ onMouseLeave: handleMouseLeave,
1350
+ onClick: handleClick,
1351
+ style: {
1352
+ cursor: readOnly ? void 0 : "pointer"
1353
+ },
1354
+ children: componentConfig.render(componentProps)
1355
+ }
1356
+ ) });
1357
+ };
1358
+ var Frame = ({ children, title = "Canvas Frame", ...props }) => {
1359
+ const [contentRef, setContentRef] = useState(null);
1360
+ const mountNode = contentRef?.contentWindow?.document?.body;
1361
+ useEffect(() => {
1362
+ if (!contentRef) return;
1363
+ const doc = contentRef.contentDocument;
1364
+ if (!doc) return;
1365
+ const copyStyles = () => {
1366
+ doc.head.innerHTML = "";
1367
+ Array.from(document.styleSheets).forEach((styleSheet) => {
1368
+ try {
1369
+ if (styleSheet.href) {
1370
+ const link = doc.createElement("link");
1371
+ link.rel = "stylesheet";
1372
+ link.href = styleSheet.href;
1373
+ doc.head.appendChild(link);
1374
+ } else {
1375
+ const cssRules = Array.from(styleSheet.cssRules).map((rule) => rule.cssText).join("\n");
1376
+ const style2 = doc.createElement("style");
1377
+ style2.textContent = cssRules;
1378
+ doc.head.appendChild(style2);
1379
+ }
1380
+ } catch (e3) {
1381
+ }
1382
+ });
1383
+ const style = doc.createElement("style");
1384
+ style.textContent = `
1385
+ html, body {
1386
+ margin: 0;
1387
+ padding: 0;
1388
+ background-color: transparent;
1389
+ min-height: 100vh;
1390
+ }
1391
+ body {
1392
+ padding: 32px 16px;
1393
+ box-sizing: border-box;
1394
+ }
1395
+ .tecof-node-wrapper {
1396
+ position: relative;
1397
+ transition: outline 0.15s ease-in-out;
1398
+ }
1399
+ /* Custom scrollbars for iframe */
1400
+ ::-webkit-scrollbar {
1401
+ width: 8px;
1402
+ height: 8px;
1403
+ }
1404
+ ::-webkit-scrollbar-track {
1405
+ background: transparent;
1406
+ }
1407
+ ::-webkit-scrollbar-thumb {
1408
+ background: rgba(0, 0, 0, 0.15);
1409
+ border-radius: 4px;
1410
+ }
1411
+ ::-webkit-scrollbar-thumb:hover {
1412
+ background: rgba(0, 0, 0, 0.25);
1413
+ }
1414
+ `;
1415
+ doc.head.appendChild(style);
1416
+ };
1417
+ copyStyles();
1418
+ if (doc.body) {
1419
+ doc.body.className = "tecof-canvas-body";
1420
+ const handleBodyClick = (e3) => {
1421
+ const target = e3.target;
1422
+ if (!target.closest(".tecof-node-wrapper")) {
1423
+ useEditorStore.getState().selectNode(null);
1424
+ const isEmbedded = typeof window !== "undefined" && window.parent !== window;
1425
+ if (isEmbedded) {
1426
+ window.parent.postMessage({ type: "puck:itemDeselected" }, "*");
1427
+ }
1428
+ }
1429
+ };
1430
+ doc.body.addEventListener("click", handleBodyClick);
1431
+ return () => {
1432
+ doc.body.removeEventListener("click", handleBodyClick);
1433
+ };
1434
+ }
1435
+ }, [contentRef]);
1436
+ return /* @__PURE__ */ jsx(
1437
+ "iframe",
1438
+ {
1439
+ title,
1440
+ ref: setContentRef,
1441
+ style: {
1442
+ width: "100%",
1443
+ height: "100%",
1444
+ border: "none",
1445
+ background: "#ffffff",
1446
+ ...props.style
1447
+ },
1448
+ ...props,
1449
+ children: mountNode && createPortal(children, mountNode)
1450
+ }
1451
+ );
1452
+ };
1453
+ var Canvas = () => {
1454
+ const content = useEditorStore((state3) => state3.document.content);
1455
+ const viewport = useEditorStore((state3) => state3.viewport);
1456
+ const getWidth2 = () => {
1457
+ switch (viewport) {
1458
+ case "tablet":
1459
+ return "768px";
1460
+ case "mobile":
1461
+ return "375px";
1462
+ case "desktop":
1463
+ default:
1464
+ return "100%";
1465
+ }
1466
+ };
1467
+ return /* @__PURE__ */ jsx("div", { className: "tecof-canvas-container", style: {
1468
+ flex: 1,
1469
+ display: "flex",
1470
+ alignItems: "center",
1471
+ justifyContent: "center",
1472
+ background: "#f4f4f5",
1473
+ padding: "24px",
1474
+ overflow: "auto",
1475
+ height: "100%",
1476
+ boxSizing: "border-box"
1477
+ }, children: /* @__PURE__ */ jsx(
1478
+ "div",
1479
+ {
1480
+ className: "tecof-canvas-viewport-wrapper",
1481
+ style: {
1482
+ width: getWidth2(),
1483
+ height: "100%",
1484
+ maxWidth: "100%",
1485
+ transition: "width 0.3s cubic-bezier(0.4, 0, 0.2, 1)",
1486
+ boxShadow: "0 10px 25px -5px rgba(0, 0, 0, 0.05), 0 8px 10px -6px rgba(0, 0, 0, 0.05)",
1487
+ borderRadius: viewport === "desktop" ? "0" : "12px",
1488
+ overflow: "hidden",
1489
+ backgroundColor: "#ffffff"
1490
+ },
1491
+ children: /* @__PURE__ */ jsx(Frame, { children: /* @__PURE__ */ jsx("div", { className: "tecof-canvas-root", style: { minHeight: "100%" }, children: content.map((item2, index2) => /* @__PURE__ */ jsx(NodeRenderer, { node: item2, index: index2 }, item2.props.id)) }) })
1492
+ }
1493
+ ) });
1494
+ };
1495
+ var useOverlayCoords = (id, iframeEl, containerEl, documentState) => {
1496
+ const [coords, setCoords] = useState(null);
1497
+ useEffect(() => {
1498
+ if (!id || !iframeEl || !containerEl) {
1499
+ setCoords(null);
1500
+ return;
1501
+ }
1502
+ let resizeObserver = null;
1503
+ let targetResizeObserver = null;
1504
+ const updateCoords = () => {
1505
+ const doc = iframeEl.contentDocument;
1506
+ if (!doc) return;
1507
+ const element = doc.querySelector(`[data-tecof-id="${id}"]`);
1508
+ if (!element) {
1509
+ setCoords(null);
1510
+ return;
1511
+ }
1512
+ const rect = element.getBoundingClientRect();
1513
+ const iframeRect = iframeEl.getBoundingClientRect();
1514
+ const containerRect = containerEl.getBoundingClientRect();
1515
+ setCoords({
1516
+ top: rect.top + iframeRect.top - containerRect.top,
1517
+ left: rect.left + iframeRect.left - containerRect.left,
1518
+ width: rect.width,
1519
+ height: rect.height
1520
+ });
1521
+ if (!targetResizeObserver) {
1522
+ targetResizeObserver = new ResizeObserver(() => {
1523
+ updateCoords();
1524
+ });
1525
+ targetResizeObserver.observe(element);
1526
+ }
1527
+ };
1528
+ updateCoords();
1529
+ const iframeWin = iframeEl.contentWindow;
1530
+ resizeObserver = new ResizeObserver(() => {
1531
+ updateCoords();
1532
+ });
1533
+ resizeObserver.observe(iframeEl);
1534
+ iframeWin?.addEventListener("scroll", updateCoords);
1535
+ window.addEventListener("resize", updateCoords);
1536
+ return () => {
1537
+ if (resizeObserver) resizeObserver.disconnect();
1538
+ if (targetResizeObserver) targetResizeObserver.disconnect();
1539
+ iframeWin?.removeEventListener("scroll", updateCoords);
1540
+ window.removeEventListener("resize", updateCoords);
1541
+ };
1542
+ }, [id, iframeEl, containerEl, documentState]);
1543
+ return coords;
1544
+ };
1545
+ var SelectionOverlay = () => {
1546
+ const documentState = useEditorStore((state3) => state3.document);
1547
+ const selectedId = useEditorStore((state3) => state3.selection.selectedId);
1548
+ const hoveredId = useEditorStore((state3) => state3.selection.hoveredId);
1549
+ const selectNode = useEditorStore((state3) => state3.selectNode);
1550
+ const removeNode2 = useEditorStore((state3) => state3.removeNode);
1551
+ const duplicateNode2 = useEditorStore((state3) => state3.duplicateNode);
1552
+ const moveNode2 = useEditorStore((state3) => state3.moveNode);
1553
+ const [iframeEl, setIframeEl] = useState(null);
1554
+ const containerRef = useRef(null);
1555
+ useEffect(() => {
1556
+ const iframe = document.querySelector(".tecof-canvas-viewport-wrapper iframe");
1557
+ setIframeEl(iframe);
1558
+ }, [documentState]);
1559
+ const selectedCoords = useOverlayCoords(selectedId, iframeEl, containerRef.current, documentState);
1560
+ const hoveredCoords = useOverlayCoords(
1561
+ hoveredId !== selectedId ? hoveredId : null,
1562
+ iframeEl,
1563
+ containerRef.current,
1564
+ documentState
1565
+ );
1566
+ const nodeDetails = selectedId ? findNodeById(documentState, selectedId) : null;
1567
+ const parentId = selectedId ? getParentId(documentState, selectedId) : null;
1568
+ const canMoveUp = nodeDetails ? nodeDetails.path.index > 0 : false;
1569
+ const canMoveDown = nodeDetails ? (() => {
1570
+ const { zoneKey, index: index2 } = nodeDetails.path;
1571
+ const items = zoneKey ? documentState.zones[zoneKey] || [] : documentState.content;
1572
+ return index2 < items.length - 1;
1573
+ })() : false;
1574
+ const handleMove = (direction) => {
1575
+ if (!selectedId || !nodeDetails) return;
1576
+ const { zoneKey, index: index2 } = nodeDetails.path;
1577
+ const newIndex = direction === "up" ? index2 - 1 : index2 + 1;
1578
+ moveNode2(selectedId, zoneKey, newIndex);
1579
+ };
1580
+ const breadcrumbs = selectedId ? getBreadcrumbs(documentState, selectedId) : [];
1581
+ return /* @__PURE__ */ jsxs(
1582
+ "div",
1583
+ {
1584
+ ref: containerRef,
1585
+ className: "tecof-selection-overlay-container",
1586
+ style: {
1587
+ position: "absolute",
1588
+ top: 0,
1589
+ left: 0,
1590
+ right: 0,
1591
+ bottom: 0,
1592
+ pointerEvents: "none",
1593
+ zIndex: 1e3
1594
+ },
1595
+ children: [
1596
+ hoveredCoords && /* @__PURE__ */ jsx(
1597
+ "div",
1598
+ {
1599
+ className: "tecof-hover-outline",
1600
+ style: {
1601
+ position: "absolute",
1602
+ top: hoveredCoords.top,
1603
+ left: hoveredCoords.left,
1604
+ width: hoveredCoords.width,
1605
+ height: hoveredCoords.height,
1606
+ border: "1.5px dashed #3b82f6",
1607
+ borderRadius: "4px",
1608
+ boxSizing: "border-box",
1609
+ pointerEvents: "none",
1610
+ transition: "all 0.1s ease-out"
1611
+ }
1612
+ }
1613
+ ),
1614
+ selectedCoords && /* @__PURE__ */ jsxs(
1615
+ "div",
1616
+ {
1617
+ className: "tecof-selected-outline",
1618
+ style: {
1619
+ position: "absolute",
1620
+ top: selectedCoords.top,
1621
+ left: selectedCoords.left,
1622
+ width: selectedCoords.width,
1623
+ height: selectedCoords.height,
1624
+ border: "2px solid #3b82f6",
1625
+ borderRadius: "4px",
1626
+ boxSizing: "border-box",
1627
+ pointerEvents: "none",
1628
+ transition: "all 0.1s ease-out"
1629
+ },
1630
+ children: [
1631
+ /* @__PURE__ */ jsxs(
1632
+ "div",
1633
+ {
1634
+ className: "tecof-floating-toolbar",
1635
+ style: {
1636
+ position: "absolute",
1637
+ top: "-36px",
1638
+ right: "-2px",
1639
+ display: "flex",
1640
+ alignItems: "center",
1641
+ gap: "4px",
1642
+ background: "#3b82f6",
1643
+ borderRadius: "6px",
1644
+ padding: "4px",
1645
+ pointerEvents: "auto",
1646
+ boxShadow: "0 4px 6px -1px rgba(59, 130, 246, 0.2)"
1647
+ },
1648
+ children: [
1649
+ parentId && /* @__PURE__ */ jsx(
1650
+ "button",
1651
+ {
1652
+ onClick: () => selectNode(parentId),
1653
+ title: "\xDCst \xD6\u011Feyi Se\xE7",
1654
+ style: {
1655
+ background: "transparent",
1656
+ border: "none",
1657
+ color: "#ffffff",
1658
+ cursor: "pointer",
1659
+ padding: "4px",
1660
+ borderRadius: "4px",
1661
+ display: "flex"
1662
+ },
1663
+ children: /* @__PURE__ */ jsx(ChevronUp, { size: 14 })
1664
+ }
1665
+ ),
1666
+ /* @__PURE__ */ jsx(
1667
+ "button",
1668
+ {
1669
+ onClick: () => handleMove("up"),
1670
+ disabled: !canMoveUp,
1671
+ title: "Yukar\u0131 Ta\u015F\u0131",
1672
+ style: {
1673
+ background: "transparent",
1674
+ border: "none",
1675
+ color: "#ffffff",
1676
+ opacity: canMoveUp ? 1 : 0.5,
1677
+ cursor: canMoveUp ? "pointer" : "not-allowed",
1678
+ padding: "4px",
1679
+ borderRadius: "4px",
1680
+ display: "flex"
1681
+ },
1682
+ children: /* @__PURE__ */ jsx(ArrowUp, { size: 14 })
1683
+ }
1684
+ ),
1685
+ /* @__PURE__ */ jsx(
1686
+ "button",
1687
+ {
1688
+ onClick: () => handleMove("down"),
1689
+ disabled: !canMoveDown,
1690
+ title: "A\u015Fa\u011F\u0131 Ta\u015F\u0131",
1691
+ style: {
1692
+ background: "transparent",
1693
+ border: "none",
1694
+ color: "#ffffff",
1695
+ opacity: canMoveDown ? 1 : 0.5,
1696
+ cursor: canMoveDown ? "pointer" : "not-allowed",
1697
+ padding: "4px",
1698
+ borderRadius: "4px",
1699
+ display: "flex"
1700
+ },
1701
+ children: /* @__PURE__ */ jsx(ArrowDown, { size: 14 })
1702
+ }
1703
+ ),
1704
+ /* @__PURE__ */ jsx("div", { style: { width: "1px", height: "14px", background: "rgba(255,255,255,0.3)", margin: "0 2px" } }),
1705
+ /* @__PURE__ */ jsx(
1706
+ "button",
1707
+ {
1708
+ onClick: () => duplicateNode2(selectedId),
1709
+ title: "Kopyala",
1710
+ style: {
1711
+ background: "transparent",
1712
+ border: "none",
1713
+ color: "#ffffff",
1714
+ cursor: "pointer",
1715
+ padding: "4px",
1716
+ borderRadius: "4px",
1717
+ display: "flex"
1718
+ },
1719
+ children: /* @__PURE__ */ jsx(Copy, { size: 14 })
1720
+ }
1721
+ ),
1722
+ /* @__PURE__ */ jsx(
1723
+ "button",
1724
+ {
1725
+ onClick: () => removeNode2(selectedId),
1726
+ title: "Sil",
1727
+ style: {
1728
+ background: "transparent",
1729
+ border: "none",
1730
+ color: "#ffffff",
1731
+ cursor: "pointer",
1732
+ padding: "4px",
1733
+ borderRadius: "4px",
1734
+ display: "flex"
1735
+ },
1736
+ children: /* @__PURE__ */ jsx(Trash2, { size: 14 })
1737
+ }
1738
+ )
1739
+ ]
1740
+ }
1741
+ ),
1742
+ nodeDetails && /* @__PURE__ */ jsx(
1743
+ "div",
1744
+ {
1745
+ className: "tecof-outline-label",
1746
+ style: {
1747
+ position: "absolute",
1748
+ top: "-26px",
1749
+ left: "-2px",
1750
+ background: "#3b82f6",
1751
+ color: "#ffffff",
1752
+ fontSize: "11px",
1753
+ fontWeight: 600,
1754
+ padding: "2px 8px",
1755
+ borderRadius: "4px 4px 0 0",
1756
+ userSelect: "none"
1757
+ },
1758
+ children: nodeDetails.node.type
1759
+ }
1760
+ ),
1761
+ breadcrumbs.length > 1 && /* @__PURE__ */ jsx(
1762
+ "div",
1763
+ {
1764
+ className: "tecof-selected-breadcrumbs",
1765
+ style: {
1766
+ position: "absolute",
1767
+ bottom: "-28px",
1768
+ left: "-2px",
1769
+ display: "flex",
1770
+ alignItems: "center",
1771
+ gap: "4px",
1772
+ background: "#18181b",
1773
+ color: "#a1a1aa",
1774
+ fontSize: "10px",
1775
+ padding: "4px 8px",
1776
+ borderRadius: "0 0 6px 6px",
1777
+ pointerEvents: "auto",
1778
+ boxShadow: "0 2px 4px rgba(0,0,0,0.05)"
1779
+ },
1780
+ children: breadcrumbs.map((crumb, idx) => /* @__PURE__ */ jsxs(React__default__default.Fragment, { children: [
1781
+ idx > 0 && /* @__PURE__ */ jsx("span", { style: { color: "#52525b" }, children: ">" }),
1782
+ /* @__PURE__ */ jsx(
1783
+ "span",
1784
+ {
1785
+ onClick: () => selectNode(crumb.id),
1786
+ style: {
1787
+ cursor: "pointer",
1788
+ color: crumb.id === selectedId ? "#ffffff" : void 0,
1789
+ fontWeight: crumb.id === selectedId ? 600 : void 0
1790
+ },
1791
+ onMouseEnter: () => useEditorStore.getState().hoverNode(crumb.id),
1792
+ onMouseLeave: () => useEditorStore.getState().hoverNode(null),
1793
+ children: crumb.type
1794
+ }
1795
+ )
1796
+ ] }, crumb.id))
1797
+ }
1798
+ )
1799
+ ]
1800
+ }
1801
+ )
1802
+ ]
1803
+ }
1804
+ );
1805
+ };
1806
+ var FieldLabel = ({
1807
+ label,
1808
+ icon,
1809
+ readOnly,
1810
+ children,
1811
+ el = "label"
1812
+ }) => {
1813
+ const Component2 = el;
1814
+ return /* @__PURE__ */ jsxs(
1815
+ Component2,
1816
+ {
1817
+ className: "tecof-field-label-container",
1818
+ style: {
1819
+ display: "flex",
1820
+ flexDirection: "column",
1821
+ gap: "6px",
1822
+ marginBottom: "16px",
1823
+ width: "100%",
1824
+ boxSizing: "border-box",
1825
+ userSelect: "none"
1826
+ },
1827
+ children: [
1828
+ /* @__PURE__ */ jsxs(
1829
+ "div",
1830
+ {
1831
+ className: "tecof-field-label-header",
1832
+ style: {
1833
+ display: "flex",
1834
+ alignItems: "center",
1835
+ gap: "6px",
1836
+ fontSize: "12px",
1837
+ fontWeight: 600,
1838
+ color: "#27272a"
1839
+ // zinc-800
1840
+ },
1841
+ children: [
1842
+ icon && /* @__PURE__ */ jsx("span", { style: { display: "inline-flex" }, children: icon }),
1843
+ /* @__PURE__ */ jsx("span", { children: label }),
1844
+ readOnly && /* @__PURE__ */ jsx(
1845
+ "span",
1846
+ {
1847
+ style: {
1848
+ fontSize: "10px",
1849
+ color: "#a1a1aa",
1850
+ fontWeight: 400,
1851
+ marginLeft: "auto"
1852
+ },
1853
+ children: "Salt Okunur"
1854
+ }
1855
+ )
1856
+ ]
1857
+ }
1858
+ ),
1859
+ /* @__PURE__ */ jsx("div", { className: "tecof-field-label-content", style: { width: "100%" }, children })
1860
+ ]
1861
+ }
1862
+ );
1863
+ };
1864
+ var FieldRenderer = ({
1865
+ name: name3,
1866
+ definition,
1867
+ value,
1868
+ onChange,
1869
+ readOnly = false
1870
+ }) => {
1871
+ const label = definition.label || name3;
1872
+ const type = definition.type;
1873
+ if (definition.render) {
1874
+ return /* @__PURE__ */ jsx("div", { className: "tecof-custom-field-wrapper", style: { width: "100%" }, children: definition.render({
1875
+ field: definition,
1876
+ name: name3,
1877
+ id: `field-${name3}`,
1878
+ value,
1879
+ onChange,
1880
+ readOnly
1881
+ }) });
1882
+ }
1883
+ switch (type) {
1884
+ case "text":
1885
+ return /* @__PURE__ */ jsx(FieldLabel, { label, readOnly, children: /* @__PURE__ */ jsx(
1886
+ "input",
1887
+ {
1888
+ id: `field-${name3}`,
1889
+ type: "text",
1890
+ value: value || "",
1891
+ disabled: readOnly,
1892
+ onChange: (e3) => onChange(e3.target.value),
1893
+ style: {
1894
+ width: "100%",
1895
+ padding: "10px 12px",
1896
+ borderRadius: "8px",
1897
+ border: "1px solid #e4e4e7",
1898
+ fontSize: "13px",
1899
+ color: "#18181b",
1900
+ backgroundColor: readOnly ? "#f4f4f5" : "#ffffff",
1901
+ outline: "none",
1902
+ boxSizing: "border-box",
1903
+ transition: "border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out"
1904
+ },
1905
+ className: "tecof-input-text"
1906
+ }
1907
+ ) });
1908
+ case "textarea":
1909
+ return /* @__PURE__ */ jsx(FieldLabel, { label, readOnly, children: /* @__PURE__ */ jsx(
1910
+ "textarea",
1911
+ {
1912
+ id: `field-${name3}`,
1913
+ rows: 4,
1914
+ value: value || "",
1915
+ disabled: readOnly,
1916
+ onChange: (e3) => onChange(e3.target.value),
1917
+ style: {
1918
+ width: "100%",
1919
+ padding: "10px 12px",
1920
+ borderRadius: "8px",
1921
+ border: "1px solid #e4e4e7",
1922
+ fontSize: "13px",
1923
+ color: "#18181b",
1924
+ backgroundColor: readOnly ? "#f4f4f5" : "#ffffff",
1925
+ outline: "none",
1926
+ resize: "vertical",
1927
+ boxSizing: "border-box",
1928
+ transition: "border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out"
1929
+ },
1930
+ className: "tecof-input-textarea"
1931
+ }
1932
+ ) });
1933
+ case "select":
1934
+ return /* @__PURE__ */ jsx(FieldLabel, { label, readOnly, children: /* @__PURE__ */ jsxs("div", { style: { position: "relative", width: "100%" }, children: [
1935
+ /* @__PURE__ */ jsx(
1936
+ "select",
1937
+ {
1938
+ id: `field-${name3}`,
1939
+ value: value || "",
1940
+ disabled: readOnly,
1941
+ onChange: (e3) => onChange(e3.target.value),
1942
+ style: {
1943
+ width: "100%",
1944
+ padding: "10px 32px 10px 12px",
1945
+ borderRadius: "8px",
1946
+ border: "1px solid #e4e4e7",
1947
+ fontSize: "13px",
1948
+ color: "#18181b",
1949
+ backgroundColor: readOnly ? "#f4f4f5" : "#ffffff",
1950
+ outline: "none",
1951
+ appearance: "none",
1952
+ boxSizing: "border-box",
1953
+ cursor: readOnly ? "not-allowed" : "pointer"
1954
+ },
1955
+ className: "tecof-input-select",
1956
+ children: (definition.options || []).map((opt) => /* @__PURE__ */ jsx("option", { value: opt.value, children: opt.label || opt.value }, opt.value))
1957
+ }
1958
+ ),
1959
+ /* @__PURE__ */ jsx(
1960
+ "div",
1961
+ {
1962
+ style: {
1963
+ position: "absolute",
1964
+ top: "50%",
1965
+ right: "12px",
1966
+ transform: "translateY(-50%)",
1967
+ pointerEvents: "none",
1968
+ display: "flex",
1969
+ alignItems: "center",
1970
+ color: "#71717a"
1971
+ },
1972
+ children: /* @__PURE__ */ jsx("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx("path", { d: "M2.5 4.5L6 8L9.5 4.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })
1973
+ }
1974
+ )
1975
+ ] }) });
1976
+ case "number":
1977
+ return /* @__PURE__ */ jsx(FieldLabel, { label, readOnly, children: /* @__PURE__ */ jsx(
1978
+ "input",
1979
+ {
1980
+ id: `field-${name3}`,
1981
+ type: "number",
1982
+ value: value !== void 0 ? value : "",
1983
+ disabled: readOnly,
1984
+ onChange: (e3) => {
1985
+ const val = e3.target.value;
1986
+ onChange(val === "" ? void 0 : Number(val));
1987
+ },
1988
+ style: {
1989
+ width: "100%",
1990
+ padding: "10px 12px",
1991
+ borderRadius: "8px",
1992
+ border: "1px solid #e4e4e7",
1993
+ fontSize: "13px",
1994
+ color: "#18181b",
1995
+ backgroundColor: readOnly ? "#f4f4f5" : "#ffffff",
1996
+ outline: "none",
1997
+ boxSizing: "border-box"
1998
+ },
1999
+ className: "tecof-input-number"
2000
+ }
2001
+ ) });
2002
+ case "radio":
2003
+ return /* @__PURE__ */ jsx(FieldLabel, { label, readOnly, children: /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: (definition.options || []).map((opt) => /* @__PURE__ */ jsxs(
2004
+ "label",
2005
+ {
2006
+ style: {
2007
+ display: "flex",
2008
+ alignItems: "center",
2009
+ gap: "8px",
2010
+ fontSize: "13px",
2011
+ color: "#27272a",
2012
+ cursor: readOnly ? "not-allowed" : "pointer"
2013
+ },
2014
+ children: [
2015
+ /* @__PURE__ */ jsx(
2016
+ "input",
2017
+ {
2018
+ type: "radio",
2019
+ name: name3,
2020
+ value: opt.value,
2021
+ checked: value === opt.value,
2022
+ disabled: readOnly,
2023
+ onChange: () => onChange(opt.value),
2024
+ style: {
2025
+ cursor: readOnly ? "not-allowed" : "pointer"
2026
+ }
2027
+ }
2028
+ ),
2029
+ /* @__PURE__ */ jsx("span", { children: opt.label || opt.value })
2030
+ ]
2031
+ },
2032
+ opt.value
2033
+ )) }) });
2034
+ default:
2035
+ return /* @__PURE__ */ jsxs("div", { style: { padding: "8px", fontSize: "11px", color: "#71717a", background: "#fafafa", borderRadius: "4px" }, children: [
2036
+ 'Desteklenmeyen alan t\xFCr\xFC: "',
2037
+ type,
2038
+ '" (',
2039
+ name3,
2040
+ ")"
2041
+ ] });
2042
+ }
2043
+ };
2044
+ var Inspector = () => {
2045
+ const documentState = useEditorStore((state3) => state3.document);
2046
+ const selectedId = useEditorStore((state3) => state3.selection.selectedId);
2047
+ const updateProps2 = useEditorStore((state3) => state3.updateProps);
2048
+ const setRootProps2 = useEditorStore((state3) => state3.setRootProps);
2049
+ const selectNode = useEditorStore((state3) => state3.selectNode);
2050
+ const { config: config3, readOnly } = useStudio();
2051
+ if (selectedId) {
2052
+ const nodeDetails = findNodeById(documentState, selectedId);
2053
+ if (!nodeDetails) {
2054
+ return /* @__PURE__ */ jsx("div", { style: { padding: "24px", color: "#71717a", fontSize: "13px", textAlign: "center" }, children: "Bile\u015Fen y\xFCkleniyor veya bulunamad\u0131." });
2055
+ }
2056
+ const { node } = nodeDetails;
2057
+ const componentConfig = config3.components[node.type];
2058
+ const fields = componentConfig?.fields || {};
2059
+ const label = componentConfig?.label || node.type;
2060
+ return /* @__PURE__ */ jsxs(
2061
+ "div",
2062
+ {
2063
+ className: "tecof-inspector",
2064
+ style: {
2065
+ width: "320px",
2066
+ height: "100%",
2067
+ borderLeft: "1px solid #e4e4e7",
2068
+ background: "#ffffff",
2069
+ display: "flex",
2070
+ flexDirection: "column",
2071
+ boxSizing: "border-box"
2072
+ },
2073
+ children: [
2074
+ /* @__PURE__ */ jsxs(
2075
+ "div",
2076
+ {
2077
+ style: {
2078
+ padding: "16px 20px",
2079
+ borderBottom: "1px solid #f4f4f5",
2080
+ display: "flex",
2081
+ alignItems: "center",
2082
+ justifyContent: "space-between"
2083
+ },
2084
+ children: [
2085
+ /* @__PURE__ */ jsxs("div", { children: [
2086
+ /* @__PURE__ */ jsx("h3", { style: { margin: 0, fontSize: "14px", fontWeight: 700, color: "#18181b" }, children: label }),
2087
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "11px", color: "#a1a1aa", fontFamily: "monospace" }, children: selectedId })
2088
+ ] }),
2089
+ /* @__PURE__ */ jsx(
2090
+ "button",
2091
+ {
2092
+ onClick: () => selectNode(null),
2093
+ style: {
2094
+ background: "transparent",
2095
+ border: "none",
2096
+ color: "#71717a",
2097
+ cursor: "pointer",
2098
+ fontSize: "11px",
2099
+ fontWeight: 500,
2100
+ padding: "4px 8px",
2101
+ borderRadius: "4px",
2102
+ hover: { background: "#f4f4f5" }
2103
+ },
2104
+ children: "Se\xE7imi Kald\u0131r"
2105
+ }
2106
+ )
2107
+ ]
2108
+ }
2109
+ ),
2110
+ /* @__PURE__ */ jsx(
2111
+ "div",
2112
+ {
2113
+ className: "tecof-inspector-fields",
2114
+ style: {
2115
+ flex: 1,
2116
+ overflowY: "auto",
2117
+ padding: "20px",
2118
+ display: "flex",
2119
+ flexDirection: "column",
2120
+ gap: "4px"
2121
+ },
2122
+ children: Object.keys(fields).length === 0 ? /* @__PURE__ */ jsx("div", { style: { color: "#a1a1aa", fontSize: "12px", textAlign: "center", marginTop: "16px" }, children: "Bu bile\u015Fenin d\xFCzenlenebilir alan\u0131 bulunmuyor." }) : Object.entries(fields).map(([fieldName, fieldDef]) => /* @__PURE__ */ jsx(
2123
+ FieldRenderer,
2124
+ {
2125
+ name: fieldName,
2126
+ definition: fieldDef,
2127
+ value: node.props[fieldName],
2128
+ onChange: (newVal) => updateProps2(selectedId, { [fieldName]: newVal }),
2129
+ readOnly
2130
+ },
2131
+ fieldName
2132
+ ))
2133
+ }
2134
+ )
2135
+ ]
2136
+ }
2137
+ );
2138
+ }
2139
+ const rootFields = config3.root?.fields || {};
2140
+ const hasRootFields = Object.keys(rootFields).length > 0;
2141
+ return /* @__PURE__ */ jsxs(
2142
+ "div",
2143
+ {
2144
+ className: "tecof-inspector",
2145
+ style: {
2146
+ width: "320px",
2147
+ height: "100%",
2148
+ borderLeft: "1px solid #e4e4e7",
2149
+ background: "#ffffff",
2150
+ display: "flex",
2151
+ flexDirection: "column",
2152
+ boxSizing: "border-box"
2153
+ },
2154
+ children: [
2155
+ /* @__PURE__ */ jsxs(
2156
+ "div",
2157
+ {
2158
+ style: {
2159
+ padding: "16px 20px",
2160
+ borderBottom: "1px solid #f4f4f5"
2161
+ },
2162
+ children: [
2163
+ /* @__PURE__ */ jsx("h3", { style: { margin: 0, fontSize: "14px", fontWeight: 700, color: "#18181b" }, children: "Sayfa Ayarlar\u0131" }),
2164
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "11px", color: "#a1a1aa" }, children: "Genel sayfa konfig\xFCrasyonu" })
2165
+ ]
2166
+ }
2167
+ ),
2168
+ /* @__PURE__ */ jsx(
2169
+ "div",
2170
+ {
2171
+ className: "tecof-inspector-fields",
2172
+ style: {
2173
+ flex: 1,
2174
+ overflowY: "auto",
2175
+ padding: "20px",
2176
+ display: "flex",
2177
+ flexDirection: "column",
2178
+ gap: "4px"
2179
+ },
2180
+ children: hasRootFields ? Object.entries(rootFields).map(([fieldName, fieldDef]) => /* @__PURE__ */ jsx(
2181
+ FieldRenderer,
2182
+ {
2183
+ name: fieldName,
2184
+ definition: fieldDef,
2185
+ value: documentState.root.props[fieldName],
2186
+ onChange: (newVal) => setRootProps2({ [fieldName]: newVal }),
2187
+ readOnly
2188
+ },
2189
+ fieldName
2190
+ )) : /* @__PURE__ */ jsxs(
2191
+ "div",
2192
+ {
2193
+ style: {
2194
+ display: "flex",
2195
+ flexDirection: "column",
2196
+ alignItems: "center",
2197
+ justifyContent: "center",
2198
+ height: "100%",
2199
+ color: "#a1a1aa",
2200
+ fontSize: "12px",
2201
+ textAlign: "center",
2202
+ padding: "20px"
2203
+ },
2204
+ children: [
2205
+ /* @__PURE__ */ jsxs(
2206
+ "svg",
2207
+ {
2208
+ width: "24",
2209
+ height: "24",
2210
+ viewBox: "0 0 24 24",
2211
+ fill: "none",
2212
+ stroke: "currentColor",
2213
+ strokeWidth: "2",
2214
+ strokeLinecap: "round",
2215
+ strokeLinejoin: "round",
2216
+ style: { marginBottom: "8px", opacity: 0.6 },
2217
+ children: [
2218
+ /* @__PURE__ */ jsx("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2" }),
2219
+ /* @__PURE__ */ jsx("path", { d: "M9 3v18" })
2220
+ ]
2221
+ }
2222
+ ),
2223
+ "Bile\u015Fen se\xE7ilmedi. D\xFCzenlemek istedi\u011Finiz bir bile\u015Fene t\u0131klay\u0131n."
2224
+ ]
2225
+ }
2226
+ )
2227
+ }
2228
+ )
2229
+ ]
2230
+ }
2231
+ );
2232
+ };
2233
+ var TecofStudio = ({
2234
+ pageId,
2235
+ config: config3,
2236
+ accessToken,
2237
+ onSave,
2238
+ onChange,
2239
+ className
2240
+ }) => {
2241
+ const { apiClient } = useTecof();
2242
+ const [loading, setLoading] = useState(true);
2243
+ const [saving, setSaving] = useState(false);
2244
+ const [saveStatus, setSaveStatus] = useState("idle");
2245
+ const setDocument = useEditorStore((state3) => state3.setDocument);
2246
+ const documentState = useEditorStore((state3) => state3.document);
2247
+ const undo = useEditorStore((state3) => state3.undo);
2248
+ const redo = useEditorStore((state3) => state3.redo);
2249
+ const setViewport = useEditorStore((state3) => state3.setViewport);
2250
+ const documentStateRef = useRef(documentState);
2251
+ documentStateRef.current = documentState;
2252
+ const isEmbedded = typeof window !== "undefined" && window.parent !== window;
2253
+ useEffect(() => {
2254
+ let cancelled = false;
2255
+ const load = async () => {
2256
+ setLoading(true);
2257
+ try {
2258
+ const res2 = await apiClient.getPage(pageId);
2259
+ if (cancelled) return;
2260
+ const rawData = res2.success && res2.data?.draftData ? res2.data.draftData : null;
2261
+ const parsedDoc = parseDocument(rawData);
2262
+ setDocument(parsedDoc);
2263
+ } catch (err) {
2264
+ console.error("Failed to load page:", err);
2265
+ } finally {
2266
+ setLoading(false);
2267
+ }
2268
+ };
2269
+ load();
2270
+ return () => {
2271
+ cancelled = true;
2272
+ };
2273
+ }, [pageId, apiClient, setDocument]);
2274
+ const isFirstRender = useRef(true);
2275
+ useEffect(() => {
2276
+ if (loading) return;
2277
+ if (isFirstRender.current) {
2278
+ isFirstRender.current = false;
2279
+ return;
2280
+ }
2281
+ const serialized = serializeDocument(documentState);
2282
+ onChange?.(serialized);
2283
+ if (isEmbedded) {
2284
+ window.parent.postMessage({ type: "puck:changed" }, "*");
2285
+ }
2286
+ }, [documentState, loading, onChange, isEmbedded]);
2287
+ const handleSaveDraft = useCallback(async () => {
2288
+ const currentDoc = documentStateRef.current;
2289
+ const serialized = serializeDocument(currentDoc);
2290
+ setSaving(true);
2291
+ setSaveStatus("idle");
2292
+ try {
2293
+ const res2 = await apiClient.savePage(pageId, serialized, void 0, accessToken);
2294
+ if (res2.success) {
2295
+ setSaveStatus("success");
2296
+ setTimeout(() => setSaveStatus("idle"), 3e3);
2297
+ onSave?.(serialized);
2298
+ if (isEmbedded) {
2299
+ window.parent.postMessage({ type: "puck:saved" }, "*");
2300
+ }
2301
+ } else {
2302
+ setSaveStatus("error");
2303
+ if (isEmbedded) {
2304
+ window.parent.postMessage({ type: "puck:saveError", message: res2.message }, "*");
2305
+ }
2306
+ }
2307
+ } catch (err) {
2308
+ setSaveStatus("error");
2309
+ if (isEmbedded) {
2310
+ window.parent.postMessage({ type: "puck:saveError", message: err.message }, "*");
2311
+ }
2312
+ } finally {
2313
+ setSaving(false);
2314
+ }
2315
+ }, [pageId, apiClient, accessToken, onSave, isEmbedded]);
2316
+ useEffect(() => {
2317
+ if (!isEmbedded) return;
2318
+ const onMessage = (e3) => {
2319
+ switch (e3.data?.type) {
2320
+ case "puck:save":
2321
+ handleSaveDraft();
2322
+ break;
2323
+ case "puck:undo":
2324
+ undo();
2325
+ break;
2326
+ case "puck:redo":
2327
+ redo();
2328
+ break;
2329
+ case "puck:viewport":
2330
+ if (e3.data.width) {
2331
+ const width = e3.data.width;
2332
+ if (width === "375px" || width === 375) {
2333
+ setViewport("mobile");
2334
+ } else if (width === "768px" || width === 768) {
2335
+ setViewport("tablet");
2336
+ } else {
2337
+ setViewport("desktop");
2338
+ }
2339
+ }
2340
+ break;
2341
+ }
2342
+ };
2343
+ window.addEventListener("message", onMessage);
2344
+ return () => window.removeEventListener("message", onMessage);
2345
+ }, [isEmbedded, handleSaveDraft, undo, redo, setViewport]);
2346
+ const studioContextValue = useMemo(() => ({
2347
+ config: config3,
2348
+ readOnly: false,
2349
+ apiClient
2350
+ }), [config3, apiClient]);
2351
+ if (loading) {
2352
+ return /* @__PURE__ */ jsx("div", { className: `tecof-editor-loading ${className || ""}`.trim(), style: {
2353
+ display: "flex",
2354
+ alignItems: "center",
2355
+ justifyContent: "center",
2356
+ height: "100vh",
2357
+ background: "#f4f4f5"
2358
+ }, children: /* @__PURE__ */ jsxs("div", { style: { textAlign: "center" }, children: [
2359
+ /* @__PURE__ */ jsx("div", { className: "tecof-editor-spinner", style: {
2360
+ width: "40px",
2361
+ height: "40px",
2362
+ border: "3px solid #e4e4e7",
2363
+ borderTopColor: "#3b82f6",
2364
+ borderRadius: "50%",
2365
+ animation: "spin 1s linear infinite",
2366
+ margin: "0 auto 16px"
2367
+ } }),
2368
+ /* @__PURE__ */ jsx("p", { style: { color: "#71717a", fontSize: "14px", margin: 0 }, children: "St\xFCdyo y\xFCkleniyor..." })
2369
+ ] }) });
2370
+ }
2371
+ return /* @__PURE__ */ jsx(StudioContext.Provider, { value: studioContextValue, children: /* @__PURE__ */ jsxs("div", { className: `tecof-studio-root ${className || ""}`.trim(), style: {
2372
+ display: "flex",
2373
+ flexDirection: "column",
2374
+ height: "100vh",
2375
+ width: "100vw",
2376
+ overflow: "hidden",
2377
+ position: "relative",
2378
+ background: "#f4f4f5"
2379
+ }, children: [
2380
+ /* @__PURE__ */ jsxs("div", { className: "tecof-studio-workspace-container", style: {
2381
+ display: "flex",
2382
+ flex: 1,
2383
+ height: "100%",
2384
+ width: "100%",
2385
+ overflow: "hidden"
2386
+ }, children: [
2387
+ /* @__PURE__ */ jsxs("div", { className: "tecof-studio-workspace", style: {
2388
+ display: "flex",
2389
+ flex: 1,
2390
+ height: "100%",
2391
+ position: "relative",
2392
+ overflow: "hidden"
2393
+ }, children: [
2394
+ /* @__PURE__ */ jsx(Canvas, {}),
2395
+ /* @__PURE__ */ jsx(SelectionOverlay, {})
2396
+ ] }),
2397
+ /* @__PURE__ */ jsx(Inspector, {})
2398
+ ] }),
2399
+ saving && /* @__PURE__ */ jsx("div", { className: "tecof-editor-save-indicator", style: {
2400
+ position: "absolute",
2401
+ bottom: "24px",
2402
+ right: "24px",
2403
+ background: saveStatus === "error" ? "#ef4444" : "#18181b",
2404
+ color: "#ffffff",
2405
+ padding: "8px 16px",
2406
+ borderRadius: "24px",
2407
+ fontSize: "12px",
2408
+ fontWeight: 500,
2409
+ boxShadow: "0 4px 6px -1px rgba(0, 0, 0, 0.1)",
2410
+ zIndex: 9999
2411
+ }, children: saveStatus === "error" ? "Kaydedilemedi" : "Kaydediliyor..." })
2412
+ ] }) });
980
2413
  };
981
2414
  var TecofRender = ({ data: data3, config: config3, className, cmsData }) => {
982
2415
  if (!data3) return null;
@@ -6209,7 +7642,7 @@ var createView = (
6209
7642
  },
6210
7643
  write: write2 = () => {
6211
7644
  },
6212
- create: create4 = () => {
7645
+ create: create5 = () => {
6213
7646
  },
6214
7647
  destroy: destroy3 = () => {
6215
7648
  },
@@ -6413,7 +7846,7 @@ var createView = (
6413
7846
  }
6414
7847
  });
6415
7848
  const internalAPI = createObject(internalAPIDefinition);
6416
- create4({
7849
+ create5({
6417
7850
  root: internalAPI,
6418
7851
  props
6419
7852
  });
@@ -9143,7 +10576,7 @@ var percentageArc = (x, y, radius, from, to) => {
9143
10576
  arcSweep
9144
10577
  );
9145
10578
  };
9146
- var create = ({ root: root3, props }) => {
10579
+ var create2 = ({ root: root3, props }) => {
9147
10580
  props.spin = false;
9148
10581
  props.progress = 0;
9149
10582
  props.opacity = 0;
@@ -9183,7 +10616,7 @@ var progressIndicator = createView({
9183
10616
  name: "progress-indicator",
9184
10617
  ignoreRectUpdate: true,
9185
10618
  ignoreRect: true,
9186
- create,
10619
+ create: create2,
9187
10620
  write,
9188
10621
  mixins: {
9189
10622
  apis: ["progress", "spin", "align"],
@@ -14023,7 +15456,7 @@ var createImageWrapperView = (_2) => {
14023
15456
  root3.ref.overlayShadow.opacity = 0.25;
14024
15457
  root3.ref.overlaySuccess.opacity = 1;
14025
15458
  };
14026
- const create4 = ({ root: root3 }) => {
15459
+ const create5 = ({ root: root3 }) => {
14027
15460
  root3.ref.images = [];
14028
15461
  root3.ref.imageData = null;
14029
15462
  root3.ref.imageViewBin = [];
@@ -14048,7 +15481,7 @@ var createImageWrapperView = (_2) => {
14048
15481
  };
14049
15482
  return _2.utils.createView({
14050
15483
  name: "image-preview-wrapper",
14051
- create: create4,
15484
+ create: create5,
14052
15485
  styles: ["height"],
14053
15486
  apis: ["height"],
14054
15487
  destroy: ({ root: root3 }) => {
@@ -15858,7 +17291,7 @@ var plugin7 = ({ addFilter: addFilter2, utils }) => {
15858
17291
  }).catch(reject);
15859
17292
  });
15860
17293
  const variantPromises = variants.map(
15861
- (create4) => create4(transform, file2, item2.getMetadata())
17294
+ (create5) => create5(transform, file2, item2.getMetadata())
15862
17295
  );
15863
17296
  Promise.all(variantPromises).then((files) => {
15864
17297
  resolve(
@@ -19198,7 +20631,7 @@ var createTexture = function(e3, t2, r2, n, i2) {
19198
20631
  }
19199
20632
  return o2;
19200
20633
  };
19201
- var create2 = function() {
20634
+ var create3 = function() {
19202
20635
  var e3 = new Float32Array(16);
19203
20636
  return e3[0] = 1, e3[5] = 1, e3[10] = 1, e3[15] = 1, e3;
19204
20637
  };
@@ -19226,7 +20659,7 @@ var rotateZ = function(e3, t2) {
19226
20659
  var r2 = Math.sin(t2), n = Math.cos(t2), i2 = e3[0], o2 = e3[1], a2 = e3[2], c2 = e3[3], l3 = e3[4], u = e3[5], s2 = e3[6], d = e3[7];
19227
20660
  e3[0] = i2 * n + l3 * r2, e3[1] = o2 * n + u * r2, e3[2] = a2 * n + s2 * r2, e3[3] = c2 * n + d * r2, e3[4] = l3 * n - i2 * r2, e3[5] = u * n - o2 * r2, e3[6] = s2 * n - a2 * r2, e3[7] = d * n - c2 * r2;
19228
20661
  };
19229
- var mat4 = { create: create2, perspective, translate, scale, rotateX, rotateY, rotateZ };
20662
+ var mat4 = { create: create3, perspective, translate, scale, rotateX, rotateY, rotateZ };
19230
20663
  var degToRad = function(e3) {
19231
20664
  return e3 * Math.PI / 180;
19232
20665
  };
@@ -23821,7 +25254,7 @@ var validators = {
23821
25254
  handler: validateHandler,
23822
25255
  initial: validateInitial
23823
25256
  };
23824
- function create3(initial) {
25257
+ function create4(initial) {
23825
25258
  var handler = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
23826
25259
  validators.initial(initial);
23827
25260
  validators.handler(handler);
@@ -23859,7 +25292,7 @@ function didStateUpdate(state3, handler, changes) {
23859
25292
  return changes;
23860
25293
  }
23861
25294
  var index = {
23862
- create: create3
25295
+ create: create4
23863
25296
  };
23864
25297
  var state_local_default = index;
23865
25298
 
@@ -25506,6 +26939,7 @@ lucide-react/dist/esm/icons/arrow-up.js:
25506
26939
  lucide-react/dist/esm/icons/check.js:
25507
26940
  lucide-react/dist/esm/icons/chevron-down.js:
25508
26941
  lucide-react/dist/esm/icons/chevron-right.js:
26942
+ lucide-react/dist/esm/icons/chevron-up.js:
25509
26943
  lucide-react/dist/esm/icons/code.js:
25510
26944
  lucide-react/dist/esm/icons/copy.js:
25511
26945
  lucide-react/dist/esm/icons/database.js:
@@ -25613,6 +27047,6 @@ filepond-plugin-image-edit/dist/filepond-plugin-image-edit.esm.js:
25613
27047
  *)
25614
27048
  */
25615
27049
 
25616
- export { CmsCollectionField, CodeEditorField, ColorField, EditorField, FieldErrorBoundary, LanguageField, LinkField, RepeaterField, TecofApiClient, TecofEditor, TecofPicture, TecofProvider, TecofRender, UnderConstruction, UploadField, createCmsCollectionField, createCodeEditorField, createColorField, createEditorField, createLanguageField, createLinkField, createRepeaterField, createUploadField, darken, generateCSSVariables, getDefaultTheme, hexToHsl, hslToHex, lighten, mergeTheme, useTecof };
27050
+ export { CmsCollectionField, CodeEditorField, ColorField, EditorField, FieldErrorBoundary, LanguageField, LinkField, RepeaterField, TecofApiClient, TecofEditor, TecofPicture, TecofProvider, TecofRender, TecofStudio, UnderConstruction, UploadField, createCmsCollectionField, createCodeEditorField, createColorField, createEditorField, createLanguageField, createLinkField, createRepeaterField, createUploadField, darken, generateCSSVariables, getDefaultTheme, hexToHsl, hslToHex, lighten, mergeTheme, useTecof };
25617
27051
  //# sourceMappingURL=index.mjs.map
25618
27052
  //# sourceMappingURL=index.mjs.map