@djangocfg/ui-tools 2.1.110 → 2.1.112

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.
Files changed (159) hide show
  1. package/README.md +242 -49
  2. package/dist/JsonSchemaForm-65NLLK56.mjs +4 -0
  3. package/dist/JsonSchemaForm-65NLLK56.mjs.map +1 -0
  4. package/dist/JsonSchemaForm-PY6DH3HE.cjs +13 -0
  5. package/dist/JsonSchemaForm-PY6DH3HE.cjs.map +1 -0
  6. package/dist/JsonTree-6RYAOPSS.mjs +4 -0
  7. package/dist/JsonTree-6RYAOPSS.mjs.map +1 -0
  8. package/dist/JsonTree-7OH6CIHT.cjs +10 -0
  9. package/dist/JsonTree-7OH6CIHT.cjs.map +1 -0
  10. package/dist/MapContainer-GXQLP5WY.mjs +214 -0
  11. package/dist/MapContainer-GXQLP5WY.mjs.map +1 -0
  12. package/dist/MapContainer-RYG4HPH4.cjs +221 -0
  13. package/dist/MapContainer-RYG4HPH4.cjs.map +1 -0
  14. package/dist/{Mermaid.client-4OCKJ6QD.mjs → Mermaid.client-OKACITCW.mjs} +16 -7
  15. package/dist/Mermaid.client-OKACITCW.mjs.map +1 -0
  16. package/dist/{Mermaid.client-ZP6OE46Z.cjs → Mermaid.client-PNXEC6YL.cjs} +16 -7
  17. package/dist/Mermaid.client-PNXEC6YL.cjs.map +1 -0
  18. package/dist/{PlaygroundLayout-XXVBU4WZ.cjs → PlaygroundLayout-SYMEAG3J.cjs} +25 -24
  19. package/dist/PlaygroundLayout-SYMEAG3J.cjs.map +1 -0
  20. package/dist/{PlaygroundLayout-LMQTVXSP.mjs → PlaygroundLayout-UQRBU5RH.mjs} +4 -3
  21. package/dist/PlaygroundLayout-UQRBU5RH.mjs.map +1 -0
  22. package/dist/{PrettyCode.client-2CLSV2VD.cjs → PrettyCode.client-DANYYQYO.cjs} +11 -4
  23. package/dist/PrettyCode.client-DANYYQYO.cjs.map +1 -0
  24. package/dist/{PrettyCode.client-Y2BVON7R.mjs → PrettyCode.client-RS5ZTNBT.mjs} +11 -4
  25. package/dist/PrettyCode.client-RS5ZTNBT.mjs.map +1 -0
  26. package/dist/chunk-2DSR7V2L.mjs +561 -0
  27. package/dist/chunk-2DSR7V2L.mjs.map +1 -0
  28. package/dist/chunk-47T5ECYV.cjs +1357 -0
  29. package/dist/chunk-47T5ECYV.cjs.map +1 -0
  30. package/dist/chunk-5QT3QYFZ.cjs +189 -0
  31. package/dist/chunk-5QT3QYFZ.cjs.map +1 -0
  32. package/dist/chunk-7IIRYG4S.mjs +1057 -0
  33. package/dist/chunk-7IIRYG4S.mjs.map +1 -0
  34. package/dist/{chunk-FB5QBSI3.cjs → chunk-DI3HUXHK.cjs} +15 -195
  35. package/dist/chunk-DI3HUXHK.cjs.map +1 -0
  36. package/dist/chunk-EVGWYASL.cjs +1528 -0
  37. package/dist/chunk-EVGWYASL.cjs.map +1 -0
  38. package/dist/chunk-F2N7P5XU.cjs +30 -0
  39. package/dist/chunk-F2N7P5XU.cjs.map +1 -0
  40. package/dist/{chunk-L6UHASYQ.mjs → chunk-G6PRZP5I.mjs} +7 -186
  41. package/dist/chunk-G6PRZP5I.mjs.map +1 -0
  42. package/dist/chunk-JWB2EWQO.mjs +5 -0
  43. package/dist/chunk-JWB2EWQO.mjs.map +1 -0
  44. package/dist/chunk-LTJX2JXE.mjs +338 -0
  45. package/dist/chunk-LTJX2JXE.mjs.map +1 -0
  46. package/dist/chunk-OVNC4KW6.mjs +1494 -0
  47. package/dist/chunk-OVNC4KW6.mjs.map +1 -0
  48. package/dist/chunk-PNZSJN6T.cjs +1086 -0
  49. package/dist/chunk-PNZSJN6T.cjs.map +1 -0
  50. package/dist/chunk-TEFRA7GW.cjs +565 -0
  51. package/dist/chunk-TEFRA7GW.cjs.map +1 -0
  52. package/dist/chunk-UOMPPIED.mjs +1343 -0
  53. package/dist/chunk-UOMPPIED.mjs.map +1 -0
  54. package/dist/chunk-W6YHQI4F.mjs +187 -0
  55. package/dist/chunk-W6YHQI4F.mjs.map +1 -0
  56. package/dist/chunk-XTBRWVIV.cjs +346 -0
  57. package/dist/chunk-XTBRWVIV.cjs.map +1 -0
  58. package/dist/components-C7ZL7OMY.mjs +5 -0
  59. package/dist/components-C7ZL7OMY.mjs.map +1 -0
  60. package/dist/components-CJ2IB65O.cjs +27 -0
  61. package/dist/components-CJ2IB65O.cjs.map +1 -0
  62. package/dist/components-EASJYK45.mjs +6 -0
  63. package/dist/components-EASJYK45.mjs.map +1 -0
  64. package/dist/components-LDRFDV4A.cjs +22 -0
  65. package/dist/components-LDRFDV4A.cjs.map +1 -0
  66. package/dist/components-VZKUTDJK.mjs +5 -0
  67. package/dist/components-VZKUTDJK.mjs.map +1 -0
  68. package/dist/components-Y64GTIMQ.cjs +42 -0
  69. package/dist/components-Y64GTIMQ.cjs.map +1 -0
  70. package/dist/index.cjs +701 -4813
  71. package/dist/index.cjs.map +1 -1
  72. package/dist/index.d.cts +1274 -1026
  73. package/dist/index.d.ts +1274 -1026
  74. package/dist/index.mjs +358 -4730
  75. package/dist/index.mjs.map +1 -1
  76. package/package.json +27 -4
  77. package/src/components/index.ts +17 -0
  78. package/src/components/lazy-wrapper.tsx +281 -0
  79. package/src/index.ts +92 -7
  80. package/src/tools/AudioPlayer/components/HybridAudioPlayer.tsx +14 -5
  81. package/src/tools/AudioPlayer/lazy.tsx +85 -0
  82. package/src/tools/Gallery/components/Gallery.tsx +182 -0
  83. package/src/tools/Gallery/components/GalleryCarousel.tsx +251 -0
  84. package/src/tools/Gallery/components/GalleryCompact.tsx +173 -0
  85. package/src/tools/Gallery/components/GalleryGrid.tsx +493 -0
  86. package/src/tools/Gallery/components/GalleryImage.tsx +66 -0
  87. package/src/tools/Gallery/components/GalleryLightbox.tsx +331 -0
  88. package/src/tools/Gallery/components/GalleryMedia.tsx +66 -0
  89. package/src/tools/Gallery/components/GalleryThumbnails.tsx +173 -0
  90. package/src/tools/Gallery/components/GalleryThumbnailsVirtual.tsx +138 -0
  91. package/src/tools/Gallery/components/GalleryVideo.tsx +222 -0
  92. package/src/tools/Gallery/components/index.ts +13 -0
  93. package/src/tools/Gallery/hooks/index.ts +23 -0
  94. package/src/tools/Gallery/hooks/useGallery.ts +137 -0
  95. package/src/tools/Gallery/hooks/useImageDimensions.ts +223 -0
  96. package/src/tools/Gallery/hooks/usePinchZoom.ts +234 -0
  97. package/src/tools/Gallery/hooks/usePreloadImages.ts +71 -0
  98. package/src/tools/Gallery/hooks/useSwipe.ts +86 -0
  99. package/src/tools/Gallery/hooks/useVirtualList.ts +129 -0
  100. package/src/tools/Gallery/hooks/useZoom.ts +316 -0
  101. package/src/tools/Gallery/index.ts +66 -0
  102. package/src/tools/Gallery/types.ts +183 -0
  103. package/src/tools/Gallery/utils/imageAnalysis.ts +52 -0
  104. package/src/tools/Gallery/utils/index.ts +11 -0
  105. package/src/tools/ImageViewer/components/ImageToolbar.tsx +20 -8
  106. package/src/tools/ImageViewer/components/ImageViewer.tsx +12 -4
  107. package/src/tools/ImageViewer/lazy.tsx +37 -0
  108. package/src/tools/JsonForm/lazy.tsx +43 -0
  109. package/src/tools/JsonForm/widgets/ColorWidget.tsx +4 -1
  110. package/src/tools/JsonTree/lazy.tsx +45 -0
  111. package/src/tools/LottiePlayer/lazy.tsx +57 -0
  112. package/src/tools/Map/components/CustomOverlay.tsx +54 -0
  113. package/src/tools/Map/components/DrawControl.tsx +36 -0
  114. package/src/tools/Map/components/GeocoderControl.tsx +70 -0
  115. package/src/tools/Map/components/LayerSwitcher.tsx +225 -0
  116. package/src/tools/Map/components/MapCluster.tsx +273 -0
  117. package/src/tools/Map/components/MapContainer.tsx +191 -0
  118. package/src/tools/Map/components/MapControls.tsx +44 -0
  119. package/src/tools/Map/components/MapLegend.tsx +161 -0
  120. package/src/tools/Map/components/MapMarker.tsx +102 -0
  121. package/src/tools/Map/components/MapPopup.tsx +46 -0
  122. package/src/tools/Map/components/MapSource.tsx +30 -0
  123. package/src/tools/Map/components/index.ts +20 -0
  124. package/src/tools/Map/context/MapContext.tsx +89 -0
  125. package/src/tools/Map/context/index.ts +2 -0
  126. package/src/tools/Map/hooks/index.ts +9 -0
  127. package/src/tools/Map/hooks/useMap.ts +11 -0
  128. package/src/tools/Map/hooks/useMapControl.ts +99 -0
  129. package/src/tools/Map/hooks/useMapEvents.ts +147 -0
  130. package/src/tools/Map/hooks/useMapLayers.ts +83 -0
  131. package/src/tools/Map/hooks/useMapViewport.ts +62 -0
  132. package/src/tools/Map/hooks/useMarkers.ts +85 -0
  133. package/src/tools/Map/index.ts +116 -0
  134. package/src/tools/Map/layers/cluster.ts +94 -0
  135. package/src/tools/Map/layers/index.ts +15 -0
  136. package/src/tools/Map/layers/line.ts +93 -0
  137. package/src/tools/Map/layers/point.ts +61 -0
  138. package/src/tools/Map/layers/polygon.ts +73 -0
  139. package/src/tools/Map/lazy.tsx +56 -0
  140. package/src/tools/Map/styles/index.ts +15 -0
  141. package/src/tools/Map/types.ts +259 -0
  142. package/src/tools/Map/utils/geo.ts +88 -0
  143. package/src/tools/Map/utils/index.ts +16 -0
  144. package/src/tools/Map/utils/transform.ts +107 -0
  145. package/src/tools/Mermaid/Mermaid.client.tsx +12 -4
  146. package/src/tools/Mermaid/components/MermaidFullscreenModal.tsx +6 -2
  147. package/src/tools/Mermaid/lazy.tsx +46 -0
  148. package/src/tools/OpenapiViewer/lazy.tsx +72 -0
  149. package/src/tools/PrettyCode/PrettyCode.client.tsx +10 -3
  150. package/src/tools/PrettyCode/lazy.tsx +64 -0
  151. package/src/tools/VideoPlayer/lazy.tsx +63 -0
  152. package/dist/Mermaid.client-4OCKJ6QD.mjs.map +0 -1
  153. package/dist/Mermaid.client-ZP6OE46Z.cjs.map +0 -1
  154. package/dist/PlaygroundLayout-LMQTVXSP.mjs.map +0 -1
  155. package/dist/PlaygroundLayout-XXVBU4WZ.cjs.map +0 -1
  156. package/dist/PrettyCode.client-2CLSV2VD.cjs.map +0 -1
  157. package/dist/PrettyCode.client-Y2BVON7R.mjs.map +0 -1
  158. package/dist/chunk-FB5QBSI3.cjs.map +0 -1
  159. package/dist/chunk-L6UHASYQ.mjs.map +0 -1
@@ -0,0 +1,221 @@
1
+ 'use strict';
2
+
3
+ var chunkWGEGR3DF_cjs = require('./chunk-WGEGR3DF.cjs');
4
+ var react = require('react');
5
+ var Map = require('react-map-gl/maplibre');
6
+ var lucideReact = require('lucide-react');
7
+ var lib = require('@djangocfg/ui-core/lib');
8
+ require('maplibre-gl/dist/maplibre-gl.css');
9
+ var jsxRuntime = require('react/jsx-runtime');
10
+
11
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
12
+
13
+ var Map__default = /*#__PURE__*/_interopDefault(Map);
14
+
15
+ var MapContext = react.createContext(null);
16
+ var DEFAULT_VIEWPORT = {
17
+ longitude: 115.1889,
18
+ latitude: -8.4095,
19
+ zoom: 10,
20
+ bearing: 0,
21
+ pitch: 0
22
+ };
23
+ function MapProvider({ children, initialViewport }) {
24
+ const mapRef = react.useRef(null);
25
+ const initialViewportRef = react.useRef({
26
+ ...DEFAULT_VIEWPORT,
27
+ ...initialViewport
28
+ });
29
+ const [viewport, setViewportState] = react.useState(initialViewportRef.current);
30
+ const [markers, setMarkers] = react.useState([]);
31
+ const [selectedMarker, setSelectedMarker] = react.useState(null);
32
+ const [hoveredFeature, setHoveredFeature] = react.useState(null);
33
+ const [isLoaded, setIsLoaded] = react.useState(false);
34
+ const setViewport = react.useCallback((newViewport) => {
35
+ setViewportState((prev) => ({ ...prev, ...newViewport }));
36
+ }, []);
37
+ const resetToInitial = react.useCallback(() => {
38
+ const map = mapRef.current;
39
+ if (map) {
40
+ map.flyTo({
41
+ center: [initialViewportRef.current.longitude, initialViewportRef.current.latitude],
42
+ zoom: initialViewportRef.current.zoom,
43
+ bearing: initialViewportRef.current.bearing ?? 0,
44
+ pitch: initialViewportRef.current.pitch ?? 0,
45
+ duration: 1e3
46
+ });
47
+ }
48
+ }, []);
49
+ const value = react.useMemo(
50
+ () => ({
51
+ mapRef,
52
+ viewport,
53
+ setViewport,
54
+ initialViewport: initialViewportRef.current,
55
+ resetToInitial,
56
+ markers,
57
+ setMarkers,
58
+ selectedMarker,
59
+ setSelectedMarker,
60
+ hoveredFeature,
61
+ setHoveredFeature,
62
+ isLoaded,
63
+ setIsLoaded
64
+ }),
65
+ [viewport, setViewport, resetToInitial, markers, selectedMarker, hoveredFeature, isLoaded]
66
+ );
67
+ return /* @__PURE__ */ jsxRuntime.jsx(MapContext.Provider, { value, children });
68
+ }
69
+ chunkWGEGR3DF_cjs.__name(MapProvider, "MapProvider");
70
+ function useMapContext() {
71
+ const context = react.useContext(MapContext);
72
+ if (!context) {
73
+ throw new Error("useMapContext must be used within a MapProvider");
74
+ }
75
+ return context;
76
+ }
77
+ chunkWGEGR3DF_cjs.__name(useMapContext, "useMapContext");
78
+
79
+ // src/tools/Map/styles/index.ts
80
+ var MAP_STYLES = {
81
+ light: "https://basemaps.cartocdn.com/gl/positron-gl-style/style.json",
82
+ dark: "https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json",
83
+ streets: "https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json",
84
+ satellite: "https://api.maptiler.com/maps/satellite/style.json"
85
+ };
86
+ function MapInner({
87
+ children,
88
+ mapStyle = "light",
89
+ interactiveLayerIds,
90
+ style,
91
+ cursor,
92
+ attributionControl = true,
93
+ reuseMaps = true,
94
+ openInMapsUrl,
95
+ openInMapsLabel = "Open in Maps",
96
+ autoResetDelay = 0,
97
+ showResetButton = false
98
+ }) {
99
+ const { mapRef, viewport, setViewport, setIsLoaded, resetToInitial, initialViewport } = useMapContext();
100
+ const resetTimerRef = react.useRef(null);
101
+ const isInteractingRef = react.useRef(false);
102
+ const hasViewportChanged = Math.abs(viewport.longitude - initialViewport.longitude) > 1e-4 || Math.abs(viewport.latitude - initialViewport.latitude) > 1e-4 || Math.abs(viewport.zoom - initialViewport.zoom) > 0.1;
103
+ const handleMove = react.useCallback(
104
+ (evt) => {
105
+ setViewport({
106
+ longitude: evt.viewState.longitude,
107
+ latitude: evt.viewState.latitude,
108
+ zoom: evt.viewState.zoom,
109
+ bearing: evt.viewState.bearing,
110
+ pitch: evt.viewState.pitch
111
+ });
112
+ },
113
+ [setViewport]
114
+ );
115
+ const handleMoveStart = react.useCallback(() => {
116
+ isInteractingRef.current = true;
117
+ if (resetTimerRef.current) {
118
+ clearTimeout(resetTimerRef.current);
119
+ resetTimerRef.current = null;
120
+ }
121
+ }, []);
122
+ const handleMoveEnd = react.useCallback(() => {
123
+ isInteractingRef.current = false;
124
+ if (autoResetDelay > 0) {
125
+ resetTimerRef.current = setTimeout(() => {
126
+ if (!isInteractingRef.current) {
127
+ resetToInitial();
128
+ }
129
+ }, autoResetDelay);
130
+ }
131
+ }, [autoResetDelay, resetToInitial]);
132
+ const handleLoad = react.useCallback(() => {
133
+ setIsLoaded(true);
134
+ }, [setIsLoaded]);
135
+ react.useEffect(() => {
136
+ return () => {
137
+ if (resetTimerRef.current) {
138
+ clearTimeout(resetTimerRef.current);
139
+ }
140
+ };
141
+ }, []);
142
+ const resolvedStyle = mapStyle in MAP_STYLES ? MAP_STYLES[mapStyle] : mapStyle;
143
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
144
+ /* @__PURE__ */ jsxRuntime.jsx(
145
+ Map__default.default,
146
+ {
147
+ ref: mapRef,
148
+ ...viewport,
149
+ onMove: handleMove,
150
+ onMoveStart: handleMoveStart,
151
+ onMoveEnd: handleMoveEnd,
152
+ onLoad: handleLoad,
153
+ mapStyle: resolvedStyle,
154
+ interactiveLayerIds,
155
+ attributionControl: attributionControl ? {} : false,
156
+ reuseMaps,
157
+ style: {
158
+ width: "100%",
159
+ height: "100%",
160
+ ...style
161
+ },
162
+ cursor,
163
+ children
164
+ }
165
+ ),
166
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute bottom-3 right-3 flex items-center gap-2", children: [
167
+ showResetButton && hasViewportChanged && /* @__PURE__ */ jsxRuntime.jsxs(
168
+ "button",
169
+ {
170
+ type: "button",
171
+ onClick: resetToInitial,
172
+ className: lib.cn(
173
+ "inline-flex items-center gap-2 px-3 py-2 rounded-lg",
174
+ "bg-background/95 backdrop-blur-sm text-foreground text-sm font-medium",
175
+ "hover:bg-background transition-colors shadow-sm border border-border"
176
+ ),
177
+ children: [
178
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCcw, { className: "w-4 h-4" }),
179
+ "Reset"
180
+ ]
181
+ }
182
+ ),
183
+ openInMapsUrl && /* @__PURE__ */ jsxRuntime.jsxs(
184
+ "a",
185
+ {
186
+ href: openInMapsUrl,
187
+ target: "_blank",
188
+ rel: "noopener noreferrer",
189
+ className: lib.cn(
190
+ "inline-flex items-center gap-2 px-4 py-2 rounded-lg",
191
+ "bg-background/95 backdrop-blur-sm text-foreground text-sm font-medium",
192
+ "hover:bg-background transition-colors shadow-sm border border-border"
193
+ ),
194
+ children: [
195
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "w-4 h-4" }),
196
+ openInMapsLabel
197
+ ]
198
+ }
199
+ )
200
+ ] })
201
+ ] });
202
+ }
203
+ chunkWGEGR3DF_cjs.__name(MapInner, "MapInner");
204
+ function MapContainer({
205
+ children,
206
+ initialViewport,
207
+ className,
208
+ ...props
209
+ }) {
210
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { width: "100%", height: "100%", position: "relative" }, children: /* @__PURE__ */ jsxRuntime.jsx(MapProvider, { initialViewport, children: /* @__PURE__ */ jsxRuntime.jsx(MapInner, { ...props, children }) }) });
211
+ }
212
+ chunkWGEGR3DF_cjs.__name(MapContainer, "MapContainer");
213
+ function MapView(props) {
214
+ return /* @__PURE__ */ jsxRuntime.jsx(MapInner, { ...props });
215
+ }
216
+ chunkWGEGR3DF_cjs.__name(MapView, "MapView");
217
+
218
+ exports.MapContainer = MapContainer;
219
+ exports.MapView = MapView;
220
+ //# sourceMappingURL=MapContainer-RYG4HPH4.cjs.map
221
+ //# sourceMappingURL=MapContainer-RYG4HPH4.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tools/Map/context/MapContext.tsx","../src/tools/Map/styles/index.ts","../src/tools/Map/components/MapContainer.tsx"],"names":["createContext","useRef","useState","useCallback","useMemo","jsx","__name","useContext","useEffect","jsxs","Fragment","Map","cn","RotateCcw","ExternalLink"],"mappings":"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","file":"MapContainer-RYG4HPH4.cjs","sourcesContent":["'use client'\n\nimport {\n createContext,\n useContext,\n useState,\n useRef,\n useMemo,\n useCallback,\n type ReactNode,\n} from 'react'\nimport type { MapRef } from 'react-map-gl/maplibre'\nimport type { MapContextValue, MapViewport, MarkerData } from '../types'\n\nconst MapContext = createContext<MapContextValue | null>(null)\n\nexport interface MapProviderProps {\n children: ReactNode\n initialViewport?: Partial<MapViewport>\n}\n\nconst DEFAULT_VIEWPORT: MapViewport = {\n longitude: 115.1889,\n latitude: -8.4095,\n zoom: 10,\n bearing: 0,\n pitch: 0,\n}\n\nexport function MapProvider({ children, initialViewport }: MapProviderProps) {\n const mapRef = useRef<MapRef | null>(null)\n const initialViewportRef = useRef<MapViewport>({\n ...DEFAULT_VIEWPORT,\n ...initialViewport,\n })\n const [viewport, setViewportState] = useState<MapViewport>(initialViewportRef.current)\n const [markers, setMarkers] = useState<MarkerData[]>([])\n const [selectedMarker, setSelectedMarker] = useState<MarkerData | null>(null)\n const [hoveredFeature, setHoveredFeature] = useState<GeoJSON.Feature | null>(null)\n const [isLoaded, setIsLoaded] = useState(false)\n\n const setViewport = useCallback((newViewport: Partial<MapViewport>) => {\n setViewportState((prev) => ({ ...prev, ...newViewport }))\n }, [])\n\n const resetToInitial = useCallback(() => {\n const map = mapRef.current\n if (map) {\n map.flyTo({\n center: [initialViewportRef.current.longitude, initialViewportRef.current.latitude],\n zoom: initialViewportRef.current.zoom,\n bearing: initialViewportRef.current.bearing ?? 0,\n pitch: initialViewportRef.current.pitch ?? 0,\n duration: 1000,\n })\n }\n }, [])\n\n const value = useMemo<MapContextValue>(\n () => ({\n mapRef,\n viewport,\n setViewport,\n initialViewport: initialViewportRef.current,\n resetToInitial,\n markers,\n setMarkers,\n selectedMarker,\n setSelectedMarker,\n hoveredFeature,\n setHoveredFeature,\n isLoaded,\n setIsLoaded,\n }),\n [viewport, setViewport, resetToInitial, markers, selectedMarker, hoveredFeature, isLoaded]\n )\n\n return <MapContext.Provider value={value}>{children}</MapContext.Provider>\n}\n\nexport function useMapContext(): MapContextValue {\n const context = useContext(MapContext)\n if (!context) {\n throw new Error('useMapContext must be used within a MapProvider')\n }\n return context\n}\n\nexport { MapContext }\n","export const MAP_STYLES = {\n light: 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json',\n dark: 'https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json',\n streets: 'https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json',\n satellite: 'https://api.maptiler.com/maps/satellite/style.json',\n} as const\n\nexport type MapStyleKey = keyof typeof MAP_STYLES\n\nexport function getMapStyle(key: MapStyleKey | string): string {\n if (key in MAP_STYLES) {\n return MAP_STYLES[key as MapStyleKey]\n }\n return key\n}\n","'use client'\n\nimport { useCallback, useEffect, useRef, type ReactNode } from 'react'\nimport Map, { type ViewStateChangeEvent } from 'react-map-gl/maplibre'\nimport { ExternalLink, RotateCcw } from 'lucide-react'\nimport { cn } from '@djangocfg/ui-core/lib'\nimport 'maplibre-gl/dist/maplibre-gl.css'\n\nimport { MapProvider, useMapContext } from '../context'\nimport { MAP_STYLES } from '../styles'\nimport type { MapViewport, MapStyleKey } from '../types'\n\nexport interface MapContainerProps {\n children?: ReactNode\n initialViewport?: Partial<MapViewport>\n mapStyle?: MapStyleKey | string\n interactiveLayerIds?: string[]\n className?: string\n style?: React.CSSProperties\n cursor?: string\n attributionControl?: boolean\n reuseMaps?: boolean\n /** URL to open in external maps app (shows \"Open in Maps\" button if provided) */\n openInMapsUrl?: string\n /** Label for the open in maps button */\n openInMapsLabel?: string\n /** Auto-reset to initial viewport after N ms of inactivity (0 = disabled) */\n autoResetDelay?: number\n /** Show reset button */\n showResetButton?: boolean\n}\n\ninterface MapInnerProps extends Omit<MapContainerProps, 'initialViewport'> {}\n\nfunction MapInner({\n children,\n mapStyle = 'light',\n interactiveLayerIds,\n style,\n cursor,\n attributionControl = true,\n reuseMaps = true,\n openInMapsUrl,\n openInMapsLabel = 'Open in Maps',\n autoResetDelay = 0,\n showResetButton = false,\n}: MapInnerProps) {\n const { mapRef, viewport, setViewport, setIsLoaded, resetToInitial, initialViewport } = useMapContext()\n const resetTimerRef = useRef<NodeJS.Timeout | null>(null)\n const isInteractingRef = useRef(false)\n\n // Check if viewport has changed from initial\n const hasViewportChanged =\n Math.abs(viewport.longitude - initialViewport.longitude) > 0.0001 ||\n Math.abs(viewport.latitude - initialViewport.latitude) > 0.0001 ||\n Math.abs(viewport.zoom - initialViewport.zoom) > 0.1\n\n const handleMove = useCallback(\n (evt: ViewStateChangeEvent) => {\n setViewport({\n longitude: evt.viewState.longitude,\n latitude: evt.viewState.latitude,\n zoom: evt.viewState.zoom,\n bearing: evt.viewState.bearing,\n pitch: evt.viewState.pitch,\n })\n },\n [setViewport]\n )\n\n const handleMoveStart = useCallback(() => {\n isInteractingRef.current = true\n // Clear any pending reset timer\n if (resetTimerRef.current) {\n clearTimeout(resetTimerRef.current)\n resetTimerRef.current = null\n }\n }, [])\n\n const handleMoveEnd = useCallback(() => {\n isInteractingRef.current = false\n // Start auto-reset timer if enabled\n if (autoResetDelay > 0) {\n resetTimerRef.current = setTimeout(() => {\n if (!isInteractingRef.current) {\n resetToInitial()\n }\n }, autoResetDelay)\n }\n }, [autoResetDelay, resetToInitial])\n\n const handleLoad = useCallback(() => {\n setIsLoaded(true)\n }, [setIsLoaded])\n\n // Cleanup timer on unmount\n useEffect(() => {\n return () => {\n if (resetTimerRef.current) {\n clearTimeout(resetTimerRef.current)\n }\n }\n }, [])\n\n const resolvedStyle = mapStyle in MAP_STYLES\n ? MAP_STYLES[mapStyle as MapStyleKey]\n : mapStyle\n\n return (\n <>\n <Map\n ref={mapRef}\n {...viewport}\n onMove={handleMove}\n onMoveStart={handleMoveStart}\n onMoveEnd={handleMoveEnd}\n onLoad={handleLoad}\n mapStyle={resolvedStyle}\n interactiveLayerIds={interactiveLayerIds}\n attributionControl={attributionControl ? {} : false}\n reuseMaps={reuseMaps}\n style={{\n width: '100%',\n height: '100%',\n ...style,\n }}\n cursor={cursor}\n >\n {children}\n </Map>\n\n {/* Map overlay buttons */}\n <div className=\"absolute bottom-3 right-3 flex items-center gap-2\">\n {/* Reset button */}\n {showResetButton && hasViewportChanged && (\n <button\n type=\"button\"\n onClick={resetToInitial}\n className={cn(\n 'inline-flex items-center gap-2 px-3 py-2 rounded-lg',\n 'bg-background/95 backdrop-blur-sm text-foreground text-sm font-medium',\n 'hover:bg-background transition-colors shadow-sm border border-border'\n )}\n >\n <RotateCcw className=\"w-4 h-4\" />\n Reset\n </button>\n )}\n\n {/* Open in Maps button */}\n {openInMapsUrl && (\n <a\n href={openInMapsUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={cn(\n 'inline-flex items-center gap-2 px-4 py-2 rounded-lg',\n 'bg-background/95 backdrop-blur-sm text-foreground text-sm font-medium',\n 'hover:bg-background transition-colors shadow-sm border border-border'\n )}\n >\n <ExternalLink className=\"w-4 h-4\" />\n {openInMapsLabel}\n </a>\n )}\n </div>\n </>\n )\n}\n\nexport function MapContainer({\n children,\n initialViewport,\n className,\n ...props\n}: MapContainerProps) {\n return (\n <div className={className} style={{ width: '100%', height: '100%', position: 'relative' }}>\n <MapProvider initialViewport={initialViewport}>\n <MapInner {...props}>{children}</MapInner>\n </MapProvider>\n </div>\n )\n}\n\n/**\n * Use this when you need the map inside an existing MapProvider\n */\nexport function MapView(props: Omit<MapContainerProps, 'initialViewport'>) {\n return <MapInner {...props} />\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  import { __name } from './chunk-CGILA3WO.mjs';
2
+ import { useState, useRef, useEffect, useCallback, useMemo } from 'react';
3
+ import { useTypedT } from '@djangocfg/i18n';
2
4
  import { useResolvedTheme } from '@djangocfg/ui-core/hooks';
