tldraw/apps/examples/src/12-events/EventsExample.tsx
Steve Ruiz 03595bc88d
[improvement] Ui events followup (#1354)
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
2023-05-12 08:16:17 +00:00

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>
)
}