@canmingir/link 1.2.40 → 1.2.42

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canmingir/link",
3
- "version": "1.2.40",
3
+ "version": "1.2.42",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./index.js",
@@ -1,10 +1,10 @@
1
+ import React, { useEffect, useRef, useState } from "react";
2
+
1
3
  import { Box } from "@mui/material";
2
4
  import FloatingGraph from "../graph/FloatingGraph";
3
5
  import SelectionOverlay from "../selection/SelectionOverlay";
4
6
  import { useSelection } from "../selection/SelectionContext";
5
7
 
6
- import React, { useEffect, useRef, useState } from "react";
7
-
8
8
  const FlowViewport = ({
9
9
  children,
10
10
  selectionColor = "#64748b",
@@ -32,6 +32,7 @@ const FlowViewport = ({
32
32
  const selectionBoxRef = useRef(null);
33
33
  const mousePositionRef = useRef({ x: 0, y: 0 });
34
34
  const innerRef = useRef(null);
35
+ const didDragRef = useRef(false);
35
36
 
36
37
  const {
37
38
  clearSelection,
@@ -168,12 +169,14 @@ const FlowViewport = ({
168
169
  if (e.target?.closest?.(".MuiCard-root") || e.target?.closest?.("button"))
169
170
  return;
170
171
 
171
- if (e.button !== 0) return;
172
+ const isPan = e.button === 0 || e.button === 2;
173
+ if (!isPan) return;
172
174
 
173
175
  const startX = e.clientX;
174
176
  const startY = e.clientY;
177
+ didDragRef.current = false;
175
178
 
176
- if (e.shiftKey || e.ctrlKey || e.metaKey) {
179
+ if (e.button === 0 && (e.shiftKey || e.ctrlKey || e.metaKey)) {
177
180
  setSelectionBox({ startX, startY, currentX: startX, currentY: startY });
178
181
  selectionBoxRef.current = {
179
182
  startX,
@@ -238,15 +241,20 @@ const FlowViewport = ({
238
241
  return;
239
242
  }
240
243
 
241
- clearSelection();
244
+ if (e.button === 0) clearSelection();
242
245
 
243
246
  setIsDragging(true);
244
247
  const startOffset = { ...offset };
245
248
 
246
249
  const onMove = (ev) => {
250
+ const dx = ev.clientX - startX;
251
+ const dy = ev.clientY - startY;
252
+ if (!didDragRef.current && (Math.abs(dx) > 3 || Math.abs(dy) > 3)) {
253
+ didDragRef.current = true;
254
+ }
247
255
  setOffset({
248
- x: startOffset.x + (ev.clientX - startX),
249
- y: startOffset.y + (ev.clientY - startY),
256
+ x: startOffset.x + dx,
257
+ y: startOffset.y + dy,
250
258
  });
251
259
  };
252
260
 
@@ -260,10 +268,27 @@ const FlowViewport = ({
260
268
  window.addEventListener("mouseup", onUp);
261
269
  };
262
270
 
271
+ useEffect(() => {
272
+ const container = containerRef.current;
273
+ if (!container) return;
274
+
275
+ const onClickCapture = (e) => {
276
+ if (didDragRef.current) {
277
+ e.stopPropagation();
278
+ e.preventDefault();
279
+ didDragRef.current = false;
280
+ }
281
+ };
282
+
283
+ container.addEventListener("click", onClickCapture, true);
284
+ return () => container.removeEventListener("click", onClickCapture, true);
285
+ }, []);
286
+
263
287
  return (
264
288
  <Box
265
289
  ref={containerRef}
266
290
  onMouseDown={handleViewportMouseDown}
291
+ onContextMenu={(e) => e.preventDefault()}
267
292
  sx={{
268
293
  width: "100%",
269
294
  height: "100vh",
@@ -0,0 +1,95 @@
1
+ import { Box, Card, Divider, Typography } from "@mui/material";
2
+ import { alpha, useTheme } from "@mui/material/styles";
3
+
4
+ import React from "react";
5
+
6
+ const GlassCard = ({
7
+ width = "100%",
8
+ height = "85vh",
9
+ header,
10
+ content,
11
+ actions,
12
+ contentSx = {},
13
+ }) => {
14
+ const theme = useTheme();
15
+
16
+ return (
17
+ <Card
18
+ sx={{
19
+ width: width || "100%",
20
+ height: height || "85vh",
21
+ flexShrink: 0,
22
+ display: "flex",
23
+ flexDirection: "column",
24
+ background: `linear-gradient(135deg, ${theme.palette.primary.main}08 0%, ${theme.palette.secondary.main}05 100%)`,
25
+ backdropFilter: "blur(10px)",
26
+ border: `1px solid ${theme.palette.divider}`,
27
+ borderRadius: 2,
28
+ overflow: "hidden",
29
+ }}
30
+ >
31
+ {header && (
32
+ <>
33
+ <Box
34
+ sx={{
35
+ display: "flex",
36
+ alignItems: "center",
37
+ justifyContent: "space-between",
38
+ px: 2,
39
+ py: 1.5,
40
+ minHeight: 52,
41
+ flexShrink: 0,
42
+ }}
43
+ >
44
+ <Box sx={{ minWidth: 0, flex: 1 }}>
45
+ <Typography
46
+ variant="subtitle2"
47
+ noWrap
48
+ sx={{
49
+ fontWeight: 600,
50
+ color: "text.primary",
51
+ lineHeight: 1.3,
52
+ }}
53
+ >
54
+ {header.title}
55
+ </Typography>
56
+ {header.subtitle && (
57
+ <Typography
58
+ variant="caption"
59
+ noWrap
60
+ sx={{
61
+ color: "text.secondary",
62
+ lineHeight: 1.3,
63
+ display: "block",
64
+ }}
65
+ >
66
+ {header.subtitle}
67
+ </Typography>
68
+ )}
69
+ </Box>
70
+ {actions && <Box sx={{ ml: 1, flexShrink: 0 }}>{actions}</Box>}
71
+ </Box>
72
+ <Divider />
73
+ </>
74
+ )}
75
+
76
+ <Box
77
+ sx={{
78
+ flex: 1,
79
+ overflow: "auto",
80
+ position: "relative",
81
+ ...contentSx,
82
+ }}
83
+ >
84
+ {!header && actions && (
85
+ <Box sx={{ position: "absolute", top: 8, right: 8, zIndex: 1 }}>
86
+ {actions}
87
+ </Box>
88
+ )}
89
+ {content}
90
+ </Box>
91
+ </Card>
92
+ );
93
+ };
94
+
95
+ export default GlassCard;
@@ -0,0 +1 @@
1
+ export { default } from "./GlassCard";
package/src/lib/index.js CHANGED
@@ -49,3 +49,4 @@ export { default as Schema } from "./Schema";
49
49
  export { default as SchemaEditor } from "./SchemaEditor";
50
50
  export { default as ToggleableMenu } from "./ToggleableMenu";
51
51
  export { default as APIBody } from "./NewApiBody/NewAPIBody";
52
+ export { default as GlassCard } from "./GlassCard/GlassCard";
@@ -157,6 +157,9 @@ export function fab(theme) {
157
157
 
158
158
  return {
159
159
  MuiFab: {
160
+ defaultProps: {
161
+ size: "small",
162
+ },
160
163
  styleOverrides: {
161
164
  root: ({ ownerState }) => rootStyles(ownerState),
162
165
  },