fix stuck pointer during text editing / palm hits (#316)

fonts
Steve Ruiz 2021-11-20 00:05:48 +00:00 zatwierdzone przez GitHub
rodzic d5d999e86d
commit 62803443ef
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
35 zmienionych plików z 688 dodań i 676 usunięć

Wyświetl plik

@ -25,7 +25,7 @@
"build:core": "lerna run build:core",
"build:packages": "lerna run build:packages --stream",
"build:apps": "lerna run build:apps",
"start": "lerna run start --stream --parallel",
"start": "yarn build:packages && lerna run start --stream --parallel",
"start:core": "lerna run start:core --stream --parallel",
"start:www": "yarn build:packages && lerna run start --parallel & cd apps/www && yarn dev",
"start:electron": "lerna run start:electron --stream --parallel",

Wyświetl plik

@ -81,4 +81,4 @@
"\\~(.*)": "<rootDir>/src/$1"
}
}
}
}

Wyświetl plik

@ -2,11 +2,11 @@
import * as React from 'react'
/* eslint-disable @typescript-eslint/no-unused-vars */
import type { TLShape, TLBounds, TLComponentProps } from '~types'
import type { TLShape, TLBounds, TLComponentProps } from '../types'
import { TLShapeUtil } from './TLShapeUtil'
import { render } from '@testing-library/react'
import { SVGContainer } from '~components'
import Utils from '~utils'
import Utils from '../utils'
export interface BoxShape extends TLShape {
type: 'box'

Wyświetl plik

@ -1,8 +1,8 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import * as React from 'react'
import Utils from '~utils'
import Utils from '../utils'
import { intersectPolylineBounds } from '@tldraw/intersect'
import type { TLBounds, TLComponentProps, TLForwardedRef, TLShape, TLUser } from '~types'
import type { TLBounds, TLComponentProps, TLForwardedRef, TLShape, TLUser } from '../types'
export abstract class TLShapeUtil<T extends TLShape, E extends Element = any, M = any> {
refMap = new Map<string, React.RefObject<E>>()

Wyświetl plik

@ -1,4 +1,4 @@
import type { TLShape } from '~types'
import type { TLShape } from '../types'
import type { TLShapeUtil } from './TLShapeUtil'
export type TLShapeUtilsMap<T extends TLShape> = {

Wyświetl plik

@ -1,7 +1,7 @@
import * as React from 'react'
import { renderWithContext } from '~test'
import { Handles } from './handles'
import { boxShape } from '~shape-utils/TLShapeUtil.spec'
import { boxShape } from '~TLShapeUtil/TLShapeUtil.spec'
import { screen } from '@testing-library/react'
describe('handles', () => {

Wyświetl plik

@ -7,7 +7,7 @@ import { BoundsBg } from '~components/bounds/bounds-bg'
import { Handles } from '~components/handles'
import { ShapeNode } from '~components/shape'
import { ShapeIndicator } from '~components/shape-indicator'
import type { TLShapeUtil } from '~shape-utils'
import type { TLShapeUtil } from '~TLShapeUtil'
interface PageProps<T extends TLShape, M extends Record<string, unknown>> {
page: TLPage<T, TLBinding>

Wyświetl plik

@ -8,12 +8,13 @@ import type {
TLTheme,
TLBounds,
TLBinding,
TLSnapLine,
TLUsers,
} from '../../types'
import { Canvas } from '../canvas'
import { Inputs } from '../../inputs'
import { useTLTheme, TLContext, TLContextType } from '../../hooks'
import type { TLSnapLine, TLUsers } from '~index'
import type { TLShapeUtilsMap } from '~shape-utils'
import type { TLShapeUtilsMap } from '../../TLShapeUtil'
export interface RendererProps<T extends TLShape, M = any> extends Partial<TLCallbacks<T>> {
/**

Wyświetl plik

@ -1,7 +1,7 @@
import * as React from 'react'
import { renderWithSvg } from '~test'
import { ShapeIndicator } from './shape-indicator'
import { boxShape } from '~shape-utils/TLShapeUtil.spec'
import { boxShape } from '~TLShapeUtil/TLShapeUtil.spec'
describe('shape indicator', () => {
test('mounts component without crashing', () => {

Wyświetl plik

@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import * as React from 'react'
import type { TLComponentProps, TLShape } from '~types'
import type { TLShapeUtil } from '~shape-utils'
import type { TLShapeUtil } from '~TLShapeUtil'
interface RenderedShapeProps<T extends TLShape, E extends Element, M>
extends TLComponentProps<T, E, M> {

Wyświetl plik

@ -1,7 +1,7 @@
import * as React from 'react'
import type { IShapeTreeNode, TLShape } from '~types'
import { Shape } from './shape'
import type { TLShapeUtilsMap } from '~shape-utils'
import type { TLShapeUtilsMap } from '~TLShapeUtil'
interface ShapeNodeProps<T extends TLShape> extends IShapeTreeNode<T> {
utils: TLShapeUtilsMap<TLShape>

Wyświetl plik

@ -1,8 +1,8 @@
import * as React from 'react'
import { renderWithContext } from '~test'
import { Shape } from './shape'
import { BoxUtil, boxShape } from '~shape-utils/TLShapeUtil.spec'
import type { TLShapeUtil } from '~shape-utils'
import { BoxUtil, boxShape } from '~TLShapeUtil/TLShapeUtil.spec'
import type { TLShapeUtil } from '~TLShapeUtil'
import type { TLShape } from '~types'
describe('shape', () => {

Wyświetl plik

@ -7,7 +7,7 @@ import { RenderedShape } from './rendered-shape'
import { Container } from '~components/container'
import { useTLContext } from '~hooks'
import { useForceUpdate } from '~hooks/useForceUpdate'
import type { TLShapeUtil } from '~shape-utils'
import type { TLShapeUtil } from '~TLShapeUtil'
interface ShapeProps<T extends TLShape, M> extends IShapeTreeNode<T, M> {
utils: TLShapeUtil<T>

Wyświetl plik

@ -28,6 +28,9 @@ export function useBoundsEvents() {
const onPointerUp = React.useCallback(
(e: React.PointerEvent) => {
if (e.button !== 0) return
inputs.activePointer = undefined
if (!inputs.pointerIsValid(e)) return
e.stopPropagation()
const isDoubleClick = inputs.isDoubleClick()

Wyświetl plik

@ -1,5 +1,5 @@
import * as React from 'react'
import type { TLBoundsEdge, TLBoundsCorner } from '~types'
import type { TLBoundsEdge, TLBoundsCorner } from '../types'
import { useTLContext } from './useTLContext'
export function useBoundsHandleEvents(

Wyświetl plik

@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import * as React from 'react'
import type { TLPageState } from '~types'
import type { TLPageState } from '../types'
export function useCameraCss(
layerRef: React.RefObject<HTMLDivElement>,

Wyświetl plik

@ -37,6 +37,9 @@ export function useCanvasEvents() {
const onPointerUp = React.useCallback(
(e: React.PointerEvent) => {
if (e.button !== 0) return
inputs.activePointer = undefined
if (!inputs.pointerIsValid(e)) return
const isDoubleClick = inputs.isDoubleClick()
const info = inputs.pointerUp(e, 'canvas')

Wyświetl plik

@ -1,4 +1,4 @@
import type { TLBinding, TLPage, TLPageState, TLShape } from '~types'
import type { TLBinding, TLPage, TLPageState, TLShape } from '../types'
export function useHandles<T extends TLShape>(page: TLPage<T, TLBinding>, pageState: TLPageState) {
const { selectedIds } = pageState

Wyświetl plik

@ -1,4 +1,4 @@
import { useTLContext } from '~hooks'
import { useTLContext } from '../hooks'
import * as React from 'react'
export function useKeyEvents() {

Wyświetl plik

@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import * as React from 'react'
import type { TLBounds } from '~types'
import type { TLBounds } from '../types'
export function usePosition(bounds: TLBounds, rotation = 0) {
const rBounds = React.useRef<HTMLDivElement>(null)

Wyświetl plik

@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
import * as React from 'react'
import { useTLContext } from '~hooks'
import { useTLContext } from './useTLContext'
export function usePreventNavigation(rCanvas: React.RefObject<HTMLDivElement>): void {
const { bounds } = useTLContext()

Wyświetl plik

@ -1,7 +1,7 @@
import { useTLContext } from '~hooks'
import { useTLContext } from '../hooks'
import * as React from 'react'
import { Utils } from '~utils'
import type { TLBounds } from '~types'
import { Utils } from '../utils'
import type { TLBounds } from '../types'
export function useResizeObserver<T extends Element>(
ref: React.RefObject<T>,

Wyświetl plik

@ -1,5 +1,5 @@
import { useEffect } from 'react'
import Utils from '~utils'
import Utils from '../utils'
import { useTLContext } from './useTLContext'
// Send event on iOS when a user presses the "Done" key while editing a text element.

Wyświetl plik

@ -1,8 +1,8 @@
import * as React from 'react'
import type { TLPage, TLPageState, TLShape, TLBounds, TLBinding } from '~types'
import Utils from '~utils'
import { useTLContext } from '~hooks'
import type { TLShapeUtil, TLShapeUtilsMap } from '~shape-utils'
import type { TLPage, TLPageState, TLShape, TLBounds, TLBinding } from '../types'
import Utils from '../utils'
import { useTLContext } from './useTLContext'
import type { TLShapeUtil, TLShapeUtilsMap } from '../TLShapeUtil'
function canvasToScreen(point: number[], camera: TLPageState['camera']): number[] {
return [(point[0] + camera.point[0]) * camera.zoom, (point[1] + camera.point[1]) * camera.zoom]

Wyświetl plik

@ -43,6 +43,9 @@ export function useShapeEvents(id: string) {
const onPointerUp = React.useCallback(
(e: React.PointerEvent) => {
if (e.button !== 0) return
inputs.activePointer = undefined
if (!inputs.pointerIsValid(e)) return
e.stopPropagation()
const isDoubleClick = inputs.isDoubleClick()

Wyświetl plik

@ -1,7 +1,7 @@
import * as React from 'react'
import type { Inputs } from '~inputs'
import type { TLCallbacks, TLShape, TLBounds, TLPageState } from '~types'
import type { TLShapeUtilsMap } from '~shape-utils'
import type { TLShapeUtilsMap } from '~TLShapeUtil'
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export interface TLContextType<T extends TLShape> {

Wyświetl plik

@ -2,4 +2,4 @@ export * from './components'
export * from './types'
export * from './utils'
export * from './inputs'
export * from './shape-utils'
export * from './TLShapeUtil'

Wyświetl plik

@ -1,8 +1,7 @@
import type React from 'react'
import type { TLKeyboardInfo, TLPointerInfo } from './types'
import type { TLBounds, TLKeyboardInfo, TLPointerInfo } from './types'
import { Utils } from './utils'
import { Vec } from '@tldraw/vec'
import type { TLBounds } from '~index'
const DOUBLE_CLICK_DURATION = 250
@ -32,12 +31,16 @@ export class Inputs {
pointerIsValid(e: TouchEvent | React.TouchEvent | PointerEvent | React.PointerEvent) {
if ('pointerId' in e) {
if (this.activePointer && this.activePointer !== e.pointerId) return false
if (this.activePointer && this.activePointer !== e.pointerId) {
return false
}
}
if ('touches' in e) {
const touch = e.changedTouches[0]
if (this.activePointer && this.activePointer !== touch.identifier) return false
if (this.activePointer && this.activePointer !== touch.identifier) {
return false
}
}
return true

Wyświetl plik

@ -5,7 +5,7 @@ import { mockUtils } from './mockUtils'
import { useTLTheme, TLContext, TLContextType } from '../hooks'
import { Inputs } from '~inputs'
import type { TLShape } from '~index'
import type { BoxShape } from '~shape-utils/TLShapeUtil.spec'
import type { BoxShape } from '~TLShapeUtil/TLShapeUtil.spec'
export const ContextWrapper: React.FC = ({ children }) => {
useTLTheme()

Wyświetl plik

@ -1,4 +1,4 @@
import type { BoxShape } from '~shape-utils/TLShapeUtil.spec'
import type { BoxShape } from '~TLShapeUtil/TLShapeUtil.spec'
import type { TLBinding, TLPage, TLPageState } from '~types'
export const mockDocument: { page: TLPage<BoxShape, TLBinding>; pageState: TLPageState } = {

Wyświetl plik

@ -1,4 +1,4 @@
import { BoxUtil } from '~shape-utils/TLShapeUtil.spec'
import { BoxUtil } from '~TLShapeUtil/TLShapeUtil.spec'
export const mockUtils = {
box: new BoxUtil(),

Wyświetl plik

@ -75,9 +75,9 @@ export interface TLComponentProps<T extends TLShape, E = any, M = any> {
isSelected: boolean
isGhost?: boolean
isChildOfSelected?: boolean
meta: M extends any ? M : never
onShapeChange?: TLCallbacks<T>['onShapeChange']
onShapeBlur?: TLCallbacks<T>['onShapeBlur']
meta: M
onShapeChange?: TLShapeChangeHandler<T, any>
onShapeBlur?: TLShapeBlurHandler<any>
events: {
onPointerDown: (e: React.PointerEvent<E>) => void
onPointerUp: (e: React.PointerEvent<E>) => void

Wyświetl plik

@ -49,7 +49,7 @@
"@radix-ui/react-radio-group": "^0.1.1",
"@radix-ui/react-tooltip": "^0.1.1",
"@stitches/react": "^1.2.5",
"@tldraw/core": "latest",
"@tldraw/core": "^1.0.4",
"@tldraw/intersect": "latest",
"@tldraw/vec": "latest",
"perfect-freehand": "^1.0.16",
@ -90,4 +90,4 @@
}
},
"gitHead": "325008ff82bd27b63d625ad1b760f8871fb71af9"
}
}

Wyświetl plik

@ -14,6 +14,7 @@ import { getEllipseIndicatorPathTDSnapshot, getEllipsePath } from './ellipseHelp
type T = EllipseShape
type E = SVGSVGElement
type M = TDMeta
export class EllipseUtil extends TDShapeUtil<T, E> {
type = TDShapeType.Ellipse as const
@ -128,7 +129,7 @@ export class EllipseUtil extends TDShapeUtil<T, E> {
}
)
Indicator = TDShapeUtil.Indicator<T>(({ shape }) => {
Indicator = TDShapeUtil.Indicator<T, M>(({ shape }) => {
return <path d={getEllipseIndicatorPathTDSnapshot(shape, this.getCenter(shape))} />
})

1258
yarn.lock

Plik diff jest za duży Load Diff