@juv/codego-react-ui 1.1.7 → 3.0.0
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/README.md +15 -0
- package/dist/index.cjs +680 -134
- package/dist/index.d.cts +33 -4
- package/dist/index.d.ts +33 -4
- package/dist/index.global.js +727 -164
- package/dist/index.js +681 -135
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4943,6 +4943,45 @@ function addTerrain(map) {
|
|
|
4943
4943
|
});
|
|
4944
4944
|
}
|
|
4945
4945
|
}
|
|
4946
|
+
var OSRM_PROFILE2 = { drive: "driving", walk: "foot" };
|
|
4947
|
+
async function fetchOsrmRoute2(points, routeType) {
|
|
4948
|
+
const profile = OSRM_PROFILE2[routeType];
|
|
4949
|
+
const coords = points.map((p) => `${p.lng},${p.lat}`).join(";");
|
|
4950
|
+
const res = await fetch(`https://router.project-osrm.org/route/v1/${profile}/${coords}?overview=full&geometries=geojson`);
|
|
4951
|
+
if (!res.ok) throw new Error("OSRM failed");
|
|
4952
|
+
const data = await res.json();
|
|
4953
|
+
if (data.code !== "Ok" || !data.routes?.length) throw new Error("No route");
|
|
4954
|
+
const route = data.routes[0];
|
|
4955
|
+
return {
|
|
4956
|
+
coords: route.geometry.coordinates,
|
|
4957
|
+
// already [lng, lat] for MapLibre
|
|
4958
|
+
distance: route.distance,
|
|
4959
|
+
duration: route.duration
|
|
4960
|
+
};
|
|
4961
|
+
}
|
|
4962
|
+
function fmtDistance2(m) {
|
|
4963
|
+
return m >= 1e3 ? `${(m / 1e3).toFixed(1)} km` : `${Math.round(m)} m`;
|
|
4964
|
+
}
|
|
4965
|
+
function fmtDuration2(s) {
|
|
4966
|
+
const h = Math.floor(s / 3600), m = Math.floor(s % 3600 / 60);
|
|
4967
|
+
return h > 0 ? `${h}h ${m}min` : `${m} min`;
|
|
4968
|
+
}
|
|
4969
|
+
function makeClusterHTML(variant, count, color) {
|
|
4970
|
+
if (variant === "bubble") {
|
|
4971
|
+
const size = count > 99 ? 52 : count > 9 ? 44 : 36;
|
|
4972
|
+
return `<div style="width:${size}px;height:${size}px;border-radius:50%;background:${color};color:#fff;font-weight:700;font-size:${count > 99 ? 11 : 13}px;font-family:sans-serif;display:flex;align-items:center;justify-content:center;border:3px solid white;box-shadow:0 2px 8px rgba(0,0,0,.3);">${count}</div>`;
|
|
4973
|
+
}
|
|
4974
|
+
if (variant === "donut") {
|
|
4975
|
+
const r = 20, stroke = 5, circ = 2 * Math.PI * r;
|
|
4976
|
+
const dash = Math.min(count / 50, 1) * circ;
|
|
4977
|
+
return `<svg width="54" height="54" viewBox="0 0 54 54"><circle cx="27" cy="27" r="${r}" fill="none" stroke="${color}33" stroke-width="${stroke}"/><circle cx="27" cy="27" r="${r}" fill="none" stroke="${color}" stroke-width="${stroke}" stroke-dasharray="${dash} ${circ}" stroke-dashoffset="${circ / 4}" stroke-linecap="round"/><circle cx="27" cy="27" r="${r - stroke - 2}" fill="${color}22"/><text x="27" y="27" text-anchor="middle" dominant-baseline="middle" font-size="12" font-weight="700" fill="${color}" font-family="sans-serif">${count}</text></svg>`;
|
|
4978
|
+
}
|
|
4979
|
+
const w = count > 99 ? 52 : 40;
|
|
4980
|
+
return `<div style="min-width:${w}px;height:28px;border-radius:14px;background:${color};color:#fff;font-weight:700;font-size:12px;font-family:sans-serif;display:flex;align-items:center;justify-content:center;padding:0 8px;border:2px solid white;box-shadow:0 2px 8px rgba(0,0,0,.25);">${count}</div>`;
|
|
4981
|
+
}
|
|
4982
|
+
function makeEndpointHTML(color, label) {
|
|
4983
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 28 28"><circle cx="14" cy="14" r="12" fill="${color}" stroke="white" stroke-width="2.5"/><text x="14" y="14" text-anchor="middle" dominant-baseline="middle" font-size="12" font-weight="700" fill="white" font-family="sans-serif">${label}</text></svg>`;
|
|
4984
|
+
}
|
|
4946
4985
|
function MapLibreMap({
|
|
4947
4986
|
style: styleProp = "street",
|
|
4948
4987
|
center = [0, 20],
|
|
@@ -4957,6 +4996,9 @@ function MapLibreMap({
|
|
|
4957
4996
|
maxBearing = 180,
|
|
4958
4997
|
flyTo,
|
|
4959
4998
|
markers = [],
|
|
4999
|
+
routes = [],
|
|
5000
|
+
cluster = false,
|
|
5001
|
+
clusterVariant = "default",
|
|
4960
5002
|
height = 480,
|
|
4961
5003
|
showControls = true,
|
|
4962
5004
|
showStyleSwitcher = true,
|
|
@@ -4967,7 +5009,9 @@ function MapLibreMap({
|
|
|
4967
5009
|
const containerRef = React22.useRef(null);
|
|
4968
5010
|
const mapRef = React22.useRef(null);
|
|
4969
5011
|
const markersRef = React22.useRef([]);
|
|
5012
|
+
const routeMarkersRef = React22.useRef([]);
|
|
4970
5013
|
const flyingRef = React22.useRef(false);
|
|
5014
|
+
const [routeLoading, setRouteLoading] = React22.useState(false);
|
|
4971
5015
|
const [activeStyle, setActiveStyle] = React22.useState(styleProp);
|
|
4972
5016
|
const [ready, setReady] = React22.useState(false);
|
|
4973
5017
|
const [showCamera, setShowCamera] = React22.useState(false);
|
|
@@ -5055,6 +5099,109 @@ function MapLibreMap({
|
|
|
5055
5099
|
if (ftBearing !== void 0) setBearing(clampBearing(ftBearing));
|
|
5056
5100
|
});
|
|
5057
5101
|
}, [flyTo]);
|
|
5102
|
+
React22.useEffect(() => {
|
|
5103
|
+
const map = mapRef.current;
|
|
5104
|
+
if (!map || !ready || routes.length === 0) return;
|
|
5105
|
+
function cleanRoutes() {
|
|
5106
|
+
routeMarkersRef.current.forEach((m) => m.remove());
|
|
5107
|
+
routeMarkersRef.current = [];
|
|
5108
|
+
const style = map.getStyle();
|
|
5109
|
+
(style.layers ?? []).forEach((l) => {
|
|
5110
|
+
if (l.id.startsWith("route-")) try {
|
|
5111
|
+
map.removeLayer(l.id);
|
|
5112
|
+
} catch {
|
|
5113
|
+
}
|
|
5114
|
+
});
|
|
5115
|
+
Object.keys(style.sources ?? {}).forEach((s) => {
|
|
5116
|
+
if (s.startsWith("route-")) try {
|
|
5117
|
+
map.removeSource(s);
|
|
5118
|
+
} catch {
|
|
5119
|
+
}
|
|
5120
|
+
});
|
|
5121
|
+
}
|
|
5122
|
+
cleanRoutes();
|
|
5123
|
+
setRouteLoading(true);
|
|
5124
|
+
Promise.all(
|
|
5125
|
+
routes.map(async (r, i) => {
|
|
5126
|
+
const points = [r.start, ...r.waypoints ?? [], r.end];
|
|
5127
|
+
try {
|
|
5128
|
+
const result = await fetchOsrmRoute2(points, r.routeType ?? "drive");
|
|
5129
|
+
return { route: r, idx: i, ...result, error: false };
|
|
5130
|
+
} catch {
|
|
5131
|
+
return { route: r, idx: i, coords: points.map((p) => [p.lng, p.lat]), distance: 0, duration: 0, error: true };
|
|
5132
|
+
}
|
|
5133
|
+
})
|
|
5134
|
+
).then((results) => {
|
|
5135
|
+
setRouteLoading(false);
|
|
5136
|
+
if (!mapRef.current) return;
|
|
5137
|
+
const m = mapRef.current;
|
|
5138
|
+
const allCoords = [];
|
|
5139
|
+
results.forEach(({ route, idx, coords, distance, duration }) => {
|
|
5140
|
+
const color = route.color ?? (route.routeType === "walk" ? "#22c55e" : "#6366f1");
|
|
5141
|
+
const srcId = `route-${idx}`;
|
|
5142
|
+
const geojson = {
|
|
5143
|
+
type: "Feature",
|
|
5144
|
+
properties: {},
|
|
5145
|
+
geometry: { type: "LineString", coordinates: coords }
|
|
5146
|
+
};
|
|
5147
|
+
m.addSource(srcId, { type: "geojson", data: geojson });
|
|
5148
|
+
m.addLayer({
|
|
5149
|
+
id: `${srcId}-outline`,
|
|
5150
|
+
type: "line",
|
|
5151
|
+
source: srcId,
|
|
5152
|
+
layout: { "line-cap": "round", "line-join": "round" },
|
|
5153
|
+
paint: { "line-color": "#ffffff", "line-width": (route.weight ?? 5) + 4, "line-opacity": 0.3 }
|
|
5154
|
+
});
|
|
5155
|
+
m.addLayer({
|
|
5156
|
+
id: `${srcId}-line`,
|
|
5157
|
+
type: "line",
|
|
5158
|
+
source: srcId,
|
|
5159
|
+
layout: { "line-cap": "round", "line-join": "round" },
|
|
5160
|
+
paint: { "line-color": color, "line-width": route.weight ?? 5, "line-opacity": 0.9 }
|
|
5161
|
+
});
|
|
5162
|
+
allCoords.push(...coords);
|
|
5163
|
+
const makeEndpointMarker = (lngLat, label, markerColor, popupHtml) => {
|
|
5164
|
+
const el = document.createElement("div");
|
|
5165
|
+
el.innerHTML = makeEndpointHTML(markerColor, label);
|
|
5166
|
+
el.style.cssText = "width:28px;height:28px";
|
|
5167
|
+
const popup = new maplibregl.Popup({ offset: [0, -16], closeButton: false }).setHTML(popupHtml);
|
|
5168
|
+
const marker = new maplibregl.Marker({ element: el, anchor: "center" }).setLngLat(lngLat).setPopup(popup).addTo(m);
|
|
5169
|
+
routeMarkersRef.current.push(marker);
|
|
5170
|
+
};
|
|
5171
|
+
const infoHtml = distance > 0 ? `<p style="font-size:11px;color:#888;margin:2px 0 0">${fmtDistance2(distance)} \xB7 ${fmtDuration2(duration)} \xB7 ${route.routeType === "walk" ? "\u{1F6B6} Walk" : "\u{1F697} Drive"}</p>` : "";
|
|
5172
|
+
makeEndpointMarker(
|
|
5173
|
+
[route.start.lng, route.start.lat],
|
|
5174
|
+
"A",
|
|
5175
|
+
color,
|
|
5176
|
+
`<div style="padding:2px;min-width:120px"><p style="font-weight:700;font-size:13px;margin:0">${route.label ? `${route.label} \u2014 Start` : "Start"}</p>${infoHtml}</div>`
|
|
5177
|
+
);
|
|
5178
|
+
makeEndpointMarker(
|
|
5179
|
+
[route.end.lng, route.end.lat],
|
|
5180
|
+
"B",
|
|
5181
|
+
"#ef4444",
|
|
5182
|
+
`<div style="padding:2px;min-width:120px"><p style="font-weight:700;font-size:13px;margin:0">${route.label ? `${route.label} \u2014 End` : "End"}</p>${infoHtml}</div>`
|
|
5183
|
+
);
|
|
5184
|
+
if (distance > 0 && coords.length > 1) {
|
|
5185
|
+
const mid = coords[Math.floor(coords.length / 2)];
|
|
5186
|
+
const text = `${fmtDistance2(distance)} \xB7 ${fmtDuration2(duration)}`;
|
|
5187
|
+
const estW = text.length * 7 + 16;
|
|
5188
|
+
const el = document.createElement("div");
|
|
5189
|
+
el.innerHTML = `<div style="display:inline-flex;align-items:center;justify-content:center;background:${color};color:white;font-size:11px;font-weight:600;font-family:sans-serif;padding:3px 8px;border-radius:12px;border:2px solid white;box-shadow:0 2px 6px rgba(0,0,0,.25);white-space:nowrap;">${text}</div>`;
|
|
5190
|
+
el.style.cssText = `width:${estW}px;height:22px;pointer-events:none`;
|
|
5191
|
+
const badge = new maplibregl.Marker({ element: el, anchor: "center" }).setLngLat(mid).addTo(m);
|
|
5192
|
+
routeMarkersRef.current.push(badge);
|
|
5193
|
+
}
|
|
5194
|
+
});
|
|
5195
|
+
if (allCoords.length > 1) {
|
|
5196
|
+
const lngs = allCoords.map((c) => c[0]), lats = allCoords.map((c) => c[1]);
|
|
5197
|
+
m.fitBounds(
|
|
5198
|
+
[[Math.min(...lngs), Math.min(...lats)], [Math.max(...lngs), Math.max(...lats)]],
|
|
5199
|
+
{ padding: 60, duration: 800 }
|
|
5200
|
+
);
|
|
5201
|
+
}
|
|
5202
|
+
});
|
|
5203
|
+
return cleanRoutes;
|
|
5204
|
+
}, [routes, ready]);
|
|
5058
5205
|
function switchStyle(s) {
|
|
5059
5206
|
const map = mapRef.current;
|
|
5060
5207
|
if (!map) return;
|
|
@@ -5062,6 +5209,8 @@ function MapLibreMap({
|
|
|
5062
5209
|
setReady(false);
|
|
5063
5210
|
markersRef.current.forEach((m) => m.remove());
|
|
5064
5211
|
markersRef.current = [];
|
|
5212
|
+
routeMarkersRef.current.forEach((m) => m.remove());
|
|
5213
|
+
routeMarkersRef.current = [];
|
|
5065
5214
|
map.setStyle(s === "satellite" ? SATELLITE_STYLE : STYLE_URLS[s]);
|
|
5066
5215
|
map.once("style.load", () => {
|
|
5067
5216
|
if (s === "globe") {
|
|
@@ -5093,32 +5242,107 @@ function MapLibreMap({
|
|
|
5093
5242
|
setReady(true);
|
|
5094
5243
|
});
|
|
5095
5244
|
}
|
|
5245
|
+
const [mapZoom, setMapZoom] = React22.useState(zoom);
|
|
5246
|
+
React22.useEffect(() => {
|
|
5247
|
+
const map = mapRef.current;
|
|
5248
|
+
if (!map) return;
|
|
5249
|
+
const h2 = () => setMapZoom(map.getZoom());
|
|
5250
|
+
map.on("zoomend", h2);
|
|
5251
|
+
return () => {
|
|
5252
|
+
map.off("zoomend", h2);
|
|
5253
|
+
};
|
|
5254
|
+
}, [ready]);
|
|
5096
5255
|
React22.useEffect(() => {
|
|
5097
5256
|
const map = mapRef.current;
|
|
5098
5257
|
if (!map || !ready) return;
|
|
5099
5258
|
markersRef.current.forEach((m) => m.remove());
|
|
5100
5259
|
markersRef.current = [];
|
|
5101
|
-
markers.
|
|
5102
|
-
const
|
|
5103
|
-
const
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5260
|
+
if (cluster && markers.length > 0) {
|
|
5261
|
+
const GRID = 80;
|
|
5262
|
+
const used = /* @__PURE__ */ new Set();
|
|
5263
|
+
const groups = [];
|
|
5264
|
+
markers.forEach((m, i) => {
|
|
5265
|
+
if (used.has(i)) return;
|
|
5266
|
+
const pt = map.project([m.lng, m.lat]);
|
|
5267
|
+
const group = [m];
|
|
5268
|
+
used.add(i);
|
|
5269
|
+
markers.forEach((m2, j) => {
|
|
5270
|
+
if (used.has(j)) return;
|
|
5271
|
+
const pt2 = map.project([m2.lng, m2.lat]);
|
|
5272
|
+
if (Math.abs(pt.x - pt2.x) < GRID && Math.abs(pt.y - pt2.y) < GRID) {
|
|
5273
|
+
group.push(m2);
|
|
5274
|
+
used.add(j);
|
|
5275
|
+
}
|
|
5276
|
+
});
|
|
5277
|
+
const lat = group.reduce((s, x) => s + x.lat, 0) / group.length;
|
|
5278
|
+
const lng = group.reduce((s, x) => s + x.lng, 0) / group.length;
|
|
5279
|
+
groups.push({ center: { lng, lat }, items: group });
|
|
5280
|
+
});
|
|
5281
|
+
groups.forEach((g, gi) => {
|
|
5282
|
+
if (g.items.length === 1) {
|
|
5283
|
+
const m = g.items[0];
|
|
5284
|
+
const color = resolveColor2(m.color);
|
|
5285
|
+
const el = document.createElement("div");
|
|
5286
|
+
el.innerHTML = makePinHTML(color, m.icon, m.image);
|
|
5287
|
+
el.style.cssText = m.image ? "width:40px;height:50px" : "width:32px;height:42px";
|
|
5288
|
+
const popup = new maplibregl.Popup({ offset: m.image ? [0, -52] : [0, -44], closeButton: false });
|
|
5289
|
+
if (m.popup) {
|
|
5290
|
+
typeof m.popup === "string" ? popup.setHTML(m.popup) : popup.setDOMContent(m.popup);
|
|
5291
|
+
} else if (m.label) popup.setHTML(`<span style="font-size:13px;font-weight:600">${m.label}</span>`);
|
|
5292
|
+
const marker = new maplibregl.Marker({ element: el, anchor: "bottom" }).setLngLat([m.lng, m.lat]);
|
|
5293
|
+
if (m.popup || m.label) marker.setPopup(popup);
|
|
5294
|
+
el.addEventListener("click", () => onMarkerClick?.(m));
|
|
5295
|
+
marker.addTo(map);
|
|
5296
|
+
markersRef.current.push(marker);
|
|
5297
|
+
} else {
|
|
5298
|
+
const color = resolveColor2(g.items[0].color);
|
|
5299
|
+
const el = document.createElement("div");
|
|
5300
|
+
el.innerHTML = makeClusterHTML(clusterVariant, g.items.length, color);
|
|
5301
|
+
el.style.cssText = "cursor:pointer";
|
|
5302
|
+
const listItems = g.items.map(
|
|
5303
|
+
(m) => `<div data-id="${m.id}" style="font-size:12px;padding:2px 0;cursor:pointer;">${m.label ?? `Marker ${m.id}`}</div>`
|
|
5304
|
+
).join("");
|
|
5305
|
+
const popup = new maplibregl.Popup({ offset: [0, -8], closeButton: false }).setHTML(`<div style="max-height:160px;overflow-y:auto;padding:2px">${listItems}</div>`);
|
|
5306
|
+
el.addEventListener("click", () => {
|
|
5307
|
+
map.flyTo({ center: [g.center.lng, g.center.lat], zoom: map.getZoom() + 2, duration: 400 });
|
|
5308
|
+
});
|
|
5309
|
+
const marker = new maplibregl.Marker({ element: el, anchor: "center" }).setLngLat([g.center.lng, g.center.lat]).setPopup(popup).addTo(map);
|
|
5310
|
+
markersRef.current.push(marker);
|
|
5311
|
+
marker.getPopup().on("open", () => {
|
|
5312
|
+
g.items.forEach((m) => {
|
|
5313
|
+
const node = document.querySelector(`[data-id="${m.id}"]`);
|
|
5314
|
+
node?.addEventListener("click", () => onMarkerClick?.(m));
|
|
5315
|
+
});
|
|
5316
|
+
});
|
|
5317
|
+
}
|
|
5318
|
+
});
|
|
5319
|
+
} else {
|
|
5320
|
+
markers.forEach((m) => {
|
|
5321
|
+
const color = resolveColor2(m.color);
|
|
5322
|
+
const el = document.createElement("div");
|
|
5323
|
+
el.innerHTML = makePinHTML(color, m.icon, m.image);
|
|
5324
|
+
el.style.cssText = m.image ? "width:40px;height:50px" : "width:32px;height:42px";
|
|
5325
|
+
const popup = new maplibregl.Popup({ offset: m.image ? [0, -52] : [0, -44], closeButton: false });
|
|
5326
|
+
if (m.popup) {
|
|
5327
|
+
if (typeof m.popup === "string") popup.setHTML(m.popup);
|
|
5328
|
+
else popup.setDOMContent(m.popup);
|
|
5329
|
+
} else if (m.label) {
|
|
5330
|
+
popup.setHTML(`<span style="font-size:13px;font-weight:600">${m.label}</span>`);
|
|
5331
|
+
}
|
|
5332
|
+
const marker = new maplibregl.Marker({ element: el, anchor: "bottom" }).setLngLat([m.lng, m.lat]);
|
|
5333
|
+
if (m.popup || m.label) marker.setPopup(popup);
|
|
5334
|
+
el.addEventListener("click", () => onMarkerClick?.(m));
|
|
5335
|
+
marker.addTo(map);
|
|
5336
|
+
markersRef.current.push(marker);
|
|
5337
|
+
});
|
|
5338
|
+
}
|
|
5339
|
+
}, [markers, ready, onMarkerClick, cluster, clusterVariant, mapZoom]);
|
|
5120
5340
|
const cameraOpen = showCameraControls || showCamera;
|
|
5121
5341
|
return /* @__PURE__ */ jsxs23("div", { className: cn("relative w-full overflow-hidden rounded-2xl border border-border", className), style: { height: h }, children: [
|
|
5342
|
+
routeLoading && /* @__PURE__ */ jsx27("div", { className: "absolute inset-0 z-[1000] flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-2 bg-card/90 backdrop-blur-sm border border-border rounded-xl px-4 py-2 shadow-lg text-sm font-medium", children: [
|
|
5343
|
+
/* @__PURE__ */ jsx27("span", { className: "h-4 w-4 rounded-full border-2 border-primary border-t-transparent animate-spin" }),
|
|
5344
|
+
"Calculating route\u2026"
|
|
5345
|
+
] }) }),
|
|
5122
5346
|
/* @__PURE__ */ jsx27("div", { ref: containerRef, style: { width: "100%", height: "100%" } }),
|
|
5123
5347
|
cameraOpen && /* @__PURE__ */ jsxs23("div", { className: "absolute top-4 left-4 z-10 bg-card/90 backdrop-blur-sm border border-border rounded-2xl p-3 shadow-xl space-y-3 w-52", children: [
|
|
5124
5348
|
/* @__PURE__ */ jsxs23("div", { className: "flex items-center justify-between", children: [
|
|
@@ -5453,6 +5677,7 @@ function Select({
|
|
|
5453
5677
|
const [isSearching, setIsSearching] = React25.useState(false);
|
|
5454
5678
|
const containerRef = React25.useRef(null);
|
|
5455
5679
|
const triggerRef = React25.useRef(null);
|
|
5680
|
+
const portalRef = React25.useRef(null);
|
|
5456
5681
|
const [dropStyle, setDropStyle] = React25.useState({});
|
|
5457
5682
|
const getKey = React25.useCallback((opt) => String(Object.keys(opt)[0]), []);
|
|
5458
5683
|
const getLabel = React25.useCallback((opt) => Object.values(opt)[0], []);
|
|
@@ -5483,9 +5708,9 @@ function Select({
|
|
|
5483
5708
|
};
|
|
5484
5709
|
React25.useEffect(() => {
|
|
5485
5710
|
const handler = (e) => {
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
|
|
5711
|
+
const target = e.target;
|
|
5712
|
+
if (containerRef.current?.contains(target) || portalRef.current?.contains(target)) return;
|
|
5713
|
+
setIsOpen(false);
|
|
5489
5714
|
};
|
|
5490
5715
|
document.addEventListener("mousedown", handler);
|
|
5491
5716
|
return () => document.removeEventListener("mousedown", handler);
|
|
@@ -5628,6 +5853,7 @@ function Select({
|
|
|
5628
5853
|
isOpen && /* @__PURE__ */ jsx30(FloatingPortal, { children: /* @__PURE__ */ jsxs26(
|
|
5629
5854
|
"div",
|
|
5630
5855
|
{
|
|
5856
|
+
ref: portalRef,
|
|
5631
5857
|
className: "max-h-60 overflow-auto rounded-md border border-white/10 bg-background/80 backdrop-blur-xl text-popover-foreground shadow-lg animate-in fade-in-80",
|
|
5632
5858
|
style: dropStyle,
|
|
5633
5859
|
children: [
|
|
@@ -6592,67 +6818,386 @@ import { createContext as createContext2, useContext as useContext2, useEffect a
|
|
|
6592
6818
|
|
|
6593
6819
|
// src/components/conf/settingConfig.json
|
|
6594
6820
|
var settingConfig_default = {
|
|
6595
|
-
|
|
6596
|
-
|
|
6597
|
-
|
|
6598
|
-
|
|
6599
|
-
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
|
|
6603
|
-
|
|
6604
|
-
|
|
6605
|
-
|
|
6606
|
-
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
|
|
6821
|
+
defaults: {
|
|
6822
|
+
theme: "light",
|
|
6823
|
+
fontSize: "16px",
|
|
6824
|
+
fontFamily: '"Space Grotesk", "Inter", sans-serif',
|
|
6825
|
+
colors: {
|
|
6826
|
+
primary: "#5CF6E2",
|
|
6827
|
+
primaryHover: "#73F3E2",
|
|
6828
|
+
secondary: "#171717",
|
|
6829
|
+
secondaryHover: "#262626",
|
|
6830
|
+
info: "#3b82f6",
|
|
6831
|
+
infoHover: "#2563eb",
|
|
6832
|
+
warning: "#f59e0b",
|
|
6833
|
+
warningHover: "#d97706",
|
|
6834
|
+
danger: "#ef4444",
|
|
6835
|
+
dangerHover: "#dc2626"
|
|
6836
|
+
}
|
|
6837
|
+
},
|
|
6838
|
+
themeOptions: [
|
|
6839
|
+
{ light: "Light" },
|
|
6840
|
+
{ dark: "Dark" },
|
|
6841
|
+
{ system: "System" }
|
|
6842
|
+
],
|
|
6843
|
+
fontSizes: [
|
|
6844
|
+
{ "14px": "Small (14px)" },
|
|
6845
|
+
{ "16px": "Medium (16px)" },
|
|
6846
|
+
{ "18px": "Large (18px)" },
|
|
6847
|
+
{ "20px": "Extra Large (20px)" }
|
|
6848
|
+
],
|
|
6849
|
+
fontFamilies: [
|
|
6850
|
+
{ '"Space Grotesk", "Inter", sans-serif': "Space Grotesk" },
|
|
6851
|
+
{ '"Inter", sans-serif': "Inter" },
|
|
6852
|
+
{ '"JetBrains Mono", monospace': "JetBrains Mono" },
|
|
6853
|
+
{ "system-ui, sans-serif": "System UI" }
|
|
6854
|
+
],
|
|
6855
|
+
colorPairs: [
|
|
6856
|
+
{ base: "primary", hover: "primaryHover", label: "Primary" },
|
|
6857
|
+
{ base: "secondary", hover: "secondaryHover", label: "Secondary" },
|
|
6858
|
+
{ base: "info", hover: "infoHover", label: "Info" },
|
|
6859
|
+
{ base: "warning", hover: "warningHover", label: "Warning" },
|
|
6860
|
+
{ base: "danger", hover: "dangerHover", label: "Danger" }
|
|
6861
|
+
],
|
|
6862
|
+
colorPalette: [
|
|
6863
|
+
{
|
|
6864
|
+
base: "#6366F1",
|
|
6865
|
+
hover: "#4F46E5",
|
|
6866
|
+
info: "#F59E0B",
|
|
6867
|
+
infoHover: "#D97706"
|
|
6868
|
+
},
|
|
6869
|
+
{
|
|
6870
|
+
base: "#818CF8",
|
|
6871
|
+
hover: "#6366F1",
|
|
6872
|
+
info: "#FBBF24",
|
|
6873
|
+
infoHover: "#F59E0B"
|
|
6874
|
+
},
|
|
6875
|
+
{
|
|
6876
|
+
base: "#4F46E5",
|
|
6877
|
+
hover: "#4338CA",
|
|
6878
|
+
info: "#F59E0B",
|
|
6879
|
+
infoHover: "#D97706"
|
|
6880
|
+
},
|
|
6881
|
+
{
|
|
6882
|
+
base: "#3730A3",
|
|
6883
|
+
hover: "#312E81",
|
|
6884
|
+
info: "#D97706",
|
|
6885
|
+
infoHover: "#B45309"
|
|
6886
|
+
},
|
|
6887
|
+
{
|
|
6888
|
+
base: "#7C3AED",
|
|
6889
|
+
hover: "#6D28D9",
|
|
6890
|
+
info: "#F97316",
|
|
6891
|
+
infoHover: "#EA580C"
|
|
6892
|
+
},
|
|
6893
|
+
{
|
|
6894
|
+
base: "#A78BFA",
|
|
6895
|
+
hover: "#8B5CF6",
|
|
6896
|
+
info: "#FB923C",
|
|
6897
|
+
infoHover: "#F97316"
|
|
6898
|
+
},
|
|
6899
|
+
{
|
|
6900
|
+
base: "#8B5CF6",
|
|
6901
|
+
hover: "#7C3AED",
|
|
6902
|
+
info: "#F97316",
|
|
6903
|
+
infoHover: "#EA580C"
|
|
6904
|
+
},
|
|
6905
|
+
{
|
|
6906
|
+
base: "#6D28D9",
|
|
6907
|
+
hover: "#5B21B6",
|
|
6908
|
+
info: "#EA580C",
|
|
6909
|
+
infoHover: "#C2410C"
|
|
6910
|
+
},
|
|
6911
|
+
{
|
|
6912
|
+
base: "#0EA5E9",
|
|
6913
|
+
hover: "#0284C7",
|
|
6914
|
+
info: "#F97316",
|
|
6915
|
+
infoHover: "#EA580C"
|
|
6916
|
+
},
|
|
6917
|
+
{
|
|
6918
|
+
base: "#38BDF8",
|
|
6919
|
+
hover: "#0EA5E9",
|
|
6920
|
+
info: "#FB923C",
|
|
6921
|
+
infoHover: "#F97316"
|
|
6922
|
+
},
|
|
6923
|
+
{
|
|
6924
|
+
base: "#3B82F6",
|
|
6925
|
+
hover: "#2563EB",
|
|
6926
|
+
info: "#F59E0B",
|
|
6927
|
+
infoHover: "#D97706"
|
|
6928
|
+
},
|
|
6929
|
+
{
|
|
6930
|
+
base: "#1D4ED8",
|
|
6931
|
+
hover: "#1E40AF",
|
|
6932
|
+
info: "#D97706",
|
|
6933
|
+
infoHover: "#B45309"
|
|
6934
|
+
},
|
|
6935
|
+
{
|
|
6936
|
+
base: "#06B6D4",
|
|
6937
|
+
hover: "#0891B2",
|
|
6938
|
+
info: "#A855F7",
|
|
6939
|
+
infoHover: "#9333EA"
|
|
6940
|
+
},
|
|
6941
|
+
{
|
|
6942
|
+
base: "#22D3EE",
|
|
6943
|
+
hover: "#06B6D4",
|
|
6944
|
+
info: "#C084FC",
|
|
6945
|
+
infoHover: "#A855F7"
|
|
6946
|
+
},
|
|
6947
|
+
{
|
|
6948
|
+
base: "#14B8A6",
|
|
6949
|
+
hover: "#0F766E",
|
|
6950
|
+
info: "#8B5CF6",
|
|
6951
|
+
infoHover: "#7C3AED"
|
|
6952
|
+
},
|
|
6953
|
+
{
|
|
6954
|
+
base: "#0D9488",
|
|
6955
|
+
hover: "#0F766E",
|
|
6956
|
+
info: "#7C3AED",
|
|
6957
|
+
infoHover: "#6D28D9"
|
|
6958
|
+
},
|
|
6959
|
+
{
|
|
6960
|
+
base: "#10B981",
|
|
6961
|
+
hover: "#059669",
|
|
6962
|
+
info: "#8B5CF6",
|
|
6963
|
+
infoHover: "#7C3AED"
|
|
6964
|
+
},
|
|
6965
|
+
{
|
|
6966
|
+
base: "#34D399",
|
|
6967
|
+
hover: "#10B981",
|
|
6968
|
+
info: "#A855F7",
|
|
6969
|
+
infoHover: "#9333EA"
|
|
6970
|
+
},
|
|
6971
|
+
{
|
|
6972
|
+
base: "#22C55E",
|
|
6973
|
+
hover: "#16A34A",
|
|
6974
|
+
info: "#7C3AED",
|
|
6975
|
+
infoHover: "#6D28D9"
|
|
6976
|
+
},
|
|
6977
|
+
{
|
|
6978
|
+
base: "#16A34A",
|
|
6979
|
+
hover: "#15803D",
|
|
6980
|
+
info: "#6D28D9",
|
|
6981
|
+
infoHover: "#5B21B6"
|
|
6982
|
+
},
|
|
6983
|
+
{
|
|
6984
|
+
base: "#84CC16",
|
|
6985
|
+
hover: "#65A30D",
|
|
6986
|
+
info: "#6366F1",
|
|
6987
|
+
infoHover: "#4F46E5"
|
|
6988
|
+
},
|
|
6989
|
+
{
|
|
6990
|
+
base: "#A3E635",
|
|
6991
|
+
hover: "#84CC16",
|
|
6992
|
+
info: "#818CF8",
|
|
6993
|
+
infoHover: "#6366F1"
|
|
6994
|
+
},
|
|
6995
|
+
{
|
|
6996
|
+
base: "#65A30D",
|
|
6997
|
+
hover: "#4D7C0F",
|
|
6998
|
+
info: "#4F46E5",
|
|
6999
|
+
infoHover: "#4338CA"
|
|
7000
|
+
},
|
|
7001
|
+
{
|
|
7002
|
+
base: "#4D7C0F",
|
|
7003
|
+
hover: "#3F6212",
|
|
7004
|
+
info: "#3730A3",
|
|
7005
|
+
infoHover: "#312E81"
|
|
7006
|
+
},
|
|
7007
|
+
{
|
|
7008
|
+
base: "#EAB308",
|
|
7009
|
+
hover: "#CA8A04",
|
|
7010
|
+
info: "#3B82F6",
|
|
7011
|
+
infoHover: "#2563EB"
|
|
7012
|
+
},
|
|
7013
|
+
{
|
|
7014
|
+
base: "#FACC15",
|
|
7015
|
+
hover: "#EAB308",
|
|
7016
|
+
info: "#60A5FA",
|
|
7017
|
+
infoHover: "#3B82F6"
|
|
7018
|
+
},
|
|
7019
|
+
{
|
|
7020
|
+
base: "#F59E0B",
|
|
7021
|
+
hover: "#D97706",
|
|
7022
|
+
info: "#2563EB",
|
|
7023
|
+
infoHover: "#1D4ED8"
|
|
7024
|
+
},
|
|
7025
|
+
{
|
|
7026
|
+
base: "#D97706",
|
|
7027
|
+
hover: "#B45309",
|
|
7028
|
+
info: "#1D4ED8",
|
|
7029
|
+
infoHover: "#1E40AF"
|
|
7030
|
+
},
|
|
7031
|
+
{
|
|
7032
|
+
base: "#F97316",
|
|
7033
|
+
hover: "#EA580C",
|
|
7034
|
+
info: "#0EA5E9",
|
|
7035
|
+
infoHover: "#0284C7"
|
|
7036
|
+
},
|
|
7037
|
+
{
|
|
7038
|
+
base: "#FB923C",
|
|
7039
|
+
hover: "#F97316",
|
|
7040
|
+
info: "#38BDF8",
|
|
7041
|
+
infoHover: "#0EA5E9"
|
|
7042
|
+
},
|
|
7043
|
+
{
|
|
7044
|
+
base: "#EA580C",
|
|
7045
|
+
hover: "#C2410C",
|
|
7046
|
+
info: "#0284C7",
|
|
7047
|
+
infoHover: "#0369A1"
|
|
7048
|
+
},
|
|
7049
|
+
{
|
|
7050
|
+
base: "#C2410C",
|
|
7051
|
+
hover: "#9A3412",
|
|
7052
|
+
info: "#0369A1",
|
|
7053
|
+
infoHover: "#075985"
|
|
7054
|
+
},
|
|
7055
|
+
{
|
|
7056
|
+
base: "#EF4444",
|
|
7057
|
+
hover: "#DC2626",
|
|
7058
|
+
info: "#0EA5E9",
|
|
7059
|
+
infoHover: "#0284C7"
|
|
7060
|
+
},
|
|
7061
|
+
{
|
|
7062
|
+
base: "#F87171",
|
|
7063
|
+
hover: "#EF4444",
|
|
7064
|
+
info: "#38BDF8",
|
|
7065
|
+
infoHover: "#0EA5E9"
|
|
7066
|
+
},
|
|
7067
|
+
{
|
|
7068
|
+
base: "#DC2626",
|
|
7069
|
+
hover: "#B91C1C",
|
|
7070
|
+
info: "#0284C7",
|
|
7071
|
+
infoHover: "#0369A1"
|
|
7072
|
+
},
|
|
7073
|
+
{
|
|
7074
|
+
base: "#B91C1C",
|
|
7075
|
+
hover: "#991B1B",
|
|
7076
|
+
info: "#0369A1",
|
|
7077
|
+
infoHover: "#075985"
|
|
7078
|
+
},
|
|
7079
|
+
{
|
|
7080
|
+
base: "#F43F5E",
|
|
7081
|
+
hover: "#E11D48",
|
|
7082
|
+
info: "#0EA5E9",
|
|
7083
|
+
infoHover: "#0284C7"
|
|
7084
|
+
},
|
|
7085
|
+
{
|
|
7086
|
+
base: "#FB7185",
|
|
7087
|
+
hover: "#F43F5E",
|
|
7088
|
+
info: "#38BDF8",
|
|
7089
|
+
infoHover: "#0EA5E9"
|
|
7090
|
+
},
|
|
7091
|
+
{
|
|
7092
|
+
base: "#E11D48",
|
|
7093
|
+
hover: "#BE123C",
|
|
7094
|
+
info: "#0284C7",
|
|
7095
|
+
infoHover: "#0369A1"
|
|
7096
|
+
},
|
|
7097
|
+
{
|
|
7098
|
+
base: "#BE123C",
|
|
7099
|
+
hover: "#9F1239",
|
|
7100
|
+
info: "#0369A1",
|
|
7101
|
+
infoHover: "#075985"
|
|
7102
|
+
},
|
|
7103
|
+
{
|
|
7104
|
+
base: "#EC4899",
|
|
7105
|
+
hover: "#DB2777",
|
|
7106
|
+
info: "#06B6D4",
|
|
7107
|
+
infoHover: "#0891B2"
|
|
7108
|
+
},
|
|
7109
|
+
{
|
|
7110
|
+
base: "#F472B6",
|
|
7111
|
+
hover: "#EC4899",
|
|
7112
|
+
info: "#22D3EE",
|
|
7113
|
+
infoHover: "#06B6D4"
|
|
7114
|
+
},
|
|
7115
|
+
{
|
|
7116
|
+
base: "#DB2777",
|
|
7117
|
+
hover: "#BE185D",
|
|
7118
|
+
info: "#0891B2",
|
|
7119
|
+
infoHover: "#0E7490"
|
|
7120
|
+
},
|
|
7121
|
+
{
|
|
7122
|
+
base: "#BE185D",
|
|
7123
|
+
hover: "#9D174D",
|
|
7124
|
+
info: "#0E7490",
|
|
7125
|
+
infoHover: "#155E75"
|
|
7126
|
+
},
|
|
7127
|
+
{
|
|
7128
|
+
base: "#D946EF",
|
|
7129
|
+
hover: "#C026D3",
|
|
7130
|
+
info: "#F59E0B",
|
|
7131
|
+
infoHover: "#D97706"
|
|
7132
|
+
},
|
|
7133
|
+
{
|
|
7134
|
+
base: "#E879F9",
|
|
7135
|
+
hover: "#D946EF",
|
|
7136
|
+
info: "#FBBF24",
|
|
7137
|
+
infoHover: "#F59E0B"
|
|
7138
|
+
},
|
|
7139
|
+
{
|
|
7140
|
+
base: "#C026D3",
|
|
7141
|
+
hover: "#A21CAF",
|
|
7142
|
+
info: "#D97706",
|
|
7143
|
+
infoHover: "#B45309"
|
|
7144
|
+
},
|
|
7145
|
+
{
|
|
7146
|
+
base: "#A21CAF",
|
|
7147
|
+
hover: "#86198F",
|
|
7148
|
+
info: "#B45309",
|
|
7149
|
+
infoHover: "#92400E"
|
|
7150
|
+
}
|
|
7151
|
+
]
|
|
6610
7152
|
};
|
|
6611
7153
|
|
|
6612
7154
|
// src/components/theme-provider.tsx
|
|
6613
7155
|
import { jsx as jsx36 } from "react/jsx-runtime";
|
|
6614
|
-
var
|
|
6615
|
-
theme: settingConfig_default.theme,
|
|
6616
|
-
fontSize: settingConfig_default.fontSize,
|
|
6617
|
-
fontFamily: settingConfig_default.fontFamily,
|
|
6618
|
-
colors: settingConfig_default.colors
|
|
7156
|
+
var FACTORY_DEFAULTS = {
|
|
7157
|
+
theme: settingConfig_default.defaults.theme,
|
|
7158
|
+
fontSize: settingConfig_default.defaults.fontSize,
|
|
7159
|
+
fontFamily: settingConfig_default.defaults.fontFamily,
|
|
7160
|
+
colors: settingConfig_default.defaults.colors
|
|
6619
7161
|
};
|
|
7162
|
+
function loadJSON(key, fallback) {
|
|
7163
|
+
try {
|
|
7164
|
+
const raw = localStorage.getItem(key);
|
|
7165
|
+
if (raw) return { ...fallback, ...JSON.parse(raw) };
|
|
7166
|
+
} catch {
|
|
7167
|
+
}
|
|
7168
|
+
return fallback;
|
|
7169
|
+
}
|
|
7170
|
+
function saveJSON(key, value) {
|
|
7171
|
+
try {
|
|
7172
|
+
localStorage.setItem(key, JSON.stringify(value));
|
|
7173
|
+
} catch {
|
|
7174
|
+
}
|
|
7175
|
+
}
|
|
6620
7176
|
var initialState = {
|
|
6621
|
-
...
|
|
7177
|
+
...FACTORY_DEFAULTS,
|
|
6622
7178
|
setTheme: () => null,
|
|
6623
7179
|
setColors: () => null,
|
|
6624
7180
|
setFontSize: () => null,
|
|
6625
7181
|
setFontFamily: () => null,
|
|
7182
|
+
saveConfig: () => null,
|
|
6626
7183
|
resetSettings: () => null
|
|
6627
7184
|
};
|
|
6628
7185
|
var ThemeProviderContext = createContext2(initialState);
|
|
6629
|
-
var COLOR_PALETTE =
|
|
6630
|
-
{ base: "#6366f1", hover: "#4f46e5" },
|
|
6631
|
-
{ base: "#8b5cf6", hover: "#7c3aed" },
|
|
6632
|
-
{ base: "#3b82f6", hover: "#2563eb" },
|
|
6633
|
-
{ base: "#10b981", hover: "#059669" },
|
|
6634
|
-
{ base: "#22c55e", hover: "#16a34a" },
|
|
6635
|
-
{ base: "#eab308", hover: "#ca8a04" },
|
|
6636
|
-
{ base: "#f59e0b", hover: "#d97706" },
|
|
6637
|
-
{ base: "#f97316", hover: "#ea580c" },
|
|
6638
|
-
{ base: "#ef4444", hover: "#dc2626" },
|
|
6639
|
-
{ base: "#ec4899", hover: "#db2777" }
|
|
6640
|
-
];
|
|
7186
|
+
var COLOR_PALETTE = settingConfig_default.colorPalette;
|
|
6641
7187
|
function ThemeProvider({
|
|
6642
7188
|
children,
|
|
6643
7189
|
storageKey = "codego-ui-theme-settings",
|
|
7190
|
+
savedConfigKey = "codego-ui-saved-config",
|
|
6644
7191
|
...props
|
|
6645
7192
|
}) {
|
|
6646
|
-
const [
|
|
6647
|
-
|
|
6648
|
-
|
|
6649
|
-
|
|
6650
|
-
|
|
6651
|
-
|
|
6652
|
-
return configDefaults;
|
|
6653
|
-
});
|
|
7193
|
+
const [savedConfig, setSavedConfig] = useState25(
|
|
7194
|
+
() => loadJSON(savedConfigKey, FACTORY_DEFAULTS)
|
|
7195
|
+
);
|
|
7196
|
+
const [settings, setSettings] = useState25(
|
|
7197
|
+
() => loadJSON(storageKey, savedConfig)
|
|
7198
|
+
);
|
|
6654
7199
|
useEffect21(() => {
|
|
6655
|
-
|
|
7200
|
+
saveJSON(storageKey, settings);
|
|
6656
7201
|
}, [settings, storageKey]);
|
|
6657
7202
|
useEffect21(() => {
|
|
6658
7203
|
const root = window.document.documentElement;
|
|
@@ -6678,7 +7223,13 @@ function ThemeProvider({
|
|
|
6678
7223
|
setColors: (colors) => setSettings((s) => ({ ...s, colors: { ...s.colors, ...colors } })),
|
|
6679
7224
|
setFontSize: (fontSize) => setSettings((s) => ({ ...s, fontSize })),
|
|
6680
7225
|
setFontFamily: (fontFamily) => setSettings((s) => ({ ...s, fontFamily })),
|
|
6681
|
-
|
|
7226
|
+
// Save current live settings as the new persisted defaults
|
|
7227
|
+
saveConfig: () => {
|
|
7228
|
+
setSavedConfig(settings);
|
|
7229
|
+
saveJSON(savedConfigKey, settings);
|
|
7230
|
+
},
|
|
7231
|
+
// Reset live settings back to saved defaults
|
|
7232
|
+
resetSettings: () => setSettings(savedConfig)
|
|
6682
7233
|
};
|
|
6683
7234
|
return /* @__PURE__ */ jsx36(ThemeProviderContext.Provider, { ...props, value, children });
|
|
6684
7235
|
}
|
|
@@ -7569,7 +8120,8 @@ function SectionBlock({
|
|
|
7569
8120
|
}
|
|
7570
8121
|
|
|
7571
8122
|
// src/components/ui/PanelSettings.tsx
|
|
7572
|
-
import
|
|
8123
|
+
import * as React39 from "react";
|
|
8124
|
+
import { RotateCcw as RotateCcw2, Save } from "lucide-react";
|
|
7573
8125
|
|
|
7574
8126
|
// src/components/ui/tabs.tsx
|
|
7575
8127
|
import * as React38 from "react";
|
|
@@ -7655,30 +8207,10 @@ function Tabs({
|
|
|
7655
8207
|
|
|
7656
8208
|
// src/components/ui/PanelSettings.tsx
|
|
7657
8209
|
import { jsx as jsx48, jsxs as jsxs42 } from "react/jsx-runtime";
|
|
7658
|
-
var
|
|
7659
|
-
|
|
7660
|
-
|
|
7661
|
-
|
|
7662
|
-
{ value: "20px", label: "Extra Large (20px)" }
|
|
7663
|
-
];
|
|
7664
|
-
var FONT_FAMILIES = [
|
|
7665
|
-
{ value: '"Space Grotesk", "Inter", sans-serif', label: "Space Grotesk" },
|
|
7666
|
-
{ value: '"Inter", sans-serif', label: "Inter" },
|
|
7667
|
-
{ value: '"JetBrains Mono", monospace', label: "JetBrains Mono" },
|
|
7668
|
-
{ value: "system-ui, sans-serif", label: "System UI" }
|
|
7669
|
-
];
|
|
7670
|
-
var THEME_OPTIONS = [
|
|
7671
|
-
{ value: "light", label: "Light" },
|
|
7672
|
-
{ value: "dark", label: "Dark" },
|
|
7673
|
-
{ value: "system", label: "System" }
|
|
7674
|
-
];
|
|
7675
|
-
var COLOR_PAIRS = [
|
|
7676
|
-
{ base: "primary", hover: "primaryHover", label: "Primary" },
|
|
7677
|
-
{ base: "secondary", hover: "secondaryHover", label: "Secondary" },
|
|
7678
|
-
{ base: "info", hover: "infoHover", label: "Info" },
|
|
7679
|
-
{ base: "warning", hover: "warningHover", label: "Warning" },
|
|
7680
|
-
{ base: "danger", hover: "dangerHover", label: "Danger" }
|
|
7681
|
-
];
|
|
8210
|
+
var THEME_OPTIONS = settingConfig_default.themeOptions;
|
|
8211
|
+
var FONT_SIZES = settingConfig_default.fontSizes;
|
|
8212
|
+
var FONT_FAMILIES = settingConfig_default.fontFamilies;
|
|
8213
|
+
var COLOR_PAIRS = settingConfig_default.colorPairs;
|
|
7682
8214
|
function SettingRow({ label, description, children }) {
|
|
7683
8215
|
return /* @__PURE__ */ jsxs42("div", { className: "flex items-start justify-between gap-4 py-3 border-b border-border/60 last:border-0", children: [
|
|
7684
8216
|
/* @__PURE__ */ jsxs42("div", { className: "min-w-0", children: [
|
|
@@ -7726,8 +8258,8 @@ function ColorsPanel({ onColorsChange }) {
|
|
|
7726
8258
|
type: "button",
|
|
7727
8259
|
title: c.base,
|
|
7728
8260
|
onClick: () => {
|
|
7729
|
-
setColors({ primary: c.base, primaryHover: c.hover });
|
|
7730
|
-
onColorsChange?.({ primary: c.base, primaryHover: c.hover });
|
|
8261
|
+
setColors({ primary: c.base, primaryHover: c.hover, info: c.info, infoHover: c.infoHover });
|
|
8262
|
+
onColorsChange?.({ primary: c.base, primaryHover: c.hover, info: c.info, infoHover: c.infoHover });
|
|
7731
8263
|
},
|
|
7732
8264
|
className: cn(
|
|
7733
8265
|
"h-7 w-full rounded-md border border-white/10 transition-transform hover:scale-110 focus:outline-none focus:ring-2 focus:ring-ring",
|
|
@@ -7803,10 +8335,18 @@ function PanelSettings({
|
|
|
7803
8335
|
onColorsChange,
|
|
7804
8336
|
onFontSizeChange,
|
|
7805
8337
|
onFontFamilyChange,
|
|
8338
|
+
onSave,
|
|
7806
8339
|
onReset,
|
|
7807
8340
|
className
|
|
7808
8341
|
}) {
|
|
7809
|
-
const { resetSettings } = useTheme();
|
|
8342
|
+
const { saveConfig, resetSettings } = useTheme();
|
|
8343
|
+
const [saved, setSaved] = React39.useState(false);
|
|
8344
|
+
const handleSave = () => {
|
|
8345
|
+
saveConfig();
|
|
8346
|
+
onSave?.();
|
|
8347
|
+
setSaved(true);
|
|
8348
|
+
setTimeout(() => setSaved(false), 2e3);
|
|
8349
|
+
};
|
|
7810
8350
|
const handleReset = () => {
|
|
7811
8351
|
resetSettings();
|
|
7812
8352
|
onReset?.();
|
|
@@ -7830,10 +8370,16 @@ function PanelSettings({
|
|
|
7830
8370
|
];
|
|
7831
8371
|
return /* @__PURE__ */ jsxs42("div", { className: cn("flex flex-col gap-4", className), children: [
|
|
7832
8372
|
/* @__PURE__ */ jsx48(Tabs, { items: tabs, defaultValue: defaultTab, variant: "pill" }),
|
|
7833
|
-
/* @__PURE__ */
|
|
7834
|
-
/* @__PURE__ */
|
|
7835
|
-
|
|
7836
|
-
|
|
8373
|
+
/* @__PURE__ */ jsxs42("div", { className: "flex justify-end gap-2 pt-1", children: [
|
|
8374
|
+
/* @__PURE__ */ jsxs42(Button, { variant: "outline", size: "sm", onClick: handleReset, children: [
|
|
8375
|
+
/* @__PURE__ */ jsx48(RotateCcw2, { className: "h-3.5 w-3.5 mr-1.5" }),
|
|
8376
|
+
"Reset"
|
|
8377
|
+
] }),
|
|
8378
|
+
/* @__PURE__ */ jsxs42(Button, { size: "sm", onClick: handleSave, children: [
|
|
8379
|
+
/* @__PURE__ */ jsx48(Save, { className: "h-3.5 w-3.5 mr-1.5" }),
|
|
8380
|
+
saved ? "Saved!" : "Save"
|
|
8381
|
+
] })
|
|
8382
|
+
] })
|
|
7837
8383
|
] });
|
|
7838
8384
|
}
|
|
7839
8385
|
|
|
@@ -7853,7 +8399,7 @@ function Skeleton({
|
|
|
7853
8399
|
}
|
|
7854
8400
|
|
|
7855
8401
|
// src/components/ui/slider.tsx
|
|
7856
|
-
import * as
|
|
8402
|
+
import * as React40 from "react";
|
|
7857
8403
|
import { jsx as jsx50, jsxs as jsxs43 } from "react/jsx-runtime";
|
|
7858
8404
|
function pct(val, min, max) {
|
|
7859
8405
|
return (val - min) / (max - min) * 100;
|
|
@@ -7873,8 +8419,8 @@ function Slider({
|
|
|
7873
8419
|
showValue = false,
|
|
7874
8420
|
className
|
|
7875
8421
|
}) {
|
|
7876
|
-
const [internal, setInternal] =
|
|
7877
|
-
const [hovering, setHovering] =
|
|
8422
|
+
const [internal, setInternal] = React40.useState(defaultValue);
|
|
8423
|
+
const [hovering, setHovering] = React40.useState(false);
|
|
7878
8424
|
const val = controlled ?? internal;
|
|
7879
8425
|
function handleChange(e) {
|
|
7880
8426
|
const v = Number(e.target.value);
|
|
@@ -7951,8 +8497,8 @@ function RangeSlider({
|
|
|
7951
8497
|
showValue = false,
|
|
7952
8498
|
className
|
|
7953
8499
|
}) {
|
|
7954
|
-
const [internal, setInternal] =
|
|
7955
|
-
const [active, setActive] =
|
|
8500
|
+
const [internal, setInternal] = React40.useState(defaultValue);
|
|
8501
|
+
const [active, setActive] = React40.useState(null);
|
|
7956
8502
|
const val = controlled ?? internal;
|
|
7957
8503
|
function handleChange(idx, e) {
|
|
7958
8504
|
const v = Number(e.target.value);
|
|
@@ -7975,7 +8521,7 @@ function RangeSlider({
|
|
|
7975
8521
|
/* @__PURE__ */ jsx50("div", { className: "absolute w-full h-1.5 rounded-full bg-muted", children: /* @__PURE__ */ jsx50("div", { className: "absolute h-full rounded-full bg-primary", style: { left: `${p0}%`, width: `${p1 - p0}%` } }) }),
|
|
7976
8522
|
[0, 1].map((idx) => {
|
|
7977
8523
|
const p = idx === 0 ? p0 : p1;
|
|
7978
|
-
return /* @__PURE__ */ jsxs43(
|
|
8524
|
+
return /* @__PURE__ */ jsxs43(React40.Fragment, { children: [
|
|
7979
8525
|
showTooltip && active === idx && !disabled && /* @__PURE__ */ jsx50(
|
|
7980
8526
|
"div",
|
|
7981
8527
|
{
|
|
@@ -8086,7 +8632,7 @@ function StatCard({
|
|
|
8086
8632
|
}
|
|
8087
8633
|
|
|
8088
8634
|
// src/components/ui/stepper.tsx
|
|
8089
|
-
import * as
|
|
8635
|
+
import * as React41 from "react";
|
|
8090
8636
|
import { Check as Check6, X as X11 } from "lucide-react";
|
|
8091
8637
|
import { jsx as jsx52, jsxs as jsxs45 } from "react/jsx-runtime";
|
|
8092
8638
|
function getStatus(idx, current) {
|
|
@@ -8109,7 +8655,7 @@ function Stepper({
|
|
|
8109
8655
|
clickable = false,
|
|
8110
8656
|
className
|
|
8111
8657
|
}) {
|
|
8112
|
-
const [internal, setInternal] =
|
|
8658
|
+
const [internal, setInternal] = React41.useState(defaultCurrent);
|
|
8113
8659
|
const current = controlled ?? internal;
|
|
8114
8660
|
function go(idx) {
|
|
8115
8661
|
if (!clickable) return;
|
|
@@ -8124,7 +8670,7 @@ function Stepper({
|
|
|
8124
8670
|
), children: steps.map((step, i) => {
|
|
8125
8671
|
const status = getStatus(i, current);
|
|
8126
8672
|
const isLast = i === steps.length - 1;
|
|
8127
|
-
return /* @__PURE__ */ jsx52(
|
|
8673
|
+
return /* @__PURE__ */ jsx52(React41.Fragment, { children: /* @__PURE__ */ jsxs45("div", { className: cn(
|
|
8128
8674
|
"flex",
|
|
8129
8675
|
isHorizontal ? "flex-col items-center flex-1" : "flex-row gap-4"
|
|
8130
8676
|
), children: [
|
|
@@ -8168,7 +8714,7 @@ function Stepper({
|
|
|
8168
8714
|
}
|
|
8169
8715
|
|
|
8170
8716
|
// src/components/ui/table.tsx
|
|
8171
|
-
import * as
|
|
8717
|
+
import * as React42 from "react";
|
|
8172
8718
|
import { ChevronLeft as ChevronLeft5, ChevronRight as ChevronRight8, Search as Search5, Trash2 as Trash23, ChevronsUpDown as ChevronsUpDown2, ChevronUp as ChevronUp2, ChevronDown as ChevronDown7, X as X12 } from "lucide-react";
|
|
8173
8719
|
import { Fragment as Fragment13, jsx as jsx53, jsxs as jsxs46 } from "react/jsx-runtime";
|
|
8174
8720
|
var BADGE_COLORS = {
|
|
@@ -8193,11 +8739,11 @@ function Table({
|
|
|
8193
8739
|
idKey = "id",
|
|
8194
8740
|
className
|
|
8195
8741
|
}) {
|
|
8196
|
-
const [search, setSearch] =
|
|
8197
|
-
const [currentPage, setCurrentPage] =
|
|
8198
|
-
const [selectedIds, setSelectedIds] =
|
|
8199
|
-
const [sortKey, setSortKey] =
|
|
8200
|
-
const [sortDir, setSortDir] =
|
|
8742
|
+
const [search, setSearch] = React42.useState("");
|
|
8743
|
+
const [currentPage, setCurrentPage] = React42.useState(1);
|
|
8744
|
+
const [selectedIds, setSelectedIds] = React42.useState([]);
|
|
8745
|
+
const [sortKey, setSortKey] = React42.useState(null);
|
|
8746
|
+
const [sortDir, setSortDir] = React42.useState(null);
|
|
8201
8747
|
const handleSort = (key) => {
|
|
8202
8748
|
if (sortKey !== key) {
|
|
8203
8749
|
setSortKey(key);
|
|
@@ -8211,7 +8757,7 @@ function Table({
|
|
|
8211
8757
|
setSortKey(null);
|
|
8212
8758
|
setSortDir(null);
|
|
8213
8759
|
};
|
|
8214
|
-
const filteredData =
|
|
8760
|
+
const filteredData = React42.useMemo(() => {
|
|
8215
8761
|
let d = search ? data.filter(
|
|
8216
8762
|
(item) => Object.values(item).some(
|
|
8217
8763
|
(val) => val && typeof val === "string" && val.toLowerCase().includes(search.toLowerCase())
|
|
@@ -8229,18 +8775,18 @@ function Table({
|
|
|
8229
8775
|
}, [data, search, sortKey, sortDir]);
|
|
8230
8776
|
const totalPages = Math.max(1, Math.ceil(filteredData.length / itemsPerPage));
|
|
8231
8777
|
const safePage = Math.min(currentPage, totalPages);
|
|
8232
|
-
const paginatedData =
|
|
8778
|
+
const paginatedData = React42.useMemo(() => {
|
|
8233
8779
|
if (!pagination) return filteredData;
|
|
8234
8780
|
const start = (safePage - 1) * itemsPerPage;
|
|
8235
8781
|
return filteredData.slice(start, start + itemsPerPage);
|
|
8236
8782
|
}, [filteredData, pagination, safePage, itemsPerPage]);
|
|
8237
|
-
|
|
8783
|
+
React42.useEffect(() => {
|
|
8238
8784
|
setCurrentPage(1);
|
|
8239
8785
|
}, [search]);
|
|
8240
8786
|
const handleSelectAll = (checked) => setSelectedIds(checked ? paginatedData.map((item) => String(item[idKey])) : []);
|
|
8241
8787
|
const handleSelect = (id, checked) => setSelectedIds((prev) => checked ? [...prev, id] : prev.filter((i) => i !== id));
|
|
8242
8788
|
const allSelected = paginatedData.length > 0 && selectedIds.length === paginatedData.length;
|
|
8243
|
-
const pagePills =
|
|
8789
|
+
const pagePills = React42.useMemo(() => {
|
|
8244
8790
|
if (totalPages <= 5) return Array.from({ length: totalPages }, (_, i) => i + 1);
|
|
8245
8791
|
if (safePage <= 3) return [1, 2, 3, 4, 5];
|
|
8246
8792
|
if (safePage >= totalPages - 2) return [totalPages - 4, totalPages - 3, totalPages - 2, totalPages - 1, totalPages];
|
|
@@ -8469,7 +9015,7 @@ function Table({
|
|
|
8469
9015
|
}
|
|
8470
9016
|
|
|
8471
9017
|
// src/components/ui/tag-input.tsx
|
|
8472
|
-
import * as
|
|
9018
|
+
import * as React43 from "react";
|
|
8473
9019
|
import { jsx as jsx54, jsxs as jsxs47 } from "react/jsx-runtime";
|
|
8474
9020
|
function TagInput({
|
|
8475
9021
|
value: controlled,
|
|
@@ -8481,9 +9027,9 @@ function TagInput({
|
|
|
8481
9027
|
disabled = false,
|
|
8482
9028
|
className
|
|
8483
9029
|
}) {
|
|
8484
|
-
const [internal, setInternal] =
|
|
8485
|
-
const [input, setInput] =
|
|
8486
|
-
const inputRef =
|
|
9030
|
+
const [internal, setInternal] = React43.useState(defaultValue);
|
|
9031
|
+
const [input, setInput] = React43.useState("");
|
|
9032
|
+
const inputRef = React43.useRef(null);
|
|
8487
9033
|
const tags = controlled ?? internal;
|
|
8488
9034
|
function addTag(raw) {
|
|
8489
9035
|
const tag = raw.trim();
|
|
@@ -8588,9 +9134,9 @@ function Timeline({ items, align = "left", className }) {
|
|
|
8588
9134
|
}
|
|
8589
9135
|
|
|
8590
9136
|
// src/components/ui/toggle-switch.tsx
|
|
8591
|
-
import * as
|
|
9137
|
+
import * as React44 from "react";
|
|
8592
9138
|
import { jsx as jsx56, jsxs as jsxs49 } from "react/jsx-runtime";
|
|
8593
|
-
var ToggleSwitch =
|
|
9139
|
+
var ToggleSwitch = React44.forwardRef(
|
|
8594
9140
|
({
|
|
8595
9141
|
className,
|
|
8596
9142
|
inline = false,
|
|
@@ -8608,10 +9154,10 @@ var ToggleSwitch = React43.forwardRef(
|
|
|
8608
9154
|
disabled,
|
|
8609
9155
|
...props
|
|
8610
9156
|
}, ref) => {
|
|
8611
|
-
const toggleId = id ??
|
|
9157
|
+
const toggleId = id ?? React44.useId();
|
|
8612
9158
|
const trackW = width ? typeof width === "number" ? `${width}px` : width : "2.75rem";
|
|
8613
9159
|
const trackH = height ? typeof height === "number" ? `${height}px` : height : "1.5rem";
|
|
8614
|
-
const [internalChecked, setInternalChecked] =
|
|
9160
|
+
const [internalChecked, setInternalChecked] = React44.useState(defaultChecked ?? false);
|
|
8615
9161
|
const isControlled = checked !== void 0;
|
|
8616
9162
|
const isOn = accepted ? true : declined ? false : isControlled ? checked : internalChecked;
|
|
8617
9163
|
const stateColor = accepted ? acceptedColor ?? "#22c55e" : declined ? declinedColor ?? "#ef4444" : isOn ? void 0 : void 0;
|
|
@@ -8681,7 +9227,7 @@ var ToggleSwitch = React43.forwardRef(
|
|
|
8681
9227
|
ToggleSwitch.displayName = "ToggleSwitch";
|
|
8682
9228
|
|
|
8683
9229
|
// src/components/ui/tree-view.tsx
|
|
8684
|
-
import * as
|
|
9230
|
+
import * as React45 from "react";
|
|
8685
9231
|
import { ChevronRight as ChevronRight9, Folder, FolderOpen, File } from "lucide-react";
|
|
8686
9232
|
import { jsx as jsx57, jsxs as jsxs50 } from "react/jsx-runtime";
|
|
8687
9233
|
function TreeNodeItem({ node, depth, selected, expanded, onToggleExpand, onSelect, multiple }) {
|
|
@@ -8735,8 +9281,8 @@ function TreeView({
|
|
|
8735
9281
|
className
|
|
8736
9282
|
}) {
|
|
8737
9283
|
const init = defaultSelected ? Array.isArray(defaultSelected) ? defaultSelected : [defaultSelected] : [];
|
|
8738
|
-
const [internal, setInternal] =
|
|
8739
|
-
const [expanded, setExpanded] =
|
|
9284
|
+
const [internal, setInternal] = React45.useState(init);
|
|
9285
|
+
const [expanded, setExpanded] = React45.useState(defaultExpanded);
|
|
8740
9286
|
const selected = controlled ? Array.isArray(controlled) ? controlled : [controlled] : internal;
|
|
8741
9287
|
function handleSelect(id) {
|
|
8742
9288
|
let next;
|
|
@@ -8767,7 +9313,7 @@ function TreeView({
|
|
|
8767
9313
|
}
|
|
8768
9314
|
|
|
8769
9315
|
// src/components/ui/widget.tsx
|
|
8770
|
-
import * as
|
|
9316
|
+
import * as React46 from "react";
|
|
8771
9317
|
import { jsx as jsx58, jsxs as jsxs51 } from "react/jsx-runtime";
|
|
8772
9318
|
var iconColorMap = {
|
|
8773
9319
|
primary: "bg-primary/10 text-primary",
|
|
@@ -8796,8 +9342,8 @@ var variantMap = {
|
|
|
8796
9342
|
outline: "bg-transparent border-2"
|
|
8797
9343
|
};
|
|
8798
9344
|
function useCountUp(target, enabled, duration = 1e3) {
|
|
8799
|
-
const [display, setDisplay] =
|
|
8800
|
-
|
|
9345
|
+
const [display, setDisplay] = React46.useState(enabled ? 0 : target);
|
|
9346
|
+
React46.useEffect(() => {
|
|
8801
9347
|
if (!enabled) {
|
|
8802
9348
|
setDisplay(target);
|
|
8803
9349
|
return;
|
|
@@ -8910,7 +9456,7 @@ function Widget({
|
|
|
8910
9456
|
}
|
|
8911
9457
|
|
|
8912
9458
|
// src/components/ui/wizard.tsx
|
|
8913
|
-
import * as
|
|
9459
|
+
import * as React47 from "react";
|
|
8914
9460
|
import { Check as Check7, X as X13, ChevronLeft as ChevronLeft6, ChevronRight as ChevronRight10, AlertCircle } from "lucide-react";
|
|
8915
9461
|
import { Fragment as Fragment15, jsx as jsx59, jsxs as jsxs52 } from "react/jsx-runtime";
|
|
8916
9462
|
var SIZE_MAP = {
|
|
@@ -8934,7 +9480,7 @@ function HeaderDefault({
|
|
|
8934
9480
|
return /* @__PURE__ */ jsx59("div", { className: "flex items-start w-full", children: steps.map((step, i) => {
|
|
8935
9481
|
const status = stepStatus(i, current);
|
|
8936
9482
|
const isLast = i === steps.length - 1;
|
|
8937
|
-
return /* @__PURE__ */ jsx59(
|
|
9483
|
+
return /* @__PURE__ */ jsx59(React47.Fragment, { children: /* @__PURE__ */ jsxs52("div", { className: "flex flex-col items-center flex-1 min-w-0", children: [
|
|
8938
9484
|
/* @__PURE__ */ jsxs52("div", { className: "flex items-center w-full", children: [
|
|
8939
9485
|
i > 0 && /* @__PURE__ */ jsx59("div", { className: cn("flex-1 h-0.5 transition-colors", i <= current ? "bg-primary" : "bg-border") }),
|
|
8940
9486
|
/* @__PURE__ */ jsx59(
|
|
@@ -9162,7 +9708,7 @@ function WizardPanel({
|
|
|
9162
9708
|
const isFirst = current === 0;
|
|
9163
9709
|
const isLast = current === steps.length - 1;
|
|
9164
9710
|
const isSidebar = variant === "sidebar";
|
|
9165
|
-
const [validationError, setValidationError] =
|
|
9711
|
+
const [validationError, setValidationError] = React47.useState(null);
|
|
9166
9712
|
const handleNext = () => {
|
|
9167
9713
|
const validate = steps[current]?.validate;
|
|
9168
9714
|
if (validate) {
|
|
@@ -9266,7 +9812,7 @@ function Wizard({
|
|
|
9266
9812
|
className,
|
|
9267
9813
|
contentClassName
|
|
9268
9814
|
}) {
|
|
9269
|
-
const [internalStep, setInternalStep] =
|
|
9815
|
+
const [internalStep, setInternalStep] = React47.useState(defaultStep);
|
|
9270
9816
|
const current = controlledStep ?? internalStep;
|
|
9271
9817
|
const go = (idx) => {
|
|
9272
9818
|
const clamped = Math.max(0, Math.min(steps.length - 1, idx));
|
|
@@ -9281,7 +9827,7 @@ function Wizard({
|
|
|
9281
9827
|
}
|
|
9282
9828
|
go(current + 1);
|
|
9283
9829
|
};
|
|
9284
|
-
|
|
9830
|
+
React47.useEffect(() => {
|
|
9285
9831
|
if (layout !== "modal" || !isOpen || unchange) return;
|
|
9286
9832
|
const handler = (e) => {
|
|
9287
9833
|
if (e.key === "Escape") onClose?.();
|