Debugging cleanup / misc cleanup (#2025)
This PR: - removes feature flags for people menu, highlighter shape - removes debugging for cursors - adds a debug flag for hiding shapes - changes Canvas to use `useValue` rather than `track` - removes the default background color on `tl-background` - in the editor components, makes `Background` null by default ### Change Type - [x] `minor` — New feature
This commit is contained in:
parent
a9236bcbb0
commit
9c1dc00740
10 changed files with 95 additions and 135 deletions
|
@ -84,7 +84,7 @@ export const allExamples: Example[] = [
|
||||||
element: <ScrollExample />,
|
element: <ScrollExample />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Custom config',
|
title: 'Custom shapes / tools',
|
||||||
path: '/custom-config',
|
path: '/custom-config',
|
||||||
element: <CustomConfigExample />,
|
element: <CustomConfigExample />,
|
||||||
},
|
},
|
||||||
|
|
|
@ -282,9 +282,9 @@ export const CAMERA_SLIDE_FRICTION = 0.09;
|
||||||
export function canonicalizeRotation(a: number): number;
|
export function canonicalizeRotation(a: number): number;
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
export const Canvas: React_2.MemoExoticComponent<({ className }: {
|
export function Canvas({ className }: {
|
||||||
className?: string | undefined;
|
className?: string;
|
||||||
}) => JSX.Element>;
|
}): JSX.Element;
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
export class Circle2d extends Geometry2d {
|
export class Circle2d extends Geometry2d {
|
||||||
|
@ -411,11 +411,12 @@ export const debugFlags: {
|
||||||
elementRemovalLogging: DebugFlag<boolean>;
|
elementRemovalLogging: DebugFlag<boolean>;
|
||||||
debugSvg: DebugFlag<boolean>;
|
debugSvg: DebugFlag<boolean>;
|
||||||
throwToBlob: DebugFlag<boolean>;
|
throwToBlob: DebugFlag<boolean>;
|
||||||
logMessages: DebugFlag<never[]>;
|
logMessages: DebugFlag<any[]>;
|
||||||
resetConnectionEveryPing: DebugFlag<boolean>;
|
resetConnectionEveryPing: DebugFlag<boolean>;
|
||||||
debugCursors: DebugFlag<boolean>;
|
debugCursors: DebugFlag<boolean>;
|
||||||
forceSrgb: DebugFlag<boolean>;
|
forceSrgb: DebugFlag<boolean>;
|
||||||
debugGeometry: DebugFlag<boolean>;
|
debugGeometry: DebugFlag<boolean>;
|
||||||
|
hideShapes: DebugFlag<boolean>;
|
||||||
};
|
};
|
||||||
|
|
||||||
// @internal (undocumented)
|
// @internal (undocumented)
|
||||||
|
@ -955,10 +956,7 @@ export const EVENT_NAME_MAP: Record<Exclude<TLEventName, TLPinchEventName>, keyo
|
||||||
export function extractSessionStateFromLegacySnapshot(store: Record<string, UnknownRecord>): null | TLSessionStateSnapshot;
|
export function extractSessionStateFromLegacySnapshot(store: Record<string, UnknownRecord>): null | TLSessionStateSnapshot;
|
||||||
|
|
||||||
// @internal (undocumented)
|
// @internal (undocumented)
|
||||||
export const featureFlags: {
|
export const featureFlags: Record<string, DebugFlag<boolean>>;
|
||||||
peopleMenu: DebugFlag<boolean>;
|
|
||||||
highlighterTool: DebugFlag<boolean>;
|
|
||||||
};
|
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
export type GapsSnapLine = {
|
export type GapsSnapLine = {
|
||||||
|
|
|
@ -213,7 +213,6 @@ input,
|
||||||
left: 0px;
|
left: 0px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: var(--color-background);
|
|
||||||
color: var(--color-text);
|
color: var(--color-text);
|
||||||
z-index: var(--layer-canvas);
|
z-index: var(--layer-canvas);
|
||||||
cursor: var(--tl-cursor);
|
cursor: var(--tl-cursor);
|
||||||
|
@ -275,7 +274,6 @@ input,
|
||||||
.tl-background {
|
.tl-background {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0px;
|
inset: 0px;
|
||||||
background-color: var(--color-background);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------- Grid Layer --------------------- */
|
/* --------------------- Grid Layer --------------------- */
|
||||||
|
|
|
@ -21,7 +21,7 @@ import { Shape } from './Shape'
|
||||||
import { ShapeIndicator } from './ShapeIndicator'
|
import { ShapeIndicator } from './ShapeIndicator'
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export const Canvas = track(function Canvas({ className }: { className?: string }) {
|
export function Canvas({ className }: { className?: string }) {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
|
|
||||||
const { Background, SvgDefs } = useEditorComponents()
|
const { Background, SvgDefs } = useEditorComponents()
|
||||||
|
@ -81,9 +81,12 @@ export const Canvas = track(function Canvas({ className }: { className?: string
|
||||||
[editor]
|
[editor]
|
||||||
)
|
)
|
||||||
|
|
||||||
React.useEffect(() => {
|
const hideShapes = useValue('debug_shapes', () => debugFlags.hideShapes.value, [debugFlags])
|
||||||
rCanvas.current?.focus()
|
const debugSvg = useValue('debug_svg', () => debugFlags.debugSvg.value, [debugFlags])
|
||||||
}, [])
|
const debugGeometry = useValue('debug_geometry', () => debugFlags.debugGeometry.value, [
|
||||||
|
debugFlags,
|
||||||
|
])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={rCanvas}
|
ref={rCanvas}
|
||||||
|
@ -107,11 +110,11 @@ export const Canvas = track(function Canvas({ className }: { className?: string
|
||||||
</svg>
|
</svg>
|
||||||
<div ref={rHtmlLayer} className="tl-html-layer tl-shapes" draggable={false}>
|
<div ref={rHtmlLayer} className="tl-html-layer tl-shapes" draggable={false}>
|
||||||
<SelectionBackgroundWrapper />
|
<SelectionBackgroundWrapper />
|
||||||
<ShapesToDisplay />
|
{hideShapes ? null : debugSvg ? <ShapesWithSVGs /> : <ShapesToDisplay />}
|
||||||
</div>
|
</div>
|
||||||
<div className="tl-fixed-layer tl-overlays">
|
<div className="tl-fixed-layer tl-overlays">
|
||||||
<div ref={rHtmlLayer2} className="tl-html-layer">
|
<div ref={rHtmlLayer2} className="tl-html-layer">
|
||||||
{debugFlags.debugGeometry.value && <GeometryDebuggingView />}
|
{debugGeometry ? <GeometryDebuggingView /> : null}
|
||||||
<HandlesWrapper />
|
<HandlesWrapper />
|
||||||
<BrushWrapper />
|
<BrushWrapper />
|
||||||
<ScribbleWrapper />
|
<ScribbleWrapper />
|
||||||
|
@ -126,7 +129,7 @@ export const Canvas = track(function Canvas({ className }: { className?: string
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})
|
}
|
||||||
|
|
||||||
function GridWrapper() {
|
function GridWrapper() {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
|
@ -278,24 +281,27 @@ function HandleWrapper({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const ShapesToDisplay = track(function ShapesToDisplay() {
|
function ShapesWithSVGs() {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
|
|
||||||
const { renderingShapes } = editor
|
const renderingShapes = useValue('rendering shapes', () => editor.renderingShapes, [editor])
|
||||||
|
|
||||||
const debugSvg = debugFlags.debugSvg.value
|
return (
|
||||||
if (debugSvg) {
|
<>
|
||||||
return (
|
{renderingShapes.map((result) => (
|
||||||
<>
|
<React.Fragment key={result.id + '_fragment'}>
|
||||||
{renderingShapes.map((result) => (
|
<Shape {...result} />
|
||||||
<React.Fragment key={result.id + '_fragment'}>
|
<DebugSvgCopy id={result.id} />
|
||||||
<Shape {...result} />
|
</React.Fragment>
|
||||||
<DebugSvgCopy id={result.id} />
|
))}
|
||||||
</React.Fragment>
|
</>
|
||||||
))}
|
)
|
||||||
</>
|
}
|
||||||
)
|
|
||||||
}
|
function ShapesToDisplay() {
|
||||||
|
const editor = useEditor()
|
||||||
|
|
||||||
|
const renderingShapes = useValue('rendering shapes', () => editor.renderingShapes, [editor])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -304,7 +310,7 @@ const ShapesToDisplay = track(function ShapesToDisplay() {
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
})
|
}
|
||||||
|
|
||||||
function SelectedIdIndicators() {
|
function SelectedIdIndicators() {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
|
@ -455,12 +461,14 @@ const DebugSvgCopy = track(function DupSvg({ id }: { id: TLShapeId }) {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
const UiLogger = track(() => {
|
function UiLogger() {
|
||||||
const logMessages = debugFlags.logMessages.value
|
const uiLog = useValue('debugging ui log', () => debugFlags.logMessages.value, [debugFlags])
|
||||||
|
|
||||||
|
if (!uiLog.length) return null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="debug__ui-logger">
|
<div className="debug__ui-logger">
|
||||||
{logMessages.map((message, messageIndex) => {
|
{uiLog.map((message, messageIndex) => {
|
||||||
const text = typeof message === 'string' ? message : JSON.stringify(message)
|
const text = typeof message === 'string' ? message : JSON.stringify(message)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -471,7 +479,7 @@ const UiLogger = track(() => {
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})
|
}
|
||||||
|
|
||||||
export function SelectionForegroundWrapper() {
|
export function SelectionForegroundWrapper() {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { track } from '@tldraw/state'
|
import { track } from '@tldraw/state'
|
||||||
import { modulate } from '@tldraw/utils'
|
import { modulate } from '@tldraw/utils'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { HIT_TEST_MARGIN } from '../constants'
|
|
||||||
import { useEditor } from '../hooks/useEditor'
|
import { useEditor } from '../hooks/useEditor'
|
||||||
|
|
||||||
function useTick(isEnabled = true) {
|
function useTick(isEnabled = true) {
|
||||||
|
@ -27,6 +26,7 @@ export const GeometryDebuggingView = track(function GeometryDebuggingView({
|
||||||
showClosestPointOnOutline?: boolean
|
showClosestPointOnOutline?: boolean
|
||||||
}) {
|
}) {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
|
|
||||||
useTick(showClosestPointOnOutline)
|
useTick(showClosestPointOnOutline)
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
@ -56,18 +56,25 @@ export const GeometryDebuggingView = track(function GeometryDebuggingView({
|
||||||
|
|
||||||
const pointInShapeSpace = editor.getPointInShapeSpace(shape, currentPagePoint)
|
const pointInShapeSpace = editor.getPointInShapeSpace(shape, currentPagePoint)
|
||||||
const nearestPointOnShape = geometry.nearestPoint(pointInShapeSpace)
|
const nearestPointOnShape = geometry.nearestPoint(pointInShapeSpace)
|
||||||
const distanceToPoint = geometry.distanceToPoint(pointInShapeSpace)
|
const distanceToPoint = geometry.distanceToPoint(pointInShapeSpace, true)
|
||||||
|
const dist = Math.abs(distanceToPoint) * zoomLevel
|
||||||
|
const hitInside = distanceToPoint < 0
|
||||||
|
|
||||||
const { vertices } = geometry
|
const { vertices } = geometry
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<g key={result.id + '_outline'} transform={pageTransform.toCssString()}>
|
<g
|
||||||
|
key={result.id + '_outline'}
|
||||||
|
transform={pageTransform.toCssString()}
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
>
|
||||||
{showStroke && (
|
{showStroke && (
|
||||||
<path
|
<path
|
||||||
stroke="red"
|
stroke="red"
|
||||||
strokeWidth={2}
|
strokeWidth="2"
|
||||||
fill="none"
|
fill="none"
|
||||||
opacity={0.5}
|
opacity="1"
|
||||||
d={geometry.toSimpleSvgPath()}
|
d={geometry.toSimpleSvgPath()}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -77,20 +84,21 @@ export const GeometryDebuggingView = track(function GeometryDebuggingView({
|
||||||
key={`v${i}`}
|
key={`v${i}`}
|
||||||
cx={v.x}
|
cx={v.x}
|
||||||
cy={v.y}
|
cy={v.y}
|
||||||
r={2}
|
r="2"
|
||||||
fill={`hsl(${modulate(i, [0, vertices.length - 1], [120, 0])}, 100%, 50%)`}
|
fill={`hsl(${modulate(i, [0, vertices.length - 1], [120, 200])}, 100%, 50%)`}
|
||||||
stroke="black"
|
stroke="black"
|
||||||
strokeWidth="1"
|
strokeWidth="1"
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
{distanceToPoint > 0 && showClosestPointOnOutline && (
|
{showClosestPointOnOutline && dist < 150 && (
|
||||||
<line
|
<line
|
||||||
x1={nearestPointOnShape.x}
|
x1={nearestPointOnShape.x}
|
||||||
y1={nearestPointOnShape.y}
|
y1={nearestPointOnShape.y}
|
||||||
x2={pointInShapeSpace.x}
|
x2={pointInShapeSpace.x}
|
||||||
y2={pointInShapeSpace.y}
|
y2={pointInShapeSpace.y}
|
||||||
strokeWidth={2}
|
opacity={1 - dist / 150}
|
||||||
stroke={distanceToPoint < HIT_TEST_MARGIN / zoomLevel ? 'red' : 'pink'}
|
stroke={hitInside ? 'goldenrod' : 'dodgerblue'}
|
||||||
|
strokeWidth="2"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</g>
|
</g>
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
import { createContext, useContext, useMemo } from 'react'
|
import { createContext, useContext, useMemo } from 'react'
|
||||||
import { ShapeIndicator, TLShapeIndicatorComponent } from '../components/ShapeIndicator'
|
import { ShapeIndicator, TLShapeIndicatorComponent } from '../components/ShapeIndicator'
|
||||||
import {
|
import { TLBackgroundComponent } from '../components/default-components/DefaultBackground'
|
||||||
DefaultBackground,
|
|
||||||
TLBackgroundComponent,
|
|
||||||
} from '../components/default-components/DefaultBackground'
|
|
||||||
import { DefaultBrush, TLBrushComponent } from '../components/default-components/DefaultBrush'
|
import { DefaultBrush, TLBrushComponent } from '../components/default-components/DefaultBrush'
|
||||||
import {
|
import {
|
||||||
DefaultCollaboratorHint,
|
DefaultCollaboratorHint,
|
||||||
|
@ -91,7 +88,7 @@ export function EditorComponentsProvider({ overrides, children }: ComponentsCont
|
||||||
<EditorComponentsContext.Provider
|
<EditorComponentsContext.Provider
|
||||||
value={useMemo(
|
value={useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
Background: DefaultBackground,
|
Background: null,
|
||||||
SvgDefs: DefaultSvgDefs,
|
SvgDefs: DefaultSvgDefs,
|
||||||
Brush: DefaultBrush,
|
Brush: DefaultBrush,
|
||||||
ZoomBrush: DefaultBrush,
|
ZoomBrush: DefaultBrush,
|
||||||
|
|
|
@ -7,12 +7,10 @@ import { Atom, atom, react } from '@tldraw/state'
|
||||||
// development. Use `createFeatureFlag` to create a boolean flag which will be
|
// development. Use `createFeatureFlag` to create a boolean flag which will be
|
||||||
// `true` by default in development and staging, and `false` in production.
|
// `true` by default in development and staging, and `false` in production.
|
||||||
/** @internal */
|
/** @internal */
|
||||||
export const featureFlags = {
|
export const featureFlags: Record<string, DebugFlag<boolean>> = {
|
||||||
// todo: remove this. it's not used, but we only have one feature flag and i
|
// todo: remove this. it's not used, but we only have one feature flag and i
|
||||||
// wanted an example :(
|
// wanted an example :(
|
||||||
peopleMenu: createFeatureFlag('peopleMenu'),
|
}
|
||||||
highlighterTool: createFeatureFlag('highlighterTool', { all: true }),
|
|
||||||
} satisfies Record<string, DebugFlag<boolean>>
|
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
export const debugFlags = {
|
export const debugFlags = {
|
||||||
|
@ -44,7 +42,7 @@ export const debugFlags = {
|
||||||
throwToBlob: createDebugValue('throwToBlob', {
|
throwToBlob: createDebugValue('throwToBlob', {
|
||||||
defaults: { all: false },
|
defaults: { all: false },
|
||||||
}),
|
}),
|
||||||
logMessages: createDebugValue('uiLog', { defaults: { all: [] } }),
|
logMessages: createDebugValue('uiLog', { defaults: { all: [] as any[] } }),
|
||||||
resetConnectionEveryPing: createDebugValue('resetConnectionEveryPing', {
|
resetConnectionEveryPing: createDebugValue('resetConnectionEveryPing', {
|
||||||
defaults: { all: false },
|
defaults: { all: false },
|
||||||
}),
|
}),
|
||||||
|
@ -53,6 +51,7 @@ export const debugFlags = {
|
||||||
}),
|
}),
|
||||||
forceSrgb: createDebugValue('forceSrgbColors', { defaults: { all: false } }),
|
forceSrgb: createDebugValue('forceSrgbColors', { defaults: { all: false } }),
|
||||||
debugGeometry: createDebugValue('debugGeometry', { defaults: { all: false } }),
|
debugGeometry: createDebugValue('debugGeometry', { defaults: { all: false } }),
|
||||||
|
hideShapes: createDebugValue('hideShapes', { defaults: { all: false } }),
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
@ -109,16 +108,17 @@ function createDebugValue<T>(
|
||||||
shouldStoreForSession,
|
shouldStoreForSession,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
function createFeatureFlag(
|
|
||||||
name: string,
|
// function createFeatureFlag(
|
||||||
defaults: Defaults<boolean> = { all: true, production: false }
|
// name: string,
|
||||||
) {
|
// defaults: Defaults<boolean> = { all: true, production: false }
|
||||||
return createDebugValueBase({
|
// ) {
|
||||||
name,
|
// return createDebugValueBase({
|
||||||
defaults,
|
// name,
|
||||||
shouldStoreForSession: true,
|
// defaults,
|
||||||
})
|
// shouldStoreForSession: true,
|
||||||
}
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
function createDebugValueBase<T>(def: DebugFlagDef<T>): DebugFlag<T> {
|
function createDebugValueBase<T>(def: DebugFlagDef<T>): DebugFlag<T> {
|
||||||
const defaultValue = getDefaultValue(def)
|
const defaultValue = getDefaultValue(def)
|
||||||
|
|
|
@ -184,30 +184,7 @@ const DebugMenuContent = track(function DebugMenuContent({
|
||||||
<DebugFlagToggle flag={debugFlags.debugSvg} />
|
<DebugFlagToggle flag={debugFlags.debugSvg} />
|
||||||
<DebugFlagToggle flag={debugFlags.forceSrgb} />
|
<DebugFlagToggle flag={debugFlags.forceSrgb} />
|
||||||
<DebugFlagToggle flag={debugFlags.debugGeometry} />
|
<DebugFlagToggle flag={debugFlags.debugGeometry} />
|
||||||
<DebugFlagToggle
|
<DebugFlagToggle flag={debugFlags.hideShapes} />
|
||||||
flag={debugFlags.debugCursors}
|
|
||||||
onChange={(enabled) => {
|
|
||||||
if (enabled) {
|
|
||||||
const MAX_COLUMNS = 5
|
|
||||||
const partials = CURSOR_NAMES.map((name, i) => {
|
|
||||||
return {
|
|
||||||
id: createShapeId(),
|
|
||||||
type: 'geo',
|
|
||||||
x: (i % MAX_COLUMNS) * 175,
|
|
||||||
y: Math.floor(i / MAX_COLUMNS) * 175,
|
|
||||||
props: {
|
|
||||||
text: name,
|
|
||||||
w: 150,
|
|
||||||
h: 150,
|
|
||||||
fill: 'semi',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
editor.createShapes(partials)
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</DropdownMenu.Group>
|
</DropdownMenu.Group>
|
||||||
<DropdownMenu.Group>
|
<DropdownMenu.Group>
|
||||||
{Object.values(featureFlags).map((flag) => {
|
{Object.values(featureFlags).map((flag) => {
|
||||||
|
@ -256,27 +233,6 @@ const DebugFlagToggle = track(function DebugFlagToggle({
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
const CURSOR_NAMES = [
|
|
||||||
'none',
|
|
||||||
'default',
|
|
||||||
'pointer',
|
|
||||||
'cross',
|
|
||||||
'move',
|
|
||||||
'grab',
|
|
||||||
'grabbing',
|
|
||||||
'text',
|
|
||||||
'ew-resize',
|
|
||||||
'ns-resize',
|
|
||||||
'nesw-resize',
|
|
||||||
'nwse-resize',
|
|
||||||
'nwse-rotate',
|
|
||||||
'nesw-rotate',
|
|
||||||
'senw-rotate',
|
|
||||||
'swne-rotate',
|
|
||||||
'zoom-in',
|
|
||||||
'zoom-out',
|
|
||||||
]
|
|
||||||
|
|
||||||
function ExampleDialog({
|
function ExampleDialog({
|
||||||
title = 'title',
|
title = 'title',
|
||||||
body = 'hello hello hello',
|
body = 'hello hello hello',
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Editor, compact, featureFlags, useEditor, useValue } from '@tldraw/editor'
|
import { Editor, compact, useEditor } from '@tldraw/editor'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { TLUiToolItem, TLUiToolsContextType, useTools } from './useTools'
|
import { TLUiToolItem, TLUiToolsContextType, useTools } from './useTools'
|
||||||
|
|
||||||
|
@ -41,7 +41,6 @@ export function ToolbarSchemaProvider({ overrides, children }: TLUiToolbarSchema
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
|
|
||||||
const tools = useTools()
|
const tools = useTools()
|
||||||
const highlighterEnabled = useValue(featureFlags.highlighterTool)
|
|
||||||
|
|
||||||
const toolbarSchema = React.useMemo<TLUiToolbarSchemaContextType>(() => {
|
const toolbarSchema = React.useMemo<TLUiToolbarSchemaContextType>(() => {
|
||||||
const schema: TLUiToolbarSchemaContextType = compact([
|
const schema: TLUiToolbarSchemaContextType = compact([
|
||||||
|
@ -72,7 +71,7 @@ export function ToolbarSchemaProvider({ overrides, children }: TLUiToolbarSchema
|
||||||
toolbarItem(tools['arrow-right']),
|
toolbarItem(tools['arrow-right']),
|
||||||
toolbarItem(tools.frame),
|
toolbarItem(tools.frame),
|
||||||
toolbarItem(tools.line),
|
toolbarItem(tools.line),
|
||||||
highlighterEnabled ? toolbarItem(tools.highlight) : null,
|
toolbarItem(tools.highlight),
|
||||||
toolbarItem(tools.laser),
|
toolbarItem(tools.laser),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -81,7 +80,7 @@ export function ToolbarSchemaProvider({ overrides, children }: TLUiToolbarSchema
|
||||||
}
|
}
|
||||||
|
|
||||||
return schema
|
return schema
|
||||||
}, [editor, highlighterEnabled, overrides, tools])
|
}, [editor, overrides, tools])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ToolbarSchemaContext.Provider value={toolbarSchema}>{children}</ToolbarSchemaContext.Provider>
|
<ToolbarSchemaContext.Provider value={toolbarSchema}>{children}</ToolbarSchemaContext.Provider>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Editor, GeoShapeGeoStyle, featureFlags, useEditor, useValue } from '@tldraw/editor'
|
import { Editor, GeoShapeGeoStyle, useEditor } from '@tldraw/editor'
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { EmbedDialog } from '../components/EmbedDialog'
|
import { EmbedDialog } from '../components/EmbedDialog'
|
||||||
import { TLUiIconType } from '../icon-types'
|
import { TLUiIconType } from '../icon-types'
|
||||||
|
@ -45,8 +45,6 @@ export function ToolsProvider({ overrides, children }: TLUiToolsProviderProps) {
|
||||||
const { addDialog } = useDialogs()
|
const { addDialog } = useDialogs()
|
||||||
const insertMedia = useInsertMedia()
|
const insertMedia = useInsertMedia()
|
||||||
|
|
||||||
const highlighterEnabled = useValue(featureFlags.highlighterTool)
|
|
||||||
|
|
||||||
const tools = React.useMemo<TLUiToolsContextType>(() => {
|
const tools = React.useMemo<TLUiToolsContextType>(() => {
|
||||||
const toolsArray: TLUiToolItem[] = [
|
const toolsArray: TLUiToolItem[] = [
|
||||||
{
|
{
|
||||||
|
@ -207,20 +205,18 @@ export function ToolsProvider({ overrides, children }: TLUiToolsProviderProps) {
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
if (highlighterEnabled) {
|
toolsArray.push({
|
||||||
toolsArray.push({
|
id: 'highlight',
|
||||||
id: 'highlight',
|
label: 'tool.highlight',
|
||||||
label: 'tool.highlight',
|
readonlyOk: true,
|
||||||
readonlyOk: true,
|
icon: 'tool-highlight',
|
||||||
icon: 'tool-highlight',
|
// TODO: pick a better shortcut
|
||||||
// TODO: pick a better shortcut
|
kbd: '!d',
|
||||||
kbd: '!d',
|
onSelect(source) {
|
||||||
onSelect(source) {
|
editor.setCurrentTool('highlight')
|
||||||
editor.setCurrentTool('highlight')
|
trackEvent('select-tool', { source, id: 'highlight' })
|
||||||
trackEvent('select-tool', { source, id: 'highlight' })
|
},
|
||||||
},
|
})
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const tools = Object.fromEntries(toolsArray.map((t) => [t.id, t]))
|
const tools = Object.fromEntries(toolsArray.map((t) => [t.id, t]))
|
||||||
|
|
||||||
|
@ -229,7 +225,7 @@ export function ToolsProvider({ overrides, children }: TLUiToolsProviderProps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return tools
|
return tools
|
||||||
}, [highlighterEnabled, overrides, editor, trackEvent, insertMedia, addDialog])
|
}, [overrides, editor, trackEvent, insertMedia, addDialog])
|
||||||
|
|
||||||
return <ToolsContext.Provider value={tools}>{children}</ToolsContext.Provider>
|
return <ToolsContext.Provider value={tools}>{children}</ToolsContext.Provider>
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue