@tecof/theme-editor 0.0.37 → 0.0.39

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
@@ -507,7 +507,7 @@ var setRootProps = (draft, patch) => {
507
507
 
508
508
  // src/engine/store.ts
509
509
  var pushToHistory = (state3) => {
510
- state3.history.past.push(JSON.parse(JSON.stringify(state3.document)));
510
+ state3.history.past.push(state3.document);
511
511
  state3.history.future = [];
512
512
  };
513
513
  var useEditorStore = zustand.create()(
@@ -568,13 +568,13 @@ var useEditorStore = zustand.create()(
568
568
  undo: () => set2((state3) => {
569
569
  if (state3.history.past.length === 0) return;
570
570
  const previous = state3.history.past.pop();
571
- state3.history.future.push(JSON.parse(JSON.stringify(state3.document)));
571
+ state3.history.future.push(state3.document);
572
572
  state3.document = previous;
573
573
  }),
574
574
  redo: () => set2((state3) => {
575
575
  if (state3.history.future.length === 0) return;
576
576
  const next = state3.history.future.pop();
577
- state3.history.past.push(JSON.parse(JSON.stringify(state3.document)));
577
+ state3.history.past.push(state3.document);
578
578
  state3.document = next;
579
579
  })
580
580
  }))
@@ -650,6 +650,44 @@ var NodeRenderer = ({ node, index: index2, zoneKey }) => {
650
650
  },
651
651
  [selectNode, node.props.id, node.type, readOnly]
652
652
  );
653
+ const handleDoubleClick = React__default.useCallback(
654
+ (e3) => {
655
+ if (readOnly) return;
656
+ const target = e3.target;
657
+ const validTags = ["h1", "h2", "h3", "h4", "h5", "h6", "p", "span", "a", "div"];
658
+ const tag = target.tagName.toLowerCase();
659
+ if (!validTags.includes(tag)) return;
660
+ const text2 = target.textContent?.trim() || "";
661
+ if (!text2) return;
662
+ let matchingPropName = null;
663
+ for (const [key, value] of Object.entries(node.props)) {
664
+ if (typeof value === "string" && value.trim() === text2) {
665
+ matchingPropName = key;
666
+ break;
667
+ }
668
+ }
669
+ if (!matchingPropName) return;
670
+ e3.stopPropagation();
671
+ target.contentEditable = "true";
672
+ target.focus();
673
+ const range = document.createRange();
674
+ range.selectNodeContents(target);
675
+ const sel = window.getSelection();
676
+ sel?.removeAllRanges();
677
+ sel?.addRange(range);
678
+ const propName = matchingPropName;
679
+ const handleBlur = () => {
680
+ target.contentEditable = "false";
681
+ target.removeEventListener("blur", handleBlur);
682
+ const newText = target.textContent?.trim() || "";
683
+ useEditorStore.getState().updateProps(node.props.id, {
684
+ [propName]: newText
685
+ });
686
+ };
687
+ target.addEventListener("blur", handleBlur);
688
+ },
689
+ [node.props, node.props.id, readOnly]
690
+ );
653
691
  if (!componentConfig) {
654
692
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "12px", background: "#fee2e2", color: "#991b1b", fontSize: "12px", borderRadius: "4px" }, children: [
655
693
  "Bile\u015Fen bulunamad\u0131: ",
@@ -679,6 +717,7 @@ var NodeRenderer = ({ node, index: index2, zoneKey }) => {
679
717
  onMouseEnter: handleMouseEnter,
680
718
  onMouseLeave: handleMouseLeave,
681
719
  onClick: handleClick,
720
+ onDoubleClick: handleDoubleClick,
682
721
  style: {
683
722
  cursor: readOnly ? void 0 : "pointer"
684
723
  },
@@ -746,6 +785,10 @@ var Frame = ({ children, title = "Canvas Frame", ...props }) => {
746
785
  doc.head.appendChild(style);
747
786
  };
748
787
  copyStyles();
788
+ const observer = new MutationObserver(() => {
789
+ copyStyles();
790
+ });
791
+ observer.observe(document.head, { childList: true, subtree: true });
749
792
  if (doc.body) {
750
793
  doc.body.className = "tecof-canvas-body";
751
794
  const handleBodyClick = (e3) => {
@@ -758,9 +801,24 @@ var Frame = ({ children, title = "Canvas Frame", ...props }) => {
758
801
  }
759
802
  }
760
803
  };
804
+ const handleIframeKeyDown = (e3) => {
805
+ const event = new KeyboardEvent("keydown", {
806
+ key: e3.key,
807
+ code: e3.code,
808
+ ctrlKey: e3.ctrlKey,
809
+ metaKey: e3.metaKey,
810
+ shiftKey: e3.shiftKey,
811
+ altKey: e3.altKey,
812
+ bubbles: true
813
+ });
814
+ window.dispatchEvent(event);
815
+ };
761
816
  doc.body.addEventListener("click", handleBodyClick);
817
+ doc.addEventListener("keydown", handleIframeKeyDown);
762
818
  return () => {
819
+ observer.disconnect();
763
820
  doc.body.removeEventListener("click", handleBodyClick);
821
+ doc.removeEventListener("keydown", handleIframeKeyDown);
764
822
  };
765
823
  }
766
824
  }, [contentRef]);
@@ -1028,8 +1086,18 @@ var __iconNode14 = [
1028
1086
  ];
1029
1087
  var Globe = createLucideIcon("globe", __iconNode14);
1030
1088
 
