[improvement] rename onEvent to onUiEvent (#1358)
This PR: - renames `onEvent` to `onUiEvent` - adds docs for `onUiEvent` to the docs site - splits the `EventsExample` into `UiEventsExample` and `StoreEventsExample` ### Change Type - [x] `major` — Breaking Change ### Release Notes - [docs] Adds docs for ui events - [tldraw] Renames `onEvent` to `onUiEvent`
This commit is contained in:
parent
8b6b244194
commit
9ccd0f480f
7 changed files with 84 additions and 19 deletions
|
@ -15,6 +15,24 @@ keywords:
|
|||
- styles
|
||||
---
|
||||
|
||||
Coming soon.
|
||||
## Events
|
||||
|
||||
The `<Tldraw>` component has a prop, `onUiEvent`, that the user interface will call when certain events occur.
|
||||
|
||||
```tsx
|
||||
function Example() {
|
||||
function handleEvent(name, data) {
|
||||
// do something with the event
|
||||
}
|
||||
|
||||
return (
|
||||
<Tldraw onUiEvent={handleEvent}/>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
The `onUiEvent` callback is called with the name of the event as a string and an object with information about the event's source (e.g. `menu` or `context-menu`) and possibly other data specific to each event, such as the direction in an `align-shapes` event.
|
||||
|
||||
Note that `onUiEvent` is only called when interacting with the user interface. It is not called when running commands manually against the app, e.g. `app.alignShapes()` will not call `onUiEvent`.
|
||||
|
||||
See the [tldraw repository](https://github.com/tldraw/tldraw) for an example of how to customize tldraw's user interface.
|
||||
|
|
41
apps/examples/src/12-ui-events/UiEventsExample.tsx
Normal file
41
apps/examples/src/12-ui-events/UiEventsExample.tsx
Normal file
|
@ -0,0 +1,41 @@
|
|||
import { TLUiEventHandler, Tldraw } from '@tldraw/tldraw'
|
||||
import '@tldraw/tldraw/editor.css'
|
||||
import '@tldraw/tldraw/ui.css'
|
||||
import { useCallback, useState } from 'react'
|
||||
|
||||
export default function UiEventsExample() {
|
||||
const [uiEvents, setUiEvents] = useState<string[]>([])
|
||||
|
||||
const handleUiEvent = useCallback<TLUiEventHandler>((name, data) => {
|
||||
setUiEvents((events) => [`${name} ${JSON.stringify(data)}`, ...events])
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div style={{ display: 'flex' }}>
|
||||
<div style={{ width: '60vw', height: '100vh' }}>
|
||||
<Tldraw autoFocus onUiEvent={handleUiEvent} />
|
||||
</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>
|
||||
)
|
||||
}
|
|
@ -1,27 +1,22 @@
|
|||
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() {
|
||||
export default function StoreEventsExample() {
|
||||
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])
|
||||
}, [])
|
||||
const [storeEvents, setStoreEvents] = useState<string[]>([])
|
||||
|
||||
useEffect(() => {
|
||||
if (!app) return
|
||||
|
||||
function logChangeEvent(eventName: string) {
|
||||
setUiEvents((events) => [eventName, ...events])
|
||||
setStoreEvents((events) => [eventName, ...events])
|
||||
}
|
||||
|
||||
// This is the fire hose, it will be called at the end of every transaction
|
||||
|
@ -64,7 +59,7 @@ export default function Example() {
|
|||
return (
|
||||
<div style={{ display: 'flex' }}>
|
||||
<div style={{ width: '60vw', height: '100vh' }}>
|
||||
<Tldraw autoFocus onMount={setAppToState} onEvent={handleEvent} />
|
||||
<Tldraw autoFocus onMount={setAppToState} />
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
|
@ -82,7 +77,7 @@ export default function Example() {
|
|||
overflow: 'auto',
|
||||
}}
|
||||
>
|
||||
{uiEvents.map((t, i) => (
|
||||
{storeEvents.map((t, i) => (
|
||||
<div key={i}>{t}</div>
|
||||
))}
|
||||
</div>
|
|
@ -11,7 +11,8 @@ import { RouterProvider, createBrowserRouter } from 'react-router-dom'
|
|||
import ExampleBasic from './1-basic/BasicExample'
|
||||
import CustomComponentsExample from './10-custom-components/CustomComponentsExample'
|
||||
import UserPresenceExample from './11-user-presence/UserPresenceExample'
|
||||
import EventsExample from './12-events/EventsExample'
|
||||
import UiEventsExample from './12-ui-events/UiEventsExample'
|
||||
import StoreEventsExample from './13-store/StoreEventsExample'
|
||||
import ExampleApi from './2-api/APIExample'
|
||||
import CustomConfigExample from './3-custom-config/CustomConfigExample'
|
||||
import CustomUiExample from './4-custom-ui/CustomUiExample'
|
||||
|
@ -73,8 +74,12 @@ export const allExamples: Example[] = [
|
|||
element: <CustomComponentsExample />,
|
||||
},
|
||||
{
|
||||
path: '/events',
|
||||
element: <EventsExample />,
|
||||
path: '/ui-events',
|
||||
element: <UiEventsExample />,
|
||||
},
|
||||
{
|
||||
path: '/store-events',
|
||||
element: <StoreEventsExample />,
|
||||
},
|
||||
{
|
||||
path: '/user-presence',
|
||||
|
|
|
@ -636,7 +636,7 @@ export const TldrawUi: React_2.NamedExoticComponent<{
|
|||
export const TldrawUiContent: React_2.NamedExoticComponent<TldrawUiContentProps>;
|
||||
|
||||
// @public (undocumented)
|
||||
export function TldrawUiContextProvider({ overrides, assetUrls, onEvent, children, }: TldrawUiContextProviderProps): JSX.Element;
|
||||
export function TldrawUiContextProvider({ overrides, assetUrls, onUiEvent, children, }: TldrawUiContextProviderProps): JSX.Element;
|
||||
|
||||
// @public (undocumented)
|
||||
export interface TldrawUiContextProviderProps {
|
||||
|
@ -645,7 +645,7 @@ export interface TldrawUiContextProviderProps {
|
|||
// (undocumented)
|
||||
children?: any;
|
||||
// (undocumented)
|
||||
onEvent?: TLUiEventHandler;
|
||||
onUiEvent?: TLUiEventHandler;
|
||||
// (undocumented)
|
||||
overrides?: TldrawUiOverrides | TldrawUiOverrides[];
|
||||
}
|
||||
|
@ -728,6 +728,11 @@ export type TLTranslationMessages = Record<TLTranslationKey, string>;
|
|||
// @public (undocumented)
|
||||
export type TLTranslations = TLTranslation[];
|
||||
|
||||
// @public (undocumented)
|
||||
export type TLUiEventHandler<T extends keyof TLUiEventMap = keyof TLUiEventMap> = (name: T, data: Join<{
|
||||
source: TLUiEventSource;
|
||||
}, TLUiEventMap[T]>) => void;
|
||||
|
||||
// @public (undocumented)
|
||||
export type TLUiIconType = 'align-bottom-center' | 'align-bottom-left' | 'align-bottom-right' | 'align-bottom' | 'align-center-center' | 'align-center-horizontal' | 'align-center-left' | 'align-center-right' | 'align-center-vertical' | 'align-left' | 'align-right' | 'align-top-center' | 'align-top-left' | 'align-top-right' | 'align-top' | 'arrow-left' | 'arrowhead-arrow' | 'arrowhead-bar' | 'arrowhead-diamond' | 'arrowhead-dot' | 'arrowhead-none' | 'arrowhead-square' | 'arrowhead-triangle-inverted' | 'arrowhead-triangle' | 'aspect-ratio' | 'avatar' | 'blob' | 'bring-forward' | 'bring-to-front' | 'check' | 'checkbox-checked' | 'checkbox-empty' | 'chevron-down' | 'chevron-left' | 'chevron-right' | 'chevron-up' | 'chevrons-ne' | 'chevrons-sw' | 'clipboard-copy' | 'code' | 'collab' | 'color' | 'comment' | 'cross-2' | 'cross' | 'dash-dashed' | 'dash-dotted' | 'dash-draw' | 'dash-solid' | 'discord' | 'distribute-horizontal' | 'distribute-vertical' | 'dot' | 'dots-horizontal' | 'dots-vertical' | 'drag-handle-dots' | 'duplicate' | 'edit' | 'external-link' | 'file' | 'fill-none' | 'fill-pattern' | 'fill-semi' | 'fill-solid' | 'follow' | 'following' | 'font-draw' | 'font-mono' | 'font-sans' | 'font-serif' | 'geo-arrow-down' | 'geo-arrow-left' | 'geo-arrow-right' | 'geo-arrow-up' | 'geo-check-box' | 'geo-diamond' | 'geo-ellipse' | 'geo-hexagon' | 'geo-octagon' | 'geo-oval' | 'geo-pentagon' | 'geo-rectangle' | 'geo-rhombus-2' | 'geo-rhombus' | 'geo-star' | 'geo-trapezoid' | 'geo-triangle' | 'geo-x-box' | 'github' | 'group' | 'hidden' | 'image' | 'info-circle' | 'leading' | 'link' | 'lock-small' | 'lock' | 'menu' | 'minus' | 'mixed' | 'pack' | 'page' | 'plus' | 'question-mark-circle' | 'question-mark' | 'redo' | 'reset-zoom' | 'rotate-ccw' | 'rotate-cw' | 'ruler' | 'search' | 'send-backward' | 'send-to-back' | 'settings-horizontal' | 'settings-vertical-1' | 'settings-vertical' | 'share-1' | 'share-2' | 'size-extra-large' | 'size-large' | 'size-medium' | 'size-small' | 'spline-cubic' | 'spline-line' | 'stack-horizontal' | 'stack-vertical' | 'stretch-horizontal' | 'stretch-vertical' | 'text-align-center' | 'text-align-justify' | 'text-align-left' | 'text-align-right' | 'tool-arrow' | 'tool-embed' | 'tool-eraser' | 'tool-frame' | 'tool-hand' | 'tool-highlighter' | 'tool-line' | 'tool-media' | 'tool-note' | 'tool-pencil' | 'tool-pointer' | 'tool-text' | 'trash' | 'triangle-down' | 'triangle-up' | 'twitter' | 'undo' | 'ungroup' | 'unlock-small' | 'unlock' | 'visible' | 'warning-triangle' | 'zoom-in' | 'zoom-out';
|
||||
|
||||
|
|
|
@ -79,6 +79,7 @@ export {
|
|||
type DialogsProviderProps,
|
||||
type TLDialog,
|
||||
} from './lib/hooks/useDialogsProvider'
|
||||
export { type TLUiEventHandler } from './lib/hooks/useEventsProvider'
|
||||
export { useExportAs } from './lib/hooks/useExportAs'
|
||||
export {
|
||||
HelpMenuSchemaContext,
|
||||
|
|
|
@ -19,7 +19,7 @@ import { TldrawUiOverrides, useMergedOverrides, useMergedTranslationOverrides }
|
|||
export interface TldrawUiContextProviderProps {
|
||||
assetUrls?: UiAssetUrls
|
||||
overrides?: TldrawUiOverrides | TldrawUiOverrides[]
|
||||
onEvent?: TLUiEventHandler
|
||||
onUiEvent?: TLUiEventHandler
|
||||
children?: any
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ export interface TldrawUiContextProviderProps {
|
|||
export function TldrawUiContextProvider({
|
||||
overrides,
|
||||
assetUrls,
|
||||
onEvent,
|
||||
onUiEvent,
|
||||
children,
|
||||
}: TldrawUiContextProviderProps) {
|
||||
return (
|
||||
|
@ -36,7 +36,7 @@ export function TldrawUiContextProvider({
|
|||
<ToastsProvider>
|
||||
<DialogsProvider>
|
||||
<BreakPointProvider>
|
||||
<EventsProvider onEvent={onEvent}>
|
||||
<EventsProvider onEvent={onUiEvent}>
|
||||
<InternalProviders overrides={overrides}>{children}</InternalProviders>
|
||||
</EventsProvider>
|
||||
</BreakPointProvider>
|
||||
|
|
Loading…
Reference in a new issue