@ultrst-armada/floks 0.0.0-stage → 1.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 +2 -3
- package/index.d.ts +2 -0
- package/index.js +2 -0
- package/package.json +67 -4
- package/packages/canvas-ui/dist/canvas/index.d.ts +54 -0
- package/packages/canvas-ui/dist/canvas/index.js +12 -0
- package/packages/canvas-ui/dist/chunk-2GLR35UM.js +391 -0
- package/packages/canvas-ui/dist/chunk-34YRDZPJ.js +189 -0
- package/packages/canvas-ui/dist/chunk-6VB74RCH.js +147 -0
- package/packages/canvas-ui/dist/chunk-QTTWWBNN.js +114 -0
- package/packages/canvas-ui/dist/chunk-QWQ4PCXQ.js +718 -0
- package/packages/canvas-ui/dist/chunk-SA3JADUG.js +160 -0
- package/packages/canvas-ui/dist/chunk-UEIMM6PV.js +508 -0
- package/packages/canvas-ui/dist/dock/index.d.ts +37 -0
- package/packages/canvas-ui/dist/dock/index.js +10 -0
- package/packages/canvas-ui/dist/editor/index.d.ts +44 -0
- package/packages/canvas-ui/dist/editor/index.js +10 -0
- package/packages/canvas-ui/dist/graph-2d/index.d.ts +270 -0
- package/packages/canvas-ui/dist/graph-2d/index.js +50 -0
- package/packages/canvas-ui/dist/index.d.ts +176 -0
- package/packages/canvas-ui/dist/index.js +1171 -0
- package/packages/canvas-ui/dist/predictive/index.d.ts +74 -0
- package/packages/canvas-ui/dist/predictive/index.js +13 -0
- package/packages/canvas-ui/dist/tile-menu/index.d.ts +45 -0
- package/packages/canvas-ui/dist/tile-menu/index.js +12 -0
- package/packages/canvas-ui/dist/types-D3RRfQUo.d.ts +46 -0
- package/packages/canvas-ui/floks.manifest.json +35 -0
- package/packages/canvas-ui/package.json +82 -0
- package/packages/ui/dist/BottomStrip-DYhAUQR4.d.ts +12 -0
- package/packages/ui/dist/chunk-5ZMXFCD4.js +0 -0
- package/packages/ui/dist/chunk-62ITRDJX.js +141 -0
- package/packages/ui/dist/chunk-A2CDQISJ.js +32 -0
- package/packages/ui/dist/chunk-C32CB5WO.js +1161 -0
- package/packages/ui/dist/chunk-C3L53YN4.js +372 -0
- package/packages/ui/dist/chunk-DABYTYOU.js +351 -0
- package/packages/ui/dist/chunk-DZJ3NSCX.js +665 -0
- package/packages/ui/dist/chunk-ELZOBTWX.js +562 -0
- package/packages/ui/dist/chunk-GKP6KHTI.js +75 -0
- package/packages/ui/dist/chunk-GWW3BGOB.js +238 -0
- package/packages/ui/dist/chunk-KIFQA7L6.js +167 -0
- package/packages/ui/dist/chunk-OHISLM3Z.js +703 -0
- package/packages/ui/dist/chunk-OR5ZNJI4.js +62 -0
- package/packages/ui/dist/chunk-QWXEW7WH.js +238 -0
- package/packages/ui/dist/chunk-RLQ2ALJG.js +182 -0
- package/packages/ui/dist/chunk-S227WJ5E.js +152 -0
- package/packages/ui/dist/chunk-SLJBDDSN.js +0 -0
- package/packages/ui/dist/chunk-TXKLROFC.js +370 -0
- package/packages/ui/dist/chunk-UOR4P6PO.js +32 -0
- package/packages/ui/dist/chunk-W42SJGOJ.js +19 -0
- package/packages/ui/dist/chunk-XXIH2HWI.js +297 -0
- package/packages/ui/dist/chunk-ZQK5I5ZL.js +277 -0
- package/packages/ui/dist/components/auth/index.css +183 -0
- package/packages/ui/dist/components/auth/index.d.ts +10 -0
- package/packages/ui/dist/components/auth/index.js +8 -0
- package/packages/ui/dist/components/base/index.css +183 -0
- package/packages/ui/dist/components/base/index.d.ts +74 -0
- package/packages/ui/dist/components/base/index.js +33 -0
- package/packages/ui/dist/components/bottom-strip/index.css +183 -0
- package/packages/ui/dist/components/bottom-strip/index.d.ts +67 -0
- package/packages/ui/dist/components/bottom-strip/index.js +22 -0
- package/packages/ui/dist/components/composite/index.css +273 -0
- package/packages/ui/dist/components/composite/index.d.ts +104 -0
- package/packages/ui/dist/components/composite/index.js +33 -0
- package/packages/ui/dist/components/containers/index.css +404 -0
- package/packages/ui/dist/components/containers/index.d.ts +93 -0
- package/packages/ui/dist/components/containers/index.js +35 -0
- package/packages/ui/dist/components/layout/index.css +246 -0
- package/packages/ui/dist/components/layout/index.d.ts +53 -0
- package/packages/ui/dist/components/layout/index.js +16 -0
- package/packages/ui/dist/components/settings/index.css +183 -0
- package/packages/ui/dist/components/settings/index.d.ts +14 -0
- package/packages/ui/dist/components/settings/index.js +12 -0
- package/packages/ui/dist/components/workspace/index.d.ts +101 -0
- package/packages/ui/dist/components/workspace/index.js +16 -0
- package/packages/ui/dist/hierarchy/index.css +183 -0
- package/packages/ui/dist/hierarchy/index.d.ts +168 -0
- package/packages/ui/dist/hierarchy/index.js +36 -0
- package/packages/ui/dist/index.css +467 -0
- package/packages/ui/dist/index.d.ts +16 -0
- package/packages/ui/dist/index.js +282 -0
- package/packages/ui/dist/palette/index.d.ts +29 -0
- package/packages/ui/dist/palette/index.js +27 -0
- package/packages/ui/dist/palettes-De5u5iID.d.ts +394 -0
- package/packages/ui/dist/theme/index.d.ts +12063 -0
- package/packages/ui/dist/theme/index.js +96 -0
- package/packages/ui/floks.manifest.json +119 -0
- package/packages/ui/package.json +92 -0
- package/packages/ui/src/styles/base.css +130 -0
- package/packages/ui/src/styles/composite.css +6 -0
- package/packages/ui/src/styles/containers.css +10 -0
- package/packages/ui/src/styles/details-panel.css +147 -0
- package/packages/ui/src/styles/layout.css +58 -0
- package/packages/ui/src/theme/tokens.css +93 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
// src/canvas/CanvasViewport.tsx
|
|
2
|
+
import { useRef, useState } from "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
function CanvasViewport({
|
|
5
|
+
children,
|
|
6
|
+
transform,
|
|
7
|
+
onChange,
|
|
8
|
+
minZoom = 0.1,
|
|
9
|
+
maxZoom = 5
|
|
10
|
+
}) {
|
|
11
|
+
const containerRef = useRef(null);
|
|
12
|
+
const [isPanning, setIsPanning] = useState(false);
|
|
13
|
+
const handleWheel = (e) => {
|
|
14
|
+
e.preventDefault();
|
|
15
|
+
if (!containerRef.current) return;
|
|
16
|
+
const zoomDelta = e.deltaY * -1e-3;
|
|
17
|
+
let newScale = transform.scale + zoomDelta;
|
|
18
|
+
newScale = Math.max(minZoom, Math.min(maxZoom, newScale));
|
|
19
|
+
const rect = containerRef.current.getBoundingClientRect();
|
|
20
|
+
const mouseX = e.clientX - rect.left;
|
|
21
|
+
const mouseY = e.clientY - rect.top;
|
|
22
|
+
const graphX = (mouseX - transform.x) / transform.scale;
|
|
23
|
+
const graphY = (mouseY - transform.y) / transform.scale;
|
|
24
|
+
const x = mouseX - graphX * newScale;
|
|
25
|
+
const y = mouseY - graphY * newScale;
|
|
26
|
+
onChange({ x, y, scale: newScale });
|
|
27
|
+
};
|
|
28
|
+
const handleMouseDown = (e) => {
|
|
29
|
+
if (e.button === 1 || e.button === 0 && (e.altKey || e.metaKey)) {
|
|
30
|
+
setIsPanning(true);
|
|
31
|
+
e.preventDefault();
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const handleMouseMove = (e) => {
|
|
35
|
+
if (isPanning) {
|
|
36
|
+
onChange({
|
|
37
|
+
...transform,
|
|
38
|
+
x: transform.x + e.movementX,
|
|
39
|
+
y: transform.y + e.movementY
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
const handleMouseUp = () => {
|
|
44
|
+
setIsPanning(false);
|
|
45
|
+
};
|
|
46
|
+
return /* @__PURE__ */ jsx(
|
|
47
|
+
"div",
|
|
48
|
+
{
|
|
49
|
+
ref: containerRef,
|
|
50
|
+
style: { width: "100%", height: "100%", overflow: "hidden", position: "relative" },
|
|
51
|
+
onWheel: handleWheel,
|
|
52
|
+
onMouseDown: handleMouseDown,
|
|
53
|
+
onMouseMove: handleMouseMove,
|
|
54
|
+
onMouseUp: handleMouseUp,
|
|
55
|
+
onMouseLeave: handleMouseUp,
|
|
56
|
+
children: /* @__PURE__ */ jsx("div", { style: {
|
|
57
|
+
position: "absolute",
|
|
58
|
+
top: 0,
|
|
59
|
+
left: 0,
|
|
60
|
+
transformOrigin: "0 0",
|
|
61
|
+
transform: `translate(${transform.x}px, ${transform.y}px) scale(${transform.scale})`,
|
|
62
|
+
willChange: "transform"
|
|
63
|
+
}, children })
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// src/canvas/MiniMap.tsx
|
|
69
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
70
|
+
function MiniMap({ items, transform, width = 150, height = 100 }) {
|
|
71
|
+
let minX = 0, minY = 0, maxX = 1e3, maxY = 1e3;
|
|
72
|
+
if (items.length > 0) {
|
|
73
|
+
minX = Math.min(...items.map((i) => i.x));
|
|
74
|
+
minY = Math.min(...items.map((i) => i.y));
|
|
75
|
+
maxX = Math.max(...items.map((i) => i.x + (i.width || 100)));
|
|
76
|
+
maxY = Math.max(...items.map((i) => i.y + (i.height || 100)));
|
|
77
|
+
}
|
|
78
|
+
minX -= 200;
|
|
79
|
+
minY -= 200;
|
|
80
|
+
maxX += 200;
|
|
81
|
+
maxY += 200;
|
|
82
|
+
const contentWidth = maxX - minX;
|
|
83
|
+
const contentHeight = maxY - minY;
|
|
84
|
+
const scaleX = width / contentWidth;
|
|
85
|
+
const scaleY = height / contentHeight;
|
|
86
|
+
const scale = Math.min(scaleX, scaleY);
|
|
87
|
+
const offsetX = (width - contentWidth * scale) / 2 - minX * scale;
|
|
88
|
+
const offsetY = (height - contentHeight * scale) / 2 - minY * scale;
|
|
89
|
+
return /* @__PURE__ */ jsxs("div", { style: {
|
|
90
|
+
width,
|
|
91
|
+
height,
|
|
92
|
+
backgroundColor: "rgba(0,0,0,0.5)",
|
|
93
|
+
border: "1px solid rgba(255,255,255,0.2)",
|
|
94
|
+
borderRadius: "8px",
|
|
95
|
+
position: "relative",
|
|
96
|
+
overflow: "hidden"
|
|
97
|
+
}, children: [
|
|
98
|
+
items.map((item) => /* @__PURE__ */ jsx2(
|
|
99
|
+
"div",
|
|
100
|
+
{
|
|
101
|
+
style: {
|
|
102
|
+
position: "absolute",
|
|
103
|
+
left: item.x * scale + offsetX,
|
|
104
|
+
top: item.y * scale + offsetY,
|
|
105
|
+
width: (item.width || 100) * scale,
|
|
106
|
+
height: (item.height || 100) * scale,
|
|
107
|
+
backgroundColor: "rgba(97, 175, 239, 0.5)",
|
|
108
|
+
borderRadius: "2px"
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
item.id
|
|
112
|
+
)),
|
|
113
|
+
/* @__PURE__ */ jsx2("div", { style: {
|
|
114
|
+
position: "absolute",
|
|
115
|
+
left: -transform.x / transform.scale * scale + offsetX,
|
|
116
|
+
top: -transform.y / transform.scale * scale + offsetY,
|
|
117
|
+
width: 1e3 / transform.scale * scale,
|
|
118
|
+
// Approximation of viewport width
|
|
119
|
+
height: 800 / transform.scale * scale,
|
|
120
|
+
border: "1px solid #d4af37",
|
|
121
|
+
backgroundColor: "rgba(212, 175, 55, 0.1)"
|
|
122
|
+
} })
|
|
123
|
+
] });
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// src/canvas/InfiniteCanvas.tsx
|
|
127
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
128
|
+
function InfiniteCanvas({
|
|
129
|
+
items,
|
|
130
|
+
transform,
|
|
131
|
+
onTransformChange,
|
|
132
|
+
showGrid = true,
|
|
133
|
+
showMiniMap = true,
|
|
134
|
+
gridSize = 40
|
|
135
|
+
}) {
|
|
136
|
+
const gridBackground = showGrid ? {
|
|
137
|
+
backgroundImage: `
|
|
138
|
+
linear-gradient(to right, rgba(255,255,255,0.05) 1px, transparent 1px),
|
|
139
|
+
linear-gradient(to bottom, rgba(255,255,255,0.05) 1px, transparent 1px)
|
|
140
|
+
`,
|
|
141
|
+
backgroundSize: `${gridSize * transform.scale}px ${gridSize * transform.scale}px`,
|
|
142
|
+
backgroundPosition: `${transform.x}px ${transform.y}px`
|
|
143
|
+
} : {};
|
|
144
|
+
return /* @__PURE__ */ jsxs2("div", { style: { width: "100%", height: "100%", position: "relative", backgroundColor: "#16161a", ...gridBackground }, children: [
|
|
145
|
+
/* @__PURE__ */ jsx3(CanvasViewport, { transform, onChange: onTransformChange, children: items.map((item) => /* @__PURE__ */ jsx3(
|
|
146
|
+
"div",
|
|
147
|
+
{
|
|
148
|
+
style: {
|
|
149
|
+
position: "absolute",
|
|
150
|
+
left: item.x,
|
|
151
|
+
top: item.y,
|
|
152
|
+
width: item.width,
|
|
153
|
+
height: item.height
|
|
154
|
+
},
|
|
155
|
+
children: item.content
|
|
156
|
+
},
|
|
157
|
+
item.id
|
|
158
|
+
)) }),
|
|
159
|
+
showMiniMap && /* @__PURE__ */ jsx3("div", { style: { position: "absolute", bottom: 16, right: 16, zIndex: 100 }, children: /* @__PURE__ */ jsx3(MiniMap, { items, transform }) })
|
|
160
|
+
] });
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// src/canvas/useCanvas.ts
|
|
164
|
+
import { useState as useState2, useCallback } from "react";
|
|
165
|
+
function useCanvas(initialTransform = { x: 0, y: 0, scale: 1 }) {
|
|
166
|
+
const [transform, setTransform] = useState2(initialTransform);
|
|
167
|
+
const [items, setItems] = useState2([]);
|
|
168
|
+
const addItem = useCallback((item) => {
|
|
169
|
+
setItems((prev) => [...prev, item]);
|
|
170
|
+
}, []);
|
|
171
|
+
const updateItemPosition = useCallback((id, x, y) => {
|
|
172
|
+
setItems((prev) => prev.map((item) => item.id === id ? { ...item, x, y } : item));
|
|
173
|
+
}, []);
|
|
174
|
+
return {
|
|
175
|
+
transform,
|
|
176
|
+
setTransform,
|
|
177
|
+
items,
|
|
178
|
+
setItems,
|
|
179
|
+
addItem,
|
|
180
|
+
updateItemPosition
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export {
|
|
185
|
+
CanvasViewport,
|
|
186
|
+
MiniMap,
|
|
187
|
+
InfiniteCanvas,
|
|
188
|
+
useCanvas
|
|
189
|
+
};
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
// src/dock/DockItem.tsx
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
function DockItem({ item, isActive, onClick }) {
|
|
4
|
+
return /* @__PURE__ */ jsxs(
|
|
5
|
+
"div",
|
|
6
|
+
{
|
|
7
|
+
style: {
|
|
8
|
+
position: "relative",
|
|
9
|
+
display: "flex",
|
|
10
|
+
justifyContent: "center",
|
|
11
|
+
alignItems: "center",
|
|
12
|
+
width: "48px",
|
|
13
|
+
height: "48px",
|
|
14
|
+
borderRadius: "12px",
|
|
15
|
+
cursor: "pointer",
|
|
16
|
+
backgroundColor: isActive ? "rgba(255, 255, 255, 0.15)" : "transparent",
|
|
17
|
+
transition: "background-color 0.2s, transform 0.1s",
|
|
18
|
+
color: "#fff"
|
|
19
|
+
},
|
|
20
|
+
onClick: () => {
|
|
21
|
+
onClick?.();
|
|
22
|
+
item.onClick?.();
|
|
23
|
+
},
|
|
24
|
+
onMouseEnter: (e) => {
|
|
25
|
+
e.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.2)";
|
|
26
|
+
e.currentTarget.style.transform = "scale(1.05)";
|
|
27
|
+
},
|
|
28
|
+
onMouseLeave: (e) => {
|
|
29
|
+
e.currentTarget.style.backgroundColor = isActive ? "rgba(255, 255, 255, 0.15)" : "transparent";
|
|
30
|
+
e.currentTarget.style.transform = "scale(1)";
|
|
31
|
+
},
|
|
32
|
+
title: item.label,
|
|
33
|
+
children: [
|
|
34
|
+
/* @__PURE__ */ jsx("div", { style: { fontSize: "24px" }, children: item.icon }),
|
|
35
|
+
item.badge && /* @__PURE__ */ jsx("div", { style: {
|
|
36
|
+
position: "absolute",
|
|
37
|
+
top: "0",
|
|
38
|
+
right: "0",
|
|
39
|
+
backgroundColor: "#ff4d4f",
|
|
40
|
+
color: "white",
|
|
41
|
+
fontSize: "10px",
|
|
42
|
+
fontWeight: "bold",
|
|
43
|
+
padding: "2px 6px",
|
|
44
|
+
borderRadius: "10px",
|
|
45
|
+
transform: "translate(25%, -25%)",
|
|
46
|
+
border: "2px solid #1e1e1e"
|
|
47
|
+
}, children: item.badge }),
|
|
48
|
+
isActive && /* @__PURE__ */ jsx("div", { style: {
|
|
49
|
+
position: "absolute",
|
|
50
|
+
bottom: "-6px",
|
|
51
|
+
width: "6px",
|
|
52
|
+
height: "6px",
|
|
53
|
+
borderRadius: "50%",
|
|
54
|
+
backgroundColor: "#d4af37"
|
|
55
|
+
} })
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// src/dock/DockBar.tsx
|
|
62
|
+
import { useState } from "react";
|
|
63
|
+
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
64
|
+
function DockBar({ items, position = "bottom", activeId, onItemClick, autoHide = false }) {
|
|
65
|
+
const [isHovered, setIsHovered] = useState(false);
|
|
66
|
+
const isVertical = position === "left" || position === "right";
|
|
67
|
+
const positionStyles = {
|
|
68
|
+
position: "fixed",
|
|
69
|
+
...position === "bottom" ? { bottom: "16px", left: "50%", transform: "translateX(-50%)" } : {},
|
|
70
|
+
...position === "top" ? { top: "16px", left: "50%", transform: "translateX(-50%)" } : {},
|
|
71
|
+
...position === "left" ? { left: "16px", top: "50%", transform: "translateY(-50%)" } : {},
|
|
72
|
+
...position === "right" ? { right: "16px", top: "50%", transform: "translateY(-50%)" } : {}
|
|
73
|
+
};
|
|
74
|
+
const hiddenTransform = position === "bottom" ? "translate(-50%, 150%)" : position === "top" ? "translate(-50%, -150%)" : position === "left" ? "translate(-150%, -50%)" : "translate(150%, -50%)";
|
|
75
|
+
const baseTransform = position === "bottom" || position === "top" ? "translateX(-50%)" : "translateY(-50%)";
|
|
76
|
+
const containerStyle = {
|
|
77
|
+
...positionStyles,
|
|
78
|
+
display: "flex",
|
|
79
|
+
flexDirection: isVertical ? "column" : "row",
|
|
80
|
+
gap: "8px",
|
|
81
|
+
padding: "8px",
|
|
82
|
+
backgroundColor: "rgba(25, 25, 25, 0.7)",
|
|
83
|
+
backdropFilter: "blur(16px)",
|
|
84
|
+
border: "1px solid rgba(212, 175, 55, 0.3)",
|
|
85
|
+
borderRadius: "16px",
|
|
86
|
+
boxShadow: "0 8px 32px rgba(0, 0, 0, 0.3)",
|
|
87
|
+
zIndex: 9999,
|
|
88
|
+
transition: "transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)",
|
|
89
|
+
transform: autoHide && !isHovered ? hiddenTransform : baseTransform
|
|
90
|
+
};
|
|
91
|
+
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
92
|
+
autoHide && /* @__PURE__ */ jsx2(
|
|
93
|
+
"div",
|
|
94
|
+
{
|
|
95
|
+
style: {
|
|
96
|
+
position: "fixed",
|
|
97
|
+
...position === "bottom" ? { bottom: 0, left: 0, right: 0, height: "24px" } : {},
|
|
98
|
+
...position === "top" ? { top: 0, left: 0, right: 0, height: "24px" } : {},
|
|
99
|
+
...position === "left" ? { left: 0, top: 0, bottom: 0, width: "24px" } : {},
|
|
100
|
+
...position === "right" ? { right: 0, top: 0, bottom: 0, width: "24px" } : {},
|
|
101
|
+
zIndex: 9998
|
|
102
|
+
},
|
|
103
|
+
onMouseEnter: () => setIsHovered(true)
|
|
104
|
+
}
|
|
105
|
+
),
|
|
106
|
+
/* @__PURE__ */ jsx2(
|
|
107
|
+
"div",
|
|
108
|
+
{
|
|
109
|
+
style: containerStyle,
|
|
110
|
+
onMouseEnter: () => setIsHovered(true),
|
|
111
|
+
onMouseLeave: () => setIsHovered(false),
|
|
112
|
+
children: items.map((item) => /* @__PURE__ */ jsx2(
|
|
113
|
+
DockItem,
|
|
114
|
+
{
|
|
115
|
+
item,
|
|
116
|
+
isActive: activeId === item.id,
|
|
117
|
+
onClick: () => onItemClick?.(item.id)
|
|
118
|
+
},
|
|
119
|
+
item.id
|
|
120
|
+
))
|
|
121
|
+
}
|
|
122
|
+
)
|
|
123
|
+
] });
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// src/dock/useDock.ts
|
|
127
|
+
import { useState as useState2, useCallback } from "react";
|
|
128
|
+
function useDock(initialItems = []) {
|
|
129
|
+
const [items, setItems] = useState2(initialItems);
|
|
130
|
+
const [activeId, setActiveId] = useState2();
|
|
131
|
+
const updateBadge = useCallback((id, badge) => {
|
|
132
|
+
setItems((prev) => prev.map((item) => item.id === id ? { ...item, badge } : item));
|
|
133
|
+
}, []);
|
|
134
|
+
return {
|
|
135
|
+
items,
|
|
136
|
+
activeId,
|
|
137
|
+
setActiveId,
|
|
138
|
+
updateBadge,
|
|
139
|
+
setItems
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export {
|
|
144
|
+
DockItem,
|
|
145
|
+
DockBar,
|
|
146
|
+
useDock
|
|
147
|
+
};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// src/editor/themes.ts
|
|
2
|
+
var skipoDarkTheme = {
|
|
3
|
+
base: "vs-dark",
|
|
4
|
+
inherit: true,
|
|
5
|
+
rules: [
|
|
6
|
+
{ token: "keyword", foreground: "d4af37" },
|
|
7
|
+
// Gold
|
|
8
|
+
{ token: "string", foreground: "98c379" },
|
|
9
|
+
// Olive
|
|
10
|
+
{ token: "number", foreground: "d19a66" },
|
|
11
|
+
// Orange
|
|
12
|
+
{ token: "comment", foreground: "5c6370", fontStyle: "italic" },
|
|
13
|
+
{ token: "type", foreground: "56b6c2" }
|
|
14
|
+
// Cyan
|
|
15
|
+
],
|
|
16
|
+
colors: {
|
|
17
|
+
"editor.background": "#16161e",
|
|
18
|
+
"editor.foreground": "#a9b1d6",
|
|
19
|
+
"editorLineNumber.foreground": "#363b54",
|
|
20
|
+
"editor.selectionBackground": "#28324a",
|
|
21
|
+
"editor.lineHighlightBackground": "#1c1c26",
|
|
22
|
+
"editorCursor.foreground": "#d4af37",
|
|
23
|
+
"editorIndentGuide.background": "#222222"
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// src/editor/useMonaco.ts
|
|
28
|
+
import { useEffect, useState } from "react";
|
|
29
|
+
function useMonaco() {
|
|
30
|
+
const [monaco, setMonaco] = useState(null);
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
let isMounted = true;
|
|
33
|
+
const monacoPkg = "monaco-editor";
|
|
34
|
+
import(
|
|
35
|
+
/* @vite-ignore */
|
|
36
|
+
monacoPkg
|
|
37
|
+
).then((monacoModule) => {
|
|
38
|
+
if (!isMounted) return;
|
|
39
|
+
monacoModule.editor.defineTheme("skipo-dark", skipoDarkTheme);
|
|
40
|
+
setMonaco(monacoModule);
|
|
41
|
+
}).catch((err) => {
|
|
42
|
+
console.warn("Failed to load monaco-editor", err);
|
|
43
|
+
});
|
|
44
|
+
return () => {
|
|
45
|
+
isMounted = false;
|
|
46
|
+
};
|
|
47
|
+
}, []);
|
|
48
|
+
return monaco;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// src/editor/MonacoEditor.tsx
|
|
52
|
+
import { useEffect as useEffect2, useRef } from "react";
|
|
53
|
+
import { jsx } from "react/jsx-runtime";
|
|
54
|
+
function MonacoEditor({
|
|
55
|
+
value,
|
|
56
|
+
language = "javascript",
|
|
57
|
+
readOnly = false,
|
|
58
|
+
minimap = false,
|
|
59
|
+
theme = "skipo-dark",
|
|
60
|
+
fontSize = 14,
|
|
61
|
+
onChange,
|
|
62
|
+
height = "100%",
|
|
63
|
+
width = "100%"
|
|
64
|
+
}) {
|
|
65
|
+
const containerRef = useRef(null);
|
|
66
|
+
const editorRef = useRef(null);
|
|
67
|
+
const monaco = useMonaco();
|
|
68
|
+
useEffect2(() => {
|
|
69
|
+
if (!monaco || !containerRef.current) return;
|
|
70
|
+
if (!editorRef.current) {
|
|
71
|
+
editorRef.current = monaco.editor.create(containerRef.current, {
|
|
72
|
+
value,
|
|
73
|
+
language,
|
|
74
|
+
theme,
|
|
75
|
+
readOnly,
|
|
76
|
+
fontSize,
|
|
77
|
+
minimap: { enabled: minimap },
|
|
78
|
+
automaticLayout: true,
|
|
79
|
+
scrollBeyondLastLine: false,
|
|
80
|
+
padding: { top: 16, bottom: 16 }
|
|
81
|
+
});
|
|
82
|
+
if (onChange) {
|
|
83
|
+
editorRef.current.onDidChangeModelContent(() => {
|
|
84
|
+
onChange(editorRef.current.getValue());
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return () => {
|
|
89
|
+
if (editorRef.current) {
|
|
90
|
+
editorRef.current.dispose();
|
|
91
|
+
editorRef.current = null;
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}, [monaco]);
|
|
95
|
+
useEffect2(() => {
|
|
96
|
+
if (editorRef.current && value !== editorRef.current.getValue()) {
|
|
97
|
+
editorRef.current.setValue(value);
|
|
98
|
+
}
|
|
99
|
+
}, [value]);
|
|
100
|
+
useEffect2(() => {
|
|
101
|
+
if (editorRef.current) {
|
|
102
|
+
monaco?.editor.setModelLanguage(editorRef.current.getModel(), language);
|
|
103
|
+
editorRef.current.updateOptions({ readOnly, fontSize, minimap: { enabled: minimap } });
|
|
104
|
+
if (theme) monaco?.editor.setTheme(theme);
|
|
105
|
+
}
|
|
106
|
+
}, [language, readOnly, fontSize, minimap, theme, monaco]);
|
|
107
|
+
return /* @__PURE__ */ jsx("div", { ref: containerRef, style: { width, height, overflow: "hidden", borderRadius: "8px" } });
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export {
|
|
111
|
+
skipoDarkTheme,
|
|
112
|
+
useMonaco,
|
|
113
|
+
MonacoEditor
|
|
114
|
+
};
|