3
- import { useState, useRef, useEffect, useCallback } from 'react';
4
5
  import { createPortal } from 'react-dom';
5
6
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
6
7
  import mermaid from 'mermaid';
@@ -82,6 +83,8 @@ var MermaidFullscreenModal = /* @__PURE__ */ __name(({
82
83
  onClose,
83
84
  onBackdropClick
84
85
  }) => {
86
+ const t = useTypedT();
87
+ const diagramTitle = useMemo(() => t("tools.diagram.title"), [t]);
85
88
  useEffect(() => {
86
89
  if (isOpen && fullscreenRef.current) {
87
90
  const getCSSVariable = /* @__PURE__ */ __name((variable) => {
@@ -113,7 +116,7 @@ var MermaidFullscreenModal = /* @__PURE__ */ __name(({
113
116
  onClick: onBackdropClick,
114
117
  children: /* @__PURE__ */ jsxs("div", { className: `relative bg-card rounded-sm shadow-xl max-h-[95vh] flex flex-col border border-border ${isVertical ? "w-auto min-w-[400px] max-w-[600px]" : "min-w-[600px] max-w-[90vw] w-auto"}`, children: [
115
118
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between py-4 px-6 border-b border-border", children: [
116
- /* @__PURE__ */ jsx("h3", { className: "text-sm font-medium text-foreground py-0 my-0", children: "Diagram" }),
119
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-medium text-foreground py-0 my-0", children: diagramTitle }),
117
120
  /* @__PURE__ */ jsx(
118
121
  "button",
119
122
  {
@@ -409,7 +412,13 @@ function useMermaidRenderer({ chart, theme, isCompact = false }) {
409
412
  }
410
413
  __name(useMermaidRenderer, "useMermaidRenderer");
411
414
  var Mermaid = /* @__PURE__ */ __name(({ chart, className = "", isCompact = false }) => {
415
+ const t = useTypedT();
412
416
  const theme = useResolvedTheme();
417
+ const labels = useMemo(() => ({
418
+ title: t("tools.diagram.title"),
419
+ clickToView: t("tools.diagram.clickToView"),
420
+ loading: t("ui.form.loading")
421
+ }), [t]);
413
422
  const { mermaidRef, svgContent, isVertical, isRendering } = useMermaidRenderer({
414
423
  chart,
415
424
  theme,
@@ -435,8 +444,8 @@ var Mermaid = /* @__PURE__ */ __name(({ chart, className = "", isCompact = false
435
444
  onClick: handleClick,
436
445
  children: [
437
446
  /* @__PURE__ */ jsxs("div", { className: "p-4 border-b border-border bg-muted/50", children: [
438
- /* @__PURE__ */ jsx("h6", { className: "text-sm font-semibold text-foreground", children: "Diagram" }),
439
- /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: "Click to view fullscreen" })
447
+ /* @__PURE__ */ jsx("h6", { className: "text-sm font-semibold text-foreground", children: labels.title }),
448
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: labels.clickToView })
440
449
  ] }),
441
450
  /* @__PURE__ */ jsxs("div", { className: "relative p-4 overflow-hidden", children: [
442
451
  /* @__PURE__ */ jsx(
@@ -449,7 +458,7 @@ var Mermaid = /* @__PURE__ */ __name(({ chart, className = "", isCompact = false
449
458
  ),
450
459
  isRendering && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-background/50 backdrop-blur-sm", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2", children: [
451
460
  /* @__PURE__ */ jsx("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-primary" }),
452
- /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Rendering diagram..." })
461
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: labels.loading })
453
462
  ] }) })
454
463
  ] })
455
464
  ]
@@ -473,5 +482,5 @@ var Mermaid = /* @__PURE__ */ __name(({ chart, className = "", isCompact = false
473
482
  var Mermaid_client_default = Mermaid;
474
483
 
475
484
  export { Mermaid_client_default as default };
476
- //# sourceMappingURL=Mermaid.client-4OCKJ6QD.mjs.map
477
- //# sourceMappingURL=Mermaid.client-4OCKJ6QD.mjs.map
485
+ //# sourceMappingURL=Mermaid.client-OKACITCW.mjs.map
486
+ //# sourceMappingURL=Mermaid.client-OKACITCW.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tools/Mermaid/utils/mermaid-helpers.ts","../src/tools/Mermaid/components/MermaidCodeViewer.tsx","../src/tools/Mermaid/components/MermaidFullscreenModal.tsx","../src/tools/Mermaid/hooks/useMermaidFullscreen.ts","../src/tools/Mermaid/hooks/useMermaidCleanup.ts","../src/tools/Mermaid/hooks/useMermaidValidation.ts","../src/tools/Mermaid/hooks/useMermaidRenderer.ts","../src/tools/Mermaid/Mermaid.client.tsx"],"names":["jsx","jsxs","useState","useEffect","applyMermaidTextColors","useRef","useTypedT","useMemo","Fragment"],"mappings":"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","file":"Mermaid.client-OKACITCW.mjs","sourcesContent":["/**\n * Helper utilities for Mermaid diagram rendering\n */\n\n// Utility function to apply text colors to Mermaid SVG\nexport const applyMermaidTextColors = (container: HTMLElement, textColor: string) => {\n const svgElement = container.querySelector('svg');\n if (svgElement) {\n // SVG text elements use 'fill'\n svgElement.querySelectorAll('text').forEach((el) => {\n (el as SVGElement).style.fill = textColor;\n });\n\n // HTML elements inside foreignObject use 'color'\n svgElement.querySelectorAll('.nodeLabel, .edgeLabel').forEach((el) => {\n (el as HTMLElement).style.color = textColor;\n });\n }\n};\n\n// Detect if diagram is vertical (tall and narrow)\nexport const isVerticalDiagram = (svgElement: SVGSVGElement): boolean => {\n const viewBox = svgElement.getAttribute('viewBox');\n if (viewBox) {\n const [, , width, height] = viewBox.split(' ').map(Number);\n return height > width * 1.5;\n }\n const bbox = svgElement.getBBox?.();\n if (bbox) {\n return bbox.height > bbox.width * 1.5;\n }\n return false;\n};\n","'use client';\n\nimport React, { useState } from 'react';\n\ninterface MermaidCodeViewerProps {\n chart: string;\n renderPreview: () => React.ReactNode;\n}\n\nexport const MermaidCodeViewer: React.FC<MermaidCodeViewerProps> = ({\n chart,\n renderPreview,\n}) => {\n const [activeTab, setActiveTab] = useState<'preview' | 'code'>('preview');\n const [copied, setCopied] = useState(false);\n\n const handleCopy = async () => {\n await navigator.clipboard.writeText(chart);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n };\n\n return (\n <div className=\"flex flex-col h-full\">\n {/* Tabs */}\n <div className=\"flex items-center justify-between border-b border-border px-4\">\n <div className=\"flex\">\n <button\n onClick={() => setActiveTab('preview')}\n className={`px-4 py-3 text-sm font-medium transition-colors relative ${\n activeTab === 'preview'\n ? 'text-foreground'\n : 'text-muted-foreground hover:text-foreground'\n }`}\n >\n Preview\n {activeTab === 'preview' && (\n <div className=\"absolute bottom-0 left-0 right-0 h-0.5 bg-primary\" />\n )}\n </button>\n <button\n onClick={() => setActiveTab('code')}\n className={`px-4 py-3 text-sm font-medium transition-colors relative ${\n activeTab === 'code'\n ? 'text-foreground'\n : 'text-muted-foreground hover:text-foreground'\n }`}\n >\n Code\n {activeTab === 'code' && (\n <div className=\"absolute bottom-0 left-0 right-0 h-0.5 bg-primary\" />\n )}\n </button>\n </div>\n\n {/* Copy button - show only on Code tab */}\n {activeTab === 'code' && (\n <button\n onClick={handleCopy}\n className=\"flex items-center gap-2 px-3 py-1.5 text-xs font-medium bg-primary/10 hover:bg-primary/20 text-primary rounded transition-colors\"\n >\n {copied ? (\n <>\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 13l4 4L19 7\" />\n </svg>\n Copied!\n </>\n ) : (\n <>\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\" />\n </svg>\n Copy\n </>\n )}\n </button>\n )}\n </div>\n\n {/* Content */}\n <div className=\"flex-1 overflow-auto\">\n {activeTab === 'preview' ? (\n <div className=\"p-6 flex items-center justify-center min-h-full\">\n {renderPreview()}\n </div>\n ) : (\n <pre className=\"p-6 text-sm font-mono text-foreground bg-muted/30 h-full overflow-auto\">\n <code>{chart}</code>\n </pre>\n )}\n </div>\n </div>\n );\n};\n","'use client';\n\nimport React, { useEffect, useMemo } from 'react';\nimport { createPortal } from 'react-dom';\n\nimport { useTypedT, type I18nTranslations } from '@djangocfg/i18n';\nimport { applyMermaidTextColors } from '../utils/mermaid-helpers';\nimport { MermaidCodeViewer } from './MermaidCodeViewer';\n\ninterface MermaidFullscreenModalProps {\n isOpen: boolean;\n svgContent: string;\n isVertical: boolean;\n theme: string;\n chart: string;\n fullscreenRef: React.RefObject<HTMLDivElement>;\n onClose: () => void;\n onBackdropClick: (e: React.MouseEvent) => void;\n}\n\nexport const MermaidFullscreenModal: React.FC<MermaidFullscreenModalProps> = ({\n isOpen,\n svgContent,\n isVertical,\n theme,\n chart,\n fullscreenRef,\n onClose,\n onBackdropClick,\n}) => {\n const t = useTypedT<I18nTranslations>();\n const diagramTitle = useMemo(() => t('tools.diagram.title'), [t]);\n\n // Apply text colors to fullscreen modal after render\n useEffect(() => {\n if (isOpen && fullscreenRef.current) {\n const getCSSVariable = (variable: string) => {\n if (typeof document === 'undefined') return '';\n const value = getComputedStyle(document.documentElement).getPropertyValue(variable).trim();\n return value ? `hsl(${value})` : '';\n };\n\n const textColor = theme === 'dark'\n ? getCSSVariable('--foreground') || 'hsl(0 0% 90%)'\n : getCSSVariable('--foreground') || 'hsl(222.2 84% 4.9%)';\n\n applyMermaidTextColors(fullscreenRef.current, textColor);\n\n // Make SVG responsive\n const svgElement = fullscreenRef.current.querySelector('svg');\n if (svgElement) {\n svgElement.style.display = 'block';\n svgElement.style.height = 'auto';\n svgElement.style.maxWidth = '100%';\n\n // For vertical diagrams, limit width\n if (isVertical) {\n svgElement.style.maxWidth = '600px';\n svgElement.style.margin = '0 auto';\n }\n }\n }\n }, [isOpen, theme, isVertical, fullscreenRef]);\n\n if (!isOpen || typeof document === 'undefined') return null;\n\n return createPortal(\n <div\n className=\"fixed inset-0 z-9999 flex items-center justify-center p-4\"\n style={{ backgroundColor: 'rgb(0 0 0 / 0.75)' }}\n onClick={onBackdropClick}\n >\n <div className={`relative bg-card rounded-sm shadow-xl max-h-[95vh] flex flex-col border border-border ${\n isVertical\n ? 'w-auto min-w-[400px] max-w-[600px]'\n : 'min-w-[600px] max-w-[90vw] w-auto'\n }`}>\n {/* Header */}\n <div className=\"flex items-center justify-between py-4 px-6 border-b border-border\">\n <h3 className=\"text-sm font-medium text-foreground py-0 my-0\">{diagramTitle}</h3>\n <button\n onClick={onClose}\n className=\"text-muted-foreground hover:text-foreground transition-colors\"\n >\n <svg className=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n {/* Content - Code Viewer with tabs */}\n <div className=\"flex-1 overflow-hidden\">\n <MermaidCodeViewer\n chart={chart}\n renderPreview={() => (\n <div\n ref={fullscreenRef}\n dangerouslySetInnerHTML={{ __html: svgContent }}\n />\n )}\n />\n </div>\n </div>\n </div>,\n document.body\n );\n};\n","/**\n * Hook for managing Mermaid fullscreen modal\n */\n\nimport { useEffect, useRef, useState } from 'react';\n\nexport function useMermaidFullscreen() {\n const [isFullscreen, setIsFullscreen] = useState(false);\n const fullscreenRef = useRef<HTMLDivElement>(null);\n\n const openFullscreen = () => setIsFullscreen(true);\n const closeFullscreen = () => setIsFullscreen(false);\n\n const handleBackdropClick = (e: React.MouseEvent) => {\n if (e.target === e.currentTarget) {\n closeFullscreen();\n }\n };\n\n // Handle ESC key\n useEffect(() => {\n const handleEscKey = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && isFullscreen) {\n closeFullscreen();\n }\n };\n\n if (isFullscreen) {\n document.addEventListener('keydown', handleEscKey);\n document.body.style.overflow = 'hidden';\n }\n\n return () => {\n document.removeEventListener('keydown', handleEscKey);\n document.body.style.overflow = 'unset';\n };\n }, [isFullscreen]);\n\n return {\n isFullscreen,\n fullscreenRef,\n openFullscreen,\n closeFullscreen,\n handleBackdropClick,\n };\n}\n","/**\n * Hook for cleaning up orphaned Mermaid DOM nodes\n */\n\nimport { useCallback, useEffect } from 'react';\n\nexport function useMermaidCleanup() {\n const cleanupMermaidErrors = useCallback(() => {\n if (typeof document === 'undefined') return;\n\n // Remove all orphaned mermaid elements from body\n // Mermaid can append: SVGs, divs with errors, text nodes\n\n // 1. Remove elements with mermaid-* IDs directly in body\n document.querySelectorAll('[id^=\"mermaid-\"]').forEach((node) => {\n if (node.parentNode === document.body) {\n node.remove();\n }\n });\n\n // 2. Remove elements with d prefix (mermaid diagram IDs) directly in body\n document.querySelectorAll('[id^=\"d\"]').forEach((node) => {\n if (node.parentNode === document.body && node.id.match(/^d\\d+$/)) {\n node.remove();\n }\n });\n\n // 3. Remove orphaned SVG elements that mermaid creates in body\n document.querySelectorAll('body > svg').forEach((node) => {\n // Check if it's a mermaid SVG (has mermaid classes or aria-roledescription)\n if (node.getAttribute('aria-roledescription') ||\n node.classList.contains('mermaid') ||\n node.querySelector('.mermaid') ||\n node.id?.includes('mermaid')) {\n node.remove();\n }\n });\n\n // 4. Remove any orphaned error divs with \"Syntax error\" text\n document.querySelectorAll('body > div').forEach((node) => {\n const text = node.textContent || '';\n if (text.includes('Syntax error in text') ||\n text.includes('mermaid version') ||\n node.id?.startsWith('mermaid-') ||\n node.id?.startsWith('d') && node.id.match(/^d\\d+$/)) {\n node.remove();\n }\n });\n\n // 5. Remove orphaned pre elements with error info\n document.querySelectorAll('body > pre').forEach((node) => {\n const text = node.textContent || '';\n if (text.includes('Syntax error') || text.includes('mermaid')) {\n node.remove();\n }\n });\n }, []);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n cleanupMermaidErrors();\n };\n }, [cleanupMermaidErrors]);\n\n // Also run cleanup periodically to catch any stray elements\n useEffect(() => {\n const interval = setInterval(cleanupMermaidErrors, 1000);\n return () => clearInterval(interval);\n }, [cleanupMermaidErrors]);\n\n return { cleanupMermaidErrors };\n}\n","/**\n * Hook for validating Mermaid code completeness\n */\n\nexport function useMermaidValidation() {\n const isMermaidCodeComplete = (code: string): boolean => {\n if (!code || code.trim().length === 0) return false;\n\n const trimmed = code.trim();\n\n // Check if code has basic structure\n const lines = trimmed.split('\\n');\n if (lines.length < 2) return false; // Need at least diagram type + one element\n\n // Check for common incomplete patterns\n const lastLine = lines[lines.length - 1].trim();\n\n // Incomplete if last line ends with arrow without destination\n if (lastLine.match(/-->?\\s*$/)) return false;\n if (lastLine.match(/-->\\|[^|]*\\|\\s*$/)) return false;\n\n // Incomplete if last line ends with opening bracket/parenthesis\n if (lastLine.match(/[\\[({]\\s*$/)) return false;\n\n return true;\n };\n\n return { isMermaidCodeComplete };\n}\n","/**\n * Hook for rendering Mermaid diagrams with debounce and validation\n */\n\nimport mermaid from 'mermaid';\nimport { useEffect, useRef, useState } from 'react';\n\nimport { useMermaidCleanup } from './useMermaidCleanup';\nimport { useMermaidValidation } from './useMermaidValidation';\n\ninterface UseMermaidRendererProps {\n chart: string;\n theme: string;\n isCompact?: boolean;\n}\n\ninterface MermaidRenderResult {\n mermaidRef: React.RefObject<HTMLDivElement>;\n svgContent: string;\n isVertical: boolean;\n isRendering: boolean;\n}\n\n// Utility function to apply text colors to Mermaid SVG\nconst applyMermaidTextColors = (container: HTMLElement, textColor: string) => {\n const svgElement = container.querySelector('svg');\n if (svgElement) {\n // SVG text elements use 'fill'\n svgElement.querySelectorAll('text').forEach((el) => {\n (el as SVGElement).style.fill = textColor;\n });\n\n // HTML elements inside foreignObject use 'color'\n svgElement.querySelectorAll('.nodeLabel, .edgeLabel').forEach((el) => {\n (el as HTMLElement).style.color = textColor;\n });\n }\n};\n\n// Detect if diagram is vertical (tall and narrow)\nconst isVerticalDiagram = (svgElement: SVGSVGElement): boolean => {\n const viewBox = svgElement.getAttribute('viewBox');\n if (viewBox) {\n const [, , width, height] = viewBox.split(' ').map(Number);\n return height > width * 1.5;\n }\n const bbox = svgElement.getBBox?.();\n if (bbox) {\n return bbox.height > bbox.width * 1.5;\n }\n return false;\n};\n\nexport function useMermaidRenderer({ chart, theme, isCompact = false }: UseMermaidRendererProps): MermaidRenderResult {\n const mermaidRef = useRef<HTMLDivElement>(null);\n const renderTimerRef = useRef<NodeJS.Timeout | null>(null);\n const [svgContent, setSvgContent] = useState<string>('');\n const [isVertical, setIsVertical] = useState(false);\n const [isRendering, setIsRendering] = useState(false);\n\n const { isMermaidCodeComplete } = useMermaidValidation();\n const { cleanupMermaidErrors } = useMermaidCleanup();\n\n useEffect(() => {\n // Get CSS variables for semantic colors\n const getCSSVariable = (variable: string) => {\n if (typeof document === 'undefined') return '';\n const value = getComputedStyle(document.documentElement).getPropertyValue(variable).trim();\n return value ? `hsl(${value})` : '';\n };\n\n const diagramFontSize = isCompact ? '12px' : '14px';\n\n const themeVariables = theme === 'dark' ? {\n primaryColor: getCSSVariable('--primary') || 'hsl(221.2 83.2% 53.3%)',\n primaryTextColor: getCSSVariable('--foreground') || 'hsl(210 40% 98%)',\n primaryBorderColor: getCSSVariable('--primary') || 'hsl(221.2 83.2% 53.3%)',\n secondaryColor: getCSSVariable('--muted') || 'hsl(217.2 32.6% 17.5%)',\n secondaryTextColor: getCSSVariable('--foreground') || 'hsl(210 40% 98%)',\n secondaryBorderColor: getCSSVariable('--border') || 'hsl(217.2 32.6% 27.5%)',\n tertiaryColor: getCSSVariable('--accent') || 'hsl(217.2 32.6% 20%)',\n tertiaryTextColor: getCSSVariable('--foreground') || 'hsl(210 40% 98%)',\n tertiaryBorderColor: getCSSVariable('--border') || 'hsl(217.2 32.6% 27.5%)',\n mainBkg: getCSSVariable('--card') || 'hsl(222.2 84% 8%)',\n textColor: getCSSVariable('--foreground') || 'hsl(210 40% 98%)',\n nodeBorder: getCSSVariable('--border') || 'hsl(217.2 32.6% 27.5%)',\n nodeTextColor: getCSSVariable('--foreground') || 'hsl(210 40% 98%)',\n secondBkg: getCSSVariable('--muted') || 'hsl(217.2 32.6% 17.5%)',\n lineColor: getCSSVariable('--primary') || 'hsl(221.2 83.2% 53.3%)',\n edgeLabelBackground: getCSSVariable('--card') || 'hsl(222.2 84% 8%)',\n clusterBkg: getCSSVariable('--muted') || 'hsl(217.2 32.6% 12%)',\n clusterBorder: getCSSVariable('--primary') || 'hsl(221.2 83.2% 53.3%)',\n background: getCSSVariable('--background') || 'hsl(222.2 84% 4.9%)',\n labelBackground: getCSSVariable('--card') || 'hsl(222.2 84% 8%)',\n labelTextColor: getCSSVariable('--foreground') || 'hsl(210 40% 98%)',\n errorBkgColor: getCSSVariable('--destructive') || 'hsl(0 62.8% 30.6%)',\n errorTextColor: 'hsl(210 40% 98%)',\n fontSize: diagramFontSize,\n fontFamily: 'Inter, system-ui, sans-serif',\n } : {\n primaryColor: getCSSVariable('--primary') || 'hsl(221.2 83.2% 53.3%)',\n primaryTextColor: getCSSVariable('--foreground') || 'hsl(222.2 84% 4.9%)',\n primaryBorderColor: getCSSVariable('--primary') || 'hsl(221.2 83.2% 53.3%)',\n secondaryColor: getCSSVariable('--secondary') || 'hsl(210 40% 96.1%)',\n secondaryTextColor: getCSSVariable('--foreground') || 'hsl(222.2 84% 4.9%)',\n secondaryBorderColor: getCSSVariable('--border') || 'hsl(214.3 31.8% 91.4%)',\n tertiaryColor: getCSSVariable('--muted') || 'hsl(210 40% 96.1%)',\n tertiaryTextColor: getCSSVariable('--foreground') || 'hsl(222.2 84% 4.9%)',\n tertiaryBorderColor: getCSSVariable('--border') || 'hsl(214.3 31.8% 91.4%)',\n mainBkg: getCSSVariable('--card') || 'hsl(0 0% 100%)',\n textColor: getCSSVariable('--foreground') || 'hsl(222.2 84% 4.9%)',\n nodeBorder: getCSSVariable('--border') || 'hsl(214.3 31.8% 91.4%)',\n nodeTextColor: getCSSVariable('--foreground') || 'hsl(222.2 84% 4.9%)',\n secondBkg: getCSSVariable('--muted') || 'hsl(210 40% 96.1%)',\n lineColor: getCSSVariable('--primary') || 'hsl(221.2 83.2% 53.3%)',\n edgeLabelBackground: getCSSVariable('--card') || 'hsl(0 0% 100%)',\n clusterBkg: getCSSVariable('--accent') || 'hsl(210 40% 98%)',\n clusterBorder: getCSSVariable('--primary') || 'hsl(221.2 83.2% 53.3%)',\n background: getCSSVariable('--background') || 'hsl(0 0% 100%)',\n labelBackground: getCSSVariable('--card') || 'hsl(0 0% 100%)',\n labelTextColor: getCSSVariable('--foreground') || 'hsl(222.2 84% 4.9%)',\n errorBkgColor: getCSSVariable('--destructive') || 'hsl(0 84.2% 60.2%)',\n errorTextColor: 'hsl(210 40% 98%)',\n fontSize: diagramFontSize,\n fontFamily: 'Inter, system-ui, sans-serif',\n };\n\n mermaid.initialize({\n startOnLoad: false,\n theme: 'base',\n securityLevel: 'loose',\n suppressErrorRendering: true, // Prevent mermaid from appending errors to body\n fontFamily: 'Inter, system-ui, sans-serif',\n flowchart: {\n useMaxWidth: true,\n htmlLabels: true,\n curve: 'basis',\n },\n themeVariables,\n });\n\n const renderChart = async () => {\n if (!mermaidRef.current || !chart) return;\n\n // Validate code completeness\n if (!isMermaidCodeComplete(chart)) {\n setIsRendering(true);\n return;\n }\n\n try {\n setIsRendering(true);\n\n // Clear container\n if (mermaidRef.current) {\n mermaidRef.current.innerHTML = '';\n }\n\n const id = `mermaid-${Math.random().toString(36).substring(2, 9)}`;\n const { svg } = await mermaid.render(id, chart);\n\n if (mermaidRef.current) {\n const textColor = theme === 'dark'\n ? getCSSVariable('--foreground') || 'hsl(0 0% 90%)'\n : getCSSVariable('--foreground') || 'hsl(222.2 84% 4.9%)';\n\n const processedSvg = svg.replace(\n /<svg /,\n `<svg style=\"--mermaid-text-color: ${textColor};\" `\n );\n\n mermaidRef.current.innerHTML = processedSvg;\n setSvgContent(processedSvg);\n\n applyMermaidTextColors(mermaidRef.current, textColor);\n\n const svgElement = mermaidRef.current.querySelector('svg');\n if (svgElement) {\n svgElement.style.maxWidth = '100%';\n svgElement.style.height = 'auto';\n svgElement.style.display = 'block';\n setIsVertical(isVerticalDiagram(svgElement));\n }\n }\n\n setIsRendering(false);\n } catch (error) {\n console.error('Mermaid rendering error:', error);\n setIsRendering(false);\n cleanupMermaidErrors();\n\n if (mermaidRef.current) {\n mermaidRef.current.innerHTML = `\n <div class=\"p-4 text-destructive bg-destructive/10 border border-destructive/20 rounded-sm\">\n <p class=\"font-semibold\">Mermaid Diagram Error</p>\n <p class=\"text-sm\">${error instanceof Error ? error.message : 'Unknown error'}</p>\n </div>\n `;\n }\n }\n };\n\n // Clear previous timer\n if (renderTimerRef.current) {\n clearTimeout(renderTimerRef.current);\n }\n\n // Debounce: wait 500ms after last update\n renderTimerRef.current = setTimeout(() => {\n renderChart();\n }, 500);\n\n return () => {\n if (renderTimerRef.current) {\n clearTimeout(renderTimerRef.current);\n }\n };\n }, [chart, theme, isCompact, isMermaidCodeComplete, cleanupMermaidErrors]);\n\n return {\n mermaidRef,\n svgContent,\n isVertical,\n isRendering,\n };\n}\n","'use client';\n\nimport React, { useMemo } from 'react';\n\nimport { useTypedT, type I18nTranslations } from '@djangocfg/i18n';\nimport { useResolvedTheme } from '@djangocfg/ui-core/hooks';\nimport { MermaidFullscreenModal } from './components/MermaidFullscreenModal';\nimport { useMermaidFullscreen } from './hooks/useMermaidFullscreen';\nimport { useMermaidRenderer } from './hooks/useMermaidRenderer';\n\ninterface MermaidProps {\n chart: string;\n className?: string;\n isCompact?: boolean;\n}\n\nconst Mermaid: React.FC<MermaidProps> = ({ chart, className = '', isCompact = false }) => {\n const t = useTypedT<I18nTranslations>();\n const theme = useResolvedTheme();\n\n const labels = useMemo(() => ({\n title: t('tools.diagram.title'),\n clickToView: t('tools.diagram.clickToView'),\n loading: t('ui.form.loading'),\n }), [t]);\n\n // Rendering logic\n const { mermaidRef, svgContent, isVertical, isRendering } = useMermaidRenderer({\n chart,\n theme,\n isCompact,\n });\n\n // Fullscreen modal logic\n const {\n isFullscreen,\n fullscreenRef,\n openFullscreen,\n closeFullscreen,\n handleBackdropClick,\n } = useMermaidFullscreen();\n\n const handleClick = () => {\n if (svgContent) {\n openFullscreen();\n }\n };\n\n return (\n <>\n <div\n className={`relative bg-card rounded-sm border border-border overflow-hidden cursor-pointer hover:shadow-sm transition-shadow ${className}`}\n onClick={handleClick}\n >\n <div className=\"p-4 border-b border-border bg-muted/50\">\n <h6 className=\"text-sm font-semibold text-foreground\">{labels.title}</h6>\n <p className=\"text-xs text-muted-foreground mt-1\">{labels.clickToView}</p>\n </div>\n <div className=\"relative p-4 overflow-hidden\">\n <div\n ref={mermaidRef}\n className=\"flex justify-center items-center min-h-[200px]\"\n style={{ isolation: 'isolate' }}\n />\n {isRendering && (\n <div className=\"absolute inset-0 flex items-center justify-center bg-background/50 backdrop-blur-sm\">\n <div className=\"flex flex-col items-center gap-2\">\n <div className=\"animate-spin rounded-full h-8 w-8 border-b-2 border-primary\"></div>\n <p className=\"text-xs text-muted-foreground\">{labels.loading}</p>\n </div>\n </div>\n )}\n </div>\n </div>\n\n <MermaidFullscreenModal\n isOpen={isFullscreen}\n svgContent={svgContent}\n isVertical={isVertical}\n theme={theme}\n chart={chart}\n fullscreenRef={fullscreenRef}\n onClose={closeFullscreen}\n onBackdropClick={handleBackdropClick}\n />\n </>\n );\n};\n\nexport default Mermaid;\n"]}
@@ -1,8 +1,9 @@
1
1
  'use strict';
2
2
 
3
3
  var chunkWGEGR3DF_cjs = require('./chunk-WGEGR3DF.cjs');
4
- var hooks = require('@djangocfg/ui-core/hooks');
5
4
  var react = require('react');
5
+ var i18n = require('@djangocfg/i18n');
6
+ var hooks = require('@djangocfg/ui-core/hooks');
6
7
  var reactDom = require('react-dom');
7
8
  var jsxRuntime = require('react/jsx-runtime');
8
9
  var mermaid = require('mermaid');
@@ -88,6 +89,8 @@ var MermaidFullscreenModal = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({
88
89
  onClose,
89
90
  onBackdropClick
90
91
  }) => {
92
+ const t = i18n.useTypedT();
93
+ const diagramTitle = react.useMemo(() => t("tools.diagram.title"), [t]);
91
94
  react.useEffect(() => {
92
95
  if (isOpen && fullscreenRef.current) {
93
96
  const getCSSVariable = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name((variable) => {
@@ -119,7 +122,7 @@ var MermaidFullscreenModal = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({
119
122
  onClick: onBackdropClick,
120
123
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `relative bg-card rounded-sm shadow-xl max-h-[95vh] flex flex-col border border-border ${isVertical ? "w-auto min-w-[400px] max-w-[600px]" : "min-w-[600px] max-w-[90vw] w-auto"}`, children: [
121
124
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between py-4 px-6 border-b border-border", children: [
122
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-medium text-foreground py-0 my-0", children: "Diagram" }),
125
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-medium text-foreground py-0 my-0", children: diagramTitle }),
123
126
  /* @__PURE__ */ jsxRuntime.jsx(
124
127
  "button",
125
128
  {
@@ -415,7 +418,13 @@ function useMermaidRenderer({ chart, theme, isCompact = false }) {
415
418
  }
416
419
  chunkWGEGR3DF_cjs.__name(useMermaidRenderer, "useMermaidRenderer");
417
420
  var Mermaid = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ chart, className = "", isCompact = false }) => {
421
+ const t = i18n.useTypedT();
418
422
  const theme = hooks.useResolvedTheme();
423
+ const labels = react.useMemo(() => ({
424
+ title: t("tools.diagram.title"),
425
+ clickToView: t("tools.diagram.clickToView"),
426
+ loading: t("ui.form.loading")
427
+ }), [t]);
419
428
  const { mermaidRef, svgContent, isVertical, isRendering } = useMermaidRenderer({
420
429
  chart,
421
430
  theme,
@@ -441,8 +450,8 @@ var Mermaid = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ chart, className = "",
441
450
  onClick: handleClick,
442
451
  children: [
443
452
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 border-b border-border bg-muted/50", children: [
444
- /* @__PURE__ */ jsxRuntime.jsx("h6", { className: "text-sm font-semibold text-foreground", children: "Diagram" }),
445
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground mt-1", children: "Click to view fullscreen" })
453
+ /* @__PURE__ */ jsxRuntime.jsx("h6", { className: "text-sm font-semibold text-foreground", children: labels.title }),
454
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground mt-1", children: labels.clickToView })
446
455
  ] }),
447
456
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative p-4 overflow-hidden", children: [
448
457
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -455,7 +464,7 @@ var Mermaid = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ chart, className = "",
455
464
  ),
456
465
  isRendering && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-background/50 backdrop-blur-sm", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-2", children: [
457
466
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-primary" }),
458
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Rendering diagram..." })
467
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: labels.loading })
459
468
  ] }) })
460
469
  ] })
461
470
  ]
@@ -479,5 +488,5 @@ var Mermaid = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ chart, className = "",
479
488
  var Mermaid_client_default = Mermaid;
480
489
 
481
490
  module.exports = Mermaid_client_default;
482
- //# sourceMappingURL=Mermaid.client-ZP6OE46Z.cjs.map
483
- //# sourceMappingURL=Mermaid.client-ZP6OE46Z.cjs.map
491
+ //# sourceMappingURL=Mermaid.client-PNXEC6YL.cjs.map
492
+ //# sourceMappingURL=Mermaid.client-PNXEC6YL.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tools/Mermaid/utils/mermaid-helpers.ts","../src/tools/Mermaid/components/MermaidCodeViewer.tsx","../src/tools/Mermaid/components/MermaidFullscreenModal.tsx","../src/tools/Mermaid/hooks/useMermaidFullscreen.ts","../src/tools/Mermaid/hooks/useMermaidCleanup.ts","../src/tools/Mermaid/hooks/useMermaidValidation.ts","../src/tools/Mermaid/hooks/useMermaidRenderer.ts","../src/tools/Mermaid/Mermaid.client.tsx"],"names":["__name","useState","jsxs","jsx","Fragment","useTypedT","useMemo","useEffect","createPortal","useRef","useCallback","applyMermaidTextColors","mermaid","useResolvedTheme"],"mappings":"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","file":"Mermaid.client-PNXEC6YL.cjs","sourcesContent":["/**\n * Helper utilities for Mermaid diagram rendering\n */\n\n// Utility function to apply text colors to Mermaid SVG\nexport const applyMermaidTextColors = (container: HTMLElement, textColor: string) => {\n const svgElement = container.querySelector('svg');\n if (svgElement) {\n // SVG text elements use 'fill'\n svgElement.querySelectorAll('text').forEach((el) => {\n (el as SVGElement).style.fill = textColor;\n });\n\n // HTML elements inside foreignObject use 'color'\n svgElement.querySelectorAll('.nodeLabel, .edgeLabel').forEach((el) => {\n (el as HTMLElement).style.color = textColor;\n });\n }\n};\n\n// Detect if diagram is vertical (tall and narrow)\nexport const isVerticalDiagram = (svgElement: SVGSVGElement): boolean => {\n const viewBox = svgElement.getAttribute('viewBox');\n if (viewBox) {\n const [, , width, height] = viewBox.split(' ').map(Number);\n return height > width * 1.5;\n }\n const bbox = svgElement.getBBox?.();\n if (bbox) {\n return bbox.height > bbox.width * 1.5;\n }\n return false;\n};\n","'use client';\n\nimport React, { useState } from 'react';\n\ninterface MermaidCodeViewerProps {\n chart: string;\n renderPreview: () => React.ReactNode;\n}\n\nexport const MermaidCodeViewer: React.FC<MermaidCodeViewerProps> = ({\n chart,\n renderPreview,\n}) => {\n const [activeTab, setActiveTab] = useState<'preview' | 'code'>('preview');\n const [copied, setCopied] = useState(false);\n\n const handleCopy = async () => {\n await navigator.clipboard.writeText(chart);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n };\n\n return (\n <div className=\"flex flex-col h-full\">\n {/* Tabs */}\n <div className=\"flex items-center justify-between border-b border-border px-4\">\n <div className=\"flex\">\n <button\n onClick={() => setActiveTab('preview')}\n className={`px-4 py-3 text-sm font-medium transition-colors relative ${\n activeTab === 'preview'\n ? 'text-foreground'\n : 'text-muted-foreground hover:text-foreground'\n }`}\n >\n Preview\n {activeTab === 'preview' && (\n <div className=\"absolute bottom-0 left-0 right-0 h-0.5 bg-primary\" />\n )}\n </button>\n <button\n onClick={() => setActiveTab('code')}\n className={`px-4 py-3 text-sm font-medium transition-colors relative ${\n activeTab === 'code'\n ? 'text-foreground'\n : 'text-muted-foreground hover:text-foreground'\n }`}\n >\n Code\n {activeTab === 'code' && (\n <div className=\"absolute bottom-0 left-0 right-0 h-0.5 bg-primary\" />\n )}\n </button>\n </div>\n\n {/* Copy button - show only on Code tab */}\n {activeTab === 'code' && (\n <button\n onClick={handleCopy}\n className=\"flex items-center gap-2 px-3 py-1.5 text-xs font-medium bg-primary/10 hover:bg-primary/20 text-primary rounded transition-colors\"\n >\n {copied ? (\n <>\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 13l4 4L19 7\" />\n </svg>\n Copied!\n </>\n ) : (\n <>\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\" />\n </svg>\n Copy\n </>\n )}\n </button>\n )}\n </div>\n\n {/* Content */}\n <div className=\"flex-1 overflow-auto\">\n {activeTab === 'preview' ? (\n <div className=\"p-6 flex items-center justify-center min-h-full\">\n {renderPreview()}\n </div>\n ) : (\n <pre className=\"p-6 text-sm font-mono text-foreground bg-muted/30 h-full overflow-auto\">\n <code>{chart}</code>\n </pre>\n )}\n </div>\n </div>\n );\n};\n","'use client';\n\nimport React, { useEffect, useMemo } from 'react';\nimport { createPortal } from 'react-dom';\n\nimport { useTypedT, type I18nTranslations } from '@djangocfg/i18n';\nimport { applyMermaidTextColors } from '../utils/mermaid-helpers';\nimport { MermaidCodeViewer } from './MermaidCodeViewer';\n\ninterface MermaidFullscreenModalProps {\n isOpen: boolean;\n svgContent: string;\n isVertical: boolean;\n theme: string;\n chart: string;\n fullscreenRef: React.RefObject<HTMLDivElement>;\n onClose: () => void;\n onBackdropClick: (e: React.MouseEvent) => void;\n}\n\nexport const MermaidFullscreenModal: React.FC<MermaidFullscreenModalProps> = ({\n isOpen,\n svgContent,\n isVertical,\n theme,\n chart,\n fullscreenRef,\n onClose,\n onBackdropClick,\n}) => {\n const t = useTypedT<I18nTranslations>();\n const diagramTitle = useMemo(() => t('tools.diagram.title'), [t]);\n\n // Apply text colors to fullscreen modal after render\n useEffect(() => {\n if (isOpen && fullscreenRef.current) {\n const getCSSVariable = (variable: string) => {\n if (typeof document === 'undefined') return '';\n const value = getComputedStyle(document.documentElement).getPropertyValue(variable).trim();\n return value ? `hsl(${value})` : '';\n };\n\n const textColor = theme === 'dark'\n ? getCSSVariable('--foreground') || 'hsl(0 0% 90%)'\n : getCSSVariable('--foreground') || 'hsl(222.2 84% 4.9%)';\n\n applyMermaidTextColors(fullscreenRef.current, textColor);\n\n // Make SVG responsive\n const svgElement = fullscreenRef.current.querySelector('svg');\n if (svgElement) {\n svgElement.style.display = 'block';\n svgElement.style.height = 'auto';\n svgElement.style.maxWidth = '100%';\n\n // For vertical diagrams, limit width\n if (isVertical) {\n svgElement.style.maxWidth = '600px';\n svgElement.style.margin = '0 auto';\n }\n }\n }\n }, [isOpen, theme, isVertical, fullscreenRef]);\n\n if (!isOpen || typeof document === 'undefined') return null;\n\n return createPortal(\n <div\n className=\"fixed inset-0 z-9999 flex items-center justify-center p-4\"\n style={{ backgroundColor: 'rgb(0 0 0 / 0.75)' }}\n onClick={onBackdropClick}\n >\n <div className={`relative bg-card rounded-sm shadow-xl max-h-[95vh] flex flex-col border border-border ${\n isVertical\n ? 'w-auto min-w-[400px] max-w-[600px]'\n : 'min-w-[600px] max-w-[90vw] w-auto'\n }`}>\n {/* Header */}\n <div className=\"flex items-center justify-between py-4 px-6 border-b border-border\">\n <h3 className=\"text-sm font-medium text-foreground py-0 my-0\">{diagramTitle}</h3>\n <button\n onClick={onClose}\n className=\"text-muted-foreground hover:text-foreground transition-colors\"\n >\n <svg className=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n {/* Content - Code Viewer with tabs */}\n <div className=\"flex-1 overflow-hidden\">\n <MermaidCodeViewer\n chart={chart}\n renderPreview={() => (\n <div\n ref={fullscreenRef}\n dangerouslySetInnerHTML={{ __html: svgContent }}\n />\n )}\n />\n </div>\n </div>\n </div>,\n document.body\n );\n};\n","/**\n * Hook for managing Mermaid fullscreen modal\n */\n\nimport { useEffect, useRef, useState } from 'react';\n\nexport function useMermaidFullscreen() {\n const [isFullscreen, setIsFullscreen] = useState(false);\n const fullscreenRef = useRef<HTMLDivElement>(null);\n\n const openFullscreen = () => setIsFullscreen(true);\n const closeFullscreen = () => setIsFullscreen(false);\n\n const handleBackdropClick = (e: React.MouseEvent) => {\n if (e.target === e.currentTarget) {\n closeFullscreen();\n }\n };\n\n // Handle ESC key\n useEffect(() => {\n const handleEscKey = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && isFullscreen) {\n closeFullscreen();\n }\n };\n\n if (isFullscreen) {\n document.addEventListener('keydown', handleEscKey);\n document.body.style.overflow = 'hidden';\n }\n\n return () => {\n document.removeEventListener('keydown', handleEscKey);\n document.body.style.overflow = 'unset';\n };\n }, [isFullscreen]);\n\n return {\n isFullscreen,\n fullscreenRef,\n openFullscreen,\n closeFullscreen,\n handleBackdropClick,\n };\n}\n","/**\n * Hook for cleaning up orphaned Mermaid DOM nodes\n */\n\nimport { useCallback, useEffect } from 'react';\n\nexport function useMermaidCleanup() {\n const cleanupMermaidErrors = useCallback(() => {\n if (typeof document === 'undefined') return;\n\n // Remove all orphaned mermaid elements from body\n // Mermaid can append: SVGs, divs with errors, text nodes\n\n // 1. Remove elements with mermaid-* IDs directly in body\n document.querySelectorAll('[id^=\"mermaid-\"]').forEach((node) => {\n if (node.parentNode === document.body) {\n node.remove();\n }\n });\n\n // 2. Remove elements with d prefix (mermaid diagram IDs) directly in body\n document.querySelectorAll('[id^=\"d\"]').forEach((node) => {\n if (node.parentNode === document.body && node.id.match(/^d\\d+$/)) {\n node.remove();\n }\n });\n\n // 3. Remove orphaned SVG elements that mermaid creates in body\n document.querySelectorAll('body > svg').forEach((node) => {\n // Check if it's a mermaid SVG (has mermaid classes or aria-roledescription)\n if (node.getAttribute('aria-roledescription') ||\n node.classList.contains('mermaid') ||\n node.querySelector('.mermaid') ||\n node.id?.includes('mermaid')) {\n node.remove();\n }\n });\n\n // 4. Remove any orphaned error divs with \"Syntax error\" text\n document.querySelectorAll('body > div').forEach((node) => {\n const text = node.textContent || '';\n if (text.includes('Syntax error in text') ||\n text.includes('mermaid version') ||\n node.id?.startsWith('mermaid-') ||\n node.id?.startsWith('d') && node.id.match(/^d\\d+$/)) {\n node.remove();\n }\n });\n\n // 5. Remove orphaned pre elements with error info\n document.querySelectorAll('body > pre').forEach((node) => {\n const text = node.textContent || '';\n if (text.includes('Syntax error') || text.includes('mermaid')) {\n node.remove();\n }\n });\n }, []);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n cleanupMermaidErrors();\n };\n }, [cleanupMermaidErrors]);\n\n // Also run cleanup periodically to catch any stray elements\n useEffect(() => {\n const interval = setInterval(cleanupMermaidErrors, 1000);\n return () => clearInterval(interval);\n }, [cleanupMermaidErrors]);\n\n return { cleanupMermaidErrors };\n}\n","/**\n * Hook for validating Mermaid code completeness\n */\n\nexport function useMermaidValidation() {\n const isMermaidCodeComplete = (code: string): boolean => {\n if (!code || code.trim().length === 0) return false;\n\n const trimmed = code.trim();\n\n // Check if code has basic structure\n const lines = trimmed.split('\\n');\n if (lines.length < 2) return false; // Need at least diagram type + one element\n\n // Check for common incomplete patterns\n const lastLine = lines[lines.length - 1].trim();\n\n // Incomplete if last line ends with arrow without destination\n if (lastLine.match(/-->?\\s*$/)) return false;\n if (lastLine.match(/-->\\|[^|]*\\|\\s*$/)) return false;\n\n // Incomplete if last line ends with opening bracket/parenthesis\n if (lastLine.match(/[\\[({]\\s*$/)) return false;\n\n return true;\n };\n\n return { isMermaidCodeComplete };\n}\n","/**\n * Hook for rendering Mermaid diagrams with debounce and validation\n */\n\nimport mermaid from 'mermaid';\nimport { useEffect, useRef, useState } from 'react';\n\nimport { useMermaidCleanup } from './useMermaidCleanup';\nimport { useMermaidValidation } from './useMermaidValidation';\n\ninterface UseMermaidRendererProps {\n chart: string;\n theme: string;\n isCompact?: boolean;\n}\n\ninterface MermaidRenderResult {\n mermaidRef: React.RefObject<HTMLDivElement>;\n svgContent: string;\n isVertical: boolean;\n isRendering: boolean;\n}\n\n// Utility function to apply text colors to Mermaid SVG\nconst applyMermaidTextColors = (container: HTMLElement, textColor: string) => {\n const svgElement = container.querySelector('svg');\n if (svgElement) {\n // SVG text elements use 'fill'\n svgElement.querySelectorAll('text').forEach((el) => {\n (el as SVGElement).style.fill = textColor;\n });\n\n // HTML elements inside foreignObject use 'color'\n svgElement.querySelectorAll('.nodeLabel, .edgeLabel').forEach((el) => {\n (el as HTMLElement).style.color = textColor;\n });\n }\n};\n\n// Detect if diagram is vertical (tall and narrow)\nconst isVerticalDiagram = (svgElement: SVGSVGElement): boolean => {\n const viewBox = svgElement.getAttribute('viewBox');\n if (viewBox) {\n const [, , width, height] = viewBox.split(' ').map(Number);\n return height > width * 1.5;\n }\n const bbox = svgElement.getBBox?.();\n if (bbox) {\n return bbox.height > bbox.width * 1.5;\n }\n return false;\n};\n\nexport function useMermaidRenderer({ chart, theme, isCompact = false }: UseMermaidRendererProps): MermaidRenderResult {\n const mermaidRef = useRef<HTMLDivElement>(null);\n const renderTimerRef = useRef<NodeJS.Timeout | null>(null);\n const [svgContent, setSvgContent] = useState<string>('');\n const [isVertical, setIsVertical] = useState(false);\n const [isRendering, setIsRendering] = useState(false);\n\n const { isMermaidCodeComplete } = useMermaidValidation();\n const { cleanupMermaidErrors } = useMermaidCleanup();\n\n useEffect(() => {\n // Get CSS variables for semantic colors\n const getCSSVariable = (variable: string) => {\n if (typeof document === 'undefined') return '';\n const value = getComputedStyle(document.documentElement).getPropertyValue(variable).trim();\n return value ? `hsl(${value})` : '';\n };\n\n const diagramFontSize = isCompact ? '12px' : '14px';\n\n const themeVariables = theme === 'dark' ? {\n primaryColor: getCSSVariable('--primary') || 'hsl(221.2 83.2% 53.3%)',\n primaryTextColor: getCSSVariable('--foreground') || 'hsl(210 40% 98%)',\n primaryBorderColor: getCSSVariable('--primary') || 'hsl(221.2 83.2% 53.3%)',\n secondaryColor: getCSSVariable('--muted') || 'hsl(217.2 32.6% 17.5%)',\n secondaryTextColor: getCSSVariable('--foreground') || 'hsl(210 40% 98%)',\n secondaryBorderColor: getCSSVariable('--border') || 'hsl(217.2 32.6% 27.5%)',\n tertiaryColor: getCSSVariable('--accent') || 'hsl(217.2 32.6% 20%)',\n tertiaryTextColor: getCSSVariable('--foreground') || 'hsl(210 40% 98%)',\n tertiaryBorderColor: getCSSVariable('--border') || 'hsl(217.2 32.6% 27.5%)',\n mainBkg: getCSSVariable('--card') || 'hsl(222.2 84% 8%)',\n textColor: getCSSVariable('--foreground') || 'hsl(210 40% 98%)',\n nodeBorder: getCSSVariable('--border') || 'hsl(217.2 32.6% 27.5%)',\n nodeTextColor: getCSSVariable('--foreground') || 'hsl(210 40% 98%)',\n secondBkg: getCSSVariable('--muted') || 'hsl(217.2 32.6% 17.5%)',\n lineColor: getCSSVariable('--primary') || 'hsl(221.2 83.2% 53.3%)',\n edgeLabelBackground: getCSSVariable('--card') || 'hsl(222.2 84% 8%)',\n clusterBkg: getCSSVariable('--muted') || 'hsl(217.2 32.6% 12%)',\n clusterBorder: getCSSVariable('--primary') || 'hsl(221.2 83.2% 53.3%)',\n background: getCSSVariable('--background') || 'hsl(222.2 84% 4.9%)',\n labelBackground: getCSSVariable('--card') || 'hsl(222.2 84% 8%)',\n labelTextColor: getCSSVariable('--foreground') || 'hsl(210 40% 98%)',\n errorBkgColor: getCSSVariable('--destructive') || 'hsl(0 62.8% 30.6%)',\n errorTextColor: 'hsl(210 40% 98%)',\n fontSize: diagramFontSize,\n fontFamily: 'Inter, system-ui, sans-serif',\n } : {\n primaryColor: getCSSVariable('--primary') || 'hsl(221.2 83.2% 53.3%)',\n primaryTextColor: getCSSVariable('--foreground') || 'hsl(222.2 84% 4.9%)',\n primaryBorderColor: getCSSVariable('--primary') || 'hsl(221.2 83.2% 53.3%)',\n secondaryColor: getCSSVariable('--secondary') || 'hsl(210 40% 96.1%)',\n secondaryTextColor: getCSSVariable('--foreground') || 'hsl(222.2 84% 4.9%)',\n secondaryBorderColor: getCSSVariable('--border') || 'hsl(214.3 31.8% 91.4%)',\n tertiaryColor: getCSSVariable('--muted') || 'hsl(210 40% 96.1%)',\n tertiaryTextColor: getCSSVariable('--foreground') || 'hsl(222.2 84% 4.9%)',\n tertiaryBorderColor: getCSSVariable('--border') || 'hsl(214.3 31.8% 91.4%)',\n mainBkg: getCSSVariable('--card') || 'hsl(0 0% 100%)',\n textColor: getCSSVariable('--foreground') || 'hsl(222.2 84% 4.9%)',\n nodeBorder: getCSSVariable('--border') || 'hsl(214.3 31.8% 91.4%)',\n nodeTextColor: getCSSVariable('--foreground') || 'hsl(222.2 84% 4.9%)',\n secondBkg: getCSSVariable('--muted') || 'hsl(210 40% 96.1%)',\n lineColor: getCSSVariable('--primary') || 'hsl(221.2 83.2% 53.3%)',\n edgeLabelBackground: getCSSVariable('--card') || 'hsl(0 0% 100%)',\n clusterBkg: getCSSVariable('--accent') || 'hsl(210 40% 98%)',\n clusterBorder: getCSSVariable('--primary') || 'hsl(221.2 83.2% 53.3%)',\n background: getCSSVariable('--background') || 'hsl(0 0% 100%)',\n labelBackground: getCSSVariable('--card') || 'hsl(0 0% 100%)',\n labelTextColor: getCSSVariable('--foreground') || 'hsl(222.2 84% 4.9%)',\n errorBkgColor: getCSSVariable('--destructive') || 'hsl(0 84.2% 60.2%)',\n errorTextColor: 'hsl(210 40% 98%)',\n fontSize: diagramFontSize,\n fontFamily: 'Inter, system-ui, sans-serif',\n };\n\n mermaid.initialize({\n startOnLoad: false,\n theme: 'base',\n securityLevel: 'loose',\n suppressErrorRendering: true, // Prevent mermaid from appending errors to body\n fontFamily: 'Inter, system-ui, sans-serif',\n flowchart: {\n useMaxWidth: true,\n htmlLabels: true,\n curve: 'basis',\n },\n themeVariables,\n });\n\n const renderChart = async () => {\n if (!mermaidRef.current || !chart) return;\n\n // Validate code completeness\n if (!isMermaidCodeComplete(chart)) {\n setIsRendering(true);\n return;\n }\n\n try {\n setIsRendering(true);\n\n // Clear container\n if (mermaidRef.current) {\n mermaidRef.current.innerHTML = '';\n }\n\n const id = `mermaid-${Math.random().toString(36).substring(2, 9)}`;\n const { svg } = await mermaid.render(id, chart);\n\n if (mermaidRef.current) {\n const textColor = theme === 'dark'\n ? getCSSVariable('--foreground') || 'hsl(0 0% 90%)'\n : getCSSVariable('--foreground') || 'hsl(222.2 84% 4.9%)';\n\n const processedSvg = svg.replace(\n /<svg /,\n `<svg style=\"--mermaid-text-color: ${textColor};\" `\n );\n\n mermaidRef.current.innerHTML = processedSvg;\n setSvgContent(processedSvg);\n\n applyMermaidTextColors(mermaidRef.current, textColor);\n\n const svgElement = mermaidRef.current.querySelector('svg');\n if (svgElement) {\n svgElement.style.maxWidth = '100%';\n svgElement.style.height = 'auto';\n svgElement.style.display = 'block';\n setIsVertical(isVerticalDiagram(svgElement));\n }\n }\n\n setIsRendering(false);\n } catch (error) {\n console.error('Mermaid rendering error:', error);\n setIsRendering(false);\n cleanupMermaidErrors();\n\n if (mermaidRef.current) {\n mermaidRef.current.innerHTML = `\n <div class=\"p-4 text-destructive bg-destructive/10 border border-destructive/20 rounded-sm\">\n <p class=\"font-semibold\">Mermaid Diagram Error</p>\n <p class=\"text-sm\">${error instanceof Error ? error.message : 'Unknown error'}</p>\n </div>\n `;\n }\n }\n };\n\n // Clear previous timer\n if (renderTimerRef.current) {\n clearTimeout(renderTimerRef.current);\n }\n\n // Debounce: wait 500ms after last update\n renderTimerRef.current = setTimeout(() => {\n renderChart();\n }, 500);\n\n return () => {\n if (renderTimerRef.current) {\n clearTimeout(renderTimerRef.current);\n }\n };\n }, [chart, theme, isCompact, isMermaidCodeComplete, cleanupMermaidErrors]);\n\n return {\n mermaidRef,\n svgContent,\n isVertical,\n isRendering,\n };\n}\n","'use client';\n\nimport React, { useMemo } from 'react';\n\nimport { useTypedT, type I18nTranslations } from '@djangocfg/i18n';\nimport { useResolvedTheme } from '@djangocfg/ui-core/hooks';\nimport { MermaidFullscreenModal } from './components/MermaidFullscreenModal';\nimport { useMermaidFullscreen } from './hooks/useMermaidFullscreen';\nimport { useMermaidRenderer } from './hooks/useMermaidRenderer';\n\ninterface MermaidProps {\n chart: string;\n className?: string;\n isCompact?: boolean;\n}\n\nconst Mermaid: React.FC<MermaidProps> = ({ chart, className = '', isCompact = false }) => {\n const t = useTypedT<I18nTranslations>();\n const theme = useResolvedTheme();\n\n const labels = useMemo(() => ({\n title: t('tools.diagram.title'),\n clickToView: t('tools.diagram.clickToView'),\n loading: t('ui.form.loading'),\n }), [t]);\n\n // Rendering logic\n const { mermaidRef, svgContent, isVertical, isRendering } = useMermaidRenderer({\n chart,\n theme,\n isCompact,\n });\n\n // Fullscreen modal logic\n const {\n isFullscreen,\n fullscreenRef,\n openFullscreen,\n closeFullscreen,\n handleBackdropClick,\n } = useMermaidFullscreen();\n\n const handleClick = () => {\n if (svgContent) {\n openFullscreen();\n }\n };\n\n return (\n <>\n <div\n className={`relative bg-card rounded-sm border border-border overflow-hidden cursor-pointer hover:shadow-sm transition-shadow ${className}`}\n onClick={handleClick}\n >\n <div className=\"p-4 border-b border-border bg-muted/50\">\n <h6 className=\"text-sm font-semibold text-foreground\">{labels.title}</h6>\n <p className=\"text-xs text-muted-foreground mt-1\">{labels.clickToView}</p>\n </div>\n <div className=\"relative p-4 overflow-hidden\">\n <div\n ref={mermaidRef}\n className=\"flex justify-center items-center min-h-[200px]\"\n style={{ isolation: 'isolate' }}\n />\n {isRendering && (\n <div className=\"absolute inset-0 flex items-center justify-center bg-background/50 backdrop-blur-sm\">\n <div className=\"flex flex-col items-center gap-2\">\n <div className=\"animate-spin rounded-full h-8 w-8 border-b-2 border-primary\"></div>\n <p className=\"text-xs text-muted-foreground\">{labels.loading}</p>\n </div>\n </div>\n )}\n </div>\n </div>\n\n <MermaidFullscreenModal\n isOpen={isFullscreen}\n svgContent={svgContent}\n isVertical={isVertical}\n theme={theme}\n chart={chart}\n fullscreenRef={fullscreenRef}\n onClose={closeFullscreen}\n onBackdropClick={handleBackdropClick}\n />\n </>\n );\n};\n\nexport default Mermaid;\n"]}