Adds double click to tool lock, replaces tool lock button with delete button (#266)

This commit is contained in:
Steve Ruiz 2021-11-11 13:03:13 +00:00 committed by GitHub
parent 5a4c075894
commit b3d0e7cceb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 78 additions and 26 deletions

View file

@ -1,6 +1,7 @@
import * as React from 'react' import * as React from 'react'
import { breakpoints } from '~components/breakpoints' import { breakpoints } from '~components/breakpoints'
import { Tooltip } from '~components/Tooltip' import { Tooltip } from '~components/Tooltip'
import { useTLDrawContext } from '~hooks'
import { styled } from '~styles' import { styled } from '~styles'
export interface ToolButtonProps { export interface ToolButtonProps {
@ -39,9 +40,16 @@ interface ToolButtonWithTooltipProps extends ToolButtonProps {
} }
export function ToolButtonWithTooltip({ label, kbd, ...rest }: ToolButtonWithTooltipProps) { export function ToolButtonWithTooltip({ label, kbd, ...rest }: ToolButtonWithTooltipProps) {
const { state } = useTLDrawContext()
const handleDoubleClick = React.useCallback(() => {
console.log('double clicking')
state.toggleToolLock()
}, [])
return ( return (
<Tooltip label={label[0].toUpperCase() + label.slice(1)} kbd={kbd}> <Tooltip label={label[0].toUpperCase() + label.slice(1)} kbd={kbd}>
<ToolButton variant="primary" {...rest} /> <ToolButton {...rest} variant="primary" onDoubleClick={handleDoubleClick} />
</Tooltip> </Tooltip>
) )
} }

View file

@ -200,7 +200,10 @@ export function ActionButton(): JSX.Element {
<AspectRatioIcon opacity={isAllAspectLocked ? 1 : 0.4} /> <AspectRatioIcon opacity={isAllAspectLocked ? 1 : 0.4} />
</Tooltip> </Tooltip>
</IconButton> </IconButton>
<IconButton disabled={!isAllGrouped && !hasMultipleSelection} onClick={handleGroup}> <IconButton
disabled={!hasSelection || (!isAllGrouped && !hasMultipleSelection)}
onClick={handleGroup}
>
<Tooltip label="Group" kbd={`#G`}> <Tooltip label="Group" kbd={`#G`}>
<GroupIcon opacity={isAllGrouped ? 1 : 0.4} /> <GroupIcon opacity={isAllGrouped ? 1 : 0.4} />
</Tooltip> </Tooltip>
@ -212,7 +215,6 @@ export function ActionButton(): JSX.Element {
<PinBottomIcon /> <PinBottomIcon />
</Tooltip> </Tooltip>
</IconButton> </IconButton>
<IconButton disabled={!hasSelection} onClick={handleMoveBackward}> <IconButton disabled={!hasSelection} onClick={handleMoveBackward}>
<Tooltip label="Move Backward" kbd={`#[`}> <Tooltip label="Move Backward" kbd={`#[`}>
<ArrowDownIcon /> <ArrowDownIcon />

View file

@ -0,0 +1,21 @@
import * as React from 'react'
import { Tooltip } from '~components/Tooltip'
import { useTLDrawContext } from '~hooks'
import { ToolButton } from '~components/ToolButton'
import { TrashIcon } from '~components/icons'
export function DeleteButton(): JSX.Element {
const { state } = useTLDrawContext()
const handleDelete = React.useCallback(() => {
state.delete()
}, [state])
return (
<Tooltip label="Delete" kbd="7">
<ToolButton variant="circle" onSelect={handleDelete}>
<TrashIcon />
</ToolButton>
</Tooltip>
)
}

View file

@ -7,6 +7,7 @@ import { BackToContent } from './BackToContent'
import { PrimaryTools } from './PrimaryTools' import { PrimaryTools } from './PrimaryTools'
import { ActionButton } from './ActionButton' import { ActionButton } from './ActionButton'
import { LockButton } from './LockButton' import { LockButton } from './LockButton'
import { DeleteButton } from './DeleteButton'
const isDebugModeSelector = (s: TLDrawSnapshot) => s.settings.isDebugMode const isDebugModeSelector = (s: TLDrawSnapshot) => s.settings.isDebugMode
@ -22,7 +23,7 @@ export const ToolsPanel = React.memo(function ToolsPanel(): JSX.Element {
<StyledPrimaryTools> <StyledPrimaryTools>
<ActionButton /> <ActionButton />
<PrimaryTools /> <PrimaryTools />
<LockButton /> <DeleteButton />
</StyledPrimaryTools> </StyledPrimaryTools>
</StyledCenterWrap> </StyledCenterWrap>
{isDebugMode && ( {isDebugMode && (

View file

@ -38,6 +38,7 @@ import {
SessionType, SessionType,
ExceptFirst, ExceptFirst,
ExceptFirstTwo, ExceptFirstTwo,
TLDrawToolType,
} from '~types' } from '~types'
import { import {
migrate, migrate,
@ -51,7 +52,7 @@ import { shapeUtils } from '~state/shapes'
import { defaultStyle } from '~state/shapes/shape-styles' import { defaultStyle } from '~state/shapes/shape-styles'
import * as Commands from './commands' import * as Commands from './commands'
import { ArgsOfType, getSession } from './sessions' import { ArgsOfType, getSession } from './sessions'
import { createTools, ToolType } from './tools' import { createTools } from './tools'
import type { BaseTool } from './tools/BaseTool' import type { BaseTool } from './tools/BaseTool'
import { USER_COLORS, FIT_TO_SCREEN_PADDING } from '~constants' import { USER_COLORS, FIT_TO_SCREEN_PADDING } from '~constants'
@ -642,12 +643,21 @@ export class TLDrawState extends StateManager<TLDrawSnapshot> {
* Select a tool. * Select a tool.
* @param tool The tool to select, or "select". * @param tool The tool to select, or "select".
*/ */
selectTool = (type: ToolType): this => { selectTool = (type: TLDrawToolType): this => {
if (this.readOnly || this.session) return this if (this.readOnly || this.session) return this
const tool = this.tools[type] const tool = this.tools[type]
if (tool === this.currentTool) return this if (tool === this.currentTool) {
console.log('hi')
this.patchState({
appState: {
isToolLocked: false,
},
})
return this
}
this.currentTool.onExit() this.currentTool.onExit()
@ -659,6 +669,7 @@ export class TLDrawState extends StateManager<TLDrawSnapshot> {
{ {
appState: { appState: {
activeTool: type, activeTool: type,
isToolLocked: false,
}, },
}, },
`selected_tool:${type}` `selected_tool:${type}`

View file

@ -12,7 +12,6 @@ import {
Utils, Utils,
} from '@tldraw/core' } from '@tldraw/core'
import type { TLDrawState } from '~state' import type { TLDrawState } from '~state'
import type { TLDrawShapeType } from '~types'
export enum Status { export enum Status {
Idle = 'idle', Idle = 'idle',
@ -22,8 +21,6 @@ export enum Status {
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
export abstract class BaseTool<T extends string = any> { export abstract class BaseTool<T extends string = any> {
abstract type: TLDrawShapeType | 'select'
state: TLDrawState state: TLDrawState
status: Status | T = Status.Idle status: Status | T = Status.Idle

View file

@ -1,5 +1,6 @@
import type { TLDrawState } from '~state' import type { TLDrawState } from '~state'
import { TLDrawShapeType } from '~types' import { TLDrawShapeType, TLDrawToolType } from '~types'
import type { BaseTool } from './BaseTool'
import { ArrowTool } from './ArrowTool' import { ArrowTool } from './ArrowTool'
import { DrawTool } from './DrawTool' import { DrawTool } from './DrawTool'
import { EllipseTool } from './EllipseTool' import { EllipseTool } from './EllipseTool'
@ -8,15 +9,6 @@ import { SelectTool } from './SelectTool'
import { StickyTool } from './StickyTool' import { StickyTool } from './StickyTool'
import { TextTool } from './TextTool' import { TextTool } from './TextTool'
export type ToolType =
| 'select'
| TLDrawShapeType.Text
| TLDrawShapeType.Draw
| TLDrawShapeType.Ellipse
| TLDrawShapeType.Rectangle
| TLDrawShapeType.Arrow
| TLDrawShapeType.Sticky
export interface ToolsMap { export interface ToolsMap {
select: typeof SelectTool select: typeof SelectTool
[TLDrawShapeType.Text]: typeof TextTool [TLDrawShapeType.Text]: typeof TextTool
@ -27,11 +19,11 @@ export interface ToolsMap {
[TLDrawShapeType.Sticky]: typeof StickyTool [TLDrawShapeType.Sticky]: typeof StickyTool
} }
export type ToolOfType<K extends ToolType> = ToolsMap[K] export type ToolOfType<K extends TLDrawToolType> = ToolsMap[K]
export type ArgsOfType<K extends ToolType> = ConstructorParameters<ToolOfType<K>> export type ArgsOfType<K extends TLDrawToolType> = ConstructorParameters<ToolOfType<K>>
export const tools: { [K in ToolType]: ToolsMap[K] } = { export const tools: { [K in TLDrawToolType]: ToolsMap[K] } = {
select: SelectTool, select: SelectTool,
[TLDrawShapeType.Text]: TextTool, [TLDrawShapeType.Text]: TextTool,
[TLDrawShapeType.Draw]: DrawTool, [TLDrawShapeType.Draw]: DrawTool,
@ -41,11 +33,11 @@ export const tools: { [K in ToolType]: ToolsMap[K] } = {
[TLDrawShapeType.Sticky]: StickyTool, [TLDrawShapeType.Sticky]: StickyTool,
} }
export const getTool = <K extends ToolType>(type: K): ToolOfType<K> => { export const getTool = <K extends TLDrawToolType>(type: K): ToolOfType<K> => {
return tools[type] return tools[type]
} }
export function createTools(state: TLDrawState) { export function createTools(state: TLDrawState): Record<TLDrawToolType, BaseTool> {
return { return {
select: new SelectTool(state), select: new SelectTool(state),
[TLDrawShapeType.Text]: new TextTool(state), [TLDrawShapeType.Text]: new TextTool(state),

View file

@ -401,6 +401,15 @@ export type Easing =
| 'easeOutExpo' | 'easeOutExpo'
| 'easeInOutExpo' | 'easeInOutExpo'
export type TLDrawToolType =
| 'select'
| TLDrawShapeType.Text
| TLDrawShapeType.Draw
| TLDrawShapeType.Ellipse
| TLDrawShapeType.Rectangle
| TLDrawShapeType.Arrow
| TLDrawShapeType.Sticky
/* ------------------- File System ------------------ */ /* ------------------- File System ------------------ */
export interface TLDrawFile { export interface TLDrawFile {

View file

@ -1,4 +1,5 @@
import { TLDraw, TLDrawState, useFileSystem } from '@tldraw/tldraw' import { TLDraw, TLDrawState, useFileSystem } from '@tldraw/tldraw'
import { signIn, signOut } from 'next-auth/client'
import * as gtag from '-utils/gtag' import * as gtag from '-utils/gtag'
import React from 'react' import React from 'react'
@ -26,13 +27,23 @@ export default function Editor({ id = 'home' }: EditorProps) {
const fileSystemEvents = useFileSystem() const fileSystemEvents = useFileSystem()
const handleSignIn = React.useCallback(() => {
signIn()
}, [])
const handleSignOut = React.useCallback(() => {
signOut()
}, [])
return ( return (
<div className="tldraw"> <div className="tldraw">
<TLDraw <TLDraw
id={id} id={id}
autofocus
onMount={handleMount} onMount={handleMount}
onPersist={handlePersist} onPersist={handlePersist}
autofocus onSignIn={handleSignIn}
onSignOut={handleSignOut}
{...fileSystemEvents} {...fileSystemEvents}
/> />
</div> </div>