import { App, debugFlags, hardResetApp, TLShapePartial, uniqueId, useApp } from '@tldraw/editor'
import * as React from 'react'
import { track, useValue } from 'signia-react'
import { useDialogs } from '../hooks/useDialogsProvider'
import { useToasts } from '../hooks/useToastsProvider'
import { useTranslation } from '../hooks/useTranslation/useTranslation'
import { Button } from './primitives/Button'
import * as Dialog from './primitives/Dialog'
import * as DropdownMenu from './primitives/DropdownMenu'
let t = 0
function createNShapes(app: App, n: number) {
const shapesToCreate: TLShapePartial[] = Array(n)
const cols = Math.floor(Math.sqrt(n))
for (let i = 0; i < n; i++) {
t++
shapesToCreate[i] = {
id: app.createShapeId('box' + t),
type: 'geo',
x: (i % cols) * 132,
y: Math.floor(i / cols) * 132,
}
}
app.batch(() => {
app.createShapes(shapesToCreate).setSelectedIds(shapesToCreate.map((s) => s.id))
})
}
/** @public */
export const DebugPanel = React.memo(function DebugPanel({
renderDebugMenuItems,
}: {
renderDebugMenuItems: (() => React.ReactNode) | null
}) {
const msg = useTranslation()
return (
)
})
const CurrentState = track(function CurrentState() {
const app = useApp()
return {app.root.path.value}
})
const ShapeCount = function ShapeCount() {
const app = useApp()
const count = useValue('rendering shapes count', () => app.renderingShapes.length, [app])
return {count} Shapes
}
function DebugMenuContent({
renderDebugMenuItems,
}: {
renderDebugMenuItems: (() => React.ReactNode) | null
}) {
const app = useApp()
const { addToast } = useToasts()
const { addDialog } = useDialogs()
const [error, setError] = React.useState(false)
return (
<>
{
addToast({
id: uniqueId(),
title: 'Something happened',
description: 'Hey, attend to this thing over here. It might be important!',
// icon?: string
// title?: string
// description?: string
// actions?: TLToastAction[]
})
}}
>
Show toast
{
addDialog({
component: ({ onClose }) => (
{
onClose()
}}
onContinue={() => {
onClose()
}}
/>
),
onClose: () => {
void null
},
})
}}
>
Show dialog
createNShapes(app, 100)}>
Create 100 shapes
{
function countDescendants({ children }: HTMLElement) {
let count = 0
if (!children.length) return 0
for (const el of [...(children as any)]) {
count++
count += countDescendants(el)
}
return count
}
const { selectedShapes } = app
const shapes = selectedShapes.length === 0 ? app.renderingShapes : selectedShapes
const elms = shapes.map(
(shape) => (document.getElementById(shape.id) as HTMLElement)!.parentElement!
)
let descendants = elms.length
for (const elm of elms) {
descendants += countDescendants(elm)
}
window.alert(`Shapes ${shapes.length}, DOM nodes:${descendants}`)
}}
>
Count shapes and nodes
{(() => {
if (error) throw Error('oh no!')
})()}
{
setError(true)
}}
>
Throw error
{
hardResetApp()
}}
>
Hard reset
{
debugFlags.peopleMenu.set(!debugFlags.peopleMenu.value)
window.location.reload()
}}
>
Toggle people menu
{
// We need to do this manually because `updateUserDocumentSettings` does not allow toggling `isReadOnly`)
app.setReadOnly(!app.isReadOnly)
}}
>
Toggle read-only
{renderDebugMenuItems?.()}
>
)
}
function ExampleDialog({
title = 'title',
body = 'hello hello hello',
cancel = 'Cancel',
confirm = 'Continue',
displayDontShowAgain = false,
onCancel,
onContinue,
}: {
title?: string
body?: string
cancel?: string
confirm?: string
displayDontShowAgain?: boolean
onCancel: () => void
onContinue: () => void
}) {
const [dontShowAgain, setDontShowAgain] = React.useState(false)
return (
<>
{title}
{body}
{displayDontShowAgain && (
)}
>
)
}