@tecof/theme-editor 0.0.37 → 0.0.40

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
@@ -337,17 +337,48 @@ function useTecof() {
337
337
  }
338
338
 
339
339
  // src/engine/document.ts
340
- var EMPTY_DOCUMENT = {
340
+ var createEmptyDocument = () => ({
341
341
  root: { props: {} },
342
342
  content: [],
343
343
  zones: {}
344
+ });
345
+ var cloneValue = (value) => {
346
+ if (Array.isArray(value)) {
347
+ return value.map((item2) => cloneValue(item2));
348
+ }
349
+ if (value && typeof value === "object") {
350
+ return Object.fromEntries(
351
+ Object.entries(value).map(([key, child]) => [key, cloneValue(child)])
352
+ );
353
+ }
354
+ return value;
344
355
  };
356
+ var cloneDocument = (doc) => ({
357
+ root: {
358
+ props: cloneValue(doc.root?.props || {})
359
+ },
360
+ content: (doc.content || []).map((node) => ({
361
+ type: node.type,
362
+ props: cloneValue(node.props || {})
363
+ })),
364
+ zones: Object.fromEntries(
365
+ Object.entries(doc.zones || {}).map(([zoneKey, nodes]) => [
366
+ zoneKey,
367
+ nodes.map((node) => ({
368
+ type: node.type,
369
+ props: cloneValue(node.props || {})
370
+ }))
371
+ ])
372
+ )
373
+ });
345
374
  var parseDocument = (rawData) => {
346
- if (!rawData) return { ...EMPTY_DOCUMENT };
375
+ if (!rawData) return createEmptyDocument();
347
376
  return {
348
377
  root: rawData.root || { props: {} },
349
- content: rawData.content || [],
350
- zones: rawData.zones || {}
378
+ content: [...rawData.content || []],
379
+ zones: Object.fromEntries(
380
+ Object.entries(rawData.zones || {}).map(([zoneKey, nodes]) => [zoneKey, [...nodes]])
381
+ )
351
382
  };
352
383
  };
353
384
  var serializeDocument = (doc) => {
@@ -473,6 +504,13 @@ var moveNode = (draft, id, targetZoneKey, targetIndex) => {
473
504
  const { node, path: sourcePath } = result;
474
505
  const sourceList = sourcePath.zoneKey ? draft.zones[sourcePath.zoneKey] : draft.content;
475
506
  let targetList = targetZoneKey ? draft.zones[targetZoneKey] : draft.content;
507
+ if (targetZoneKey) {
508
+ const targetParentId = parseZoneKey(targetZoneKey).parentId;
509
+ const descendantZoneKeys = getDescendantZoneKeys(draft.zones, id);
510
+ if (targetParentId === id || descendantZoneKeys.includes(targetZoneKey)) {
511
+ return;
512
+ }
513
+ }
476
514
  if (!targetList && targetZoneKey) {
477
515
  targetList = [];
478
516
  draft.zones[targetZoneKey] = targetList;
@@ -506,14 +544,27 @@ var setRootProps = (draft, patch) => {
506
544
  };
507
545
 
508
546
  // src/engine/store.ts
547
+ var HISTORY_LIMIT = 50;
548
+ var COALESCE_MS = 500;
509
549
  var pushToHistory = (state3) => {
510
- state3.history.past.push(JSON.parse(JSON.stringify(state3.document)));
550
+ state3.history.past.push(cloneDocument(state3.document));
551
+ if (state3.history.past.length > HISTORY_LIMIT) {
552
+ state3.history.past.shift();
553
+ }
511
554
  state3.history.future = [];
555
+ state3._lastCommit = null;
556
+ };
557
+ var validateSelection = (state3) => {
558
+ const id = state3.selection.selectedId;
559
+ if (id && !findNodeById(state3.document, id)) {
560
+ state3.selection.selectedId = null;
561
+ }
562
+ state3.selection.hoveredId = null;
512
563
  };
513
564
  var useEditorStore = zustand.create()(
514
565
  immer.immer((set2) => ({
515
566
  // Initial State
516
- document: { ...EMPTY_DOCUMENT },
567
+ document: createEmptyDocument(),
517
568
  history: {
518
569
  past: [],
519
570
  future: []
@@ -523,11 +574,14 @@ var useEditorStore = zustand.create()(
523
574
  hoveredId: null
524
575
  },
525
576
  viewport: "desktop",
577
+ drag: null,
578
+ _lastCommit: null,
526
579
  // Actions
527
580
  setDocument: (doc) => set2((state3) => {
528
- state3.document = doc;
581
+ state3.document = cloneDocument(parseDocument(doc));
529
582
  state3.history = { past: [], future: [] };
530
583
  state3.selection = { selectedId: null, hoveredId: null };
584
+ state3._lastCommit = null;
531
585
  }),
532
586
  selectNode: (id) => set2((state3) => {
533
587
  state3.selection.selectedId = id;
@@ -538,6 +592,12 @@ var useEditorStore = zustand.create()(
538
592
  setViewport: (viewport) => set2((state3) => {
539
593
  state3.viewport = viewport;
540
594
  }),
595
+ beginDrag: (payload) => set2((state3) => {
596
+ state3.drag = payload;
597
+ }),
598
+ endDrag: () => set2((state3) => {
599
+ state3.drag = null;
600
+ }),
541
601
  insertNode: (node, targetZoneKey, index2) => set2((state3) => {
542
602
  pushToHistory(state3);
543
603
  insertNode(state3.document, node, targetZoneKey, index2);
@@ -558,24 +618,48 @@ var useEditorStore = zustand.create()(
558
618
  duplicateNode(state3.document, id);
559
619
  }),
560
620
  updateProps: (id, patch) => set2((state3) => {
561
- pushToHistory(state3);
621
+ const now2 = Date.now();
622
+ const last = state3._lastCommit;
623
+ const isContinuation = last && last.id === id && now2 - last.time < COALESCE_MS;
624
+ if (!isContinuation) {
625
+ state3.history.past.push(cloneDocument(state3.document));
626
+ if (state3.history.past.length > HISTORY_LIMIT) {
627
+ state3.history.past.shift();
628
+ }
629
+ state3.history.future = [];
630
+ }
562
631
  updateProps(state3.document, id, patch);
632
+ state3._lastCommit = { id, time: now2 };
563
633
  }),
564
634
  setRootProps: (patch) => set2((state3) => {
565
- pushToHistory(state3);
635
+ const now2 = Date.now();
636
+ const last = state3._lastCommit;
637
+ const isContinuation = last && last.id === "__root__" && now2 - last.time < COALESCE_MS;
638
+ if (!isContinuation) {
639
+ state3.history.past.push(cloneDocument(state3.document));
640
+ if (state3.history.past.length > HISTORY_LIMIT) {
641
+ state3.history.past.shift();
642
+ }
643
+ state3.history.future = [];
644
+ }
566
645
  setRootProps(state3.document, patch);
646
+ state3._lastCommit = { id: "__root__", time: now2 };
567
647
  }),
568
648
  undo: () => set2((state3) => {
569
649
  if (state3.history.past.length === 0) return;
570
650
  const previous = state3.history.past.pop();
571
- state3.history.future.push(JSON.parse(JSON.stringify(state3.document)));
651
+ state3.history.future.push(cloneDocument(state3.document));
572
652
  state3.document = previous;
653
+ state3._lastCommit = null;
654
+ validateSelection(state3);
573
655
  }),
574
656
  redo: () => set2((state3) => {
575
657
  if (state3.history.future.length === 0) return;
576
658
  const next = state3.history.future.pop();
577
- state3.history.past.push(JSON.parse(JSON.stringify(state3.document)));
659
+ state3.history.past.push(cloneDocument(state3.document));
578
660
  state3.document = next;
661
+ state3._lastCommit = null;
662
+ validateSelection(state3);
579
663
  })
580
664
  }))
581
665
  );
@@ -587,106 +671,13 @@ var useStudio = () => {
587
671
  }
588
672
  return ctx;
589
673
  };
590
- var ParentNodeContext = React__default.createContext(null);
591
- var DropZone = ({ zone, className, style }) => {
592
- const parentId = React__default.useContext(ParentNodeContext);
593
- const zoneKey = parentId ? `${parentId}:${zone}` : zone;
594
- const items = useEditorStore((state3) => state3.document.zones[zoneKey] || []);
595
- return /* @__PURE__ */ jsxRuntime.jsx(
596
- "div",
597
- {
598
- className: `tecof-dropzone ${className || ""}`,
599
- style: { minHeight: items.length === 0 ? "40px" : void 0, ...style },
600
- "data-tecof-zone": zoneKey,
601
- children: items.map((item2, index2) => /* @__PURE__ */ jsxRuntime.jsx(NodeRenderer, { node: item2, index: index2, zoneKey }, item2.props.id))
602
- }
603
- );
604
- };
605
- var renderDropZone = ({ zone, className, style }) => {
606
- return /* @__PURE__ */ jsxRuntime.jsx(DropZone, { zone, className, style });
607
- };
608
- var NodeRenderer = ({ node, index: index2, zoneKey }) => {
609
- const { config: config3, metadata, readOnly } = useStudio();
610
- const componentConfig = config3.components[node.type];
611
- const selectNode = useEditorStore((state3) => state3.selectNode);
612
- const hoverNode = useEditorStore((state3) => state3.hoverNode);
613
- const hoveredId = useEditorStore((state3) => state3.selection.hoveredId);
614
- const handleMouseEnter = React__default.useCallback(
615
- (e3) => {
616
- if (readOnly) return;
617
- e3.stopPropagation();
618
- hoverNode(node.props.id);
619
- },
620
- [hoverNode, node.props.id, readOnly]
621
- );
622
- const handleMouseLeave = React__default.useCallback(
623
- (e3) => {
624
- if (readOnly) return;
625
- e3.stopPropagation();
626
- if (hoveredId === node.props.id) {
627
- hoverNode(null);
628
- }
629
- },
630
- [hoverNode, node.props.id, hoveredId, readOnly]
631
- );
632
- const handleClick = React__default.useCallback(
633
- (e3) => {
634
- if (readOnly) return;
635
- e3.stopPropagation();
636
- selectNode(node.props.id);
637
- const isEmbedded = typeof window !== "undefined" && window.parent !== window;
638
- if (isEmbedded) {
639
- window.parent.postMessage(
640
- {
641
- type: "puck:itemSelected",
642
- item: {
643
- type: node.type,
644
- id: node.props.id
645
- }
646
- },
647
- "*"
648
- );
649
- }
650
- },
651
- [selectNode, node.props.id, node.type, readOnly]
652
- );
653
- if (!componentConfig) {
654
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "12px", background: "#fee2e2", color: "#991b1b", fontSize: "12px", borderRadius: "4px" }, children: [
655
- "Bile\u015Fen bulunamad\u0131: ",
656
- node.type
657
- ] });
658
- }
659
- const componentProps = {
660
- ...node.props,
661
- puck: {
662
- renderDropZone,
663
- isEditing: !readOnly,
664
- metadata: {
665
- ...metadata || {},
666
- ...componentConfig.metadata || {}
667
- }
668
- },
669
- editMode: !readOnly
670
- };
671
- return /* @__PURE__ */ jsxRuntime.jsx(ParentNodeContext.Provider, { value: node.props.id, children: /* @__PURE__ */ jsxRuntime.jsx(
672
- "div",
673
- {
674
- className: "tecof-node-wrapper",
675
- "data-tecof-id": node.props.id,
676
- "data-tecof-type": node.type,
677
- "data-tecof-index": index2,
678
- "data-tecof-zone": zoneKey || "root",
679
- onMouseEnter: handleMouseEnter,
680
- onMouseLeave: handleMouseLeave,
681
- onClick: handleClick,
682
- style: {
683
- cursor: readOnly ? void 0 : "pointer"
684
- },
685
- children: componentConfig.render(componentProps)
686
- }
687
- ) });
688
- };
689
- var Frame = ({ children, title = "Canvas Frame", ...props }) => {
674
+ var Frame = ({
675
+ children,
676
+ title = "Canvas Frame",
677
+ className,
678
+ style: _style,
679
+ ...props
680
+ }) => {
690
681
  const [contentRef, setContentRef] = React__default.useState(null);
691
682
  const mountNode = contentRef?.contentWindow?.document?.body;
692
683
  React__default.useEffect(() => {
@@ -736,16 +727,20 @@ var Frame = ({ children, title = "Canvas Frame", ...props }) => {
736
727
  background: transparent;
737
728
  }
738
729
  ::-webkit-scrollbar-thumb {
739
- background: rgba(0, 0, 0, 0.15);
740
- border-radius: 4px;
730
+ background: var(--tecof-scrollbar-thumb);
731
+ border-radius: var(--tecof-radius-xs);
741
732
  }
742
733
  ::-webkit-scrollbar-thumb:hover {
743
- background: rgba(0, 0, 0, 0.25);
734
+ background: var(--tecof-scrollbar-thumb-hover);
744
735
  }
745
736
  `;
746
737
  doc.head.appendChild(style);
747
738
  };
748
739
  copyStyles();
740
+ const observer = new MutationObserver(() => {
741
+ copyStyles();
742
+ });
743
+ observer.observe(document.head, { childList: true, subtree: true });
749
744
  if (doc.body) {
750
745
  doc.body.className = "tecof-canvas-body";
751
746
  const handleBodyClick = (e3) => {
@@ -758,9 +753,24 @@ var Frame = ({ children, title = "Canvas Frame", ...props }) => {
758
753
  }
759
754
  }
760
755
  };
756
+ const handleIframeKeyDown = (e3) => {
757
+ const event = new KeyboardEvent("keydown", {
758
+ key: e3.key,
759
+ code: e3.code,
760
+ ctrlKey: e3.ctrlKey,
761
+ metaKey: e3.metaKey,
762
+ shiftKey: e3.shiftKey,
763
+ altKey: e3.altKey,
764
+ bubbles: true
765
+ });
766
+ window.dispatchEvent(event);
767
+ };
761
768
  doc.body.addEventListener("click", handleBodyClick);
769
+ doc.addEventListener("keydown", handleIframeKeyDown);
762
770
  return () => {
771
+ observer.disconnect();
763
772
  doc.body.removeEventListener("click", handleBodyClick);
773
+ doc.removeEventListener("keydown", handleIframeKeyDown);
764
774
  };
765
775
  }
766
776
  }, [contentRef]);
@@ -769,59 +779,496 @@ var Frame = ({ children, title = "Canvas Frame", ...props }) => {
769
779
  {
770
780
  title,
771
781
  ref: setContentRef,
772
- style: {
773
- width: "100%",
774
- height: "100%",
775
- border: "none",
776
- background: "#ffffff",
777
- ...props.style
778
- },
782
+ className: ["tecof-canvas-frame", className].filter(Boolean).join(" "),
779
783
  ...props,
780
784
  children: mountNode && ReactDOM.createPortal(children, mountNode)
781
785
  }
782
786
  );
783
787
  };
788
+
789
+ // src/studio/canvas/dndUtils.ts
790
+ var TECOF_NODE_ID = "application/tecof-node-id";
791
+ var TECOF_BLOCK_TYPE = "application/tecof-block-type";
792
+ function createNode(config3, type) {
793
+ const compConfig = config3?.components?.[type] || {};
794
+ const defaultProps = compConfig.defaultProps || {};
795
+ return {
796
+ type,
797
+ props: {
798
+ id: generateId(),
799
+ ...JSON.parse(JSON.stringify(defaultProps))
800
+ }
801
+ };
802
+ }
803
+ function readDragData(e3) {
804
+ return {
805
+ nodeId: e3.dataTransfer.getData(TECOF_NODE_ID),
806
+ type: e3.dataTransfer.getData(TECOF_BLOCK_TYPE)
807
+ };
808
+ }
809
+ function writeDragData(e3, payload) {
810
+ if (payload.nodeId) {
811
+ e3.dataTransfer.setData(TECOF_NODE_ID, payload.nodeId);
812
+ }
813
+ if (payload.type) {
814
+ e3.dataTransfer.setData(TECOF_BLOCK_TYPE, payload.type);
815
+ }
816
+ }
817
+ function getDragScrollContainer(e3) {
818
+ const ownerDoc = e3.currentTarget.ownerDocument;
819
+ return ownerDoc.scrollingElement || ownerDoc.documentElement || ownerDoc.body;
820
+ }
821
+ var EDGE = 64;
822
+ var MAX_SPEED = 18;
823
+ function createAutoScroller(getContainer) {
824
+ let raf = 0;
825
+ let velocity = 0;
826
+ const getEdgeBounds = (el) => {
827
+ const doc = el.ownerDocument;
828
+ const win = doc.defaultView;
829
+ const isDocumentScroller = el === doc.documentElement || el === doc.body || el === doc.scrollingElement;
830
+ if (isDocumentScroller && win) {
831
+ return { top: 0, bottom: win.innerHeight };
832
+ }
833
+ return el.getBoundingClientRect();
834
+ };
835
+ const loop = () => {
836
+ const el = getContainer();
837
+ if (el && velocity !== 0) {
838
+ el.scrollTop += velocity;
839
+ }
840
+ raf = requestAnimationFrame(loop);
841
+ };
842
+ const update = (clientY) => {
843
+ const el = getContainer();
844
+ if (!el) return;
845
+ const rect = getEdgeBounds(el);
846
+ if (clientY < rect.top + EDGE) {
847
+ const ratio = (rect.top + EDGE - clientY) / EDGE;
848
+ velocity = -Math.ceil(Math.min(1, ratio) * MAX_SPEED);
849
+ } else if (clientY > rect.bottom - EDGE) {
850
+ const ratio = (clientY - (rect.bottom - EDGE)) / EDGE;
851
+ velocity = Math.ceil(Math.min(1, ratio) * MAX_SPEED);
852
+ } else {
853
+ velocity = 0;
854
+ }
855
+ if (!raf) loop();
856
+ };
857
+ const stop = () => {
858
+ velocity = 0;
859
+ if (raf) {
860
+ cancelAnimationFrame(raf);
861
+ raf = 0;
862
+ }
863
+ };
864
+ return { update, stop };
865
+ }
866
+ function createEventAutoScroller() {
867
+ let container = null;
868
+ const scroller = createAutoScroller(() => container);
869
+ return {
870
+ update(e3) {
871
+ container = getDragScrollContainer(e3);
872
+ scroller.update(e3.clientY);
873
+ },
874
+ stop() {
875
+ scroller.stop();
876
+ container = null;
877
+ }
878
+ };
879
+ }
880
+ var ParentNodeContext = React__default.createContext(null);
881
+ var DropZone = ({ zone, className, style }) => {
882
+ const parentId = React__default.useContext(ParentNodeContext);
883
+ const zoneKey = parentId ? `${parentId}:${zone}` : zone;
884
+ const { config: config3 } = useStudio();
885
+ const insertNode2 = useEditorStore((state3) => state3.insertNode);
886
+ const endDrag = useEditorStore((state3) => state3.endDrag);
887
+ const drag = useEditorStore((state3) => state3.drag);
888
+ const autoScrollerRef = React__default.useRef(createEventAutoScroller());
889
+ const [isDragOver, setIsDragOver] = React__default.useState(false);
890
+ const items = useEditorStore((state3) => state3.document.zones[zoneKey] || []);
891
+ const handleDragOver = (e3) => {
892
+ e3.preventDefault();
893
+ e3.stopPropagation();
894
+ autoScrollerRef.current.update(e3);
895
+ setIsDragOver(true);
896
+ };
897
+ const handleDragLeave = (e3) => {
898
+ if (e3.currentTarget.contains(e3.relatedTarget)) return;
899
+ autoScrollerRef.current.stop();
900
+ setIsDragOver(false);
901
+ };
902
+ const handleDrop = (e3) => {
903
+ e3.preventDefault();
904
+ e3.stopPropagation();
905
+ autoScrollerRef.current.stop();
906
+ setIsDragOver(false);
907
+ const { nodeId, type } = readDragData(e3);
908
+ if (nodeId) {
909
+ useEditorStore.getState().moveNode(nodeId, zoneKey, items.length);
910
+ } else if (type) {
911
+ insertNode2(createNode(config3, type), zoneKey, items.length);
912
+ }
913
+ endDrag();
914
+ };
915
+ const dropzoneClassName = [
916
+ "tecof-dropzone",
917
+ items.length === 0 ? "is-empty" : "",
918
+ isDragOver ? "is-dragover" : "",
919
+ drag ? "is-drag-active" : "",
920
+ className
921
+ ].filter(Boolean).join(" ");
922
+ return /* @__PURE__ */ jsxRuntime.jsx(
923
+ "div",
924
+ {
925
+ className: dropzoneClassName,
926
+ onDragOver: handleDragOver,
927
+ onDragLeave: handleDragLeave,
928
+ onDrop: handleDrop,
929
+ style,
930
+ "data-tecof-zone": zoneKey,
931
+ children: items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-dropzone-hint", children: isDragOver ? "Buraya B\u0131rak\u0131n" : "Bile\u015Fen S\xFCr\xFCkleyin veya T\u0131klay\u0131n" }) : items.map((item2, index2) => /* @__PURE__ */ jsxRuntime.jsx(NodeRenderer, { node: item2, index: index2, zoneKey }, item2.props.id))
932
+ }
933
+ );
934
+ };
935
+ var renderDropZone = ({ zone, className, style }) => {
936
+ return /* @__PURE__ */ jsxRuntime.jsx(DropZone, { zone, className, style });
937
+ };
938
+
939
+ // src/studio/canvas/dragGhost.ts
940
+ function setDragGhost(e3, label) {
941
+ const ownerDoc = e3.currentTarget?.ownerDocument || (typeof document !== "undefined" ? document : null);
942
+ if (!ownerDoc) return;
943
+ const ghost = ownerDoc.createElement("div");
944
+ ghost.className = "tecof-drag-ghost";
945
+ ghost.textContent = label;
946
+ ownerDoc.body.appendChild(ghost);
947
+ try {
948
+ e3.dataTransfer.setDragImage(ghost, 14, 14);
949
+ } catch {
950
+ }
951
+ const win = ownerDoc.defaultView || window;
952
+ win.requestAnimationFrame(() => {
953
+ win.requestAnimationFrame(() => ghost.remove());
954
+ });
955
+ }
956
+ var NodeRenderer = ({ node, index: index2, zoneKey }) => {
957
+ const { config: config3, metadata, readOnly } = useStudio();
958
+ const componentConfig = config3.components[node.type];
959
+ const selectNode = useEditorStore((state3) => state3.selectNode);
960
+ const hoverNode = useEditorStore((state3) => state3.hoverNode);
961
+ const hoveredId = useEditorStore((state3) => state3.selection.hoveredId);
962
+ const beginDrag = useEditorStore((state3) => state3.beginDrag);
963
+ const endDrag = useEditorStore((state3) => state3.endDrag);
964
+ const drag = useEditorStore((state3) => state3.drag);
965
+ const autoScrollerRef = React__default.useRef(createEventAutoScroller());
966
+ const handleMouseEnter = React__default.useCallback(
967
+ (e3) => {
968
+ if (readOnly) return;
969
+ e3.stopPropagation();
970
+ hoverNode(node.props.id);
971
+ },
972
+ [hoverNode, node.props.id, readOnly]
973
+ );
974
+ const handleMouseLeave = React__default.useCallback(
975
+ (e3) => {
976
+ if (readOnly) return;
977
+ e3.stopPropagation();
978
+ if (hoveredId === node.props.id) {
979
+ hoverNode(null);
980
+ }
981
+ },
982
+ [hoverNode, node.props.id, hoveredId, readOnly]
983
+ );
984
+ const handleClick = React__default.useCallback(
985
+ (e3) => {
986
+ if (readOnly) return;
987
+ e3.stopPropagation();
988
+ selectNode(node.props.id);
989
+ const isEmbedded = typeof window !== "undefined" && window.parent !== window;
990
+ if (isEmbedded) {
991
+ window.parent.postMessage(
992
+ {
993
+ type: "puck:itemSelected",
994
+ item: {
995
+ type: node.type,
996
+ id: node.props.id
997
+ }
998
+ },
999
+ "*"
1000
+ );
1001
+ }
1002
+ },
1003
+ [selectNode, node.props.id, node.type, readOnly]
1004
+ );
1005
+ const handleDoubleClick = React__default.useCallback(
1006
+ (e3) => {
1007
+ if (readOnly) return;
1008
+ const target = e3.target;
1009
+ const validTags = ["h1", "h2", "h3", "h4", "h5", "h6", "p", "span", "a", "div"];
1010
+ const tag = target.tagName.toLowerCase();
1011
+ if (!validTags.includes(tag)) return;
1012
+ const text2 = target.textContent?.trim() || "";
1013
+ if (!text2) return;
1014
+ let matchingPropName = null;
1015
+ let isMultilingual = false;
1016
+ const ownerDoc = target.ownerDocument;
1017
+ const ownerWin = ownerDoc.defaultView;
1018
+ let matchedLangCode = ownerDoc.documentElement.lang || "tr";
1019
+ for (const [key, value] of Object.entries(node.props)) {
1020
+ if (typeof value === "string" && value.trim() === text2) {
1021
+ matchingPropName = key;
1022
+ break;
1023
+ }
1024
+ if (Array.isArray(value)) {
1025
+ const matchedItem = value.find(
1026
+ (item2) => item2 && typeof item2 === "object" && typeof item2.value === "string" && item2.value.trim() === text2
1027
+ );
1028
+ if (matchedItem) {
1029
+ matchingPropName = key;
1030
+ isMultilingual = true;
1031
+ matchedLangCode = matchedItem.code;
1032
+ break;
1033
+ }
1034
+ }
1035
+ }
1036
+ if (!matchingPropName) return;
1037
+ e3.stopPropagation();
1038
+ const originalText = target.textContent || "";
1039
+ target.contentEditable = "true";
1040
+ target.setAttribute("data-tecof-inline-editing", "true");
1041
+ target.focus();
1042
+ const range = ownerDoc.createRange();
1043
+ range.selectNodeContents(target);
1044
+ const sel = ownerWin?.getSelection();
1045
+ sel?.removeAllRanges();
1046
+ sel?.addRange(range);
1047
+ const propName = matchingPropName;
1048
+ const finalIsMultilingual = isMultilingual;
1049
+ const finalLangCode = matchedLangCode;
1050
+ const commitInlineEdit = () => {
1051
+ target.contentEditable = "false";
1052
+ target.removeAttribute("data-tecof-inline-editing");
1053
+ target.removeEventListener("blur", handleBlur);
1054
+ target.removeEventListener("keydown", handleKeyDown);
1055
+ const newText = target.textContent?.trim() || "";
1056
+ if (finalIsMultilingual) {
1057
+ const currentArray = Array.isArray(node.props[propName]) ? node.props[propName] : [];
1058
+ const updatedArray = currentArray.map((item2) => {
1059
+ if (item2 && item2.code === finalLangCode) {
1060
+ return { ...item2, value: newText };
1061
+ }
1062
+ return item2;
1063
+ });
1064
+ if (!updatedArray.some((item2) => item2 && item2.code === finalLangCode)) {
1065
+ updatedArray.push({ code: finalLangCode, value: newText });
1066
+ }
1067
+ useEditorStore.getState().updateProps(node.props.id, {
1068
+ [propName]: updatedArray
1069
+ });
1070
+ } else {
1071
+ useEditorStore.getState().updateProps(node.props.id, {
1072
+ [propName]: newText
1073
+ });
1074
+ }
1075
+ };
1076
+ const cancelInlineEdit = () => {
1077
+ target.textContent = originalText;
1078
+ target.contentEditable = "false";
1079
+ target.removeAttribute("data-tecof-inline-editing");
1080
+ target.removeEventListener("blur", handleBlur);
1081
+ target.removeEventListener("keydown", handleKeyDown);
1082
+ };
1083
+ const handleBlur = () => {
1084
+ commitInlineEdit();
1085
+ };
1086
+ const handleKeyDown = (event) => {
1087
+ if (event.key === "Escape") {
1088
+ event.preventDefault();
1089
+ cancelInlineEdit();
1090
+ return;
1091
+ }
1092
+ if (event.key === "Enter" && !event.shiftKey) {
1093
+ event.preventDefault();
1094
+ target.blur();
1095
+ }
1096
+ };
1097
+ target.addEventListener("blur", handleBlur);
1098
+ target.addEventListener("keydown", handleKeyDown);
1099
+ },
1100
+ [node.props, node.props.id, readOnly]
1101
+ );
1102
+ const [dragOverPosition, setDragOverPosition] = React__default.useState(null);
1103
+ const handleDragOver = React__default.useCallback((e3) => {
1104
+ if (readOnly) return;
1105
+ e3.preventDefault();
1106
+ e3.stopPropagation();
1107
+ autoScrollerRef.current.update(e3);
1108
+ const rect = e3.currentTarget.getBoundingClientRect();
1109
+ const relativeY = e3.clientY - rect.top;
1110
+ if (relativeY < rect.height / 2) {
1111
+ setDragOverPosition("top");
1112
+ } else {
1113
+ setDragOverPosition("bottom");
1114
+ }
1115
+ }, [readOnly]);
1116
+ const handleDragLeave = React__default.useCallback((e3) => {
1117
+ if (e3.currentTarget.contains(e3.relatedTarget)) return;
1118
+ autoScrollerRef.current.stop();
1119
+ setDragOverPosition(null);
1120
+ }, []);
1121
+ const handleDrop = React__default.useCallback((e3) => {
1122
+ if (readOnly) return;
1123
+ e3.preventDefault();
1124
+ e3.stopPropagation();
1125
+ autoScrollerRef.current.stop();
1126
+ setDragOverPosition(null);
1127
+ const { nodeId, type } = readDragData(e3);
1128
+ const targetIndex = dragOverPosition === "top" ? index2 : index2 + 1;
1129
+ if (nodeId && nodeId !== node.props.id) {
1130
+ useEditorStore.getState().moveNode(nodeId, zoneKey || void 0, targetIndex);
1131
+ } else if (type) {
1132
+ useEditorStore.getState().insertNode(createNode(config3, type), zoneKey || void 0, targetIndex);
1133
+ }
1134
+ endDrag();
1135
+ }, [dragOverPosition, index2, node.props.id, zoneKey, config3, readOnly, endDrag]);
1136
+ if (!componentConfig) {
1137
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-node-missing", children: [
1138
+ "Bile\u015Fen bulunamad\u0131: ",
1139
+ node.type
1140
+ ] });
1141
+ }
1142
+ const label = componentConfig.label || node.type;
1143
+ const wrapperClassName = [
1144
+ "tecof-node-wrapper",
1145
+ readOnly ? "is-readonly" : "",
1146
+ drag?.id === node.props.id ? "is-dragging" : ""
1147
+ ].filter(Boolean).join(" ");
1148
+ const componentProps = {
1149
+ ...node.props,
1150
+ puck: {
1151
+ renderDropZone,
1152
+ isEditing: !readOnly,
1153
+ metadata: {
1154
+ ...metadata || {},
1155
+ ...componentConfig.metadata || {}
1156
+ }
1157
+ },
1158
+ editMode: !readOnly
1159
+ };
1160
+ return /* @__PURE__ */ jsxRuntime.jsx(ParentNodeContext.Provider, { value: node.props.id, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-node", children: [
1161
+ dragOverPosition === "top" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-drop-line" }),
1162
+ /* @__PURE__ */ jsxRuntime.jsx(
1163
+ "div",
1164
+ {
1165
+ className: wrapperClassName,
1166
+ "data-tecof-id": node.props.id,
1167
+ "data-tecof-type": node.type,
1168
+ "data-tecof-index": index2,
1169
+ "data-tecof-zone": zoneKey || "root",
1170
+ draggable: !readOnly,
1171
+ onDragStart: (e3) => {
1172
+ writeDragData(e3, { nodeId: node.props.id });
1173
+ e3.dataTransfer.effectAllowed = "move";
1174
+ setDragGhost(e3, label);
1175
+ beginDrag({ id: node.props.id });
1176
+ },
1177
+ onDragEnd: () => {
1178
+ autoScrollerRef.current.stop();
1179
+ endDrag();
1180
+ },
1181
+ onMouseEnter: handleMouseEnter,
1182
+ onMouseLeave: handleMouseLeave,
1183
+ onClick: handleClick,
1184
+ onDoubleClick: handleDoubleClick,
1185
+ onDragOver: handleDragOver,
1186
+ onDragLeave: handleDragLeave,
1187
+ onDrop: handleDrop,
1188
+ children: componentConfig.render(componentProps)
1189
+ }
1190
+ ),
1191
+ dragOverPosition === "bottom" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-drop-line" })
1192
+ ] }) });
1193
+ };
784
1194
  var Canvas = () => {
785
1195
  const content = useEditorStore((state3) => state3.document.content);
786
1196
  const viewport = useEditorStore((state3) => state3.viewport);
787
- const getWidth2 = () => {
788
- switch (viewport) {
789
- case "tablet":
790
- return "768px";
791
- case "mobile":
792
- return "375px";
793
- case "desktop":
794
- default:
795
- return "100%";
796
- }
797
- };
798
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-canvas-container", style: {
799
- flex: 1,
800
- display: "flex",
801
- alignItems: "center",
802
- justifyContent: "center",
803
- background: "#f4f4f5",
804
- padding: "24px",
805
- overflow: "auto",
806
- height: "100%",
807
- boxSizing: "border-box"
808
- }, children: /* @__PURE__ */ jsxRuntime.jsx(
1197
+ const insertNode2 = useEditorStore((state3) => state3.insertNode);
1198
+ const endDrag = useEditorStore((state3) => state3.endDrag);
1199
+ const { config: config3, readOnly } = useStudio();
1200
+ const rootProps = useEditorStore((state3) => state3.document.root?.props || {});
1201
+ const [isRootDragOver, setIsRootDragOver] = React__default.useState(false);
1202
+ const autoScrollerRef = React__default.useRef(createEventAutoScroller());
1203
+ React__default.useEffect(() => {
1204
+ if (!readOnly) return;
1205
+ autoScrollerRef.current.stop();
1206
+ setIsRootDragOver(false);
1207
+ }, [readOnly]);
1208
+ const handleRootDragOver = React__default.useCallback(
1209
+ (e3) => {
1210
+ if (readOnly) return;
1211
+ e3.preventDefault();
1212
+ autoScrollerRef.current.update(e3);
1213
+ setIsRootDragOver(true);
1214
+ },
1215
+ [readOnly]
1216
+ );
1217
+ const handleRootDragLeave = React__default.useCallback((e3) => {
1218
+ if (e3.currentTarget.contains(e3.relatedTarget)) return;
1219
+ autoScrollerRef.current.stop();
1220
+ setIsRootDragOver(false);
1221
+ }, []);
1222
+ const handleRootDrop = React__default.useCallback(
1223
+ (e3) => {
1224
+ if (readOnly) return;
1225
+ e3.preventDefault();
1226
+ autoScrollerRef.current.stop();
1227
+ setIsRootDragOver(false);
1228
+ const { nodeId, type } = readDragData(e3);
1229
+ if (nodeId) {
1230
+ useEditorStore.getState().moveNode(nodeId, void 0, content.length);
1231
+ } else if (type) {
1232
+ insertNode2(createNode(config3, type), void 0, content.length);
1233
+ }
1234
+ endDrag();
1235
+ },
1236
+ [config3, content.length, endDrag, insertNode2, readOnly]
1237
+ );
1238
+ const rootClassName = [
1239
+ "tecof-canvas-root",
1240
+ content.length === 0 ? "is-empty" : "",
1241
+ isRootDragOver ? "is-dragover" : ""
1242
+ ].filter(Boolean).join(" ");
1243
+ const viewportClassName = [
1244
+ "tecof-canvas-viewport",
1245
+ viewport !== "desktop" ? `is-${viewport}` : ""
1246
+ ].filter(Boolean).join(" ");
1247
+ const renderedContent = /* @__PURE__ */ jsxRuntime.jsx(
809
1248
  "div",
810
1249
  {
811
- className: "tecof-canvas-viewport-wrapper",
812
- style: {
813
- width: getWidth2(),
814
- height: "100%",
815
- maxWidth: "100%",
816
- transition: "width 0.3s cubic-bezier(0.4, 0, 0.2, 1)",
817
- boxShadow: "0 10px 25px -5px rgba(0, 0, 0, 0.05), 0 8px 10px -6px rgba(0, 0, 0, 0.05)",
818
- borderRadius: viewport === "desktop" ? "0" : "12px",
819
- overflow: "hidden",
820
- backgroundColor: "#ffffff"
821
- },
822
- children: /* @__PURE__ */ jsxRuntime.jsx(Frame, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-canvas-root", style: { minHeight: "100%" }, children: content.map((item2, index2) => /* @__PURE__ */ jsxRuntime.jsx(NodeRenderer, { node: item2, index: index2 }, item2.props.id)) }) })
1250
+ className: rootClassName,
1251
+ onDragOver: handleRootDragOver,
1252
+ onDragLeave: handleRootDragLeave,
1253
+ onDrop: handleRootDrop,
1254
+ "data-tecof-zone": "root",
1255
+ children: content.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-canvas-empty", children: [
1256
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-canvas-empty-kicker", children: "Root" }),
1257
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "tecof-canvas-empty-title", children: isRootDragOver ? "B\u0131rakmaya haz\u0131r" : "Canvas bo\u015F" }),
1258
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "tecof-canvas-empty-sub", children: isRootDragOver ? "Bile\u015Fen ana ak\u0131\u015Fa eklenecek" : "\u0130lk blo\u011Fu buraya b\u0131rak\u0131n" })
1259
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1260
+ content.map((item2, index2) => /* @__PURE__ */ jsxRuntime.jsx(NodeRenderer, { node: item2, index: index2 }, item2.props.id)),
1261
+ !readOnly && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-canvas-root-tail", "aria-hidden": "true" })
1262
+ ] })
823
1263
  }
824
- ) });
1264
+ );
1265
+ const rootConfig = config3.root;
1266
+ const contentWithLayout = rootConfig?.render ? rootConfig.render({
1267
+ ...rootProps,
1268
+ children: renderedContent,
1269
+ editMode: true
1270
+ }) : renderedContent;
1271
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-canvas-container", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: viewportClassName, children: /* @__PURE__ */ jsxRuntime.jsx(Frame, { className: "tecof-canvas-frame", children: contentWithLayout }) }) });
825
1272
  };
826
1273
 
827
1274
  // node_modules/lucide-react/dist/esm/shared/src/utils/mergeClasses.js
@@ -1028,8 +1475,18 @@ var __iconNode14 = [
1028
1475
  ];
1029
1476
  var Globe = createLucideIcon("globe", __iconNode14);
1030
1477
 
1031
- // node_modules/lucide-react/dist/esm/icons/grip-vertical.js
1478
+ // node_modules/lucide-react/dist/esm/icons/grid-3x3.js
1032
1479
  var __iconNode15 = [
1480
+ ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }],
1481
+ ["path", { d: "M3 9h18", key: "1pudct" }],
1482
+ ["path", { d: "M3 15h18", key: "5xshup" }],
1483
+ ["path", { d: "M9 3v18", key: "fh3hqa" }],
1484
+ ["path", { d: "M15 3v18", key: "14nvp0" }]
1485
+ ];
1486
+ var Grid3x3 = createLucideIcon("grid-3x3", __iconNode15);
1487
+
1488
+ // node_modules/lucide-react/dist/esm/icons/grip-vertical.js
1489
+ var __iconNode16 = [
1033
1490
  ["circle", { cx: "9", cy: "12", r: "1", key: "1vctgf" }],
1034
1491
  ["circle", { cx: "9", cy: "5", r: "1", key: "hp0tcf" }],
1035
1492
  ["circle", { cx: "9", cy: "19", r: "1", key: "fkjjf6" }],
@@ -1037,28 +1494,28 @@ var __iconNode15 = [
1037
1494
  ["circle", { cx: "15", cy: "5", r: "1", key: "19l28e" }],
1038
1495
  ["circle", { cx: "15", cy: "19", r: "1", key: "f4zoj3" }]
1039
1496
  ];
1040
- var GripVertical = createLucideIcon("grip-vertical", __iconNode15);
1497
+ var GripVertical = createLucideIcon("grip-vertical", __iconNode16);
1041
1498
 
1042
1499
  // node_modules/lucide-react/dist/esm/icons/image-plus.js
1043
- var __iconNode16 = [
1500
+ var __iconNode17 = [
1044
1501
  ["path", { d: "M16 5h6", key: "1vod17" }],
1045
1502
  ["path", { d: "M19 2v6", key: "4bpg5p" }],
1046
1503
  ["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" }],
1047
1504
  ["path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21", key: "1xmnt7" }],
1048
1505
  ["circle", { cx: "9", cy: "9", r: "2", key: "af1f0g" }]
1049
1506
  ];
1050
- var ImagePlus = createLucideIcon("image-plus", __iconNode16);
1507
+ var ImagePlus = createLucideIcon("image-plus", __iconNode17);
1051
1508
 
1052
1509
  // node_modules/lucide-react/dist/esm/icons/image.js
1053
- var __iconNode17 = [
1510
+ var __iconNode18 = [
1054
1511
  ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2", key: "1m3agn" }],
1055
1512
  ["circle", { cx: "9", cy: "9", r: "2", key: "af1f0g" }],
1056
1513
  ["path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21", key: "1xmnt7" }]
1057
1514
  ];
1058
- var Image2 = createLucideIcon("image", __iconNode17);
1515
+ var Image2 = createLucideIcon("image", __iconNode18);
1059
1516
 
1060
1517
  // node_modules/lucide-react/dist/esm/icons/languages.js
1061
- var __iconNode18 = [
1518
+ var __iconNode19 = [
1062
1519
  ["path", { d: "m5 8 6 6", key: "1wu5hv" }],
1063
1520
  ["path", { d: "m4 14 6-6 2-3", key: "1k1g8d" }],
1064
1521
  ["path", { d: "M2 5h12", key: "or177f" }],
@@ -1066,29 +1523,71 @@ var __iconNode18 = [
1066
1523
  ["path", { d: "m22 22-5-10-5 10", key: "don7ne" }],
1067
1524
  ["path", { d: "M14 18h6", key: "1m8k6r" }]
1068
1525
  ];
1069
- var Languages = createLucideIcon("languages", __iconNode18);
1526
+ var Languages = createLucideIcon("languages", __iconNode19);
1527
+
1528
+ // node_modules/lucide-react/dist/esm/icons/layers.js
1529
+ var __iconNode20 = [
1530
+ [
1531
+ "path",
1532
+ {
1533
+ d: "M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z",
1534
+ key: "zw3jo"
1535
+ }
1536
+ ],
1537
+ [
1538
+ "path",
1539
+ {
1540
+ d: "M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12",
1541
+ key: "1wduqc"
1542
+ }
1543
+ ],
1544
+ [
1545
+ "path",
1546
+ {
1547
+ d: "M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17",
1548
+ key: "kqbvx6"
1549
+ }
1550
+ ]
1551
+ ];
1552
+ var Layers = createLucideIcon("layers", __iconNode20);
1070
1553
 
1071
1554
  // node_modules/lucide-react/dist/esm/icons/link-2.js
1072
- var __iconNode19 = [
1555
+ var __iconNode21 = [
1073
1556
  ["path", { d: "M9 17H7A5 5 0 0 1 7 7h2", key: "8i5ue5" }],
1074
1557
  ["path", { d: "M15 7h2a5 5 0 1 1 0 10h-2", key: "1b9ql8" }],
1075
1558
  ["line", { x1: "8", x2: "16", y1: "12", y2: "12", key: "1jonct" }]
1076
1559
  ];
1077
- var Link2 = createLucideIcon("link-2", __iconNode19);
1560
+ var Link2 = createLucideIcon("link-2", __iconNode21);
1078
1561
 
1079
1562
  // node_modules/lucide-react/dist/esm/icons/link.js
1080
- var __iconNode20 = [
1563
+ var __iconNode22 = [
1081
1564
  ["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" }],
1082
1565
  ["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" }]
1083
1566
  ];
1084
- var Link = createLucideIcon("link", __iconNode20);
1567
+ var Link = createLucideIcon("link", __iconNode22);
1085
1568
 
1086
1569
  // node_modules/lucide-react/dist/esm/icons/loader-circle.js
1087
- var __iconNode21 = [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]];
1088
- var LoaderCircle = createLucideIcon("loader-circle", __iconNode21);
1570
+ var __iconNode23 = [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]];
1571
+ var LoaderCircle = createLucideIcon("loader-circle", __iconNode23);
1572
+
1573
+ // node_modules/lucide-react/dist/esm/icons/monitor.js
1574
+ var __iconNode24 = [
1575
+ ["rect", { width: "20", height: "14", x: "2", y: "3", rx: "2", key: "48i651" }],
1576
+ ["line", { x1: "8", x2: "16", y1: "21", y2: "21", key: "1svkeh" }],
1577
+ ["line", { x1: "12", x2: "12", y1: "17", y2: "21", key: "vw1qmm" }]
1578
+ ];
1579
+ var Monitor = createLucideIcon("monitor", __iconNode24);
1580
+
1581
+ // node_modules/lucide-react/dist/esm/icons/panels-top-left.js
1582
+ var __iconNode25 = [
1583
+ ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }],
1584
+ ["path", { d: "M3 9h18", key: "1pudct" }],
1585
+ ["path", { d: "M9 21V9", key: "1oto5p" }]
1586
+ ];
1587
+ var PanelsTopLeft = createLucideIcon("panels-top-left", __iconNode25);
1089
1588
 
1090
1589
  // node_modules/lucide-react/dist/esm/icons/pencil.js
1091
- var __iconNode22 = [
1590
+ var __iconNode26 = [
1092
1591
  [
1093
1592
  "path",
1094
1593
  {
@@ -1098,71 +1597,119 @@ var __iconNode22 = [
1098
1597
  ],
1099
1598
  ["path", { d: "m15 5 4 4", key: "1mk7zo" }]
1100
1599
  ];
1101
- var Pencil = createLucideIcon("pencil", __iconNode22);
1600
+ var Pencil = createLucideIcon("pencil", __iconNode26);
1102
1601
 
1103
1602
  // node_modules/lucide-react/dist/esm/icons/plus.js
1104
- var __iconNode23 = [
1603
+ var __iconNode27 = [
1105
1604
  ["path", { d: "M5 12h14", key: "1ays0h" }],
1106
1605
  ["path", { d: "M12 5v14", key: "s699le" }]
1107
1606
  ];
1108
- var Plus = createLucideIcon("plus", __iconNode23);
1607
+ var Plus = createLucideIcon("plus", __iconNode27);
1608
+
1609
+ // node_modules/lucide-react/dist/esm/icons/redo-2.js
1610
+ var __iconNode28 = [
1611
+ ["path", { d: "m15 14 5-5-5-5", key: "12vg1m" }],
1612
+ ["path", { d: "M20 9H9.5A5.5 5.5 0 0 0 4 14.5A5.5 5.5 0 0 0 9.5 20H13", key: "6uklza" }]
1613
+ ];
1614
+ var Redo2 = createLucideIcon("redo-2", __iconNode28);
1109
1615
 
1110
1616
  // node_modules/lucide-react/dist/esm/icons/refresh-ccw.js
1111
- var __iconNode24 = [
1617
+ var __iconNode29 = [
1112
1618
  ["path", { d: "M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8", key: "14sxne" }],
1113
1619
  ["path", { d: "M3 3v5h5", key: "1xhq8a" }],
1114
1620
  ["path", { d: "M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16", key: "1hlbsb" }],
1115
1621
  ["path", { d: "M16 16h5v5", key: "ccwih5" }]
1116
1622
  ];
1117
- var RefreshCcw = createLucideIcon("refresh-ccw", __iconNode24);
1623
+ var RefreshCcw = createLucideIcon("refresh-ccw", __iconNode29);
1118
1624
 
1119
1625
  // node_modules/lucide-react/dist/esm/icons/refresh-cw.js
1120
- var __iconNode25 = [
1626
+ var __iconNode30 = [
1121
1627
  ["path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8", key: "v9h5vc" }],
1122
1628
  ["path", { d: "M21 3v5h-5", key: "1q7to0" }],
1123
1629
  ["path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16", key: "3uifl3" }],
1124
1630
  ["path", { d: "M8 16H3v5", key: "1cv678" }]
1125
1631
  ];
1126
- var RefreshCw = createLucideIcon("refresh-cw", __iconNode25);
1632
+ var RefreshCw = createLucideIcon("refresh-cw", __iconNode30);
1127
1633
 
1128
1634
  // node_modules/lucide-react/dist/esm/icons/rotate-ccw.js
1129
- var __iconNode26 = [
1635
+ var __iconNode31 = [
1130
1636
  ["path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8", key: "1357e3" }],
1131
1637
  ["path", { d: "M3 3v5h5", key: "1xhq8a" }]
1132
1638
  ];
1133
- var RotateCcw = createLucideIcon("rotate-ccw", __iconNode26);
1639
+ var RotateCcw = createLucideIcon("rotate-ccw", __iconNode31);
1640
+
1641
+ // node_modules/lucide-react/dist/esm/icons/save.js
1642
+ var __iconNode32 = [
1643
+ [
1644
+ "path",
1645
+ {
1646
+ d: "M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z",
1647
+ key: "1c8476"
1648
+ }
1649
+ ],
1650
+ ["path", { d: "M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7", key: "1ydtos" }],
1651
+ ["path", { d: "M7 3v4a1 1 0 0 0 1 1h7", key: "t51u73" }]
1652
+ ];
1653
+ var Save = createLucideIcon("save", __iconNode32);
1134
1654
 
1135
1655
  // node_modules/lucide-react/dist/esm/icons/search.js
1136
- var __iconNode27 = [
1656
+ var __iconNode33 = [
1137
1657
  ["path", { d: "m21 21-4.34-4.34", key: "14j7rj" }],
1138
1658
  ["circle", { cx: "11", cy: "11", r: "8", key: "4ej97u" }]
1139
1659
  ];
1140
- var Search = createLucideIcon("search", __iconNode27);
1660
+ var Search = createLucideIcon("search", __iconNode33);
1661
+
1662
+ // node_modules/lucide-react/dist/esm/icons/smartphone.js
1663
+ var __iconNode34 = [
1664
+ ["rect", { width: "14", height: "20", x: "5", y: "2", rx: "2", ry: "2", key: "1yt0o3" }],
1665
+ ["path", { d: "M12 18h.01", key: "mhygvu" }]
1666
+ ];
1667
+ var Smartphone = createLucideIcon("smartphone", __iconNode34);
1668
+
1669
+ // node_modules/lucide-react/dist/esm/icons/tablet.js
1670
+ var __iconNode35 = [
1671
+ ["rect", { width: "16", height: "20", x: "4", y: "2", rx: "2", ry: "2", key: "76otgf" }],
1672
+ ["line", { x1: "12", x2: "12.01", y1: "18", y2: "18", key: "1dp563" }]
1673
+ ];
1674
+ var Tablet = createLucideIcon("tablet", __iconNode35);
1141
1675
 
1142
1676
  // node_modules/lucide-react/dist/esm/icons/trash-2.js
1143
- var __iconNode28 = [
1677
+ var __iconNode36 = [
1144
1678
  ["path", { d: "M10 11v6", key: "nco0om" }],
1145
1679
  ["path", { d: "M14 11v6", key: "outv1u" }],
1146
1680
  ["path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6", key: "miytrc" }],
1147
1681
  ["path", { d: "M3 6h18", key: "d0wm0j" }],
1148
1682
  ["path", { d: "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2", key: "e791ji" }]
1149
1683
  ];
1150
- var Trash2 = createLucideIcon("trash-2", __iconNode28);
1684
+ var Trash2 = createLucideIcon("trash-2", __iconNode36);
1685
+
1686
+ // node_modules/lucide-react/dist/esm/icons/undo-2.js
1687
+ var __iconNode37 = [
1688
+ ["path", { d: "M9 14 4 9l5-5", key: "102s5s" }],
1689
+ ["path", { d: "M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5a5.5 5.5 0 0 1-5.5 5.5H11", key: "f3b9sd" }]
1690
+ ];
1691
+ var Undo2 = createLucideIcon("undo-2", __iconNode37);
1151
1692
 
1152
1693
  // node_modules/lucide-react/dist/esm/icons/upload.js
1153
- var __iconNode29 = [
1694
+ var __iconNode38 = [
1154
1695
  ["path", { d: "M12 3v12", key: "1x0j5s" }],
1155
1696
  ["path", { d: "m17 8-5-5-5 5", key: "7q97r8" }],
1156
1697
  ["path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4", key: "ih7n3h" }]
1157
1698
  ];
1158
- var Upload = createLucideIcon("upload", __iconNode29);
1699
+ var Upload = createLucideIcon("upload", __iconNode38);
1159
1700
 
1160
1701
  // node_modules/lucide-react/dist/esm/icons/x.js
1161
- var __iconNode30 = [
1702
+ var __iconNode39 = [
1162
1703
  ["path", { d: "M18 6 6 18", key: "1bl5f8" }],
1163
1704
  ["path", { d: "m6 6 12 12", key: "d8bk6v" }]
1164
1705
  ];
1165
- var X = createLucideIcon("x", __iconNode30);
1706
+ var X = createLucideIcon("x", __iconNode39);
1707
+ var getOutlineStyle = (coords) => ({
1708
+ "--tecof-outline-top": `${coords.top}px`,
1709
+ "--tecof-outline-left": `${coords.left}px`,
1710
+ "--tecof-outline-width": `${coords.width}px`,
1711
+ "--tecof-outline-height": `${coords.height}px`
1712
+ });
1166
1713
  var useOverlayCoords = (id, iframeEl, containerEl, documentState) => {
1167
1714
  const [coords, setCoords] = React__default.useState(null);
1168
1715
  React__default.useEffect(() => {
@@ -1224,7 +1771,7 @@ var SelectionOverlay = () => {
1224
1771
  const [iframeEl, setIframeEl] = React__default.useState(null);
1225
1772
  const containerRef = React__default.useRef(null);
1226
1773
  React__default.useEffect(() => {
1227
- const iframe = document.querySelector(".tecof-canvas-viewport-wrapper iframe");
1774
+ const iframe = document.querySelector(".tecof-canvas-viewport iframe");
1228
1775
  setIframeEl(iframe);
1229
1776
  }, [documentState]);
1230
1777
  const selectedCoords = useOverlayCoords(selectedId, iframeEl, containerRef.current, documentState);
@@ -1253,220 +1800,95 @@ var SelectionOverlay = () => {
1253
1800
  "div",
1254
1801
  {
1255
1802
  ref: containerRef,
1256
- className: "tecof-selection-overlay-container",
1257
- style: {
1258
- position: "absolute",
1259
- top: 0,
1260
- left: 0,
1261
- right: 0,
1262
- bottom: 0,
1263
- pointerEvents: "none",
1264
- zIndex: 1e3
1265
- },
1803
+ className: "tecof-overlay",
1266
1804
  children: [
1267
1805
  hoveredCoords && /* @__PURE__ */ jsxRuntime.jsx(
1268
1806
  "div",
1269
1807
  {
1270
- className: "tecof-hover-outline",
1271
- style: {
1272
- position: "absolute",
1273
- top: hoveredCoords.top,
1274
- left: hoveredCoords.left,
1275
- width: hoveredCoords.width,
1276
- height: hoveredCoords.height,
1277
- border: "1.5px dashed #3b82f6",
1278
- borderRadius: "4px",
1279
- boxSizing: "border-box",
1280
- pointerEvents: "none",
1281
- transition: "all 0.1s ease-out"
1282
- }
1808
+ className: "tecof-outline is-hover",
1809
+ style: getOutlineStyle(hoveredCoords)
1283
1810
  }
1284
1811
  ),
1285
1812
  selectedCoords && /* @__PURE__ */ jsxRuntime.jsxs(
1286
1813
  "div",
1287
1814
  {
1288
- className: "tecof-selected-outline",
1289
- style: {
1290
- position: "absolute",
1291
- top: selectedCoords.top,
1292
- left: selectedCoords.left,
1293
- width: selectedCoords.width,
1294
- height: selectedCoords.height,
1295
- border: "2px solid #3b82f6",
1296
- borderRadius: "4px",
1297
- boxSizing: "border-box",
1298
- pointerEvents: "none",
1299
- transition: "all 0.1s ease-out"
1300
- },
1815
+ className: "tecof-outline is-selected",
1816
+ style: getOutlineStyle(selectedCoords),
1301
1817
  children: [
1302
- /* @__PURE__ */ jsxRuntime.jsxs(
1303
- "div",
1304
- {
1305
- className: "tecof-floating-toolbar",
1306
- style: {
1307
- position: "absolute",
1308
- top: "-36px",
1309
- right: "-2px",
1310
- display: "flex",
1311
- alignItems: "center",
1312
- gap: "4px",
1313
- background: "#3b82f6",
1314
- borderRadius: "6px",
1315
- padding: "4px",
1316
- pointerEvents: "auto",
1317
- boxShadow: "0 4px 6px -1px rgba(59, 130, 246, 0.2)"
1318
- },
1319
- children: [
1320
- parentId && /* @__PURE__ */ jsxRuntime.jsx(
1321
- "button",
1322
- {
1323
- onClick: () => selectNode(parentId),
1324
- title: "\xDCst \xD6\u011Feyi Se\xE7",
1325
- style: {
1326
- background: "transparent",
1327
- border: "none",
1328
- color: "#ffffff",
1329
- cursor: "pointer",
1330
- padding: "4px",
1331
- borderRadius: "4px",
1332
- display: "flex"
1333
- },
1334
- children: /* @__PURE__ */ jsxRuntime.jsx(ChevronUp, { size: 14 })
1335
- }
1336
- ),
1337
- /* @__PURE__ */ jsxRuntime.jsx(
1338
- "button",
1339
- {
1340
- onClick: () => handleMove("up"),
1341
- disabled: !canMoveUp,
1342
- title: "Yukar\u0131 Ta\u015F\u0131",
1343
- style: {
1344
- background: "transparent",
1345
- border: "none",
1346
- color: "#ffffff",
1347
- opacity: canMoveUp ? 1 : 0.5,
1348
- cursor: canMoveUp ? "pointer" : "not-allowed",
1349
- padding: "4px",
1350
- borderRadius: "4px",
1351
- display: "flex"
1352
- },
1353
- children: /* @__PURE__ */ jsxRuntime.jsx(ArrowUp, { size: 14 })
1354
- }
1355
- ),
1356
- /* @__PURE__ */ jsxRuntime.jsx(
1357
- "button",
1358
- {
1359
- onClick: () => handleMove("down"),
1360
- disabled: !canMoveDown,
1361
- title: "A\u015Fa\u011F\u0131 Ta\u015F\u0131",
1362
- style: {
1363
- background: "transparent",
1364
- border: "none",
1365
- color: "#ffffff",
1366
- opacity: canMoveDown ? 1 : 0.5,
1367
- cursor: canMoveDown ? "pointer" : "not-allowed",
1368
- padding: "4px",
1369
- borderRadius: "4px",
1370
- display: "flex"
1371
- },
1372
- children: /* @__PURE__ */ jsxRuntime.jsx(ArrowDown, { size: 14 })
1373
- }
1374
- ),
1375
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: "1px", height: "14px", background: "rgba(255,255,255,0.3)", margin: "0 2px" } }),
1376
- /* @__PURE__ */ jsxRuntime.jsx(
1377
- "button",
1378
- {
1379
- onClick: () => duplicateNode2(selectedId),
1380
- title: "Kopyala",
1381
- style: {
1382
- background: "transparent",
1383
- border: "none",
1384
- color: "#ffffff",
1385
- cursor: "pointer",
1386
- padding: "4px",
1387
- borderRadius: "4px",
1388
- display: "flex"
1389
- },
1390
- children: /* @__PURE__ */ jsxRuntime.jsx(Copy, { size: 14 })
1391
- }
1392
- ),
1393
- /* @__PURE__ */ jsxRuntime.jsx(
1394
- "button",
1395
- {
1396
- onClick: () => removeNode2(selectedId),
1397
- title: "Sil",
1398
- style: {
1399
- background: "transparent",
1400
- border: "none",
1401
- color: "#ffffff",
1402
- cursor: "pointer",
1403
- padding: "4px",
1404
- borderRadius: "4px",
1405
- display: "flex"
1406
- },
1407
- children: /* @__PURE__ */ jsxRuntime.jsx(Trash2, { size: 14 })
1408
- }
1409
- )
1410
- ]
1411
- }
1412
- ),
1413
- nodeDetails && /* @__PURE__ */ jsxRuntime.jsx(
1414
- "div",
1415
- {
1416
- className: "tecof-outline-label",
1417
- style: {
1418
- position: "absolute",
1419
- top: "-26px",
1420
- left: "-2px",
1421
- background: "#3b82f6",
1422
- color: "#ffffff",
1423
- fontSize: "11px",
1424
- fontWeight: 600,
1425
- padding: "2px 8px",
1426
- borderRadius: "4px 4px 0 0",
1427
- userSelect: "none"
1428
- },
1429
- children: nodeDetails.node.type
1430
- }
1431
- ),
1432
- breadcrumbs.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(
1433
- "div",
1434
- {
1435
- className: "tecof-selected-breadcrumbs",
1436
- style: {
1437
- position: "absolute",
1438
- bottom: "-28px",
1439
- left: "-2px",
1440
- display: "flex",
1441
- alignItems: "center",
1442
- gap: "4px",
1443
- background: "#18181b",
1444
- color: "#a1a1aa",
1445
- fontSize: "10px",
1446
- padding: "4px 8px",
1447
- borderRadius: "0 0 6px 6px",
1448
- pointerEvents: "auto",
1449
- boxShadow: "0 2px 4px rgba(0,0,0,0.05)"
1450
- },
1451
- children: breadcrumbs.map((crumb, idx) => /* @__PURE__ */ jsxRuntime.jsxs(React__default__namespace.default.Fragment, { children: [
1452
- idx > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#52525b" }, children: ">" }),
1453
- /* @__PURE__ */ jsxRuntime.jsx(
1454
- "span",
1455
- {
1456
- onClick: () => selectNode(crumb.id),
1457
- style: {
1458
- cursor: "pointer",
1459
- color: crumb.id === selectedId ? "#ffffff" : void 0,
1460
- fontWeight: crumb.id === selectedId ? 600 : void 0
1461
- },
1462
- onMouseEnter: () => useEditorStore.getState().hoverNode(crumb.id),
1463
- onMouseLeave: () => useEditorStore.getState().hoverNode(null),
1464
- children: crumb.type
1465
- }
1466
- )
1467
- ] }, crumb.id))
1468
- }
1469
- )
1818
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-toolbar", children: [
1819
+ parentId && /* @__PURE__ */ jsxRuntime.jsx(
1820
+ "button",
1821
+ {
1822
+ type: "button",
1823
+ onClick: () => selectNode(parentId),
1824
+ title: "\xDCst \xD6\u011Feyi Se\xE7",
1825
+ className: "tecof-toolbar-btn",
1826
+ "aria-label": "\xDCst \xF6\u011Feyi se\xE7",
1827
+ children: /* @__PURE__ */ jsxRuntime.jsx(ChevronUp, { size: 14 })
1828
+ }
1829
+ ),
1830
+ /* @__PURE__ */ jsxRuntime.jsx(
1831
+ "button",
1832
+ {
1833
+ type: "button",
1834
+ onClick: () => handleMove("up"),
1835
+ disabled: !canMoveUp,
1836
+ title: "Yukar\u0131 Ta\u015F\u0131",
1837
+ className: "tecof-toolbar-btn",
1838
+ "aria-label": "Yukar\u0131 ta\u015F\u0131",
1839
+ children: /* @__PURE__ */ jsxRuntime.jsx(ArrowUp, { size: 14 })
1840
+ }
1841
+ ),
1842
+ /* @__PURE__ */ jsxRuntime.jsx(
1843
+ "button",
1844
+ {
1845
+ type: "button",
1846
+ onClick: () => handleMove("down"),
1847
+ disabled: !canMoveDown,
1848
+ title: "A\u015Fa\u011F\u0131 Ta\u015F\u0131",
1849
+ className: "tecof-toolbar-btn",
1850
+ "aria-label": "A\u015Fa\u011F\u0131 ta\u015F\u0131",
1851
+ children: /* @__PURE__ */ jsxRuntime.jsx(ArrowDown, { size: 14 })
1852
+ }
1853
+ ),
1854
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-toolbar-sep" }),
1855
+ /* @__PURE__ */ jsxRuntime.jsx(
1856
+ "button",
1857
+ {
1858
+ type: "button",
1859
+ onClick: () => duplicateNode2(selectedId),
1860
+ title: "Kopyala",
1861
+ className: "tecof-toolbar-btn",
1862
+ "aria-label": "Kopyala",
1863
+ children: /* @__PURE__ */ jsxRuntime.jsx(Copy, { size: 14 })
1864
+ }
1865
+ ),
1866
+ /* @__PURE__ */ jsxRuntime.jsx(
1867
+ "button",
1868
+ {
1869
+ type: "button",
1870
+ onClick: () => removeNode2(selectedId),
1871
+ title: "Sil",
1872
+ className: "tecof-toolbar-btn",
1873
+ "aria-label": "Sil",
1874
+ children: /* @__PURE__ */ jsxRuntime.jsx(Trash2, { size: 14 })
1875
+ }
1876
+ )
1877
+ ] }),
1878
+ nodeDetails && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-outline-label", children: nodeDetails.node.type }),
1879
+ breadcrumbs.length > 1 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-breadcrumbs", children: breadcrumbs.map((crumb, idx) => /* @__PURE__ */ jsxRuntime.jsxs(React__default__namespace.default.Fragment, { children: [
1880
+ idx > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-breadcrumb-sep", children: ">" }),
1881
+ /* @__PURE__ */ jsxRuntime.jsx(
1882
+ "span",
1883
+ {
1884
+ onClick: () => selectNode(crumb.id),
1885
+ className: `tecof-breadcrumb${crumb.id === selectedId ? " is-active" : ""}`,
1886
+ onMouseEnter: () => useEditorStore.getState().hoverNode(crumb.id),
1887
+ onMouseLeave: () => useEditorStore.getState().hoverNode(null),
1888
+ children: crumb.type
1889
+ }
1890
+ )
1891
+ ] }, crumb.id)) })
1470
1892
  ]
1471
1893
  }
1472
1894
  )
@@ -1482,55 +1904,14 @@ var FieldLabel = ({
1482
1904
  el = "label"
1483
1905
  }) => {
1484
1906
  const Component2 = el;
1485
- return /* @__PURE__ */ jsxRuntime.jsxs(
1486
- Component2,
1487
- {
1488
- className: "tecof-field-label-container",
1489
- style: {
1490
- display: "flex",
1491
- flexDirection: "column",
1492
- gap: "6px",
1493
- marginBottom: "16px",
1494
- width: "100%",
1495
- boxSizing: "border-box",
1496
- userSelect: "none"
1497
- },
1498
- children: [
1499
- /* @__PURE__ */ jsxRuntime.jsxs(
1500
- "div",
1501
- {
1502
- className: "tecof-field-label-header",
1503
- style: {
1504
- display: "flex",
1505
- alignItems: "center",
1506
- gap: "6px",
1507
- fontSize: "12px",
1508
- fontWeight: 600,
1509
- color: "#27272a"
1510
- // zinc-800
1511
- },
1512
- children: [
1513
- icon && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { display: "inline-flex" }, children: icon }),
1514
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: label }),
1515
- readOnly && /* @__PURE__ */ jsxRuntime.jsx(
1516
- "span",
1517
- {
1518
- style: {
1519
- fontSize: "10px",
1520
- color: "#a1a1aa",
1521
- fontWeight: 400,
1522
- marginLeft: "auto"
1523
- },
1524
- children: "Salt Okunur"
1525
- }
1526
- )
1527
- ]
1528
- }
1529
- ),
1530
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-field-label-content", style: { width: "100%" }, children })
1531
- ]
1532
- }
1533
- );
1907
+ return /* @__PURE__ */ jsxRuntime.jsxs(Component2, { className: "tecof-field-label-container", children: [
1908
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-field-label-header", children: [
1909
+ icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-field-label-icon", children: icon }),
1910
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: label }),
1911
+ readOnly && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-field-label-readonly", children: "Salt Okunur" })
1912
+ ] }),
1913
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-field-label-content", children })
1914
+ ] });
1534
1915
  };
1535
1916
  var FieldRenderer = ({
1536
1917
  name: name3,
@@ -1539,10 +1920,11 @@ var FieldRenderer = ({
1539
1920
  onChange,
1540
1921
  readOnly = false
1541
1922
  }) => {
1923
+ const [expandedIndices, setExpandedIndices] = React__default.useState({});
1542
1924
  const label = definition.label || name3;
1543
1925
  const type = definition.type;
1544
1926
  if (definition.render) {
1545
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-custom-field-wrapper", style: { width: "100%" }, children: definition.render({
1927
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-field-custom", children: definition.render({
1546
1928
  field: definition,
1547
1929
  name: name3,
1548
1930
  id: `field-${name3}`,
@@ -1561,18 +1943,6 @@ var FieldRenderer = ({
1561
1943
  value: value || "",
1562
1944
  disabled: readOnly,
1563
1945
  onChange: (e3) => onChange(e3.target.value),
1564
- style: {
1565
- width: "100%",
1566
- padding: "10px 12px",
1567
- borderRadius: "8px",
1568
- border: "1px solid #e4e4e7",
1569
- fontSize: "13px",
1570
- color: "#18181b",
1571
- backgroundColor: readOnly ? "#f4f4f5" : "#ffffff",
1572
- outline: "none",
1573
- boxSizing: "border-box",
1574
- transition: "border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out"
1575
- },
1576
1946
  className: "tecof-input-text"
1577
1947
  }
1578
1948
  ) });
@@ -1585,24 +1955,11 @@ var FieldRenderer = ({
1585
1955
  value: value || "",
1586
1956
  disabled: readOnly,
1587
1957
  onChange: (e3) => onChange(e3.target.value),
1588
- style: {
1589
- width: "100%",
1590
- padding: "10px 12px",
1591
- borderRadius: "8px",
1592
- border: "1px solid #e4e4e7",
1593
- fontSize: "13px",
1594
- color: "#18181b",
1595
- backgroundColor: readOnly ? "#f4f4f5" : "#ffffff",
1596
- outline: "none",
1597
- resize: "vertical",
1598
- boxSizing: "border-box",
1599
- transition: "border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out"
1600
- },
1601
1958
  className: "tecof-input-textarea"
1602
1959
  }
1603
1960
  ) });
1604
1961
  case "select":
1605
- return /* @__PURE__ */ jsxRuntime.jsx(FieldLabel, { label, readOnly, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative", width: "100%" }, children: [
1962
+ return /* @__PURE__ */ jsxRuntime.jsx(FieldLabel, { label, readOnly, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-field-select-wrap", children: [
1606
1963
  /* @__PURE__ */ jsxRuntime.jsx(
1607
1964
  "select",
1608
1965
  {
@@ -1610,100 +1967,198 @@ var FieldRenderer = ({
1610
1967
  value: value || "",
1611
1968
  disabled: readOnly,
1612
1969
  onChange: (e3) => onChange(e3.target.value),
1613
- style: {
1614
- width: "100%",
1615
- padding: "10px 32px 10px 12px",
1616
- borderRadius: "8px",
1617
- border: "1px solid #e4e4e7",
1618
- fontSize: "13px",
1619
- color: "#18181b",
1620
- backgroundColor: readOnly ? "#f4f4f5" : "#ffffff",
1621
- outline: "none",
1622
- appearance: "none",
1623
- boxSizing: "border-box",
1624
- cursor: readOnly ? "not-allowed" : "pointer"
1625
- },
1626
1970
  className: "tecof-input-select",
1627
1971
  children: (definition.options || []).map((opt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: opt.value, children: opt.label || opt.value }, opt.value))
1628
1972
  }
1629
1973
  ),
1630
- /* @__PURE__ */ jsxRuntime.jsx(
1631
- "div",
1974
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-field-select-caret", children: /* @__PURE__ */ jsxRuntime.jsx(ChevronDown, { size: 12 }) })
1975
+ ] }) });
1976
+ case "number":
1977
+ return /* @__PURE__ */ jsxRuntime.jsx(FieldLabel, { label, readOnly, children: /* @__PURE__ */ jsxRuntime.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
+ className: "tecof-input-number"
1989
+ }
1990
+ ) });
1991
+ case "radio":
1992
+ return /* @__PURE__ */ jsxRuntime.jsx(FieldLabel, { label, readOnly, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-field-radio-group", children: (definition.options || []).map((opt) => /* @__PURE__ */ jsxRuntime.jsxs(
1993
+ "label",
1994
+ {
1995
+ className: `tecof-field-radio${readOnly ? " is-readonly" : ""}`,
1996
+ children: [
1997
+ /* @__PURE__ */ jsxRuntime.jsx(
1998
+ "input",
1999
+ {
2000
+ type: "radio",
2001
+ name: name3,
2002
+ value: opt.value,
2003
+ checked: value === opt.value,
2004
+ disabled: readOnly,
2005
+ onChange: () => onChange(opt.value)
2006
+ }
2007
+ ),
2008
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: opt.label || opt.value })
2009
+ ]
2010
+ },
2011
+ opt.value
2012
+ )) }) });
2013
+ case "array": {
2014
+ const items = Array.isArray(value) ? value : [];
2015
+ const arrayFields = definition.arrayFields || {};
2016
+ const getItemLabel = (item2, idx) => {
2017
+ if (!item2) return `\xD6\u011Fe ${idx + 1}`;
2018
+ for (const val of Object.values(item2)) {
2019
+ if (typeof val === "string" && val.trim().length > 0) {
2020
+ return val;
2021
+ }
2022
+ if (Array.isArray(val)) {
2023
+ const trVal = val.find((v2) => typeof v2 === "object" && v2 !== null && "value" in v2);
2024
+ if (trVal && typeof trVal.value === "string" && trVal.value.trim().length > 0) {
2025
+ return trVal.value;
2026
+ }
2027
+ }
2028
+ }
2029
+ return `\xD6\u011Fe ${idx + 1}`;
2030
+ };
2031
+ const toggleExpand = (idx) => {
2032
+ setExpandedIndices((prev) => ({ ...prev, [idx]: !prev[idx] }));
2033
+ };
2034
+ const handleAdd = () => {
2035
+ const newItem = {};
2036
+ Object.entries(arrayFields).forEach(([subName, subDef]) => {
2037
+ newItem[subName] = subDef.defaultValue !== void 0 ? subDef.defaultValue : null;
2038
+ });
2039
+ onChange([...items, newItem]);
2040
+ setExpandedIndices((prev) => ({ ...prev, [items.length]: true }));
2041
+ };
2042
+ const handleRemove = (idx) => {
2043
+ const copy = [...items];
2044
+ copy.splice(idx, 1);
2045
+ onChange(copy);
2046
+ const newExpanded = { ...expandedIndices };
2047
+ delete newExpanded[idx];
2048
+ setExpandedIndices(newExpanded);
2049
+ };
2050
+ const handleMove = (idx, direction) => {
2051
+ if (direction === "up" && idx === 0) return;
2052
+ if (direction === "down" && idx === items.length - 1) return;
2053
+ const copy = [...items];
2054
+ const targetIdx = direction === "up" ? idx - 1 : idx + 1;
2055
+ const temp = copy[idx];
2056
+ copy[idx] = copy[targetIdx];
2057
+ copy[targetIdx] = temp;
2058
+ onChange(copy);
2059
+ const newExpanded = { ...expandedIndices };
2060
+ const tempExpanded = newExpanded[idx];
2061
+ newExpanded[idx] = newExpanded[targetIdx];
2062
+ newExpanded[targetIdx] = tempExpanded;
2063
+ setExpandedIndices(newExpanded);
2064
+ };
2065
+ return /* @__PURE__ */ jsxRuntime.jsx(FieldLabel, { label, readOnly, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-array", children: [
2066
+ items.map((item2, idx) => {
2067
+ const isExpanded = !!expandedIndices[idx];
2068
+ const itemLabel = getItemLabel(item2, idx);
2069
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-array-item", children: [
2070
+ /* @__PURE__ */ jsxRuntime.jsxs(
2071
+ "div",
2072
+ {
2073
+ onClick: () => toggleExpand(idx),
2074
+ onKeyDown: (e3) => {
2075
+ if (e3.key === "Enter" || e3.key === " ") {
2076
+ e3.preventDefault();
2077
+ toggleExpand(idx);
2078
+ }
2079
+ },
2080
+ className: "tecof-array-item-header",
2081
+ role: "button",
2082
+ tabIndex: 0,
2083
+ "aria-expanded": isExpanded,
2084
+ children: [
2085
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-array-item-title-wrap", children: [
2086
+ isExpanded ? /* @__PURE__ */ jsxRuntime.jsx(ChevronDown, { size: 14 }) : /* @__PURE__ */ jsxRuntime.jsx(ChevronRight, { size: 14 }),
2087
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-array-item-title", children: itemLabel })
2088
+ ] }),
2089
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-array-item-actions", onClick: (e3) => e3.stopPropagation(), children: [
2090
+ /* @__PURE__ */ jsxRuntime.jsx(
2091
+ "button",
2092
+ {
2093
+ type: "button",
2094
+ onClick: () => handleMove(idx, "up"),
2095
+ disabled: idx === 0,
2096
+ className: "tecof-array-btn",
2097
+ title: "Yukar\u0131 ta\u015F\u0131",
2098
+ children: /* @__PURE__ */ jsxRuntime.jsx(ArrowUp, { size: 12 })
2099
+ }
2100
+ ),
2101
+ /* @__PURE__ */ jsxRuntime.jsx(
2102
+ "button",
2103
+ {
2104
+ type: "button",
2105
+ onClick: () => handleMove(idx, "down"),
2106
+ disabled: idx === items.length - 1,
2107
+ className: "tecof-array-btn",
2108
+ title: "A\u015Fa\u011F\u0131 ta\u015F\u0131",
2109
+ children: /* @__PURE__ */ jsxRuntime.jsx(ArrowDown, { size: 12 })
2110
+ }
2111
+ ),
2112
+ !readOnly && /* @__PURE__ */ jsxRuntime.jsx(
2113
+ "button",
2114
+ {
2115
+ type: "button",
2116
+ onClick: () => handleRemove(idx),
2117
+ className: "tecof-array-btn danger",
2118
+ title: "Sil",
2119
+ children: /* @__PURE__ */ jsxRuntime.jsx(Trash2, { size: 12 })
2120
+ }
2121
+ )
2122
+ ] })
2123
+ ]
2124
+ }
2125
+ ),
2126
+ isExpanded && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-array-item-body", children: Object.entries(arrayFields).map(([subFieldName, subFieldDef]) => /* @__PURE__ */ jsxRuntime.jsx(
2127
+ FieldRenderer,
2128
+ {
2129
+ name: subFieldName,
2130
+ definition: subFieldDef,
2131
+ value: item2[subFieldName],
2132
+ onChange: (newSubVal) => {
2133
+ const updatedItems = [...items];
2134
+ updatedItems[idx] = {
2135
+ ...updatedItems[idx],
2136
+ [subFieldName]: newSubVal
2137
+ };
2138
+ onChange(updatedItems);
2139
+ },
2140
+ readOnly
2141
+ },
2142
+ subFieldName
2143
+ )) })
2144
+ ] }, idx);
2145
+ }),
2146
+ !readOnly && /* @__PURE__ */ jsxRuntime.jsxs(
2147
+ "button",
1632
2148
  {
1633
- style: {
1634
- position: "absolute",
1635
- top: "50%",
1636
- right: "12px",
1637
- transform: "translateY(-50%)",
1638
- pointerEvents: "none",
1639
- display: "flex",
1640
- alignItems: "center",
1641
- color: "#71717a"
1642
- },
1643
- children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M2.5 4.5L6 8L9.5 4.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })
2149
+ type: "button",
2150
+ onClick: handleAdd,
2151
+ className: "tecof-add-array-item-btn",
2152
+ children: [
2153
+ /* @__PURE__ */ jsxRuntime.jsx(Plus, { size: 14 }),
2154
+ "\xD6\u011Fe Ekle"
2155
+ ]
1644
2156
  }
1645
2157
  )
1646
2158
  ] }) });
1647
- case "number":
1648
- return /* @__PURE__ */ jsxRuntime.jsx(FieldLabel, { label, readOnly, children: /* @__PURE__ */ jsxRuntime.jsx(
1649
- "input",
1650
- {
1651
- id: `field-${name3}`,
1652
- type: "number",
1653
- value: value !== void 0 ? value : "",
1654
- disabled: readOnly,
1655
- onChange: (e3) => {
1656
- const val = e3.target.value;
1657
- onChange(val === "" ? void 0 : Number(val));
1658
- },
1659
- style: {
1660
- width: "100%",
1661
- padding: "10px 12px",
1662
- borderRadius: "8px",
1663
- border: "1px solid #e4e4e7",
1664
- fontSize: "13px",
1665
- color: "#18181b",
1666
- backgroundColor: readOnly ? "#f4f4f5" : "#ffffff",
1667
- outline: "none",
1668
- boxSizing: "border-box"
1669
- },
1670
- className: "tecof-input-number"
1671
- }
1672
- ) });
1673
- case "radio":
1674
- return /* @__PURE__ */ jsxRuntime.jsx(FieldLabel, { label, readOnly, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: (definition.options || []).map((opt) => /* @__PURE__ */ jsxRuntime.jsxs(
1675
- "label",
1676
- {
1677
- style: {
1678
- display: "flex",
1679
- alignItems: "center",
1680
- gap: "8px",
1681
- fontSize: "13px",
1682
- color: "#27272a",
1683
- cursor: readOnly ? "not-allowed" : "pointer"
1684
- },
1685
- children: [
1686
- /* @__PURE__ */ jsxRuntime.jsx(
1687
- "input",
1688
- {
1689
- type: "radio",
1690
- name: name3,
1691
- value: opt.value,
1692
- checked: value === opt.value,
1693
- disabled: readOnly,
1694
- onChange: () => onChange(opt.value),
1695
- style: {
1696
- cursor: readOnly ? "not-allowed" : "pointer"
1697
- }
1698
- }
1699
- ),
1700
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: opt.label || opt.value })
1701
- ]
1702
- },
1703
- opt.value
1704
- )) }) });
2159
+ }
1705
2160
  default:
1706
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "8px", fontSize: "11px", color: "#71717a", background: "#fafafa", borderRadius: "4px" }, children: [
2161
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-field-unsupported", children: [
1707
2162
  'Desteklenmeyen alan t\xFCr\xFC: "',
1708
2163
  type,
1709
2164
  '" (',
@@ -1722,184 +2177,383 @@ var Inspector = () => {
1722
2177
  if (selectedId) {
1723
2178
  const nodeDetails = findNodeById(documentState, selectedId);
1724
2179
  if (!nodeDetails) {
1725
- return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "24px", color: "#71717a", fontSize: "13px", textAlign: "center" }, children: "Bile\u015Fen y\xFCkleniyor veya bulunamad\u0131." });
2180
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-inspector", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-inspector-empty", children: "Bile\u015Fen y\xFCkleniyor veya bulunamad\u0131." }) });
1726
2181
  }
1727
2182
  const { node } = nodeDetails;
1728
2183
  const componentConfig = config3.components[node.type];
1729
2184
  const fields = componentConfig?.fields || {};
1730
2185
  const label = componentConfig?.label || node.type;
1731
- return /* @__PURE__ */ jsxRuntime.jsxs(
2186
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-inspector", children: [
2187
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-inspector-header", children: [
2188
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2189
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "tecof-inspector-title", children: label }),
2190
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-inspector-id", children: selectedId })
2191
+ ] }),
2192
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => selectNode(null), className: "tecof-inspector-deselect", children: "Se\xE7imi Kald\u0131r" })
2193
+ ] }),
2194
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-inspector-fields", children: Object.keys(fields).length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-inspector-empty-fields", children: "Bu bile\u015Fenin d\xFCzenlenebilir alan\u0131 bulunmuyor." }) : Object.entries(fields).map(([fieldName, fieldDef]) => /* @__PURE__ */ jsxRuntime.jsx(
2195
+ FieldRenderer,
2196
+ {
2197
+ name: fieldName,
2198
+ definition: fieldDef,
2199
+ value: node.props[fieldName],
2200
+ onChange: (newVal) => updateProps2(selectedId, { [fieldName]: newVal }),
2201
+ readOnly
2202
+ },
2203
+ fieldName
2204
+ )) })
2205
+ ] });
2206
+ }
2207
+ const rootFields = config3.root?.fields || {};
2208
+ const hasRootFields = Object.keys(rootFields).length > 0;
2209
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-inspector", children: [
2210
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-inspector-header", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2211
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "tecof-inspector-title", children: "Sayfa Ayarlar\u0131" }),
2212
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-inspector-id", children: "Genel sayfa konfig\xFCrasyonu" })
2213
+ ] }) }),
2214
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-inspector-fields", children: hasRootFields ? Object.entries(rootFields).map(([fieldName, fieldDef]) => /* @__PURE__ */ jsxRuntime.jsx(
2215
+ FieldRenderer,
2216
+ {
2217
+ name: fieldName,
2218
+ definition: fieldDef,
2219
+ value: documentState.root.props[fieldName],
2220
+ onChange: (newVal) => setRootProps2({ [fieldName]: newVal }),
2221
+ readOnly
2222
+ },
2223
+ fieldName
2224
+ )) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-inspector-empty", children: [
2225
+ /* @__PURE__ */ jsxRuntime.jsxs(
2226
+ "svg",
2227
+ {
2228
+ width: "24",
2229
+ height: "24",
2230
+ viewBox: "0 0 24 24",
2231
+ fill: "none",
2232
+ stroke: "currentColor",
2233
+ strokeWidth: "2",
2234
+ strokeLinecap: "round",
2235
+ strokeLinejoin: "round",
2236
+ className: "tecof-inspector-empty-icon",
2237
+ children: [
2238
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2" }),
2239
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 3v18" })
2240
+ ]
2241
+ }
2242
+ ),
2243
+ "Bile\u015Fen se\xE7ilmedi. D\xFCzenlemek istedi\u011Finiz bir bile\u015Fene t\u0131klay\u0131n."
2244
+ ] }) })
2245
+ ] });
2246
+ };
2247
+ var TopBar = ({ onSave, saving, saveStatus }) => {
2248
+ const viewport = useEditorStore((state3) => state3.viewport);
2249
+ const setViewport = useEditorStore((state3) => state3.setViewport);
2250
+ const pastCount = useEditorStore((state3) => state3.history.past.length);
2251
+ const futureCount = useEditorStore((state3) => state3.history.future.length);
2252
+ const undo = useEditorStore((state3) => state3.undo);
2253
+ const redo = useEditorStore((state3) => state3.redo);
2254
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-topbar", children: [
2255
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-topbar-title", children: [
2256
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Sayfa D\xFCzenleyici" }),
2257
+ saveStatus === "success" && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "tecof-topbar-saved", children: [
2258
+ /* @__PURE__ */ jsxRuntime.jsx(Check, { size: 12 }),
2259
+ " Kaydedildi"
2260
+ ] })
2261
+ ] }),
2262
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-topbar-viewports", children: [
2263
+ /* @__PURE__ */ jsxRuntime.jsx(
2264
+ "button",
2265
+ {
2266
+ type: "button",
2267
+ onClick: () => setViewport("desktop"),
2268
+ className: `tecof-vp-btn${viewport === "desktop" ? " is-active" : ""}`,
2269
+ title: "Masa\xFCst\xFC",
2270
+ "aria-label": "Masa\xFCst\xFC g\xF6r\xFCn\xFCm\xFC",
2271
+ "aria-pressed": viewport === "desktop",
2272
+ children: /* @__PURE__ */ jsxRuntime.jsx(Monitor, { size: 16 })
2273
+ }
2274
+ ),
2275
+ /* @__PURE__ */ jsxRuntime.jsx(
2276
+ "button",
2277
+ {
2278
+ type: "button",
2279
+ onClick: () => setViewport("tablet"),
2280
+ className: `tecof-vp-btn${viewport === "tablet" ? " is-active" : ""}`,
2281
+ title: "Tablet",
2282
+ "aria-label": "Tablet g\xF6r\xFCn\xFCm\xFC",
2283
+ "aria-pressed": viewport === "tablet",
2284
+ children: /* @__PURE__ */ jsxRuntime.jsx(Tablet, { size: 16 })
2285
+ }
2286
+ ),
2287
+ /* @__PURE__ */ jsxRuntime.jsx(
2288
+ "button",
2289
+ {
2290
+ type: "button",
2291
+ onClick: () => setViewport("mobile"),
2292
+ className: `tecof-vp-btn${viewport === "mobile" ? " is-active" : ""}`,
2293
+ title: "Mobil",
2294
+ "aria-label": "Mobil g\xF6r\xFCn\xFCm\xFC",
2295
+ "aria-pressed": viewport === "mobile",
2296
+ children: /* @__PURE__ */ jsxRuntime.jsx(Smartphone, { size: 16 })
2297
+ }
2298
+ )
2299
+ ] }),
2300
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-topbar-actions", children: [
2301
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-topbar-undoredo", children: [
2302
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: undo, disabled: pastCount === 0, className: "tecof-icon-btn", title: "Geri Al", "aria-label": "Geri al", children: /* @__PURE__ */ jsxRuntime.jsx(Undo2, { size: 16 }) }),
2303
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: redo, disabled: futureCount === 0, className: "tecof-icon-btn", title: "Yinele", "aria-label": "Yinele", children: /* @__PURE__ */ jsxRuntime.jsx(Redo2, { size: 16 }) })
2304
+ ] }),
2305
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-topbar-divider" }),
2306
+ /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", onClick: onSave, disabled: saving, className: "tecof-btn-primary", "aria-busy": saving, children: [
2307
+ /* @__PURE__ */ jsxRuntime.jsx(Save, { size: 14 }),
2308
+ saving ? "Kaydediliyor..." : "Taslak Kaydet"
2309
+ ] })
2310
+ ] })
2311
+ ] });
2312
+ };
2313
+ var getLayerRowStyle = (depth) => ({ "--tecof-layer-indent": `${depth * 12 + 8}px` });
2314
+ var getLayerZoneStyle = (depth) => ({ "--tecof-layer-zone-indent": `${(depth + 1) * 12 + 14}px` });
2315
+ var TreeNode = ({ node, depth }) => {
2316
+ const { config: config3 } = useStudio();
2317
+ const documentState = useEditorStore((state3) => state3.document);
2318
+ const selectedId = useEditorStore((state3) => state3.selection.selectedId);
2319
+ const selectNode = useEditorStore((state3) => state3.selectNode);
2320
+ const hoverNode = useEditorStore((state3) => state3.hoverNode);
2321
+ const removeNode2 = useEditorStore((state3) => state3.removeNode);
2322
+ const beginDrag = useEditorStore((state3) => state3.beginDrag);
2323
+ const endDrag = useEditorStore((state3) => state3.endDrag);
2324
+ const [expanded, setExpanded] = React__default.useState(true);
2325
+ const [dragOverPos, setDragOverPos] = React__default.useState(null);
2326
+ const isSelected = selectedId === node.props.id;
2327
+ const componentConfig = config3.components[node.type];
2328
+ const label = componentConfig?.label || node.type;
2329
+ const childZoneKeys = Object.keys(documentState.zones).filter(
2330
+ (key) => key.startsWith(`${node.props.id}:`)
2331
+ );
2332
+ const hasChildren = childZoneKeys.some(
2333
+ (key) => (documentState.zones[key] || []).length > 0
2334
+ );
2335
+ const handleDragOver = (e3) => {
2336
+ e3.preventDefault();
2337
+ e3.stopPropagation();
2338
+ const rect = e3.currentTarget.getBoundingClientRect();
2339
+ const relativeY = e3.clientY - rect.top;
2340
+ setDragOverPos(relativeY < rect.height / 2 ? "top" : "bottom");
2341
+ };
2342
+ const handleDragLeave = () => {
2343
+ setDragOverPos(null);
2344
+ };
2345
+ const handleDrop = (e3) => {
2346
+ e3.preventDefault();
2347
+ e3.stopPropagation();
2348
+ setDragOverPos(null);
2349
+ const { nodeId: draggedId } = readDragData(e3);
2350
+ if (!draggedId || draggedId === node.props.id) return;
2351
+ const doc = useEditorStore.getState().document;
2352
+ const res2 = findNodeById(doc, node.props.id);
2353
+ if (!res2) return;
2354
+ const { path } = res2;
2355
+ const targetZoneKey = path.zoneKey;
2356
+ const targetIndex = dragOverPos === "top" ? path.index : path.index + 1;
2357
+ useEditorStore.getState().moveNode(draggedId, targetZoneKey, targetIndex);
2358
+ };
2359
+ const handleRowKeyDown = (e3) => {
2360
+ if (e3.key === "Enter" || e3.key === " ") {
2361
+ e3.preventDefault();
2362
+ selectNode(node.props.id);
2363
+ return;
2364
+ }
2365
+ if ((e3.key === "Delete" || e3.key === "Backspace") && isSelected) {
2366
+ e3.preventDefault();
2367
+ removeNode2(node.props.id);
2368
+ }
2369
+ };
2370
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-layer-node", children: [
2371
+ dragOverPos === "top" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-drop-line sm" }),
2372
+ /* @__PURE__ */ jsxRuntime.jsxs(
1732
2373
  "div",
1733
2374
  {
1734
- className: "tecof-inspector",
1735
- style: {
1736
- width: "320px",
1737
- height: "100%",
1738
- borderLeft: "1px solid #e4e4e7",
1739
- background: "#ffffff",
1740
- display: "flex",
1741
- flexDirection: "column",
1742
- boxSizing: "border-box"
2375
+ draggable: true,
2376
+ onDragStart: (e3) => {
2377
+ writeDragData(e3, { nodeId: node.props.id });
2378
+ e3.dataTransfer.effectAllowed = "move";
2379
+ setDragGhost(e3, label);
2380
+ beginDrag({ id: node.props.id });
1743
2381
  },
2382
+ onDragEnd: endDrag,
2383
+ onDragOver: handleDragOver,
2384
+ onDragLeave: handleDragLeave,
2385
+ onDrop: handleDrop,
2386
+ onMouseEnter: () => hoverNode(node.props.id),
2387
+ onMouseLeave: () => hoverNode(null),
2388
+ onClick: () => selectNode(node.props.id),
2389
+ onKeyDown: handleRowKeyDown,
2390
+ className: `tecof-layer-row${isSelected ? " is-selected" : ""}`,
2391
+ role: "treeitem",
2392
+ tabIndex: 0,
2393
+ "aria-selected": isSelected,
2394
+ "aria-expanded": hasChildren ? expanded : void 0,
2395
+ style: getLayerRowStyle(depth),
1744
2396
  children: [
1745
- /* @__PURE__ */ jsxRuntime.jsxs(
1746
- "div",
1747
- {
1748
- style: {
1749
- padding: "16px 20px",
1750
- borderBottom: "1px solid #f4f4f5",
1751
- display: "flex",
1752
- alignItems: "center",
1753
- justifyContent: "space-between"
1754
- },
1755
- children: [
1756
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1757
- /* @__PURE__ */ jsxRuntime.jsx("h3", { style: { margin: 0, fontSize: "14px", fontWeight: 700, color: "#18181b" }, children: label }),
1758
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "11px", color: "#a1a1aa", fontFamily: "monospace" }, children: selectedId })
1759
- ] }),
1760
- /* @__PURE__ */ jsxRuntime.jsx(
1761
- "button",
1762
- {
1763
- onClick: () => selectNode(null),
1764
- style: {
1765
- background: "transparent",
1766
- border: "none",
1767
- color: "#71717a",
1768
- cursor: "pointer",
1769
- fontSize: "11px",
1770
- fontWeight: 500,
1771
- padding: "4px 8px",
1772
- borderRadius: "4px",
1773
- hover: { background: "#f4f4f5" }
1774
- },
1775
- children: "Se\xE7imi Kald\u0131r"
1776
- }
1777
- )
1778
- ]
1779
- }
1780
- ),
2397
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-layer-row-main", children: [
2398
+ hasChildren ? /* @__PURE__ */ jsxRuntime.jsx(
2399
+ "button",
2400
+ {
2401
+ type: "button",
2402
+ onClick: (e3) => {
2403
+ e3.stopPropagation();
2404
+ setExpanded(!expanded);
2405
+ },
2406
+ className: "tecof-layer-caret",
2407
+ "aria-label": expanded ? `${label} katman\u0131n\u0131 daralt` : `${label} katman\u0131n\u0131 geni\u015Flet`,
2408
+ "aria-expanded": expanded,
2409
+ children: expanded ? /* @__PURE__ */ jsxRuntime.jsx(ChevronDown, { size: 14 }) : /* @__PURE__ */ jsxRuntime.jsx(ChevronRight, { size: 14 })
2410
+ }
2411
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-layer-caret-spacer" }),
2412
+ /* @__PURE__ */ jsxRuntime.jsx(PanelsTopLeft, { size: 14, className: "tecof-layer-icon" }),
2413
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-layer-label", children: label })
2414
+ ] }),
1781
2415
  /* @__PURE__ */ jsxRuntime.jsx(
1782
- "div",
2416
+ "button",
1783
2417
  {
1784
- className: "tecof-inspector-fields",
1785
- style: {
1786
- flex: 1,
1787
- overflowY: "auto",
1788
- padding: "20px",
1789
- display: "flex",
1790
- flexDirection: "column",
1791
- gap: "4px"
2418
+ type: "button",
2419
+ onClick: (e3) => {
2420
+ e3.stopPropagation();
2421
+ removeNode2(node.props.id);
1792
2422
  },
1793
- children: Object.keys(fields).length === 0 ? /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx(
1794
- FieldRenderer,
1795
- {
1796
- name: fieldName,
1797
- definition: fieldDef,
1798
- value: node.props[fieldName],
1799
- onChange: (newVal) => updateProps2(selectedId, { [fieldName]: newVal }),
1800
- readOnly
1801
- },
1802
- fieldName
1803
- ))
2423
+ className: "tecof-layer-delete",
2424
+ title: "Sil",
2425
+ "aria-label": `${label} katman\u0131n\u0131 sil`,
2426
+ children: /* @__PURE__ */ jsxRuntime.jsx(Trash2, { size: 12 })
1804
2427
  }
1805
2428
  )
1806
2429
  ]
1807
2430
  }
1808
- );
2431
+ ),
2432
+ dragOverPos === "bottom" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-drop-line sm" }),
2433
+ expanded && childZoneKeys.map((zoneKey) => {
2434
+ const zoneItems = documentState.zones[zoneKey] || [];
2435
+ const zoneName = zoneKey.split(":").pop() || "";
2436
+ if (zoneItems.length === 0) return null;
2437
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-layer-node", children: [
2438
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-layer-zone-label", style: getLayerZoneStyle(depth), children: zoneName }),
2439
+ zoneItems.map((childNode) => /* @__PURE__ */ jsxRuntime.jsx(TreeNode, { node: childNode, depth: depth + 1 }, childNode.props.id))
2440
+ ] }, zoneKey);
2441
+ })
2442
+ ] });
2443
+ };
2444
+ var LayersTree = () => {
2445
+ const documentState = useEditorStore((state3) => state3.document);
2446
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-layers", role: "tree", "aria-label": "Sayfa katmanlar\u0131", children: documentState.content.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-layers-empty", children: "S\xFCr\xFCklenmi\u015F katman yok" }) : documentState.content.map((node) => /* @__PURE__ */ jsxRuntime.jsx(TreeNode, { node, depth: 0 }, node.props.id)) });
2447
+ };
2448
+ var LeftPanel = () => {
2449
+ const { config: config3 } = useStudio();
2450
+ const insertNode2 = useEditorStore((state3) => state3.insertNode);
2451
+ const beginDrag = useEditorStore((state3) => state3.beginDrag);
2452
+ const endDrag = useEditorStore((state3) => state3.endDrag);
2453
+ const [activeTab, setActiveTab] = React__default.useState("blocks");
2454
+ const [searchQuery, setSearchQuery] = React__default.useState("");
2455
+ const categories = config3.categories || {};
2456
+ const components = config3.components || {};
2457
+ const groupedComponents = {};
2458
+ if (Object.keys(categories).length > 0) {
2459
+ Object.entries(categories).forEach(([key, value]) => {
2460
+ groupedComponents[value.title || key] = value.components;
2461
+ });
2462
+ } else {
2463
+ Object.entries(components).forEach(([name3, compConfig]) => {
2464
+ const cat = compConfig.category || "Genel";
2465
+ if (!groupedComponents[cat]) {
2466
+ groupedComponents[cat] = [];
2467
+ }
2468
+ groupedComponents[cat].push(name3);
2469
+ });
1809
2470
  }
1810
- const rootFields = config3.root?.fields || {};
1811
- const hasRootFields = Object.keys(rootFields).length > 0;
1812
- return /* @__PURE__ */ jsxRuntime.jsxs(
1813
- "div",
1814
- {
1815
- className: "tecof-inspector",
1816
- style: {
1817
- width: "320px",
1818
- height: "100%",
1819
- borderLeft: "1px solid #e4e4e7",
1820
- background: "#ffffff",
1821
- display: "flex",
1822
- flexDirection: "column",
1823
- boxSizing: "border-box"
1824
- },
1825
- children: [
1826
- /* @__PURE__ */ jsxRuntime.jsxs(
1827
- "div",
1828
- {
1829
- style: {
1830
- padding: "16px 20px",
1831
- borderBottom: "1px solid #f4f4f5"
1832
- },
1833
- children: [
1834
- /* @__PURE__ */ jsxRuntime.jsx("h3", { style: { margin: 0, fontSize: "14px", fontWeight: 700, color: "#18181b" }, children: "Sayfa Ayarlar\u0131" }),
1835
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "11px", color: "#a1a1aa" }, children: "Genel sayfa konfig\xFCrasyonu" })
1836
- ]
1837
- }
1838
- ),
2471
+ const handleAddBlock = (type) => {
2472
+ insertNode2(createNode(config3, type));
2473
+ };
2474
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-left-panel", children: [
2475
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-panel-tabs", role: "tablist", "aria-label": "Sol panel g\xF6r\xFCn\xFCm\xFC", children: [
2476
+ /* @__PURE__ */ jsxRuntime.jsxs(
2477
+ "button",
2478
+ {
2479
+ type: "button",
2480
+ onClick: () => setActiveTab("blocks"),
2481
+ className: `tecof-tab${activeTab === "blocks" ? " is-active" : ""}`,
2482
+ role: "tab",
2483
+ "aria-selected": activeTab === "blocks",
2484
+ children: [
2485
+ /* @__PURE__ */ jsxRuntime.jsx(Grid3x3, { size: 14 }),
2486
+ "Blok Ekle"
2487
+ ]
2488
+ }
2489
+ ),
2490
+ /* @__PURE__ */ jsxRuntime.jsxs(
2491
+ "button",
2492
+ {
2493
+ type: "button",
2494
+ onClick: () => setActiveTab("layers"),
2495
+ className: `tecof-tab${activeTab === "layers" ? " is-active" : ""}`,
2496
+ role: "tab",
2497
+ "aria-selected": activeTab === "layers",
2498
+ children: [
2499
+ /* @__PURE__ */ jsxRuntime.jsx(Layers, { size: 14 }),
2500
+ "Katmanlar"
2501
+ ]
2502
+ }
2503
+ )
2504
+ ] }),
2505
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-panel-body", children: activeTab === "blocks" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-blocks", children: [
2506
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-search", children: [
2507
+ /* @__PURE__ */ jsxRuntime.jsx(Search, { size: 14, className: "tecof-icon-muted" }),
1839
2508
  /* @__PURE__ */ jsxRuntime.jsx(
1840
- "div",
2509
+ "input",
1841
2510
  {
1842
- className: "tecof-inspector-fields",
1843
- style: {
1844
- flex: 1,
1845
- overflowY: "auto",
1846
- padding: "20px",
1847
- display: "flex",
1848
- flexDirection: "column",
1849
- gap: "4px"
1850
- },
1851
- children: hasRootFields ? Object.entries(rootFields).map(([fieldName, fieldDef]) => /* @__PURE__ */ jsxRuntime.jsx(
1852
- FieldRenderer,
1853
- {
1854
- name: fieldName,
1855
- definition: fieldDef,
1856
- value: documentState.root.props[fieldName],
1857
- onChange: (newVal) => setRootProps2({ [fieldName]: newVal }),
1858
- readOnly
1859
- },
1860
- fieldName
1861
- )) : /* @__PURE__ */ jsxRuntime.jsxs(
1862
- "div",
2511
+ type: "text",
2512
+ placeholder: "Bile\u015Fen ara...",
2513
+ value: searchQuery,
2514
+ onChange: (e3) => setSearchQuery(e3.target.value),
2515
+ className: "tecof-search-input"
2516
+ }
2517
+ )
2518
+ ] }),
2519
+ Object.entries(groupedComponents).map(([catTitle, blockTypes]) => {
2520
+ const filteredTypes = blockTypes.filter((type) => {
2521
+ const label = components[type]?.label || type;
2522
+ return label.toLowerCase().includes(searchQuery.toLowerCase());
2523
+ });
2524
+ if (filteredTypes.length === 0) return null;
2525
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-block-cat", children: [
2526
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-block-cat-title", children: catTitle }),
2527
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-block-grid", children: filteredTypes.map((type) => {
2528
+ const compConfig = components[type] || {};
2529
+ const label = compConfig.label || type;
2530
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2531
+ "button",
1863
2532
  {
1864
- style: {
1865
- display: "flex",
1866
- flexDirection: "column",
1867
- alignItems: "center",
1868
- justifyContent: "center",
1869
- height: "100%",
1870
- color: "#a1a1aa",
1871
- fontSize: "12px",
1872
- textAlign: "center",
1873
- padding: "20px"
2533
+ type: "button",
2534
+ onClick: () => handleAddBlock(type),
2535
+ draggable: true,
2536
+ onDragStart: (e3) => {
2537
+ writeDragData(e3, { type });
2538
+ e3.dataTransfer.effectAllowed = "copy";
2539
+ setDragGhost(e3, label);
2540
+ beginDrag({ type });
1874
2541
  },
2542
+ onDragEnd: endDrag,
2543
+ className: "tecof-block-btn",
2544
+ title: `${label} ekle`,
1875
2545
  children: [
1876
- /* @__PURE__ */ jsxRuntime.jsxs(
1877
- "svg",
1878
- {
1879
- width: "24",
1880
- height: "24",
1881
- viewBox: "0 0 24 24",
1882
- fill: "none",
1883
- stroke: "currentColor",
1884
- strokeWidth: "2",
1885
- strokeLinecap: "round",
1886
- strokeLinejoin: "round",
1887
- style: { marginBottom: "8px", opacity: 0.6 },
1888
- children: [
1889
- /* @__PURE__ */ jsxRuntime.jsx("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2" }),
1890
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 3v18" })
1891
- ]
1892
- }
1893
- ),
1894
- "Bile\u015Fen se\xE7ilmedi. D\xFCzenlemek istedi\u011Finiz bir bile\u015Fene t\u0131klay\u0131n."
2546
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: label }),
2547
+ /* @__PURE__ */ jsxRuntime.jsx(Plus, { size: 14, className: "tecof-block-btn-icon" })
1895
2548
  ]
1896
- }
1897
- )
1898
- }
1899
- )
1900
- ]
1901
- }
1902
- );
2549
+ },
2550
+ type
2551
+ );
2552
+ }) })
2553
+ ] }, catTitle);
2554
+ })
2555
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(LayersTree, {}) })
2556
+ ] });
1903
2557
  };
1904
2558
  var TecofStudio = ({
1905
2559
  pageId,
@@ -1967,7 +2621,7 @@ var TecofStudio = ({
1967
2621
  setTimeout(() => setSaveStatus("idle"), 3e3);
1968
2622
  onSave?.(serialized);
1969
2623
  if (isEmbedded) {
1970
- window.parent.postMessage({ type: "puck:saved" }, "*");
2624
+ window.parent.postMessage({ type: "puck:saved", data: serialized }, "*");
1971
2625
  }
1972
2626
  } else {
1973
2627
  setSaveStatus("error");
@@ -1989,6 +2643,7 @@ var TecofStudio = ({
1989
2643
  const onMessage = (e3) => {
1990
2644
  switch (e3.data?.type) {
1991
2645
  case "puck:save":
2646
+ case "puck:publish":
1992
2647
  handleSaveDraft();
1993
2648
  break;
1994
2649
  case "puck:undo":
@@ -2014,74 +2669,117 @@ var TecofStudio = ({
2014
2669
  window.addEventListener("message", onMessage);
2015
2670
  return () => window.removeEventListener("message", onMessage);
2016
2671
  }, [isEmbedded, handleSaveDraft, undo, redo, setViewport]);
2672
+ React__default.useEffect(() => {
2673
+ const handleKeyDown = (e3) => {
2674
+ const isInput2 = () => {
2675
+ const activeEl = document.activeElement;
2676
+ if (activeEl) {
2677
+ const tag = activeEl.tagName.toLowerCase();
2678
+ if (tag === "input" || tag === "textarea" || activeEl.hasAttribute("contenteditable")) {
2679
+ return true;
2680
+ }
2681
+ }
2682
+ const iframe = document.querySelector(".tecof-canvas-viewport iframe");
2683
+ const iframeDoc = iframe?.contentDocument;
2684
+ const iframeActiveEl = iframeDoc?.activeElement;
2685
+ if (iframeActiveEl) {
2686
+ const tag = iframeActiveEl.tagName.toLowerCase();
2687
+ if (tag === "input" || tag === "textarea" || iframeActiveEl.hasAttribute("contenteditable")) {
2688
+ return true;
2689
+ }
2690
+ }
2691
+ return false;
2692
+ };
2693
+ const selectedId = useEditorStore.getState().selection.selectedId;
2694
+ const isCmdOrCtrl = e3.metaKey || e3.ctrlKey;
2695
+ if (e3.key === "Escape") {
2696
+ useEditorStore.getState().selectNode(null);
2697
+ if (isEmbedded) {
2698
+ window.parent.postMessage({ type: "puck:itemDeselected" }, "*");
2699
+ }
2700
+ return;
2701
+ }
2702
+ if (isCmdOrCtrl && e3.key.toLowerCase() === "z") {
2703
+ e3.preventDefault();
2704
+ if (e3.shiftKey) {
2705
+ redo();
2706
+ } else {
2707
+ undo();
2708
+ }
2709
+ return;
2710
+ }
2711
+ if (isCmdOrCtrl && e3.key.toLowerCase() === "y") {
2712
+ e3.preventDefault();
2713
+ redo();
2714
+ return;
2715
+ }
2716
+ if (isInput2()) return;
2717
+ if ((e3.key === "Delete" || e3.key === "Backspace") && selectedId) {
2718
+ e3.preventDefault();
2719
+ useEditorStore.getState().removeNode(selectedId);
2720
+ return;
2721
+ }
2722
+ if (isCmdOrCtrl && e3.key.toLowerCase() === "d" && selectedId) {
2723
+ e3.preventDefault();
2724
+ useEditorStore.getState().duplicateNode(selectedId);
2725
+ return;
2726
+ }
2727
+ };
2728
+ window.addEventListener("keydown", handleKeyDown);
2729
+ return () => {
2730
+ window.removeEventListener("keydown", handleKeyDown);
2731
+ };
2732
+ }, [undo, redo, isEmbedded]);
2017
2733
  const studioContextValue = React__default.useMemo(() => ({
2018
2734
  config: config3,
2019
2735
  readOnly: false,
2020
2736
  apiClient
2021
2737
  }), [config3, apiClient]);
2022
2738
  if (loading) {
2023
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `tecof-editor-loading ${className || ""}`.trim(), style: {
2024
- display: "flex",
2025
- alignItems: "center",
2026
- justifyContent: "center",
2027
- height: "100vh",
2028
- background: "#f4f4f5"
2029
- }, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { textAlign: "center" }, children: [
2030
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-editor-spinner", style: {
2031
- width: "40px",
2032
- height: "40px",
2033
- border: "3px solid #e4e4e7",
2034
- borderTopColor: "#3b82f6",
2035
- borderRadius: "50%",
2036
- animation: "spin 1s linear infinite",
2037
- margin: "0 auto 16px"
2038
- } }),
2039
- /* @__PURE__ */ jsxRuntime.jsx("p", { style: { color: "#71717a", fontSize: "14px", margin: 0 }, children: "St\xFCdyo y\xFCkleniyor..." })
2040
- ] }) });
2041
- }
2042
- return /* @__PURE__ */ jsxRuntime.jsx(StudioContext.Provider, { value: studioContextValue, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `tecof-studio-root ${className || ""}`.trim(), style: {
2043
- display: "flex",
2044
- flexDirection: "column",
2045
- height: "100vh",
2046
- width: "100vw",
2047
- overflow: "hidden",
2048
- position: "relative",
2049
- background: "#f4f4f5"
2050
- }, children: [
2051
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-studio-workspace-container", style: {
2052
- display: "flex",
2053
- flex: 1,
2054
- height: "100%",
2055
- width: "100%",
2056
- overflow: "hidden"
2057
- }, children: [
2058
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-studio-workspace", style: {
2059
- display: "flex",
2060
- flex: 1,
2061
- height: "100%",
2062
- position: "relative",
2063
- overflow: "hidden"
2064
- }, children: [
2739
+ return /* @__PURE__ */ jsxRuntime.jsx(StudioSkeleton, { className });
2740
+ }
2741
+ return /* @__PURE__ */ jsxRuntime.jsx(StudioContext.Provider, { value: studioContextValue, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `tecof-studio-root ${className || ""}`.trim(), children: [
2742
+ /* @__PURE__ */ jsxRuntime.jsx(TopBar, { onSave: handleSaveDraft, saving, saveStatus }),
2743
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-studio-workspace-container", children: [
2744
+ /* @__PURE__ */ jsxRuntime.jsx(LeftPanel, {}),
2745
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-studio-workspace", children: [
2065
2746
  /* @__PURE__ */ jsxRuntime.jsx(Canvas, {}),
2066
2747
  /* @__PURE__ */ jsxRuntime.jsx(SelectionOverlay, {})
2067
2748
  ] }),
2068
2749
  /* @__PURE__ */ jsxRuntime.jsx(Inspector, {})
2069
2750
  ] }),
2070
- saving && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-editor-save-indicator", style: {
2071
- position: "absolute",
2072
- bottom: "24px",
2073
- right: "24px",
2074
- background: saveStatus === "error" ? "#ef4444" : "#18181b",
2075
- color: "#ffffff",
2076
- padding: "8px 16px",
2077
- borderRadius: "24px",
2078
- fontSize: "12px",
2079
- fontWeight: 500,
2080
- boxShadow: "0 4px 6px -1px rgba(0, 0, 0, 0.1)",
2081
- zIndex: 9999
2082
- }, children: saveStatus === "error" ? "Kaydedilemedi" : "Kaydediliyor..." })
2751
+ saving && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `tecof-studio-save-indicator${saveStatus === "error" ? " is-error" : ""}`, children: saveStatus === "error" ? "Kaydedilemedi" : "Kaydediliyor..." })
2083
2752
  ] }) });
2084
2753
  };
2754
+ var StudioSkeleton = ({ className }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `tecof-studio-skeleton ${className || ""}`.trim(), "aria-busy": "true", "aria-label": "St\xFCdyo y\xFCkleniyor", children: [
2755
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-studio-skeleton-topbar", children: [
2756
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-skeleton tecof-studio-skeleton-title" }),
2757
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-skeleton tecof-studio-skeleton-vp" }),
2758
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-studio-skeleton-toolgroup", children: [
2759
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-skeleton tecof-studio-skeleton-dot" }),
2760
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-skeleton tecof-studio-skeleton-dot" }),
2761
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-skeleton tecof-studio-skeleton-cta" })
2762
+ ] })
2763
+ ] }),
2764
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-studio-skeleton-body", children: [
2765
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-studio-skeleton-side", children: [
2766
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-skeleton tecof-studio-skeleton-search" }),
2767
+ Array.from({ length: 6 }).map((_2, i2) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-skeleton tecof-studio-skeleton-blockrow" }, i2))
2768
+ ] }),
2769
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-studio-skeleton-canvas", children: [
2770
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-skeleton tecof-skeleton-block" }),
2771
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-skeleton tecof-skeleton-block" }),
2772
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-skeleton tecof-skeleton-block" })
2773
+ ] }),
2774
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-studio-skeleton-side right", children: [
2775
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-skeleton tecof-skeleton-text w-60" }),
2776
+ Array.from({ length: 5 }).map((_2, i2) => /* @__PURE__ */ jsxRuntime.jsxs(React__default__namespace.default.Fragment, { children: [
2777
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-skeleton tecof-skeleton-text sm w-40" }),
2778
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-skeleton tecof-studio-skeleton-field" })
2779
+ ] }, i2))
2780
+ ] })
2781
+ ] })
2782
+ ] });
2085
2783
 
2086
2784
  // src/components/TecofEditor.tsx
2087
2785
  var TecofEditor = TecofStudio;
@@ -2121,7 +2819,15 @@ var TecofRender = ({ data: data3, config: config3, className, cmsData }) => {
2121
2819
  config: config3,
2122
2820
  cmsData: cmsData || null
2123
2821
  };
2124
- return /* @__PURE__ */ jsxRuntime.jsx(RenderContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className, children: data3.content.map((item2, index2) => /* @__PURE__ */ jsxRuntime.jsx(RenderNode, { node: item2, index: index2 }, item2.props.id || index2)) }) });
2822
+ const renderedContent = data3.content.map((item2, index2) => /* @__PURE__ */ jsxRuntime.jsx(RenderNode, { node: item2, index: index2 }, item2.props.id || index2));
2823
+ const rootProps = data3.root?.props || {};
2824
+ const rootConfig = config3.root;
2825
+ const contentWithLayout = rootConfig?.render ? rootConfig.render({
2826
+ ...rootProps,
2827
+ children: renderedContent,
2828
+ editMode: false
2829
+ }) : renderedContent;
2830
+ return /* @__PURE__ */ jsxRuntime.jsx(RenderContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className, children: contentWithLayout }) });
2125
2831
  };
2126
2832
  var IMAGE_EXTENSIONS = ["png", "jpg", "jpeg", "webp", "gif", "svg", "avif", "bmp", "tiff", "heic"];
2127
2833
  var VIDEO_EXTENSIONS = ["mp4", "webm", "ogg", "avi", "mov", "quicktime"];
@@ -2231,7 +2937,7 @@ var TecofPicture = React__default.memo(({
2231
2937
  {
2232
2938
  "data-fancybox": fancyboxName,
2233
2939
  href: fileURL,
2234
- style: { display: "block", textDecoration: "none" },
2940
+ className: "tecof-picture-link",
2235
2941
  children: /* @__PURE__ */ jsxRuntime.jsx("div", { style, className: containerClassName, children: isVideoType ? renderVideo() : renderImg() })
2236
2942
  }
2237
2943
  );
@@ -2589,10 +3295,15 @@ var LanguageTabBar = ({
2589
3295
  code
2590
3296
  )) });
2591
3297
  };
2592
- var FieldLoading = () => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-lang-loading", children: [
2593
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-lang-loading-dot" }),
2594
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-lang-loading-dot" }),
2595
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-lang-loading-dot" })
3298
+ var FieldLoading = () => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-field-loading", "aria-busy": "true", children: [
3299
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-field-loading-row", children: [
3300
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-skeleton tecof-skeleton-circle tecof-field-loading-thumb" }),
3301
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-field-loading-lines", children: [
3302
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-skeleton tecof-skeleton-text w-60" }),
3303
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-skeleton tecof-skeleton-text sm w-80" })
3304
+ ] })
3305
+ ] }),
3306
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-skeleton tecof-skeleton-block tecof-studio-skeleton-field" })
2596
3307
  ] });
2597
3308
  var StableInput = ({
2598
3309
  value: externalValue,
@@ -6379,7 +7090,7 @@ var MediaDrawer = ({
6379
7090
  ] })
6380
7091
  ] }),
6381
7092
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-upload-search-box", children: [
6382
- /* @__PURE__ */ jsxRuntime.jsx(Search, { size: 15, color: "#a1a1aa" }),
7093
+ /* @__PURE__ */ jsxRuntime.jsx(Search, { size: 15, className: "tecof-icon-muted" }),
6383
7094
  /* @__PURE__ */ jsxRuntime.jsx(
6384
7095
  "input",
6385
7096
  {
@@ -6400,11 +7111,11 @@ var MediaDrawer = ({
6400
7111
  }
6401
7112
  )
6402
7113
  ] }),
6403
- loading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-upload-gallery-empty", children: [
6404
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-upload-gallery-empty-icon", children: /* @__PURE__ */ jsxRuntime.jsx(RefreshCcw, { size: 24, color: "#a1a1aa", className: "tecof-upload-spin" }) }),
6405
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "tecof-upload-loading-text", children: "Y\xFCkleniyor..." })
6406
- ] }) : filteredGallery.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-upload-gallery-empty", children: [
6407
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-upload-gallery-empty-icon", children: /* @__PURE__ */ jsxRuntime.jsx(Image2, { size: 24, color: "#a1a1aa" }) }),
7114
+ loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-media-skeleton-grid", "aria-busy": "true", children: Array.from({ length: 8 }).map((_2, index2) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-media-skeleton-card", children: [
7115
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-skeleton tecof-skeleton-block tecof-media-skeleton-thumb" }),
7116
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-skeleton tecof-skeleton-text w-80" })
7117
+ ] }, index2)) }) : filteredGallery.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-upload-gallery-empty", children: [
7118
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-upload-gallery-empty-icon", children: /* @__PURE__ */ jsxRuntime.jsx(Image2, { size: 24, className: "tecof-icon-muted" }) }),
6408
7119
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "tecof-upload-empty-heading", children: gallerySearch ? "Sonu\xE7 bulunamad\u0131" : "Hen\xFCz dosya yok" }),
6409
7120
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "tecof-upload-empty-subheading", children: gallerySearch ? "Farkl\u0131 bir arama terimi deneyin" : "Dosyalar\u0131n\u0131z burada g\xF6r\xFCnecek" })
6410
7121
  ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-upload-gallery-grid", children: filteredGallery.map((file2) => {
@@ -6422,10 +7133,9 @@ var MediaDrawer = ({
6422
7133
  data: file2,
6423
7134
  alt: file2.name,
6424
7135
  size: "thumbnail",
6425
- className: "tecof-upload-gallery-thumb",
6426
- imgStyle: { width: "100%", height: "100%", objectFit: "cover", borderRadius: "8px" }
7136
+ className: "tecof-upload-gallery-thumb"
6427
7137
  }
6428
- ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-upload-gallery-thumb tecof-upload-gallery-file-icon-wrap", children: /* @__PURE__ */ jsxRuntime.jsx(File2, { size: 24, color: "#a1a1aa" }) }),
7138
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-upload-gallery-thumb tecof-upload-gallery-file-icon-wrap", children: /* @__PURE__ */ jsxRuntime.jsx(File2, { size: 24, className: "tecof-icon-muted" }) }),
6429
7139
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "tecof-upload-gallery-file-name", children: file2.meta?.originalName || file2.name })
6430
7140
  ]
6431
7141
  },
@@ -24301,14 +25011,13 @@ var FileItemRenderer = ({
24301
25011
  `${cdnUrl}/${file2.name}`;
24302
25012
  const ext = getFileExtension(file2.name);
24303
25013
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-upload-file-item", children: [
24304
- file2.type === "image/reference" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-upload-file-icon", style: { backgroundColor: "#f4f4f5", color: "#18181b" }, children: /* @__PURE__ */ jsxRuntime.jsx(Code, { size: 16 }) }) : isImageType2(file2.type) ? /* @__PURE__ */ jsxRuntime.jsx(
25014
+ file2.type === "image/reference" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-upload-file-icon is-reference", children: /* @__PURE__ */ jsxRuntime.jsx(Code, { size: 16 }) }) : isImageType2(file2.type) ? /* @__PURE__ */ jsxRuntime.jsx(
24305
25015
  TecofPicture,
24306
25016
  {
24307
25017
  data: file2,
24308
25018
  alt: file2.meta?.originalName || file2.name,
24309
25019
  size: "thumbnail",
24310
- className: "tecof-upload-file-thumb",
24311
- imgStyle: { width: "100%", height: "100%", objectFit: "cover", borderRadius: "6px" }
25020
+ className: "tecof-upload-file-thumb"
24312
25021
  }
24313
25022
  ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-upload-file-icon", children: /* @__PURE__ */ jsxRuntime.jsx(File2, { size: 16 }) }),
24314
25023
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-upload-file-info", children: [
@@ -24622,12 +25331,12 @@ var UploadField = ({
24622
25331
  " Y\xFCkle"
24623
25332
  ] })
24624
25333
  ] }),
24625
- showRefInput && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-upload-ref-section", style: { background: "#ffffff", padding: "10px", borderRadius: "8px", border: "1px solid #e4e4e7", display: "flex", flexDirection: "column", gap: "8px", marginTop: "4px" }, children: [
24626
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
24627
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "11px", fontWeight: 500, color: "#71717a" }, children: "Dinamik CMS De\u011Fi\u015Fkeni" }),
24628
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => setShowRefInput(false), style: { background: "none", border: "none", cursor: "pointer", color: "#a1a1aa", padding: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx(X, { size: 12 }) })
25334
+ showRefInput && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-upload-ref-section", children: [
25335
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-upload-ref-header", children: [
25336
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-upload-ref-title", children: "Dinamik CMS De\u011Fi\u015Fkeni" }),
25337
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => setShowRefInput(false), className: "tecof-upload-ref-close", title: "Kapat", children: /* @__PURE__ */ jsxRuntime.jsx(X, { size: 12 }) })
24629
25338
  ] }),
24630
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: "6px" }, children: [
25339
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-upload-ref-row", children: [
24631
25340
  /* @__PURE__ */ jsxRuntime.jsx(
24632
25341
  "input",
24633
25342
  {
@@ -24635,7 +25344,7 @@ var UploadField = ({
24635
25344
  value: refCode,
24636
25345
  onChange: (e3) => setRefCode(e3.target.value),
24637
25346
  placeholder: "{{ data. }}",
24638
- style: { flex: 1, padding: "6px 8px", fontSize: "12px", borderRadius: "6px", border: "1px solid #cbd5e1", outline: "none" },
25347
+ className: "tecof-upload-ref-input",
24639
25348
  autoFocus: true,
24640
25349
  onKeyDown: (e3) => {
24641
25350
  if (e3.key === "Enter") {
@@ -24650,7 +25359,7 @@ var UploadField = ({
24650
25359
  {
24651
25360
  type: "button",
24652
25361
  onClick: handleAddRef,
24653
- style: { padding: "0 10px", background: "#18181b", color: "#fff", fontSize: "11px", fontWeight: 500, borderRadius: "6px", border: "none", cursor: "pointer" },
25362
+ className: "tecof-upload-ref-add",
24654
25363
  children: "Ekle"
24655
25364
  }
24656
25365
  )
@@ -25539,7 +26248,7 @@ var LinkField = ({
25539
26248
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "tecof-link-value-url", children: activeValue.url })
25540
26249
  ] }),
25541
26250
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: `tecof-link-value-badge ${activeValue.type === "page" ? "tecof-link-badge-page" : "tecof-link-badge-custom"}`, children: activeValue.type === "page" ? "Sayfa" : "Link" }),
25542
- activeValue.target === "_blank" && /* @__PURE__ */ jsxRuntime.jsx(ExternalLink, { size: 14, color: "#a1a1aa" }),
26251
+ activeValue.target === "_blank" && /* @__PURE__ */ jsxRuntime.jsx(ExternalLink, { size: 14, className: "tecof-icon-muted" }),
25543
26252
  !readOnly && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
25544
26253
  /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "tecof-link-action-btn-small", onClick: handleEditManual, title: "D\xFCzenle", children: /* @__PURE__ */ jsxRuntime.jsx(Pencil, { size: 14 }) }),
25545
26254
  /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "tecof-link-action-btn-small", onClick: handleClear, title: "Kald\u0131r", children: /* @__PURE__ */ jsxRuntime.jsx(X, { size: 14 }) })
@@ -25612,7 +26321,7 @@ var LinkField = ({
25612
26321
  /* @__PURE__ */ jsxRuntime.jsx("button", { className: "tecof-link-drawer-close-btn", onClick: () => setDrawerOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(X, { size: 16 }) })
25613
26322
  ] }),
25614
26323
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-link-search-box", children: [
25615
- /* @__PURE__ */ jsxRuntime.jsx(Search, { size: 16, color: "#a1a1aa" }),
26324
+ /* @__PURE__ */ jsxRuntime.jsx(Search, { size: 16, className: "tecof-icon-muted" }),
25616
26325
  /* @__PURE__ */ jsxRuntime.jsx(
25617
26326
  "input",
25618
26327
  {
@@ -25624,7 +26333,13 @@ var LinkField = ({
25624
26333
  }
25625
26334
  )
25626
26335
  ] }),
25627
- loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-text-center tecof-p-40 tecof-text-muted", children: "Y\xFCkleniyor..." }) : filteredPages.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-text-center tecof-p-40 tecof-text-muted", children: search ? "Sonu\xE7 bulunamad\u0131" : "Hen\xFCz sayfa yok" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-link-page-list", children: filteredPages.map((page) => {
26336
+ loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-field-loading", "aria-busy": "true", children: [0, 1, 2].map((item2) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-field-loading-row", children: [
26337
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-skeleton tecof-skeleton-circle tecof-field-loading-thumb" }),
26338
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-field-loading-lines", children: [
26339
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-skeleton tecof-skeleton-text w-60" }),
26340
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-skeleton tecof-skeleton-text sm w-80" })
26341
+ ] })
26342
+ ] }, item2)) }) : filteredPages.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-text-center tecof-p-40 tecof-text-muted", children: search ? "Sonu\xE7 bulunamad\u0131" : "Hen\xFCz sayfa yok" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-link-page-list", children: filteredPages.map((page) => {
25628
26343
  const selected = activeValue?.url === `/${page.slug}`;
25629
26344
  return /* @__PURE__ */ jsxRuntime.jsxs(
25630
26345
  "div",
@@ -25640,7 +26355,7 @@ var LinkField = ({
25640
26355
  ] }),
25641
26356
  page.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "tecof-link-page-title", children: page.title })
25642
26357
  ] }),
25643
- /* @__PURE__ */ jsxRuntime.jsx(ChevronRight, { size: 16, color: "#d4d4d8" })
26358
+ /* @__PURE__ */ jsxRuntime.jsx(ChevronRight, { size: 16, className: "tecof-icon-faint" })
25644
26359
  ]
25645
26360
  },
25646
26361
  page._id
@@ -25791,7 +26506,7 @@ var ColorField = ({
25791
26506
  "div",
25792
26507
  {
25793
26508
  className: `tecof-color-swatch ${focused ? "focused" : ""}`,
25794
- style: { background: isValid && currentColor ? currentColor : "#ffffff" },
26509
+ style: { background: isValid && currentColor ? currentColor : "var(--tecof-surface)" },
25795
26510
  children: !readOnly && /* @__PURE__ */ jsxRuntime.jsx(
25796
26511
  "input",
25797
26512
  {
@@ -26274,9 +26989,9 @@ var CmsCollectionField = ({
26274
26989
  );
26275
26990
  }, [collections, searchQuery]);
26276
26991
  if (loading) {
26277
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-cms-col-loading", children: [
26278
- /* @__PURE__ */ jsxRuntime.jsx(LoaderCircle, { size: 16, className: "tecof-spin" }),
26279
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Koleksiyonlar y\xFCkleniyor\u2026" })
26992
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-cms-col-loading tecof-field-loading-compact", "aria-busy": "true", children: [
26993
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-skeleton tecof-skeleton-circle" }),
26994
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tecof-skeleton tecof-skeleton-text w-60" })
26280
26995
  ] });
26281
26996
  }
26282
26997
  if (error2) {
@@ -26482,9 +27197,9 @@ var createCmsCollectionField = (options = {}) => {
26482
27197
  function hexToHsl(hex) {
26483
27198
  const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
26484
27199
  if (!result) return { h: 0, s: 0, l: 0 };
26485
- let r2 = parseInt(result[1], 16) / 255;
26486
- let g = parseInt(result[2], 16) / 255;
26487
- let b = parseInt(result[3], 16) / 255;
27200
+ const r2 = parseInt(result[1], 16) / 255;
27201
+ const g = parseInt(result[2], 16) / 255;
27202
+ const b = parseInt(result[3], 16) / 255;
26488
27203
  const max = Math.max(r2, g, b);
26489
27204
  const min = Math.min(r2, g, b);
26490
27205
  let h2 = 0;
@@ -26649,20 +27364,29 @@ lucide-react/dist/esm/icons/file-text.js:
26649
27364
  lucide-react/dist/esm/icons/file.js:
26650
27365
  lucide-react/dist/esm/icons/folder-open.js:
26651
27366
  lucide-react/dist/esm/icons/globe.js:
27367
+ lucide-react/dist/esm/icons/grid-3x3.js:
26652
27368
  lucide-react/dist/esm/icons/grip-vertical.js:
26653
27369
  lucide-react/dist/esm/icons/image-plus.js:
26654
27370
  lucide-react/dist/esm/icons/image.js:
26655
27371
  lucide-react/dist/esm/icons/languages.js:
27372
+ lucide-react/dist/esm/icons/layers.js:
26656
27373
  lucide-react/dist/esm/icons/link-2.js:
26657
27374
  lucide-react/dist/esm/icons/link.js:
26658
27375
  lucide-react/dist/esm/icons/loader-circle.js:
27376
+ lucide-react/dist/esm/icons/monitor.js:
27377
+ lucide-react/dist/esm/icons/panels-top-left.js:
26659
27378
  lucide-react/dist/esm/icons/pencil.js:
26660
27379
  lucide-react/dist/esm/icons/plus.js:
27380
+ lucide-react/dist/esm/icons/redo-2.js:
26661
27381
  lucide-react/dist/esm/icons/refresh-ccw.js:
26662
27382
  lucide-react/dist/esm/icons/refresh-cw.js:
26663
27383
  lucide-react/dist/esm/icons/rotate-ccw.js:
27384
+ lucide-react/dist/esm/icons/save.js:
26664
27385
  lucide-react/dist/esm/icons/search.js:
27386
+ lucide-react/dist/esm/icons/smartphone.js:
27387
+ lucide-react/dist/esm/icons/tablet.js:
26665
27388
  lucide-react/dist/esm/icons/trash-2.js:
27389
+ lucide-react/dist/esm/icons/undo-2.js:
26666
27390
  lucide-react/dist/esm/icons/upload.js:
26667
27391
  lucide-react/dist/esm/icons/x.js:
26668
27392
  lucide-react/dist/esm/lucide-react.js: