Skip to content

Commit 21602ad

Browse files
add story with hotkeys
1 parent 346bfa3 commit 21602ad

File tree

5 files changed

+193
-6
lines changed

5 files changed

+193
-6
lines changed

docs/Hotkeys.mdx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,21 @@ return <GraphCanvas ref={graphRef} />;
2929
useHotkeys([
3030
{
3131
name: 'Zoom In',
32-
keys: 'shift+i',
32+
keys: 'mod+shift+i',
33+
action: 'keydown',
3334
category: 'Graph',
3435
callback: event => {
35-
event.preventDefault();
36+
event?.preventDefault();
3637
graphRef.current?.zoomIn();
3738
}
3839
},
3940
{
4041
name: 'Zoom Out',
41-
keys: 'shift+o',
42+
keys: 'mod+shift+o',
43+
action: 'keydown',
4244
category: 'Graph',
4345
callback: event => {
44-
event.preventDefault();
46+
event?.preventDefault();
4547
graphRef.current?.zoomOut();
4648
}
4749
},
@@ -51,8 +53,8 @@ useHotkeys([
5153
keys: 'mod+shift+c',
5254
action: 'keydown',
5355
callback: event => {
54-
event.preventDefault();
55-
graphRef.current?.centerGraph(nodeIds);
56+
event?.preventDefault();
57+
graphRef.current?.centerGraph(complexNodes.map(node => node.id));
5658
}
5759
}
5860
]);

docs/demos/Hotkeys.story.tsx

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
import React, { useEffect, useRef, useState } from 'react';
2+
import { useHotkeys } from 'reakeys';
3+
import {
4+
GraphCanvas,
5+
GraphCanvasRef,
6+
lightTheme,
7+
useSelection
8+
} from '../../src';
9+
import { complexEdges, complexNodes } from '../assets/demo';
10+
11+
export default {
12+
title: 'Demos/Hotkeys',
13+
component: GraphCanvas
14+
};
15+
16+
export const CameraControls = () => {
17+
const graphRef = useRef<GraphCanvasRef | null>(null);
18+
19+
const { selections, onNodeClick, onCanvasClick } = useSelection({
20+
ref: graphRef,
21+
nodes: complexNodes,
22+
edges: complexEdges,
23+
type: 'multi',
24+
selections: []
25+
});
26+
27+
const hotkeys = useHotkeys([
28+
{
29+
name: 'Zoom In',
30+
keys: 'mod+shift+i',
31+
action: 'keydown',
32+
category: 'Graph',
33+
callback: event => {
34+
event?.preventDefault();
35+
graphRef.current?.zoomIn();
36+
}
37+
},
38+
{
39+
name: 'Zoom Out',
40+
keys: 'mod+shift+o',
41+
action: 'keydown',
42+
category: 'Graph',
43+
callback: event => {
44+
event?.preventDefault();
45+
graphRef.current?.zoomOut();
46+
}
47+
},
48+
{
49+
name: 'Center',
50+
category: 'Graph',
51+
keys: 'mod+shift+c',
52+
action: 'keydown',
53+
callback: event => {
54+
event?.preventDefault();
55+
graphRef.current?.centerGraph(complexNodes.map(node => node.id));
56+
}
57+
}
58+
]);
59+
60+
return (
61+
<>
62+
<GraphCanvas
63+
ref={graphRef}
64+
nodes={complexNodes}
65+
edges={complexEdges}
66+
selections={selections}
67+
onNodeClick={onNodeClick}
68+
onCanvasClick={onCanvasClick}
69+
/>
70+
<div
71+
style={{
72+
position: 'absolute',
73+
top: 0,
74+
left: 0,
75+
color: 'black',
76+
padding: '10px'
77+
}}
78+
>
79+
<h1>Hotkeys</h1>
80+
{hotkeys.map(hotkey => (
81+
<p key={hotkey.name}>
82+
{hotkey.name} - <strong>{hotkey.keys}</strong>
83+
</p>
84+
))}
85+
</div>
86+
</>
87+
);
88+
};
89+
90+
export const Selection = () => {
91+
const graphRef = useRef<GraphCanvasRef | null>(null);
92+
93+
const {
94+
selections,
95+
setSelections,
96+
clearSelections,
97+
onNodeClick,
98+
onCanvasClick
99+
} = useSelection({
100+
ref: graphRef,
101+
nodes: complexNodes,
102+
edges: complexEdges,
103+
type: 'multi',
104+
selections: [complexNodes[0].id, complexNodes[1].id]
105+
});
106+
107+
const hotkeys = useHotkeys([
108+
{
109+
name: 'Select All',
110+
keys: 'mod+a',
111+
action: 'keydown',
112+
category: 'Graph',
113+
description: 'Select all nodes and edges',
114+
callback: event => {
115+
event?.preventDefault();
116+
setSelections(complexNodes.map(node => node.id));
117+
}
118+
},
119+
{
120+
name: 'Deselect Selections',
121+
category: 'Graph',
122+
description: 'Deselect selected nodes and edges',
123+
keys: 'escape',
124+
action: 'keydown',
125+
callback: event => {
126+
event?.preventDefault();
127+
clearSelections();
128+
}
129+
}
130+
]);
131+
132+
return (
133+
<>
134+
<GraphCanvas
135+
ref={graphRef}
136+
nodes={complexNodes}
137+
edges={complexEdges}
138+
selections={selections}
139+
onNodeClick={onNodeClick}
140+
onCanvasClick={onCanvasClick}
141+
/>
142+
<div
143+
style={{
144+
position: 'absolute',
145+
top: 0,
146+
left: 0,
147+
color: 'black',
148+
padding: '10px'
149+
}}
150+
>
151+
<h1>Hotkeys</h1>
152+
{hotkeys.map(hotkey => (
153+
<p key={hotkey.name}>
154+
{hotkey.name} - <strong>{hotkey.keys}</strong>
155+
</p>
156+
))}
157+
</div>
158+
</>
159+
);
160+
};

package-lock.json

Lines changed: 23 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@
112112
"prettier": "^3.2.5",
113113
"react": "^18.2.0",
114114
"react-dom": "^18.2.0",
115+
"reakeys": "^2.0.6",
115116
"rollup-plugin-peer-deps-external": "2.2.4",
116117
"stats.js": "^0.17.0",
117118
"storybook": "^7.6.17",

src/CameraControls/CameraControls.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ export const CameraControls: FC<
339339
ref={controls => {
340340
cameraRef.current = controls;
341341
if (!controlMounted) {
342+
// Update the state when the controls are mounted to notify about it component that using that controls
342343
setControlMounted(true);
343344
}
344345
}}

0 commit comments

Comments
 (0)