From 417cd334c32efe98b606e372768ac9e1a08ddf86 Mon Sep 17 00:00:00 2001 From: Steve Ruiz Date: Thu, 22 Feb 2024 18:40:10 +0000 Subject: [PATCH] more content --- .../components/mdx-components/generic.tsx | 3 +- apps/docs/content/docs/user-interface.mdx | 107 +-- .../content/getting-started/installation.mdx | 130 ++- apps/docs/content/getting-started/tips.mdx | 129 --- .../content/getting-started/tldraw-usage.mdx | 50 ++ apps/docs/styles/globals.css | 8 +- packages/editor/api-report.md | 5 +- packages/editor/api/api.json | 13 +- packages/editor/src/lib/TldrawEditor.tsx | 32 +- packages/tldraw/api-report.md | 137 ++- packages/tldraw/api/api.json | 828 +++++++++++++++++- packages/tldraw/src/lib/Tldraw.tsx | 4 +- packages/tldraw/src/lib/ui/TldrawUi.tsx | 16 +- 13 files changed, 1199 insertions(+), 263 deletions(-) delete mode 100644 apps/docs/content/getting-started/tips.mdx create mode 100644 apps/docs/content/getting-started/tldraw-usage.mdx diff --git a/apps/docs/components/mdx-components/generic.tsx b/apps/docs/components/mdx-components/generic.tsx index 277c4cd9f..f298ab46f 100644 --- a/apps/docs/components/mdx-components/generic.tsx +++ b/apps/docs/components/mdx-components/generic.tsx @@ -1,5 +1,4 @@ import React from 'react' -import { Icon } from '../Icon' /* ---------------------- Lists --------------------- */ @@ -168,7 +167,7 @@ export const Embed = (props: any) => { export const Callout = ({ icon, children }: any) => { return (
- + {icon}

{children}

) diff --git a/apps/docs/content/docs/user-interface.mdx b/apps/docs/content/docs/user-interface.mdx index 8cbabcb20..45509219f 100644 --- a/apps/docs/content/docs/user-interface.mdx +++ b/apps/docs/content/docs/user-interface.mdx @@ -1,5 +1,5 @@ --- -title: User Interface +title: User interface status: published author: steveruizok date: 3/22/2023 @@ -39,6 +39,27 @@ All of our user interface works by controlling the editor via its `Editor` metho The source for these examples are available in the [tldraw repository](https://github.com/tldraw/tldraw/blob/main/apps/examples/src) or in a [sandbox here](https://stackblitz.com/github/tldraw/tldraw/tree/examples?file=src%2Findex.tsx). +## 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 +} +``` + +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. calling [Editor#alignShapes](?) will not call `onUiEvent`. + +See the [tldraw repository](https://github.com/tldraw/tldraw/tree/main/apps/examples) for an example of how to customize tldraw's user interface. + + ## Overrides The content of tldraw's menus can be controlled via the `overrides` prop. This prop accepts a [TLUiOverrides](/reference/tldraw/TLUiOverrides) object, which has methods for each part of the user interface, such as the `toolbar` or `keyboardShortcutsMenu`. @@ -99,70 +120,6 @@ const myOverrides: TLUiOverrides = { The `tools` object is a map of [TLUiToolItem](/reference/tldraw/TLUiToolItem)s, with each item keyed under its `id`. -### Toolbar and Menus - -The remaining overrides are for toolbar and the various menus: the main menu, actions menu, context menu, help menu, and the keyboard shortcuts menu. - -Each of these overrides accepts a method that receives the default menu schema and returns a mutated version of that schema. - -```ts -const myOverrides: TLUiOverrides = { - actions(editor, actions) { - // Create a new action or replace an existing one - actions['my-new-action'] = { - id: 'my-new-action', - label: 'My new action', - readonlyOk: true, - kbd: '$u', - onSelect(source: any) { - window.alert('My new action just happened!') - }, - } - return actions - }, - contextMenu(editor, contextMenu, { actions }) { - const newMenuItem = menuItem(actions['my-new-action']) - const newMenuGroup = menuGroup('my-items', newMenuItem) - contextMenu.unshift(newMenuItem) - return contextMenu - }, - menu(editor, menu, { actions }) { - // using the findMenuItem helper - const fileMenu = findMenuItem(menu, ['menu', 'file']) - if (fileMenu.type === 'submenu') { - // add the new item to the file menu's children - const newMenuItem = menuItem(actions['my-new-action']) - fileMenu.children.unshift(newMenuItem) - } - return menu - }, -} -``` - -A menu schema is an array of either [submenus](/reference/tldraw/TLUiSubMenu), [groups](/reference/tldraw/TLUiMenuGroup), [items](/reference/tldraw/TLUiMenuItem), or [custom items](/reference/tldraw/TLUiCustomMenuItem). Each group or submenu may include any of the other types as its children. - -The menu schema is stateful. Referencing atomic properties (such as computed values in the editor) will cause the menu to update when those values change. If you wish for a menu item to disappear from the menu, you can return `null` from the menu method. You can also provide additional options for each item, `disabled` or `checked`. - -```ts -const myOverrides: TLUiOverrides = { - menu(editor, menu, { actions }) { - const selectedShapes = editor.getSelectedShapeIds().length - - const newMenuGroup = menuGroup( - 'my-actions', - selectedShapes > 0 ? menuItem(actions['action-a']) : null, - menuItem(actions['action-b'], { disabled: selectedShapes < 3 }) - ) - - menu.unshift(newMenuGroup) - - return menu - }, -} -``` - -It's recommmended to explore the [default menu schema](https://github.com/tldraw/tldraw/blob/main/packages/tldraw/src/lib/ui/hooks/useMenuSchema.tsx) in order to understand how menu items work. - ### Translations The `translations` method accepts a table of new translations. For example, if you wanted a tool to reference a key `"tools.card"`, then you should at minimum provide an english translation for this key. @@ -176,23 +133,3 @@ const myOverrides: TLUiOverrides = { }, } ``` - -## 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 -} -``` - -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. calling [Editor#alignShapes](?) will not call `onUiEvent`. - -See the [tldraw repository](https://github.com/tldraw/tldraw/tree/main/apps/examples) for an example of how to customize tldraw's user interface. diff --git a/apps/docs/content/getting-started/installation.mdx b/apps/docs/content/getting-started/installation.mdx index 72af1960f..aaf554ce1 100644 --- a/apps/docs/content/getting-started/installation.mdx +++ b/apps/docs/content/getting-started/installation.mdx @@ -10,7 +10,7 @@ Install the `@tldraw/tldraw` package from [NPM](https://npmjs.com/tldraw/tldraw) -You can use the [Tldraw](?) component inside of any React component. +Use the [Tldraw](?) component inside of any React component. ```tsx import { Tldraw } from '@tldraw/tldraw' @@ -25,4 +25,130 @@ export default function () { } ``` -> 🙋‍♂️ Using tldraw in a framework like Vite or Next.js ? Visit our [framework examples repository](https://github.com/tldraw/examples) to see examples of tldraw being used in various frameworks. \ No newline at end of file +> 🙋‍♂️ Using tldraw in a framework like Vite or Next.js ? Visit our [framework examples repository](https://github.com/tldraw/examples) to see examples of how you can use tldraw in your favorite framework. + +--- + +## More info on installation + +The [Tldraw](?) component has a few requirements and best practices to keep in mind when using it in your app. This article will walk you through the necessary steps to get started. + + +### CSS + +The [Tldraw](?) component relies on CSS for styling. Depending on your framework or build system, you can import these in a JavaScript file: + +```tsx +import '@tldraw/tldraw/tldraw.css' +``` + +...or from inside of another CSS file using the `@import` syntax: + +```css +@import url('@tldraw/tldraw/tldraw.css'); +``` + +Want to change how tldraw looks? You can always use your own CSS. Make a new CSS file in your project, copy the contents of our `tldraw.css` file, make your changes, and import your file instead. + +### Wrapper element + +You must wrap the [Tldraw](?) component in a parent container with a known size. The component's own height and width are set to `100%`, so it will fill its parent container. + +```tsx +export function Example() { + return ( +
+ +
+ ) +} +``` + +### Viewport + +If you're using the [Tldraw](?) component in a full-screen app, you may also want to update your `index.html`'s meta viewport element with the following properties: + +```html + +``` + +### Fonts + +The tldraw component's user interface will inherit the page's body font. If you'd like to use the same font that we use on [tldraw.com](https://tldraw.com), import the [Inter font](https://github.com/rsms/inter) from Google fonts: + +```css +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap'); +``` + + +### Server Rendering + +The [Tldraw](?) component can't be server-rendered. If you're using the component in a server-rendered framework (such as Next.js) then you need to import it dynamically. + +```tsx +const Tldraw = dynamic(async () => (await import('@tldraw/tldraw')).Tldraw, { ssr: false }) +``` + +See our [framework examples repository](https://github.com/tldraw/examples) for an example. + +## Static Assets + +In order to use the [Tldraw](?) component, the app must be able to find certain assets. These are contained in the `embed-icons`, `fonts`, `icons`, and `translations` folders. We offer a few different ways of making these assets available to your app. + +### Using a public CDN + +By default we serve these assets from a [public CDN called unpkg](https://unpkg.com/browse/@tldraw/assets@2.0.0-alpha.12/), so everything should work out of the box and is a good way to get started. + +If you would like to customize some of the assets you can pass the customizations to our [Tldraw](?) component. For example, to use a custom icon for the `hand` tool you can do the following: + +```tsx +const assetUrls = { + icons: { + 'tool-hand': './custom-tool-hand.svg', + }, +} + + +``` + +This will use the custom icon for the `hand` tool and the default assets for everything else. + +### Using a bundler + +If you're using a bundler like webpack or rollup, you can import the assets directly from the `@tldraw/assets` package. Here you can use `getAssetUrlsByMetaUrl` helper function: + +```tsx +import { getAssetUrlsByMetaUrl } from '@tldraw/assets/urls' + +const assetUrls = getAssetUrlsByMetaUrl() + + +``` + +### Self-hosting static assets + +If you want more flexibility you can also host these assets yourself: + +1. Download the `embed-icons`, `fonts`, `icons`, and `translations` folders from the [assets folder](https://github.com/tldraw/tldraw/tree/main/assets) of the tldraw repository. +2. Place the folders in your project's public path. +3. Pass `assetUrls` prop to our `` component to let the component know where the assets live. + +You can use our `getAssetUrls` helper function from the `@tldraw/assets` package to generate these urls for you. + +```tsx +import { getAssetUrls } from '@tldraw/assets/selfHosted' + +const assetUrls = getAssetUrls() + + +``` + +While these files must be available, you can overwrite the individual files. For example, to change our icons, you can place a new icon under the same name. You can also modify translations in this same way. + +If you use a CDN for hosting these files you can specify the base url of your assets. To recreate the above option of serving the assets from unpkg you would do the following: + +```ts +const assetUrls = getAssetUrls({ + baseUrl: 'https://unpkg.com/@tldraw/assets@2.0.0-alpha.12/', +}) +``` diff --git a/apps/docs/content/getting-started/tips.mdx b/apps/docs/content/getting-started/tips.mdx deleted file mode 100644 index b1ee19e4e..000000000 --- a/apps/docs/content/getting-started/tips.mdx +++ /dev/null @@ -1,129 +0,0 @@ ---- -title: Advanced -status: published -author: steveruizok -date: 3/22/2023 -order: 3 ---- - -The tldraw SDK is designed to let you configure its user interface, extend its features, and control with JavaScript. This article contains notes on using the component in your project. - - -### CSS - -The [Tldraw](?) component relies on CSS for styling. Depending on your framework or build system, you can import these in a JavaScript file: - -```tsx -import '@tldraw/tldraw/tldraw.css' -``` - -...or from inside of another CSS file using the `@import` syntax: - -```css -@import url('@tldraw/tldraw/tldraw.css'); -``` - -Want to change how tldraw looks? You can always use your own CSS. Make a new CSS file in your project, copy the contents of our `tldraw.css` file, make your changes, and import your file instead. - -### Wrapper element - -You must wrap the [Tldraw](?) component in a parent container with a known size. The component's own height and width are set to `100%`, so it will fill its parent container. - -```tsx -export function Example() { - return ( -
- -
- ) -} -``` - -### Viewport - -If you're using the [Tldraw](?) component in a full-screen app, you may also want to update your `index.html`'s meta viewport element with the following properties: - -```html - -``` - -### Fonts - -The tldraw component's user interface will inherit the page's body font. If you'd like to use the same font that we use on [tldraw.com](https://tldraw.com), import the [Inter font](https://github.com/rsms/inter) from Google fonts: - -```css -@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap'); -``` - - -### Server Rendering - -The [Tldraw](?) component can't be server-rendered. If you're using the component in a server-rendered framework (such as Next.js) then you need to import it dynamically. - -```tsx -const Tldraw = dynamic(async () => (await import('@tldraw/tldraw')).Tldraw, { ssr: false }) -``` - -See our [framework examples repository](https://github.com/tldraw/examples) for an example. - -## Static Assets - -In order to use the [Tldraw](?) component, the app must be able to find certain assets. These are contained in the `embed-icons`, `fonts`, `icons`, and `translations` folders. We offer a few different ways of making these assets available to your app. - -### Using a public CDN - -By default we serve these assets from a [public CDN called unpkg](https://unpkg.com/browse/@tldraw/assets@2.0.0-alpha.12/), so everything should work out of the box and is a good way to get started. - -If you would like to customize some of the assets you can pass the customizations to our [Tldraw](?) component. For example, to use a custom icon for the `hand` tool you can do the following: - -```tsx -const assetUrls = { - icons: { - 'tool-hand': './custom-tool-hand.svg', - }, -} - - -``` - -This will use the custom icon for the `hand` tool and the default assets for everything else. - -### Using a bundler - -If you're using a bundler like webpack or rollup, you can import the assets directly from the `@tldraw/assets` package. Here you can use `getAssetUrlsByMetaUrl` helper function: - -```tsx -import { getAssetUrlsByMetaUrl } from '@tldraw/assets/urls' - -const assetUrls = getAssetUrlsByMetaUrl() - - -``` - -### Self-hosting static assets - -If you want more flexibility you can also host these assets yourself: - -1. Download the `embed-icons`, `fonts`, `icons`, and `translations` folders from the [assets folder](https://github.com/tldraw/tldraw/tree/main/assets) of the tldraw repository. -2. Place the folders in your project's public path. -3. Pass `assetUrls` prop to our `` component to let the component know where the assets live. - -You can use our `getAssetUrls` helper function from the `@tldraw/assets` package to generate these urls for you. - -```tsx -import { getAssetUrls } from '@tldraw/assets/selfHosted' - -const assetUrls = getAssetUrls() - - -``` - -While these files must be available, you can overwrite the individual files. For example, to change our icons, you can place a new icon under the same name. You can also modify translations in this same way. - -If you use a CDN for hosting these files you can specify the base url of your assets. To recreate the above option of serving the assets from unpkg you would do the following: - -```ts -const assetUrls = getAssetUrls({ - baseUrl: 'https://unpkg.com/@tldraw/assets@2.0.0-alpha.12/', -}) -``` diff --git a/apps/docs/content/getting-started/tldraw-usage.mdx b/apps/docs/content/getting-started/tldraw-usage.mdx new file mode 100644 index 000000000..0bb275c12 --- /dev/null +++ b/apps/docs/content/getting-started/tldraw-usage.mdx @@ -0,0 +1,50 @@ +--- +title: Usage +status: published +author: steveruizok +date: 3/22/2023 +order: 3 +--- + +The [Tldraw](?) component is designed to be customized and extended. It combines several other elements: +- a canvas to render shapes, controls, and overlays +- a user interface that provides tools for working with the canvas +- an [Editor](?) instance that controls the state and handles events + +> 🙋‍♂️ There's a lot you can do with the [Tldraw](?) component. The best way to learn is through our [examples](/examples), which demonstrate how different props and techniques can be used together. + +## Props + +You can configure the [Tldraw](?) component via its props. See the [TldrawProps](?) page for a full reference. + +#### `onMount` + +The `onMount` prop accepts a callback that will be fired when the component is mounted. The callback will be passed the [Editor](?) instance as its first argument. + +#### `persistenceKey` + +When you provide a `persistenceKey`, the state of the editor will be saved locally. It will also be syncronized between tabs, so that any window with the editor open will have its state kept in sync. See the [Persistence](/docs/persistence) page for more information. + +#### `snapshot` + +You can use the `snapshot` prop to set the initial data for the editor. This can be useful for loading a saved state, or for initializing the editor with a specific set of shapes. See [persistence](/docs/persistence) page for more information. + +#### `forceMobile` + +The `forceMobile` prop will force the editor to use the mobile layout, regardless of the user's device. This can be useful for testing the mobile layout on a desktop device. + +#### `hideUi` + +If you want to hide the user interface completely, set the `hideUi` prop to `true`. + +#### `components` + +If you want to change the way that the [Tldraw](?) component's user interface looks or behaves, you can provide overrides for the various components that it uses. See the [User Interface](/docs/user-interface) section for more information. + +#### `onUiEvent` + +The `onUiEvent` prop accepts a callback that is called when a user interacts with the user interface. See the [User Interface](/docs/user-interface#events) section for more information. + +#### `store` + +For advanced cases, you can provide the [Tldraw](?) component with a custom [Store](?) via its `store` prop. This can be useful for cases where you want to load data into a store asynchronously and then pass it to the editor. \ No newline at end of file diff --git a/apps/docs/styles/globals.css b/apps/docs/styles/globals.css index 15d6f1121..a574f6e2c 100644 --- a/apps/docs/styles/globals.css +++ b/apps/docs/styles/globals.css @@ -465,8 +465,9 @@ body { .article > blockquote { max-width: 100%; margin: 20px 0px; - padding-left: 16px; - border-left: 2px solid var(--color-tint-2); + padding: 16px; + border-radius: var(--border-radius-menu); + background-color: var(--color-tint-0); } .article pre { @@ -513,8 +514,7 @@ body { color: var(--color-text); } -.article ol h3, -.article ol li::marker { +.article ol h3 { font-size: 1.17em; line-height: 28px; } diff --git a/packages/editor/api-report.md b/packages/editor/api-report.md index 79e28713a..b9a72fc86 100644 --- a/packages/editor/api-report.md +++ b/packages/editor/api-report.md @@ -15,6 +15,7 @@ import { computed } from '@tldraw/state'; import { EmbedDefinition } from '@tldraw/tlschema'; import { EMPTY_ARRAY } from '@tldraw/state'; import { EventEmitter } from 'eventemitter3'; +import { Expand } from '@tldraw/utils'; import { HistoryEntry } from '@tldraw/store'; import { IndexKey } from '@tldraw/utils'; import { JsonObject } from '@tldraw/utils'; @@ -2031,7 +2032,7 @@ export interface TldrawEditorBaseProps { } // @public -export type TldrawEditorProps = TldrawEditorBaseProps & ({ +export type TldrawEditorProps = Expand; // @public (undocumented) export type TLEditorComponents = Partial<{ diff --git a/packages/editor/api/api.json b/packages/editor/api/api.json index 3802abd40..32a5c40d9 100644 --- a/packages/editor/api/api.json +++ b/packages/editor/api/api.json @@ -36448,6 +36448,15 @@ "kind": "Content", "text": "export type TldrawEditorProps = " }, + { + "kind": "Reference", + "text": "Expand", + "canonicalReference": "@tldraw/utils!Expand:type" + }, + { + "kind": "Content", + "text": "<" + }, { "kind": "Reference", "text": "TldrawEditorBaseProps", @@ -36509,7 +36518,7 @@ }, { "kind": "Content", - "text": ">;\n persistenceKey?: string;\n sessionId?: string;\n defaultName?: string;\n})" + "text": ">;\n persistenceKey?: string;\n sessionId?: string;\n defaultName?: string;\n})>" }, { "kind": "Content", @@ -36521,7 +36530,7 @@ "name": "TldrawEditorProps", "typeTokenRange": { "startIndex": 1, - "endIndex": 15 + "endIndex": 17 } }, { diff --git a/packages/editor/src/lib/TldrawEditor.tsx b/packages/editor/src/lib/TldrawEditor.tsx index fff13cf47..a42db8b12 100644 --- a/packages/editor/src/lib/TldrawEditor.tsx +++ b/packages/editor/src/lib/TldrawEditor.tsx @@ -1,6 +1,6 @@ import { SerializedStore, Store, StoreSnapshot } from '@tldraw/store' import { TLRecord, TLStore } from '@tldraw/tlschema' -import { Required, annotateError } from '@tldraw/utils' +import { Expand, Required, annotateError } from '@tldraw/utils' import React, { memo, useCallback, @@ -41,20 +41,22 @@ import { TLStoreWithStatus } from './utils/sync/StoreWithStatus' * * @public **/ -export type TldrawEditorProps = TldrawEditorBaseProps & - ( - | { - store: TLStore | TLStoreWithStatus - } - | { - store?: undefined - snapshot?: StoreSnapshot - initialData?: SerializedStore - persistenceKey?: string - sessionId?: string - defaultName?: string - } - ) +export type TldrawEditorProps = Expand< + TldrawEditorBaseProps & + ( + | { + store: TLStore | TLStoreWithStatus + } + | { + store?: undefined + snapshot?: StoreSnapshot + initialData?: SerializedStore + persistenceKey?: string + sessionId?: string + defaultName?: string + } + ) +> /** * Base props for the {@link @tldraw/tldraw#Tldraw} and {@link TldrawEditor} components. diff --git a/packages/tldraw/api-report.md b/packages/tldraw/api-report.md index 2f58b78cd..bfdbea54d 100644 --- a/packages/tldraw/api-report.md +++ b/packages/tldraw/api-report.md @@ -1213,7 +1213,7 @@ export type TldrawImageProps = Expand<{ } & Partial>; // @public (undocumented) -export type TldrawProps = (Omit & Omit & { +export type TldrawProps = Expand<(Omit & Omit & { components?: TLComponents; }) & Partial & ({ store: TLStore | TLStoreWithStatus; @@ -1223,7 +1223,7 @@ export type TldrawProps = (Omit & Omit; -}); +})>; // @public (undocumented) export function TldrawScribble({ scribble, zoom, color, opacity, className }: TLScribbleProps): JSX_2.Element | null; @@ -1235,7 +1235,136 @@ export const TldrawSelectionBackground: ({ bounds, rotation }: TLSelectionBackgr export const TldrawSelectionForeground: MemoExoticComponent<({ bounds, rotation, }: TLSelectionForegroundProps) => JSX_2.Element | null>; // @public (undocumented) -export const TldrawUi: React_2.NamedExoticComponent; +export const TldrawUi: React_2.NamedExoticComponent<{ + children?: any; + hideUi?: boolean | undefined; + components?: Partial<{ + ContextMenu: null | React_2.ComponentType; + ActionsMenu: null | React_2.ComponentType; + HelpMenu: null | React_2.ComponentType; + ZoomMenu: null | React_2.ComponentType; + MainMenu: null | React_2.ComponentType; + Minimap: null | React_2.ComponentType; + StylePanel: null | React_2.ComponentType; + PageMenu: null | React_2.ComponentType; + NavigationPanel: null | React_2.ComponentType; + Toolbar: null | React_2.ComponentType; + KeyboardShortcutsDialog: null | React_2.ComponentType; + QuickActions: null | React_2.ComponentType; + HelperButtons: null | React_2.ComponentType; + DebugMenu: null | React_2.ComponentType; + MenuPanel: null | React_2.ComponentType; + TopPanel: null | React_2.ComponentType; + SharePanel: null | React_2.ComponentType; + }> | undefined; + renderDebugMenuItems?: (() => React_2.ReactNode) | undefined; + assetUrls?: (RecursivePartial & RecursivePartial) | undefined; + overrides?: Partial<{ + actions: TLUiOverride & { + id?: string | undefined; + }) => string; + removeToast: (id: string) => string; + clearToasts: () => void; + addDialog: (dialog: Omit & { + id?: string | undefined; + }) => string; + clearDialogs: () => void; + removeDialog: (id: string) => string; + updateDialog: (id: string, newDialogData: Partial) => string; + msg: (id?: string | undefined) => string; + isMobile: boolean; + }>; + toolbar: TLUiOverride & { + id?: string | undefined; + }) => string; + removeToast: (id: string) => string; + clearToasts: () => void; + addDialog: (dialog: Omit & { + id?: string | undefined; + }) => string; + clearDialogs: () => void; + removeDialog: (id: string) => string; + updateDialog: (id: string, newDialogData: Partial) => string; + msg: (id?: string | undefined) => string; + isMobile: boolean; + }>; + tools: TLUiOverride void; + } & { + addToast: (toast: Omit & { + id?: string | undefined; + }) => string; + removeToast: (id: string) => string; + clearToasts: () => void; + addDialog: (dialog: Omit & { + id?: string | undefined; + }) => string; + clearDialogs: () => void; + removeDialog: (id: string) => string; + updateDialog: (id: string, newDialogData: Partial) => string; + msg: (id?: string | undefined) => string; + isMobile: boolean; + }>; + translations: Record> | undefined; + }> | Partial<{ + actions: TLUiOverride & { + id?: string | undefined; + }) => string; + removeToast: (id: string) => string; + clearToasts: () => void; + addDialog: (dialog: Omit & { + id?: string | undefined; + }) => string; + clearDialogs: () => void; + removeDialog: (id: string) => string; + updateDialog: (id: string, newDialogData: Partial) => string; + msg: (id?: string | undefined) => string; + isMobile: boolean; + }>; + toolbar: TLUiOverride & { + id?: string | undefined; + }) => string; + removeToast: (id: string) => string; + clearToasts: () => void; + addDialog: (dialog: Omit & { + id?: string | undefined; + }) => string; + clearDialogs: () => void; + removeDialog: (id: string) => string; + updateDialog: (id: string, newDialogData: Partial) => string; + msg: (id?: string | undefined) => string; + isMobile: boolean; + }>; + tools: TLUiOverride void; + } & { + addToast: (toast: Omit & { + id?: string | undefined; + }) => string; + removeToast: (id: string) => string; + clearToasts: () => void; + addDialog: (dialog: Omit & { + id?: string | undefined; + }) => string; + clearDialogs: () => void; + removeDialog: (id: string) => string; + updateDialog: (id: string, newDialogData: Partial) => string; + msg: (id?: string | undefined) => string; + isMobile: boolean; + }>; + translations: Record> | undefined; + }>[] | undefined; + onUiEvent?: TLUiEventHandler | undefined; + forceMobile?: boolean | undefined; +}>; // @public export interface TldrawUiBaseProps { @@ -1353,7 +1482,7 @@ export function TldrawUiPopoverContent({ side, children, align, sideOffset, alig export function TldrawUiPopoverTrigger({ children }: TLUiPopoverTriggerProps): JSX_2.Element; // @public -export type TldrawUiProps = TldrawUiBaseProps & TldrawUiContextProviderProps; +export type TldrawUiProps = Expand; // @internal (undocumented) export const TldrawUiSlider: NamedExoticComponent; diff --git a/packages/tldraw/api/api.json b/packages/tldraw/api/api.json index 255e2780d..b99004ca7 100644 --- a/packages/tldraw/api/api.json +++ b/packages/tldraw/api/api.json @@ -14037,9 +14037,14 @@ "kind": "Content", "text": "export type TldrawProps = " }, + { + "kind": "Reference", + "text": "Expand", + "canonicalReference": "@tldraw/utils!Expand:type" + }, { "kind": "Content", - "text": "(" + "text": "<(" }, { "kind": "Reference", @@ -14138,7 +14143,7 @@ }, { "kind": "Content", - "text": ">;\n})" + "text": ">;\n})>" }, { "kind": "Content", @@ -14150,7 +14155,7 @@ "name": "TldrawProps", "typeTokenRange": { "startIndex": 1, - "endIndex": 24 + "endIndex": 25 } }, { @@ -14315,16 +14320,808 @@ }, { "kind": "Content", - "text": "<" + "text": "<{\n children?: any;\n hideUi?: boolean | undefined;\n components?: " }, { "kind": "Reference", - "text": "TldrawUiProps", - "canonicalReference": "@tldraw/tldraw!TldrawUiProps:type" + "text": "Partial", + "canonicalReference": "!Partial:type" }, { "kind": "Content", - "text": ">" + "text": "<{\n ContextMenu: null | " + }, + { + "kind": "Reference", + "text": "React.ComponentType", + "canonicalReference": "@types/react!React.ComponentType:type" + }, + { + "kind": "Content", + "text": ";\n ActionsMenu: null | " + }, + { + "kind": "Reference", + "text": "React.ComponentType", + "canonicalReference": "@types/react!React.ComponentType:type" + }, + { + "kind": "Content", + "text": ";\n HelpMenu: null | " + }, + { + "kind": "Reference", + "text": "React.ComponentType", + "canonicalReference": "@types/react!React.ComponentType:type" + }, + { + "kind": "Content", + "text": ";\n ZoomMenu: null | " + }, + { + "kind": "Reference", + "text": "React.ComponentType", + "canonicalReference": "@types/react!React.ComponentType:type" + }, + { + "kind": "Content", + "text": ";\n MainMenu: null | " + }, + { + "kind": "Reference", + "text": "React.ComponentType", + "canonicalReference": "@types/react!React.ComponentType:type" + }, + { + "kind": "Content", + "text": ";\n Minimap: null | " + }, + { + "kind": "Reference", + "text": "React.ComponentType", + "canonicalReference": "@types/react!React.ComponentType:type" + }, + { + "kind": "Content", + "text": ";\n StylePanel: null | " + }, + { + "kind": "Reference", + "text": "React.ComponentType", + "canonicalReference": "@types/react!React.ComponentType:type" + }, + { + "kind": "Content", + "text": ";\n PageMenu: null | " + }, + { + "kind": "Reference", + "text": "React.ComponentType", + "canonicalReference": "@types/react!React.ComponentType:type" + }, + { + "kind": "Content", + "text": ";\n NavigationPanel: null | " + }, + { + "kind": "Reference", + "text": "React.ComponentType", + "canonicalReference": "@types/react!React.ComponentType:type" + }, + { + "kind": "Content", + "text": ";\n Toolbar: null | " + }, + { + "kind": "Reference", + "text": "React.ComponentType", + "canonicalReference": "@types/react!React.ComponentType:type" + }, + { + "kind": "Content", + "text": ";\n KeyboardShortcutsDialog: null | " + }, + { + "kind": "Reference", + "text": "React.ComponentType", + "canonicalReference": "@types/react!React.ComponentType:type" + }, + { + "kind": "Content", + "text": ";\n QuickActions: null | " + }, + { + "kind": "Reference", + "text": "React.ComponentType", + "canonicalReference": "@types/react!React.ComponentType:type" + }, + { + "kind": "Content", + "text": ";\n HelperButtons: null | " + }, + { + "kind": "Reference", + "text": "React.ComponentType", + "canonicalReference": "@types/react!React.ComponentType:type" + }, + { + "kind": "Content", + "text": ";\n DebugMenu: null | " + }, + { + "kind": "Reference", + "text": "React.ComponentType", + "canonicalReference": "@types/react!React.ComponentType:type" + }, + { + "kind": "Content", + "text": ";\n MenuPanel: null | " + }, + { + "kind": "Reference", + "text": "React.ComponentType", + "canonicalReference": "@types/react!React.ComponentType:type" + }, + { + "kind": "Content", + "text": ";\n TopPanel: null | " + }, + { + "kind": "Reference", + "text": "React.ComponentType", + "canonicalReference": "@types/react!React.ComponentType:type" + }, + { + "kind": "Content", + "text": ";\n SharePanel: null | " + }, + { + "kind": "Reference", + "text": "React.ComponentType", + "canonicalReference": "@types/react!React.ComponentType:type" + }, + { + "kind": "Content", + "text": ";\n }> | undefined;\n renderDebugMenuItems?: (() => " + }, + { + "kind": "Reference", + "text": "React.ReactNode", + "canonicalReference": "@types/react!React.ReactNode:type" + }, + { + "kind": "Content", + "text": ") | undefined;\n assetUrls?: (import(\"@tldraw/editor\")." + }, + { + "kind": "Reference", + "text": "RecursivePartial", + "canonicalReference": "@tldraw/utils!RecursivePartial:type" + }, + { + "kind": "Content", + "text": " & import(\"@tldraw/editor\")." + }, + { + "kind": "Reference", + "text": "RecursivePartial", + "canonicalReference": "@tldraw/utils!RecursivePartial:type" + }, + { + "kind": "Content", + "text": ") | undefined;\n overrides?: " + }, + { + "kind": "Reference", + "text": "Partial", + "canonicalReference": "!Partial:type" + }, + { + "kind": "Content", + "text": "<{\n actions: import(\"./overrides\")." + }, + { + "kind": "Reference", + "text": "TLUiOverride", + "canonicalReference": "@tldraw/tldraw!~TLUiOverride:type" + }, + { + "kind": "Content", + "text": " & {\n id?: string | undefined;\n }) => string;\n removeToast: (id: string) => string;\n clearToasts: () => void;\n addDialog: (dialog: " + }, + { + "kind": "Reference", + "text": "Omit", + "canonicalReference": "!Omit:type" + }, + { + "kind": "Content", + "text": " & {\n id?: string | undefined;\n }) => string;\n clearDialogs: () => void;\n removeDialog: (id: string) => string;\n updateDialog: (id: string, newDialogData: " + }, + { + "kind": "Reference", + "text": "Partial", + "canonicalReference": "!Partial:type" + }, + { + "kind": "Content", + "text": ") => string;\n msg: (id?: string | undefined) => string;\n isMobile: boolean;\n }>;\n toolbar: import(\"./overrides\")." + }, + { + "kind": "Reference", + "text": "TLUiOverride", + "canonicalReference": "@tldraw/tldraw!~TLUiOverride:type" + }, + { + "kind": "Content", + "text": " & {\n id?: string | undefined;\n }) => string;\n removeToast: (id: string) => string;\n clearToasts: () => void;\n addDialog: (dialog: " + }, + { + "kind": "Reference", + "text": "Omit", + "canonicalReference": "!Omit:type" + }, + { + "kind": "Content", + "text": " & {\n id?: string | undefined;\n }) => string;\n clearDialogs: () => void;\n removeDialog: (id: string) => string;\n updateDialog: (id: string, newDialogData: " + }, + { + "kind": "Reference", + "text": "Partial", + "canonicalReference": "!Partial:type" + }, + { + "kind": "Content", + "text": ") => string;\n msg: (id?: string | undefined) => string;\n isMobile: boolean;\n }>;\n tools: import(\"./overrides\")." + }, + { + "kind": "Reference", + "text": "TLUiOverride", + "canonicalReference": "@tldraw/tldraw!~TLUiOverride:type" + }, + { + "kind": "Content", + "text": " void;\n } & {\n addToast: (toast: " + }, + { + "kind": "Reference", + "text": "Omit", + "canonicalReference": "!Omit:type" + }, + { + "kind": "Content", + "text": " & {\n id?: string | undefined;\n }) => string;\n removeToast: (id: string) => string;\n clearToasts: () => void;\n addDialog: (dialog: " + }, + { + "kind": "Reference", + "text": "Omit", + "canonicalReference": "!Omit:type" + }, + { + "kind": "Content", + "text": " & {\n id?: string | undefined;\n }) => string;\n clearDialogs: () => void;\n removeDialog: (id: string) => string;\n updateDialog: (id: string, newDialogData: " + }, + { + "kind": "Reference", + "text": "Partial", + "canonicalReference": "!Partial:type" + }, + { + "kind": "Content", + "text": ") => string;\n msg: (id?: string | undefined) => string;\n isMobile: boolean;\n }>;\n translations: " + }, + { + "kind": "Reference", + "text": "Record", + "canonicalReference": "!Record:type" + }, + { + "kind": "Content", + "text": "> | undefined;\n }> | " + }, + { + "kind": "Reference", + "text": "Partial", + "canonicalReference": "!Partial:type" + }, + { + "kind": "Content", + "text": "<{\n actions: import(\"./overrides\")." + }, + { + "kind": "Reference", + "text": "TLUiOverride", + "canonicalReference": "@tldraw/tldraw!~TLUiOverride:type" + }, + { + "kind": "Content", + "text": " & {\n id?: string | undefined;\n }) => string;\n removeToast: (id: string) => string;\n clearToasts: () => void;\n addDialog: (dialog: " + }, + { + "kind": "Reference", + "text": "Omit", + "canonicalReference": "!Omit:type" + }, + { + "kind": "Content", + "text": " & {\n id?: string | undefined;\n }) => string;\n clearDialogs: () => void;\n removeDialog: (id: string) => string;\n updateDialog: (id: string, newDialogData: " + }, + { + "kind": "Reference", + "text": "Partial", + "canonicalReference": "!Partial:type" + }, + { + "kind": "Content", + "text": ") => string;\n msg: (id?: string | undefined) => string;\n isMobile: boolean;\n }>;\n toolbar: import(\"./overrides\")." + }, + { + "kind": "Reference", + "text": "TLUiOverride", + "canonicalReference": "@tldraw/tldraw!~TLUiOverride:type" + }, + { + "kind": "Content", + "text": " & {\n id?: string | undefined;\n }) => string;\n removeToast: (id: string) => string;\n clearToasts: () => void;\n addDialog: (dialog: " + }, + { + "kind": "Reference", + "text": "Omit", + "canonicalReference": "!Omit:type" + }, + { + "kind": "Content", + "text": " & {\n id?: string | undefined;\n }) => string;\n clearDialogs: () => void;\n removeDialog: (id: string) => string;\n updateDialog: (id: string, newDialogData: " + }, + { + "kind": "Reference", + "text": "Partial", + "canonicalReference": "!Partial:type" + }, + { + "kind": "Content", + "text": ") => string;\n msg: (id?: string | undefined) => string;\n isMobile: boolean;\n }>;\n tools: import(\"./overrides\")." + }, + { + "kind": "Reference", + "text": "TLUiOverride", + "canonicalReference": "@tldraw/tldraw!~TLUiOverride:type" + }, + { + "kind": "Content", + "text": " void;\n } & {\n addToast: (toast: " + }, + { + "kind": "Reference", + "text": "Omit", + "canonicalReference": "!Omit:type" + }, + { + "kind": "Content", + "text": " & {\n id?: string | undefined;\n }) => string;\n removeToast: (id: string) => string;\n clearToasts: () => void;\n addDialog: (dialog: " + }, + { + "kind": "Reference", + "text": "Omit", + "canonicalReference": "!Omit:type" + }, + { + "kind": "Content", + "text": " & {\n id?: string | undefined;\n }) => string;\n clearDialogs: () => void;\n removeDialog: (id: string) => string;\n updateDialog: (id: string, newDialogData: " + }, + { + "kind": "Reference", + "text": "Partial", + "canonicalReference": "!Partial:type" + }, + { + "kind": "Content", + "text": ") => string;\n msg: (id?: string | undefined) => string;\n isMobile: boolean;\n }>;\n translations: " + }, + { + "kind": "Reference", + "text": "Record", + "canonicalReference": "!Record:type" + }, + { + "kind": "Content", + "text": "> | undefined;\n }>[] | undefined;\n onUiEvent?: import(\"./context/events\")." + }, + { + "kind": "Reference", + "text": "TLUiEventHandler", + "canonicalReference": "@tldraw/tldraw!TLUiEventHandler:type" + }, + { + "kind": "Content", + "text": " | undefined;\n forceMobile?: boolean | undefined;\n}>" } ], "fileUrlPath": "packages/tldraw/src/lib/ui/TldrawUi.tsx", @@ -14333,7 +15130,7 @@ "name": "TldrawUi", "variableTypeTokenRange": { "startIndex": 1, - "endIndex": 5 + "endIndex": 181 } }, { @@ -16442,6 +17239,15 @@ "kind": "Content", "text": "export type TldrawUiProps = " }, + { + "kind": "Reference", + "text": "Expand", + "canonicalReference": "@tldraw/utils!Expand:type" + }, + { + "kind": "Content", + "text": "<" + }, { "kind": "Reference", "text": "TldrawUiBaseProps", @@ -16456,6 +17262,10 @@ "text": "TldrawUiContextProviderProps", "canonicalReference": "@tldraw/tldraw!TldrawUiContextProviderProps:interface" }, + { + "kind": "Content", + "text": ">" + }, { "kind": "Content", "text": ";" @@ -16466,7 +17276,7 @@ "name": "TldrawUiProps", "typeTokenRange": { "startIndex": 1, - "endIndex": 4 + "endIndex": 7 } }, { diff --git a/packages/tldraw/src/lib/Tldraw.tsx b/packages/tldraw/src/lib/Tldraw.tsx index 752b93f4b..a3199390b 100644 --- a/packages/tldraw/src/lib/Tldraw.tsx +++ b/packages/tldraw/src/lib/Tldraw.tsx @@ -1,6 +1,7 @@ import { Editor, ErrorScreen, + Expand, LoadingScreen, StoreSnapshot, TLEditorComponents, @@ -39,7 +40,7 @@ import { useDefaultEditorAssetsWithOverrides } from './utils/static-assets/asset export type TLComponents = TLEditorComponents & TLUiComponents /** @public */ -export type TldrawProps = +export type TldrawProps = Expand< // combine components from base editor and ui (Omit & Omit & { @@ -62,6 +63,7 @@ export type TldrawProps = snapshot?: StoreSnapshot } ) +> /** @public */ export function Tldraw(props: TldrawProps) { diff --git a/packages/tldraw/src/lib/ui/TldrawUi.tsx b/packages/tldraw/src/lib/ui/TldrawUi.tsx index 41c2f70b7..4bbbff85b 100644 --- a/packages/tldraw/src/lib/ui/TldrawUi.tsx +++ b/packages/tldraw/src/lib/ui/TldrawUi.tsx @@ -1,5 +1,5 @@ import { ToastProvider } from '@radix-ui/react-toast' -import { useEditor, useValue } from '@tldraw/editor' +import { Expand, useEditor, useValue } from '@tldraw/editor' import classNames from 'classnames' import React, { ReactNode } from 'react' import { TLUiAssetUrlOverrides } from './assetUrls' @@ -23,13 +23,6 @@ import { useKeyboardShortcuts } from './hooks/useKeyboardShortcuts' import { useReadonly } from './hooks/useReadonly' import { useTranslation } from './hooks/useTranslation/useTranslation' -/** - * Props for the {@link @tldraw/tldraw#Tldraw} and {@link TldrawUi} components. - * - * @public - */ -export type TldrawUiProps = TldrawUiBaseProps & TldrawUiContextProviderProps - /** * Base props for the {@link @tldraw/tldraw#Tldraw} and {@link TldrawUi} components. * @@ -60,6 +53,13 @@ export interface TldrawUiBaseProps { assetUrls?: TLUiAssetUrlOverrides } +/** + * Props for the {@link @tldraw/tldraw#Tldraw} and {@link TldrawUi} components. + * + * @public + */ +export type TldrawUiProps = Expand + /** * @public */