2023-04-25 11:01:25 +00:00
|
|
|
## API Report File for "@tldraw/editor"
|
|
|
|
|
|
|
|
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
|
|
/// <reference types="react" />
|
|
|
|
|
|
|
|
import { Atom } from 'signia';
|
|
|
|
import { Box2d } from '@tldraw/primitives';
|
|
|
|
import { Box2dModel } from '@tldraw/tlschema';
|
|
|
|
import { Computed } from 'signia';
|
|
|
|
import { ComputedCache } from '@tldraw/tlstore';
|
|
|
|
import { CubicSpline2d } from '@tldraw/primitives';
|
|
|
|
import { EASINGS } from '@tldraw/primitives';
|
|
|
|
import { EmbedDefinition } from '@tldraw/tlschema';
|
|
|
|
import { EventEmitter } from 'eventemitter3';
|
|
|
|
import { getHashForString } from '@tldraw/utils';
|
2023-05-22 08:18:01 +00:00
|
|
|
import { getIndexAbove } from '@tldraw/indices';
|
|
|
|
import { getIndexBelow } from '@tldraw/indices';
|
|
|
|
import { getIndexBetween } from '@tldraw/indices';
|
|
|
|
import { getIndices } from '@tldraw/indices';
|
|
|
|
import { getIndicesAbove } from '@tldraw/indices';
|
|
|
|
import { getIndicesBelow } from '@tldraw/indices';
|
|
|
|
import { getIndicesBetween } from '@tldraw/indices';
|
2023-04-25 11:01:25 +00:00
|
|
|
import { HistoryEntry } from '@tldraw/tlstore';
|
|
|
|
import { MatLike } from '@tldraw/primitives';
|
|
|
|
import { Matrix2d } from '@tldraw/primitives';
|
|
|
|
import { Matrix2dModel } from '@tldraw/primitives';
|
|
|
|
import { Migrations } from '@tldraw/tlstore';
|
|
|
|
import { Polyline2d } from '@tldraw/primitives';
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
import { default as React_2 } from 'react';
|
|
|
|
import * as React_3 from 'react';
|
2023-04-25 11:01:25 +00:00
|
|
|
import { RotateCorner } from '@tldraw/primitives';
|
|
|
|
import { SelectionCorner } from '@tldraw/primitives';
|
|
|
|
import { SelectionEdge } from '@tldraw/primitives';
|
|
|
|
import { SelectionHandle } from '@tldraw/primitives';
|
|
|
|
import { SerializedSchema } from '@tldraw/tlstore';
|
derived presence state (#1204)
This PR adds
- A new `TLInstancePresence` record type, to collect info about the
presence state in a particular instance of the editor. This will
eventually be used to sync presence data instead of sending
instance-only state across the wire.
- **Record Scopes**
`RecordType` now has a `scope` property which can be one of three
things:
- `document`: the record belongs to the document and should be synced
and persisted freely. Currently: `TLDocument`, `TLPage`, `TLShape`, and
`TLAsset`
- `instance`: the record belongs to a single instance of the store and
should not be synced at all. It should not be persisted directly in most
cases, but rather compiled into a kind of 'instance configuration' to
store alongside the local document data so that when reopening the
associated document it can remember some of the previous instance state.
Currently: `TLInstance`, `TLInstancePageState`, `TLCamera`, `TLUser`,
`TLUserDocument`, `TLUserPresence`
- `presence`: the record belongs to a single instance of the store and
should not be persisted, but may be synced using the special presence
sync protocol. Currently just `TLInstancePresence`
This sets us up for the following changes, which are gonna be pretty
high-impact in terms of integrating tldraw into existing systems:
- Removing `instanceId` as a config option. Each instance gets a
randomly generated ID.
- We'd replace it with an `instanceConfig` option that has stuff like
selectedIds, camera positions, and so on. Then it's up to library users
to get and reinstate the instance config at persistence boundaries.
- Removing `userId` as config option, and removing the `TLUser` type
altogether.
- We might need to revisit when doing auth-enabled features like locking
shapes, but I suspect that will be separate.
2023-04-27 18:03:19 +00:00
|
|
|
import { Signal } from 'signia';
|
2023-05-22 08:18:01 +00:00
|
|
|
import { sortByIndex } from '@tldraw/indices';
|
2023-04-25 11:01:25 +00:00
|
|
|
import { StoreSnapshot } from '@tldraw/tlstore';
|
|
|
|
import { StrokePoint } from '@tldraw/primitives';
|
|
|
|
import { TLAlignType } from '@tldraw/tlschema';
|
|
|
|
import { TLArrowheadType } from '@tldraw/tlschema';
|
|
|
|
import { TLArrowShape } from '@tldraw/tlschema';
|
|
|
|
import { TLAsset } from '@tldraw/tlschema';
|
|
|
|
import { TLAssetId } from '@tldraw/tlschema';
|
|
|
|
import { TLAssetPartial } from '@tldraw/tlschema';
|
|
|
|
import { TLBaseShape } from '@tldraw/tlschema';
|
|
|
|
import { TLBookmarkAsset } from '@tldraw/tlschema';
|
|
|
|
import { TLBookmarkShape } from '@tldraw/tlschema';
|
|
|
|
import { TLCamera } from '@tldraw/tlschema';
|
|
|
|
import { TLColorStyle } from '@tldraw/tlschema';
|
|
|
|
import { TLColorType } from '@tldraw/tlschema';
|
|
|
|
import { TLCursor } from '@tldraw/tlschema';
|
|
|
|
import { TLDocument } from '@tldraw/tlschema';
|
|
|
|
import { TLDrawShape } from '@tldraw/tlschema';
|
|
|
|
import { TLEmbedShape } from '@tldraw/tlschema';
|
|
|
|
import { TLFontType } from '@tldraw/tlschema';
|
|
|
|
import { TLFrameShape } from '@tldraw/tlschema';
|
|
|
|
import { TLGeoShape } from '@tldraw/tlschema';
|
|
|
|
import { TLGroupShape } from '@tldraw/tlschema';
|
|
|
|
import { TLHandle } from '@tldraw/tlschema';
|
2023-06-01 12:46:13 +00:00
|
|
|
import { TLHighlightShape } from '@tldraw/tlschema';
|
2023-04-25 11:01:25 +00:00
|
|
|
import { TLImageAsset } from '@tldraw/tlschema';
|
|
|
|
import { TLImageShape } from '@tldraw/tlschema';
|
|
|
|
import { TLInstance } from '@tldraw/tlschema';
|
|
|
|
import { TLInstanceId } from '@tldraw/tlschema';
|
|
|
|
import { TLInstancePageState } from '@tldraw/tlschema';
|
derived presence state (#1204)
This PR adds
- A new `TLInstancePresence` record type, to collect info about the
presence state in a particular instance of the editor. This will
eventually be used to sync presence data instead of sending
instance-only state across the wire.
- **Record Scopes**
`RecordType` now has a `scope` property which can be one of three
things:
- `document`: the record belongs to the document and should be synced
and persisted freely. Currently: `TLDocument`, `TLPage`, `TLShape`, and
`TLAsset`
- `instance`: the record belongs to a single instance of the store and
should not be synced at all. It should not be persisted directly in most
cases, but rather compiled into a kind of 'instance configuration' to
store alongside the local document data so that when reopening the
associated document it can remember some of the previous instance state.
Currently: `TLInstance`, `TLInstancePageState`, `TLCamera`, `TLUser`,
`TLUserDocument`, `TLUserPresence`
- `presence`: the record belongs to a single instance of the store and
should not be persisted, but may be synced using the special presence
sync protocol. Currently just `TLInstancePresence`
This sets us up for the following changes, which are gonna be pretty
high-impact in terms of integrating tldraw into existing systems:
- Removing `instanceId` as a config option. Each instance gets a
randomly generated ID.
- We'd replace it with an `instanceConfig` option that has stuff like
selectedIds, camera positions, and so on. Then it's up to library users
to get and reinstate the instance config at persistence boundaries.
- Removing `userId` as config option, and removing the `TLUser` type
altogether.
- We might need to revisit when doing auth-enabled features like locking
shapes, but I suspect that will be separate.
2023-04-27 18:03:19 +00:00
|
|
|
import { TLInstancePresence } from '@tldraw/tlschema';
|
2023-04-25 11:01:25 +00:00
|
|
|
import { TLInstancePropsForNextShape } from '@tldraw/tlschema';
|
|
|
|
import { TLLineShape } from '@tldraw/tlschema';
|
|
|
|
import { TLNoteShape } from '@tldraw/tlschema';
|
|
|
|
import { TLNullableShapeProps } from '@tldraw/tlschema';
|
|
|
|
import { TLPage } from '@tldraw/tlschema';
|
|
|
|
import { TLPageId } from '@tldraw/tlschema';
|
|
|
|
import { TLParentId } from '@tldraw/tlschema';
|
|
|
|
import { TLRecord } from '@tldraw/tlschema';
|
|
|
|
import { TLScribble } from '@tldraw/tlschema';
|
|
|
|
import { TLShape } from '@tldraw/tlschema';
|
|
|
|
import { TLShapeId } from '@tldraw/tlschema';
|
|
|
|
import { TLShapePartial } from '@tldraw/tlschema';
|
|
|
|
import { TLShapeProp } from '@tldraw/tlschema';
|
|
|
|
import { TLShapeProps } from '@tldraw/tlschema';
|
|
|
|
import { TLSizeStyle } from '@tldraw/tlschema';
|
|
|
|
import { TLSizeType } from '@tldraw/tlschema';
|
|
|
|
import { TLStore } from '@tldraw/tlschema';
|
|
|
|
import { TLStyleCollections } from '@tldraw/tlschema';
|
|
|
|
import { TLStyleType } from '@tldraw/tlschema';
|
|
|
|
import { TLTextShape } from '@tldraw/tlschema';
|
|
|
|
import { TLTextShapeProps } from '@tldraw/tlschema';
|
|
|
|
import { TLUnknownShape } from '@tldraw/tlschema';
|
|
|
|
import { TLUserDocument } from '@tldraw/tlschema';
|
|
|
|
import { TLVideoAsset } from '@tldraw/tlschema';
|
|
|
|
import { TLVideoShape } from '@tldraw/tlschema';
|
2023-05-24 11:25:41 +00:00
|
|
|
import { UnknownRecord } from '@tldraw/tlstore';
|
2023-04-25 11:01:25 +00:00
|
|
|
import { Vec2d } from '@tldraw/primitives';
|
|
|
|
import { Vec2dModel } from '@tldraw/tlschema';
|
|
|
|
import { VecLike } from '@tldraw/primitives';
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const ACCEPTED_ASSET_TYPE: string;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const ACCEPTED_IMG_TYPE: string[];
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const ACCEPTED_VID_TYPE: string[];
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const ANIMATION_MEDIUM_MS = 320;
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const ANIMATION_SHORT_MS = 80;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type AnimationOptions = Partial<{
|
|
|
|
duration: number;
|
|
|
|
easing: typeof EASINGS.easeInOutCubic;
|
|
|
|
}>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
2023-05-11 22:14:58 +00:00
|
|
|
export class App extends EventEmitter<TLEventMap> {
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
constructor({ store, user, tools, shapes, getContainer, }: AppOptions);
|
2023-05-11 22:14:58 +00:00
|
|
|
addOpenMenu: (id: string) => this;
|
2023-04-25 11:01:25 +00:00
|
|
|
alignShapes(operation: 'bottom' | 'center-horizontal' | 'center-vertical' | 'left' | 'right' | 'top', ids?: TLShapeId[]): this;
|
|
|
|
get allShapesCommonBounds(): Box2d | null;
|
|
|
|
animateCamera(x: number, y: number, z?: number, opts?: AnimationOptions): this;
|
|
|
|
animateShapes(partials: (null | TLShapePartial | undefined)[], options?: {
|
|
|
|
duration?: number;
|
|
|
|
ease?: (t: number) => number;
|
|
|
|
}): this;
|
|
|
|
// (undocumented)
|
|
|
|
animateToShape(shapeId: TLShapeId, opts?: AnimationOptions): this;
|
2023-05-30 15:22:49 +00:00
|
|
|
// (undocumented)
|
|
|
|
get animationSpeed(): number;
|
2023-04-25 11:01:25 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
annotateError(error: unknown, { origin, willCrashApp, tags, extras, }: {
|
|
|
|
origin: string;
|
|
|
|
willCrashApp: boolean;
|
|
|
|
tags?: Record<string, boolean | number | string>;
|
|
|
|
extras?: Record<string, unknown>;
|
|
|
|
}): void;
|
|
|
|
get assets(): (TLBookmarkAsset | TLImageAsset | TLVideoAsset)[];
|
|
|
|
bail(): this;
|
|
|
|
bailToMark(id: string): this;
|
|
|
|
batch(fn: () => void): this;
|
|
|
|
blur(): this;
|
|
|
|
bringForward(ids?: TLShapeId[]): this;
|
|
|
|
bringToFront(ids?: TLShapeId[]): this;
|
|
|
|
// (undocumented)
|
|
|
|
get brush(): Box2dModel | null;
|
|
|
|
get camera(): TLCamera;
|
|
|
|
cancel(): this;
|
|
|
|
cancelDoubleClick(): void;
|
|
|
|
get canMoveCamera(): boolean;
|
|
|
|
set canMoveCamera(canMove: boolean);
|
|
|
|
get canRedo(): boolean;
|
|
|
|
get canUndo(): boolean;
|
2023-05-19 10:35:24 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
capturedPointerId: null | number;
|
2023-04-25 11:01:25 +00:00
|
|
|
centerOnPoint(x: number, y: number, opts?: AnimationOptions): this;
|
|
|
|
// @internal
|
|
|
|
protected _clickManager: ClickManager;
|
|
|
|
complete(): this;
|
|
|
|
// @internal (undocumented)
|
|
|
|
crash(error: unknown): void;
|
|
|
|
// @internal
|
|
|
|
get crashingError(): unknown;
|
|
|
|
createAssets(assets: TLAsset[]): this;
|
|
|
|
// @internal (undocumented)
|
|
|
|
createErrorAnnotations(origin: string, willCrashApp: 'unknown' | boolean): {
|
|
|
|
tags: {
|
|
|
|
origin: string;
|
|
|
|
willCrashApp: 'unknown' | boolean;
|
|
|
|
};
|
|
|
|
extras: {
|
|
|
|
activeStateNode?: string;
|
|
|
|
selectedShapes?: TLUnknownShape[];
|
|
|
|
editingShape?: TLUnknownShape;
|
|
|
|
inputs?: Record<string, unknown>;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
createPage(title: string, id?: TLPageId, belowPageIndex?: string): this;
|
|
|
|
createShapeId(id?: string): TLShapeId;
|
|
|
|
createShapes(partials: TLShapePartial[], select?: boolean): this;
|
|
|
|
get croppingId(): null | TLShapeId;
|
|
|
|
get cullingBounds(): Box2d;
|
|
|
|
// @internal (undocumented)
|
|
|
|
readonly _cullingBounds: Atom<Box2d, unknown>;
|
|
|
|
get cullingBoundsExpanded(): Box2d;
|
|
|
|
// @internal (undocumented)
|
|
|
|
readonly _cullingBoundsExpanded: Atom<Box2d, unknown>;
|
|
|
|
get currentPage(): TLPage;
|
|
|
|
get currentPageId(): TLPageId;
|
|
|
|
get currentToolId(): string;
|
|
|
|
// (undocumented)
|
|
|
|
get cursor(): TLCursor;
|
|
|
|
deleteAssets(ids: TLAssetId[]): this;
|
2023-05-11 22:14:58 +00:00
|
|
|
deleteOpenMenu: (id: string) => this;
|
2023-04-25 11:01:25 +00:00
|
|
|
deletePage(id: TLPageId): void;
|
|
|
|
deleteShapes(ids?: TLShapeId[]): this;
|
|
|
|
deselect(...ids: TLShapeId[]): this;
|
|
|
|
// (undocumented)
|
|
|
|
get devicePixelRatio(): number;
|
|
|
|
dispatch: (info: TLEventInfo) => this;
|
|
|
|
readonly disposables: Set<() => void>;
|
|
|
|
dispose(): void;
|
|
|
|
distributeShapes(operation: 'horizontal' | 'vertical', ids?: TLShapeId[]): this;
|
|
|
|
get documentSettings(): TLDocument;
|
|
|
|
// (undocumented)
|
|
|
|
duplicatePage(id?: TLPageId, createId?: TLPageId): void;
|
|
|
|
duplicateShapes(ids?: TLShapeId[], offset?: VecLike): this;
|
|
|
|
get editingId(): null | TLShapeId;
|
|
|
|
// (undocumented)
|
|
|
|
get editingShape(): null | TLUnknownShape;
|
2023-05-30 14:28:56 +00:00
|
|
|
// (undocumented)
|
|
|
|
enableAnimations: boolean;
|
2023-04-25 11:01:25 +00:00
|
|
|
get erasingIds(): TLShapeId[];
|
|
|
|
get erasingIdsSet(): Set<TLShapeId>;
|
|
|
|
findAncestor(shape: TLShape, predicate: (parent: TLShape) => boolean): TLShape | undefined;
|
|
|
|
findCommonAncestor(shapes: TLShape[], predicate?: (shape: TLShape) => boolean): TLShapeId | undefined;
|
|
|
|
flipShapes(operation: 'horizontal' | 'vertical', ids?: TLShapeId[]): this;
|
|
|
|
focus(): this;
|
|
|
|
// (undocumented)
|
|
|
|
get focusLayerId(): TLPageId | TLShapeId;
|
|
|
|
// (undocumented)
|
|
|
|
get focusLayerShape(): TLShape | undefined;
|
|
|
|
getAncestors(shape: TLShape, acc?: TLShape[]): TLShape[];
|
|
|
|
getAncestorsById(id: TLShapeId, acc?: TLShape[]): TLShape[];
|
|
|
|
getArrowsBoundTo(shapeId: TLShapeId): {
|
|
|
|
arrowId: TLShapeId;
|
|
|
|
handleId: "end" | "start";
|
|
|
|
}[];
|
|
|
|
getAssetById(id: TLAssetId): TLAsset | undefined;
|
|
|
|
getAssetBySrc(src: string): TLBookmarkAsset | TLImageAsset | TLVideoAsset | undefined;
|
|
|
|
getBounds(shape: TLShape): Box2d;
|
|
|
|
getBoundsById(id: TLShapeId): Box2d | undefined;
|
|
|
|
getClipPathById(id: TLShapeId): string | undefined;
|
|
|
|
getContainer: () => HTMLElement;
|
|
|
|
// (undocumented)
|
|
|
|
getContent(ids?: TLShapeId[]): TLClipboardModel | undefined;
|
|
|
|
getCssColor(id: TLColorStyle['id']): string;
|
|
|
|
getDeltaInParentSpace(shape: TLShape, delta: VecLike): Vec2d;
|
|
|
|
getDeltaInShapeSpace(shape: TLShape, delta: VecLike): Vec2d;
|
|
|
|
// (undocumented)
|
|
|
|
getDroppingShape(point: VecLike, droppingShapes?: TLShape[]): TLUnknownShape | undefined;
|
|
|
|
// (undocumented)
|
|
|
|
getHighestIndexForParent(parentId: TLPageId | TLShapeId): string;
|
|
|
|
getMaskedPageBounds(shape: TLShape): Box2d | undefined;
|
|
|
|
getMaskedPageBoundsById(id: TLShapeId): Box2d | undefined;
|
|
|
|
// (undocumented)
|
|
|
|
getOutermostSelectableShape(shape: TLShape, filter?: (shape: TLShape) => boolean): TLShape;
|
|
|
|
getOutline(shape: TLShape): Vec2dModel[];
|
|
|
|
getOutlineById(id: TLShapeId): Vec2dModel[];
|
|
|
|
getPageBounds(shape: TLShape): Box2d | undefined;
|
|
|
|
getPageBoundsById(id: TLShapeId): Box2d | undefined;
|
|
|
|
getPageById(id: TLPage['id']): TLPage | undefined;
|
|
|
|
getPageCenter(shape: TLShape): null | Vec2d;
|
|
|
|
getPageCenterById(id: TLShapeId): null | Vec2d;
|
|
|
|
getPageCorners(shape: TLShape): Vec2d[];
|
|
|
|
getPageInfoById(id: TLPage['id']): TLPage | undefined;
|
|
|
|
getPageMaskById(id: TLShapeId): undefined | VecLike[];
|
|
|
|
getPagePointById(id: TLShapeId): undefined | Vec2d;
|
|
|
|
getPageRotation(shape: TLShape): number;
|
|
|
|
getPageRotationById(id: TLShapeId): number;
|
|
|
|
getPageStateByPageId(id: TLPageId): TLInstancePageState | undefined;
|
|
|
|
getPageTransform(shape: TLShape): Matrix2d | undefined;
|
|
|
|
getPageTransformById(id: TLShapeId): Matrix2d | undefined;
|
|
|
|
// (undocumented)
|
2023-05-24 10:48:31 +00:00
|
|
|
getParentIdForNewShapeAtPoint(point: VecLike, shapeType: TLShape['type']): TLPageId | TLShapeId;
|
2023-04-25 11:01:25 +00:00
|
|
|
getParentPageId(shape?: TLShape): TLPageId | undefined;
|
|
|
|
getParentShape(shape?: TLShape): TLShape | undefined;
|
|
|
|
getParentsMappedToChildren(ids: TLShapeId[]): Map<TLParentId, Set<TLShape>>;
|
|
|
|
getParentTransform(shape: TLShape): Matrix2d;
|
|
|
|
getPointInParentSpace(shapeId: TLShapeId, point: VecLike): Vec2d;
|
|
|
|
getPointInShapeSpace(shape: TLShape, point: VecLike): Vec2d;
|
|
|
|
// (undocumented)
|
2023-06-01 15:22:47 +00:00
|
|
|
getShapeAndDescendantIds(ids: TLShapeId[]): Set<TLShapeId>;
|
|
|
|
getShapeById<T extends TLShape = TLShape>(id: TLParentId): T | undefined;
|
|
|
|
getShapeIdsInPage(pageId: TLPageId): Set<TLShapeId>;
|
2023-04-25 11:01:25 +00:00
|
|
|
getShapesAtPoint(point: VecLike): TLShape[];
|
2023-05-23 12:32:42 +00:00
|
|
|
getShapeUtil<C extends {
|
|
|
|
new (...args: any[]): TLShapeUtil<any>;
|
|
|
|
type: string;
|
|
|
|
}>(util: C): InstanceType<C>;
|
|
|
|
getShapeUtil<S extends TLUnknownShape>(shape: S | TLShapePartial<S>): TLShapeUtil<S>;
|
2023-04-25 11:01:25 +00:00
|
|
|
getSortedChildIds(parentId: TLParentId): TLShapeId[];
|
|
|
|
getStateDescendant(path: string): StateNode | undefined;
|
|
|
|
getStrokeWidth(id: TLSizeStyle['id']): number;
|
|
|
|
// (undocumented)
|
|
|
|
getSvg(ids?: TLShapeId[], opts?: Partial<{
|
|
|
|
scale: number;
|
|
|
|
background: boolean;
|
|
|
|
padding: number;
|
|
|
|
darkMode?: boolean | undefined;
|
|
|
|
preserveAspectRatio: React.SVGAttributes<SVGSVGElement>['preserveAspectRatio'];
|
|
|
|
}>): Promise<SVGSVGElement | undefined>;
|
|
|
|
getTransform(shape: TLShape): Matrix2d;
|
|
|
|
// (undocumented)
|
|
|
|
get gridSize(): number;
|
|
|
|
// (undocumented)
|
|
|
|
groupShapes(ids?: TLShapeId[], groupId?: TLShapeId): this;
|
|
|
|
hasAncestor(shape: TLShape | undefined, ancestorId: TLShapeId): boolean;
|
|
|
|
get hintingIds(): TLShapeId[];
|
|
|
|
readonly history: HistoryManager<this>;
|
|
|
|
// (undocumented)
|
|
|
|
get hoveredId(): null | TLShapeId;
|
|
|
|
// (undocumented)
|
|
|
|
get hoveredShape(): null | TLUnknownShape;
|
|
|
|
inputs: {
|
|
|
|
originPagePoint: Vec2d;
|
|
|
|
originScreenPoint: Vec2d;
|
|
|
|
previousPagePoint: Vec2d;
|
|
|
|
previousScreenPoint: Vec2d;
|
|
|
|
currentPagePoint: Vec2d;
|
|
|
|
currentScreenPoint: Vec2d;
|
|
|
|
keys: Set<string>;
|
|
|
|
buttons: Set<number>;
|
|
|
|
isPen: boolean;
|
|
|
|
shiftKey: boolean;
|
|
|
|
ctrlKey: boolean;
|
|
|
|
altKey: boolean;
|
|
|
|
isDragging: boolean;
|
|
|
|
isPointing: boolean;
|
|
|
|
isPinching: boolean;
|
|
|
|
isEditing: boolean;
|
|
|
|
isPanning: boolean;
|
|
|
|
pointerVelocity: Vec2d;
|
|
|
|
};
|
|
|
|
get instanceId(): TLInstanceId;
|
|
|
|
get instanceState(): TLInstance;
|
|
|
|
interrupt(): this;
|
|
|
|
get isChangingStyle(): boolean;
|
|
|
|
set isChangingStyle(v: boolean);
|
|
|
|
readonly isChromeForIos: boolean;
|
|
|
|
get isCoarsePointer(): boolean;
|
|
|
|
set isCoarsePointer(v: boolean);
|
2023-05-11 22:14:58 +00:00
|
|
|
// (undocumented)
|
|
|
|
get isDarkMode(): boolean;
|
2023-04-25 11:01:25 +00:00
|
|
|
get isFocused(): boolean;
|
|
|
|
// (undocumented)
|
2023-05-11 22:14:58 +00:00
|
|
|
get isFocusMode(): boolean;
|
|
|
|
// (undocumented)
|
2023-04-25 11:01:25 +00:00
|
|
|
get isGridMode(): boolean;
|
|
|
|
isIn(path: string): boolean;
|
|
|
|
isInAny(...paths: string[]): boolean;
|
|
|
|
readonly isIos: boolean;
|
|
|
|
get isMenuOpen(): boolean;
|
|
|
|
// (undocumented)
|
|
|
|
get isPenMode(): boolean;
|
|
|
|
isPointInShape(point: VecLike, shape: TLShape): boolean;
|
|
|
|
// (undocumented)
|
|
|
|
get isReadOnly(): boolean;
|
|
|
|
readonly isSafari: boolean;
|
|
|
|
isSelected(id: TLShapeId): boolean;
|
|
|
|
isShapeInPage(shape: TLShape, pageId?: TLPageId): boolean;
|
|
|
|
isShapeInViewport(id: TLShapeId): boolean;
|
2023-05-23 12:32:42 +00:00
|
|
|
isShapeOfType<T extends TLUnknownShape>(shape: TLUnknownShape, util: {
|
|
|
|
new (...args: any): TLShapeUtil<T>;
|
|
|
|
type: string;
|
|
|
|
}): shape is T;
|
2023-06-01 18:13:38 +00:00
|
|
|
isShapeOrAncestorLocked(shape?: TLShape): boolean;
|
2023-05-11 22:14:58 +00:00
|
|
|
// (undocumented)
|
|
|
|
get isSnapMode(): boolean;
|
|
|
|
// (undocumented)
|
|
|
|
get isToolLocked(): boolean;
|
2023-04-25 11:01:25 +00:00
|
|
|
isWithinSelection(id: TLShapeId): boolean;
|
2023-05-25 09:54:29 +00:00
|
|
|
get locale(): string;
|
2023-04-25 11:01:25 +00:00
|
|
|
mark(reason?: string, onUndo?: boolean, onRedo?: boolean): string;
|
|
|
|
moveShapesToPage(ids: TLShapeId[], pageId: TLPageId): this;
|
|
|
|
nudgeShapes(ids: TLShapeId[], direction: Vec2dModel, major?: boolean, ephemeral?: boolean): this;
|
|
|
|
onCreateAssetFromFile(file: File): Promise<TLAsset>;
|
|
|
|
onCreateBookmarkFromUrl(url: string): Promise<{
|
|
|
|
image: string;
|
|
|
|
title: string;
|
|
|
|
description: string;
|
|
|
|
}>;
|
2023-05-23 12:32:42 +00:00
|
|
|
get onlySelectedShape(): null | TLShape;
|
2023-05-11 22:14:58 +00:00
|
|
|
get openMenus(): string[];
|
2023-04-25 11:01:25 +00:00
|
|
|
packShapes(ids?: TLShapeId[], padding?: number): this;
|
|
|
|
get pages(): TLPage[];
|
|
|
|
get pageState(): TLInstancePageState;
|
|
|
|
pageToScreen(x: number, y: number, z?: number, camera?: Vec2dModel): {
|
|
|
|
x: number;
|
|
|
|
y: number;
|
|
|
|
z: number;
|
|
|
|
};
|
|
|
|
pan(dx: number, dy: number, opts?: AnimationOptions): this;
|
|
|
|
panZoomIntoView(ids: TLShapeId[], opts?: AnimationOptions): this;
|
|
|
|
// (undocumented)
|
|
|
|
popFocusLayer(): this;
|
2023-06-01 18:46:26 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
get projectName(): string;
|
2023-04-25 11:01:25 +00:00
|
|
|
// @internal
|
|
|
|
get props(): null | TLNullableShapeProps;
|
|
|
|
// (undocumented)
|
|
|
|
putContent(content: TLClipboardModel, options?: {
|
|
|
|
point?: VecLike;
|
|
|
|
select?: boolean;
|
|
|
|
preservePosition?: boolean;
|
|
|
|
preserveIds?: boolean;
|
|
|
|
}): this;
|
|
|
|
redo(): this;
|
|
|
|
renamePage(id: TLPageId, name: string, squashing?: boolean): this;
|
|
|
|
get renderingShapes(): {
|
|
|
|
id: TLShapeId;
|
|
|
|
index: number;
|
2023-06-01 15:22:47 +00:00
|
|
|
backgroundIndex: number;
|
2023-04-25 11:01:25 +00:00
|
|
|
opacity: number;
|
|
|
|
isCulled: boolean;
|
|
|
|
isInViewport: boolean;
|
2023-06-01 15:22:47 +00:00
|
|
|
maskedPageBounds: Box2d | undefined;
|
2023-04-25 11:01:25 +00:00
|
|
|
}[];
|
2023-05-11 22:14:58 +00:00
|
|
|
reorderShapes(operation: 'backward' | 'forward' | 'toBack' | 'toFront', ids: TLShapeId[]): this;
|
2023-04-25 11:01:25 +00:00
|
|
|
reparentShapesById(ids: TLShapeId[], parentId: TLParentId, insertIndex?: string): this;
|
|
|
|
// (undocumented)
|
|
|
|
replaceStoreContentsWithRecordsForOtherDocument(records: TLRecord[]): void;
|
|
|
|
resetZoom(point?: Vec2d, opts?: AnimationOptions): this;
|
|
|
|
// (undocumented)
|
|
|
|
resizeShape(id: TLShapeId, scale: VecLike, options?: {
|
|
|
|
initialBounds?: Box2d;
|
|
|
|
scaleOrigin?: VecLike;
|
|
|
|
scaleAxisRotation?: number;
|
|
|
|
initialShape?: TLShape;
|
|
|
|
initialPageTransform?: MatLike;
|
|
|
|
dragHandle?: TLResizeHandle;
|
|
|
|
mode?: TLResizeMode;
|
|
|
|
}): this;
|
|
|
|
readonly root: RootState;
|
|
|
|
rotateShapesBy(ids: TLShapeId[], delta: number): this;
|
|
|
|
screenToPage(x: number, y: number, z?: number, camera?: Vec2dModel): {
|
|
|
|
x: number;
|
|
|
|
y: number;
|
|
|
|
z: number;
|
|
|
|
};
|
|
|
|
// (undocumented)
|
|
|
|
get scribble(): null | TLScribble;
|
|
|
|
select(...ids: TLShapeId[]): this;
|
|
|
|
selectAll(): this;
|
|
|
|
get selectedIds(): TLShapeId[];
|
|
|
|
get selectedIdsSet(): ReadonlySet<TLShapeId>;
|
|
|
|
get selectedPageBounds(): Box2d | null;
|
2023-05-23 12:32:42 +00:00
|
|
|
get selectedShapes(): TLShape[];
|
2023-04-25 11:01:25 +00:00
|
|
|
// (undocumented)
|
|
|
|
get selectionBounds(): Box2d | undefined;
|
|
|
|
// (undocumented)
|
|
|
|
get selectionPageCenter(): null | Vec2d;
|
|
|
|
get selectionRotation(): number;
|
|
|
|
selectNone(): this;
|
|
|
|
sendBackward(ids?: TLShapeId[]): this;
|
|
|
|
sendToBack(ids?: TLShapeId[]): this;
|
2023-05-30 15:22:49 +00:00
|
|
|
// (undocumented)
|
|
|
|
setAnimationSpeed(animationSpeed: number): this;
|
2023-04-25 11:01:25 +00:00
|
|
|
setBrush(brush?: Box2dModel | null): this;
|
|
|
|
setCamera(x: number, y: number, z?: number, { stopFollowing }?: ViewportOptions): this;
|
|
|
|
// (undocumented)
|
|
|
|
setCroppingId(id: null | TLShapeId): this;
|
|
|
|
setCurrentPageId(pageId: TLPageId, { stopFollowing }?: ViewportOptions): this;
|
|
|
|
setCursor(cursor: Partial<TLCursor>): this;
|
|
|
|
// (undocumented)
|
2023-05-11 22:14:58 +00:00
|
|
|
setDarkMode(isDarkMode: boolean): this;
|
2023-04-25 11:01:25 +00:00
|
|
|
setEditingId(id: null | TLShapeId): this;
|
|
|
|
setErasingIds(ids?: TLShapeId[]): this;
|
|
|
|
setFocusLayer(next: null | TLShapeId): this;
|
|
|
|
// (undocumented)
|
2023-05-11 22:14:58 +00:00
|
|
|
setFocusMode(isFocusMode: boolean): this;
|
|
|
|
// (undocumented)
|
|
|
|
setGridMode(isGridMode: boolean): this;
|
2023-04-25 11:01:25 +00:00
|
|
|
setHintingIds(ids: TLShapeId[]): this;
|
|
|
|
setHoveredId(id?: null | TLShapeId): this;
|
|
|
|
setInstancePageState(partial: Partial<TLInstancePageState>, ephemeral?: boolean): void;
|
2023-05-25 09:54:29 +00:00
|
|
|
setLocale(locale: string): void;
|
2023-04-25 11:01:25 +00:00
|
|
|
// (undocumented)
|
2023-05-11 22:14:58 +00:00
|
|
|
setPenMode(isPenMode: boolean): this;
|
2023-06-01 18:46:26 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
setProjectName(name: string): void;
|
2023-04-25 11:01:25 +00:00
|
|
|
setProp(key: TLShapeProp, value: any, ephemeral?: boolean, squashing?: boolean): this;
|
2023-05-17 10:45:43 +00:00
|
|
|
// @internal (undocumented)
|
2023-05-11 22:14:58 +00:00
|
|
|
setReadOnly(isReadOnly: boolean): this;
|
2023-04-25 11:01:25 +00:00
|
|
|
setScribble(scribble?: null | TLScribble): this;
|
|
|
|
setSelectedIds(ids: TLShapeId[], squashing?: boolean): this;
|
|
|
|
setSelectedTool(id: string, info?: {}): this;
|
2023-05-11 22:14:58 +00:00
|
|
|
// (undocumented)
|
|
|
|
setSnapMode(isSnapMode: boolean): this;
|
|
|
|
// (undocumented)
|
|
|
|
setToolLocked(isToolLocked: boolean): this;
|
2023-04-25 11:01:25 +00:00
|
|
|
setZoomBrush(zoomBrush?: Box2dModel | null): this;
|
|
|
|
get shapeIds(): Set<TLShapeId>;
|
|
|
|
get shapesArray(): TLShape[];
|
|
|
|
shapeUtils: {
|
|
|
|
readonly [K in string]?: TLShapeUtil<TLUnknownShape>;
|
|
|
|
};
|
|
|
|
// (undocumented)
|
|
|
|
slideCamera(opts?: {
|
|
|
|
speed: number;
|
|
|
|
direction: Vec2d;
|
|
|
|
friction: number;
|
|
|
|
speedThreshold?: number | undefined;
|
2023-05-30 15:22:49 +00:00
|
|
|
}): this | undefined;
|
2023-04-25 11:01:25 +00:00
|
|
|
readonly snaps: SnapManager;
|
|
|
|
get sortedShapesArray(): TLShape[];
|
|
|
|
stackShapes(operation: 'horizontal' | 'vertical', ids?: TLShapeId[], gap?: number): this;
|
2023-05-25 09:54:29 +00:00
|
|
|
startFollowingUser: (userId: string) => this | undefined;
|
2023-04-25 11:01:25 +00:00
|
|
|
stopCameraAnimation(): this;
|
|
|
|
stopFollowingUser: () => this;
|
|
|
|
readonly store: TLStore;
|
|
|
|
stretchShapes(operation: 'horizontal' | 'vertical', ids?: TLShapeId[]): this;
|
|
|
|
static styles: TLStyleCollections;
|
|
|
|
textMeasure: TextManager;
|
2023-06-01 18:13:38 +00:00
|
|
|
// (undocumented)
|
|
|
|
toggleLock(ids?: TLShapeId[]): this;
|
2023-04-25 11:01:25 +00:00
|
|
|
undo(): HistoryManager<this>;
|
|
|
|
// (undocumented)
|
|
|
|
ungroupShapes(ids?: TLShapeId[]): this;
|
|
|
|
updateAssets(assets: TLAssetPartial[]): this;
|
|
|
|
// @internal
|
|
|
|
updateCullingBounds(): this;
|
2023-06-01 18:46:26 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
updateDocumentSettings(settings: Partial<TLDocument>): void;
|
2023-04-25 11:01:25 +00:00
|
|
|
updateInstanceState(partial: Partial<Omit<TLInstance, 'currentPageId' | 'documentId' | 'userId'>>, ephemeral?: boolean, squashing?: boolean): this;
|
|
|
|
updatePage(partial: RequiredKeys<TLPage, 'id'>, squashing?: boolean): this;
|
|
|
|
updateShapes(partials: (null | TLShapePartial | undefined)[], squashing?: boolean): this;
|
|
|
|
updateUserDocumentSettings(partial: Partial<TLUserDocument>, ephemeral?: boolean): this;
|
|
|
|
updateViewportScreenBounds(center?: boolean): this;
|
2023-05-25 09:54:29 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
readonly user: UserPreferencesManager;
|
2023-04-25 11:01:25 +00:00
|
|
|
// (undocumented)
|
|
|
|
get userDocumentSettings(): TLUserDocument;
|
|
|
|
get viewportPageBounds(): Box2d;
|
|
|
|
get viewportPageCenter(): Vec2d;
|
|
|
|
get viewportScreenBounds(): Box2d;
|
|
|
|
get viewportScreenCenter(): Vec2d;
|
|
|
|
visitDescendants(parentId: TLParentId, visitor: (id: TLShapeId) => false | void): void;
|
|
|
|
// (undocumented)
|
|
|
|
get zoomBrush(): Box2dModel | null;
|
|
|
|
zoomIn(point?: Vec2d, opts?: AnimationOptions): this;
|
|
|
|
get zoomLevel(): number;
|
|
|
|
zoomOut(point?: Vec2d, opts?: AnimationOptions): this;
|
|
|
|
zoomToBounds(x: number, y: number, width: number, height: number, targetZoom?: number, opts?: AnimationOptions): this;
|
2023-05-11 22:14:58 +00:00
|
|
|
zoomToContent(): this;
|
2023-04-25 11:01:25 +00:00
|
|
|
zoomToFit(opts?: AnimationOptions): this;
|
|
|
|
zoomToSelection(opts?: AnimationOptions): this;
|
|
|
|
}
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export function applyRotationToSnapshotShapes({ delta, app, snapshot, stage, }: {
|
|
|
|
delta: number;
|
|
|
|
snapshot: RotationSnapshot;
|
|
|
|
app: App;
|
|
|
|
stage: 'end' | 'one-off' | 'start' | 'update';
|
|
|
|
}): void;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export interface AppOptions {
|
|
|
|
getContainer: () => HTMLElement;
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
shapes?: Record<string, ShapeInfo>;
|
2023-04-25 11:01:25 +00:00
|
|
|
store: TLStore;
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
tools?: StateNodeConstructor[];
|
|
|
|
user?: TLUser;
|
2023-04-25 11:01:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const ARROW_LABEL_FONT_SIZES: Record<TLSizeType, number>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function blobAsString(blob: Blob): Promise<string>;
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const BOUND_ARROW_OFFSET = 10;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
export const Canvas: React_3.MemoExoticComponent<({ onDropOverride, }: {
|
|
|
|
onDropOverride?: ((defaultOnDrop: (e: React_3.DragEvent<Element>) => Promise<void>) => (e: React_3.DragEvent<Element>) => Promise<void>) | undefined;
|
2023-04-25 11:01:25 +00:00
|
|
|
}) => JSX.Element>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const checkFlag: (flag: (() => boolean) | boolean | undefined) => boolean | undefined;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type ClipboardPayload = {
|
|
|
|
data: string;
|
|
|
|
kind: 'file';
|
|
|
|
type: 'application/tldraw';
|
|
|
|
} | {
|
|
|
|
data: string;
|
|
|
|
kind: 'text';
|
|
|
|
type: 'application/tldraw';
|
|
|
|
} | {
|
|
|
|
data: TLClipboardModel;
|
|
|
|
kind: 'content';
|
|
|
|
type: 'application/tldraw';
|
|
|
|
};
|
|
|
|
|
|
|
|
// @public
|
|
|
|
export function containBoxSize(originalSize: BoxWidthHeight, containBoxSize: BoxWidthHeight): BoxWidthHeight;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function correctSpacesToNbsp(input: string): string;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function createAssetShapeAtPoint(app: App, svgString: string, point: Vec2dModel): Promise<void>;
|
|
|
|
|
|
|
|
// @public
|
|
|
|
export function createBookmarkShapeAtPoint(app: App, url: string, point: Vec2dModel): Promise<void>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function createEmbedShapeAtPoint(app: App, url: string, point: Vec2dModel, props: {
|
|
|
|
width?: number;
|
|
|
|
height?: number;
|
|
|
|
doesResize?: boolean;
|
|
|
|
}): void;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function createShapesFromFiles(app: App, files: File[], position: VecLike, _ignoreParent?: boolean): Promise<void>;
|
|
|
|
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
// @public
|
|
|
|
export function createTLStore(opts?: StoreOptions): TLStore;
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export function dataTransferItemAsString(item: DataTransferItem): Promise<string>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function dataUrlToFile(url: string, filename: string, mimeType: string): Promise<File>;
|
|
|
|
|
Feature flags rework (#1474)
This diff tweaks our `debugFlags` framework to support setting different
default value for different environments, makes it easier to define
feature flags, and makes feature flags show up in the debug menu by
default. With this change, feature flags will default to being enabled
in dev and preview environments, but disabled in production.
Specify a feature flag like this:
```ts
const featureFlags = {
myCoolNewFeature: createFeatureFlag('myCoolNewFeature')
}
```
optionally, pass a second value to control its defaults:
```ts
const featureFlags = {
featureEnabledInProduction: createFeatureFlag('someFeature', { all: true }),
customEnabled: createFeatureFlag('otherFeature', {development: true, staging: false, production: false}),
}
```
In code, the value can be read using `featureFlags.myFeature.value`.
Remember to wrap reading it in a reactive context!
### Change Type
- [x] `patch` — Bug Fix
### Test Plan
-
### Release Notes
[internal only change]
2023-05-30 13:06:15 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
export type DebugFlag<T> = DebugFlagDef<T> & Atom<T>;
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
export const debugFlags: {
|
Feature flags rework (#1474)
This diff tweaks our `debugFlags` framework to support setting different
default value for different environments, makes it easier to define
feature flags, and makes feature flags show up in the debug menu by
default. With this change, feature flags will default to being enabled
in dev and preview environments, but disabled in production.
Specify a feature flag like this:
```ts
const featureFlags = {
myCoolNewFeature: createFeatureFlag('myCoolNewFeature')
}
```
optionally, pass a second value to control its defaults:
```ts
const featureFlags = {
featureEnabledInProduction: createFeatureFlag('someFeature', { all: true }),
customEnabled: createFeatureFlag('otherFeature', {development: true, staging: false, production: false}),
}
```
In code, the value can be read using `featureFlags.myFeature.value`.
Remember to wrap reading it in a reactive context!
### Change Type
- [x] `patch` — Bug Fix
### Test Plan
-
### Release Notes
[internal only change]
2023-05-30 13:06:15 +00:00
|
|
|
preventDefaultLogging: DebugFlag<boolean>;
|
|
|
|
pointerCaptureLogging: DebugFlag<boolean>;
|
|
|
|
pointerCaptureTracking: DebugFlag<boolean>;
|
|
|
|
pointerCaptureTrackingObject: DebugFlag<Map<Element, number>>;
|
|
|
|
elementRemovalLogging: DebugFlag<boolean>;
|
|
|
|
debugSvg: DebugFlag<boolean>;
|
|
|
|
throwToBlob: DebugFlag<boolean>;
|
|
|
|
logMessages: DebugFlag<never[]>;
|
|
|
|
resetConnectionEveryPing: DebugFlag<boolean>;
|
|
|
|
debugCursors: DebugFlag<boolean>;
|
[3/3] Highlighter styling (#1490)
This PR finalises the highlighter shape with new colors, sizing, and
perfect freehand options.
The colors are based on our existing colour palette, but take advantage
of wide-gamut displays to make the highlighter highlightier. I used my
[oklch color palette tool to pick the
palette](https://alex.dytry.ch/toys/palette/?palette=%7B%22families%22:%5B%22black%22,%22grey%22,%22white%22,%22green%22,%22light-green%22,%22blue%22,%22light-blue%22,%22violet%22,%22light-violet%22,%22red%22,%22light-red%22,%22orange%22,%22yellow%22%5D,%22shades%22:%5B%22light-mode%22,%22dark-mode%22,%22hl-light%22,%22hl-dark%22%5D,%22colors%22:%5B%5B%5B0.2308,0,null%5D,%5B0.9097,0,null%5D,%5B0.2308,0,null%5D,%5B0.2308,0,null%5D%5D,%5B%5B0.7692,0.0145,248.02%5D,%5B0.6778,0.0118,256.72%5D,%5B0.7692,0.0145,248.02%5D,%5B0.7692,0.0145,248.02%5D%5D,%5B%5B1,0,null%5D,%5B0.2308,0,null%5D,%5B1,0,null%5D,%5B1,0,null%5D%5D,%5B%5B0.5851,0.1227,164.1%5D,%5B0.5319,0.0811,162.23%5D,%5B0.8729,0.2083,173.3%5D,%5B0.5851,0.152,173.3%5D%5D,%5B%5B0.7146,0.1835,146.44%5D,%5B0.6384,0.1262,143.36%5D,%5B0.8603,0.2438,140.11%5D,%5B0.6082,0.2286,140.11%5D%5D,%5B%5B0.5566,0.2082,268.35%5D,%5B0.4961,0.1644,270.65%5D,%5B0.7158,0.173,243.85%5D,%5B0.5573,0.178,243.85%5D%5D,%5B%5B0.718,0.1422,246.06%5D,%5B0.6366,0.1055,250.98%5D,%5B0.8615,0.1896,200.03%5D,%5B0.707,0.161,200.03%5D%5D,%5B%5B0.5783,0.2186,319.15%5D,%5B0.5043,0.1647,315.37%5D,%5B0.728,0.2001,307.45%5D,%5B0.5433,0.2927,307.45%5D%5D,%5B%5B0.7904,0.1516,319.77%5D,%5B0.6841,0.1139,315.99%5D,%5B0.812,0.21,327.8%5D,%5B0.5668,0.281,327.8%5D%5D,%5B%5B0.5928,0.2106,26.53%5D,%5B0.5112,0.1455,26.18%5D,%5B0.7326,0.21,20.59%5D,%5B0.554,0.2461,20.59%5D%5D,%5B%5B0.7563,0.146,21.1%5D,%5B0.6561,0.0982,20.86%5D,%5B0.7749,0.178,6.8%5D,%5B0.5565,0.2454,6.8%5D%5D,%5B%5B0.6851,0.1954,44.57%5D,%5B0.5958,0.1366,46.6%5D,%5B0.8207,0.175,68.62%5D,%5B0.6567,0.164,68.61%5D%5D,%5B%5B0.8503,0.1149,68.95%5D,%5B0.7404,0.0813,72.25%5D,%5B0.8939,0.2137,100.36%5D,%5B0.7776,0.186,100.36%5D%5D%5D%7D&selected=3).
I'm not sure happy about these colors as they are right now - in
particular, i think dark mode looks a bit rubbish and there are a few
colors where the highlight and original version are much too similar
(light-violet & light-red). Black uses yellow (like note shape) and grey
uses light-blue. Exports are forced into srgb color space rather than P3
for maximum compatibility.
![image](https://github.com/tldraw/tldraw/assets/1489520/e3de762b-6ef7-4d17-87db-3e2b71dd8de1)
![image](https://github.com/tldraw/tldraw/assets/1489520/3bd90aa9-bdbc-4a2b-9e56-e3a83a2a877b)
The size of a highlighter stroke is now based on the text size which
works nicely for making the highlighter play well with text:
![image](https://github.com/tldraw/tldraw/assets/1489520/dd3184fc-decd-4db5-90ce-e9cc75edd3d6)
Perfect freehands settings are very similar to the draw tool, but with
the thinning turned way down. There is still some, but it's pretty
minimal.
### The plan
1. initial highlighter shape/tool #1401
2. sandwich rendering for highlighter shapes #1418
3. shape styling - new colours and sizes, lightweight perfect freehand
changes #1490 **>you are here<**
### Change Type
- [x] `minor` — New Feature
### Test Plan
1. You can find the highlighter tool in the extended toolbar
2. You can activate the highlighter tool by pressing shift-D
3. Highlighter draws nice and vibrantly when over the page background or
frame background
4. Highlighter is less vibrant but still visible when drawn over images
/ other fills
5. Highlighter size should nicely match the corresponding unscaled text
size
6. Exports with highlighter look as expected
### Release Notes
Highlighter pen is here! 🎉🎉🎉
---------
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
2023-06-01 15:34:59 +00:00
|
|
|
forceSrgb: DebugFlag<boolean>;
|
2023-04-25 11:01:25 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const DEFAULT_ANIMATION_OPTIONS: {
|
|
|
|
duration: number;
|
|
|
|
easing: (t: number) => number;
|
|
|
|
};
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const DEFAULT_BOOKMARK_HEIGHT = 320;
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const DEFAULT_BOOKMARK_WIDTH = 300;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
2023-05-05 13:10:36 +00:00
|
|
|
export let defaultEditorAssetUrls: EditorAssetUrls;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function defaultEmptyAs(str: string, dflt: string): string;
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const DefaultErrorFallback: TLErrorFallback;
|
|
|
|
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const defaultShapes: Record<string, ShapeInfo>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const defaultTools: StateNodeConstructor[];
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
export const DOUBLE_CLICK_DURATION = 450;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function downloadDataURLAsFile(dataUrl: string, filename: string): void;
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const DRAG_DISTANCE = 4;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type EditorAssetUrls = {
|
|
|
|
fonts: {
|
|
|
|
monospace: string;
|
|
|
|
serif: string;
|
|
|
|
sansSerif: string;
|
|
|
|
draw: string;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type EmbedResult = {
|
|
|
|
definition: EmbedDefinition;
|
|
|
|
url: string;
|
|
|
|
embedUrl: string;
|
|
|
|
} | undefined;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
export class ErrorBoundary extends React_3.Component<React_3.PropsWithRef<React_3.PropsWithChildren<ErrorBoundaryProps>>, ErrorBoundaryState> {
|
2023-04-25 11:01:25 +00:00
|
|
|
// (undocumented)
|
|
|
|
componentDidCatch(error: unknown): void;
|
|
|
|
// (undocumented)
|
|
|
|
static getDerivedStateFromError(error: Error): {
|
|
|
|
error: Error;
|
|
|
|
};
|
|
|
|
// (undocumented)
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
render(): React_3.ReactNode;
|
2023-04-25 11:01:25 +00:00
|
|
|
// (undocumented)
|
|
|
|
state: ErrorBoundaryState;
|
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export interface ErrorBoundaryProps {
|
|
|
|
// (undocumented)
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
children: React_3.ReactNode;
|
2023-04-25 11:01:25 +00:00
|
|
|
// (undocumented)
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
fallback: (error: unknown) => React_3.ReactNode;
|
2023-04-25 11:01:25 +00:00
|
|
|
// (undocumented)
|
|
|
|
onError?: ((error: unknown) => void) | null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function ErrorScreen({ children }: {
|
|
|
|
children: any;
|
|
|
|
}): JSX.Element;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const EVENT_NAME_MAP: Record<Exclude<TLEventName, TLPinchEventName>, keyof TLEventHandlers>;
|
|
|
|
|
Feature flags rework (#1474)
This diff tweaks our `debugFlags` framework to support setting different
default value for different environments, makes it easier to define
feature flags, and makes feature flags show up in the debug menu by
default. With this change, feature flags will default to being enabled
in dev and preview environments, but disabled in production.
Specify a feature flag like this:
```ts
const featureFlags = {
myCoolNewFeature: createFeatureFlag('myCoolNewFeature')
}
```
optionally, pass a second value to control its defaults:
```ts
const featureFlags = {
featureEnabledInProduction: createFeatureFlag('someFeature', { all: true }),
customEnabled: createFeatureFlag('otherFeature', {development: true, staging: false, production: false}),
}
```
In code, the value can be read using `featureFlags.myFeature.value`.
Remember to wrap reading it in a reactive context!
### Change Type
- [x] `patch` — Bug Fix
### Test Plan
-
### Release Notes
[internal only change]
2023-05-30 13:06:15 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
export const featureFlags: {
|
|
|
|
peopleMenu: DebugFlag<boolean>;
|
2023-06-01 12:46:13 +00:00
|
|
|
highlighterTool: DebugFlag<boolean>;
|
Feature flags rework (#1474)
This diff tweaks our `debugFlags` framework to support setting different
default value for different environments, makes it easier to define
feature flags, and makes feature flags show up in the debug menu by
default. With this change, feature flags will default to being enabled
in dev and preview environments, but disabled in production.
Specify a feature flag like this:
```ts
const featureFlags = {
myCoolNewFeature: createFeatureFlag('myCoolNewFeature')
}
```
optionally, pass a second value to control its defaults:
```ts
const featureFlags = {
featureEnabledInProduction: createFeatureFlag('someFeature', { all: true }),
customEnabled: createFeatureFlag('otherFeature', {development: true, staging: false, production: false}),
}
```
In code, the value can be read using `featureFlags.myFeature.value`.
Remember to wrap reading it in a reactive context!
### Change Type
- [x] `patch` — Bug Fix
### Test Plan
-
### Release Notes
[internal only change]
2023-05-30 13:06:15 +00:00
|
|
|
};
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @public
|
|
|
|
export function fileToBase64(file: Blob): Promise<string>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const FONT_ALIGNMENT: Record<TLAlignType, string>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const FONT_FAMILIES: Record<TLFontType, string>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const FONT_SIZES: Record<TLSizeType, number>;
|
|
|
|
|
|
|
|
// @public
|
|
|
|
export function getEmbedInfo(inputUrl: string): EmbedResult;
|
|
|
|
|
|
|
|
// @public
|
|
|
|
export function getEmbedInfoUnsafely(inputUrl: string): EmbedResult;
|
|
|
|
|
|
|
|
// @public
|
|
|
|
export function getFileMetaData(file: File): Promise<{
|
|
|
|
isAnimated: boolean;
|
|
|
|
}>;
|
|
|
|
|
|
|
|
export { getHashForString }
|
|
|
|
|
|
|
|
// @public
|
|
|
|
export function getImageSizeFromSrc(dataURL: string): Promise<{
|
|
|
|
w: number;
|
|
|
|
h: number;
|
|
|
|
}>;
|
|
|
|
|
|
|
|
// @public
|
|
|
|
export function getIncrementedName(name: string, others: string[]): string;
|
|
|
|
|
2023-05-22 08:18:01 +00:00
|
|
|
export { getIndexAbove }
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-05-22 08:18:01 +00:00
|
|
|
export { getIndexBelow }
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-05-22 08:18:01 +00:00
|
|
|
export { getIndexBetween }
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-05-22 08:18:01 +00:00
|
|
|
export { getIndices }
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-05-22 08:18:01 +00:00
|
|
|
export { getIndicesAbove }
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-05-22 08:18:01 +00:00
|
|
|
export { getIndicesBelow }
|
2023-04-25 11:01:25 +00:00
|
|
|
|
2023-05-22 08:18:01 +00:00
|
|
|
export { getIndicesBetween }
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public
|
|
|
|
export function getMediaAssetFromFile(file: File): Promise<TLAsset>;
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export function getPointerInfo(e: PointerEvent | React.PointerEvent, container: HTMLElement): {
|
|
|
|
point: {
|
|
|
|
x: number;
|
|
|
|
y: number;
|
|
|
|
z: number;
|
|
|
|
};
|
|
|
|
shiftKey: boolean;
|
|
|
|
altKey: boolean;
|
|
|
|
ctrlKey: boolean;
|
|
|
|
pointerId: number;
|
|
|
|
button: number;
|
|
|
|
isPen: boolean;
|
|
|
|
};
|
|
|
|
|
|
|
|
// @public
|
|
|
|
export function getResizedImageDataUrl(dataURLForImage: string, width: number, height: number): Promise<string>;
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export function getRotationSnapshot({ app }: {
|
|
|
|
app: App;
|
|
|
|
}): {
|
|
|
|
selectionPageCenter: Vec2d;
|
|
|
|
initialCursorAngle: number;
|
|
|
|
initialSelectionRotation: number;
|
|
|
|
shapeSnapshots: {
|
2023-05-23 12:32:42 +00:00
|
|
|
shape: TLShape;
|
2023-04-25 11:01:25 +00:00
|
|
|
initialPagePoint: Vec2d;
|
|
|
|
}[];
|
|
|
|
};
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function getSplineForLineShape(shape: TLLineShape): NonNullable<CubicSpline2d | Polyline2d>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function getSvgAsDataUrl(svg: SVGElement): Promise<string>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function getSvgAsDataUrlSync(node: SVGElement): string;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function getSvgAsImage(svg: SVGElement, options: {
|
|
|
|
type: TLCopyType | TLExportType;
|
|
|
|
quality: number;
|
|
|
|
scale: number;
|
|
|
|
}): Promise<Blob | null>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function getSvgAsString(svg: SVGElement): string;
|
|
|
|
|
|
|
|
// @public
|
|
|
|
export function getSvgPathFromStroke(points: Vec2d[], closed?: boolean): string;
|
|
|
|
|
|
|
|
// @public
|
|
|
|
export function getSvgPathFromStrokePoints(points: StrokePoint[], closed?: boolean): string;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function getTextBoundingBox(text: SVGTextElement): DOMRect;
|
|
|
|
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export function getUserPreferences(): TLUserPreferences;
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const getValidHttpURLList: (url: string) => string[] | undefined;
|
|
|
|
|
|
|
|
// @public
|
|
|
|
export function getVideoSizeFromSrc(src: string): Promise<{
|
|
|
|
w: number;
|
|
|
|
h: number;
|
|
|
|
}>;
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const GRID_INCREMENT = 5;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const GRID_STEPS: {
|
|
|
|
min: number;
|
|
|
|
mid: number;
|
|
|
|
step: number;
|
|
|
|
}[];
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const HAND_TOOL_FRICTION = 0.09;
|
|
|
|
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
// @public
|
|
|
|
export function hardReset({ shouldReload }?: {
|
|
|
|
shouldReload?: boolean | undefined;
|
|
|
|
}): Promise<void>;
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export function hardResetApp(): void;
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const HASH_PATERN_ZOOM_NAMES: Record<string, string>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function HTMLContainer({ children, className, ...rest }: HTMLContainerProps): JSX.Element;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
export type HTMLContainerProps = React_3.HTMLAttributes<HTMLDivElement>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const ICON_SIZES: Record<TLSizeType, number>;
|
|
|
|
|
[improvement] refactor paste to support multi-line text (#1398)
This PR refactors our clipboard handlers. It should simplify the way
that things work and better handle the difference between how the native
API events are handled vs. the browser's clipboard API events.
![Kapture 2023-05-17 at 13 26
34](https://github.com/tldraw/tldraw/assets/23072548/5dedcc25-a1d2-423f-8bc2-415f761b643b)
Everything that used to be supported now also still works.
In addition, we now have several useful features:
### Multiline text can be pasted into the app
When pasting text that contains more than one line, the text is pasted
correctly; even if the clipboard also includes HTML data. Previously, we
would try to paste HTML data if we found it, because that data might
contain tldraw's own content as a comment; but if that failed, we would
paste the data as text instead. This led to pasting text that lost lots
of information from that text, such as line breaks and indentations.
### Multiline text shapes are aligned correctly
When pasting raw text that has more than one line, the text will be left
aligned—or right aligned if the text is likely from a RTL language.
![Kapture 2023-05-17 at 13 42
54](https://github.com/tldraw/tldraw/assets/23072548/f705acd5-136c-4144-80da-6e97ff766a58)
### Common minimum indentation is removed from each line
![Kapture 2023-05-17 at 13 56
28](https://github.com/tldraw/tldraw/assets/23072548/d45c95f6-6d28-4c9f-8cd3-8078700ce928)
This is something that absolutely every app should implement, but here
we go. When multiline text has "common indentation" on each line, which
is often the case when pasting text from code, then that indentation is
removed from each line.
### Auto wrapping for big pastes
When a line has no text breaks but a lot of text, we now set the width
of the text shape.
![Kapture 2023-05-17 at 14 00
04](https://github.com/tldraw/tldraw/assets/23072548/0b7f69c3-bcf9-42e9-a1ed-df026f868793)
## How it works
A `ClipboardThing` is the common interface for things that we found on
the clipboard, native or otherwise. Both `handlePasteFromClipboardApi`
and `handlePasteFromEventClipboardData` parse out `ClipboardThing`s and
pass them to `handleClipboardThings`.
<img width="905" alt="image"
src="https://github.com/tldraw/tldraw/assets/23072548/fd087539-edbb-4527-b5ff-ca7d7c1726b2">
A `ClipboardResult` is the result of processing a `ClipboardThing`, and
usually contains text and other information about that text. We make
decisions on what to create based on which `ClipboardResult`s we find.
When pasting text, we check to see whether the result would be bigger
than the viewport, or if the text is multiline, or if the text is of an
RTL language by testing certain common RTL characters. We make some
adjustments based on those factors, ensuring that the top-left corner of
the text is on screen and reasonably positioned within the viewport if
possible.
### Change Type
- [x] `minor` — New Feature
### Test Plan
1. Copy and paste shapes
2. Copy and paste text from elsewhere into the app
3. Copy and paste images from elsewhere into the app
4. Try on different browsers
### Release Notes
- Improves clipboard logic when pasting text
- Adds support for pasting multi-line text
- Adds maximum widths when pasting single-line text
- Adds support for RTL languages when pasting multi-line or wrapped text
- Strips leading indentation when pasting text
2023-05-17 16:32:25 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const INDENT = " ";
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @public
|
|
|
|
export function isAnimated(buffer: ArrayBuffer): boolean;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function isGeoShape(shape: TLShape): shape is TLGeoShape;
|
|
|
|
|
|
|
|
// @public
|
|
|
|
export function isGIF(buffer: ArrayBuffer): boolean;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const isImage: (ext: string) => boolean;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function isNoteShape(shape: TLShape): shape is TLNoteShape;
|
|
|
|
|
|
|
|
// @public
|
|
|
|
export function isSerializable(value: any): boolean;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function isShapeWithHandles(shape: TLShape): boolean;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const isSvgText: (text: string) => boolean;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const isValidHttpURL: (url: string) => boolean;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const LABEL_FONT_SIZES: Record<TLSizeType, number>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function LoadingScreen({ children }: {
|
|
|
|
children: any;
|
|
|
|
}): JSX.Element;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function loopToHtmlElement(elm: Element): HTMLElement;
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const MAJOR_NUDGE_FACTOR = 10;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function matchEmbedUrl(url: string): {
|
|
|
|
definition: {
|
|
|
|
readonly type: "codepen";
|
|
|
|
readonly title: "Codepen";
|
|
|
|
readonly hostnames: readonly ["codepen.io"];
|
|
|
|
readonly minWidth: 300;
|
|
|
|
readonly minHeight: 300;
|
|
|
|
readonly width: 520;
|
|
|
|
readonly height: 400;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "codesandbox";
|
|
|
|
readonly title: "CodeSandbox";
|
|
|
|
readonly hostnames: readonly ["codesandbox.io"];
|
|
|
|
readonly minWidth: 300;
|
|
|
|
readonly minHeight: 300;
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "excalidraw";
|
|
|
|
readonly title: "Excalidraw";
|
|
|
|
readonly hostnames: readonly ["excalidraw.com"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly isAspectRatioLocked: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "felt";
|
|
|
|
readonly title: "Felt";
|
|
|
|
readonly hostnames: readonly ["felt.com"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "figma";
|
|
|
|
readonly title: "Figma";
|
|
|
|
readonly hostnames: readonly ["figma.com"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "github_gist";
|
|
|
|
readonly title: "GitHub Gist";
|
|
|
|
readonly hostnames: readonly ["gist.github.com"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "google_calendar";
|
|
|
|
readonly title: "Google Calendar";
|
|
|
|
readonly hostnames: readonly ["calendar.google.*"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly minWidth: 460;
|
|
|
|
readonly minHeight: 360;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly instructionLink: "https://support.google.com/calendar/answer/41207?hl=en";
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "google_maps";
|
|
|
|
readonly title: "Google Maps";
|
|
|
|
readonly hostnames: readonly ["google.*"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "google_slides";
|
|
|
|
readonly title: "Google Slides";
|
|
|
|
readonly hostnames: readonly ["docs.google.*"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly minWidth: 460;
|
|
|
|
readonly minHeight: 360;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "observable";
|
|
|
|
readonly title: "Observable";
|
|
|
|
readonly hostnames: readonly ["observablehq.com"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly isAspectRatioLocked: false;
|
|
|
|
readonly backgroundColor: "#fff";
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "replit";
|
|
|
|
readonly title: "Replit";
|
|
|
|
readonly hostnames: readonly ["replit.com"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "scratch";
|
|
|
|
readonly title: "Scratch";
|
|
|
|
readonly hostnames: readonly ["scratch.mit.edu"];
|
|
|
|
readonly width: 520;
|
|
|
|
readonly height: 400;
|
|
|
|
readonly doesResize: false;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "spotify";
|
|
|
|
readonly title: "Spotify";
|
|
|
|
readonly hostnames: readonly ["open.spotify.com"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly minHeight: 500;
|
|
|
|
readonly overrideOutlineRadius: 12;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "tldraw";
|
|
|
|
readonly title: "tldraw";
|
|
|
|
readonly hostnames: readonly ["beta.tldraw.com", "lite.tldraw.com", "www.tldraw.com"];
|
|
|
|
readonly minWidth: 300;
|
|
|
|
readonly minHeight: 300;
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "vimeo";
|
|
|
|
readonly title: "Vimeo";
|
|
|
|
readonly hostnames: readonly ["vimeo.com", "player.vimeo.com"];
|
|
|
|
readonly width: 640;
|
|
|
|
readonly height: 360;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly isAspectRatioLocked: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "youtube";
|
|
|
|
readonly title: "YouTube";
|
|
|
|
readonly hostnames: readonly ["*.youtube.com", "youtube.com", "youtu.be"];
|
|
|
|
readonly width: 800;
|
|
|
|
readonly height: 450;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly overridePermissions: {
|
|
|
|
readonly 'allow-presentation': true;
|
|
|
|
};
|
|
|
|
readonly isAspectRatioLocked: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
};
|
|
|
|
url: string;
|
|
|
|
embedUrl: string;
|
|
|
|
} | undefined;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function matchUrl(url: string): {
|
|
|
|
definition: {
|
|
|
|
readonly type: "codepen";
|
|
|
|
readonly title: "Codepen";
|
|
|
|
readonly hostnames: readonly ["codepen.io"];
|
|
|
|
readonly minWidth: 300;
|
|
|
|
readonly minHeight: 300;
|
|
|
|
readonly width: 520;
|
|
|
|
readonly height: 400;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "codesandbox";
|
|
|
|
readonly title: "CodeSandbox";
|
|
|
|
readonly hostnames: readonly ["codesandbox.io"];
|
|
|
|
readonly minWidth: 300;
|
|
|
|
readonly minHeight: 300;
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "excalidraw";
|
|
|
|
readonly title: "Excalidraw";
|
|
|
|
readonly hostnames: readonly ["excalidraw.com"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly isAspectRatioLocked: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "felt";
|
|
|
|
readonly title: "Felt";
|
|
|
|
readonly hostnames: readonly ["felt.com"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "figma";
|
|
|
|
readonly title: "Figma";
|
|
|
|
readonly hostnames: readonly ["figma.com"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "github_gist";
|
|
|
|
readonly title: "GitHub Gist";
|
|
|
|
readonly hostnames: readonly ["gist.github.com"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "google_calendar";
|
|
|
|
readonly title: "Google Calendar";
|
|
|
|
readonly hostnames: readonly ["calendar.google.*"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly minWidth: 460;
|
|
|
|
readonly minHeight: 360;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly instructionLink: "https://support.google.com/calendar/answer/41207?hl=en";
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "google_maps";
|
|
|
|
readonly title: "Google Maps";
|
|
|
|
readonly hostnames: readonly ["google.*"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "google_slides";
|
|
|
|
readonly title: "Google Slides";
|
|
|
|
readonly hostnames: readonly ["docs.google.*"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly minWidth: 460;
|
|
|
|
readonly minHeight: 360;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "observable";
|
|
|
|
readonly title: "Observable";
|
|
|
|
readonly hostnames: readonly ["observablehq.com"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly isAspectRatioLocked: false;
|
|
|
|
readonly backgroundColor: "#fff";
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "replit";
|
|
|
|
readonly title: "Replit";
|
|
|
|
readonly hostnames: readonly ["replit.com"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "scratch";
|
|
|
|
readonly title: "Scratch";
|
|
|
|
readonly hostnames: readonly ["scratch.mit.edu"];
|
|
|
|
readonly width: 520;
|
|
|
|
readonly height: 400;
|
|
|
|
readonly doesResize: false;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "spotify";
|
|
|
|
readonly title: "Spotify";
|
|
|
|
readonly hostnames: readonly ["open.spotify.com"];
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly minHeight: 500;
|
|
|
|
readonly overrideOutlineRadius: 12;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "tldraw";
|
|
|
|
readonly title: "tldraw";
|
|
|
|
readonly hostnames: readonly ["beta.tldraw.com", "lite.tldraw.com", "www.tldraw.com"];
|
|
|
|
readonly minWidth: 300;
|
|
|
|
readonly minHeight: 300;
|
|
|
|
readonly width: 720;
|
|
|
|
readonly height: 500;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "vimeo";
|
|
|
|
readonly title: "Vimeo";
|
|
|
|
readonly hostnames: readonly ["vimeo.com", "player.vimeo.com"];
|
|
|
|
readonly width: 640;
|
|
|
|
readonly height: 360;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly isAspectRatioLocked: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
} | {
|
|
|
|
readonly type: "youtube";
|
|
|
|
readonly title: "YouTube";
|
|
|
|
readonly hostnames: readonly ["*.youtube.com", "youtube.com", "youtu.be"];
|
|
|
|
readonly width: 800;
|
|
|
|
readonly height: 450;
|
|
|
|
readonly doesResize: true;
|
|
|
|
readonly overridePermissions: {
|
|
|
|
readonly 'allow-presentation': true;
|
|
|
|
};
|
|
|
|
readonly isAspectRatioLocked: true;
|
|
|
|
readonly toEmbedUrl: (url: string) => string | undefined;
|
|
|
|
readonly fromEmbedUrl: (url: string) => string | undefined;
|
|
|
|
};
|
|
|
|
embedUrl: string;
|
|
|
|
url: string;
|
|
|
|
} | undefined;
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const MAX_ASSET_HEIGHT = 1000;
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const MAX_ASSET_WIDTH = 1000;
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const MAX_PAGES = 40;
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const MAX_SHAPES_PER_PAGE = 2000;
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const MAX_ZOOM = 8;
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const MIN_ARROW_LENGTH = 48;
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const MIN_ZOOM = 0.1;
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const MINOR_NUDGE_FACTOR = 1;
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const MULTI_CLICK_DURATION = 200;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function normalizeWheel(event: React.WheelEvent<HTMLElement> | WheelEvent): {
|
|
|
|
x: number;
|
|
|
|
y: number;
|
|
|
|
z: number;
|
|
|
|
};
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type OnBeforeCreateHandler<T extends TLShape> = (next: T) => T | void;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type OnBeforeUpdateHandler<T extends TLShape> = (prev: T, next: T) => T | void;
|
|
|
|
|
add docs for TLShapeUtil (#1215)
This PR adds docs for the methods in the TLShapeUtil class.
I think that it's a good page to have docs on, as it shows people what's
possible with the custom shape API.
Currently, our docs are not showing `@param` info for lots of methods,
including the ones added in this PR.
I'll do fix for that in a follow-up PR, so that it's easier to review.
---
Note: Moving forward, we probably want to consider **_where_** these
docs are shown, and how we achieve that.
For example, do we put the docs for these methods in:
* The docs page for the `TLShapeUtil` class?
* The docs pages for the handler types, eg:
[`OnResizeHandler`](http://localhost:3000/gen/editor/OnResizeHandler-type)?
* Both?
Right now, I opted for putting them in the the TLShapeUtil class, as it
keeps them all in one place, and it's what we already do for some
others.
We should consider both - what works best for the docs? and what works
best for code editors?
---
This PR also includes a fix to our pre-commit step that @SomeHats did.
2023-05-05 14:05:25 +00:00
|
|
|
// @internal (undocumented)
|
2023-04-25 11:01:25 +00:00
|
|
|
export type OnBindingChangeHandler<T extends TLShape> = (shape: T) => TLShapePartial<T> | void;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type OnChildrenChangeHandler<T extends TLShape> = (shape: T) => TLShapePartial[] | void;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type OnClickHandler<T extends TLShape> = (shape: T) => TLShapePartial<T> | void;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type OnDoubleClickHandleHandler<T extends TLShape> = (shape: T, handle: TLHandle) => TLShapePartial<T> | void;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type OnDoubleClickHandler<T extends TLShape> = (shape: T) => TLShapePartial<T> | void;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type OnDragHandler<T extends TLShape, R = void> = (shape: T, shapes: TLShape[]) => R;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type OnEditEndHandler<T extends TLShape> = (shape: T) => void;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type OnHandleChangeHandler<T extends TLShape> = (shape: T, info: {
|
|
|
|
handle: TLHandle;
|
|
|
|
isPrecise: boolean;
|
|
|
|
}) => TLShapePartial<T> | void;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type OnResizeEndHandler<T extends TLShape> = EventChangeHandler<T>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
add docs for TLShapeUtil (#1215)
This PR adds docs for the methods in the TLShapeUtil class.
I think that it's a good page to have docs on, as it shows people what's
possible with the custom shape API.
Currently, our docs are not showing `@param` info for lots of methods,
including the ones added in this PR.
I'll do fix for that in a follow-up PR, so that it's easier to review.
---
Note: Moving forward, we probably want to consider **_where_** these
docs are shown, and how we achieve that.
For example, do we put the docs for these methods in:
* The docs page for the `TLShapeUtil` class?
* The docs pages for the handler types, eg:
[`OnResizeHandler`](http://localhost:3000/gen/editor/OnResizeHandler-type)?
* Both?
Right now, I opted for putting them in the the TLShapeUtil class, as it
keeps them all in one place, and it's what we already do for some
others.
We should consider both - what works best for the docs? and what works
best for code editors?
---
This PR also includes a fix to our pre-commit step that @SomeHats did.
2023-05-05 14:05:25 +00:00
|
|
|
export type OnResizeHandler<T extends TLShape> = (shape: T, info: TLResizeInfo<T>) => Partial<TLShapePartial<T>> | undefined | void;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type OnResizeStartHandler<T extends TLShape> = EventStartHandler<T>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type OnRotateEndHandler<T extends TLShape> = EventChangeHandler<T>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type OnRotateHandler<T extends TLShape> = EventChangeHandler<T>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type OnRotateStartHandler<T extends TLShape> = EventStartHandler<T>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type OnTranslateEndHandler<T extends TLShape> = EventChangeHandler<T>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type OnTranslateHandler<T extends TLShape> = EventChangeHandler<T>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type OnTranslateStartHandler<T extends TLShape> = EventStartHandler<T>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function openWindow(url: string, target?: string): void;
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export function OptionalErrorBoundary({ children, fallback, ...props }: Omit<ErrorBoundaryProps, 'fallback'> & {
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
fallback: ((error: unknown) => React_3.ReactNode) | null;
|
2023-04-25 11:01:25 +00:00
|
|
|
}): JSX.Element;
|
|
|
|
|
|
|
|
// @public
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
export function preventDefault(event: Event | React_2.BaseSyntheticEvent): void;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function refreshPage(): void;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
export function releasePointerCapture(element: Element, event: PointerEvent | React_2.PointerEvent<Element>): void;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const REMOVE_SYMBOL: unique symbol;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type RequiredKeys<T, K extends keyof T> = Pick<T, K> & Partial<T>;
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const RICH_TYPES: Record<string, boolean>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function rotateBoxShadow(rotation: number, shadows: {
|
|
|
|
offsetX: number;
|
|
|
|
offsetY: number;
|
|
|
|
blur: number;
|
|
|
|
spread: number;
|
|
|
|
color: string;
|
|
|
|
}[]): string;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const ROTATING_SHADOWS: {
|
|
|
|
offsetX: number;
|
|
|
|
offsetY: number;
|
|
|
|
blur: number;
|
|
|
|
spread: number;
|
|
|
|
color: string;
|
|
|
|
}[];
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export type RotationSnapshot = ReturnType<typeof getRotationSnapshot>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const runtime: {
|
|
|
|
openWindow: (url: string, target: string) => void;
|
|
|
|
refreshPage: () => void;
|
|
|
|
hardReset: () => void;
|
|
|
|
};
|
|
|
|
|
2023-05-05 13:10:36 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
export function setDefaultEditorAssetUrls(assetUrls: EditorAssetUrls): void;
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @public (undocumented)
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
export function setPointerCapture(element: Element, event: PointerEvent | React_2.PointerEvent<Element>): void;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function setPropsForNextShape(previousProps: TLInstancePropsForNextShape, newProps: Partial<TLShapeProps>): TLInstancePropsForNextShape;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function setRuntimeOverrides(input: Partial<typeof runtime>): void;
|
|
|
|
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export function setUserPreferences(user: TLUserPreferences): void;
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export function snapToGrid(n: number, gridSize: number): number;
|
|
|
|
|
2023-05-22 08:18:01 +00:00
|
|
|
export { sortByIndex }
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export abstract class StateNode implements Partial<TLEventHandlers> {
|
|
|
|
constructor(app: App, parent?: StateNode);
|
|
|
|
// (undocumented)
|
|
|
|
app: App;
|
|
|
|
// (undocumented)
|
|
|
|
static children?: () => StateNodeConstructor[];
|
|
|
|
// (undocumented)
|
|
|
|
children?: Record<string, StateNode>;
|
|
|
|
// (undocumented)
|
|
|
|
current: Atom<StateNode | undefined>;
|
|
|
|
// (undocumented)
|
|
|
|
enter(info: any, from: string): void;
|
|
|
|
// (undocumented)
|
|
|
|
exit(info: any, from: string): void;
|
|
|
|
// (undocumented)
|
|
|
|
handleEvent(info: Exclude<TLEventInfo, TLPinchEventInfo>): void;
|
|
|
|
// (undocumented)
|
|
|
|
static id: string;
|
|
|
|
// (undocumented)
|
|
|
|
id: string;
|
|
|
|
// (undocumented)
|
|
|
|
static initial?: string;
|
|
|
|
// (undocumented)
|
|
|
|
initial?: string;
|
|
|
|
// (undocumented)
|
|
|
|
isActive: boolean;
|
|
|
|
// (undocumented)
|
|
|
|
onCancel?: TLEventHandlers['onCancel'];
|
|
|
|
// (undocumented)
|
|
|
|
onComplete?: TLEventHandlers['onComplete'];
|
|
|
|
// (undocumented)
|
|
|
|
onDoubleClick?: TLEventHandlers['onDoubleClick'];
|
|
|
|
// (undocumented)
|
|
|
|
onEnter?: UiEnterHandler;
|
|
|
|
// (undocumented)
|
|
|
|
onExit?: UiExitHandler;
|
|
|
|
// (undocumented)
|
|
|
|
onInterrupt?: TLEventHandlers['onInterrupt'];
|
|
|
|
// (undocumented)
|
|
|
|
onKeyDown?: TLEventHandlers['onKeyDown'];
|
|
|
|
// (undocumented)
|
|
|
|
onKeyRepeat?: TLEventHandlers['onKeyRepeat'];
|
|
|
|
// (undocumented)
|
|
|
|
onKeyUp?: TLEventHandlers['onKeyUp'];
|
|
|
|
// (undocumented)
|
|
|
|
onMiddleClick?: TLEventHandlers['onMiddleClick'];
|
|
|
|
// (undocumented)
|
|
|
|
onPointerDown?: TLEventHandlers['onPointerDown'];
|
|
|
|
// (undocumented)
|
|
|
|
onPointerEnter?: TLEventHandlers['onPointerEnter'];
|
|
|
|
// (undocumented)
|
|
|
|
onPointerLeave?: TLEventHandlers['onPointerLeave'];
|
|
|
|
// (undocumented)
|
|
|
|
onPointerMove?: TLEventHandlers['onPointerMove'];
|
|
|
|
// (undocumented)
|
|
|
|
onPointerUp?: TLEventHandlers['onPointerUp'];
|
|
|
|
// (undocumented)
|
|
|
|
onQuadrupleClick?: TLEventHandlers['onQuadrupleClick'];
|
|
|
|
// (undocumented)
|
|
|
|
onRightClick?: TLEventHandlers['onRightClick'];
|
|
|
|
// (undocumented)
|
|
|
|
onTripleClick?: TLEventHandlers['onTripleClick'];
|
|
|
|
// (undocumented)
|
|
|
|
onWheel?: TLEventHandlers['onWheel'];
|
|
|
|
// (undocumented)
|
|
|
|
parent: StateNode;
|
|
|
|
// (undocumented)
|
|
|
|
path: Computed<string>;
|
|
|
|
// (undocumented)
|
|
|
|
readonly styles: TLStyleType[];
|
|
|
|
// (undocumented)
|
|
|
|
transition(id: string, info: any): this;
|
|
|
|
// (undocumented)
|
|
|
|
type: StateNodeType;
|
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export interface StateNodeConstructor {
|
|
|
|
// (undocumented)
|
|
|
|
new (app: App, parent?: StateNode): StateNode;
|
|
|
|
// (undocumented)
|
|
|
|
children?: () => StateNodeConstructor[];
|
|
|
|
// (undocumented)
|
|
|
|
id: string;
|
|
|
|
// (undocumented)
|
|
|
|
initial?: string;
|
|
|
|
// (undocumented)
|
|
|
|
styles?: TLStyleType[];
|
|
|
|
}
|
|
|
|
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export type StoreWithStatus = {
|
|
|
|
readonly status: 'error';
|
|
|
|
readonly store?: undefined;
|
|
|
|
readonly error: Error;
|
|
|
|
} | {
|
|
|
|
readonly status: 'loading';
|
|
|
|
readonly store?: undefined;
|
|
|
|
readonly error?: undefined;
|
|
|
|
} | {
|
|
|
|
readonly status: 'not-synced';
|
|
|
|
readonly store: TLStore;
|
|
|
|
readonly error?: undefined;
|
|
|
|
} | {
|
|
|
|
readonly status: 'synced-local';
|
|
|
|
readonly store: TLStore;
|
|
|
|
readonly error?: undefined;
|
|
|
|
} | {
|
|
|
|
readonly status: 'synced-remote';
|
|
|
|
readonly connectionStatus: 'offline' | 'online';
|
|
|
|
readonly store: TLStore;
|
|
|
|
readonly error?: undefined;
|
|
|
|
};
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export const STYLES: TLStyleCollections;
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const SVG_PADDING = 32;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function SVGContainer({ children, className, ...rest }: SVGContainerProps): JSX.Element;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
export type SVGContainerProps = React_3.HTMLAttributes<SVGElement>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
export const TAB_ID: TLInstanceId;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const TEXT_PROPS: {
|
|
|
|
lineHeight: number;
|
|
|
|
fontWeight: string;
|
|
|
|
fontVariant: string;
|
|
|
|
fontStyle: string;
|
|
|
|
padding: string;
|
|
|
|
maxWidth: string;
|
|
|
|
};
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export class TLArrowUtil extends TLShapeUtil<TLArrowShape> {
|
|
|
|
// (undocumented)
|
|
|
|
canBind: () => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
canEdit: () => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
defaultProps(): TLArrowShape['props'];
|
|
|
|
// (undocumented)
|
|
|
|
getArrowInfo(shape: TLArrowShape): ArrowInfo | undefined;
|
|
|
|
// (undocumented)
|
|
|
|
getBounds(shape: TLArrowShape): Box2d;
|
|
|
|
// (undocumented)
|
|
|
|
getCenter(shape: TLArrowShape): Vec2d;
|
|
|
|
// (undocumented)
|
|
|
|
getEditingBounds: (shape: TLArrowShape) => Box2d;
|
|
|
|
// (undocumented)
|
|
|
|
getHandles(shape: TLArrowShape): TLHandle[];
|
|
|
|
// (undocumented)
|
|
|
|
getLabelBounds(shape: TLArrowShape): Box2d | null;
|
|
|
|
// (undocumented)
|
|
|
|
getOutline(shape: TLArrowShape): Vec2dModel[];
|
|
|
|
// (undocumented)
|
|
|
|
getOutlineWithoutLabel(shape: TLArrowShape): VecLike[];
|
|
|
|
// (undocumented)
|
|
|
|
hideResizeHandles: TLShapeUtilFlag<TLArrowShape>;
|
|
|
|
// (undocumented)
|
|
|
|
hideRotateHandle: TLShapeUtilFlag<TLArrowShape>;
|
|
|
|
// (undocumented)
|
|
|
|
hideSelectionBoundsBg: TLShapeUtilFlag<TLArrowShape>;
|
|
|
|
// (undocumented)
|
|
|
|
hideSelectionBoundsFg: TLShapeUtilFlag<TLArrowShape>;
|
|
|
|
// (undocumented)
|
|
|
|
hitTestLineSegment(shape: TLArrowShape, A: VecLike, B: VecLike): boolean;
|
|
|
|
// (undocumented)
|
|
|
|
hitTestPoint(shape: TLArrowShape, point: VecLike): boolean;
|
|
|
|
// (undocumented)
|
|
|
|
indicator(shape: TLArrowShape): JSX.Element | null;
|
|
|
|
// (undocumented)
|
|
|
|
isClosed: () => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
get labelBoundsCache(): ComputedCache<Box2d | null, TLArrowShape>;
|
|
|
|
// (undocumented)
|
|
|
|
onDoubleClickHandle: (shape: TLArrowShape, handle: TLHandle) => TLShapePartial<TLArrowShape> | void;
|
|
|
|
// (undocumented)
|
|
|
|
onEditEnd: OnEditEndHandler<TLArrowShape>;
|
|
|
|
// (undocumented)
|
|
|
|
onHandleChange: OnHandleChangeHandler<TLArrowShape>;
|
|
|
|
// (undocumented)
|
|
|
|
onResize: OnResizeHandler<TLArrowShape>;
|
|
|
|
// (undocumented)
|
|
|
|
onTranslateStart: OnTranslateStartHandler<TLArrowShape>;
|
|
|
|
// (undocumented)
|
|
|
|
render(shape: TLArrowShape): JSX.Element | null;
|
|
|
|
// (undocumented)
|
|
|
|
snapPoints(_shape: TLArrowShape): Vec2d[];
|
|
|
|
// (undocumented)
|
|
|
|
toSvg(shape: TLArrowShape, font: string, colors: TLExportColors): SVGGElement;
|
|
|
|
// (undocumented)
|
|
|
|
static type: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export interface TLBaseEventInfo {
|
|
|
|
// (undocumented)
|
|
|
|
altKey: boolean;
|
|
|
|
// (undocumented)
|
|
|
|
ctrlKey: boolean;
|
|
|
|
// (undocumented)
|
|
|
|
shiftKey: boolean;
|
|
|
|
// (undocumented)
|
|
|
|
type: UiEventType;
|
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export class TLBookmarkUtil extends TLBoxUtil<TLBookmarkShape> {
|
|
|
|
// (undocumented)
|
|
|
|
canResize: () => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
defaultProps(): TLBookmarkShape['props'];
|
|
|
|
// (undocumented)
|
|
|
|
getHumanReadableAddress(shape: TLBookmarkShape): string;
|
|
|
|
// (undocumented)
|
|
|
|
hideSelectionBoundsBg: () => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
hideSelectionBoundsFg: () => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
indicator(shape: TLBookmarkShape): JSX.Element;
|
|
|
|
// (undocumented)
|
|
|
|
onBeforeCreate?: OnBeforeCreateHandler<TLBookmarkShape>;
|
|
|
|
// (undocumented)
|
|
|
|
onBeforeUpdate?: OnBeforeUpdateHandler<TLBookmarkShape>;
|
|
|
|
// (undocumented)
|
|
|
|
render(shape: TLBookmarkShape): JSX.Element;
|
|
|
|
// (undocumented)
|
|
|
|
static type: string;
|
|
|
|
// (undocumented)
|
|
|
|
protected updateBookmarkAsset: {
|
|
|
|
(shape: TLBookmarkShape): Promise<void>;
|
|
|
|
cancel(): void;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLBoxLike = TLBaseShape<string, {
|
|
|
|
w: number;
|
|
|
|
h: number;
|
|
|
|
}>;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export abstract class TLBoxTool extends StateNode {
|
|
|
|
// (undocumented)
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
static children: () => (typeof Idle_4 | typeof Pointing_2)[];
|
2023-04-25 11:01:25 +00:00
|
|
|
// (undocumented)
|
|
|
|
static id: string;
|
|
|
|
// (undocumented)
|
|
|
|
static initial: string;
|
|
|
|
// (undocumented)
|
|
|
|
abstract shapeType: string;
|
|
|
|
// (undocumented)
|
2023-05-19 10:23:43 +00:00
|
|
|
styles: ("align" | "arrowheadEnd" | "arrowheadStart" | "color" | "dash" | "fill" | "font" | "geo" | "icon" | "labelColor" | "opacity" | "size" | "spline" | "verticalAlign")[];
|
2023-04-25 11:01:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export abstract class TLBoxUtil<Shape extends TLBoxLike> extends TLShapeUtil<Shape> {
|
|
|
|
// (undocumented)
|
|
|
|
getBounds(shape: Shape): Box2d;
|
|
|
|
// (undocumented)
|
|
|
|
getCenter(shape: Shape): Vec2d;
|
|
|
|
// (undocumented)
|
|
|
|
getOutline(shape: Shape): Vec2d[];
|
|
|
|
// (undocumented)
|
|
|
|
hitTestLineSegment(shape: Shape, A: VecLike, B: VecLike): boolean;
|
|
|
|
// (undocumented)
|
|
|
|
hitTestPoint(shape: Shape, point: VecLike): boolean;
|
|
|
|
// (undocumented)
|
|
|
|
onResize: OnResizeHandler<any>;
|
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLCancelEvent = (info: TLCancelEventInfo) => void;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLCancelEventInfo = {
|
|
|
|
type: 'misc';
|
|
|
|
name: 'cancel';
|
|
|
|
};
|
|
|
|
|
|
|
|
// @public (undocumented)
|
2023-05-24 11:25:41 +00:00
|
|
|
export type TLChange<T extends UnknownRecord = any> = HistoryEntry<T>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLClickEvent = (info: TLClickEventInfo) => void;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLClickEventInfo = TLBaseEventInfo & {
|
|
|
|
type: 'click';
|
|
|
|
name: TLCLickEventName;
|
|
|
|
point: VecLike;
|
|
|
|
pointerId: number;
|
|
|
|
button: number;
|
|
|
|
phase: 'down' | 'settle' | 'up';
|
|
|
|
} & TLPointerEventTarget;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLCLickEventName = 'double_click' | 'quadruple_click' | 'triple_click';
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export interface TLClipboardModel {
|
|
|
|
// (undocumented)
|
|
|
|
assets: TLAsset[];
|
|
|
|
// (undocumented)
|
|
|
|
rootShapeIds: TLShapeId[];
|
|
|
|
// (undocumented)
|
|
|
|
schema: SerializedSchema;
|
|
|
|
// (undocumented)
|
|
|
|
shapes: TLShape[];
|
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLCommand<Name extends string = any, Data = any> = {
|
|
|
|
type: 'command';
|
|
|
|
id: string;
|
|
|
|
data: Data;
|
|
|
|
name: Name;
|
|
|
|
preservesRedoStack?: boolean;
|
|
|
|
};
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLCommandHandler<Data> = {
|
|
|
|
do: (data: Data) => void;
|
|
|
|
undo: (data: Data) => void;
|
|
|
|
redo?: (data: Data) => void;
|
|
|
|
squash?: (prevData: Data, nextData: Data) => Data;
|
|
|
|
};
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLCompleteEvent = (info: TLCompleteEventInfo) => void;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLCompleteEventInfo = {
|
|
|
|
type: 'misc';
|
|
|
|
name: 'complete';
|
|
|
|
};
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLCopyType = 'jpeg' | 'json' | 'png' | 'svg';
|
|
|
|
|
|
|
|
// @public (undocumented)
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
export const TldrawEditor: React_2.NamedExoticComponent<TldrawEditorProps>;
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
export type TldrawEditorProps = {
|
|
|
|
children?: any;
|
|
|
|
shapes?: Record<string, ShapeInfo>;
|
|
|
|
tools?: StateNodeConstructor[];
|
2023-04-25 11:01:25 +00:00
|
|
|
assetUrls?: EditorAssetUrls;
|
|
|
|
autoFocus?: boolean;
|
|
|
|
components?: Partial<TLEditorComponents>;
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
onMount?: (app: App) => void;
|
2023-04-25 11:01:25 +00:00
|
|
|
onCreateAssetFromFile?: (file: File) => Promise<TLAsset>;
|
|
|
|
onCreateBookmarkFromUrl?: (url: string) => Promise<{
|
|
|
|
image: string;
|
|
|
|
title: string;
|
|
|
|
description: string;
|
|
|
|
}>;
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
} & ({
|
|
|
|
store: StoreWithStatus | TLStore;
|
|
|
|
} | {
|
|
|
|
store?: undefined;
|
|
|
|
initialData?: StoreSnapshot<TLRecord>;
|
|
|
|
instanceId?: TLInstanceId;
|
|
|
|
persistenceKey?: string;
|
2023-06-01 18:46:26 +00:00
|
|
|
defaultName?: string;
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
});
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export class TLDrawUtil extends TLShapeUtil<TLDrawShape> {
|
|
|
|
// (undocumented)
|
|
|
|
defaultProps(): TLDrawShape['props'];
|
|
|
|
// (undocumented)
|
2023-05-16 08:35:45 +00:00
|
|
|
expandSelectionOutlinePx(shape: TLDrawShape): number;
|
|
|
|
// (undocumented)
|
2023-04-25 11:01:25 +00:00
|
|
|
getBounds(shape: TLDrawShape): Box2d;
|
|
|
|
// (undocumented)
|
|
|
|
getCenter(shape: TLDrawShape): Vec2d;
|
|
|
|
// (undocumented)
|
|
|
|
getOutline(shape: TLDrawShape): Vec2d[];
|
|
|
|
// (undocumented)
|
|
|
|
hideResizeHandles: (shape: TLDrawShape) => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
hideRotateHandle: (shape: TLDrawShape) => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
hideSelectionBoundsBg: (shape: TLDrawShape) => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
hideSelectionBoundsFg: (shape: TLDrawShape) => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
hitTestLineSegment(shape: TLDrawShape, A: VecLike, B: VecLike): boolean;
|
|
|
|
// (undocumented)
|
|
|
|
hitTestPoint(shape: TLDrawShape, point: VecLike): boolean;
|
|
|
|
// (undocumented)
|
|
|
|
indicator(shape: TLDrawShape): JSX.Element;
|
|
|
|
// (undocumented)
|
|
|
|
isClosed: (shape: TLDrawShape) => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
onResize: OnResizeHandler<TLDrawShape>;
|
|
|
|
// (undocumented)
|
|
|
|
render(shape: TLDrawShape): JSX.Element;
|
|
|
|
// (undocumented)
|
|
|
|
toSvg(shape: TLDrawShape, _font: string | undefined, colors: TLExportColors): SVGGElement;
|
|
|
|
// (undocumented)
|
|
|
|
static type: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLEasingType = 'easeInCubic' | 'easeInExpo' | 'easeInOutCubic' | 'easeInOutExpo' | 'easeInOutQuad' | 'easeInOutQuart' | 'easeInOutQuint' | 'easeInOutSine' | 'easeInQuad' | 'easeInQuart' | 'easeInQuint' | 'easeInSine' | 'easeOutCubic' | 'easeOutExpo' | 'easeOutQuad' | 'easeOutQuart' | 'easeOutQuint' | 'easeOutSine' | 'linear';
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export interface TLEditorComponents {
|
|
|
|
// (undocumented)
|
|
|
|
Background: null | TLBackgroundComponent;
|
|
|
|
// (undocumented)
|
|
|
|
Brush: null | TLBrushComponent;
|
|
|
|
// (undocumented)
|
|
|
|
CollaboratorBrush: null | TLBrushComponent;
|
|
|
|
// (undocumented)
|
|
|
|
CollaboratorCursor: null | TLCursorComponent;
|
|
|
|
// (undocumented)
|
|
|
|
CollaboratorHint: null | TLCollaboratorHintComponent;
|
|
|
|
// (undocumented)
|
|
|
|
CollaboratorScribble: null | TLScribbleComponent;
|
|
|
|
// (undocumented)
|
|
|
|
CollaboratorShapeIndicator: null | TLShapeIndicatorComponent;
|
|
|
|
// (undocumented)
|
|
|
|
Cursor: null | TLCursorComponent;
|
|
|
|
// (undocumented)
|
|
|
|
ErrorFallback: null | TLErrorFallback;
|
|
|
|
// (undocumented)
|
|
|
|
Grid: null | TLGridComponent;
|
|
|
|
// (undocumented)
|
|
|
|
Handle: null | TLHandleComponent;
|
|
|
|
// (undocumented)
|
|
|
|
Scribble: null | TLScribbleComponent;
|
|
|
|
// (undocumented)
|
|
|
|
ShapeErrorFallback: null | TLShapeErrorFallback;
|
|
|
|
// (undocumented)
|
|
|
|
ShapeIndicatorErrorFallback: null | TLShapeIndicatorErrorFallback;
|
|
|
|
// (undocumented)
|
|
|
|
SnapLine: null | TLSnapLineComponent;
|
|
|
|
// (undocumented)
|
|
|
|
Spinner: null | TLSpinnerComponent;
|
|
|
|
// (undocumented)
|
|
|
|
SvgDefs: null | TLSvgDefsComponent;
|
|
|
|
// (undocumented)
|
|
|
|
ZoomBrush: null | TLBrushComponent;
|
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export class TLEmbedUtil extends TLBoxUtil<TLEmbedShape> {
|
|
|
|
// (undocumented)
|
|
|
|
canEdit: TLShapeUtilFlag<TLEmbedShape>;
|
|
|
|
// (undocumented)
|
|
|
|
canResize: (shape: TLEmbedShape) => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
canUnmount: TLShapeUtilFlag<TLEmbedShape>;
|
|
|
|
// (undocumented)
|
|
|
|
defaultProps(): TLEmbedShape['props'];
|
|
|
|
// (undocumented)
|
|
|
|
hideSelectionBoundsBg: TLShapeUtilFlag<TLEmbedShape>;
|
|
|
|
// (undocumented)
|
|
|
|
hideSelectionBoundsFg: TLShapeUtilFlag<TLEmbedShape>;
|
|
|
|
// (undocumented)
|
|
|
|
indicator(shape: TLEmbedShape): JSX.Element;
|
|
|
|
// (undocumented)
|
|
|
|
isAspectRatioLocked: TLShapeUtilFlag<TLEmbedShape>;
|
|
|
|
// (undocumented)
|
|
|
|
onResize: OnResizeHandler<TLEmbedShape>;
|
|
|
|
// (undocumented)
|
|
|
|
render(shape: TLEmbedShape): JSX.Element;
|
|
|
|
// (undocumented)
|
|
|
|
static type: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export interface TLEventHandlers {
|
|
|
|
// (undocumented)
|
|
|
|
onCancel: TLCancelEvent;
|
|
|
|
// (undocumented)
|
|
|
|
onComplete: TLCompleteEvent;
|
|
|
|
// (undocumented)
|
|
|
|
onDoubleClick: TLClickEvent;
|
|
|
|
// (undocumented)
|
|
|
|
onInterrupt: TLInterruptEvent;
|
|
|
|
// (undocumented)
|
|
|
|
onKeyDown: TLKeyboardEvent;
|
|
|
|
// (undocumented)
|
|
|
|
onKeyRepeat: TLKeyboardEvent;
|
|
|
|
// (undocumented)
|
|
|
|
onKeyUp: TLKeyboardEvent;
|
|
|
|
// (undocumented)
|
|
|
|
onMiddleClick: TLPointerEvent;
|
|
|
|
// (undocumented)
|
|
|
|
onPointerDown: TLPointerEvent;
|
|
|
|
// (undocumented)
|
|
|
|
onPointerEnter: TLPointerEvent;
|
|
|
|
// (undocumented)
|
|
|
|
onPointerLeave: TLPointerEvent;
|
|
|
|
// (undocumented)
|
|
|
|
onPointerMove: TLPointerEvent;
|
|
|
|
// (undocumented)
|
|
|
|
onPointerUp: TLPointerEvent;
|
|
|
|
// (undocumented)
|
|
|
|
onQuadrupleClick: TLClickEvent;
|
|
|
|
// (undocumented)
|
|
|
|
onRightClick: TLPointerEvent;
|
|
|
|
// (undocumented)
|
|
|
|
onTripleClick: TLClickEvent;
|
|
|
|
// (undocumented)
|
|
|
|
onWheel: TLWheelEvent;
|
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLEventInfo = TLCancelEventInfo | TLClickEventInfo | TLCompleteEventInfo | TLInterruptEventInfo | TLKeyboardEventInfo | TLPinchEventInfo | TLPointerEventInfo | TLWheelEventInfo;
|
|
|
|
|
2023-05-11 22:14:58 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export interface TLEventMap {
|
|
|
|
// (undocumented)
|
|
|
|
'change-history': [{
|
|
|
|
reason: 'bail';
|
|
|
|
markId?: string;
|
|
|
|
} | {
|
|
|
|
reason: 'push' | 'redo' | 'undo';
|
|
|
|
}];
|
|
|
|
// (undocumented)
|
|
|
|
'mark-history': [{
|
|
|
|
id: string;
|
|
|
|
}];
|
|
|
|
// (undocumented)
|
|
|
|
'max-shapes': [{
|
|
|
|
name: string;
|
|
|
|
pageId: TLPageId;
|
|
|
|
count: number;
|
|
|
|
}];
|
|
|
|
// (undocumented)
|
|
|
|
'stop-camera-animation': [];
|
|
|
|
// (undocumented)
|
|
|
|
'stop-following': [];
|
|
|
|
// (undocumented)
|
|
|
|
change: [TLChange<TLRecord>];
|
|
|
|
// (undocumented)
|
|
|
|
crash: [{
|
|
|
|
error: unknown;
|
|
|
|
}];
|
|
|
|
// (undocumented)
|
|
|
|
event: [TLEventInfo];
|
|
|
|
// (undocumented)
|
2023-05-23 08:04:07 +00:00
|
|
|
frame: [number];
|
|
|
|
// (undocumented)
|
2023-05-11 22:14:58 +00:00
|
|
|
mount: [];
|
|
|
|
// (undocumented)
|
|
|
|
tick: [number];
|
|
|
|
// (undocumented)
|
|
|
|
update: [];
|
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLEventMapHandler<T extends keyof TLEventMap> = (...args: TLEventMap[T]) => void;
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export type TLEventName = 'cancel' | 'complete' | 'interrupt' | 'wheel' | TLCLickEventName | TLKeyboardEventName | TLPinchEventName | TLPointerEventName;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLExportType = 'jpeg' | 'json' | 'png' | 'svg' | 'webp';
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export class TLFrameUtil extends TLBoxUtil<TLFrameShape> {
|
|
|
|
// (undocumented)
|
|
|
|
canBind: () => boolean;
|
|
|
|
// (undocumented)
|
2023-06-01 18:13:38 +00:00
|
|
|
canDropShapes: (shape: TLFrameShape, _shapes: TLShape[]) => boolean;
|
2023-04-25 11:01:25 +00:00
|
|
|
// (undocumented)
|
|
|
|
canEdit: () => boolean;
|
|
|
|
// (undocumented)
|
2023-06-01 18:13:38 +00:00
|
|
|
canReceiveNewChildrenOfType: (shape: TLShape, _type: TLShape['type']) => boolean;
|
2023-04-25 11:01:25 +00:00
|
|
|
// (undocumented)
|
|
|
|
defaultProps(): TLFrameShape['props'];
|
|
|
|
// (undocumented)
|
|
|
|
indicator(shape: TLFrameShape): JSX.Element;
|
|
|
|
// (undocumented)
|
|
|
|
onDragShapesOut: (_shape: TLFrameShape, shapes: TLShape[]) => void;
|
|
|
|
// (undocumented)
|
|
|
|
onDragShapesOver: (frame: TLFrameShape, shapes: TLShape[]) => {
|
|
|
|
shouldHint: boolean;
|
|
|
|
};
|
|
|
|
// (undocumented)
|
|
|
|
onResizeEnd: OnResizeEndHandler<TLFrameShape>;
|
|
|
|
// (undocumented)
|
2023-06-01 15:22:47 +00:00
|
|
|
providesBackgroundForChildren(): boolean;
|
|
|
|
// (undocumented)
|
2023-04-25 11:01:25 +00:00
|
|
|
render(shape: TLFrameShape): JSX.Element;
|
|
|
|
// (undocumented)
|
|
|
|
toSvg(shape: TLFrameShape, font: string, colors: TLExportColors): Promise<SVGElement> | SVGElement;
|
|
|
|
// (undocumented)
|
|
|
|
static type: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export class TLGeoUtil extends TLBoxUtil<TLGeoShape> {
|
|
|
|
// (undocumented)
|
|
|
|
canEdit: () => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
defaultProps(): TLGeoShape['props'];
|
|
|
|
// (undocumented)
|
|
|
|
getBounds(shape: TLGeoShape): Box2d;
|
|
|
|
// (undocumented)
|
|
|
|
getCenter(shape: TLGeoShape): Vec2d;
|
|
|
|
// (undocumented)
|
|
|
|
getOutline(shape: TLGeoShape): Vec2d[];
|
|
|
|
// (undocumented)
|
|
|
|
hitTestLineSegment(shape: TLGeoShape, A: VecLike, B: VecLike): boolean;
|
|
|
|
// (undocumented)
|
2023-05-09 13:32:04 +00:00
|
|
|
hitTestPoint(shape: TLGeoShape, point: VecLike): boolean;
|
|
|
|
// (undocumented)
|
2023-04-25 11:01:25 +00:00
|
|
|
indicator(shape: TLGeoShape): JSX.Element;
|
|
|
|
// (undocumented)
|
|
|
|
onBeforeCreate: (shape: TLGeoShape) => {
|
|
|
|
props: {
|
|
|
|
growY: number;
|
2023-05-09 13:32:04 +00:00
|
|
|
geo: "arrow-down" | "arrow-left" | "arrow-right" | "arrow-up" | "check-box" | "diamond" | "ellipse" | "hexagon" | "octagon" | "oval" | "pentagon" | "rectangle" | "rhombus-2" | "rhombus" | "star" | "trapezoid" | "triangle" | "x-box";
|
2023-04-25 11:01:25 +00:00
|
|
|
labelColor: "black" | "blue" | "green" | "grey" | "light-blue" | "light-green" | "light-red" | "light-violet" | "orange" | "red" | "violet" | "yellow";
|
|
|
|
color: "black" | "blue" | "green" | "grey" | "light-blue" | "light-green" | "light-red" | "light-violet" | "orange" | "red" | "violet" | "yellow";
|
|
|
|
fill: "none" | "pattern" | "semi" | "solid";
|
|
|
|
dash: "dashed" | "dotted" | "draw" | "solid";
|
|
|
|
size: "l" | "m" | "s" | "xl";
|
|
|
|
opacity: "0.1" | "0.25" | "0.5" | "0.75" | "1";
|
|
|
|
font: "draw" | "mono" | "sans" | "serif";
|
|
|
|
align: "end" | "middle" | "start";
|
2023-05-19 10:23:43 +00:00
|
|
|
verticalAlign: "end" | "middle" | "start";
|
2023-04-25 11:01:25 +00:00
|
|
|
url: string;
|
|
|
|
w: number;
|
|
|
|
h: number;
|
|
|
|
text: string;
|
|
|
|
};
|
|
|
|
type: "geo";
|
|
|
|
x: number;
|
|
|
|
y: number;
|
|
|
|
rotation: number;
|
|
|
|
index: string;
|
|
|
|
parentId: TLParentId;
|
|
|
|
isLocked: boolean;
|
2023-05-24 11:25:41 +00:00
|
|
|
id: TLShapeId;
|
2023-04-25 11:01:25 +00:00
|
|
|
typeName: "shape";
|
|
|
|
} | undefined;
|
|
|
|
// (undocumented)
|
|
|
|
onBeforeUpdate: (prev: TLGeoShape, next: TLGeoShape) => {
|
|
|
|
props: {
|
|
|
|
growY: number;
|
2023-05-09 13:32:04 +00:00
|
|
|
geo: "arrow-down" | "arrow-left" | "arrow-right" | "arrow-up" | "check-box" | "diamond" | "ellipse" | "hexagon" | "octagon" | "oval" | "pentagon" | "rectangle" | "rhombus-2" | "rhombus" | "star" | "trapezoid" | "triangle" | "x-box";
|
2023-04-25 11:01:25 +00:00
|
|
|
labelColor: "black" | "blue" | "green" | "grey" | "light-blue" | "light-green" | "light-red" | "light-violet" | "orange" | "red" | "violet" | "yellow";
|
|
|
|
color: "black" | "blue" | "green" | "grey" | "light-blue" | "light-green" | "light-red" | "light-violet" | "orange" | "red" | "violet" | "yellow";
|
|
|
|
fill: "none" | "pattern" | "semi" | "solid";
|
|
|
|
dash: "dashed" | "dotted" | "draw" | "solid";
|
|
|
|
size: "l" | "m" | "s" | "xl";
|
|
|
|
opacity: "0.1" | "0.25" | "0.5" | "0.75" | "1";
|
|
|
|
font: "draw" | "mono" | "sans" | "serif";
|
|
|
|
align: "end" | "middle" | "start";
|
2023-05-19 10:23:43 +00:00
|
|
|
verticalAlign: "end" | "middle" | "start";
|
2023-04-25 11:01:25 +00:00
|
|
|
url: string;
|
|
|
|
w: number;
|
|
|
|
h: number;
|
|
|
|
text: string;
|
|
|
|
};
|
|
|
|
type: "geo";
|
|
|
|
x: number;
|
|
|
|
y: number;
|
|
|
|
rotation: number;
|
|
|
|
index: string;
|
|
|
|
parentId: TLParentId;
|
|
|
|
isLocked: boolean;
|
2023-05-24 11:25:41 +00:00
|
|
|
id: TLShapeId;
|
2023-04-25 11:01:25 +00:00
|
|
|
typeName: "shape";
|
|
|
|
} | undefined;
|
|
|
|
// (undocumented)
|
2023-05-09 13:32:04 +00:00
|
|
|
onDoubleClick: (shape: TLGeoShape) => {
|
|
|
|
props: {
|
|
|
|
geo: "check-box";
|
|
|
|
};
|
|
|
|
type: "geo";
|
|
|
|
x: number;
|
|
|
|
y: number;
|
|
|
|
rotation: number;
|
|
|
|
index: string;
|
|
|
|
parentId: TLParentId;
|
|
|
|
isLocked: boolean;
|
2023-05-24 11:25:41 +00:00
|
|
|
id: TLShapeId;
|
2023-05-09 13:32:04 +00:00
|
|
|
typeName: "shape";
|
|
|
|
} | {
|
|
|
|
props: {
|
|
|
|
geo: "rectangle";
|
|
|
|
};
|
|
|
|
type: "geo";
|
|
|
|
x: number;
|
|
|
|
y: number;
|
|
|
|
rotation: number;
|
|
|
|
index: string;
|
|
|
|
parentId: TLParentId;
|
|
|
|
isLocked: boolean;
|
2023-05-24 11:25:41 +00:00
|
|
|
id: TLShapeId;
|
2023-05-09 13:32:04 +00:00
|
|
|
typeName: "shape";
|
|
|
|
} | undefined;
|
|
|
|
// (undocumented)
|
2023-04-25 11:01:25 +00:00
|
|
|
onEditEnd: OnEditEndHandler<TLGeoShape>;
|
|
|
|
// (undocumented)
|
|
|
|
onResize: OnResizeHandler<TLGeoShape>;
|
|
|
|
// (undocumented)
|
|
|
|
render(shape: TLGeoShape): JSX.Element;
|
|
|
|
// (undocumented)
|
|
|
|
toSvg(shape: TLGeoShape, font: string, colors: TLExportColors): SVGElement;
|
|
|
|
// (undocumented)
|
|
|
|
static type: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export class TLGroupUtil extends TLShapeUtil<TLGroupShape> {
|
|
|
|
// (undocumented)
|
|
|
|
canBind: () => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
defaultProps(): TLGroupShape['props'];
|
|
|
|
// (undocumented)
|
|
|
|
getBounds(shape: TLGroupShape): Box2d;
|
|
|
|
// (undocumented)
|
|
|
|
getCenter(shape: TLGroupShape): Vec2dModel;
|
|
|
|
// (undocumented)
|
|
|
|
getOutline(shape: TLGroupShape): Vec2dModel[];
|
|
|
|
// (undocumented)
|
|
|
|
hideSelectionBoundsBg: () => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
hideSelectionBoundsFg: () => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
indicator(shape: TLGroupShape): JSX.Element;
|
|
|
|
// (undocumented)
|
|
|
|
onChildrenChange: OnChildrenChangeHandler<TLGroupShape>;
|
|
|
|
// (undocumented)
|
|
|
|
render(shape: TLGroupShape): JSX.Element | null;
|
|
|
|
// (undocumented)
|
|
|
|
static type: string;
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
// (undocumented)
|
|
|
|
type: "group";
|
2023-04-25 11:01:25 +00:00
|
|
|
}
|
|
|
|
|
2023-06-01 12:46:13 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export class TLHighlightUtil extends TLShapeUtil<TLHighlightShape> {
|
|
|
|
// (undocumented)
|
|
|
|
defaultProps(): TLHighlightShape['props'];
|
|
|
|
// (undocumented)
|
|
|
|
expandSelectionOutlinePx(shape: TLHighlightShape): number;
|
|
|
|
// (undocumented)
|
|
|
|
getBounds(shape: TLHighlightShape): Box2d;
|
|
|
|
// (undocumented)
|
|
|
|
getCenter(shape: TLHighlightShape): Vec2d;
|
|
|
|
// (undocumented)
|
|
|
|
getOutline(shape: TLHighlightShape): Vec2d[];
|
|
|
|
// (undocumented)
|
|
|
|
hideResizeHandles: (shape: TLHighlightShape) => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
hideRotateHandle: (shape: TLHighlightShape) => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
hideSelectionBoundsBg: (shape: TLHighlightShape) => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
hideSelectionBoundsFg: (shape: TLHighlightShape) => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
hitTestLineSegment(shape: TLHighlightShape, A: VecLike, B: VecLike): boolean;
|
|
|
|
// (undocumented)
|
|
|
|
hitTestPoint(shape: TLHighlightShape, point: VecLike): boolean;
|
|
|
|
// (undocumented)
|
|
|
|
indicator(shape: TLHighlightShape): JSX.Element;
|
|
|
|
// (undocumented)
|
|
|
|
onResize: OnResizeHandler<TLHighlightShape>;
|
|
|
|
// (undocumented)
|
|
|
|
render(shape: TLHighlightShape): JSX.Element;
|
|
|
|
// (undocumented)
|
2023-06-01 15:22:47 +00:00
|
|
|
renderBackground(shape: TLHighlightShape): JSX.Element;
|
|
|
|
// (undocumented)
|
|
|
|
toBackgroundSvg(shape: TLHighlightShape, font: string | undefined, colors: TLExportColors): SVGPathElement;
|
|
|
|
// (undocumented)
|
2023-06-01 12:46:13 +00:00
|
|
|
toSvg(shape: TLHighlightShape, _font: string | undefined, colors: TLExportColors): SVGPathElement;
|
|
|
|
// (undocumented)
|
|
|
|
static type: string;
|
|
|
|
}
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export type TLHistoryEntry = TLCommand | TLMark;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export class TLImageUtil extends TLBoxUtil<TLImageShape> {
|
|
|
|
// (undocumented)
|
|
|
|
canCrop: () => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
defaultProps(): TLImageShape['props'];
|
|
|
|
// (undocumented)
|
|
|
|
indicator(shape: TLImageShape): JSX.Element | null;
|
|
|
|
// (undocumented)
|
|
|
|
isAspectRatioLocked: () => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
onDoubleClick: (shape: TLImageShape) => void;
|
|
|
|
// (undocumented)
|
|
|
|
onDoubleClickEdge: OnDoubleClickHandler<TLImageShape>;
|
|
|
|
// (undocumented)
|
|
|
|
render(shape: TLImageShape): JSX.Element;
|
|
|
|
// (undocumented)
|
|
|
|
toSvg(shape: TLImageShape): Promise<SVGGElement>;
|
|
|
|
// (undocumented)
|
|
|
|
static type: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLInterruptEvent = (info: TLInterruptEventInfo) => void;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLInterruptEventInfo = {
|
|
|
|
type: 'misc';
|
|
|
|
name: 'interrupt';
|
|
|
|
};
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLKeyboardEvent = (info: TLKeyboardEventInfo) => void;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLKeyboardEventInfo = TLBaseEventInfo & {
|
|
|
|
type: 'keyboard';
|
|
|
|
name: TLKeyboardEventName;
|
|
|
|
key: string;
|
|
|
|
code: string;
|
|
|
|
};
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLKeyboardEventName = 'key_down' | 'key_repeat' | 'key_up';
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export class TLLineUtil extends TLShapeUtil<TLLineShape> {
|
|
|
|
// (undocumented)
|
|
|
|
defaultProps(): TLLineShape['props'];
|
|
|
|
// (undocumented)
|
|
|
|
getBounds(shape: TLLineShape): Box2d;
|
|
|
|
// (undocumented)
|
|
|
|
getCenter(shape: TLLineShape): Vec2d;
|
|
|
|
// (undocumented)
|
|
|
|
getHandles(shape: TLLineShape): TLHandle[];
|
|
|
|
// (undocumented)
|
|
|
|
getOutline(shape: TLLineShape): Vec2d[];
|
|
|
|
// (undocumented)
|
|
|
|
hideResizeHandles: () => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
hideRotateHandle: () => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
hideSelectionBoundsBg: () => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
hideSelectionBoundsFg: () => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
hitTestLineSegment(shape: TLLineShape, A: VecLike, B: VecLike): boolean;
|
|
|
|
// (undocumented)
|
|
|
|
hitTestPoint(shape: TLLineShape, point: Vec2d): boolean;
|
|
|
|
// (undocumented)
|
|
|
|
indicator(shape: TLLineShape): JSX.Element;
|
|
|
|
// (undocumented)
|
|
|
|
isClosed: () => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
onHandleChange: OnHandleChangeHandler<TLLineShape>;
|
|
|
|
// (undocumented)
|
|
|
|
onResize: OnResizeHandler<TLLineShape>;
|
|
|
|
// (undocumented)
|
|
|
|
render(shape: TLLineShape): JSX.Element | undefined;
|
|
|
|
// (undocumented)
|
|
|
|
toSvg(shape: TLLineShape, _font: string, colors: TLExportColors): SVGGElement;
|
|
|
|
// (undocumented)
|
|
|
|
static type: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLMark = {
|
|
|
|
type: 'STOP';
|
|
|
|
id: string;
|
|
|
|
onUndo: boolean;
|
|
|
|
onRedo: boolean;
|
|
|
|
};
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export class TLNoteUtil extends TLShapeUtil<TLNoteShape> {
|
|
|
|
// (undocumented)
|
|
|
|
canEdit: () => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
defaultProps(): TLNoteShape['props'];
|
|
|
|
// (undocumented)
|
|
|
|
getBounds(shape: TLNoteShape): Box2d;
|
|
|
|
// (undocumented)
|
|
|
|
getCenter(_shape: TLNoteShape): Vec2d;
|
|
|
|
// (undocumented)
|
|
|
|
getHeight(shape: TLNoteShape): number;
|
|
|
|
// (undocumented)
|
|
|
|
getOutline(shape: TLNoteShape): Vec2d[];
|
|
|
|
// (undocumented)
|
|
|
|
hideResizeHandles: () => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
hideSelectionBoundsBg: () => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
hideSelectionBoundsFg: () => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
indicator(shape: TLNoteShape): JSX.Element;
|
|
|
|
// (undocumented)
|
|
|
|
onBeforeCreate: (next: TLNoteShape) => {
|
|
|
|
props: {
|
|
|
|
growY: number;
|
|
|
|
color: "black" | "blue" | "green" | "grey" | "light-blue" | "light-green" | "light-red" | "light-violet" | "orange" | "red" | "violet" | "yellow";
|
|
|
|
size: "l" | "m" | "s" | "xl";
|
|
|
|
font: "draw" | "mono" | "sans" | "serif";
|
|
|
|
align: "end" | "middle" | "start";
|
|
|
|
opacity: "0.1" | "0.25" | "0.5" | "0.75" | "1";
|
|
|
|
url: string;
|
|
|
|
text: string;
|
|
|
|
};
|
|
|
|
type: "note";
|
|
|
|
x: number;
|
|
|
|
y: number;
|
|
|
|
rotation: number;
|
|
|
|
index: string;
|
|
|
|
parentId: TLParentId;
|
|
|
|
isLocked: boolean;
|
2023-05-24 11:25:41 +00:00
|
|
|
id: TLShapeId;
|
2023-04-25 11:01:25 +00:00
|
|
|
typeName: "shape";
|
|
|
|
} | undefined;
|
|
|
|
// (undocumented)
|
|
|
|
onBeforeUpdate: (prev: TLNoteShape, next: TLNoteShape) => {
|
|
|
|
props: {
|
|
|
|
growY: number;
|
|
|
|
color: "black" | "blue" | "green" | "grey" | "light-blue" | "light-green" | "light-red" | "light-violet" | "orange" | "red" | "violet" | "yellow";
|
|
|
|
size: "l" | "m" | "s" | "xl";
|
|
|
|
font: "draw" | "mono" | "sans" | "serif";
|
|
|
|
align: "end" | "middle" | "start";
|
|
|
|
opacity: "0.1" | "0.25" | "0.5" | "0.75" | "1";
|
|
|
|
url: string;
|
|
|
|
text: string;
|
|
|
|
};
|
|
|
|
type: "note";
|
|
|
|
x: number;
|
|
|
|
y: number;
|
|
|
|
rotation: number;
|
|
|
|
index: string;
|
|
|
|
parentId: TLParentId;
|
|
|
|
isLocked: boolean;
|
2023-05-24 11:25:41 +00:00
|
|
|
id: TLShapeId;
|
2023-04-25 11:01:25 +00:00
|
|
|
typeName: "shape";
|
|
|
|
} | undefined;
|
|
|
|
// (undocumented)
|
|
|
|
onEditEnd: OnEditEndHandler<TLNoteShape>;
|
|
|
|
// (undocumented)
|
|
|
|
render(shape: TLNoteShape): JSX.Element;
|
|
|
|
// (undocumented)
|
|
|
|
toSvg(shape: TLNoteShape, font: string, colors: TLExportColors): SVGGElement;
|
|
|
|
// (undocumented)
|
|
|
|
static type: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLPinchEvent = (info: TLPinchEventInfo) => void;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLPinchEventInfo = TLBaseEventInfo & {
|
|
|
|
type: 'pinch';
|
|
|
|
name: TLPinchEventName;
|
|
|
|
point: Vec2dModel;
|
|
|
|
delta: Vec2dModel;
|
|
|
|
};
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLPinchEventName = 'pinch_end' | 'pinch_start' | 'pinch';
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLPointerEvent = (info: TLPointerEventInfo) => void;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLPointerEventInfo = TLBaseEventInfo & {
|
|
|
|
type: 'pointer';
|
|
|
|
name: TLPointerEventName;
|
|
|
|
point: VecLike;
|
|
|
|
pointerId: number;
|
|
|
|
button: number;
|
|
|
|
isPen: boolean;
|
|
|
|
} & TLPointerEventTarget;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLPointerEventName = 'middle_click' | 'pointer_down' | 'pointer_enter' | 'pointer_leave' | 'pointer_move' | 'pointer_up' | 'right_click';
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLPointerEventTarget = {
|
|
|
|
target: 'canvas';
|
|
|
|
shape?: undefined;
|
|
|
|
} | {
|
|
|
|
target: 'handle';
|
|
|
|
shape: TLShape;
|
|
|
|
handle: TLHandle;
|
|
|
|
} | {
|
|
|
|
target: 'selection';
|
|
|
|
handle?: TLSelectionHandle;
|
|
|
|
shape?: undefined;
|
|
|
|
} | {
|
|
|
|
target: 'shape';
|
|
|
|
shape: TLShape;
|
|
|
|
};
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLResizeHandle = SelectionCorner | SelectionEdge;
|
|
|
|
|
add docs for TLShapeUtil (#1215)
This PR adds docs for the methods in the TLShapeUtil class.
I think that it's a good page to have docs on, as it shows people what's
possible with the custom shape API.
Currently, our docs are not showing `@param` info for lots of methods,
including the ones added in this PR.
I'll do fix for that in a follow-up PR, so that it's easier to review.
---
Note: Moving forward, we probably want to consider **_where_** these
docs are shown, and how we achieve that.
For example, do we put the docs for these methods in:
* The docs page for the `TLShapeUtil` class?
* The docs pages for the handler types, eg:
[`OnResizeHandler`](http://localhost:3000/gen/editor/OnResizeHandler-type)?
* Both?
Right now, I opted for putting them in the the TLShapeUtil class, as it
keeps them all in one place, and it's what we already do for some
others.
We should consider both - what works best for the docs? and what works
best for code editors?
---
This PR also includes a fix to our pre-commit step that @SomeHats did.
2023-05-05 14:05:25 +00:00
|
|
|
// @public
|
|
|
|
export type TLResizeInfo<T extends TLShape> = {
|
|
|
|
newPoint: Vec2dModel;
|
|
|
|
handle: TLResizeHandle;
|
|
|
|
mode: TLResizeMode;
|
|
|
|
scaleX: number;
|
|
|
|
scaleY: number;
|
|
|
|
initialBounds: Box2d;
|
|
|
|
initialShape: T;
|
|
|
|
};
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @public
|
|
|
|
export type TLResizeMode = 'resize_bounds' | 'scale_shape';
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLSelectionHandle = RotateCorner | SelectionCorner | SelectionEdge;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
2023-05-23 12:32:42 +00:00
|
|
|
export abstract class TLShapeUtil<T extends TLUnknownShape = TLUnknownShape> {
|
2023-04-25 11:01:25 +00:00
|
|
|
constructor(app: App, type: T['type']);
|
|
|
|
// (undocumented)
|
|
|
|
app: App;
|
|
|
|
bounds(shape: T): Box2d;
|
|
|
|
canBind: <K>(_shape: T, _otherShape?: K | undefined) => boolean;
|
|
|
|
canCrop: TLShapeUtilFlag<T>;
|
|
|
|
canDropShapes(shape: T, shapes: TLShape[]): boolean;
|
|
|
|
canEdit: TLShapeUtilFlag<T>;
|
2023-06-01 18:13:38 +00:00
|
|
|
canReceiveNewChildrenOfType(shape: T, type: TLShape['type']): boolean;
|
2023-04-25 11:01:25 +00:00
|
|
|
canResize: TLShapeUtilFlag<T>;
|
|
|
|
canScroll: TLShapeUtilFlag<T>;
|
|
|
|
canUnmount: TLShapeUtilFlag<T>;
|
|
|
|
center(shape: T): Vec2dModel;
|
|
|
|
abstract defaultProps(): T['props'];
|
2023-05-16 08:35:45 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
expandSelectionOutlinePx(shape: T): number;
|
2023-04-25 11:01:25 +00:00
|
|
|
protected abstract getBounds(shape: T): Box2d;
|
|
|
|
abstract getCenter(shape: T): Vec2dModel;
|
|
|
|
getEditingBounds: (shape: T) => Box2d;
|
|
|
|
protected getHandles?(shape: T): TLHandle[];
|
|
|
|
protected abstract getOutline(shape: T): Vec2dModel[];
|
|
|
|
handles(shape: T): TLHandle[];
|
|
|
|
hideResizeHandles: TLShapeUtilFlag<T>;
|
|
|
|
hideRotateHandle: TLShapeUtilFlag<T>;
|
|
|
|
hideSelectionBoundsBg: TLShapeUtilFlag<T>;
|
|
|
|
hideSelectionBoundsFg: TLShapeUtilFlag<T>;
|
|
|
|
hitTestLineSegment(shape: T, A: VecLike, B: VecLike): boolean;
|
|
|
|
hitTestPoint(shape: T, point: VecLike): boolean;
|
|
|
|
abstract indicator(shape: T): any;
|
|
|
|
is(shape: TLBaseShape<string, object>): shape is T;
|
|
|
|
isAspectRatioLocked: TLShapeUtilFlag<T>;
|
|
|
|
isClosed: TLShapeUtilFlag<T>;
|
|
|
|
onBeforeCreate?: OnBeforeCreateHandler<T>;
|
|
|
|
onBeforeUpdate?: OnBeforeUpdateHandler<T>;
|
add docs for TLShapeUtil (#1215)
This PR adds docs for the methods in the TLShapeUtil class.
I think that it's a good page to have docs on, as it shows people what's
possible with the custom shape API.
Currently, our docs are not showing `@param` info for lots of methods,
including the ones added in this PR.
I'll do fix for that in a follow-up PR, so that it's easier to review.
---
Note: Moving forward, we probably want to consider **_where_** these
docs are shown, and how we achieve that.
For example, do we put the docs for these methods in:
* The docs page for the `TLShapeUtil` class?
* The docs pages for the handler types, eg:
[`OnResizeHandler`](http://localhost:3000/gen/editor/OnResizeHandler-type)?
* Both?
Right now, I opted for putting them in the the TLShapeUtil class, as it
keeps them all in one place, and it's what we already do for some
others.
We should consider both - what works best for the docs? and what works
best for code editors?
---
This PR also includes a fix to our pre-commit step that @SomeHats did.
2023-05-05 14:05:25 +00:00
|
|
|
// @internal
|
2023-04-25 11:01:25 +00:00
|
|
|
onBindingChange?: OnBindingChangeHandler<T>;
|
|
|
|
onChildrenChange?: OnChildrenChangeHandler<T>;
|
|
|
|
onClick?: OnClickHandler<T>;
|
|
|
|
onDoubleClick?: OnDoubleClickHandler<T>;
|
|
|
|
onDoubleClickEdge?: OnDoubleClickHandler<T>;
|
|
|
|
onDoubleClickHandle?: OnDoubleClickHandleHandler<T>;
|
|
|
|
onDragShapesOut?: OnDragHandler<T>;
|
|
|
|
onDragShapesOver?: OnDragHandler<T, {
|
|
|
|
shouldHint: boolean;
|
|
|
|
}>;
|
|
|
|
onDropShapesOver?: OnDragHandler<T>;
|
|
|
|
onEditEnd?: OnEditEndHandler<T>;
|
|
|
|
onHandleChange?: OnHandleChangeHandler<T>;
|
|
|
|
onResize?: OnResizeHandler<T>;
|
|
|
|
onResizeEnd?: OnResizeEndHandler<T>;
|
|
|
|
onResizeStart?: OnResizeStartHandler<T>;
|
|
|
|
onRotate?: OnRotateHandler<T>;
|
|
|
|
onRotateEnd?: OnRotateEndHandler<T>;
|
|
|
|
onRotateStart?: OnRotateStartHandler<T>;
|
|
|
|
onTranslate?: OnTranslateHandler<T>;
|
|
|
|
onTranslateEnd?: OnTranslateEndHandler<T>;
|
|
|
|
onTranslateStart?: OnTranslateStartHandler<T>;
|
|
|
|
outline(shape: T): Vec2dModel[];
|
|
|
|
point(shape: T): Vec2dModel;
|
2023-06-01 15:22:47 +00:00
|
|
|
// @internal
|
|
|
|
providesBackgroundForChildren(shape: T): boolean;
|
2023-04-25 11:01:25 +00:00
|
|
|
abstract render(shape: T): any;
|
2023-06-01 15:22:47 +00:00
|
|
|
// @internal
|
|
|
|
renderBackground?(shape: T): any;
|
2023-04-25 11:01:25 +00:00
|
|
|
snapPoints(shape: T): Vec2d[];
|
2023-06-01 15:22:47 +00:00
|
|
|
toBackgroundSvg?(shape: T, font: string | undefined, colors: TLExportColors): null | Promise<SVGElement> | SVGElement;
|
2023-04-25 11:01:25 +00:00
|
|
|
toSvg?(shape: T, font: string | undefined, colors: TLExportColors): Promise<SVGElement> | SVGElement;
|
|
|
|
transform(shape: T): Matrix2d;
|
|
|
|
// (undocumented)
|
|
|
|
readonly type: T['type'];
|
2023-05-23 12:32:42 +00:00
|
|
|
// (undocumented)
|
|
|
|
static type: string;
|
2023-04-25 11:01:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export interface TLShapeUtilConstructor<T extends TLUnknownShape, ShapeUtil extends TLShapeUtil<T> = TLShapeUtil<T>> {
|
|
|
|
// (undocumented)
|
|
|
|
new (app: App, type: T['type']): ShapeUtil;
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
// (undocumented)
|
|
|
|
type: T['type'];
|
2023-04-25 11:01:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLShapeUtilFlag<T> = (shape: T) => boolean;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export class TLTextUtil extends TLShapeUtil<TLTextShape> {
|
|
|
|
// (undocumented)
|
|
|
|
canEdit: () => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
defaultProps(): TLTextShape['props'];
|
|
|
|
// (undocumented)
|
|
|
|
getBounds(shape: TLTextShape): Box2d;
|
|
|
|
// (undocumented)
|
|
|
|
getCenter(shape: TLTextShape): Vec2d;
|
|
|
|
// (undocumented)
|
|
|
|
getMinDimensions(shape: TLTextShape): {
|
|
|
|
height: number;
|
|
|
|
width: number;
|
|
|
|
};
|
|
|
|
// (undocumented)
|
|
|
|
getOutline(shape: TLTextShape): Vec2d[];
|
|
|
|
// (undocumented)
|
|
|
|
indicator(shape: TLTextShape): JSX.Element;
|
|
|
|
// (undocumented)
|
|
|
|
isAspectRatioLocked: TLShapeUtilFlag<TLTextShape>;
|
|
|
|
// (undocumented)
|
|
|
|
onBeforeCreate: (shape: TLTextShape) => {
|
|
|
|
x: number;
|
|
|
|
y: number;
|
|
|
|
type: "text";
|
|
|
|
rotation: number;
|
|
|
|
index: string;
|
|
|
|
parentId: TLParentId;
|
|
|
|
isLocked: boolean;
|
|
|
|
props: TLTextShapeProps;
|
2023-05-24 11:25:41 +00:00
|
|
|
id: TLShapeId;
|
2023-04-25 11:01:25 +00:00
|
|
|
typeName: "shape";
|
|
|
|
} | undefined;
|
|
|
|
// (undocumented)
|
|
|
|
onBeforeUpdate: (prev: TLTextShape, next: TLTextShape) => {
|
|
|
|
x: number;
|
|
|
|
y: number;
|
|
|
|
props: {
|
|
|
|
w: number;
|
|
|
|
color: "black" | "blue" | "green" | "grey" | "light-blue" | "light-green" | "light-red" | "light-violet" | "orange" | "red" | "violet" | "yellow";
|
|
|
|
size: "l" | "m" | "s" | "xl";
|
|
|
|
font: "draw" | "mono" | "sans" | "serif";
|
|
|
|
align: "end" | "middle" | "start";
|
|
|
|
opacity: "0.1" | "0.25" | "0.5" | "0.75" | "1";
|
|
|
|
text: string;
|
|
|
|
scale: number;
|
|
|
|
autoSize: boolean;
|
|
|
|
};
|
|
|
|
type: "text";
|
|
|
|
rotation: number;
|
|
|
|
index: string;
|
|
|
|
parentId: TLParentId;
|
|
|
|
isLocked: boolean;
|
2023-05-24 11:25:41 +00:00
|
|
|
id: TLShapeId;
|
2023-04-25 11:01:25 +00:00
|
|
|
typeName: "shape";
|
|
|
|
} | undefined;
|
|
|
|
// (undocumented)
|
|
|
|
onDoubleClickEdge: (shape: TLTextShape) => {
|
2023-05-24 11:25:41 +00:00
|
|
|
id: TLShapeId;
|
2023-04-25 11:01:25 +00:00
|
|
|
type: "text";
|
|
|
|
props: {
|
|
|
|
autoSize: boolean;
|
|
|
|
scale?: undefined;
|
|
|
|
};
|
|
|
|
} | {
|
2023-05-24 11:25:41 +00:00
|
|
|
id: TLShapeId;
|
2023-04-25 11:01:25 +00:00
|
|
|
type: "text";
|
|
|
|
props: {
|
|
|
|
scale: number;
|
|
|
|
autoSize?: undefined;
|
|
|
|
};
|
|
|
|
} | undefined;
|
|
|
|
// (undocumented)
|
|
|
|
onEditEnd: OnEditEndHandler<TLTextShape>;
|
|
|
|
// (undocumented)
|
|
|
|
onResize: OnResizeHandler<TLTextShape>;
|
|
|
|
// (undocumented)
|
|
|
|
render(shape: TLTextShape): JSX.Element;
|
|
|
|
// (undocumented)
|
|
|
|
toSvg(shape: TLTextShape, font: string | undefined, colors: TLExportColors): SVGGElement;
|
|
|
|
// (undocumented)
|
|
|
|
static type: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLTickEvent = (elapsed: number) => void;
|
|
|
|
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
// @public
|
|
|
|
export interface TLUserPreferences {
|
|
|
|
// (undocumented)
|
|
|
|
animationSpeed: number;
|
|
|
|
// (undocumented)
|
|
|
|
color: string;
|
|
|
|
// (undocumented)
|
|
|
|
id: string;
|
|
|
|
// (undocumented)
|
|
|
|
isDarkMode: boolean;
|
|
|
|
// (undocumented)
|
|
|
|
locale: string;
|
|
|
|
// (undocumented)
|
|
|
|
name: string;
|
|
|
|
}
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export class TLVideoUtil extends TLBoxUtil<TLVideoShape> {
|
|
|
|
// (undocumented)
|
|
|
|
canEdit: () => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
defaultProps(): TLVideoShape['props'];
|
|
|
|
// (undocumented)
|
|
|
|
indicator(shape: TLVideoShape): JSX.Element;
|
|
|
|
// (undocumented)
|
|
|
|
isAspectRatioLocked: () => boolean;
|
|
|
|
// (undocumented)
|
|
|
|
render(shape: TLVideoShape): JSX.Element;
|
|
|
|
// (undocumented)
|
|
|
|
toSvg(shape: TLVideoShape): SVGGElement;
|
|
|
|
// (undocumented)
|
|
|
|
static type: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLWheelEvent = (info: TLWheelEventInfo) => void;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type TLWheelEventInfo = TLBaseEventInfo & {
|
|
|
|
type: 'wheel';
|
|
|
|
name: 'wheel';
|
|
|
|
delta: Vec2dModel;
|
|
|
|
};
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const truncateStringWithEllipsis: (str: string, maxLength: number) => string;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type UiEnterHandler = (info: any, from: string) => void;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type UiEvent = TLCancelEvent | TLClickEvent | TLCompleteEvent | TLKeyboardEvent | TLPinchEvent | TLPointerEvent;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type UiEventType = 'click' | 'keyboard' | 'pinch' | 'pointer' | 'wheel' | 'zoom';
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export type UiExitHandler = (info: any, to: string) => void;
|
|
|
|
|
|
|
|
// @public
|
|
|
|
export function uniqueId(): string;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export const useApp: () => App;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export function useContainer(): HTMLDivElement;
|
|
|
|
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
export function useLocalStore(opts?: {
|
|
|
|
persistenceKey?: string | undefined;
|
|
|
|
} & StoreOptions): StoreWithStatus;
|
|
|
|
|
2023-05-03 13:48:46 +00:00
|
|
|
// @internal (undocumented)
|
2023-05-25 09:54:29 +00:00
|
|
|
export function usePeerIds(): string[];
|
2023-05-03 13:48:46 +00:00
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export function usePrefersReducedMotion(): boolean;
|
|
|
|
|
2023-05-03 13:48:46 +00:00
|
|
|
// @internal (undocumented)
|
2023-05-25 09:54:29 +00:00
|
|
|
export function usePresence(userId: string): null | TLInstancePresence;
|
2023-05-03 13:48:46 +00:00
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export function useQuickReactor(name: string, reactFn: () => void, deps?: any[]): void;
|
|
|
|
|
2023-05-25 09:54:29 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
export const USER_COLORS: readonly ["#FF802B", "#EC5E41", "#F2555A", "#F04F88", "#E34BA9", "#BD54C6", "#9D5BD2", "#7B66DC", "#02B1CC", "#11B3A3", "#39B178", "#55B467"];
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export function useReactor(name: string, reactFn: () => void, deps?: any[] | undefined): void;
|
|
|
|
|
[refactor] User-facing APIs (#1478)
This PR updates our user-facing APIs for the Tldraw and TldrawEditor
components, as well as the Editor (App). It mainly incorporates surface
changes from #1450 without any changes to validators or migrators,
incorporating feedback / discussion with @SomeHats and @ds300.
Here we:
- remove the TldrawEditorConfig
- bring back a loose version of shape definitions
- make a separation between "core" shapes and "default" shapes
- do not allow custom shapes, migrators or validators to overwrite core
shapes
- but _do_ allow new shapes
## `<Tldraw>` component
In this PR, the `Tldraw` component wraps both the `TldrawEditor`
component and our `TldrawUi` component. It accepts a union of props for
both components. Previously, this component also added local syncing via
a `useLocalSyncClient` hook call, however that has been pushed down to
the `TldrawEditor` component.
## `<TldrawEditor>` component
The `TldrawEditor` component now more neatly wraps up the different ways
that the editor can be configured.
## The store prop (`TldrawEditorProps.store`)
There are three main ways for the `TldrawEditor` component to be run:
1. with an externally defined store
2. with an externally defined syncing store (local or remote)
3. with an internally defined store
4. with an internally defined locally syncing store
The `store` prop allows for these configurations.
If the `store` prop is defined, it may be defined either as a `TLStore`
or as a `SyncedStore`. If the store is a `TLStore`, then the Editor will
assume that the store is ready to go; if it is defined as a SyncedStore,
then the component will display the loading / error screens as needed,
or the final editor once the store's status is "synced".
When the store is left undefined, then the `TldrawEditor` will create
its own internal store using the optional `instanceId`, `initialData`,
or `shapes` props to define the store / store schema.
If the `persistenceKey` prop is left undefined, then the store will not
be synced. If the `persistenceKey` is defined, then the store will be
synced locally. In the future, we may also here accept the API key /
roomId / etc for creating a remotely synced store.
The `SyncedStore` type has been expanded to also include types used for
remote syncing, e.g. with `ConnectionStatus`.
## Tools
By default, the App has two "baked-in" tools: the select tool and the
zoom tool. These cannot (for now) be replaced or removed. The default
tools are used by default, but may be replaced by other tools if
provided.
## Shapes
By default, the App has a set of "core" shapes:
- group
- embed
- bookmark
- image
- video
- text
That cannot by overwritten because they're created by the app at
different moments, such as when double clicking on the canvas or via a
copy and paste event. In follow up PRs, we'll split these out so that
users can replace parts of the code where these shapes are created.
### Change Type
- [x] `major` — Breaking Change
### Test Plan
- [x] Unit Tests
2023-06-01 15:47:34 +00:00
|
|
|
// @public (undocumented)
|
|
|
|
export function useTLStore(opts: StoreOptions): TLStore;
|
|
|
|
|
2023-04-25 11:01:25 +00:00
|
|
|
// @internal (undocumented)
|
|
|
|
export const WAY_TOO_BIG_ARROW_BEND_FACTOR = 10;
|
|
|
|
|
|
|
|
// @public (undocumented)
|
|
|
|
export class WeakMapCache<T extends object, K> {
|
|
|
|
// (undocumented)
|
|
|
|
access(item: T): K | undefined;
|
|
|
|
// (undocumented)
|
|
|
|
bust(): void;
|
|
|
|
// (undocumented)
|
|
|
|
get<P extends T>(item: P, cb: (item: P) => K): NonNullable<K>;
|
|
|
|
// (undocumented)
|
|
|
|
has(item: T): boolean;
|
|
|
|
// (undocumented)
|
|
|
|
invalidate(item: T): void;
|
|
|
|
// (undocumented)
|
|
|
|
items: WeakMap<T, K>;
|
|
|
|
// (undocumented)
|
|
|
|
set(item: T, value: K): void;
|
|
|
|
}
|
|
|
|
|
|
|
|
// @internal (undocumented)
|
|
|
|
export const ZOOMS: number[];
|
|
|
|
|
|
|
|
|
|
|
|
export * from "@tldraw/tlschema";
|
|
|
|
|
|
|
|
// (No @packageDocumentation comment for this package)
|
|
|
|
|
|
|
|
```
|