
This PR makes several changes to the ui events APIs. ### Change Type - [ ] `patch` — Bug Fix - [ ] `minor` — New Feature - [x] `major` — Breaking Change ### Release Notes - [ui] Adds source to ui events data object - [ui] Corrects source for toolbar events - [ui] Corrects source for clipboard events - [examples] Updates events example
92 lines
2.3 KiB
TypeScript
92 lines
2.3 KiB
TypeScript
import { App, TLEventMapHandler, Tldraw } from '@tldraw/tldraw'
|
|
import '@tldraw/tldraw/editor.css'
|
|
import '@tldraw/tldraw/ui.css'
|
|
import { TLUiEventHandler } from '@tldraw/ui/src/lib/hooks/useEventsProvider'
|
|
import { useCallback, useEffect, useState } from 'react'
|
|
|
|
export default function Example() {
|
|
const [app, setApp] = useState<App>()
|
|
|
|
const setAppToState = useCallback((app: App) => {
|
|
setApp(app)
|
|
}, [])
|
|
|
|
const [uiEvents, setUiEvents] = useState<string[]>([])
|
|
|
|
const handleEvent = useCallback<TLUiEventHandler>((name, data) => {
|
|
setUiEvents((events) => [`${name} ${JSON.stringify(data)}`, ...events])
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
if (!app) return
|
|
|
|
function logChangeEvent(eventName: string) {
|
|
setUiEvents((events) => [eventName, ...events])
|
|
}
|
|
|
|
// This is the fire hose, it will be called at the end of every transaction
|
|
const handleChangeEvent: TLEventMapHandler<'change'> = (change) => {
|
|
if (change.source === 'user') {
|
|
// Added
|
|
for (const record of Object.values(change.changes.added)) {
|
|
if (record.typeName === 'shape') {
|
|
logChangeEvent(`created shape (${record.type})`)
|
|
}
|
|
}
|
|
|
|
// Updated
|
|
for (const [from, to] of Object.values(change.changes.updated)) {
|
|
if (
|
|
from.typeName === 'instance' &&
|
|
to.typeName === 'instance' &&
|
|
from.currentPageId !== to.currentPageId
|
|
) {
|
|
logChangeEvent(`changed page (${from.currentPageId}, ${to.currentPageId})`)
|
|
}
|
|
}
|
|
|
|
// Removed
|
|
for (const record of Object.values(change.changes.removed)) {
|
|
if (record.typeName === 'shape') {
|
|
logChangeEvent(`deleted shape (${record.type})`)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
app.on('change', handleChangeEvent)
|
|
|
|
return () => {
|
|
app.off('change', handleChangeEvent)
|
|
}
|
|
}, [app])
|
|
|
|
return (
|
|
<div style={{ display: 'flex' }}>
|
|
<div style={{ width: '60vw', height: '100vh' }}>
|
|
<Tldraw autoFocus onMount={setAppToState} onEvent={handleEvent} />
|
|
</div>
|
|
<div>
|
|
<div
|
|
style={{
|
|
width: '40vw',
|
|
height: '100vh',
|
|
padding: 8,
|
|
background: '#eee',
|
|
border: 'none',
|
|
fontFamily: 'monospace',
|
|
fontSize: 12,
|
|
borderLeft: 'solid 2px #333',
|
|
display: 'flex',
|
|
flexDirection: 'column-reverse',
|
|
overflow: 'auto',
|
|
}}
|
|
>
|
|
{uiEvents.map((t, i) => (
|
|
<div key={i}>{t}</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|