@djangocfg/ui-tools 2.1.239 → 2.1.240

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.cjs CHANGED
@@ -905,6 +905,730 @@ function CronSchedulerFallback() {
905
905
  }
906
906
  chunkWGEGR3DF_cjs.__name(CronSchedulerFallback, "CronSchedulerFallback");
907
907
 
908
+ // src/tools/CodeEditor/workers/setup.ts
909
+ var isSetup = false;
910
+ function setupMonacoWorkers(getWorker) {
911
+ if (isSetup || typeof window === "undefined") return;
912
+ if (getWorker) {
913
+ self.MonacoEnvironment = {
914
+ getWorker: /* @__PURE__ */ chunkWGEGR3DF_cjs.__name((_workerId, label) => getWorker(label), "getWorker")
915
+ };
916
+ }
917
+ isSetup = true;
918
+ }
919
+ chunkWGEGR3DF_cjs.__name(setupMonacoWorkers, "setupMonacoWorkers");
920
+
921
+ // src/tools/CodeEditor/hooks/useMonaco.ts
922
+ function useMonaco() {
923
+ const [monaco, setMonaco] = React3.useState(null);
924
+ const [isLoading, setIsLoading] = React3.useState(true);
925
+ const [error, setError] = React3.useState(null);
926
+ React3.useEffect(() => {
927
+ let mounted = true;
928
+ async function loadMonaco() {
929
+ try {
930
+ setupMonacoWorkers();
931
+ const monacoModule = await import('monaco-editor');
932
+ if (mounted) {
933
+ setMonaco(monacoModule);
934
+ setIsLoading(false);
935
+ }
936
+ } catch (err) {
937
+ if (mounted) {
938
+ setError(err instanceof Error ? err : new Error("Failed to load Monaco Editor"));
939
+ setIsLoading(false);
940
+ }
941
+ }
942
+ }
943
+ chunkWGEGR3DF_cjs.__name(loadMonaco, "loadMonaco");
944
+ loadMonaco();
945
+ return () => {
946
+ mounted = false;
947
+ };
948
+ }, []);
949
+ return { monaco, isLoading, error };
950
+ }
951
+ chunkWGEGR3DF_cjs.__name(useMonaco, "useMonaco");
952
+ function useEditorTheme(monaco, themeOverride) {
953
+ const appTheme = hooks.useResolvedTheme();
954
+ const registered = React3.useRef(false);
955
+ React3.useEffect(() => {
956
+ if (!monaco || registered.current) return;
957
+ try {
958
+ const colors = _readCSSColors();
959
+ monaco.editor.defineTheme("app-dark", {
960
+ base: "vs-dark",
961
+ inherit: true,
962
+ rules: [
963
+ { token: "comment", foreground: "6A9955", fontStyle: "italic" },
964
+ { token: "keyword", foreground: "C586C0" },
965
+ { token: "string", foreground: "CE9178" },
966
+ { token: "number", foreground: "B5CEA8" },
967
+ { token: "type", foreground: "4EC9B0" },
968
+ { token: "function", foreground: "DCDCAA" },
969
+ { token: "variable", foreground: "9CDCFE" }
970
+ ],
971
+ colors: {
972
+ "editor.background": colors.background,
973
+ "editor.foreground": colors.foreground,
974
+ "editor.lineHighlightBackground": colors.lineHighlight,
975
+ "editor.selectionBackground": colors.selection,
976
+ "editorCursor.foreground": colors.foreground,
977
+ "editorLineNumber.foreground": colors.mutedForeground,
978
+ "editorWidget.background": colors.card,
979
+ "editorWidget.border": colors.border,
980
+ "input.background": colors.card,
981
+ "dropdown.background": colors.card
982
+ }
983
+ });
984
+ monaco.editor.defineTheme("app-light", {
985
+ base: "vs",
986
+ inherit: true,
987
+ rules: [
988
+ { token: "comment", foreground: "008000", fontStyle: "italic" },
989
+ { token: "keyword", foreground: "AF00DB" },
990
+ { token: "string", foreground: "A31515" },
991
+ { token: "number", foreground: "098658" },
992
+ { token: "type", foreground: "267F99" },
993
+ { token: "function", foreground: "795E26" },
994
+ { token: "variable", foreground: "001080" }
995
+ ],
996
+ colors: {
997
+ "editor.background": colors.backgroundLight,
998
+ "editor.foreground": colors.foregroundLight,
999
+ "editor.lineHighlightBackground": colors.lineHighlightLight,
1000
+ "editor.selectionBackground": colors.selectionLight,
1001
+ "editorLineNumber.foreground": colors.mutedForegroundLight,
1002
+ "editorWidget.background": colors.cardLight,
1003
+ "editorWidget.border": colors.borderLight
1004
+ }
1005
+ });
1006
+ registered.current = true;
1007
+ } catch {
1008
+ }
1009
+ }, [monaco]);
1010
+ if (themeOverride) return themeOverride;
1011
+ if (registered.current) {
1012
+ return appTheme === "dark" ? "app-dark" : "app-light";
1013
+ }
1014
+ return appTheme === "dark" ? "vs-dark" : "vs";
1015
+ }
1016
+ chunkWGEGR3DF_cjs.__name(useEditorTheme, "useEditorTheme");
1017
+ function _readCSSColors() {
1018
+ const get = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name((varName) => {
1019
+ if (typeof document === "undefined") return "";
1020
+ return getComputedStyle(document.documentElement).getPropertyValue(varName).trim();
1021
+ }, "get");
1022
+ const hslToHex2 = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name((hsl) => {
1023
+ if (!hsl) return "";
1024
+ const parts = hsl.split(/\s+/).map((s2) => parseFloat(s2.replace("%", "")));
1025
+ if (parts.length < 3 || parts.some(isNaN)) return "";
1026
+ const [h, s, l] = [parts[0], parts[1] / 100, parts[2] / 100];
1027
+ const a = s * Math.min(l, 1 - l);
1028
+ const f = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name((n) => {
1029
+ const k = (n + h / 30) % 12;
1030
+ const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
1031
+ return Math.round(255 * color).toString(16).padStart(2, "0");
1032
+ }, "f");
1033
+ return `#${f(0)}${f(8)}${f(4)}`;
1034
+ }, "hslToHex");
1035
+ const background = hslToHex2(get("--background")) || "#0a0a0a";
1036
+ const foreground = hslToHex2(get("--foreground")) || "#f5f5f5";
1037
+ const card = hslToHex2(get("--card")) || "#141414";
1038
+ const border = hslToHex2(get("--border")) || "#262626";
1039
+ const mutedForeground = hslToHex2(get("--muted-foreground")) || "#858585";
1040
+ const lineHighlight = _adjustBrightness(background, 10);
1041
+ const primary = hslToHex2(get("--primary"));
1042
+ const selection = primary ? _adjustBrightness(primary, -40) : "#264F78";
1043
+ return {
1044
+ background,
1045
+ foreground,
1046
+ card,
1047
+ border,
1048
+ mutedForeground,
1049
+ lineHighlight,
1050
+ selection,
1051
+ // Light variants
1052
+ backgroundLight: "#ffffff",
1053
+ foregroundLight: "#1a1a1a",
1054
+ cardLight: "#ffffff",
1055
+ borderLight: "#e5e5e5",
1056
+ mutedForegroundLight: "#737373",
1057
+ lineHighlightLight: "#f5f5f5",
1058
+ selectionLight: "#ADD6FF"
1059
+ };
1060
+ }
1061
+ chunkWGEGR3DF_cjs.__name(_readCSSColors, "_readCSSColors");
1062
+ function _adjustBrightness(hex, amount) {
1063
+ const num = parseInt(hex.replace("#", ""), 16);
1064
+ const r = Math.min(255, Math.max(0, (num >> 16 & 255) + amount));
1065
+ const g = Math.min(255, Math.max(0, (num >> 8 & 255) + amount));
1066
+ const b = Math.min(255, Math.max(0, (num & 255) + amount));
1067
+ return `#${(r << 16 | g << 8 | b).toString(16).padStart(6, "0")}`;
1068
+ }
1069
+ chunkWGEGR3DF_cjs.__name(_adjustBrightness, "_adjustBrightness");
1070
+ var Editor = React3.forwardRef(/* @__PURE__ */ chunkWGEGR3DF_cjs.__name(function Editor2({
1071
+ value = "",
1072
+ language = "plaintext",
1073
+ onChange,
1074
+ onMount,
1075
+ options = {},
1076
+ className = "",
1077
+ height = "100%",
1078
+ width = "100%",
1079
+ autoHeight = false,
1080
+ minHeight = 100,
1081
+ maxHeight = 600
1082
+ }, ref) {
1083
+ const containerRef = React3.useRef(null);
1084
+ const editorRef = React3.useRef(null);
1085
+ const { monaco, isLoading } = useMonaco();
1086
+ const resolvedTheme = useEditorTheme(monaco, options.theme);
1087
+ const [contentHeight, setContentHeight] = React3.useState(null);
1088
+ const updateContentHeight = React3.useCallback((editor) => {
1089
+ if (!autoHeight) return;
1090
+ const h = editor.getContentHeight();
1091
+ setContentHeight(Math.min(Math.max(h, minHeight), maxHeight));
1092
+ }, [autoHeight, minHeight, maxHeight]);
1093
+ const isInternalChangeRef = React3.useRef(false);
1094
+ React3.useImperativeHandle(ref, () => ({
1095
+ getEditor: /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => editorRef.current, "getEditor"),
1096
+ getValue: /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => editorRef.current?.getValue() || "", "getValue"),
1097
+ setValue: /* @__PURE__ */ chunkWGEGR3DF_cjs.__name((val) => editorRef.current?.setValue(val), "setValue"),
1098
+ focus: /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => editorRef.current?.focus(), "focus")
1099
+ }));
1100
+ React3.useEffect(() => {
1101
+ if (!monaco || !containerRef.current || editorRef.current) return;
1102
+ const editor = monaco.editor.create(containerRef.current, {
1103
+ value,
1104
+ language,
1105
+ theme: resolvedTheme,
1106
+ fontSize: options.fontSize || 14,
1107
+ fontFamily: options.fontFamily || "'Fira Code', 'Consolas', monospace",
1108
+ tabSize: options.tabSize || 2,
1109
+ insertSpaces: options.insertSpaces !== false,
1110
+ wordWrap: options.wordWrap || "on",
1111
+ minimap: { enabled: options.minimap !== false },
1112
+ lineNumbers: options.lineNumbers || "on",
1113
+ readOnly: options.readOnly || false,
1114
+ automaticLayout: true,
1115
+ scrollBeyondLastLine: autoHeight ? false : false,
1116
+ scrollbar: autoHeight ? { vertical: "hidden", horizontal: "auto" } : void 0,
1117
+ overviewRulerLanes: autoHeight ? 0 : void 0,
1118
+ padding: { top: 16, bottom: 16 },
1119
+ renderLineHighlight: "all",
1120
+ cursorBlinking: "smooth",
1121
+ cursorSmoothCaretAnimation: "on",
1122
+ smoothScrolling: true,
1123
+ bracketPairColorization: { enabled: true },
1124
+ guides: {
1125
+ bracketPairs: true,
1126
+ indentation: true
1127
+ }
1128
+ });
1129
+ editorRef.current = editor;
1130
+ if (onChange) {
1131
+ editor.onDidChangeModelContent(() => {
1132
+ isInternalChangeRef.current = true;
1133
+ onChange(editor.getValue());
1134
+ });
1135
+ }
1136
+ if (autoHeight) {
1137
+ editor.onDidContentSizeChange(() => updateContentHeight(editor));
1138
+ updateContentHeight(editor);
1139
+ }
1140
+ onMount?.(editor);
1141
+ return () => {
1142
+ editor.dispose();
1143
+ editorRef.current = null;
1144
+ };
1145
+ }, [monaco]);
1146
+ React3.useEffect(() => {
1147
+ const editor = editorRef.current;
1148
+ if (!editor) return;
1149
+ if (isInternalChangeRef.current) {
1150
+ isInternalChangeRef.current = false;
1151
+ return;
1152
+ }
1153
+ const currentValue = editor.getValue();
1154
+ if (value !== currentValue) {
1155
+ const position = editor.getPosition();
1156
+ const selections = editor.getSelections();
1157
+ editor.setValue(value);
1158
+ if (position) {
1159
+ editor.setPosition(position);
1160
+ }
1161
+ if (selections && selections.length > 0) {
1162
+ editor.setSelections(selections);
1163
+ }
1164
+ }
1165
+ }, [value]);
1166
+ React3.useEffect(() => {
1167
+ const editor = editorRef.current;
1168
+ if (!editor || !monaco) return;
1169
+ const model = editor.getModel();
1170
+ if (model) {
1171
+ monaco.editor.setModelLanguage(model, language);
1172
+ }
1173
+ }, [language, monaco]);
1174
+ React3.useEffect(() => {
1175
+ const editor = editorRef.current;
1176
+ if (!editor) return;
1177
+ editor.updateOptions({
1178
+ theme: resolvedTheme,
1179
+ fontSize: options.fontSize,
1180
+ readOnly: options.readOnly,
1181
+ minimap: { enabled: options.minimap !== false },
1182
+ wordWrap: options.wordWrap,
1183
+ lineNumbers: options.lineNumbers
1184
+ });
1185
+ }, [options, resolvedTheme]);
1186
+ if (isLoading) {
1187
+ return /* @__PURE__ */ jsxRuntime.jsx(
1188
+ "div",
1189
+ {
1190
+ className,
1191
+ style: {
1192
+ width,
1193
+ height,
1194
+ display: "flex",
1195
+ alignItems: "center",
1196
+ justifyContent: "center",
1197
+ backgroundColor: "#1e1e1e",
1198
+ color: "#666"
1199
+ },
1200
+ children: "Loading editor..."
1201
+ }
1202
+ );
1203
+ }
1204
+ const resolvedHeight = autoHeight && contentHeight != null ? contentHeight : height;
1205
+ return /* @__PURE__ */ jsxRuntime.jsx(
1206
+ "div",
1207
+ {
1208
+ ref: containerRef,
1209
+ className,
1210
+ style: {
1211
+ width,
1212
+ height: resolvedHeight,
1213
+ ...autoHeight && { minHeight, maxHeight, overflow: "hidden" }
1214
+ }
1215
+ }
1216
+ );
1217
+ }, "Editor"));
1218
+ function DiffEditor({
1219
+ original,
1220
+ modified,
1221
+ language = "plaintext",
1222
+ options = {},
1223
+ className = "",
1224
+ height = "100%"
1225
+ }) {
1226
+ const containerRef = React3.useRef(null);
1227
+ const editorRef = React3.useRef(null);
1228
+ const { monaco, isLoading } = useMonaco();
1229
+ const resolvedTheme = useEditorTheme(monaco, options.theme);
1230
+ React3.useEffect(() => {
1231
+ if (!monaco || !containerRef.current || editorRef.current) return;
1232
+ const editor = monaco.editor.createDiffEditor(containerRef.current, {
1233
+ theme: resolvedTheme,
1234
+ fontSize: options.fontSize || 14,
1235
+ fontFamily: options.fontFamily || "'Fira Code', 'Consolas', monospace",
1236
+ readOnly: true,
1237
+ automaticLayout: true,
1238
+ renderSideBySide: true,
1239
+ scrollBeyondLastLine: false,
1240
+ minimap: { enabled: false }
1241
+ });
1242
+ const originalModel = monaco.editor.createModel(original, language);
1243
+ const modifiedModel = monaco.editor.createModel(modified, language);
1244
+ editor.setModel({
1245
+ original: originalModel,
1246
+ modified: modifiedModel
1247
+ });
1248
+ editorRef.current = editor;
1249
+ return () => {
1250
+ originalModel.dispose();
1251
+ modifiedModel.dispose();
1252
+ editor.dispose();
1253
+ editorRef.current = null;
1254
+ };
1255
+ }, [monaco]);
1256
+ React3.useEffect(() => {
1257
+ const editor = editorRef.current;
1258
+ if (!editor || !monaco) return;
1259
+ const model = editor.getModel();
1260
+ if (model) {
1261
+ model.original.setValue(original);
1262
+ model.modified.setValue(modified);
1263
+ }
1264
+ }, [original, modified, monaco]);
1265
+ React3.useEffect(() => {
1266
+ const editor = editorRef.current;
1267
+ if (!editor || !monaco) return;
1268
+ const model = editor.getModel();
1269
+ if (model) {
1270
+ monaco.editor.setModelLanguage(model.original, language);
1271
+ monaco.editor.setModelLanguage(model.modified, language);
1272
+ }
1273
+ }, [language, monaco]);
1274
+ if (isLoading) {
1275
+ return /* @__PURE__ */ jsxRuntime.jsx(
1276
+ "div",
1277
+ {
1278
+ className,
1279
+ style: {
1280
+ width: "100%",
1281
+ height,
1282
+ display: "flex",
1283
+ alignItems: "center",
1284
+ justifyContent: "center",
1285
+ backgroundColor: "#1e1e1e",
1286
+ color: "#666"
1287
+ },
1288
+ children: "Loading diff editor..."
1289
+ }
1290
+ );
1291
+ }
1292
+ return /* @__PURE__ */ jsxRuntime.jsx(
1293
+ "div",
1294
+ {
1295
+ ref: containerRef,
1296
+ className,
1297
+ style: {
1298
+ width: "100%",
1299
+ height
1300
+ }
1301
+ }
1302
+ );
1303
+ }
1304
+ chunkWGEGR3DF_cjs.__name(DiffEditor, "DiffEditor");
1305
+
1306
+ // src/tools/CodeEditor/lib/languages.ts
1307
+ var LANGUAGE_MAP = {
1308
+ // Web
1309
+ ".html": "html",
1310
+ ".htm": "html",
1311
+ ".xhtml": "html",
1312
+ ".vue": "html",
1313
+ ".svelte": "html",
1314
+ // CSS
1315
+ ".css": "css",
1316
+ ".scss": "scss",
1317
+ ".sass": "scss",
1318
+ ".less": "less",
1319
+ // JavaScript/TypeScript
1320
+ ".js": "javascript",
1321
+ ".mjs": "javascript",
1322
+ ".cjs": "javascript",
1323
+ ".jsx": "javascript",
1324
+ ".ts": "typescript",
1325
+ ".tsx": "typescript",
1326
+ ".mts": "typescript",
1327
+ ".cts": "typescript",
1328
+ // Data formats
1329
+ ".json": "json",
1330
+ ".jsonc": "json",
1331
+ ".json5": "json",
1332
+ ".yaml": "yaml",
1333
+ ".yml": "yaml",
1334
+ ".toml": "ini",
1335
+ ".xml": "xml",
1336
+ ".svg": "xml",
1337
+ ".xsl": "xml",
1338
+ ".xsd": "xml",
1339
+ // Markdown & Documentation
1340
+ ".md": "markdown",
1341
+ ".mdx": "markdown",
1342
+ ".markdown": "markdown",
1343
+ ".rst": "restructuredtext",
1344
+ ".txt": "plaintext",
1345
+ ".text": "plaintext",
1346
+ // Programming languages
1347
+ ".py": "python",
1348
+ ".pyw": "python",
1349
+ ".pyi": "python",
1350
+ ".rb": "ruby",
1351
+ ".rake": "ruby",
1352
+ ".gemspec": "ruby",
1353
+ ".php": "php",
1354
+ ".phtml": "php",
1355
+ ".java": "java",
1356
+ ".kt": "kotlin",
1357
+ ".kts": "kotlin",
1358
+ ".scala": "scala",
1359
+ ".go": "go",
1360
+ ".rs": "rust",
1361
+ ".swift": "swift",
1362
+ ".c": "c",
1363
+ ".h": "c",
1364
+ ".cpp": "cpp",
1365
+ ".cc": "cpp",
1366
+ ".cxx": "cpp",
1367
+ ".hpp": "cpp",
1368
+ ".hxx": "cpp",
1369
+ ".cs": "csharp",
1370
+ ".fs": "fsharp",
1371
+ ".fsx": "fsharp",
1372
+ ".vb": "vb",
1373
+ ".lua": "lua",
1374
+ ".r": "r",
1375
+ ".R": "r",
1376
+ ".m": "objective-c",
1377
+ ".mm": "objective-c",
1378
+ ".pl": "perl",
1379
+ ".pm": "perl",
1380
+ ".ex": "elixir",
1381
+ ".exs": "elixir",
1382
+ ".erl": "erlang",
1383
+ ".hrl": "erlang",
1384
+ ".clj": "clojure",
1385
+ ".cljs": "clojure",
1386
+ ".cljc": "clojure",
1387
+ ".hs": "haskell",
1388
+ ".lhs": "haskell",
1389
+ ".ml": "fsharp",
1390
+ ".mli": "fsharp",
1391
+ ".dart": "dart",
1392
+ ".groovy": "groovy",
1393
+ ".gradle": "groovy",
1394
+ ".jl": "julia",
1395
+ // Shell & Scripts
1396
+ ".sh": "shell",
1397
+ ".bash": "shell",
1398
+ ".zsh": "shell",
1399
+ ".fish": "shell",
1400
+ ".ps1": "powershell",
1401
+ ".psm1": "powershell",
1402
+ ".psd1": "powershell",
1403
+ ".bat": "bat",
1404
+ ".cmd": "bat",
1405
+ // Config files
1406
+ ".ini": "ini",
1407
+ ".cfg": "ini",
1408
+ ".conf": "ini",
1409
+ ".properties": "ini",
1410
+ ".env": "ini",
1411
+ ".gitignore": "ini",
1412
+ ".gitattributes": "ini",
1413
+ ".editorconfig": "ini",
1414
+ ".npmrc": "ini",
1415
+ // Database
1416
+ ".sql": "sql",
1417
+ ".mysql": "mysql",
1418
+ ".pgsql": "pgsql",
1419
+ ".plsql": "plsql",
1420
+ ".redis": "redis",
1421
+ // Templates
1422
+ ".hbs": "handlebars",
1423
+ ".handlebars": "handlebars",
1424
+ ".mustache": "handlebars",
1425
+ ".ejs": "html",
1426
+ ".pug": "pug",
1427
+ ".jade": "pug",
1428
+ ".twig": "twig",
1429
+ ".liquid": "liquid",
1430
+ // GraphQL
1431
+ ".graphql": "graphql",
1432
+ ".gql": "graphql",
1433
+ // Docker
1434
+ ".dockerfile": "dockerfile",
1435
+ // Other
1436
+ ".diff": "diff",
1437
+ ".patch": "diff",
1438
+ ".log": "log",
1439
+ ".tex": "latex",
1440
+ ".cls": "latex",
1441
+ ".sty": "latex",
1442
+ ".proto": "protobuf",
1443
+ ".sol": "sol",
1444
+ ".asm": "mips",
1445
+ ".s": "mips",
1446
+ ".wasm": "wasm"
1447
+ };
1448
+ var FILENAME_MAP = {
1449
+ Dockerfile: "dockerfile",
1450
+ "docker-compose.yml": "yaml",
1451
+ "docker-compose.yaml": "yaml",
1452
+ Makefile: "makefile",
1453
+ makefile: "makefile",
1454
+ Gemfile: "ruby",
1455
+ Rakefile: "ruby",
1456
+ Jenkinsfile: "groovy",
1457
+ Vagrantfile: "ruby",
1458
+ ".bashrc": "shell",
1459
+ ".bash_profile": "shell",
1460
+ ".zshrc": "shell",
1461
+ ".profile": "shell",
1462
+ ".vimrc": "plaintext",
1463
+ ".gitconfig": "ini",
1464
+ ".htaccess": "ini",
1465
+ "nginx.conf": "ini",
1466
+ "package.json": "json",
1467
+ "tsconfig.json": "json",
1468
+ "jsconfig.json": "json",
1469
+ ".prettierrc": "json",
1470
+ ".eslintrc": "json",
1471
+ "composer.json": "json",
1472
+ "Cargo.toml": "ini",
1473
+ "go.mod": "go",
1474
+ "go.sum": "plaintext",
1475
+ "requirements.txt": "plaintext",
1476
+ "pyproject.toml": "ini",
1477
+ "setup.py": "python",
1478
+ "setup.cfg": "ini"
1479
+ };
1480
+ function getLanguageByFilename(filename) {
1481
+ if (FILENAME_MAP[filename]) {
1482
+ return FILENAME_MAP[filename];
1483
+ }
1484
+ const lastDot = filename.lastIndexOf(".");
1485
+ if (lastDot === -1) {
1486
+ return "plaintext";
1487
+ }
1488
+ const extension = filename.slice(lastDot).toLowerCase();
1489
+ return LANGUAGE_MAP[extension] || "plaintext";
1490
+ }
1491
+ chunkWGEGR3DF_cjs.__name(getLanguageByFilename, "getLanguageByFilename");
1492
+ var EditorContext = React3.createContext(null);
1493
+ function useEditorContext() {
1494
+ const context = React3.useContext(EditorContext);
1495
+ if (!context) {
1496
+ throw new Error("useEditorContext must be used within EditorProvider");
1497
+ }
1498
+ return context;
1499
+ }
1500
+ chunkWGEGR3DF_cjs.__name(useEditorContext, "useEditorContext");
1501
+ function EditorProvider({ children, onSave }) {
1502
+ const { monaco } = useMonaco();
1503
+ const [editor, setEditor] = React3.useState(null);
1504
+ const [openFiles, setOpenFiles] = React3.useState([]);
1505
+ const [activeFilePath, setActiveFilePath] = React3.useState(null);
1506
+ const activeFile = React3.useMemo(
1507
+ () => openFiles.find((f) => f.path === activeFilePath) || null,
1508
+ [openFiles, activeFilePath]
1509
+ );
1510
+ const openFile = React3.useCallback(
1511
+ (path, content, language) => {
1512
+ setOpenFiles((files) => {
1513
+ const existing = files.find((f) => f.path === path);
1514
+ if (existing) {
1515
+ return files;
1516
+ }
1517
+ const basename = path.split("/").pop() || path;
1518
+ const detectedLanguage = language || getLanguageByFilename(basename);
1519
+ const newFile = {
1520
+ path,
1521
+ content,
1522
+ language: detectedLanguage,
1523
+ isDirty: false
1524
+ };
1525
+ return [...files, newFile];
1526
+ });
1527
+ setActiveFilePath(path);
1528
+ },
1529
+ []
1530
+ );
1531
+ const closeFile = React3.useCallback(
1532
+ (path) => {
1533
+ setOpenFiles((files) => {
1534
+ const index = files.findIndex((f) => f.path === path);
1535
+ if (index === -1) return files;
1536
+ const newFiles = files.filter((f) => f.path !== path);
1537
+ if (activeFilePath === path && newFiles.length > 0) {
1538
+ const newIndex = Math.min(index, newFiles.length - 1);
1539
+ setActiveFilePath(newFiles[newIndex].path);
1540
+ } else if (newFiles.length === 0) {
1541
+ setActiveFilePath(null);
1542
+ }
1543
+ return newFiles;
1544
+ });
1545
+ },
1546
+ [activeFilePath]
1547
+ );
1548
+ const setActiveFile = React3.useCallback((path) => {
1549
+ setActiveFilePath(path);
1550
+ }, []);
1551
+ const updateContent = React3.useCallback((path, content) => {
1552
+ setOpenFiles(
1553
+ (files) => files.map(
1554
+ (f) => f.path === path ? { ...f, content, isDirty: true } : f
1555
+ )
1556
+ );
1557
+ }, []);
1558
+ const saveFile = React3.useCallback(
1559
+ async (path) => {
1560
+ const file = openFiles.find((f) => f.path === path);
1561
+ if (!file) return;
1562
+ if (onSave) {
1563
+ await onSave(path, file.content);
1564
+ }
1565
+ setOpenFiles(
1566
+ (files) => files.map(
1567
+ (f) => f.path === path ? { ...f, isDirty: false } : f
1568
+ )
1569
+ );
1570
+ },
1571
+ [openFiles, onSave]
1572
+ );
1573
+ const isDirty = React3.useCallback(
1574
+ (path) => {
1575
+ const file = openFiles.find((f) => f.path === path);
1576
+ return file?.isDirty || false;
1577
+ },
1578
+ [openFiles]
1579
+ );
1580
+ const getContent = React3.useCallback(
1581
+ (path) => {
1582
+ const file = openFiles.find((f) => f.path === path);
1583
+ return file?.content || null;
1584
+ },
1585
+ [openFiles]
1586
+ );
1587
+ const getFile = React3.useCallback(
1588
+ (path) => {
1589
+ return openFiles.find((f) => f.path === path) || null;
1590
+ },
1591
+ [openFiles]
1592
+ );
1593
+ const value = {
1594
+ openFiles,
1595
+ activeFile,
1596
+ monaco,
1597
+ editor,
1598
+ isReady: monaco !== null && editor !== null,
1599
+ openFile,
1600
+ closeFile,
1601
+ setActiveFile,
1602
+ updateContent,
1603
+ saveFile,
1604
+ isDirty,
1605
+ getContent,
1606
+ getFile
1607
+ };
1608
+ return /* @__PURE__ */ jsxRuntime.jsx(EditorContext.Provider, { value, children });
1609
+ }
1610
+ chunkWGEGR3DF_cjs.__name(EditorProvider, "EditorProvider");
1611
+ function useEditor() {
1612
+ const [editor, setEditorState] = React3.useState(null);
1613
+ const setEditor = React3.useCallback((editorInstance) => {
1614
+ setEditorState(editorInstance);
1615
+ }, []);
1616
+ return {
1617
+ editor,
1618
+ isReady: editor !== null,
1619
+ setEditor
1620
+ };
1621
+ }
1622
+ chunkWGEGR3DF_cjs.__name(useEditor, "useEditor");
1623
+ function useLanguage(filename) {
1624
+ return React3.useMemo(() => {
1625
+ if (!filename) return "plaintext";
1626
+ const basename = filename.split("/").pop() || filename;
1627
+ return getLanguageByFilename(basename);
1628
+ }, [filename]);
1629
+ }
1630
+ chunkWGEGR3DF_cjs.__name(useLanguage, "useLanguage");
1631
+
908
1632
  Object.defineProperty(exports, "AudioReactiveCover", {
909
1633
  enumerable: true,
910
1634
  get: function () { return chunkYZX6FH3H_cjs.AudioReactiveCover; }
@@ -1307,6 +2031,9 @@ Object.defineProperty(exports, "useLottie", {
1307
2031
  });
1308
2032
  exports.CardLoadingFallback = CardLoadingFallback;
1309
2033
  exports.CronScheduler = CronScheduler;
2034
+ exports.DiffEditor = DiffEditor;
2035
+ exports.Editor = Editor;
2036
+ exports.EditorProvider = EditorProvider;
1310
2037
  exports.LazyCronScheduler = LazyCronScheduler;
1311
2038
  exports.LazyHybridAudioPlayer = LazyHybridAudioPlayer;
1312
2039
  exports.LazyHybridCompactPlayer = LazyHybridCompactPlayer;
@@ -1331,5 +2058,9 @@ exports.OpenapiViewer = OpenapiViewer_default;
1331
2058
  exports.Spinner = Spinner;
1332
2059
  exports.createLazyComponent = createLazyComponent;
1333
2060
  exports.useCollapsibleContent = useCollapsibleContent;
2061
+ exports.useEditor = useEditor;
2062
+ exports.useEditorContext = useEditorContext;
2063
+ exports.useLanguage = useLanguage;
2064
+ exports.useMonaco = useMonaco;
1334
2065
  //# sourceMappingURL=index.cjs.map
1335
2066
  //# sourceMappingURL=index.cjs.map