1031
- // node_modules/lucide-react/dist/esm/icons/grip-vertical.js
1089
+ // node_modules/lucide-react/dist/esm/icons/grid-3x3.js
1032
1090
  var __iconNode15 = [
1091
+ ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }],
1092
+ ["path", { d: "M3 9h18", key: "1pudct" }],
1093
+ ["path", { d: "M3 15h18", key: "5xshup" }],
1094
+ ["path", { d: "M9 3v18", key: "fh3hqa" }],
1095
+ ["path", { d: "M15 3v18", key: "14nvp0" }]
1096
+ ];
1097
+ var Grid3x3 = createLucideIcon("grid-3x3", __iconNode15);
1098
+
1099
+ // node_modules/lucide-react/dist/esm/icons/grip-vertical.js
1100
+ var __iconNode16 = [
1033
1101
  ["circle", { cx: "9", cy: "12", r: "1", key: "1vctgf" }],
1034
1102
  ["circle", { cx: "9", cy: "5", r: "1", key: "hp0tcf" }],
1035
1103
  ["circle", { cx: "9", cy: "19", r: "1", key: "fkjjf6" }],
@@ -1037,28 +1105,28 @@ var __iconNode15 = [
1037
1105
  ["circle", { cx: "15", cy: "5", r: "1", key: "19l28e" }],
1038
1106
  ["circle", { cx: "15", cy: "19", r: "1", key: "f4zoj3" }]
1039
1107
  ];
1040
- var GripVertical = createLucideIcon("grip-vertical", __iconNode15);
1108
+ var GripVertical = createLucideIcon("grip-vertical", __iconNode16);
1041
1109
 
1042
1110
  // node_modules/lucide-react/dist/esm/icons/image-plus.js
1043
- var __iconNode16 = [
1111
+ var __iconNode17 = [
1044
1112
  ["path", { d: "M16 5h6", key: "1vod17" }],
1045
1113
  ["path", { d: "M19 2v6", key: "4bpg5p" }],
1046
1114
  ["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
1115
  ["path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21", key: "1xmnt7" }],
1048
1116
  ["circle", { cx: "9", cy: "9", r: "2", key: "af1f0g" }]
1049
1117
  ];
1050
- var ImagePlus = createLucideIcon("image-plus", __iconNode16);
1118
+ var ImagePlus = createLucideIcon("image-plus", __iconNode17);
1051
1119
 
1052
1120
  // node_modules/lucide-react/dist/esm/icons/image.js
1053
- var __iconNode17 = [
1121
+ var __iconNode18 = [
1054
1122
  ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2", key: "1m3agn" }],
1055
1123
  ["circle", { cx: "9", cy: "9", r: "2", key: "af1f0g" }],
1056
1124
  ["path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21", key: "1xmnt7" }]
1057
1125
  ];
1058
- var Image2 = createLucideIcon("image", __iconNode17);
1126
+ var Image2 = createLucideIcon("image", __iconNode18);
1059
1127
 
1060
1128
  // node_modules/lucide-react/dist/esm/icons/languages.js
1061
- var __iconNode18 = [
1129
+ var __iconNode19 = [
1062
1130
  ["path", { d: "m5 8 6 6", key: "1wu5hv" }],
1063
1131
  ["path", { d: "m4 14 6-6 2-3", key: "1k1g8d" }],
1064
1132
  ["path", { d: "M2 5h12", key: "or177f" }],
@@ -1066,29 +1134,71 @@ var __iconNode18 = [
1066
1134
  ["path", { d: "m22 22-5-10-5 10", key: "don7ne" }],
1067
1135
  ["path", { d: "M14 18h6", key: "1m8k6r" }]
1068
1136
  ];
1069
- var Languages = createLucideIcon("languages", __iconNode18);
1137
+ var Languages = createLucideIcon("languages", __iconNode19);
1138
+
1139
+ // node_modules/lucide-react/dist/esm/icons/layers.js
1140
+ var __iconNode20 = [
1141
+ [
1142
+ "path",
1143
+ {
1144
+ 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",
1145
+ key: "zw3jo"
1146
+ }
1147
+ ],
1148
+ [
1149
+ "path",
1150
+ {
1151
+ 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",
1152
+ key: "1wduqc"
1153
+ }
1154
+ ],
1155
+ [
1156
+ "path",
1157
+ {
1158
+ 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",
1159
+ key: "kqbvx6"
1160
+ }
1161
+ ]
1162
+ ];
1163
+ var Layers = createLucideIcon("layers", __iconNode20);
1070
1164
 
1071
1165
  // node_modules/lucide-react/dist/esm/icons/link-2.js
1072
- var __iconNode19 = [
1166
+ var __iconNode21 = [
1073
1167
  ["path", { d: "M9 17H7A5 5 0 0 1 7 7h2", key: "8i5ue5" }],
1074
1168
  ["path", { d: "M15 7h2a5 5 0 1 1 0 10h-2", key: "1b9ql8" }],
1075
1169
  ["line", { x1: "8", x2: "16", y1: "12", y2: "12", key: "1jonct" }]
1076
1170
  ];
1077
- var Link2 = createLucideIcon("link-2", __iconNode19);
1171
+ var Link2 = createLucideIcon("link-2", __iconNode21);
1078
1172
 
1079
1173
  // node_modules/lucide-react/dist/esm/icons/link.js
1080
- var __iconNode20 = [
1174
+ var __iconNode22 = [
1081
1175
  ["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
1176
  ["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
1177
  ];
1084
- var Link = createLucideIcon("link", __iconNode20);
1178
+ var Link = createLucideIcon("link", __iconNode22);
1085
1179
 
1086
1180
  // 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);
1181
+ var __iconNode23 = [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]];
1182
+ var LoaderCircle = createLucideIcon("loader-circle", __iconNode23);
1183
+
1184
+ // node_modules/lucide-react/dist/esm/icons/monitor.js
1185
+ var __iconNode24 = [
1186
+ ["rect", { width: "20", height: "14", x: "2", y: "3", rx: "2", key: "48i651" }],
1187
+ ["line", { x1: "8", x2: "16", y1: "21", y2: "21", key: "1svkeh" }],
1188
+ ["line", { x1: "12", x2: "12", y1: "17", y2: "21", key: "vw1qmm" }]
1189
+ ];
1190
+ var Monitor = createLucideIcon("monitor", __iconNode24);
1191
+
1192
+ // node_modules/lucide-react/dist/esm/icons/panels-top-left.js
1193
+ var __iconNode25 = [
1194
+ ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }],
1195
+ ["path", { d: "M3 9h18", key: "1pudct" }],
1196
+ ["path", { d: "M9 21V9", key: "1oto5p" }]
1197
+ ];
1198
+ var PanelsTopLeft = createLucideIcon("panels-top-left", __iconNode25);
1089
1199
 
1090
1200
  // node_modules/lucide-react/dist/esm/icons/pencil.js
1091
- var __iconNode22 = [
1201
+ var __iconNode26 = [
1092
1202
  [
1093
1203
  "path",
1094
1204
  {
@@ -1098,71 +1208,113 @@ var __iconNode22 = [
1098
1208
  ],
1099
1209
  ["path", { d: "m15 5 4 4", key: "1mk7zo" }]
1100
1210
  ];
1101
- var Pencil = createLucideIcon("pencil", __iconNode22);
1211
+ var Pencil = createLucideIcon("pencil", __iconNode26);
1102
1212
 
1103
1213
  // node_modules/lucide-react/dist/esm/icons/plus.js
1104
- var __iconNode23 = [
1214
+ var __iconNode27 = [
1105
1215
  ["path", { d: "M5 12h14", key: "1ays0h" }],
1106
1216
  ["path", { d: "M12 5v14", key: "s699le" }]
1107
1217
  ];
1108
- var Plus = createLucideIcon("plus", __iconNode23);
1218
+ var Plus = createLucideIcon("plus", __iconNode27);
1219
+
1220
+ // node_modules/lucide-react/dist/esm/icons/redo-2.js
1221
+ var __iconNode28 = [
1222
+ ["path", { d: "m15 14 5-5-5-5", key: "12vg1m" }],
1223
+ ["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" }]
1224
+ ];
1225
+ var Redo2 = createLucideIcon("redo-2", __iconNode28);
1109
1226
 
1110
1227
  // node_modules/lucide-react/dist/esm/icons/refresh-ccw.js
1111
- var __iconNode24 = [
1228
+ var __iconNode29 = [
1112
1229
  ["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
1230
  ["path", { d: "M3 3v5h5", key: "1xhq8a" }],
1114
1231
  ["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
1232
  ["path", { d: "M16 16h5v5", key: "ccwih5" }]
1116
1233
  ];
1117
- var RefreshCcw = createLucideIcon("refresh-ccw", __iconNode24);
1234
+ var RefreshCcw = createLucideIcon("refresh-ccw", __iconNode29);
1118
1235
 
1119
1236
  // node_modules/lucide-react/dist/esm/icons/refresh-cw.js
1120
- var __iconNode25 = [
1237
+ var __iconNode30 = [
1121
1238
  ["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
1239
  ["path", { d: "M21 3v5h-5", key: "1q7to0" }],
1123
1240
  ["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
1241
  ["path", { d: "M8 16H3v5", key: "1cv678" }]
1125
1242
  ];
1126
- var RefreshCw = createLucideIcon("refresh-cw", __iconNode25);
1243
+ var RefreshCw = createLucideIcon("refresh-cw", __iconNode30);
1127
1244
 
1128
1245
  // node_modules/lucide-react/dist/esm/icons/rotate-ccw.js
1129
- var __iconNode26 = [
1246
+ var __iconNode31 = [
1130
1247
  ["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
1248
  ["path", { d: "M3 3v5h5", key: "1xhq8a" }]
1132
1249
  ];
1133
- var RotateCcw = createLucideIcon("rotate-ccw", __iconNode26);
1250
+ var RotateCcw = createLucideIcon("rotate-ccw", __iconNode31);
1251
+
1252
+ // node_modules/lucide-react/dist/esm/icons/save.js
1253
+ var __iconNode32 = [
1254
+ [
1255
+ "path",
1256
+ {
1257
+ 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",
1258
+ key: "1c8476"
1259
+ }
1260
+ ],
1261
+ ["path", { d: "M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7", key: "1ydtos" }],
1262
+ ["path", { d: "M7 3v4a1 1 0 0 0 1 1h7", key: "t51u73" }]
1263
+ ];
1264
+ var Save = createLucideIcon("save", __iconNode32);
1134
1265
 
1135
1266
  // node_modules/lucide-react/dist/esm/icons/search.js
1136
- var __iconNode27 = [
1267
+ var __iconNode33 = [
1137
1268
  ["path", { d: "m21 21-4.34-4.34", key: "14j7rj" }],
1138
1269
  ["circle", { cx: "11", cy: "11", r: "8", key: "4ej97u" }]
1139
1270
  ];
1140
- var Search = createLucideIcon("search", __iconNode27);
1271
+ var Search = createLucideIcon("search", __iconNode33);
1272
+
1273
+ // node_modules/lucide-react/dist/esm/icons/smartphone.js
1274
+ var __iconNode34 = [
1275
+ ["rect", { width: "14", height: "20", x: "5", y: "2", rx: "2", ry: "2", key: "1yt0o3" }],
1276
+ ["path", { d: "M12 18h.01", key: "mhygvu" }]
1277
+ ];
1278
+ var Smartphone = createLucideIcon("smartphone", __iconNode34);
1279
+
1280
+ // node_modules/lucide-react/dist/esm/icons/tablet.js
1281
+ var __iconNode35 = [
1282
+ ["rect", { width: "16", height: "20", x: "4", y: "2", rx: "2", ry: "2", key: "76otgf" }],
1283
+ ["line", { x1: "12", x2: "12.01", y1: "18", y2: "18", key: "1dp563" }]
1284
+ ];
1285
+ var Tablet = createLucideIcon("tablet", __iconNode35);
1141
1286
 
1142
1287
  // node_modules/lucide-react/dist/esm/icons/trash-2.js
1143
- var __iconNode28 = [
1288
+ var __iconNode36 = [
1144
1289
  ["path", { d: "M10 11v6", key: "nco0om" }],
1145
1290
  ["path", { d: "M14 11v6", key: "outv1u" }],
1146
1291
  ["path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6", key: "miytrc" }],
1147
1292
  ["path", { d: "M3 6h18", key: "d0wm0j" }],
1148
1293
  ["path", { d: "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2", key: "e791ji" }]
1149
1294
  ];
1150
- var Trash2 = createLucideIcon("trash-2", __iconNode28);
1295
+ var Trash2 = createLucideIcon("trash-2", __iconNode36);
1296
+
1297
+ // node_modules/lucide-react/dist/esm/icons/undo-2.js
1298
+ var __iconNode37 = [
1299
+ ["path", { d: "M9 14 4 9l5-5", key: "102s5s" }],
1300
+ ["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" }]
1301
+ ];
1302
+ var Undo2 = createLucideIcon("undo-2", __iconNode37);
1151
1303
 
1152
1304
  // node_modules/lucide-react/dist/esm/icons/upload.js
1153
- var __iconNode29 = [
1305
+ var __iconNode38 = [
1154
1306
  ["path", { d: "M12 3v12", key: "1x0j5s" }],
1155
1307
  ["path", { d: "m17 8-5-5-5 5", key: "7q97r8" }],
1156
1308
  ["path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4", key: "ih7n3h" }]
1157
1309
  ];
1158
- var Upload = createLucideIcon("upload", __iconNode29);
1310
+ var Upload = createLucideIcon("upload", __iconNode38);
1159
1311
 
1160
1312
  // node_modules/lucide-react/dist/esm/icons/x.js
1161
- var __iconNode30 = [
1313
+ var __iconNode39 = [
1162
1314
  ["path", { d: "M18 6 6 18", key: "1bl5f8" }],
1163
1315
  ["path", { d: "m6 6 12 12", key: "d8bk6v" }]
1164
1316
  ];
1165
- var X = createLucideIcon("x", __iconNode30);
1317
+ var X = createLucideIcon("x", __iconNode39);
1166
1318
  var useOverlayCoords = (id, iframeEl, containerEl, documentState) => {
1167
1319
  const [coords, setCoords] = React__default.useState(null);
1168
1320
  React__default.useEffect(() => {
@@ -1539,6 +1691,7 @@ var FieldRenderer = ({
1539
1691
  onChange,
1540
1692
  readOnly = false
1541
1693
  }) => {
1694
+ const [expandedIndices, setExpandedIndices] = React__default.useState({});
1542
1695
  const label = definition.label || name3;
1543
1696
  const type = definition.type;
1544
1697
  if (definition.render) {
@@ -1702,6 +1855,215 @@ var FieldRenderer = ({
1702
1855
  },
1703
1856
  opt.value
1704
1857
  )) }) });
1858
+ case "array": {
1859
+ const items = Array.isArray(value) ? value : [];
1860
+ const arrayFields = definition.arrayFields || {};
1861
+ const getItemLabel = (item2, idx) => {
1862
+ if (!item2) return `\xD6\u011Fe ${idx + 1}`;
1863
+ for (const val of Object.values(item2)) {
1864
+ if (typeof val === "string" && val.trim().length > 0) {
1865
+ return val;
1866
+ }
1867
+ if (Array.isArray(val)) {
1868
+ const trVal = val.find((v2) => typeof v2 === "object" && v2 !== null && "value" in v2);
1869
+ if (trVal && typeof trVal.value === "string" && trVal.value.trim().length > 0) {
1870
+ return trVal.value;
1871
+ }
1872
+ }
1873
+ }
1874
+ return `\xD6\u011Fe ${idx + 1}`;
1875
+ };
1876
+ const toggleExpand = (idx) => {
1877
+ setExpandedIndices((prev) => ({ ...prev, [idx]: !prev[idx] }));
1878
+ };
1879
+ const handleAdd = () => {
1880
+ const newItem = {};
1881
+ Object.entries(arrayFields).forEach(([subName, subDef]) => {
1882
+ newItem[subName] = subDef.defaultValue !== void 0 ? subDef.defaultValue : null;
1883
+ });
1884
+ onChange([...items, newItem]);
1885
+ setExpandedIndices((prev) => ({ ...prev, [items.length]: true }));
1886
+ };
1887
+ const handleRemove = (idx) => {
1888
+ const copy = [...items];
1889
+ copy.splice(idx, 1);
1890
+ onChange(copy);
1891
+ const newExpanded = { ...expandedIndices };
1892
+ delete newExpanded[idx];
1893
+ setExpandedIndices(newExpanded);
1894
+ };
1895
+ const handleMove = (idx, direction) => {
1896
+ if (direction === "up" && idx === 0) return;
1897
+ if (direction === "down" && idx === items.length - 1) return;
1898
+ const copy = [...items];
1899
+ const targetIdx = direction === "up" ? idx - 1 : idx + 1;
1900
+ const temp = copy[idx];
1901
+ copy[idx] = copy[targetIdx];
1902
+ copy[targetIdx] = temp;
1903
+ onChange(copy);
1904
+ const newExpanded = { ...expandedIndices };
1905
+ const tempExpanded = newExpanded[idx];
1906
+ newExpanded[idx] = newExpanded[targetIdx];
1907
+ newExpanded[targetIdx] = tempExpanded;
1908
+ setExpandedIndices(newExpanded);
1909
+ };
1910
+ return /* @__PURE__ */ jsxRuntime.jsx(FieldLabel, { label, readOnly, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "8px", width: "100%" }, children: [
1911
+ items.map((item2, idx) => {
1912
+ const isExpanded = !!expandedIndices[idx];
1913
+ const itemLabel = getItemLabel(item2, idx);
1914
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1915
+ "div",
1916
+ {
1917
+ style: {
1918
+ border: "1px solid #e4e4e7",
1919
+ borderRadius: "8px",
1920
+ overflow: "hidden",
1921
+ background: "#f8fafc",
1922
+ display: "flex",
1923
+ flexDirection: "column"
1924
+ },
1925
+ children: [
1926
+ /* @__PURE__ */ jsxRuntime.jsxs(
1927
+ "div",
1928
+ {
1929
+ onClick: () => toggleExpand(idx),
1930
+ style: {
1931
+ padding: "8px 12px",
1932
+ display: "flex",
1933
+ alignItems: "center",
1934
+ justifyContent: "space-between",
1935
+ cursor: "pointer",
1936
+ background: "#ffffff",
1937
+ userSelect: "none"
1938
+ },
1939
+ children: [
1940
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "6px" }, children: [
1941
+ isExpanded ? /* @__PURE__ */ jsxRuntime.jsx(ChevronDown, { size: 14, color: "#71717a" }) : /* @__PURE__ */ jsxRuntime.jsx(ChevronRight, { size: 14, color: "#71717a" }),
1942
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "13px", fontWeight: 500, color: "#3f3f46" }, children: itemLabel })
1943
+ ] }),
1944
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "4px" }, onClick: (e3) => e3.stopPropagation(), children: [
1945
+ /* @__PURE__ */ jsxRuntime.jsx(
1946
+ "button",
1947
+ {
1948
+ onClick: () => handleMove(idx, "up"),
1949
+ disabled: idx === 0,
1950
+ style: {
1951
+ background: "transparent",
1952
+ border: "none",
1953
+ cursor: idx === 0 ? "not-allowed" : "pointer",
1954
+ padding: "2px",
1955
+ color: idx === 0 ? "#e4e4e7" : "#71717a"
1956
+ },
1957
+ children: /* @__PURE__ */ jsxRuntime.jsx(ArrowUp, { size: 12 })
1958
+ }
1959
+ ),
1960
+ /* @__PURE__ */ jsxRuntime.jsx(
1961
+ "button",
1962
+ {
1963
+ onClick: () => handleMove(idx, "down"),
1964
+ disabled: idx === items.length - 1,
1965
+ style: {
1966
+ background: "transparent",
1967
+ border: "none",
1968
+ cursor: idx === items.length - 1 ? "not-allowed" : "pointer",
1969
+ padding: "2px",
1970
+ color: idx === items.length - 1 ? "#e4e4e7" : "#71717a"
1971
+ },
1972
+ children: /* @__PURE__ */ jsxRuntime.jsx(ArrowDown, { size: 12 })
1973
+ }
1974
+ ),
1975
+ !readOnly && /* @__PURE__ */ jsxRuntime.jsx(
1976
+ "button",
1977
+ {
1978
+ onClick: () => handleRemove(idx),
1979
+ style: {
1980
+ background: "transparent",
1981
+ border: "none",
1982
+ cursor: "pointer",
1983
+ padding: "2px",
1984
+ color: "#ef4444",
1985
+ marginLeft: "4px"
1986
+ },
1987
+ children: /* @__PURE__ */ jsxRuntime.jsx(Trash2, { size: 12 })
1988
+ }
1989
+ )
1990
+ ] })
1991
+ ]
1992
+ }
1993
+ ),
1994
+ isExpanded && /* @__PURE__ */ jsxRuntime.jsx(
1995
+ "div",
1996
+ {
1997
+ style: {
1998
+ padding: "12px",
1999
+ borderTop: "1px solid #e4e4e7",
2000
+ display: "flex",
2001
+ flexDirection: "column",
2002
+ gap: "12px",
2003
+ background: "#ffffff"
2004
+ },
2005
+ children: Object.entries(arrayFields).map(([subFieldName, subFieldDef]) => /* @__PURE__ */ jsxRuntime.jsx(
2006
+ FieldRenderer,
2007
+ {
2008
+ name: subFieldName,
2009
+ definition: subFieldDef,
2010
+ value: item2[subFieldName],
2011
+ onChange: (newSubVal) => {
2012
+ const updatedItems = [...items];
2013
+ updatedItems[idx] = {
2014
+ ...updatedItems[idx],
2015
+ [subFieldName]: newSubVal
2016
+ };
2017
+ onChange(updatedItems);
2018
+ },
2019
+ readOnly
2020
+ },
2021
+ subFieldName
2022
+ ))
2023
+ }
2024
+ )
2025
+ ]
2026
+ },
2027
+ idx
2028
+ );
2029
+ }),
2030
+ !readOnly && /* @__PURE__ */ jsxRuntime.jsxs(
2031
+ "button",
2032
+ {
2033
+ type: "button",
2034
+ onClick: handleAdd,
2035
+ style: {
2036
+ display: "flex",
2037
+ alignItems: "center",
2038
+ justifyContent: "center",
2039
+ gap: "6px",
2040
+ width: "100%",
2041
+ padding: "10px",
2042
+ borderRadius: "8px",
2043
+ border: "1px dashed #cbd5e1",
2044
+ background: "#ffffff",
2045
+ color: "#64748b",
2046
+ fontSize: "13px",
2047
+ fontWeight: 500,
2048
+ cursor: "pointer",
2049
+ transition: "all 0.2s"
2050
+ },
2051
+ className: "tecof-add-array-item-btn",
2052
+ children: [
2053
+ /* @__PURE__ */ jsxRuntime.jsx(Plus, { size: 14 }),
2054
+ "\xD6\u011Fe Ekle"
2055
+ ]
2056
+ }
2057
+ ),
2058
+ /* @__PURE__ */ jsxRuntime.jsx("style", { dangerouslySetInnerHTML: { __html: `
2059
+ .tecof-add-array-item-btn:hover {
2060
+ border-color: #3b82f6 !important;
2061
+ color: #2563eb !important;
2062
+ background-color: #eff6ff !important;
2063
+ }
2064
+ ` } })
2065
+ ] }) });
2066
+ }
1705
2067
  default:
1706
2068
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "8px", fontSize: "11px", color: "#71717a", background: "#fafafa", borderRadius: "4px" }, children: [
1707
2069
  'Desteklenmeyen alan t\xFCr\xFC: "',
@@ -1901,6 +2263,528 @@ var Inspector = () => {
1901
2263
  }
1902
2264
  );
1903
2265
  };
2266
+ var TopBar = ({ onSave, saving, saveStatus }) => {
2267
+ const viewport = useEditorStore((state3) => state3.viewport);
2268
+ const setViewport = useEditorStore((state3) => state3.setViewport);
2269
+ const pastCount = useEditorStore((state3) => state3.history.past.length);
2270
+ const futureCount = useEditorStore((state3) => state3.history.future.length);
2271
+ const undo = useEditorStore((state3) => state3.undo);
2272
+ const redo = useEditorStore((state3) => state3.redo);
2273
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-studio-topbar", style: {
2274
+ height: "56px",
2275
+ borderBottom: "1px solid #e4e4e7",
2276
+ background: "#ffffff",
2277
+ display: "flex",
2278
+ alignItems: "center",
2279
+ justifyContent: "space-between",
2280
+ padding: "0 20px",
2281
+ boxSizing: "border-box",
2282
+ zIndex: 100
2283
+ }, children: [
2284
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-studio-topbar-title", style: {
2285
+ fontSize: "14px",
2286
+ fontWeight: 600,
2287
+ color: "#18181b",
2288
+ display: "flex",
2289
+ alignItems: "center",
2290
+ gap: "8px"
2291
+ }, children: [
2292
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Sayfa D\xFCzenleyici" }),
2293
+ saveStatus === "success" && /* @__PURE__ */ jsxRuntime.jsxs("span", { style: {
2294
+ fontSize: "11px",
2295
+ color: "#10b981",
2296
+ display: "inline-flex",
2297
+ alignItems: "center",
2298
+ gap: "4px",
2299
+ fontWeight: 500
2300
+ }, children: [
2301
+ /* @__PURE__ */ jsxRuntime.jsx(Check, { size: 12 }),
2302
+ " Kaydedildi"
2303
+ ] })
2304
+ ] }),
2305
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-studio-topbar-viewports", style: {
2306
+ display: "flex",
2307
+ alignItems: "center",
2308
+ background: "#f4f4f5",
2309
+ padding: "3px",
2310
+ borderRadius: "8px",
2311
+ gap: "2px"
2312
+ }, children: [
2313
+ /* @__PURE__ */ jsxRuntime.jsx(
2314
+ "button",
2315
+ {
2316
+ onClick: () => setViewport("desktop"),
2317
+ style: {
2318
+ background: viewport === "desktop" ? "#ffffff" : "transparent",
2319
+ border: "none",
2320
+ outline: "none",
2321
+ cursor: "pointer",
2322
+ padding: "6px 12px",
2323
+ borderRadius: "6px",
2324
+ color: viewport === "desktop" ? "#18181b" : "#71717a",
2325
+ display: "flex",
2326
+ alignItems: "center",
2327
+ justifyContent: "center",
2328
+ boxShadow: viewport === "desktop" ? "0 1px 3px 0 rgba(0, 0, 0, 0.1)" : "none",
2329
+ transition: "all 0.2s"
2330
+ },
2331
+ title: "Masa\xFCst\xFC",
2332
+ children: /* @__PURE__ */ jsxRuntime.jsx(Monitor, { size: 16 })
2333
+ }
2334
+ ),
2335
+ /* @__PURE__ */ jsxRuntime.jsx(
2336
+ "button",
2337
+ {
2338
+ onClick: () => setViewport("tablet"),
2339
+ style: {
2340
+ background: viewport === "tablet" ? "#ffffff" : "transparent",
2341
+ border: "none",
2342
+ outline: "none",
2343
+ cursor: "pointer",
2344
+ padding: "6px 12px",
2345
+ borderRadius: "6px",
2346
+ color: viewport === "tablet" ? "#18181b" : "#71717a",
2347
+ display: "flex",
2348
+ alignItems: "center",
2349
+ justifyContent: "center",
2350
+ boxShadow: viewport === "tablet" ? "0 1px 3px 0 rgba(0, 0, 0, 0.1)" : "none",
2351
+ transition: "all 0.2s"
2352
+ },
2353
+ title: "Tablet",
2354
+ children: /* @__PURE__ */ jsxRuntime.jsx(Tablet, { size: 16 })
2355
+ }
2356
+ ),
2357
+ /* @__PURE__ */ jsxRuntime.jsx(
2358
+ "button",
2359
+ {
2360
+ onClick: () => setViewport("mobile"),
2361
+ style: {
2362
+ background: viewport === "mobile" ? "#ffffff" : "transparent",
2363
+ border: "none",
2364
+ outline: "none",
2365
+ cursor: "pointer",
2366
+ padding: "6px 12px",
2367
+ borderRadius: "6px",
2368
+ color: viewport === "mobile" ? "#18181b" : "#71717a",
2369
+ display: "flex",
2370
+ alignItems: "center",
2371
+ justifyContent: "center",
2372
+ boxShadow: viewport === "mobile" ? "0 1px 3px 0 rgba(0, 0, 0, 0.1)" : "none",
2373
+ transition: "all 0.2s"
2374
+ },
2375
+ title: "Mobil",
2376
+ children: /* @__PURE__ */ jsxRuntime.jsx(Smartphone, { size: 16 })
2377
+ }
2378
+ )
2379
+ ] }),
2380
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-studio-topbar-actions", style: {
2381
+ display: "flex",
2382
+ alignItems: "center",
2383
+ gap: "12px"
2384
+ }, children: [
2385
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: "4px" }, children: [
2386
+ /* @__PURE__ */ jsxRuntime.jsx(
2387
+ "button",
2388
+ {
2389
+ onClick: undo,
2390
+ disabled: pastCount === 0,
2391
+ style: {
2392
+ background: "transparent",
2393
+ border: "none",
2394
+ cursor: pastCount === 0 ? "not-allowed" : "pointer",
2395
+ padding: "8px",
2396
+ borderRadius: "6px",
2397
+ color: pastCount === 0 ? "#d4d4d8" : "#71717a",
2398
+ display: "flex",
2399
+ alignItems: "center",
2400
+ justifyContent: "center",
2401
+ transition: "background 0.2s"
2402
+ },
2403
+ title: "Geri Al",
2404
+ children: /* @__PURE__ */ jsxRuntime.jsx(Undo2, { size: 16 })
2405
+ }
2406
+ ),
2407
+ /* @__PURE__ */ jsxRuntime.jsx(
2408
+ "button",
2409
+ {
2410
+ onClick: redo,
2411
+ disabled: futureCount === 0,
2412
+ style: {
2413
+ background: "transparent",
2414
+ border: "none",
2415
+ cursor: futureCount === 0 ? "not-allowed" : "pointer",
2416
+ padding: "8px",
2417
+ borderRadius: "6px",
2418
+ color: futureCount === 0 ? "#d4d4d8" : "#71717a",
2419
+ display: "flex",
2420
+ alignItems: "center",
2421
+ justifyContent: "center",
2422
+ transition: "background 0.2s"
2423
+ },
2424
+ title: "Yinele",
2425
+ children: /* @__PURE__ */ jsxRuntime.jsx(Redo2, { size: 16 })
2426
+ }
2427
+ )
2428
+ ] }),
2429
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: "1px", height: "20px", background: "#e4e4e7" } }),
2430
+ /* @__PURE__ */ jsxRuntime.jsxs(
2431
+ "button",
2432
+ {
2433
+ onClick: onSave,
2434
+ disabled: saving,
2435
+ style: {
2436
+ background: "#2563eb",
2437
+ color: "#ffffff",
2438
+ border: "none",
2439
+ cursor: saving ? "wait" : "pointer",
2440
+ padding: "8px 16px",
2441
+ borderRadius: "8px",
2442
+ fontSize: "13px",
2443
+ fontWeight: 500,
2444
+ display: "flex",
2445
+ alignItems: "center",
2446
+ gap: "8px",
2447
+ transition: "background 0.2s",
2448
+ opacity: saving ? 0.7 : 1
2449
+ },
2450
+ children: [
2451
+ /* @__PURE__ */ jsxRuntime.jsx(Save, { size: 14 }),
2452
+ saving ? "Kaydediliyor..." : "Taslak Kaydet"
2453
+ ]
2454
+ }
2455
+ )
2456
+ ] })
2457
+ ] });
2458
+ };
2459
+ var TreeNode = ({ node, depth }) => {
2460
+ const { config: config3 } = useStudio();
2461
+ const documentState = useEditorStore((state3) => state3.document);
2462
+ const selectedId = useEditorStore((state3) => state3.selection.selectedId);
2463
+ const selectNode = useEditorStore((state3) => state3.selectNode);
2464
+ const hoverNode = useEditorStore((state3) => state3.hoverNode);
2465
+ const removeNode2 = useEditorStore((state3) => state3.removeNode);
2466
+ const [expanded, setExpanded] = React__default.useState(true);
2467
+ const isSelected = selectedId === node.props.id;
2468
+ const componentConfig = config3.components[node.type];
2469
+ const label = componentConfig?.label || node.type;
2470
+ const childZoneKeys = Object.keys(documentState.zones).filter(
2471
+ (key) => key.startsWith(`${node.props.id}:`)
2472
+ );
2473
+ const hasChildren = childZoneKeys.some(
2474
+ (key) => (documentState.zones[key] || []).length > 0
2475
+ );
2476
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-layers-tree-node", style: { display: "flex", flexDirection: "column" }, children: [
2477
+ /* @__PURE__ */ jsxRuntime.jsxs(
2478
+ "div",
2479
+ {
2480
+ onMouseEnter: () => hoverNode(node.props.id),
2481
+ onMouseLeave: () => hoverNode(null),
2482
+ onClick: () => selectNode(node.props.id),
2483
+ style: {
2484
+ display: "flex",
2485
+ alignItems: "center",
2486
+ justifyContent: "space-between",
2487
+ padding: "6px 8px",
2488
+ paddingLeft: `${depth * 12 + 8}px`,
2489
+ background: isSelected ? "#eff6ff" : "transparent",
2490
+ color: isSelected ? "#1d4ed8" : "#3f3f46",
2491
+ cursor: "pointer",
2492
+ borderRadius: "6px",
2493
+ fontSize: "13px",
2494
+ fontWeight: isSelected ? 500 : 400,
2495
+ transition: "all 0.15s"
2496
+ },
2497
+ children: [
2498
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "6px" }, children: [
2499
+ hasChildren ? /* @__PURE__ */ jsxRuntime.jsx(
2500
+ "button",
2501
+ {
2502
+ onClick: (e3) => {
2503
+ e3.stopPropagation();
2504
+ setExpanded(!expanded);
2505
+ },
2506
+ style: {
2507
+ background: "transparent",
2508
+ border: "none",
2509
+ cursor: "pointer",
2510
+ padding: 0,
2511
+ display: "flex",
2512
+ alignItems: "center",
2513
+ color: "#a1a1aa"
2514
+ },
2515
+ children: expanded ? /* @__PURE__ */ jsxRuntime.jsx(ChevronDown, { size: 14 }) : /* @__PURE__ */ jsxRuntime.jsx(ChevronRight, { size: 14 })
2516
+ }
2517
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: "14px" } }),
2518
+ /* @__PURE__ */ jsxRuntime.jsx(PanelsTopLeft, { size: 14, style: { color: isSelected ? "#3b82f6" : "#71717a" } }),
2519
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: {
2520
+ whiteSpace: "nowrap",
2521
+ overflow: "hidden",
2522
+ textOverflow: "ellipsis",
2523
+ maxWidth: "120px"
2524
+ }, children: label })
2525
+ ] }),
2526
+ /* @__PURE__ */ jsxRuntime.jsx(
2527
+ "button",
2528
+ {
2529
+ onClick: (e3) => {
2530
+ e3.stopPropagation();
2531
+ removeNode2(node.props.id);
2532
+ },
2533
+ className: "tecof-layers-delete-btn",
2534
+ style: {
2535
+ background: "transparent",
2536
+ border: "none",
2537
+ cursor: "pointer",
2538
+ padding: "2px",
2539
+ color: "#a1a1aa",
2540
+ display: "flex",
2541
+ alignItems: "center",
2542
+ opacity: 0,
2543
+ transition: "opacity 0.2s"
2544
+ },
2545
+ children: /* @__PURE__ */ jsxRuntime.jsx(Trash2, { size: 12 })
2546
+ }
2547
+ )
2548
+ ]
2549
+ }
2550
+ ),
2551
+ /* @__PURE__ */ jsxRuntime.jsx("style", { dangerouslySetInnerHTML: { __html: `
2552
+ .tecof-layers-tree-node:hover .tecof-layers-delete-btn {
2553
+ opacity: 1 !important;
2554
+ }
2555
+ .tecof-layers-delete-btn:hover {
2556
+ color: #ef4444 !important;
2557
+ }
2558
+ ` } }),
2559
+ expanded && childZoneKeys.map((zoneKey) => {
2560
+ const zoneItems = documentState.zones[zoneKey] || [];
2561
+ const zoneName = zoneKey.split(":").pop() || "";
2562
+ if (zoneItems.length === 0) return null;
2563
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column" }, children: [
2564
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
2565
+ fontSize: "10px",
2566
+ textTransform: "uppercase",
2567
+ letterSpacing: "0.05em",
2568
+ color: "#a1a1aa",
2569
+ padding: "4px 8px",
2570
+ paddingLeft: `${(depth + 1) * 12 + 14}px`,
2571
+ fontWeight: 600
2572
+ }, children: zoneName }),
2573
+ zoneItems.map((childNode) => /* @__PURE__ */ jsxRuntime.jsx(TreeNode, { node: childNode, depth: depth + 1 }, childNode.props.id))
2574
+ ] }, zoneKey);
2575
+ })
2576
+ ] });
2577
+ };
2578
+ var LayersTree = () => {
2579
+ const documentState = useEditorStore((state3) => state3.document);
2580
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tecof-studio-layers-tree", style: {
2581
+ display: "flex",
2582
+ flexDirection: "column",
2583
+ gap: "2px",
2584
+ overflowY: "auto",
2585
+ height: "100%"
2586
+ }, children: documentState.content.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
2587
+ textAlign: "center",
2588
+ color: "#a1a1aa",
2589
+ fontSize: "13px",
2590
+ padding: "24px 12px"
2591
+ }, children: "S\xFCr\xFCklenmi\u015F katman yok" }) : documentState.content.map((node) => /* @__PURE__ */ jsxRuntime.jsx(TreeNode, { node, depth: 0 }, node.props.id)) });
2592
+ };
2593
+ var LeftPanel = () => {
2594
+ const { config: config3 } = useStudio();
2595
+ const insertNode2 = useEditorStore((state3) => state3.insertNode);
2596
+ useEditorStore((state3) => state3.selection.selectedId);
2597
+ useEditorStore((state3) => state3.document);
2598
+ const [activeTab, setActiveTab] = React__default.useState("blocks");
2599
+ const [searchQuery, setSearchQuery] = React__default.useState("");
2600
+ const categories = config3.categories || {};
2601
+ const components = config3.components || {};
2602
+ const groupedComponents = {};
2603
+ if (Object.keys(categories).length > 0) {
2604
+ Object.entries(categories).forEach(([key, value]) => {
2605
+ groupedComponents[value.title || key] = value.components;
2606
+ });
2607
+ } else {
2608
+ Object.entries(components).forEach(([name3, compConfig]) => {
2609
+ const cat = compConfig.category || "Genel";
2610
+ if (!groupedComponents[cat]) {
2611
+ groupedComponents[cat] = [];
2612
+ }
2613
+ groupedComponents[cat].push(name3);
2614
+ });
2615
+ }
2616
+ const handleAddBlock = (type) => {
2617
+ const compConfig = components[type] || {};
2618
+ const defaultProps = compConfig.defaultProps || {};
2619
+ const newNode = {
2620
+ type,
2621
+ props: {
2622
+ id: generateId(),
2623
+ ...JSON.parse(JSON.stringify(defaultProps))
2624
+ }
2625
+ };
2626
+ insertNode2(newNode);
2627
+ };
2628
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-studio-left-panel", style: {
2629
+ width: "280px",
2630
+ borderRight: "1px solid #e4e4e7",
2631
+ background: "#ffffff",
2632
+ display: "flex",
2633
+ flexDirection: "column",
2634
+ height: "100%",
2635
+ boxSizing: "border-box"
2636
+ }, children: [
2637
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
2638
+ display: "flex",
2639
+ borderBottom: "1px solid #e4e4e7",
2640
+ padding: "8px 12px",
2641
+ gap: "4px"
2642
+ }, children: [
2643
+ /* @__PURE__ */ jsxRuntime.jsxs(
2644
+ "button",
2645
+ {
2646
+ onClick: () => setActiveTab("blocks"),
2647
+ style: {
2648
+ flex: 1,
2649
+ display: "flex",
2650
+ alignItems: "center",
2651
+ justifyContent: "center",
2652
+ gap: "6px",
2653
+ border: "none",
2654
+ outline: "none",
2655
+ padding: "8px",
2656
+ borderRadius: "6px",
2657
+ fontSize: "12px",
2658
+ fontWeight: 600,
2659
+ cursor: "pointer",
2660
+ background: activeTab === "blocks" ? "#f4f4f5" : "transparent",
2661
+ color: activeTab === "blocks" ? "#18181b" : "#71717a",
2662
+ transition: "all 0.2s"
2663
+ },
2664
+ children: [
2665
+ /* @__PURE__ */ jsxRuntime.jsx(Grid3x3, { size: 14 }),
2666
+ "Blok Ekle"
2667
+ ]
2668
+ }
2669
+ ),
2670
+ /* @__PURE__ */ jsxRuntime.jsxs(
2671
+ "button",
2672
+ {
2673
+ onClick: () => setActiveTab("layers"),
2674
+ style: {
2675
+ flex: 1,
2676
+ display: "flex",
2677
+ alignItems: "center",
2678
+ justifyContent: "center",
2679
+ gap: "6px",
2680
+ border: "none",
2681
+ outline: "none",
2682
+ padding: "8px",
2683
+ borderRadius: "6px",
2684
+ fontSize: "12px",
2685
+ fontWeight: 600,
2686
+ cursor: "pointer",
2687
+ background: activeTab === "layers" ? "#f4f4f5" : "transparent",
2688
+ color: activeTab === "layers" ? "#18181b" : "#71717a",
2689
+ transition: "all 0.2s"
2690
+ },
2691
+ children: [
2692
+ /* @__PURE__ */ jsxRuntime.jsx(Layers, { size: 14 }),
2693
+ "Katmanlar"
2694
+ ]
2695
+ }
2696
+ )
2697
+ ] }),
2698
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: 1, overflowY: "auto", padding: "12px" }, children: activeTab === "blocks" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "16px" }, children: [
2699
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
2700
+ display: "flex",
2701
+ alignItems: "center",
2702
+ background: "#f4f4f5",
2703
+ padding: "6px 10px",
2704
+ borderRadius: "8px",
2705
+ gap: "8px"
2706
+ }, children: [
2707
+ /* @__PURE__ */ jsxRuntime.jsx(Search, { size: 14, color: "#a1a1aa" }),
2708
+ /* @__PURE__ */ jsxRuntime.jsx(
2709
+ "input",
2710
+ {
2711
+ type: "text",
2712
+ placeholder: "Bile\u015Fen ara...",
2713
+ value: searchQuery,
2714
+ onChange: (e3) => setSearchQuery(e3.target.value),
2715
+ style: {
2716
+ border: "none",
2717
+ outline: "none",
2718
+ background: "transparent",
2719
+ fontSize: "12px",
2720
+ color: "#18181b",
2721
+ width: "100%"
2722
+ }
2723
+ }
2724
+ )
2725
+ ] }),
2726
+ Object.entries(groupedComponents).map(([catTitle, blockTypes]) => {
2727
+ const filteredTypes = blockTypes.filter((type) => {
2728
+ const label = components[type]?.label || type;
2729
+ return label.toLowerCase().includes(searchQuery.toLowerCase());
2730
+ });
2731
+ if (filteredTypes.length === 0) return null;
2732
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: [
2733
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
2734
+ fontSize: "11px",
2735
+ fontWeight: 700,
2736
+ color: "#71717a",
2737
+ textTransform: "uppercase",
2738
+ letterSpacing: "0.05em"
2739
+ }, children: catTitle }),
2740
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
2741
+ display: "grid",
2742
+ gridTemplateColumns: "1fr",
2743
+ gap: "6px"
2744
+ }, children: filteredTypes.map((type) => {
2745
+ const compConfig = components[type] || {};
2746
+ const label = compConfig.label || type;
2747
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2748
+ "button",
2749
+ {
2750
+ onClick: () => handleAddBlock(type),
2751
+ style: {
2752
+ background: "#ffffff",
2753
+ border: "1px solid #e4e4e7",
2754
+ padding: "10px 12px",
2755
+ borderRadius: "8px",
2756
+ fontSize: "13px",
2757
+ fontWeight: 500,
2758
+ color: "#3f3f46",
2759
+ cursor: "pointer",
2760
+ display: "flex",
2761
+ alignItems: "center",
2762
+ justifyContent: "space-between",
2763
+ textAlign: "left",
2764
+ transition: "all 0.2s",
2765
+ boxShadow: "0 1px 2px 0 rgba(0, 0, 0, 0.02)"
2766
+ },
2767
+ className: "tecof-studio-block-btn",
2768
+ children: [
2769
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: label }),
2770
+ /* @__PURE__ */ jsxRuntime.jsx(Plus, { size: 14, style: { color: "#a1a1aa" } })
2771
+ ]
2772
+ },
2773
+ type
2774
+ );
2775
+ }) })
2776
+ ] }, catTitle);
2777
+ }),
2778
+ /* @__PURE__ */ jsxRuntime.jsx("style", { dangerouslySetInnerHTML: { __html: `
2779
+ .tecof-studio-block-btn:hover {
2780
+ border-color: #3b82f6 !important;
2781
+ color: #2563eb !important;
2782
+ background-color: #eff6ff !important;
2783
+ }
2784
+ ` } })
2785
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(LayersTree, {}) })
2786
+ ] });
2787
+ };
1904
2788
  var TecofStudio = ({
1905
2789
  pageId,
1906
2790
  config: config3,
@@ -2014,6 +2898,67 @@ var TecofStudio = ({
2014
2898
  window.addEventListener("message", onMessage);
2015
2899
  return () => window.removeEventListener("message", onMessage);
2016
2900
  }, [isEmbedded, handleSaveDraft, undo, redo, setViewport]);
2901
+ React__default.useEffect(() => {
2902
+ const handleKeyDown = (e3) => {
2903
+ const isInput2 = () => {
2904
+ const activeEl = document.activeElement;
2905
+ if (activeEl) {
2906
+ const tag = activeEl.tagName.toLowerCase();
2907
+ if (tag === "input" || tag === "textarea" || activeEl.hasAttribute("contenteditable")) {
2908
+ return true;
2909
+ }
2910
+ }
2911
+ const iframe = document.querySelector(".tecof-canvas-viewport-wrapper iframe");
2912
+ const iframeDoc = iframe?.contentDocument;
2913
+ const iframeActiveEl = iframeDoc?.activeElement;
2914
+ if (iframeActiveEl) {
2915
+ const tag = iframeActiveEl.tagName.toLowerCase();
2916
+ if (tag === "input" || tag === "textarea" || iframeActiveEl.hasAttribute("contenteditable")) {
2917
+ return true;
2918
+ }
2919
+ }
2920
+ return false;
2921
+ };
2922
+ const selectedId = useEditorStore.getState().selection.selectedId;
2923
+ const isCmdOrCtrl = e3.metaKey || e3.ctrlKey;
2924
+ if (e3.key === "Escape") {
2925
+ useEditorStore.getState().selectNode(null);
2926
+ if (isEmbedded) {
2927
+ window.parent.postMessage({ type: "puck:itemDeselected" }, "*");
2928
+ }
2929
+ return;
2930
+ }
2931
+ if (isCmdOrCtrl && e3.key.toLowerCase() === "z") {
2932
+ e3.preventDefault();
2933
+ if (e3.shiftKey) {
2934
+ redo();
2935
+ } else {
2936
+ undo();
2937
+ }
2938
+ return;
2939
+ }
2940
+ if (isCmdOrCtrl && e3.key.toLowerCase() === "y") {
2941
+ e3.preventDefault();
2942
+ redo();
2943
+ return;
2944
+ }
2945
+ if (isInput2()) return;
2946
+ if ((e3.key === "Delete" || e3.key === "Backspace") && selectedId) {
2947
+ e3.preventDefault();
2948
+ useEditorStore.getState().removeNode(selectedId);
2949
+ return;
2950
+ }
2951
+ if (isCmdOrCtrl && e3.key.toLowerCase() === "d" && selectedId) {
2952
+ e3.preventDefault();
2953
+ useEditorStore.getState().duplicateNode(selectedId);
2954
+ return;
2955
+ }
2956
+ };
2957
+ window.addEventListener("keydown", handleKeyDown);
2958
+ return () => {
2959
+ window.removeEventListener("keydown", handleKeyDown);
2960
+ };
2961
+ }, [undo, redo, isEmbedded]);
2017
2962
  const studioContextValue = React__default.useMemo(() => ({
2018
2963
  config: config3,
2019
2964
  readOnly: false,
@@ -2048,13 +2993,15 @@ var TecofStudio = ({
2048
2993
  position: "relative",
2049
2994
  background: "#f4f4f5"
2050
2995
  }, children: [
2996
+ /* @__PURE__ */ jsxRuntime.jsx(TopBar, { onSave: handleSaveDraft, saving, saveStatus }),
2051
2997
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-studio-workspace-container", style: {
2052
2998
  display: "flex",
2053
2999
  flex: 1,
2054
- height: "100%",
3000
+ height: "calc(100% - 56px)",
2055
3001
  width: "100%",
2056
3002
  overflow: "hidden"
2057
3003
  }, children: [
3004
+ /* @__PURE__ */ jsxRuntime.jsx(LeftPanel, {}),
2058
3005
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tecof-studio-workspace", style: {
2059
3006
  display: "flex",
2060
3007
  flex: 1,
@@ -26649,20 +27596,29 @@ lucide-react/dist/esm/icons/file-text.js:
26649
27596
  lucide-react/dist/esm/icons/file.js:
26650
27597
  lucide-react/dist/esm/icons/folder-open.js:
26651
27598
  lucide-react/dist/esm/icons/globe.js:
27599
+ lucide-react/dist/esm/icons/grid-3x3.js:
26652
27600
  lucide-react/dist/esm/icons/grip-vertical.js:
26653
27601
  lucide-react/dist/esm/icons/image-plus.js:
26654
27602
  lucide-react/dist/esm/icons/image.js:
26655
27603
  lucide-react/dist/esm/icons/languages.js:
27604
+ lucide-react/dist/esm/icons/layers.js:
26656
27605
  lucide-react/dist/esm/icons/link-2.js:
26657
27606
  lucide-react/dist/esm/icons/link.js:
26658
27607
  lucide-react/dist/esm/icons/loader-circle.js:
27608
+ lucide-react/dist/esm/icons/monitor.js:
27609
+ lucide-react/dist/esm/icons/panels-top-left.js:
26659
27610
  lucide-react/dist/esm/icons/pencil.js:
26660
27611
  lucide-react/dist/esm/icons/plus.js:
27612
+ lucide-react/dist/esm/icons/redo-2.js:
26661
27613
  lucide-react/dist/esm/icons/refresh-ccw.js:
26662
27614
  lucide-react/dist/esm/icons/refresh-cw.js:
26663
27615
  lucide-react/dist/esm/icons/rotate-ccw.js:
27616
+ lucide-react/dist/esm/icons/save.js:
26664
27617
  lucide-react/dist/esm/icons/search.js:
27618
+ lucide-react/dist/esm/icons/smartphone.js:
27619
+ lucide-react/dist/esm/icons/tablet.js:
26665
27620
  lucide-react/dist/esm/icons/trash-2.js:
27621
+ lucide-react/dist/esm/icons/undo-2.js:
26666
27622
  lucide-react/dist/esm/icons/upload.js:
26667
27623
  lucide-react/dist/esm/icons/x.js:
26668
27624
  lucide-react/dist/esm/lucide-react.js: