@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.cjs
CHANGED
|
@@ -5050,6 +5050,45 @@ function addTerrain(map) {
|
|
|
5050
5050
|
});
|
|
5051
5051
|
}
|
|
5052
5052
|
}
|
|
5053
|
+
var OSRM_PROFILE2 = { drive: "driving", walk: "foot" };
|
|
5054
|
+
async function fetchOsrmRoute2(points, routeType) {
|
|
5055
|
+
const profile = OSRM_PROFILE2[routeType];
|
|
5056
|
+
const coords = points.map((p) => `${p.lng},${p.lat}`).join(";");
|
|
5057
|
+
const res = await fetch(`https://router.project-osrm.org/route/v1/${profile}/${coords}?overview=full&geometries=geojson`);
|
|
5058
|
+
if (!res.ok) throw new Error("OSRM failed");
|
|
5059
|
+
const data = await res.json();
|
|
5060
|
+
if (data.code !== "Ok" || !data.routes?.length) throw new Error("No route");
|
|
5061
|
+
const route = data.routes[0];
|
|
5062
|
+
return {
|
|
5063
|
+
coords: route.geometry.coordinates,
|
|
5064
|
+
// already [lng, lat] for MapLibre
|
|
5065
|
+
distance: route.distance,
|
|
5066
|
+
duration: route.duration
|
|
5067
|
+
};
|
|
5068
|
+
}
|
|
5069
|
+
function fmtDistance2(m) {
|
|
5070
|
+
return m >= 1e3 ? `${(m / 1e3).toFixed(1)} km` : `${Math.round(m)} m`;
|
|
5071
|
+
}
|
|
5072
|
+
function fmtDuration2(s) {
|
|
5073
|
+
const h = Math.floor(s / 3600), m = Math.floor(s % 3600 / 60);
|
|
5074
|
+
return h > 0 ? `${h}h ${m}min` : `${m} min`;
|
|
5075
|
+
}
|
|
5076
|
+
function makeClusterHTML(variant, count, color) {
|
|
5077
|
+
if (variant === "bubble") {
|
|
5078
|
+
const size = count > 99 ? 52 : count > 9 ? 44 : 36;
|
|
5079
|
+
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>`;
|
|
5080
|
+
}
|
|
5081
|
+
if (variant === "donut") {
|
|
5082
|
+
const r = 20, stroke = 5, circ = 2 * Math.PI * r;
|
|
5083
|
+
const dash = Math.min(count / 50, 1) * circ;
|
|
5084
|
+
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>`;
|
|
5085
|
+
}
|
|
5086
|
+
const w = count > 99 ? 52 : 40;
|
|
5087
|
+
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>`;
|
|
5088
|
+
}
|
|
5089
|
+
function makeEndpointHTML(color, label) {
|
|
5090
|
+
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>`;
|
|
5091
|
+
}
|
|
5053
5092
|
function MapLibreMap({
|
|
5054
5093
|
style: styleProp = "street",
|
|
5055
5094
|
center = [0, 20],
|
|
@@ -5064,6 +5103,9 @@ function MapLibreMap({
|
|
|
5064
5103
|
maxBearing = 180,
|
|
5065
5104
|
flyTo,
|
|
5066
5105
|
markers = [],
|
|
5106
|
+
routes = [],
|
|
5107
|
+
cluster = false,
|
|
5108
|
+
clusterVariant = "default",
|
|
5067
5109
|
height = 480,
|
|
5068
5110
|
showControls = true,
|
|
5069
5111
|
showStyleSwitcher = true,
|
|
@@ -5074,7 +5116,9 @@ function MapLibreMap({
|
|
|
5074
5116
|
const containerRef = React22.useRef(null);
|
|
5075
5117
|
const mapRef = React22.useRef(null);
|
|
5076
5118
|
const markersRef = React22.useRef([]);
|
|
5119
|
+
const routeMarkersRef = React22.useRef([]);
|
|
5077
5120
|
const flyingRef = React22.useRef(false);
|
|
5121
|
+
const [routeLoading, setRouteLoading] = React22.useState(false);
|
|
5078
5122
|
const [activeStyle, setActiveStyle] = React22.useState(styleProp);
|
|
5079
5123
|
const [ready, setReady] = React22.useState(false);
|
|
5080
5124
|
const [showCamera, setShowCamera] = React22.useState(false);
|
|
@@ -5162,6 +5206,109 @@ function MapLibreMap({
|
|
|
5162
5206
|
if (ftBearing !== void 0) setBearing(clampBearing(ftBearing));
|
|
5163
5207
|
});
|
|
5164
5208
|
}, [flyTo]);
|
|
5209
|
+
React22.useEffect(() => {
|
|
5210
|
+
const map = mapRef.current;
|
|
5211
|
+
if (!map || !ready || routes.length === 0) return;
|
|
5212
|
+
function cleanRoutes() {
|
|
5213
|
+
routeMarkersRef.current.forEach((m) => m.remove());
|
|
5214
|
+
routeMarkersRef.current = [];
|
|
5215
|
+
const style = map.getStyle();
|
|
5216
|
+
(style.layers ?? []).forEach((l) => {
|
|
5217
|
+
if (l.id.startsWith("route-")) try {
|
|
5218
|
+
map.removeLayer(l.id);
|
|
5219
|
+
} catch {
|
|
5220
|
+
}
|
|
5221
|
+
});
|
|
5222
|
+
Object.keys(style.sources ?? {}).forEach((s) => {
|
|
5223
|
+
if (s.startsWith("route-")) try {
|
|
5224
|
+
map.removeSource(s);
|
|
5225
|
+
} catch {
|
|
5226
|
+
}
|
|
5227
|
+
});
|
|
5228
|
+
}
|
|
5229
|
+
cleanRoutes();
|
|
5230
|
+
setRouteLoading(true);
|
|
5231
|
+
Promise.all(
|
|
5232
|
+
routes.map(async (r, i) => {
|
|
5233
|
+
const points = [r.start, ...r.waypoints ?? [], r.end];
|
|
5234
|
+
try {
|
|
5235
|
+
const result = await fetchOsrmRoute2(points, r.routeType ?? "drive");
|
|
5236
|
+
return { route: r, idx: i, ...result, error: false };
|
|
5237
|
+
} catch {
|
|
5238
|
+
return { route: r, idx: i, coords: points.map((p) => [p.lng, p.lat]), distance: 0, duration: 0, error: true };
|
|
5239
|
+
}
|
|
5240
|
+
})
|
|
5241
|
+
).then((results) => {
|
|
5242
|
+
setRouteLoading(false);
|
|
5243
|
+
if (!mapRef.current) return;
|
|
5244
|
+
const m = mapRef.current;
|
|
5245
|
+
const allCoords = [];
|
|
5246
|
+
results.forEach(({ route, idx, coords, distance, duration }) => {
|
|
5247
|
+
const color = route.color ?? (route.routeType === "walk" ? "#22c55e" : "#6366f1");
|
|
5248
|
+
const srcId = `route-${idx}`;
|
|
5249
|
+
const geojson = {
|
|
5250
|
+
type: "Feature",
|
|
5251
|
+
properties: {},
|
|
5252
|
+
geometry: { type: "LineString", coordinates: coords }
|
|
5253
|
+
};
|
|
5254
|
+
m.addSource(srcId, { type: "geojson", data: geojson });
|
|
5255
|
+
m.addLayer({
|
|
5256
|
+
id: `${srcId}-outline`,
|
|
5257
|
+
type: "line",
|
|
5258
|
+
source: srcId,
|
|
5259
|
+
layout: { "line-cap": "round", "line-join": "round" },
|
|
5260
|
+
paint: { "line-color": "#ffffff", "line-width": (route.weight ?? 5) + 4, "line-opacity": 0.3 }
|
|
5261
|
+
});
|
|
5262
|
+
m.addLayer({
|
|
5263
|
+
id: `${srcId}-line`,
|
|
5264
|
+
type: "line",
|
|
5265
|
+
source: srcId,
|
|
5266
|
+
layout: { "line-cap": "round", "line-join": "round" },
|
|
5267
|
+
paint: { "line-color": color, "line-width": route.weight ?? 5, "line-opacity": 0.9 }
|
|
5268
|
+
});
|
|
5269
|
+
allCoords.push(...coords);
|
|
5270
|
+
const makeEndpointMarker = (lngLat, label, markerColor, popupHtml) => {
|
|
5271
|
+
const el = document.createElement("div");
|
|
5272
|
+
el.innerHTML = makeEndpointHTML(markerColor, label);
|
|
5273
|
+
el.style.cssText = "width:28px;height:28px";
|
|
5274
|
+
const popup = new import_maplibre_gl.default.Popup({ offset: [0, -16], closeButton: false }).setHTML(popupHtml);
|
|
5275
|
+
const marker = new import_maplibre_gl.default.Marker({ element: el, anchor: "center" }).setLngLat(lngLat).setPopup(popup).addTo(m);
|
|
5276
|
+
routeMarkersRef.current.push(marker);
|
|
5277
|
+
};
|
|
5278
|
+
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>` : "";
|
|
5279
|
+
makeEndpointMarker(
|
|
5280
|
+
[route.start.lng, route.start.lat],
|
|
5281
|
+
"A",
|
|
5282
|
+
color,
|
|
5283
|
+
`<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>`
|
|
5284
|
+
);
|
|
5285
|
+
makeEndpointMarker(
|
|
5286
|
+
[route.end.lng, route.end.lat],
|
|
5287
|
+
"B",
|
|
5288
|
+
"#ef4444",
|
|
5289
|
+
`<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>`
|
|
5290
|
+
);
|
|
5291
|
+
if (distance > 0 && coords.length > 1) {
|
|
5292
|
+
const mid = coords[Math.floor(coords.length / 2)];
|
|
5293
|
+
const text = `${fmtDistance2(distance)} \xB7 ${fmtDuration2(duration)}`;
|
|
5294
|
+
const estW = text.length * 7 + 16;
|
|
5295
|
+
const el = document.createElement("div");
|
|
5296
|
+
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>`;
|
|
5297
|
+
el.style.cssText = `width:${estW}px;height:22px;pointer-events:none`;
|
|
5298
|
+
const badge = new import_maplibre_gl.default.Marker({ element: el, anchor: "center" }).setLngLat(mid).addTo(m);
|
|
5299
|
+
routeMarkersRef.current.push(badge);
|
|
5300
|
+
}
|
|
5301
|
+
});
|
|
5302
|
+
if (allCoords.length > 1) {
|
|
5303
|
+
const lngs = allCoords.map((c) => c[0]), lats = allCoords.map((c) => c[1]);
|
|
5304
|
+
m.fitBounds(
|
|
5305
|
+
[[Math.min(...lngs), Math.min(...lats)], [Math.max(...lngs), Math.max(...lats)]],
|
|
5306
|
+
{ padding: 60, duration: 800 }
|
|
5307
|
+
);
|
|
5308
|
+
}
|
|
5309
|
+
});
|
|
5310
|
+
return cleanRoutes;
|
|
5311
|
+
}, [routes, ready]);
|
|
5165
5312
|
function switchStyle(s) {
|
|
5166
5313
|
const map = mapRef.current;
|
|
5167
5314
|
if (!map) return;
|
|
@@ -5169,6 +5316,8 @@ function MapLibreMap({
|
|
|
5169
5316
|
setReady(false);
|
|
5170
5317
|
markersRef.current.forEach((m) => m.remove());
|
|
5171
5318
|
markersRef.current = [];
|
|
5319
|
+
routeMarkersRef.current.forEach((m) => m.remove());
|
|
5320
|
+
routeMarkersRef.current = [];
|
|
5172
5321
|
map.setStyle(s === "satellite" ? SATELLITE_STYLE : STYLE_URLS[s]);
|
|
5173
5322
|
map.once("style.load", () => {
|
|
5174
5323
|
if (s === "globe") {
|
|
@@ -5200,32 +5349,107 @@ function MapLibreMap({
|
|
|
5200
5349
|
setReady(true);
|
|
5201
5350
|
});
|
|
5202
5351
|
}
|
|
5352
|
+
const [mapZoom, setMapZoom] = React22.useState(zoom);
|
|
5353
|
+
React22.useEffect(() => {
|
|
5354
|
+
const map = mapRef.current;
|
|
5355
|
+
if (!map) return;
|
|
5356
|
+
const h2 = () => setMapZoom(map.getZoom());
|
|
5357
|
+
map.on("zoomend", h2);
|
|
5358
|
+
return () => {
|
|
5359
|
+
map.off("zoomend", h2);
|
|
5360
|
+
};
|
|
5361
|
+
}, [ready]);
|
|
5203
5362
|
React22.useEffect(() => {
|
|
5204
5363
|
const map = mapRef.current;
|
|
5205
5364
|
if (!map || !ready) return;
|
|
5206
5365
|
markersRef.current.forEach((m) => m.remove());
|
|
5207
5366
|
markersRef.current = [];
|
|
5208
|
-
markers.
|
|
5209
|
-
const
|
|
5210
|
-
const
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5367
|
+
if (cluster && markers.length > 0) {
|
|
5368
|
+
const GRID = 80;
|
|
5369
|
+
const used = /* @__PURE__ */ new Set();
|
|
5370
|
+
const groups = [];
|
|
5371
|
+
markers.forEach((m, i) => {
|
|
5372
|
+
if (used.has(i)) return;
|
|
5373
|
+
const pt = map.project([m.lng, m.lat]);
|
|
5374
|
+
const group = [m];
|
|
5375
|
+
used.add(i);
|
|
5376
|
+
markers.forEach((m2, j) => {
|
|
5377
|
+
if (used.has(j)) return;
|
|
5378
|
+
const pt2 = map.project([m2.lng, m2.lat]);
|
|
5379
|
+
if (Math.abs(pt.x - pt2.x) < GRID && Math.abs(pt.y - pt2.y) < GRID) {
|
|
5380
|
+
group.push(m2);
|
|
5381
|
+
used.add(j);
|
|
5382
|
+
}
|
|
5383
|
+
});
|
|
5384
|
+
const lat = group.reduce((s, x) => s + x.lat, 0) / group.length;
|
|
5385
|
+
const lng = group.reduce((s, x) => s + x.lng, 0) / group.length;
|
|
5386
|
+
groups.push({ center: { lng, lat }, items: group });
|
|
5387
|
+
});
|
|
5388
|
+
groups.forEach((g, gi) => {
|
|
5389
|
+
if (g.items.length === 1) {
|
|
5390
|
+
const m = g.items[0];
|
|
5391
|
+
const color = resolveColor2(m.color);
|
|
5392
|
+
const el = document.createElement("div");
|
|
5393
|
+
el.innerHTML = makePinHTML(color, m.icon, m.image);
|
|
5394
|
+
el.style.cssText = m.image ? "width:40px;height:50px" : "width:32px;height:42px";
|
|
5395
|
+
const popup = new import_maplibre_gl.default.Popup({ offset: m.image ? [0, -52] : [0, -44], closeButton: false });
|
|
5396
|
+
if (m.popup) {
|
|
5397
|
+
typeof m.popup === "string" ? popup.setHTML(m.popup) : popup.setDOMContent(m.popup);
|
|
5398
|
+
} else if (m.label) popup.setHTML(`<span style="font-size:13px;font-weight:600">${m.label}</span>`);
|
|
5399
|
+
const marker = new import_maplibre_gl.default.Marker({ element: el, anchor: "bottom" }).setLngLat([m.lng, m.lat]);
|
|
5400
|
+
if (m.popup || m.label) marker.setPopup(popup);
|
|
5401
|
+
el.addEventListener("click", () => onMarkerClick?.(m));
|
|
5402
|
+
marker.addTo(map);
|
|
5403
|
+
markersRef.current.push(marker);
|
|
5404
|
+
} else {
|
|
5405
|
+
const color = resolveColor2(g.items[0].color);
|
|
5406
|
+
const el = document.createElement("div");
|
|
5407
|
+
el.innerHTML = makeClusterHTML(clusterVariant, g.items.length, color);
|
|
5408
|
+
el.style.cssText = "cursor:pointer";
|
|
5409
|
+
const listItems = g.items.map(
|
|
5410
|
+
(m) => `<div data-id="${m.id}" style="font-size:12px;padding:2px 0;cursor:pointer;">${m.label ?? `Marker ${m.id}`}</div>`
|
|
5411
|
+
).join("");
|
|
5412
|
+
const popup = new import_maplibre_gl.default.Popup({ offset: [0, -8], closeButton: false }).setHTML(`<div style="max-height:160px;overflow-y:auto;padding:2px">${listItems}</div>`);
|
|
5413
|
+
el.addEventListener("click", () => {
|
|
5414
|
+
map.flyTo({ center: [g.center.lng, g.center.lat], zoom: map.getZoom() + 2, duration: 400 });
|
|
5415
|
+
});
|
|
5416
|
+
const marker = new import_maplibre_gl.default.Marker({ element: el, anchor: "center" }).setLngLat([g.center.lng, g.center.lat]).setPopup(popup).addTo(map);
|
|
5417
|
+
markersRef.current.push(marker);
|
|
5418
|
+
marker.getPopup().on("open", () => {
|
|
5419
|
+
g.items.forEach((m) => {
|
|
5420
|
+
const node = document.querySelector(`[data-id="${m.id}"]`);
|
|
5421
|
+
node?.addEventListener("click", () => onMarkerClick?.(m));
|
|
5422
|
+
});
|
|
5423
|
+
});
|
|
5424
|
+
}
|
|
5425
|
+
});
|
|
5426
|
+
} else {
|
|
5427
|
+
markers.forEach((m) => {
|
|
5428
|
+
const color = resolveColor2(m.color);
|
|
5429
|
+
const el = document.createElement("div");
|
|
5430
|
+
el.innerHTML = makePinHTML(color, m.icon, m.image);
|
|
5431
|
+
el.style.cssText = m.image ? "width:40px;height:50px" : "width:32px;height:42px";
|
|
5432
|
+
const popup = new import_maplibre_gl.default.Popup({ offset: m.image ? [0, -52] : [0, -44], closeButton: false });
|
|
5433
|
+
if (m.popup) {
|
|
5434
|
+
if (typeof m.popup === "string") popup.setHTML(m.popup);
|
|
5435
|
+
else popup.setDOMContent(m.popup);
|
|
5436
|
+
} else if (m.label) {
|
|
5437
|
+
popup.setHTML(`<span style="font-size:13px;font-weight:600">${m.label}</span>`);
|
|
5438
|
+
}
|
|
5439
|
+
const marker = new import_maplibre_gl.default.Marker({ element: el, anchor: "bottom" }).setLngLat([m.lng, m.lat]);
|
|
5440
|
+
if (m.popup || m.label) marker.setPopup(popup);
|
|
5441
|
+
el.addEventListener("click", () => onMarkerClick?.(m));
|
|
5442
|
+
marker.addTo(map);
|
|
5443
|
+
markersRef.current.push(marker);
|
|
5444
|
+
});
|
|
5445
|
+
}
|
|
5446
|
+
}, [markers, ready, onMarkerClick, cluster, clusterVariant, mapZoom]);
|
|
5227
5447
|
const cameraOpen = showCameraControls || showCamera;
|
|
5228
5448
|
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: cn("relative w-full overflow-hidden rounded-2xl border border-border", className), style: { height: h }, children: [
|
|
5449
|
+
routeLoading && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "absolute inset-0 z-[1000] flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("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: [
|
|
5450
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "h-4 w-4 rounded-full border-2 border-primary border-t-transparent animate-spin" }),
|
|
5451
|
+
"Calculating route\u2026"
|
|
5452
|
+
] }) }),
|
|
5229
5453
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { ref: containerRef, style: { width: "100%", height: "100%" } }),
|
|
5230
5454
|
cameraOpen && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("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: [
|
|
5231
5455
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
@@ -5560,6 +5784,7 @@ function Select({
|
|
|
5560
5784
|
const [isSearching, setIsSearching] = React25.useState(false);
|
|
5561
5785
|
const containerRef = React25.useRef(null);
|
|
5562
5786
|
const triggerRef = React25.useRef(null);
|
|
5787
|
+
const portalRef = React25.useRef(null);
|
|
5563
5788
|
const [dropStyle, setDropStyle] = React25.useState({});
|
|
5564
5789
|
const getKey = React25.useCallback((opt) => String(Object.keys(opt)[0]), []);
|
|
5565
5790
|
const getLabel = React25.useCallback((opt) => Object.values(opt)[0], []);
|
|
@@ -5590,9 +5815,9 @@ function Select({
|
|
|
5590
5815
|
};
|
|
5591
5816
|
React25.useEffect(() => {
|
|
5592
5817
|
const handler = (e) => {
|
|
5593
|
-
|
|
5594
|
-
|
|
5595
|
-
|
|
5818
|
+
const target = e.target;
|
|
5819
|
+
if (containerRef.current?.contains(target) || portalRef.current?.contains(target)) return;
|
|
5820
|
+
setIsOpen(false);
|
|
5596
5821
|
};
|
|
5597
5822
|
document.addEventListener("mousedown", handler);
|
|
5598
5823
|
return () => document.removeEventListener("mousedown", handler);
|
|
@@ -5735,6 +5960,7 @@ function Select({
|
|
|
5735
5960
|
isOpen && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(FloatingPortal, { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
5736
5961
|
"div",
|
|
5737
5962
|
{
|
|
5963
|
+
ref: portalRef,
|
|
5738
5964
|
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",
|
|
5739
5965
|
style: dropStyle,
|
|
5740
5966
|
children: [
|
|
@@ -6699,67 +6925,386 @@ var import_react = require("react");
|
|
|
6699
6925
|
|
|
6700
6926
|
// src/components/conf/settingConfig.json
|
|
6701
6927
|
var settingConfig_default = {
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
|
|
6710
|
-
|
|
6711
|
-
|
|
6712
|
-
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
|
|
6716
|
-
|
|
6928
|
+
defaults: {
|
|
6929
|
+
theme: "light",
|
|
6930
|
+
fontSize: "16px",
|
|
6931
|
+
fontFamily: '"Space Grotesk", "Inter", sans-serif',
|
|
6932
|
+
colors: {
|
|
6933
|
+
primary: "#5CF6E2",
|
|
6934
|
+
primaryHover: "#73F3E2",
|
|
6935
|
+
secondary: "#171717",
|
|
6936
|
+
secondaryHover: "#262626",
|
|
6937
|
+
info: "#3b82f6",
|
|
6938
|
+
infoHover: "#2563eb",
|
|
6939
|
+
warning: "#f59e0b",
|
|
6940
|
+
warningHover: "#d97706",
|
|
6941
|
+
danger: "#ef4444",
|
|
6942
|
+
dangerHover: "#dc2626"
|
|
6943
|
+
}
|
|
6944
|
+
},
|
|
6945
|
+
themeOptions: [
|
|
6946
|
+
{ light: "Light" },
|
|
6947
|
+
{ dark: "Dark" },
|
|
6948
|
+
{ system: "System" }
|
|
6949
|
+
],
|
|
6950
|
+
fontSizes: [
|
|
6951
|
+
{ "14px": "Small (14px)" },
|
|
6952
|
+
{ "16px": "Medium (16px)" },
|
|
6953
|
+
{ "18px": "Large (18px)" },
|
|
6954
|
+
{ "20px": "Extra Large (20px)" }
|
|
6955
|
+
],
|
|
6956
|
+
fontFamilies: [
|
|
6957
|
+
{ '"Space Grotesk", "Inter", sans-serif': "Space Grotesk" },
|
|
6958
|
+
{ '"Inter", sans-serif': "Inter" },
|
|
6959
|
+
{ '"JetBrains Mono", monospace': "JetBrains Mono" },
|
|
6960
|
+
{ "system-ui, sans-serif": "System UI" }
|
|
6961
|
+
],
|
|
6962
|
+
colorPairs: [
|
|
6963
|
+
{ base: "primary", hover: "primaryHover", label: "Primary" },
|
|
6964
|
+
{ base: "secondary", hover: "secondaryHover", label: "Secondary" },
|
|
6965
|
+
{ base: "info", hover: "infoHover", label: "Info" },
|
|
6966
|
+
{ base: "warning", hover: "warningHover", label: "Warning" },
|
|
6967
|
+
{ base: "danger", hover: "dangerHover", label: "Danger" }
|
|
6968
|
+
],
|
|
6969
|
+
colorPalette: [
|
|
6970
|
+
{
|
|
6971
|
+
base: "#6366F1",
|
|
6972
|
+
hover: "#4F46E5",
|
|
6973
|
+
info: "#F59E0B",
|
|
6974
|
+
infoHover: "#D97706"
|
|
6975
|
+
},
|
|
6976
|
+
{
|
|
6977
|
+
base: "#818CF8",
|
|
6978
|
+
hover: "#6366F1",
|
|
6979
|
+
info: "#FBBF24",
|
|
6980
|
+
infoHover: "#F59E0B"
|
|
6981
|
+
},
|
|
6982
|
+
{
|
|
6983
|
+
base: "#4F46E5",
|
|
6984
|
+
hover: "#4338CA",
|
|
6985
|
+
info: "#F59E0B",
|
|
6986
|
+
infoHover: "#D97706"
|
|
6987
|
+
},
|
|
6988
|
+
{
|
|
6989
|
+
base: "#3730A3",
|
|
6990
|
+
hover: "#312E81",
|
|
6991
|
+
info: "#D97706",
|
|
6992
|
+
infoHover: "#B45309"
|
|
6993
|
+
},
|
|
6994
|
+
{
|
|
6995
|
+
base: "#7C3AED",
|
|
6996
|
+
hover: "#6D28D9",
|
|
6997
|
+
info: "#F97316",
|
|
6998
|
+
infoHover: "#EA580C"
|
|
6999
|
+
},
|
|
7000
|
+
{
|
|
7001
|
+
base: "#A78BFA",
|
|
7002
|
+
hover: "#8B5CF6",
|
|
7003
|
+
info: "#FB923C",
|
|
7004
|
+
infoHover: "#F97316"
|
|
7005
|
+
},
|
|
7006
|
+
{
|
|
7007
|
+
base: "#8B5CF6",
|
|
7008
|
+
hover: "#7C3AED",
|
|
7009
|
+
info: "#F97316",
|
|
7010
|
+
infoHover: "#EA580C"
|
|
7011
|
+
},
|
|
7012
|
+
{
|
|
7013
|
+
base: "#6D28D9",
|
|
7014
|
+
hover: "#5B21B6",
|
|
7015
|
+
info: "#EA580C",
|
|
7016
|
+
infoHover: "#C2410C"
|
|
7017
|
+
},
|
|
7018
|
+
{
|
|
7019
|
+
base: "#0EA5E9",
|
|
7020
|
+
hover: "#0284C7",
|
|
7021
|
+
info: "#F97316",
|
|
7022
|
+
infoHover: "#EA580C"
|
|
7023
|
+
},
|
|
7024
|
+
{
|
|
7025
|
+
base: "#38BDF8",
|
|
7026
|
+
hover: "#0EA5E9",
|
|
7027
|
+
info: "#FB923C",
|
|
7028
|
+
infoHover: "#F97316"
|
|
7029
|
+
},
|
|
7030
|
+
{
|
|
7031
|
+
base: "#3B82F6",
|
|
7032
|
+
hover: "#2563EB",
|
|
7033
|
+
info: "#F59E0B",
|
|
7034
|
+
infoHover: "#D97706"
|
|
7035
|
+
},
|
|
7036
|
+
{
|
|
7037
|
+
base: "#1D4ED8",
|
|
7038
|
+
hover: "#1E40AF",
|
|
7039
|
+
info: "#D97706",
|
|
7040
|
+
infoHover: "#B45309"
|
|
7041
|
+
},
|
|
7042
|
+
{
|
|
7043
|
+
base: "#06B6D4",
|
|
7044
|
+
hover: "#0891B2",
|
|
7045
|
+
info: "#A855F7",
|
|
7046
|
+
infoHover: "#9333EA"
|
|
7047
|
+
},
|
|
7048
|
+
{
|
|
7049
|
+
base: "#22D3EE",
|
|
7050
|
+
hover: "#06B6D4",
|
|
7051
|
+
info: "#C084FC",
|
|
7052
|
+
infoHover: "#A855F7"
|
|
7053
|
+
},
|
|
7054
|
+
{
|
|
7055
|
+
base: "#14B8A6",
|
|
7056
|
+
hover: "#0F766E",
|
|
7057
|
+
info: "#8B5CF6",
|
|
7058
|
+
infoHover: "#7C3AED"
|
|
7059
|
+
},
|
|
7060
|
+
{
|
|
7061
|
+
base: "#0D9488",
|
|
7062
|
+
hover: "#0F766E",
|
|
7063
|
+
info: "#7C3AED",
|
|
7064
|
+
infoHover: "#6D28D9"
|
|
7065
|
+
},
|
|
7066
|
+
{
|
|
7067
|
+
base: "#10B981",
|
|
7068
|
+
hover: "#059669",
|
|
7069
|
+
info: "#8B5CF6",
|
|
7070
|
+
infoHover: "#7C3AED"
|
|
7071
|
+
},
|
|
7072
|
+
{
|
|
7073
|
+
base: "#34D399",
|
|
7074
|
+
hover: "#10B981",
|
|
7075
|
+
info: "#A855F7",
|
|
7076
|
+
infoHover: "#9333EA"
|
|
7077
|
+
},
|
|
7078
|
+
{
|
|
7079
|
+
base: "#22C55E",
|
|
7080
|
+
hover: "#16A34A",
|
|
7081
|
+
info: "#7C3AED",
|
|
7082
|
+
infoHover: "#6D28D9"
|
|
7083
|
+
},
|
|
7084
|
+
{
|
|
7085
|
+
base: "#16A34A",
|
|
7086
|
+
hover: "#15803D",
|
|
7087
|
+
info: "#6D28D9",
|
|
7088
|
+
infoHover: "#5B21B6"
|
|
7089
|
+
},
|
|
7090
|
+
{
|
|
7091
|
+
base: "#84CC16",
|
|
7092
|
+
hover: "#65A30D",
|
|
7093
|
+
info: "#6366F1",
|
|
7094
|
+
infoHover: "#4F46E5"
|
|
7095
|
+
},
|
|
7096
|
+
{
|
|
7097
|
+
base: "#A3E635",
|
|
7098
|
+
hover: "#84CC16",
|
|
7099
|
+
info: "#818CF8",
|
|
7100
|
+
infoHover: "#6366F1"
|
|
7101
|
+
},
|
|
7102
|
+
{
|
|
7103
|
+
base: "#65A30D",
|
|
7104
|
+
hover: "#4D7C0F",
|
|
7105
|
+
info: "#4F46E5",
|
|
7106
|
+
infoHover: "#4338CA"
|
|
7107
|
+
},
|
|
7108
|
+
{
|
|
7109
|
+
base: "#4D7C0F",
|
|
7110
|
+
hover: "#3F6212",
|
|
7111
|
+
info: "#3730A3",
|
|
7112
|
+
infoHover: "#312E81"
|
|
7113
|
+
},
|
|
7114
|
+
{
|
|
7115
|
+
base: "#EAB308",
|
|
7116
|
+
hover: "#CA8A04",
|
|
7117
|
+
info: "#3B82F6",
|
|
7118
|
+
infoHover: "#2563EB"
|
|
7119
|
+
},
|
|
7120
|
+
{
|
|
7121
|
+
base: "#FACC15",
|
|
7122
|
+
hover: "#EAB308",
|
|
7123
|
+
info: "#60A5FA",
|
|
7124
|
+
infoHover: "#3B82F6"
|
|
7125
|
+
},
|
|
7126
|
+
{
|
|
7127
|
+
base: "#F59E0B",
|
|
7128
|
+
hover: "#D97706",
|
|
7129
|
+
info: "#2563EB",
|
|
7130
|
+
infoHover: "#1D4ED8"
|
|
7131
|
+
},
|
|
7132
|
+
{
|
|
7133
|
+
base: "#D97706",
|
|
7134
|
+
hover: "#B45309",
|
|
7135
|
+
info: "#1D4ED8",
|
|
7136
|
+
infoHover: "#1E40AF"
|
|
7137
|
+
},
|
|
7138
|
+
{
|
|
7139
|
+
base: "#F97316",
|
|
7140
|
+
hover: "#EA580C",
|
|
7141
|
+
info: "#0EA5E9",
|
|
7142
|
+
infoHover: "#0284C7"
|
|
7143
|
+
},
|
|
7144
|
+
{
|
|
7145
|
+
base: "#FB923C",
|
|
7146
|
+
hover: "#F97316",
|
|
7147
|
+
info: "#38BDF8",
|
|
7148
|
+
infoHover: "#0EA5E9"
|
|
7149
|
+
},
|
|
7150
|
+
{
|
|
7151
|
+
base: "#EA580C",
|
|
7152
|
+
hover: "#C2410C",
|
|
7153
|
+
info: "#0284C7",
|
|
7154
|
+
infoHover: "#0369A1"
|
|
7155
|
+
},
|
|
7156
|
+
{
|
|
7157
|
+
base: "#C2410C",
|
|
7158
|
+
hover: "#9A3412",
|
|
7159
|
+
info: "#0369A1",
|
|
7160
|
+
infoHover: "#075985"
|
|
7161
|
+
},
|
|
7162
|
+
{
|
|
7163
|
+
base: "#EF4444",
|
|
7164
|
+
hover: "#DC2626",
|
|
7165
|
+
info: "#0EA5E9",
|
|
7166
|
+
infoHover: "#0284C7"
|
|
7167
|
+
},
|
|
7168
|
+
{
|
|
7169
|
+
base: "#F87171",
|
|
7170
|
+
hover: "#EF4444",
|
|
7171
|
+
info: "#38BDF8",
|
|
7172
|
+
infoHover: "#0EA5E9"
|
|
7173
|
+
},
|
|
7174
|
+
{
|
|
7175
|
+
base: "#DC2626",
|
|
7176
|
+
hover: "#B91C1C",
|
|
7177
|
+
info: "#0284C7",
|
|
7178
|
+
infoHover: "#0369A1"
|
|
7179
|
+
},
|
|
7180
|
+
{
|
|
7181
|
+
base: "#B91C1C",
|
|
7182
|
+
hover: "#991B1B",
|
|
7183
|
+
info: "#0369A1",
|
|
7184
|
+
infoHover: "#075985"
|
|
7185
|
+
},
|
|
7186
|
+
{
|
|
7187
|
+
base: "#F43F5E",
|
|
7188
|
+
hover: "#E11D48",
|
|
7189
|
+
info: "#0EA5E9",
|
|
7190
|
+
infoHover: "#0284C7"
|
|
7191
|
+
},
|
|
7192
|
+
{
|
|
7193
|
+
base: "#FB7185",
|
|
7194
|
+
hover: "#F43F5E",
|
|
7195
|
+
info: "#38BDF8",
|
|
7196
|
+
infoHover: "#0EA5E9"
|
|
7197
|
+
},
|
|
7198
|
+
{
|
|
7199
|
+
base: "#E11D48",
|
|
7200
|
+
hover: "#BE123C",
|
|
7201
|
+
info: "#0284C7",
|
|
7202
|
+
infoHover: "#0369A1"
|
|
7203
|
+
},
|
|
7204
|
+
{
|
|
7205
|
+
base: "#BE123C",
|
|
7206
|
+
hover: "#9F1239",
|
|
7207
|
+
info: "#0369A1",
|
|
7208
|
+
infoHover: "#075985"
|
|
7209
|
+
},
|
|
7210
|
+
{
|
|
7211
|
+
base: "#EC4899",
|
|
7212
|
+
hover: "#DB2777",
|
|
7213
|
+
info: "#06B6D4",
|
|
7214
|
+
infoHover: "#0891B2"
|
|
7215
|
+
},
|
|
7216
|
+
{
|
|
7217
|
+
base: "#F472B6",
|
|
7218
|
+
hover: "#EC4899",
|
|
7219
|
+
info: "#22D3EE",
|
|
7220
|
+
infoHover: "#06B6D4"
|
|
7221
|
+
},
|
|
7222
|
+
{
|
|
7223
|
+
base: "#DB2777",
|
|
7224
|
+
hover: "#BE185D",
|
|
7225
|
+
info: "#0891B2",
|
|
7226
|
+
infoHover: "#0E7490"
|
|
7227
|
+
},
|
|
7228
|
+
{
|
|
7229
|
+
base: "#BE185D",
|
|
7230
|
+
hover: "#9D174D",
|
|
7231
|
+
info: "#0E7490",
|
|
7232
|
+
infoHover: "#155E75"
|
|
7233
|
+
},
|
|
7234
|
+
{
|
|
7235
|
+
base: "#D946EF",
|
|
7236
|
+
hover: "#C026D3",
|
|
7237
|
+
info: "#F59E0B",
|
|
7238
|
+
infoHover: "#D97706"
|
|
7239
|
+
},
|
|
7240
|
+
{
|
|
7241
|
+
base: "#E879F9",
|
|
7242
|
+
hover: "#D946EF",
|
|
7243
|
+
info: "#FBBF24",
|
|
7244
|
+
infoHover: "#F59E0B"
|
|
7245
|
+
},
|
|
7246
|
+
{
|
|
7247
|
+
base: "#C026D3",
|
|
7248
|
+
hover: "#A21CAF",
|
|
7249
|
+
info: "#D97706",
|
|
7250
|
+
infoHover: "#B45309"
|
|
7251
|
+
},
|
|
7252
|
+
{
|
|
7253
|
+
base: "#A21CAF",
|
|
7254
|
+
hover: "#86198F",
|
|
7255
|
+
info: "#B45309",
|
|
7256
|
+
infoHover: "#92400E"
|
|
7257
|
+
}
|
|
7258
|
+
]
|
|
6717
7259
|
};
|
|
6718
7260
|
|
|
6719
7261
|
// src/components/theme-provider.tsx
|
|
6720
7262
|
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
6721
|
-
var
|
|
6722
|
-
theme: settingConfig_default.theme,
|
|
6723
|
-
fontSize: settingConfig_default.fontSize,
|
|
6724
|
-
fontFamily: settingConfig_default.fontFamily,
|
|
6725
|
-
colors: settingConfig_default.colors
|
|
7263
|
+
var FACTORY_DEFAULTS = {
|
|
7264
|
+
theme: settingConfig_default.defaults.theme,
|
|
7265
|
+
fontSize: settingConfig_default.defaults.fontSize,
|
|
7266
|
+
fontFamily: settingConfig_default.defaults.fontFamily,
|
|
7267
|
+
colors: settingConfig_default.defaults.colors
|
|
6726
7268
|
};
|
|
7269
|
+
function loadJSON(key, fallback) {
|
|
7270
|
+
try {
|
|
7271
|
+
const raw = localStorage.getItem(key);
|
|
7272
|
+
if (raw) return { ...fallback, ...JSON.parse(raw) };
|
|
7273
|
+
} catch {
|
|
7274
|
+
}
|
|
7275
|
+
return fallback;
|
|
7276
|
+
}
|
|
7277
|
+
function saveJSON(key, value) {
|
|
7278
|
+
try {
|
|
7279
|
+
localStorage.setItem(key, JSON.stringify(value));
|
|
7280
|
+
} catch {
|
|
7281
|
+
}
|
|
7282
|
+
}
|
|
6727
7283
|
var initialState = {
|
|
6728
|
-
...
|
|
7284
|
+
...FACTORY_DEFAULTS,
|
|
6729
7285
|
setTheme: () => null,
|
|
6730
7286
|
setColors: () => null,
|
|
6731
7287
|
setFontSize: () => null,
|
|
6732
7288
|
setFontFamily: () => null,
|
|
7289
|
+
saveConfig: () => null,
|
|
6733
7290
|
resetSettings: () => null
|
|
6734
7291
|
};
|
|
6735
7292
|
var ThemeProviderContext = (0, import_react.createContext)(initialState);
|
|
6736
|
-
var COLOR_PALETTE =
|
|
6737
|
-
{ base: "#6366f1", hover: "#4f46e5" },
|
|
6738
|
-
{ base: "#8b5cf6", hover: "#7c3aed" },
|
|
6739
|
-
{ base: "#3b82f6", hover: "#2563eb" },
|
|
6740
|
-
{ base: "#10b981", hover: "#059669" },
|
|
6741
|
-
{ base: "#22c55e", hover: "#16a34a" },
|
|
6742
|
-
{ base: "#eab308", hover: "#ca8a04" },
|
|
6743
|
-
{ base: "#f59e0b", hover: "#d97706" },
|
|
6744
|
-
{ base: "#f97316", hover: "#ea580c" },
|
|
6745
|
-
{ base: "#ef4444", hover: "#dc2626" },
|
|
6746
|
-
{ base: "#ec4899", hover: "#db2777" }
|
|
6747
|
-
];
|
|
7293
|
+
var COLOR_PALETTE = settingConfig_default.colorPalette;
|
|
6748
7294
|
function ThemeProvider({
|
|
6749
7295
|
children,
|
|
6750
7296
|
storageKey = "codego-ui-theme-settings",
|
|
7297
|
+
savedConfigKey = "codego-ui-saved-config",
|
|
6751
7298
|
...props
|
|
6752
7299
|
}) {
|
|
6753
|
-
const [
|
|
6754
|
-
|
|
6755
|
-
|
|
6756
|
-
|
|
6757
|
-
|
|
6758
|
-
|
|
6759
|
-
return configDefaults;
|
|
6760
|
-
});
|
|
7300
|
+
const [savedConfig, setSavedConfig] = (0, import_react.useState)(
|
|
7301
|
+
() => loadJSON(savedConfigKey, FACTORY_DEFAULTS)
|
|
7302
|
+
);
|
|
7303
|
+
const [settings, setSettings] = (0, import_react.useState)(
|
|
7304
|
+
() => loadJSON(storageKey, savedConfig)
|
|
7305
|
+
);
|
|
6761
7306
|
(0, import_react.useEffect)(() => {
|
|
6762
|
-
|
|
7307
|
+
saveJSON(storageKey, settings);
|
|
6763
7308
|
}, [settings, storageKey]);
|
|
6764
7309
|
(0, import_react.useEffect)(() => {
|
|
6765
7310
|
const root = window.document.documentElement;
|
|
@@ -6785,7 +7330,13 @@ function ThemeProvider({
|
|
|
6785
7330
|
setColors: (colors) => setSettings((s) => ({ ...s, colors: { ...s.colors, ...colors } })),
|
|
6786
7331
|
setFontSize: (fontSize) => setSettings((s) => ({ ...s, fontSize })),
|
|
6787
7332
|
setFontFamily: (fontFamily) => setSettings((s) => ({ ...s, fontFamily })),
|
|
6788
|
-
|
|
7333
|
+
// Save current live settings as the new persisted defaults
|
|
7334
|
+
saveConfig: () => {
|
|
7335
|
+
setSavedConfig(settings);
|
|
7336
|
+
saveJSON(savedConfigKey, settings);
|
|
7337
|
+
},
|
|
7338
|
+
// Reset live settings back to saved defaults
|
|
7339
|
+
resetSettings: () => setSettings(savedConfig)
|
|
6789
7340
|
};
|
|
6790
7341
|
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ThemeProviderContext.Provider, { ...props, value, children });
|
|
6791
7342
|
}
|
|
@@ -7676,6 +8227,7 @@ function SectionBlock({
|
|
|
7676
8227
|
}
|
|
7677
8228
|
|
|
7678
8229
|
// src/components/ui/PanelSettings.tsx
|
|
8230
|
+
var React39 = __toESM(require("react"), 1);
|
|
7679
8231
|
var import_lucide_react25 = require("lucide-react");
|
|
7680
8232
|
|
|
7681
8233
|
// src/components/ui/tabs.tsx
|
|
@@ -7762,30 +8314,10 @@ function Tabs({
|
|
|
7762
8314
|
|
|
7763
8315
|
// src/components/ui/PanelSettings.tsx
|
|
7764
8316
|
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
7765
|
-
var
|
|
7766
|
-
|
|
7767
|
-
|
|
7768
|
-
|
|
7769
|
-
{ value: "20px", label: "Extra Large (20px)" }
|
|
7770
|
-
];
|
|
7771
|
-
var FONT_FAMILIES = [
|
|
7772
|
-
{ value: '"Space Grotesk", "Inter", sans-serif', label: "Space Grotesk" },
|
|
7773
|
-
{ value: '"Inter", sans-serif', label: "Inter" },
|
|
7774
|
-
{ value: '"JetBrains Mono", monospace', label: "JetBrains Mono" },
|
|
7775
|
-
{ value: "system-ui, sans-serif", label: "System UI" }
|
|
7776
|
-
];
|
|
7777
|
-
var THEME_OPTIONS = [
|
|
7778
|
-
{ value: "light", label: "Light" },
|
|
7779
|
-
{ value: "dark", label: "Dark" },
|
|
7780
|
-
{ value: "system", label: "System" }
|
|
7781
|
-
];
|
|
7782
|
-
var COLOR_PAIRS = [
|
|
7783
|
-
{ base: "primary", hover: "primaryHover", label: "Primary" },
|
|
7784
|
-
{ base: "secondary", hover: "secondaryHover", label: "Secondary" },
|
|
7785
|
-
{ base: "info", hover: "infoHover", label: "Info" },
|
|
7786
|
-
{ base: "warning", hover: "warningHover", label: "Warning" },
|
|
7787
|
-
{ base: "danger", hover: "dangerHover", label: "Danger" }
|
|
7788
|
-
];
|
|
8317
|
+
var THEME_OPTIONS = settingConfig_default.themeOptions;
|
|
8318
|
+
var FONT_SIZES = settingConfig_default.fontSizes;
|
|
8319
|
+
var FONT_FAMILIES = settingConfig_default.fontFamilies;
|
|
8320
|
+
var COLOR_PAIRS = settingConfig_default.colorPairs;
|
|
7789
8321
|
function SettingRow({ label, description, children }) {
|
|
7790
8322
|
return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex items-start justify-between gap-4 py-3 border-b border-border/60 last:border-0", children: [
|
|
7791
8323
|
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "min-w-0", children: [
|
|
@@ -7833,8 +8365,8 @@ function ColorsPanel({ onColorsChange }) {
|
|
|
7833
8365
|
type: "button",
|
|
7834
8366
|
title: c.base,
|
|
7835
8367
|
onClick: () => {
|
|
7836
|
-
setColors({ primary: c.base, primaryHover: c.hover });
|
|
7837
|
-
onColorsChange?.({ primary: c.base, primaryHover: c.hover });
|
|
8368
|
+
setColors({ primary: c.base, primaryHover: c.hover, info: c.info, infoHover: c.infoHover });
|
|
8369
|
+
onColorsChange?.({ primary: c.base, primaryHover: c.hover, info: c.info, infoHover: c.infoHover });
|
|
7838
8370
|
},
|
|
7839
8371
|
className: cn(
|
|
7840
8372
|
"h-7 w-full rounded-md border border-white/10 transition-transform hover:scale-110 focus:outline-none focus:ring-2 focus:ring-ring",
|
|
@@ -7910,10 +8442,18 @@ function PanelSettings({
|
|
|
7910
8442
|
onColorsChange,
|
|
7911
8443
|
onFontSizeChange,
|
|
7912
8444
|
onFontFamilyChange,
|
|
8445
|
+
onSave,
|
|
7913
8446
|
onReset,
|
|
7914
8447
|
className
|
|
7915
8448
|
}) {
|
|
7916
|
-
const { resetSettings } = useTheme();
|
|
8449
|
+
const { saveConfig, resetSettings } = useTheme();
|
|
8450
|
+
const [saved, setSaved] = React39.useState(false);
|
|
8451
|
+
const handleSave = () => {
|
|
8452
|
+
saveConfig();
|
|
8453
|
+
onSave?.();
|
|
8454
|
+
setSaved(true);
|
|
8455
|
+
setTimeout(() => setSaved(false), 2e3);
|
|
8456
|
+
};
|
|
7917
8457
|
const handleReset = () => {
|
|
7918
8458
|
resetSettings();
|
|
7919
8459
|
onReset?.();
|
|
@@ -7937,10 +8477,16 @@ function PanelSettings({
|
|
|
7937
8477
|
];
|
|
7938
8478
|
return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: cn("flex flex-col gap-4", className), children: [
|
|
7939
8479
|
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Tabs, { items: tabs, defaultValue: defaultTab, variant: "pill" }),
|
|
7940
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.
|
|
7941
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.
|
|
7942
|
-
|
|
7943
|
-
|
|
8480
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex justify-end gap-2 pt-1", children: [
|
|
8481
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(Button, { variant: "outline", size: "sm", onClick: handleReset, children: [
|
|
8482
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_lucide_react25.RotateCcw, { className: "h-3.5 w-3.5 mr-1.5" }),
|
|
8483
|
+
"Reset"
|
|
8484
|
+
] }),
|
|
8485
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(Button, { size: "sm", onClick: handleSave, children: [
|
|
8486
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_lucide_react25.Save, { className: "h-3.5 w-3.5 mr-1.5" }),
|
|
8487
|
+
saved ? "Saved!" : "Save"
|
|
8488
|
+
] })
|
|
8489
|
+
] })
|
|
7944
8490
|
] });
|
|
7945
8491
|
}
|
|
7946
8492
|
|
|
@@ -7960,7 +8506,7 @@ function Skeleton({
|
|
|
7960
8506
|
}
|
|
7961
8507
|
|
|
7962
8508
|
// src/components/ui/slider.tsx
|
|
7963
|
-
var
|
|
8509
|
+
var React40 = __toESM(require("react"), 1);
|
|
7964
8510
|
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
7965
8511
|
function pct(val, min, max) {
|
|
7966
8512
|
return (val - min) / (max - min) * 100;
|
|
@@ -7980,8 +8526,8 @@ function Slider({
|
|
|
7980
8526
|
showValue = false,
|
|
7981
8527
|
className
|
|
7982
8528
|
}) {
|
|
7983
|
-
const [internal, setInternal] =
|
|
7984
|
-
const [hovering, setHovering] =
|
|
8529
|
+
const [internal, setInternal] = React40.useState(defaultValue);
|
|
8530
|
+
const [hovering, setHovering] = React40.useState(false);
|
|
7985
8531
|
const val = controlled ?? internal;
|
|
7986
8532
|
function handleChange(e) {
|
|
7987
8533
|
const v = Number(e.target.value);
|
|
@@ -8058,8 +8604,8 @@ function RangeSlider({
|
|
|
8058
8604
|
showValue = false,
|
|
8059
8605
|
className
|
|
8060
8606
|
}) {
|
|
8061
|
-
const [internal, setInternal] =
|
|
8062
|
-
const [active, setActive] =
|
|
8607
|
+
const [internal, setInternal] = React40.useState(defaultValue);
|
|
8608
|
+
const [active, setActive] = React40.useState(null);
|
|
8063
8609
|
const val = controlled ?? internal;
|
|
8064
8610
|
function handleChange(idx, e) {
|
|
8065
8611
|
const v = Number(e.target.value);
|
|
@@ -8082,7 +8628,7 @@ function RangeSlider({
|
|
|
8082
8628
|
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "absolute w-full h-1.5 rounded-full bg-muted", children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "absolute h-full rounded-full bg-primary", style: { left: `${p0}%`, width: `${p1 - p0}%` } }) }),
|
|
8083
8629
|
[0, 1].map((idx) => {
|
|
8084
8630
|
const p = idx === 0 ? p0 : p1;
|
|
8085
|
-
return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
8631
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(React40.Fragment, { children: [
|
|
8086
8632
|
showTooltip && active === idx && !disabled && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
8087
8633
|
"div",
|
|
8088
8634
|
{
|
|
@@ -8193,7 +8739,7 @@ function StatCard({
|
|
|
8193
8739
|
}
|
|
8194
8740
|
|
|
8195
8741
|
// src/components/ui/stepper.tsx
|
|
8196
|
-
var
|
|
8742
|
+
var React41 = __toESM(require("react"), 1);
|
|
8197
8743
|
var import_lucide_react27 = require("lucide-react");
|
|
8198
8744
|
var import_jsx_runtime52 = require("react/jsx-runtime");
|
|
8199
8745
|
function getStatus(idx, current) {
|
|
@@ -8216,7 +8762,7 @@ function Stepper({
|
|
|
8216
8762
|
clickable = false,
|
|
8217
8763
|
className
|
|
8218
8764
|
}) {
|
|
8219
|
-
const [internal, setInternal] =
|
|
8765
|
+
const [internal, setInternal] = React41.useState(defaultCurrent);
|
|
8220
8766
|
const current = controlled ?? internal;
|
|
8221
8767
|
function go(idx) {
|
|
8222
8768
|
if (!clickable) return;
|
|
@@ -8231,7 +8777,7 @@ function Stepper({
|
|
|
8231
8777
|
), children: steps.map((step, i) => {
|
|
8232
8778
|
const status = getStatus(i, current);
|
|
8233
8779
|
const isLast = i === steps.length - 1;
|
|
8234
|
-
return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
8780
|
+
return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(React41.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: cn(
|
|
8235
8781
|
"flex",
|
|
8236
8782
|
isHorizontal ? "flex-col items-center flex-1" : "flex-row gap-4"
|
|
8237
8783
|
), children: [
|
|
@@ -8275,7 +8821,7 @@ function Stepper({
|
|
|
8275
8821
|
}
|
|
8276
8822
|
|
|
8277
8823
|
// src/components/ui/table.tsx
|
|
8278
|
-
var
|
|
8824
|
+
var React42 = __toESM(require("react"), 1);
|
|
8279
8825
|
var import_lucide_react28 = require("lucide-react");
|
|
8280
8826
|
var import_jsx_runtime53 = require("react/jsx-runtime");
|
|
8281
8827
|
var BADGE_COLORS = {
|
|
@@ -8300,11 +8846,11 @@ function Table({
|
|
|
8300
8846
|
idKey = "id",
|
|
8301
8847
|
className
|
|
8302
8848
|
}) {
|
|
8303
|
-
const [search, setSearch] =
|
|
8304
|
-
const [currentPage, setCurrentPage] =
|
|
8305
|
-
const [selectedIds, setSelectedIds] =
|
|
8306
|
-
const [sortKey, setSortKey] =
|
|
8307
|
-
const [sortDir, setSortDir] =
|
|
8849
|
+
const [search, setSearch] = React42.useState("");
|
|
8850
|
+
const [currentPage, setCurrentPage] = React42.useState(1);
|
|
8851
|
+
const [selectedIds, setSelectedIds] = React42.useState([]);
|
|
8852
|
+
const [sortKey, setSortKey] = React42.useState(null);
|
|
8853
|
+
const [sortDir, setSortDir] = React42.useState(null);
|
|
8308
8854
|
const handleSort = (key) => {
|
|
8309
8855
|
if (sortKey !== key) {
|
|
8310
8856
|
setSortKey(key);
|
|
@@ -8318,7 +8864,7 @@ function Table({
|
|
|
8318
8864
|
setSortKey(null);
|
|
8319
8865
|
setSortDir(null);
|
|
8320
8866
|
};
|
|
8321
|
-
const filteredData =
|
|
8867
|
+
const filteredData = React42.useMemo(() => {
|
|
8322
8868
|
let d = search ? data.filter(
|
|
8323
8869
|
(item) => Object.values(item).some(
|
|
8324
8870
|
(val) => val && typeof val === "string" && val.toLowerCase().includes(search.toLowerCase())
|
|
@@ -8336,18 +8882,18 @@ function Table({
|
|
|
8336
8882
|
}, [data, search, sortKey, sortDir]);
|
|
8337
8883
|
const totalPages = Math.max(1, Math.ceil(filteredData.length / itemsPerPage));
|
|
8338
8884
|
const safePage = Math.min(currentPage, totalPages);
|
|
8339
|
-
const paginatedData =
|
|
8885
|
+
const paginatedData = React42.useMemo(() => {
|
|
8340
8886
|
if (!pagination) return filteredData;
|
|
8341
8887
|
const start = (safePage - 1) * itemsPerPage;
|
|
8342
8888
|
return filteredData.slice(start, start + itemsPerPage);
|
|
8343
8889
|
}, [filteredData, pagination, safePage, itemsPerPage]);
|
|
8344
|
-
|
|
8890
|
+
React42.useEffect(() => {
|
|
8345
8891
|
setCurrentPage(1);
|
|
8346
8892
|
}, [search]);
|
|
8347
8893
|
const handleSelectAll = (checked) => setSelectedIds(checked ? paginatedData.map((item) => String(item[idKey])) : []);
|
|
8348
8894
|
const handleSelect = (id, checked) => setSelectedIds((prev) => checked ? [...prev, id] : prev.filter((i) => i !== id));
|
|
8349
8895
|
const allSelected = paginatedData.length > 0 && selectedIds.length === paginatedData.length;
|
|
8350
|
-
const pagePills =
|
|
8896
|
+
const pagePills = React42.useMemo(() => {
|
|
8351
8897
|
if (totalPages <= 5) return Array.from({ length: totalPages }, (_, i) => i + 1);
|
|
8352
8898
|
if (safePage <= 3) return [1, 2, 3, 4, 5];
|
|
8353
8899
|
if (safePage >= totalPages - 2) return [totalPages - 4, totalPages - 3, totalPages - 2, totalPages - 1, totalPages];
|
|
@@ -8576,7 +9122,7 @@ function Table({
|
|
|
8576
9122
|
}
|
|
8577
9123
|
|
|
8578
9124
|
// src/components/ui/tag-input.tsx
|
|
8579
|
-
var
|
|
9125
|
+
var React43 = __toESM(require("react"), 1);
|
|
8580
9126
|
var import_jsx_runtime54 = require("react/jsx-runtime");
|
|
8581
9127
|
function TagInput({
|
|
8582
9128
|
value: controlled,
|
|
@@ -8588,9 +9134,9 @@ function TagInput({
|
|
|
8588
9134
|
disabled = false,
|
|
8589
9135
|
className
|
|
8590
9136
|
}) {
|
|
8591
|
-
const [internal, setInternal] =
|
|
8592
|
-
const [input, setInput] =
|
|
8593
|
-
const inputRef =
|
|
9137
|
+
const [internal, setInternal] = React43.useState(defaultValue);
|
|
9138
|
+
const [input, setInput] = React43.useState("");
|
|
9139
|
+
const inputRef = React43.useRef(null);
|
|
8594
9140
|
const tags = controlled ?? internal;
|
|
8595
9141
|
function addTag(raw) {
|
|
8596
9142
|
const tag = raw.trim();
|
|
@@ -8695,9 +9241,9 @@ function Timeline({ items, align = "left", className }) {
|
|
|
8695
9241
|
}
|
|
8696
9242
|
|
|
8697
9243
|
// src/components/ui/toggle-switch.tsx
|
|
8698
|
-
var
|
|
9244
|
+
var React44 = __toESM(require("react"), 1);
|
|
8699
9245
|
var import_jsx_runtime56 = require("react/jsx-runtime");
|
|
8700
|
-
var ToggleSwitch =
|
|
9246
|
+
var ToggleSwitch = React44.forwardRef(
|
|
8701
9247
|
({
|
|
8702
9248
|
className,
|
|
8703
9249
|
inline = false,
|
|
@@ -8715,10 +9261,10 @@ var ToggleSwitch = React43.forwardRef(
|
|
|
8715
9261
|
disabled,
|
|
8716
9262
|
...props
|
|
8717
9263
|
}, ref) => {
|
|
8718
|
-
const toggleId = id ??
|
|
9264
|
+
const toggleId = id ?? React44.useId();
|
|
8719
9265
|
const trackW = width ? typeof width === "number" ? `${width}px` : width : "2.75rem";
|
|
8720
9266
|
const trackH = height ? typeof height === "number" ? `${height}px` : height : "1.5rem";
|
|
8721
|
-
const [internalChecked, setInternalChecked] =
|
|
9267
|
+
const [internalChecked, setInternalChecked] = React44.useState(defaultChecked ?? false);
|
|
8722
9268
|
const isControlled = checked !== void 0;
|
|
8723
9269
|
const isOn = accepted ? true : declined ? false : isControlled ? checked : internalChecked;
|
|
8724
9270
|
const stateColor = accepted ? acceptedColor ?? "#22c55e" : declined ? declinedColor ?? "#ef4444" : isOn ? void 0 : void 0;
|
|
@@ -8788,7 +9334,7 @@ var ToggleSwitch = React43.forwardRef(
|
|
|
8788
9334
|
ToggleSwitch.displayName = "ToggleSwitch";
|
|
8789
9335
|
|
|
8790
9336
|
// src/components/ui/tree-view.tsx
|
|
8791
|
-
var
|
|
9337
|
+
var React45 = __toESM(require("react"), 1);
|
|
8792
9338
|
var import_lucide_react30 = require("lucide-react");
|
|
8793
9339
|
var import_jsx_runtime57 = require("react/jsx-runtime");
|
|
8794
9340
|
function TreeNodeItem({ node, depth, selected, expanded, onToggleExpand, onSelect, multiple }) {
|
|
@@ -8842,8 +9388,8 @@ function TreeView({
|
|
|
8842
9388
|
className
|
|
8843
9389
|
}) {
|
|
8844
9390
|
const init = defaultSelected ? Array.isArray(defaultSelected) ? defaultSelected : [defaultSelected] : [];
|
|
8845
|
-
const [internal, setInternal] =
|
|
8846
|
-
const [expanded, setExpanded] =
|
|
9391
|
+
const [internal, setInternal] = React45.useState(init);
|
|
9392
|
+
const [expanded, setExpanded] = React45.useState(defaultExpanded);
|
|
8847
9393
|
const selected = controlled ? Array.isArray(controlled) ? controlled : [controlled] : internal;
|
|
8848
9394
|
function handleSelect(id) {
|
|
8849
9395
|
let next;
|
|
@@ -8874,7 +9420,7 @@ function TreeView({
|
|
|
8874
9420
|
}
|
|
8875
9421
|
|
|
8876
9422
|
// src/components/ui/widget.tsx
|
|
8877
|
-
var
|
|
9423
|
+
var React46 = __toESM(require("react"), 1);
|
|
8878
9424
|
var import_jsx_runtime58 = require("react/jsx-runtime");
|
|
8879
9425
|
var iconColorMap = {
|
|
8880
9426
|
primary: "bg-primary/10 text-primary",
|
|
@@ -8903,8 +9449,8 @@ var variantMap = {
|
|
|
8903
9449
|
outline: "bg-transparent border-2"
|
|
8904
9450
|
};
|
|
8905
9451
|
function useCountUp(target, enabled, duration = 1e3) {
|
|
8906
|
-
const [display, setDisplay] =
|
|
8907
|
-
|
|
9452
|
+
const [display, setDisplay] = React46.useState(enabled ? 0 : target);
|
|
9453
|
+
React46.useEffect(() => {
|
|
8908
9454
|
if (!enabled) {
|
|
8909
9455
|
setDisplay(target);
|
|
8910
9456
|
return;
|
|
@@ -9017,7 +9563,7 @@ function Widget({
|
|
|
9017
9563
|
}
|
|
9018
9564
|
|
|
9019
9565
|
// src/components/ui/wizard.tsx
|
|
9020
|
-
var
|
|
9566
|
+
var React47 = __toESM(require("react"), 1);
|
|
9021
9567
|
var import_lucide_react31 = require("lucide-react");
|
|
9022
9568
|
var import_jsx_runtime59 = require("react/jsx-runtime");
|
|
9023
9569
|
var SIZE_MAP = {
|
|
@@ -9041,7 +9587,7 @@ function HeaderDefault({
|
|
|
9041
9587
|
return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "flex items-start w-full", children: steps.map((step, i) => {
|
|
9042
9588
|
const status = stepStatus(i, current);
|
|
9043
9589
|
const isLast = i === steps.length - 1;
|
|
9044
|
-
return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
|
|
9590
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(React47.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "flex flex-col items-center flex-1 min-w-0", children: [
|
|
9045
9591
|
/* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "flex items-center w-full", children: [
|
|
9046
9592
|
i > 0 && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: cn("flex-1 h-0.5 transition-colors", i <= current ? "bg-primary" : "bg-border") }),
|
|
9047
9593
|
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
|
|
@@ -9269,7 +9815,7 @@ function WizardPanel({
|
|
|
9269
9815
|
const isFirst = current === 0;
|
|
9270
9816
|
const isLast = current === steps.length - 1;
|
|
9271
9817
|
const isSidebar = variant === "sidebar";
|
|
9272
|
-
const [validationError, setValidationError] =
|
|
9818
|
+
const [validationError, setValidationError] = React47.useState(null);
|
|
9273
9819
|
const handleNext = () => {
|
|
9274
9820
|
const validate = steps[current]?.validate;
|
|
9275
9821
|
if (validate) {
|
|
@@ -9373,7 +9919,7 @@ function Wizard({
|
|
|
9373
9919
|
className,
|
|
9374
9920
|
contentClassName
|
|
9375
9921
|
}) {
|
|
9376
|
-
const [internalStep, setInternalStep] =
|
|
9922
|
+
const [internalStep, setInternalStep] = React47.useState(defaultStep);
|
|
9377
9923
|
const current = controlledStep ?? internalStep;
|
|
9378
9924
|
const go = (idx) => {
|
|
9379
9925
|
const clamped = Math.max(0, Math.min(steps.length - 1, idx));
|
|
@@ -9388,7 +9934,7 @@ function Wizard({
|
|
|
9388
9934
|
}
|
|
9389
9935
|
go(current + 1);
|
|
9390
9936
|
};
|
|
9391
|
-
|
|
9937
|
+
React47.useEffect(() => {
|
|
9392
9938
|
if (layout !== "modal" || !isOpen || unchange) return;
|
|
9393
9939
|
const handler = (e) => {
|
|
9394
9940
|
if (e.key === "Escape") onClose?.();
|