Improves bounds corner touch targets on mobile
This commit is contained in:
parent
2af0d7b3a7
commit
03d0eadb6e
6 changed files with 80 additions and 67 deletions
|
@ -28,7 +28,7 @@ export default function Bounds() {
|
||||||
if (!bounds) return null
|
if (!bounds) return null
|
||||||
if (!isSelecting) return null
|
if (!isSelecting) return null
|
||||||
|
|
||||||
const size = (isMobile().any ? 12 : 8) / zoom // Touch target size
|
const size = (isMobile().any ? 10 : 8) / zoom // Touch target size
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<g
|
<g
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import useHandleEvents from "hooks/useBoundsHandleEvents"
|
import useHandleEvents from 'hooks/useBoundsHandleEvents'
|
||||||
import styled from "styles"
|
import styled from 'styles'
|
||||||
import { Corner, Bounds } from "types"
|
import { Corner, Bounds } from 'types'
|
||||||
|
|
||||||
export default function CornerHandle({
|
export default function CornerHandle({
|
||||||
size,
|
size,
|
||||||
|
@ -17,27 +17,41 @@ export default function CornerHandle({
|
||||||
const isLeft = corner === Corner.TopLeft || corner === Corner.BottomLeft
|
const isLeft = corner === Corner.TopLeft || corner === Corner.BottomLeft
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledCorner
|
<g>
|
||||||
corner={corner}
|
<StyledCorner
|
||||||
x={(isLeft ? 0 : bounds.width) - size / 2}
|
corner={corner}
|
||||||
y={(isTop ? 0 : bounds.height) - size / 2}
|
x={(isLeft ? 0 : bounds.width) - size}
|
||||||
width={size}
|
y={(isTop ? 0 : bounds.height) - size}
|
||||||
height={size}
|
width={size * 2}
|
||||||
{...events}
|
height={size * 2}
|
||||||
/>
|
{...events}
|
||||||
|
/>
|
||||||
|
<StyledCornerInner
|
||||||
|
x={(isLeft ? 0 : bounds.width) - size / 2}
|
||||||
|
y={(isTop ? 0 : bounds.height) - size / 2}
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
pointerEvents="none"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const StyledCorner = styled("rect", {
|
const StyledCorner = styled('rect', {
|
||||||
stroke: "$bounds",
|
stroke: 'none',
|
||||||
fill: "#fff",
|
fill: 'transparent',
|
||||||
zStrokeWidth: 2,
|
|
||||||
variants: {
|
variants: {
|
||||||
corner: {
|
corner: {
|
||||||
[Corner.TopLeft]: { cursor: "nwse-resize" },
|
[Corner.TopLeft]: { cursor: 'nwse-resize' },
|
||||||
[Corner.TopRight]: { cursor: "nesw-resize" },
|
[Corner.TopRight]: { cursor: 'nesw-resize' },
|
||||||
[Corner.BottomRight]: { cursor: "nwse-resize" },
|
[Corner.BottomRight]: { cursor: 'nwse-resize' },
|
||||||
[Corner.BottomLeft]: { cursor: "nesw-resize" },
|
[Corner.BottomLeft]: { cursor: 'nesw-resize' },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const StyledCornerInner = styled('rect', {
|
||||||
|
stroke: '$bounds',
|
||||||
|
fill: '#fff',
|
||||||
|
zStrokeWidth: 2,
|
||||||
|
})
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import useHandleEvents from "hooks/useBoundsHandleEvents"
|
import useHandleEvents from 'hooks/useBoundsHandleEvents'
|
||||||
import styled from "styles"
|
import styled from 'styles'
|
||||||
import { Edge, Bounds } from "types"
|
import { Edge, Bounds } from 'types'
|
||||||
|
|
||||||
export default function EdgeHandle({
|
export default function EdgeHandle({
|
||||||
size,
|
size,
|
||||||
|
@ -28,15 +28,15 @@ export default function EdgeHandle({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const StyledEdge = styled("rect", {
|
const StyledEdge = styled('rect', {
|
||||||
stroke: "none",
|
stroke: 'none',
|
||||||
fill: "none",
|
fill: 'none',
|
||||||
variants: {
|
variants: {
|
||||||
edge: {
|
edge: {
|
||||||
[Edge.Top]: { cursor: "ns-resize" },
|
[Edge.Top]: { cursor: 'ns-resize' },
|
||||||
[Edge.Right]: { cursor: "ew-resize" },
|
[Edge.Right]: { cursor: 'ew-resize' },
|
||||||
[Edge.Bottom]: { cursor: "ns-resize" },
|
[Edge.Bottom]: { cursor: 'ns-resize' },
|
||||||
[Edge.Left]: { cursor: "ew-resize" },
|
[Edge.Left]: { cursor: 'ew-resize' },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import Editor, { Monaco } from "@monaco-editor/react"
|
import Editor, { Monaco } from '@monaco-editor/react'
|
||||||
import useTheme from "hooks/useTheme"
|
import useTheme from 'hooks/useTheme'
|
||||||
import prettier from "prettier/standalone"
|
import prettier from 'prettier/standalone'
|
||||||
import parserTypeScript from "prettier/parser-typescript"
|
import parserTypeScript from 'prettier/parser-typescript'
|
||||||
import codeAsString from "./code-as-string"
|
import codeAsString from './code-as-string'
|
||||||
import React, { useCallback, useEffect, useRef } from "react"
|
import React, { useCallback, useEffect, useRef } from 'react'
|
||||||
import styled from "styles"
|
import styled from 'styles'
|
||||||
import { IMonaco, IMonacoEditor } from "types"
|
import { IMonaco, IMonacoEditor } from 'types'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
value: string
|
value: string
|
||||||
|
@ -48,7 +48,7 @@ export default function CodeEditor({
|
||||||
checkJs: false,
|
checkJs: false,
|
||||||
strict: false,
|
strict: false,
|
||||||
noLib: true,
|
noLib: true,
|
||||||
lib: ["es6"],
|
lib: ['es6'],
|
||||||
target: monaco.languages.typescript.ScriptTarget.ES2015,
|
target: monaco.languages.typescript.ScriptTarget.ES2015,
|
||||||
allowNonTsExtensions: true,
|
allowNonTsExtensions: true,
|
||||||
})
|
})
|
||||||
|
@ -69,13 +69,13 @@ export default function CodeEditor({
|
||||||
|
|
||||||
monaco.languages.typescript.javascriptDefaults.addExtraLib(codeAsString)
|
monaco.languages.typescript.javascriptDefaults.addExtraLib(codeAsString)
|
||||||
|
|
||||||
monaco.languages.registerDocumentFormattingEditProvider("javascript", {
|
monaco.languages.registerDocumentFormattingEditProvider('javascript', {
|
||||||
async provideDocumentFormattingEdits(model) {
|
async provideDocumentFormattingEdits(model) {
|
||||||
const text = prettier.format(model.getValue(), {
|
const text = prettier.format(model.getValue(), {
|
||||||
parser: "typescript",
|
parser: 'typescript',
|
||||||
plugins: [parserTypeScript],
|
plugins: [parserTypeScript],
|
||||||
singleQuote: true,
|
singleQuote: true,
|
||||||
trailingComma: "es5",
|
trailingComma: 'es5',
|
||||||
semi: false,
|
semi: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -114,12 +114,12 @@ export default function CodeEditor({
|
||||||
(e: React.KeyboardEvent<HTMLDivElement>) => {
|
(e: React.KeyboardEvent<HTMLDivElement>) => {
|
||||||
onKey && onKey()
|
onKey && onKey()
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
const metaKey = navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey
|
const metaKey = navigator.platform.match('Mac') ? e.metaKey : e.ctrlKey
|
||||||
if (e.key === "s" && metaKey) {
|
if (e.key === 's' && metaKey) {
|
||||||
const editor = rEditor.current
|
const editor = rEditor.current
|
||||||
if (!editor) return
|
if (!editor) return
|
||||||
editor
|
editor
|
||||||
.getAction("editor.action.formatDocument")
|
.getAction('editor.action.formatDocument')
|
||||||
.run()
|
.run()
|
||||||
.then(() =>
|
.then(() =>
|
||||||
onSave(rEditor.current?.getModel().getValue(), rEditor.current)
|
onSave(rEditor.current?.getModel().getValue(), rEditor.current)
|
||||||
|
@ -127,10 +127,10 @@ export default function CodeEditor({
|
||||||
|
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
}
|
}
|
||||||
if (e.key === "p" && metaKey) {
|
if (e.key === 'p' && metaKey) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
}
|
}
|
||||||
if (e.key === "d" && metaKey) {
|
if (e.key === 'd' && metaKey) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -167,7 +167,7 @@ export default function CodeEditor({
|
||||||
),
|
),
|
||||||
options: {
|
options: {
|
||||||
isWholeLine: true,
|
isWholeLine: true,
|
||||||
className: "editorLineError",
|
className: 'editorLineError',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
@ -176,7 +176,7 @@ export default function CodeEditor({
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const monaco = rMonaco.current
|
const monaco = rMonaco.current
|
||||||
if (!monaco) return
|
if (!monaco) return
|
||||||
monaco.editor.setTheme(theme === "dark" ? "vs-dark" : "light")
|
monaco.editor.setTheme(theme === 'dark' ? 'vs-dark' : 'light')
|
||||||
}, [theme])
|
}, [theme])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -194,7 +194,7 @@ export default function CodeEditor({
|
||||||
height="100%"
|
height="100%"
|
||||||
language="javascript"
|
language="javascript"
|
||||||
value={value}
|
value={value}
|
||||||
theme={theme === "dark" ? "vs-dark" : "light"}
|
theme={theme === 'dark' ? 'vs-dark' : 'light'}
|
||||||
beforeMount={handleBeforeMount}
|
beforeMount={handleBeforeMount}
|
||||||
onMount={handleMount}
|
onMount={handleMount}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
|
@ -203,12 +203,12 @@ export default function CodeEditor({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const EditorContainer = styled("div", {
|
const EditorContainer = styled('div', {
|
||||||
height: "100%",
|
height: '100%',
|
||||||
pointerEvents: "all",
|
pointerEvents: 'all',
|
||||||
userSelect: "all",
|
userSelect: 'all',
|
||||||
|
|
||||||
".editorLineError": {
|
'.editorLineError': {
|
||||||
backgroundColor: "$lineError",
|
backgroundColor: '$lineError',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -40,9 +40,11 @@ const Layout = styled('div', {
|
||||||
left: 0,
|
left: 0,
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
right: 0,
|
right: 0,
|
||||||
|
height: '100%',
|
||||||
|
width: '100%',
|
||||||
display: 'grid',
|
display: 'grid',
|
||||||
gridTemplateRows: '1fr auto 40px',
|
gridTemplateRows: '1fr auto 144px',
|
||||||
gridTemplateColumns: 'minmax(50%, 400px) 1fr auto',
|
gridTemplateColumns: 'minmax(0, 720px) 1fr auto',
|
||||||
gridTemplateAreas: `
|
gridTemplateAreas: `
|
||||||
"leftPanels main rightPanels"
|
"leftPanels main rightPanels"
|
||||||
"tools tools tools"
|
"tools tools tools"
|
||||||
|
@ -59,11 +61,11 @@ const LeftPanels = styled('main', {
|
||||||
})
|
})
|
||||||
|
|
||||||
const RightPanels = styled('main', {
|
const RightPanels = styled('main', {
|
||||||
display: 'grid',
|
|
||||||
gridArea: 'rightPanels',
|
gridArea: 'rightPanels',
|
||||||
gridTemplateRows: 'auto',
|
|
||||||
height: 'fit-content',
|
|
||||||
justifyContent: 'flex-end',
|
|
||||||
padding: 8,
|
padding: 8,
|
||||||
gap: 8,
|
// display: 'grid',
|
||||||
|
// gridTemplateRows: 'auto',
|
||||||
|
// height: 'fit-content',
|
||||||
|
// justifyContent: 'flex-end',
|
||||||
|
// gap: 8,
|
||||||
})
|
})
|
||||||
|
|
|
@ -13,10 +13,7 @@ export const Root = styled('div', {
|
||||||
|
|
||||||
variants: {
|
variants: {
|
||||||
isOpen: {
|
isOpen: {
|
||||||
true: {
|
true: {},
|
||||||
width: 'auto',
|
|
||||||
minWidth: 300,
|
|
||||||
},
|
|
||||||
false: {
|
false: {
|
||||||
height: 34,
|
height: 34,
|
||||||
width: 34,
|
width: 34,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue