@ultrst-armada/floks 0.0.0-stage → 1.0.1
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 +69 -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-34YRDZPJ.js +189 -0
- package/packages/canvas-ui/dist/chunk-6VB74RCH.js +147 -0
- package/packages/canvas-ui/dist/chunk-OOTTFWXA.js +508 -0
- package/packages/canvas-ui/dist/chunk-QTTWWBNN.js +114 -0
- package/packages/canvas-ui/dist/chunk-SA3JADUG.js +160 -0
- package/packages/canvas-ui/dist/chunk-U2SC3RMJ.js +391 -0
- package/packages/canvas-ui/dist/chunk-XVAHT5WE.js +718 -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 +75 -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-ATQPZLJX.js +238 -0
- package/packages/ui/dist/chunk-C32CB5WO.js +1161 -0
- package/packages/ui/dist/chunk-C3L53YN4.js +372 -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-KYFSUQVT.js +769 -0
- package/packages/ui/dist/chunk-OR5ZNJI4.js +62 -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-VEWPTZGO.js +351 -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 +233 -0
- package/packages/ui/dist/hierarchy/index.js +74 -0
- package/packages/ui/dist/index.css +467 -0
- package/packages/ui/dist/index.d.ts +16 -0
- package/packages/ui/dist/index.js +320 -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
package/README.md
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
|
|
1
|
+
# Floks
|
|
2
|
+
This will be the counterpart Kloks but for the frontend components. This will store the canonical frontend elements that we will use in our Skipo projects.
|
package/index.d.ts
ADDED
package/index.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,71 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ultrst-armada/floks",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"private": false,
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public",
|
|
7
|
+
"registry": "https://registry.npmjs.org/"
|
|
8
|
+
},
|
|
9
|
+
"description": "Floks — Public Frontend, 2D Graph & UI Package Library (@floks/*)",
|
|
10
|
+
"type": "module",
|
|
11
|
+
"main": "./index.js",
|
|
12
|
+
"module": "./index.js",
|
|
13
|
+
"types": "./index.d.ts",
|
|
14
|
+
"files": [
|
|
15
|
+
"index.js",
|
|
16
|
+
"index.d.ts",
|
|
17
|
+
"packages/*/dist/**",
|
|
18
|
+
"packages/*/src/theme/tokens.css",
|
|
19
|
+
"packages/*/src/styles/**",
|
|
20
|
+
"packages/*/package.json",
|
|
21
|
+
"packages/*/floks.manifest.json"
|
|
22
|
+
],
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"types": "./index.d.ts",
|
|
26
|
+
"import": "./index.js",
|
|
27
|
+
"default": "./index.js"
|
|
28
|
+
},
|
|
29
|
+
"./ui": {
|
|
30
|
+
"types": "./packages/ui/dist/index.d.ts",
|
|
31
|
+
"import": "./packages/ui/dist/index.js",
|
|
32
|
+
"default": "./packages/ui/dist/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./ui/theme/tokens.css": "./packages/ui/src/theme/tokens.css",
|
|
35
|
+
"./ui/styles/*": "./packages/ui/src/styles/*",
|
|
36
|
+
"./canvas-ui": {
|
|
37
|
+
"types": "./packages/canvas-ui/dist/index.d.ts",
|
|
38
|
+
"import": "./packages/canvas-ui/dist/index.js",
|
|
39
|
+
"default": "./packages/canvas-ui/dist/index.js"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "pnpm -r run build",
|
|
44
|
+
"postbuild": "node -e \"import('fs').then(fs => { for (const pkg of fs.readdirSync('packages')) { const d = 'packages/' + pkg + '/dist'; if (!fs.existsSync(d)) continue; for (const f of fs.readdirSync(d, { recursive: true })) { const p = d + '/' + f; if (fs.statSync(p).isFile() && (p.endsWith('.js') || p.endsWith('.d.ts'))) { const c = fs.readFileSync(p, 'utf8'); const n = c.replaceAll('@kloks/', '@ultrst-armada/kloks/').replaceAll('@floks/', '@ultrst-armada/floks/').replaceAll('@ultrst/kloks/', '@ultrst-armada/kloks/').replaceAll('@ultrst/floks/', '@ultrst-armada/floks/').replaceAll('\\\"kloks/', '\\\"@ultrst-armada/kloks/').replaceAll('\\'kloks/', '\\'@ultrst-armada/kloks/').replaceAll('\\\"floks/', '\\\"@ultrst-armada/floks/').replaceAll('\\'floks/', '\\'@ultrst-armada/floks/'); if (c !== n) fs.writeFileSync(p, n); } } } })\"",
|
|
45
|
+
"test": "vitest run",
|
|
46
|
+
"typecheck": "pnpm -r run typecheck",
|
|
47
|
+
"clean": "pnpm -r run clean"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"zod": "^3.24.1"
|
|
51
|
+
},
|
|
52
|
+
"peerDependencies": {
|
|
53
|
+
"@ultrst-armada/kloks": "^1.0.2",
|
|
54
|
+
"lucide-react": ">=0.300.0",
|
|
55
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
56
|
+
"react-dom": "^18.0.0 || ^19.0.0"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"@types/node": "^22.0.0",
|
|
60
|
+
"@types/react": "^19.0.0",
|
|
61
|
+
"@types/react-dom": "^19.0.0",
|
|
62
|
+
"@ultrst-armada/kloks": "^1.0.2",
|
|
63
|
+
"lucide-react": "^1.55.0",
|
|
64
|
+
"react": "^19.0.1",
|
|
65
|
+
"react-dom": "^19.0.1",
|
|
66
|
+
"tsup": "^8.4.0",
|
|
67
|
+
"typescript": "^5.7.3",
|
|
68
|
+
"vitest": "^3.1.0"
|
|
69
|
+
},
|
|
70
|
+
"packageManager": "pnpm@9.15.0"
|
|
71
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import React__default from 'react';
|
|
3
|
+
|
|
4
|
+
interface Transform {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
scale: number;
|
|
8
|
+
}
|
|
9
|
+
interface CanvasItem {
|
|
10
|
+
id: string;
|
|
11
|
+
x: number;
|
|
12
|
+
y: number;
|
|
13
|
+
width?: number;
|
|
14
|
+
height?: number;
|
|
15
|
+
content: React.ReactNode;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface CanvasViewportProps {
|
|
19
|
+
children: React__default.ReactNode;
|
|
20
|
+
transform: Transform;
|
|
21
|
+
onChange: (t: Transform) => void;
|
|
22
|
+
minZoom?: number;
|
|
23
|
+
maxZoom?: number;
|
|
24
|
+
}
|
|
25
|
+
declare function CanvasViewport({ children, transform, onChange, minZoom, maxZoom }: CanvasViewportProps): React__default.JSX.Element;
|
|
26
|
+
|
|
27
|
+
interface InfiniteCanvasProps {
|
|
28
|
+
items: CanvasItem[];
|
|
29
|
+
transform: Transform;
|
|
30
|
+
onTransformChange: (t: Transform) => void;
|
|
31
|
+
showGrid?: boolean;
|
|
32
|
+
showMiniMap?: boolean;
|
|
33
|
+
gridSize?: number;
|
|
34
|
+
}
|
|
35
|
+
declare function InfiniteCanvas({ items, transform, onTransformChange, showGrid, showMiniMap, gridSize }: InfiniteCanvasProps): React.JSX.Element;
|
|
36
|
+
|
|
37
|
+
interface MiniMapProps {
|
|
38
|
+
items: CanvasItem[];
|
|
39
|
+
transform: Transform;
|
|
40
|
+
width?: number;
|
|
41
|
+
height?: number;
|
|
42
|
+
}
|
|
43
|
+
declare function MiniMap({ items, transform, width, height }: MiniMapProps): React.JSX.Element;
|
|
44
|
+
|
|
45
|
+
declare function useCanvas(initialTransform?: Transform): {
|
|
46
|
+
transform: Transform;
|
|
47
|
+
setTransform: React.Dispatch<React.SetStateAction<Transform>>;
|
|
48
|
+
items: CanvasItem[];
|
|
49
|
+
setItems: React.Dispatch<React.SetStateAction<CanvasItem[]>>;
|
|
50
|
+
addItem: (item: CanvasItem) => void;
|
|
51
|
+
updateItemPosition: (id: string, x: number, y: number) => void;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export { type CanvasItem, CanvasViewport, InfiniteCanvas, MiniMap, type Transform, useCanvas };
|
|
@@ -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
|
+
};
|