Skip to content

Commit f48cb75

Browse files
committed
feat(devtools-client): add zoom to devtools
1 parent ad880ff commit f48cb75

File tree

7 files changed

+127
-8
lines changed

7 files changed

+127
-8
lines changed

packages/overmind-devtools-client/src/components/ActionSelector/styles.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,6 @@ export const resultWrapper = css({
7979
overflowY: 'auto',
8080
left: 0,
8181
backgroundColor: colors.border,
82-
borderBottomLeftRadius: 3,
83-
borderBottomRightRadius: 3,
8482
zIndex: 2,
8583
})
8684

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import * as React from 'react'
2+
import { ZoomProvider, useZoom } from '../common/ZoomContext'
3+
import * as styles from './styles'
4+
import Workspace from '../Workspace'
5+
6+
// Wrapper component that applies the zoom level
7+
const ZoomableContainer: React.FC<{ children: React.ReactNode }> = ({
8+
children,
9+
}) => {
10+
const { zoomLevel } = useZoom()
11+
12+
return <div className={styles.container(zoomLevel)}>{children}</div>
13+
}
14+
15+
const App: React.FC = () => {
16+
return (
17+
<ZoomProvider>
18+
<ZoomableContainer>
19+
<Workspace />
20+
</ZoomableContainer>
21+
</ZoomProvider>
22+
)
23+
}
24+
25+
export default App
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { css } from 'emotion'
2+
import { colors } from '../../theme'
3+
4+
export const container = (zoomLevel: number) =>
5+
css({
6+
height: `calc(100vh / ${zoomLevel})`,
7+
width: `calc(100vw / ${zoomLevel})`,
8+
overflow: 'auto',
9+
transform: `scale(${zoomLevel})`,
10+
transformOrigin: 'top left',
11+
transition: 'transform 0.1s ease',
12+
scrollbarColor: `rgba(121, 121, 121, 0.4) ${colors.foreground}`,
13+
scrollbarWidth: 'thin',
14+
':hover': {
15+
scrollbarColor: `rgba(100, 100, 100, 0.7) ${colors.foreground}`,
16+
},
17+
})

packages/overmind-devtools-client/src/components/Devtools/index.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import * as React from 'react'
2-
import { useAppState } from '../../overmind'
2+
import { useAppState, useEffects } from '../../overmind'
33
import * as styles from './styles'
44
import * as text from '../../styles/text'
5-
import Workspace from '../Workspace'
5+
import App from '../App'
66
import { css } from 'emotion'
7+
import Workspace from '../Workspace'
78

89
const Devtools: React.FunctionComponent = () => {
910
const state = useAppState()
11+
const effects = useEffects()
1012

1113
if (state.error) {
1214
return (
@@ -21,7 +23,11 @@ const Devtools: React.FunctionComponent = () => {
2123
)
2224
}
2325

24-
return <Workspace />
26+
if (effects.platform.isVSCodeExtension()) {
27+
return <Workspace />
28+
}
29+
30+
return <App />
2531
}
2632

2733
export default Devtools

packages/overmind-devtools-client/src/components/StateMachineSelector/styles.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,6 @@ export const resultWrapper = css({
8585
overflowY: 'auto',
8686
left: 0,
8787
backgroundColor: colors.border,
88-
borderBottomLeftRadius: 3,
89-
borderBottomRightRadius: 3,
9088
zIndex: 2,
9189
})
9290

packages/overmind-devtools-client/src/components/Workspace/styles.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,13 @@ export const wrapper = css({
55
display: 'flex',
66
flexDirection: 'column',
77
justifyContent: 'stretch',
8-
height: '100vh',
8+
height: '100%',
9+
'*': {
10+
scrollbarColor: `rgba(121, 121, 121, 0.4) ${colors.foreground}`,
11+
':hover': {
12+
scrollbarColor: `rgba(100, 100, 100, 0.7) ${colors.foreground}`,
13+
},
14+
},
915
})
1016

1117
export const content = css({
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import * as React from 'react'
2+
3+
type ZoomContextType = {
4+
zoomLevel: number
5+
zoomIn: () => void
6+
zoomOut: () => void
7+
resetZoom: () => void
8+
}
9+
10+
const DEFAULT_ZOOM = 1
11+
const MIN_ZOOM = 0.5
12+
const MAX_ZOOM = 2
13+
const ZOOM_STEP = 0.1
14+
15+
export const ZoomContext = React.createContext<ZoomContextType>({
16+
zoomLevel: DEFAULT_ZOOM,
17+
zoomIn: () => {},
18+
zoomOut: () => {},
19+
resetZoom: () => {},
20+
})
21+
22+
export const ZoomProvider: React.FC<{ children: React.ReactNode }> = ({
23+
children,
24+
}) => {
25+
const [zoomLevel, setZoomLevel] = React.useState(DEFAULT_ZOOM)
26+
27+
const zoomIn = React.useCallback(() => {
28+
setZoomLevel((current) => Math.min(MAX_ZOOM, current + ZOOM_STEP))
29+
}, [])
30+
31+
const zoomOut = React.useCallback(() => {
32+
setZoomLevel((current) => Math.max(MIN_ZOOM, current - ZOOM_STEP))
33+
}, [])
34+
35+
const resetZoom = React.useCallback(() => {
36+
setZoomLevel(DEFAULT_ZOOM)
37+
}, [])
38+
39+
React.useEffect(() => {
40+
const handleKeyDown = (e: KeyboardEvent) => {
41+
if (e.ctrlKey) {
42+
if (e.key === '=' || e.key === '+') {
43+
e.preventDefault()
44+
zoomIn()
45+
} else if (e.key === '-') {
46+
e.preventDefault()
47+
zoomOut()
48+
} else if (e.key === '0') {
49+
e.preventDefault()
50+
resetZoom()
51+
}
52+
}
53+
}
54+
55+
window.addEventListener('keydown', handleKeyDown)
56+
return () => {
57+
window.removeEventListener('keydown', handleKeyDown)
58+
}
59+
}, [zoomIn, zoomOut, resetZoom])
60+
61+
const value = React.useMemo(
62+
() => ({ zoomLevel, zoomIn, zoomOut, resetZoom }),
63+
[zoomLevel, zoomIn, zoomOut, resetZoom]
64+
)
65+
66+
return <ZoomContext.Provider value={value}>{children}</ZoomContext.Provider>
67+
}
68+
69+
export const useZoom = () => React.useContext(ZoomContext)

0 commit comments

Comments
 (0)