Pārlūkot izejas kodu

Replaces isDarkMode with meta, a more flexible option for custom rendering context

main
Steve Ruiz 3 gadus atpakaļ
vecāks
revīzija
64d00dc427
47 mainītis faili ar 390 papildinājumiem un 335 dzēšanām
  1. 2
    3
      .vscode/snippets.code-snippets
  2. 4
    2
      package.json
  3. 3
    3
      packages/core/src/components/canvas/canvas.tsx
  4. 0
    1
      packages/core/src/components/page/page.test.tsx
  5. 11
    3
      packages/core/src/components/page/page.tsx
  6. 57
    9
      packages/core/src/components/renderer/renderer.tsx
  7. 7
    5
      packages/core/src/components/shape/editing-text-shape.tsx
  8. 8
    6
      packages/core/src/components/shape/rendered-shape.tsx
  9. 9
    2
      packages/core/src/components/shape/shape-node.tsx
  10. 0
    1
      packages/core/src/components/shape/shape.test.tsx
  11. 9
    3
      packages/core/src/components/shape/shape.tsx
  12. 15
    17
      packages/core/src/hooks/useShapeTree.tsx
  13. 0
    4
      packages/core/src/index.ts
  14. 8
    12
      packages/core/src/types.ts
  15. 0
    8
      packages/core/src/utils/utils.ts
  16. 7
    1
      packages/tldraw/README.md
  17. 71
    52
      packages/tldraw/src/components/page-panel/page-panel.tsx
  18. 3
    1
      packages/tldraw/src/components/tldraw/tldraw.tsx
  19. 55
    101
      packages/tldraw/src/shape/shapes/arrow/arrow.tsx
  20. 11
    4
      packages/tldraw/src/shape/shapes/draw/draw.tsx
  21. 11
    4
      packages/tldraw/src/shape/shapes/ellipse/ellipse.tsx
  22. 11
    4
      packages/tldraw/src/shape/shapes/rectangle/rectangle.tsx
  23. 11
    5
      packages/tldraw/src/shape/shapes/text/text.tsx
  24. 3
    3
      packages/tldraw/src/state/command/align/align.command.ts
  25. 2
    3
      packages/tldraw/src/state/command/change-page/change-page.command.ts
  26. 2
    2
      packages/tldraw/src/state/command/create-page/create-page.command.ts
  27. 5
    5
      packages/tldraw/src/state/command/create/create.command.ts
  28. 2
    2
      packages/tldraw/src/state/command/delete-page/delete-page.command.ts
  29. 2
    2
      packages/tldraw/src/state/command/delete/delete.command.ts
  30. 2
    2
      packages/tldraw/src/state/command/distribute/distribute.command.ts
  31. 2
    2
      packages/tldraw/src/state/command/duplicate-page/duplicate-page.command.ts
  32. 2
    2
      packages/tldraw/src/state/command/duplicate/duplicate.command.ts
  33. 2
    2
      packages/tldraw/src/state/command/flip/flip.command.ts
  34. 2
    2
      packages/tldraw/src/state/command/move/move.command.ts
  35. 2
    2
      packages/tldraw/src/state/command/rename-page/rename-page.command.ts
  36. 2
    2
      packages/tldraw/src/state/command/rotate/rotate.command.ts
  37. 2
    2
      packages/tldraw/src/state/command/stretch/stretch.command.ts
  38. 2
    2
      packages/tldraw/src/state/command/style/style.command.ts
  39. 6
    2
      packages/tldraw/src/state/command/toggle-decoration/toggle-decoration.command.ts
  40. 2
    2
      packages/tldraw/src/state/command/toggle/toggle.command.ts
  41. 2
    2
      packages/tldraw/src/state/command/translate/translate.command.ts
  42. 2
    3
      packages/tldraw/src/state/session/sessions/brush/brush.session.ts
  43. 2
    2
      packages/tldraw/src/state/session/sessions/translate/translate.session.ts
  44. 8
    11
      packages/tldraw/src/state/tldr.ts
  45. 19
    26
      packages/tldraw/src/types.ts
  46. 1
    0
      tsconfig.base.json
  47. 1
    1
      tsconfig.tsbuildinfo

+ 2
- 3
.vscode/snippets.code-snippets Parādīt failu

@@ -1,7 +1,7 @@
1 1
 {
2 2
   "createComment": {
3 3
     "scope": "typescript,typescriptreact",
4
-    "prefix": "/**",
4
+    "prefix": "ccc",
5 5
     "body": [
6 6
       "/**",
7 7
       " * ${1:description}",
@@ -10,8 +10,7 @@
10 10
       " *",
11 11
       " *```ts",
12 12
       " * ${2:example}",
13
-      " *```",
14
-      " */"
13
+      " *```"
15 14
     ],
16 15
     "description": "comment"
17 16
   }

+ 4
- 2
package.json Parādīt failu

@@ -19,11 +19,12 @@
19 19
     "test": "jest",
20 20
     "test:watch": "test --watchAll",
21 21
     "lerna": "lerna",
22
-    "start": "yarn build:packages && lerna run start --parallel",
22
+    "start": "lerna run start --stream --parallel",
23 23
     "start:www": "yarn build:packages && lerna run start --parallel & cd packages/www && yarn dev",
24 24
     "build": "yarn build:packages && cd packages/www && yarn build",
25 25
     "build:packages": "cd packages/core && yarn build && cd ../tldraw && yarn build",
26
-    "publish:patch": "yarn build:packages && lerna publish patch"
26
+    "publish:patch": "yarn build:packages && lerna publish patch",
27
+    "docs": "lerna run docs --stream"
27 28
   },
28 29
   "devDependencies": {
29 30
     "@babel/plugin-syntax-import-meta": "^7.10.4",
@@ -46,6 +47,7 @@
46 47
     "react-dom": "^17.0.2",
47 48
     "ts-jest": "^27.0.5",
48 49
     "tslib": "^2.3.0",
50
+    "typedoc": "^0.21.9",
49 51
     "typescript": "^4.4.2"
50 52
   },
51 53
   "dependencies": {},

+ 3
- 3
packages/core/src/components/canvas/canvas.tsx Parādīt failu

@@ -23,13 +23,13 @@ interface CanvasProps<T extends TLShape> {
23 23
   hideBounds?: boolean
24 24
   hideHandles?: boolean
25 25
   hideIndicators?: boolean
26
-  isDarkMode?: boolean
26
+  meta?: Record<string, unknown>
27 27
 }
28 28
 
29 29
 export const Canvas = React.memo(function Canvas<T extends TLShape>({
30 30
   page,
31 31
   pageState,
32
-  isDarkMode = false,
32
+  meta,
33 33
   hideHandles = false,
34 34
   hideBounds = false,
35 35
   hideIndicators = false,
@@ -58,7 +58,7 @@ export const Canvas = React.memo(function Canvas<T extends TLShape>({
58 58
               hideBounds={hideBounds}
59 59
               hideIndicators={hideIndicators}
60 60
               hideHandles={hideHandles}
61
-              isDarkMode={isDarkMode}
61
+              meta={meta}
62 62
             />
63 63
             <Brush />
64 64
           </g>

+ 0
- 1
packages/core/src/components/page/page.test.tsx Parādīt failu

@@ -11,7 +11,6 @@ describe('page', () => {
11 11
         hideBounds={false}
12 12
         hideIndicators={false}
13 13
         hideHandles={false}
14
-        isDarkMode={false}
15 14
       />
16 15
     )
17 16
   })

+ 11
- 3
packages/core/src/components/page/page.tsx Parādīt failu

@@ -13,22 +13,30 @@ interface PageProps<T extends TLShape> {
13 13
   hideBounds: boolean
14 14
   hideHandles: boolean
15 15
   hideIndicators: boolean
16
-  isDarkMode: boolean
16
+  meta?: Record<string, unknown>
17 17
 }
18 18
 
19
+/**
20
+ * The Page component renders the current page.
21
+ *
22
+ * ### Example
23
+ *
24
+ *```ts
25
+ * example
26
+ *``` */
19 27
 export function Page<T extends TLShape>({
20 28
   page,
21 29
   pageState,
22 30
   hideBounds,
23 31
   hideHandles,
24 32
   hideIndicators,
25
-  isDarkMode,
33
+  meta,
26 34
 }: PageProps<T>): JSX.Element {
27 35
   const { callbacks, shapeUtils } = useTLContext()
28 36
 
29 37
   useRenderOnResize()
30 38
 
31
-  const shapeTree = useShapeTree(page, pageState, shapeUtils, isDarkMode, callbacks.onChange)
39
+  const shapeTree = useShapeTree(page, pageState, shapeUtils, meta, callbacks.onChange)
32 40
 
33 41
   const { shapeWithHandles } = useHandles(page, pageState)
34 42
 

+ 57
- 9
packages/core/src/components/renderer/renderer.tsx Parādīt failu

@@ -3,7 +3,6 @@ import type {
3 3
   TLShape,
4 4
   TLPage,
5 5
   TLPageState,
6
-  TLSettings,
7 6
   TLCallbacks,
8 7
   TLShapeUtils,
9 8
   TLTheme,
@@ -13,30 +12,79 @@ import type {
13 12
 import { Canvas } from '../canvas'
14 13
 import { useTLTheme, TLContext } from '../../hooks'
15 14
 
16
-export interface RendererProps<T extends TLShape>
17
-  extends Partial<TLSettings>,
18
-    Partial<TLCallbacks> {
15
+export interface RendererProps<T extends TLShape, M extends Record<string, unknown>>
16
+  extends Partial<TLCallbacks> {
17
+  /**
18
+   * An object containing instances of your shape classes.
19
+   */
19 20
   shapeUtils: TLShapeUtils<T>
21
+  /**
22
+   * The current page, containing shapes and bindings.
23
+   */
20 24
   page: TLPage<T, TLBinding>
25
+  /**
26
+   * The current page state.
27
+   */
21 28
   pageState: TLPageState
29
+  /**
30
+   * An object of custom theme colors.
31
+   */
22 32
   theme?: Partial<TLTheme>
33
+  /**
34
+   * When true, the renderer will not show the bounds for selected objects.
35
+   */
23 36
   hideBounds?: boolean
37
+  /**
38
+   * When true, the renderer will not show the handles of shapes with handles.
39
+   */
24 40
   hideHandles?: boolean
41
+  /**
42
+   * When true, the renderer will not show indicators for selected or hovered objects,
43
+   */
25 44
   hideIndicators?: boolean
26
-  isDarkMode?: boolean
45
+  /**
46
+   * When true, the renderer will ignore all inputs that were not made by a stylus or pen-type device.
47
+   */
48
+  isPenMode?: boolean
49
+  /**
50
+   * An object of custom options that should be passed to rendered shapes.
51
+   */
52
+  meta?: M
27 53
 }
28 54
 
29
-export function Renderer<T extends TLShape>({
55
+/**
56
+ The Renderer component is the main component of the library. It accepts the current `page`, the `shapeUtils` needed to interpret and render the shapes and bindings on the `page`, and the current `pageState`.
57
+ 
58
+* It also (optionally) accepts several settings and visibility flags,
59
+ * a `theme` to use, and callbacks to respond to various user interactions.
60
+ *
61
+ * ### Example
62
+ *
63
+ *```tsx
64
+ * <Renderer 
65
+ *  shapeUtils={shapeUtils} 
66
+ *  page={page} 
67
+ *  pageState={pageState}
68
+ * />
69
+ *```
70
+ */
71
+
72
+/**
73
+ * The Renderer component is the main component of the library. It accepts the current `page`, the `shapeUtils` needed to interpret and render the shapes and bindings on the `page`, and the current `pageState`.
74
+ * @param props
75
+ * @returns
76
+ */
77
+export function Renderer<T extends TLShape, M extends Record<string, unknown>>({
30 78
   shapeUtils,
31 79
   page,
32 80
   pageState,
33 81
   theme,
82
+  meta,
34 83
   hideHandles = false,
35 84
   hideIndicators = false,
36 85
   hideBounds = false,
37
-  isDarkMode = false,
38 86
   ...rest
39
-}: RendererProps<T>): JSX.Element {
87
+}: RendererProps<T, M>): JSX.Element {
40 88
   useTLTheme(theme)
41 89
   const rScreenBounds = React.useRef<TLBounds>(null)
42 90
   const rPageState = React.useRef<TLPageState>(pageState)
@@ -60,7 +108,7 @@ export function Renderer<T extends TLShape>({
60 108
         hideBounds={hideBounds}
61 109
         hideIndicators={hideIndicators}
62 110
         hideHandles={hideHandles}
63
-        isDarkMode={isDarkMode}
111
+        meta={meta}
64 112
       />
65 113
     </TLContext.Provider>
66 114
   )

+ 7
- 5
packages/core/src/components/shape/editing-text-shape.tsx Parādīt failu

@@ -2,19 +2,21 @@ import { useTLContext } from '+hooks'
2 2
 import * as React from 'react'
3 3
 import type { TLShapeUtil, TLRenderInfo, TLShape } from '+types'
4 4
 
5
-interface EditingShapeProps<T extends TLShape> extends TLRenderInfo {
5
+interface EditingShapeProps<T extends TLShape, M extends Record<string, unknown>>
6
+  extends TLRenderInfo {
6 7
   shape: T
7 8
   utils: TLShapeUtil<T>
9
+  meta?: M
8 10
 }
9 11
 
10
-export function EditingTextShape({
12
+export function EditingTextShape<M extends Record<string, unknown>>({
11 13
   shape,
12 14
   utils,
13 15
   isEditing,
14 16
   isBinding,
15
-  isDarkMode,
16 17
   isCurrentParent,
17
-}: EditingShapeProps<TLShape>) {
18
+  meta,
19
+}: EditingShapeProps<TLShape, M>) {
18 20
   const {
19 21
     callbacks: { onTextChange, onTextBlur, onTextFocus, onTextKeyDown, onTextKeyUp },
20 22
   } = useTLContext()
@@ -26,11 +28,11 @@ export function EditingTextShape({
26 28
     isEditing,
27 29
     isCurrentParent,
28 30
     isBinding,
29
-    isDarkMode,
30 31
     onTextChange,
31 32
     onTextBlur,
32 33
     onTextFocus,
33 34
     onTextKeyDown,
34 35
     onTextKeyUp,
36
+    meta,
35 37
   })
36 38
 }

+ 8
- 6
packages/core/src/components/shape/rendered-shape.tsx Parādīt failu

@@ -1,32 +1,34 @@
1 1
 import * as React from 'react'
2 2
 import type { TLShapeUtil, TLRenderInfo, TLShape } from '+types'
3 3
 
4
-interface RenderedShapeProps<T extends TLShape> extends TLRenderInfo {
4
+interface RenderedShapeProps<T extends TLShape, M extends Record<string, unknown>>
5
+  extends TLRenderInfo {
5 6
   shape: T
6 7
   utils: TLShapeUtil<T>
8
+  meta?: M
7 9
 }
8 10
 
9 11
 export const RenderedShape = React.memo(
10
-  function RenderedShape({
12
+  function RenderedShape<M extends Record<string, unknown>>({
11 13
     shape,
12 14
     utils,
13 15
     isEditing,
14 16
     isBinding,
15
-    isDarkMode,
16 17
     isCurrentParent,
17
-  }: RenderedShapeProps<TLShape>) {
18
+    meta,
19
+  }: RenderedShapeProps<TLShape, M>) {
18 20
     return utils.render(shape, {
19 21
       isEditing,
20 22
       isBinding,
21
-      isDarkMode,
22 23
       isCurrentParent,
24
+      meta,
23 25
     })
24 26
   },
25 27
   (prev, next) => {
26 28
     if (
27 29
       prev.isEditing !== next.isEditing ||
28
-      prev.isDarkMode !== next.isDarkMode ||
29 30
       prev.isBinding !== next.isBinding ||
31
+      prev.meta !== next.meta ||
30 32
       prev.isCurrentParent !== next.isCurrentParent
31 33
     ) {
32 34
       return false

+ 9
- 2
packages/core/src/components/shape/shape-node.tsx Parādīt failu

@@ -3,15 +3,22 @@ import type { IShapeTreeNode } from '+types'
3 3
 import { Shape } from './shape'
4 4
 
5 5
 export const ShapeNode = React.memo(
6
-  ({ shape, children, isEditing, isDarkMode, isBinding, isCurrentParent }: IShapeTreeNode) => {
6
+  <M extends Record<string, unknown>>({
7
+    shape,
8
+    children,
9
+    isEditing,
10
+    isBinding,
11
+    isCurrentParent,
12
+    meta,
13
+  }: IShapeTreeNode<M>) => {
7 14
     return (
8 15
       <>
9 16
         <Shape
10 17
           shape={shape}
11 18
           isEditing={isEditing}
12
-          isDarkMode={isDarkMode}
13 19
           isBinding={isBinding}
14 20
           isCurrentParent={isCurrentParent}
21
+          meta={meta}
15 22
         />
16 23
         {children &&
17 24
           children.map((childNode) => <ShapeNode key={childNode.shape.id} {...childNode} />)}

+ 0
- 1
packages/core/src/components/shape/shape.test.tsx Parādīt failu

@@ -9,7 +9,6 @@ describe('handles', () => {
9 9
         shape={mockUtils.box.create({})}
10 10
         isEditing={false}
11 11
         isBinding={false}
12
-        isDarkMode={false}
13 12
         isCurrentParent={false}
14 13
       />
15 14
     )

+ 9
- 3
packages/core/src/components/shape/shape.tsx Parādīt failu

@@ -5,7 +5,13 @@ import { RenderedShape } from './rendered-shape'
5 5
 import { EditingTextShape } from './editing-text-shape'
6 6
 
7 7
 export const Shape = React.memo(
8
-  ({ shape, isEditing, isBinding, isDarkMode, isCurrentParent }: IShapeTreeNode) => {
8
+  <M extends Record<string, unknown>>({
9
+    shape,
10
+    isEditing,
11
+    isBinding,
12
+    isCurrentParent,
13
+    meta,
14
+  }: IShapeTreeNode<M>) => {
9 15
     const { shapeUtils } = useTLContext()
10 16
     const events = useShapeEvents(shape.id, isCurrentParent)
11 17
     const utils = shapeUtils[shape.type]
@@ -26,9 +32,9 @@ export const Shape = React.memo(
26 32
             shape={shape}
27 33
             isBinding={false}
28 34
             isCurrentParent={false}
29
-            isDarkMode={isDarkMode}
30 35
             isEditing={true}
31 36
             utils={utils}
37
+            meta={meta}
32 38
           />
33 39
         ) : (
34 40
           <RenderedShape
@@ -36,8 +42,8 @@ export const Shape = React.memo(
36 42
             utils={utils}
37 43
             isBinding={isBinding}
38 44
             isCurrentParent={isCurrentParent}
39
-            isDarkMode={isDarkMode}
40 45
             isEditing={isEditing}
46
+            meta={meta}
41 47
           />
42 48
         )}
43 49
       </g>

+ 15
- 17
packages/core/src/hooks/useShapeTree.tsx Parādīt failu

@@ -10,26 +10,26 @@ import type {
10 10
 } from '+types'
11 11
 import { Utils, Vec } from '+utils'
12 12
 
13
-function addToShapeTree<T extends TLShape>(
13
+function addToShapeTree<T extends TLShape, M extends Record<string, unknown>>(
14 14
   shape: TLShape,
15
-  branch: IShapeTreeNode[],
15
+  branch: IShapeTreeNode<M>[],
16 16
   shapes: TLPage<T, TLBinding>['shapes'],
17 17
   selectedIds: string[],
18
-  info: {
18
+  pageState: {
19 19
     bindingId?: string
20 20
     hoveredId?: string
21 21
     currentParentId?: string
22 22
     editingId?: string
23 23
     editingBindingId?: string
24
-    isDarkMode?: boolean
25
-  }
24
+  },
25
+  meta?: M
26 26
 ) {
27
-  const node: IShapeTreeNode = {
27
+  const node: IShapeTreeNode<M> = {
28 28
     shape,
29
-    isCurrentParent: info.currentParentId === shape.id,
30
-    isEditing: info.editingId === shape.id,
31
-    isBinding: info.bindingId === shape.id,
32
-    isDarkMode: info.isDarkMode || false,
29
+    isCurrentParent: pageState.currentParentId === shape.id,
30
+    isEditing: pageState.editingId === shape.id,
31
+    isBinding: pageState.bindingId === shape.id,
32
+    meta,
33 33
   }
34 34
 
35 35
   branch.push(node)
@@ -41,16 +41,16 @@ function addToShapeTree<T extends TLShape>(
41 41
       .sort((a, b) => a.childIndex - b.childIndex)
42 42
       .forEach((childShape) =>
43 43
         // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
44
-        addToShapeTree(childShape, node.children!, shapes, selectedIds, info)
44
+        addToShapeTree(childShape, node.children!, shapes, selectedIds, pageState, meta)
45 45
       )
46 46
   }
47 47
 }
48 48
 
49
-export function useShapeTree<T extends TLShape>(
49
+export function useShapeTree<T extends TLShape, M extends Record<string, unknown>>(
50 50
   page: TLPage<T, TLBinding>,
51 51
   pageState: TLPageState,
52 52
   shapeUtils: TLShapeUtils<T>,
53
-  isDarkMode: boolean,
53
+  meta?: M,
54 54
   onChange?: TLCallbacks['onChange']
55 55
 ) {
56 56
   const rPreviousCount = React.useRef(0)
@@ -102,13 +102,11 @@ export function useShapeTree<T extends TLShape>(
102 102
 
103 103
   // Populate the shape tree
104 104
 
105
-  const tree: IShapeTreeNode[] = []
105
+  const tree: IShapeTreeNode<M>[] = []
106 106
 
107 107
   shapesToRender
108 108
     .sort((a, b) => a.childIndex - b.childIndex)
109
-    .forEach((shape) =>
110
-      addToShapeTree(shape, tree, page.shapes, selectedIds, { ...pageState, isDarkMode })
111
-    )
109
+    .forEach((shape) => addToShapeTree(shape, tree, page.shapes, selectedIds, pageState, meta))
112 110
 
113 111
   return tree
114 112
 }

+ 0
- 4
packages/core/src/index.ts Parādīt failu

@@ -2,7 +2,3 @@ export * from './components'
2 2
 export * from './types'
3 3
 export * from './utils'
4 4
 export * from './inputs'
5
-
6
-export interface Steve {
7
-  age: string
8
-}

+ 8
- 12
packages/core/src/types.ts Parādīt failu

@@ -54,17 +54,17 @@ export interface TLShape {
54 54
 
55 55
 export type TLShapeUtils<T extends TLShape> = Record<string, TLShapeUtil<T>>
56 56
 
57
-export interface TLRenderInfo<T extends SVGElement | HTMLElement = any> {
57
+export interface TLRenderInfo<M = any, T extends SVGElement | HTMLElement = any> {
58
+  ref?: React.RefObject<T>
58 59
   isEditing: boolean
59 60
   isBinding: boolean
60
-  isDarkMode: boolean
61 61
   isCurrentParent: boolean
62
-  ref?: React.RefObject<T>
63 62
   onTextChange?: TLCallbacks['onTextChange']
64 63
   onTextBlur?: TLCallbacks['onTextBlur']
65 64
   onTextFocus?: TLCallbacks['onTextFocus']
66 65
   onTextKeyDown?: TLCallbacks['onTextKeyDown']
67 66
   onTextKeyUp?: TLCallbacks['onTextKeyUp']
67
+  meta: M extends any ? M : never
68 68
 }
69 69
 
70 70
 export interface TLTool {
@@ -79,12 +79,6 @@ export interface TLBinding {
79 79
   fromId: string
80 80
 }
81 81
 
82
-export interface TLSettings {
83
-  isDebugMode: boolean
84
-  isDarkMode: boolean
85
-  isPenMode: boolean
86
-}
87
-
88 82
 export interface TLTheme {
89 83
   brushFill?: string
90 84
   brushStroke?: string
@@ -375,24 +369,26 @@ export abstract class TLShapeUtil<T extends TLShape> {
375 369
 
376 370
 /* -------------------- Internal -------------------- */
377 371
 
378
-export interface IShapeTreeNode {
372
+export interface IShapeTreeNode<M extends Record<string, unknown>> {
379 373
   shape: TLShape
380
-  children?: IShapeTreeNode[]
374
+  children?: IShapeTreeNode<M>[]
381 375
   isEditing: boolean
382 376
   isBinding: boolean
383
-  isDarkMode: boolean
384 377
   isCurrentParent: boolean
378
+  meta?: M
385 379
 }
386 380
 
387 381
 /* -------------------------------------------------- */
388 382
 /*                    Utility Types                   */
389 383
 /* -------------------------------------------------- */
390 384
 
385
+/** @internal */
391 386
 export type MappedByType<T extends { type: string }> = {
392 387
   // eslint-disable-next-line @typescript-eslint/no-explicit-any
393 388
   [P in T['type']]: T extends any ? (P extends T['type'] ? T : never) : never
394 389
 }
395 390
 
391
+/** @internal */
396 392
 export type RequiredKeys<T> = {
397 393
   [K in keyof T]-?: Record<string, unknown> extends Pick<T, K> ? never : K
398 394
 }[keyof T]

+ 0
- 8
packages/core/src/utils/utils.ts Parādīt failu

@@ -1718,14 +1718,6 @@ export default Utils
1718 1718
 
1719 1719
 // Helper types
1720 1720
 
1721
-export type DeepPartial<T> = T extends Function
1722
-  ? T
1723
-  : T extends object
1724
-  ? T extends unknown[]
1725
-    ? DeepPartial<T[number]>[]
1726
-    : { [P in keyof T]?: DeepPartial<T[P]> }
1727
-  : T
1728
-
1729 1721
 type Entry<T> = {
1730 1722
   [K in keyof T]: [K, T[K]]
1731 1723
 }[keyof T]

+ 7
- 1
packages/tldraw/README.md Parādīt failu

@@ -5,7 +5,13 @@ This package contains the [tldraw](https://tldraw.com) editor as a standalone Re
5 5
 ## Installation
6 6
 
7 7
 ```bash
8
-yarn add @tldraw/tldraw --peer
8
+npm i @tldraw/tldraw
9
+```
10
+
11
+or
12
+
13
+```bash
14
+yarn add @tldraw/tldraw
9 15
 ```
10 16
 
11 17
 ## Usage

+ 71
- 52
packages/tldraw/src/components/page-panel/page-panel.tsx Parādīt failu

@@ -18,13 +18,16 @@ import type { Data } from '~types'
18 18
 const sortedSelector = (s: Data) =>
19 19
   Object.values(s.document.pages).sort((a, b) => (a.childIndex || 0) - (b.childIndex || 0))
20 20
 
21
-const currentPageSelector = (s: Data) => s.document.pages[s.appState.currentPageId]
21
+const currentPageNameSelector = (s: Data) => s.document.pages[s.appState.currentPageId].name
22
+
23
+const currentPageIdSelector = (s: Data) => s.document.pages[s.appState.currentPageId].id
22 24
 
23 25
 export function PagePanel(): JSX.Element {
26
+  const { useSelector } = useTLDrawContext()
27
+
24 28
   const rIsOpen = React.useRef(false)
25
-  const [isOpen, setIsOpen] = React.useState(false)
26 29
 
27
-  const { tlstate, useSelector } = useTLDrawContext()
30
+  const [isOpen, setIsOpen] = React.useState(false)
28 31
 
29 32
   React.useEffect(() => {
30 33
     if (rIsOpen.current !== isOpen) {
@@ -32,70 +35,86 @@ export function PagePanel(): JSX.Element {
32 35
     }
33 36
   }, [isOpen])
34 37
 
35
-  const handleCreatePage = React.useCallback(() => {
36
-    tlstate.createPage()
37
-  }, [tlstate])
38
+  const handleClose = React.useCallback(() => {
39
+    setIsOpen(false)
40
+  }, [setIsOpen])
38 41
 
39
-  const handleChangePage = React.useCallback(
40
-    (id: string) => {
41
-      setIsOpen(false)
42
-      tlstate.changePage(id)
42
+  const handleOpenChange = React.useCallback(
43
+    (isOpen: boolean) => {
44
+      if (rIsOpen.current !== isOpen) {
45
+        setIsOpen(isOpen)
46
+      }
43 47
     },
44
-    [tlstate]
48
+    [setIsOpen]
45 49
   )
46
-
47
-  const currentPage = useSelector(currentPageSelector)
48
-
49
-  const sortedPages = useSelector(sortedSelector)
50
+  const currentPageName = useSelector(currentPageNameSelector)
50 51
 
51 52
   return (
52
-    <DropdownMenu.Root
53
-      dir="ltr"
54
-      open={isOpen}
55
-      onOpenChange={(isOpen) => {
56
-        if (rIsOpen.current !== isOpen) {
57
-          setIsOpen(isOpen)
58
-        }
59
-      }}
60
-    >
53
+    <DropdownMenu.Root dir="ltr" open={isOpen} onOpenChange={handleOpenChange}>
61 54
       <FloatingContainer>
62 55
         <RowButton as={DropdownMenu.Trigger} bp={breakpoints} variant="noIcon">
63
-          <span>{currentPage.name || 'Page'}</span>
56
+          <span>{currentPageName || 'Page'}</span>
64 57
         </RowButton>
65 58
       </FloatingContainer>
66 59
       <MenuContent as={DropdownMenu.Content} sideOffset={8} align="start">
67
-        <DropdownMenu.RadioGroup value={currentPage.id} onValueChange={handleChangePage}>
68
-          {sortedPages.map((page) => (
69
-            <ButtonWithOptions key={page.id}>
70
-              <DropdownMenu.RadioItem
71
-                as={RowButton}
72
-                bp={breakpoints}
73
-                value={page.id}
74
-                variant="pageButton"
75
-              >
76
-                <span>{page.name || 'Page'}</span>
77
-                <DropdownMenu.ItemIndicator>
78
-                  <IconWrapper size="small">
79
-                    <CheckIcon />
80
-                  </IconWrapper>
81
-                </DropdownMenu.ItemIndicator>
82
-              </DropdownMenu.RadioItem>
83
-              <PageOptionsDialog page={page} />
84
-            </ButtonWithOptions>
85
-          ))}
86
-        </DropdownMenu.RadioGroup>
87
-        <DropdownMenuDivider />
88
-        <DropdownMenuButton onSelect={handleCreatePage}>
89
-          <span>Create Page</span>
90
-          <IconWrapper size="small">
91
-            <PlusIcon />
92
-          </IconWrapper>
93
-        </DropdownMenuButton>
60
+        {isOpen && <PageMenuContent onClose={handleClose} />}
94 61
       </MenuContent>
95 62
     </DropdownMenu.Root>
96 63
   )
97 64
 }
98 65
 
66
+function PageMenuContent({ onClose }: { onClose: () => void }) {
67
+  const { tlstate, useSelector } = useTLDrawContext()
68
+
69
+  const sortedPages = useSelector(sortedSelector)
70
+
71
+  const currentPageId = useSelector(currentPageIdSelector)
72
+
73
+  const handleCreatePage = React.useCallback(() => {
74
+    tlstate.createPage()
75
+  }, [tlstate])
76
+
77
+  const handleChangePage = React.useCallback(
78
+    (id: string) => {
79
+      onClose()
80
+      tlstate.changePage(id)
81
+    },
82
+    [tlstate]
83
+  )
84
+
85
+  return (
86
+    <>
87
+      <DropdownMenu.RadioGroup value={currentPageId} onValueChange={handleChangePage}>
88
+        {sortedPages.map((page) => (
89
+          <ButtonWithOptions key={page.id}>
90
+            <DropdownMenu.RadioItem
91
+              as={RowButton}
92
+              bp={breakpoints}
93
+              value={page.id}
94
+              variant="pageButton"
95
+            >
96
+              <span>{page.name || 'Page'}</span>
97
+              <DropdownMenu.ItemIndicator>
98
+                <IconWrapper size="small">
99
+                  <CheckIcon />
100
+                </IconWrapper>
101
+              </DropdownMenu.ItemIndicator>
102
+            </DropdownMenu.RadioItem>
103
+            <PageOptionsDialog page={page} />
104
+          </ButtonWithOptions>
105
+        ))}
106
+      </DropdownMenu.RadioGroup>
107
+      <DropdownMenuDivider />
108
+      <DropdownMenuButton onSelect={handleCreatePage}>
109
+        <span>Create Page</span>
110
+        <IconWrapper size="small">
111
+          <PlusIcon />
112
+        </IconWrapper>
113
+      </DropdownMenuButton>
114
+    </>
115
+  )
116
+}
117
+
99 118
 const ButtonWithOptions = styled('div', {
100 119
   display: 'grid',
101 120
   gridTemplateColumns: '1fr auto',

+ 3
- 1
packages/tldraw/src/components/tldraw/tldraw.tsx Parādīt failu

@@ -53,6 +53,8 @@ export function TLDraw({ document, currentPageId, onMount, onChange: _onChange }
53 53
   // Hide indicators when not using the select tool, or when in session
54 54
   const hideIndicators = !isSelecting || isInSession
55 55
 
56
+  const meta = React.useMemo(() => ({ isDarkMode }), [isDarkMode])
57
+
56 58
   React.useEffect(() => {
57 59
     if (!document) return
58 60
     tlstate.loadDocument(document, _onChange)
@@ -92,7 +94,7 @@ export function TLDraw({ document, currentPageId, onMount, onChange: _onChange }
92 94
               pageState={pageState}
93 95
               shapeUtils={tldrawShapeUtils}
94 96
               theme={theme}
95
-              isDarkMode={isDarkMode}
97
+              meta={meta}
96 98
               hideBounds={hideBounds}
97 99
               hideHandles={hideHandles}
98 100
               hideIndicators={hideIndicators}

+ 55
- 101
packages/tldraw/src/shape/shapes/arrow/arrow.tsx Parādīt failu

@@ -4,7 +4,6 @@ import {
4 4
   Utils,
5 5
   Vec,
6 6
   TLTransformInfo,
7
-  TLRenderInfo,
8 7
   Intersect,
9 8
   TLHandle,
10 9
   TLPointerInfo,
@@ -20,6 +19,7 @@ import {
20 19
   DashStyle,
21 20
   TLDrawShape,
22 21
   ArrowBinding,
22
+  TLDrawRenderInfo,
23 23
 } from '~types'
24 24
 
25 25
 export class Arrow extends TLDrawShapeUtil<ArrowShape> {
@@ -70,7 +70,7 @@ export class Arrow extends TLDrawShapeUtil<ArrowShape> {
70 70
     return next.handles !== prev.handles || next.style !== prev.style
71 71
   }
72 72
 
73
-  render = (shape: ArrowShape, { isDarkMode }: TLRenderInfo) => {
73
+  render = (shape: ArrowShape, { meta }: TLDrawRenderInfo) => {
74 74
     const {
75 75
       handles: { start, bend, end },
76 76
       decorations = {},
@@ -79,57 +79,11 @@ export class Arrow extends TLDrawShapeUtil<ArrowShape> {
79 79
 
80 80
     const isDraw = style.dash === DashStyle.Draw
81 81
 
82
-    // if (!isDraw) {
83
-    //   const styles = getShapeStyle(style, isDarkMode)
84
-
85
-    //   const { strokeWidth } = styles
86
-
87
-    //   const arrowDist = Vec.dist(start.point, end.point)
88
-
89
-    //   const sw = strokeWidth * 1.618
90
-
91
-    //   const { strokeDasharray, strokeDashoffset } = getPerfectDashProps(
92
-    //     arrowDist,
93
-    //     sw,
94
-    //     shape.style.dash,
95
-    //     2
96
-    //   )
97
-
98
-    //   const path = getArrowPath(shape)
99
-
100
-    //   return (
101
-    //     <g pointerEvents="none">
102
-    //       <path
103
-    //         d={path}
104
-    //         fill="none"
105
-    //         stroke="transparent"
106
-    //         strokeWidth={Math.max(8, strokeWidth * 2)}
107
-    //         strokeDasharray="none"
108
-    //         strokeDashoffset="none"
109
-    //         strokeLinecap="round"
110
-    //         strokeLinejoin="round"
111
-    //         pointerEvents="stroke"
112
-    //       />
113
-    //       <path
114
-    //         d={path}
115
-    //         fill={isDraw ? styles.stroke : 'none'}
116
-    //         stroke={styles.stroke}
117
-    //         strokeWidth={sw}
118
-    //         strokeDasharray={strokeDasharray}
119
-    //         strokeDashoffset={strokeDashoffset}
120
-    //         strokeLinecap="round"
121
-    //         strokeLinejoin="round"
122
-    //         pointerEvents="stroke"
123
-    //       />
124
-    //     </g>
125
-    //   )
126
-    // }
127
-
128 82
     // TODO: Improve drawn arrows
129 83
 
130 84
     const isStraightLine = Vec.dist(bend.point, Vec.round(Vec.med(start.point, end.point))) < 1
131 85
 
132
-    const styles = getShapeStyle(style, isDarkMode)
86
+    const styles = getShapeStyle(style, meta.isDarkMode)
133 87
 
134 88
     const { strokeWidth } = styles
135 89
 
@@ -724,21 +678,6 @@ function renderCurvedFreehandArrowShaft(shape: ArrowShape, circle: number[]) {
724 678
   return path
725 679
 }
726 680
 
727
-function getArrowHeadPath(shape: ArrowShape, point: number[], inset: number[]) {
728
-  const { left, right } = getArrowHeadPoints(shape, point, inset)
729
-  return ['M', left, 'L', point, right].join(' ')
730
-}
731
-
732
-function getArrowHeadPoints(shape: ArrowShape, point: number[], inset: number[]) {
733
-  // Use the shape's random seed to create minor offsets for the angles
734
-  const getRandom = Utils.rng(shape.id)
735
-
736
-  return {
737
-    left: Vec.rotWith(inset, point, Math.PI / 6 + (Math.PI / 12) * getRandom()),
738
-    right: Vec.rotWith(inset, point, -Math.PI / 6 + (Math.PI / 12) * getRandom()),
739
-  }
740
-}
741
-
742 681
 function getCtp(shape: ArrowShape) {
743 682
   const { start, end, bend } = shape.handles
744 683
   return Utils.circleFromThreePoints(start.point, end.point, bend.point)
@@ -844,52 +783,67 @@ function getArrowPath(shape: ArrowShape) {
844 783
   return path.join(' ')
845 784
 }
846 785
 
847
-function getDrawArrowPath(shape: ArrowShape) {
848
-  const {
849
-    decorations,
850
-    handles: { start, end, bend: _bend },
851
-    style,
852
-  } = shape
786
+// function getArrowHeadPath(shape: ArrowShape, point: number[], inset: number[]) {
787
+//   const { left, right } = getArrowHeadPoints(shape, point, inset)
788
+//   return ['M', left, 'L', point, right].join(' ')
789
+// }
853 790
 
854
-  const { strokeWidth } = getShapeStyle(style, false)
791
+// function getArrowHeadPoints(shape: ArrowShape, point: number[], inset: number[]) {
792
+//   // Use the shape's random seed to create minor offsets for the angles
793
+//   const getRandom = Utils.rng(shape.id)
855 794
 
856
-  const arrowDist = Vec.dist(start.point, end.point)
795
+//   return {
796
+//     left: Vec.rotWith(inset, point, Math.PI / 6 + (Math.PI / 12) * getRandom()),
797
+//     right: Vec.rotWith(inset, point, -Math.PI / 6 + (Math.PI / 12) * getRandom()),
798
+//   }
799
+// }
857 800
 
858
-  const arrowHeadLength = Math.min(arrowDist / 3, strokeWidth * 8)
801
+// function getDrawArrowPath(shape: ArrowShape) {
802
+//   const {
803
+//     decorations,
804
+//     handles: { start, end, bend: _bend },
805
+//     style,
806
+//   } = shape
859 807
 
860
-  const path: (string | number)[] = []
808
+//   const { strokeWidth } = getShapeStyle(style, false)
861 809
 
862
-  const isStraightLine = Vec.dist(_bend.point, Vec.round(Vec.med(start.point, end.point))) < 1
810
+//   const arrowDist = Vec.dist(start.point, end.point)
863 811
 
864
-  if (isStraightLine) {
865
-    // Path (line segment)
866
-    path.push(`M ${start.point} L ${end.point}`)
812
+//   const arrowHeadLength = Math.min(arrowDist / 3, strokeWidth * 8)
867 813
 
868
-    // Start arrow head
869
-    if (decorations?.start) {
870
-      path.push(getStraightArrowHeadPath(start.point, end.point, arrowHeadLength))
871
-    }
814
+//   const path: (string | number)[] = []
872 815
 
873
-    // End arrow head
874
-    if (decorations?.end) {
875
-      path.push(getStraightArrowHeadPath(end.point, start.point, arrowHeadLength))
876
-    }
877
-  } else {
878
-    const { center, radius, length } = getArrowArc(shape)
816
+//   const isStraightLine = Vec.dist(_bend.point, Vec.round(Vec.med(start.point, end.point))) < 1
879 817
 
880
-    // Path (arc)
881
-    path.push(`M ${start.point} A ${radius} ${radius} 0 0 ${length > 0 ? '1' : '0'} ${end.point}`)
818
+//   if (isStraightLine) {
819
+//     // Path (line segment)
820
+//     path.push(`M ${start.point} L ${end.point}`)
882 821
 
883
-    // Start Arrow head
884
-    if (decorations?.start) {
885
-      path.push(getCurvedArrowHeadPath(start.point, arrowHeadLength, center, radius, length < 0))
886
-    }
822
+//     // Start arrow head
823
+//     if (decorations?.start) {
824
+//       path.push(getStraightArrowHeadPath(start.point, end.point, arrowHeadLength))
825
+//     }
887 826
 
888
-    // End arrow head
889
-    if (decorations?.end) {
890
-      path.push(getCurvedArrowHeadPath(end.point, arrowHeadLength, center, radius, length >= 0))
891
-    }
892
-  }
827
+//     // End arrow head
828
+//     if (decorations?.end) {
829
+//       path.push(getStraightArrowHeadPath(end.point, start.point, arrowHeadLength))
830
+//     }
831
+//   } else {
832
+//     const { center, radius, length } = getArrowArc(shape)
893 833
 
894
-  return path.join(' ')
895
-}
834
+//     // Path (arc)
835
+//     path.push(`M ${start.point} A ${radius} ${radius} 0 0 ${length > 0 ? '1' : '0'} ${end.point}`)
836
+
837
+//     // Start Arrow head
838
+//     if (decorations?.start) {
839
+//       path.push(getCurvedArrowHeadPath(start.point, arrowHeadLength, center, radius, length < 0))
840
+//     }
841
+
842
+//     // End arrow head
843
+//     if (decorations?.end) {
844
+//       path.push(getCurvedArrowHeadPath(end.point, arrowHeadLength, center, radius, length >= 0))
845
+//     }
846
+//   }
847
+
848
+//   return path.join(' ')
849
+// }

+ 11
- 4
packages/tldraw/src/shape/shapes/draw/draw.tsx Parādīt failu

@@ -1,8 +1,15 @@
1 1
 import * as React from 'react'
2
-import { TLBounds, Utils, Vec, TLTransformInfo, TLRenderInfo, Intersect } from '@tldraw/core'
2
+import { TLBounds, Utils, Vec, TLTransformInfo, Intersect } from '@tldraw/core'
3 3
 import getStroke, { getStrokePoints } from 'perfect-freehand'
4 4
 import { defaultStyle, getShapeStyle } from '~shape/shape-styles'
5
-import { DrawShape, DashStyle, TLDrawShapeUtil, TLDrawShapeType, TLDrawToolType } from '~types'
5
+import {
6
+  DrawShape,
7
+  DashStyle,
8
+  TLDrawShapeUtil,
9
+  TLDrawShapeType,
10
+  TLDrawToolType,
11
+  TLDrawRenderInfo,
12
+} from '~types'
6 13
 
7 14
 export class Draw extends TLDrawShapeUtil<DrawShape> {
8 15
   type = TLDrawShapeType.Draw as const
@@ -30,10 +37,10 @@ export class Draw extends TLDrawShapeUtil<DrawShape> {
30 37
     return next.points !== prev.points || next.style !== prev.style
31 38
   }
32 39
 
33
-  render(shape: DrawShape, { isDarkMode, isEditing }: TLRenderInfo): JSX.Element {
40
+  render(shape: DrawShape, { meta, isEditing }: TLDrawRenderInfo): JSX.Element {
34 41
     const { points, style } = shape
35 42
 
36
-    const styles = getShapeStyle(style, isDarkMode)
43
+    const styles = getShapeStyle(style, meta.isDarkMode)
37 44
 
38 45
     const strokeWidth = styles.strokeWidth
39 46
 

+ 11
- 4
packages/tldraw/src/shape/shapes/ellipse/ellipse.tsx Parādīt failu

@@ -1,6 +1,13 @@
1 1
 import * as React from 'react'
2
-import { Utils, TLTransformInfo, TLBounds, Intersect, Vec, TLRenderInfo } from '@tldraw/core'
3
-import { DashStyle, EllipseShape, TLDrawShapeType, TLDrawShapeUtil, TLDrawToolType } from '~types'
2
+import { Utils, TLTransformInfo, TLBounds, Intersect, Vec } from '@tldraw/core'
3
+import {
4
+  DashStyle,
5
+  EllipseShape,
6
+  TLDrawRenderInfo,
7
+  TLDrawShapeType,
8
+  TLDrawShapeUtil,
9
+  TLDrawToolType,
10
+} from '~types'
4 11
 import { defaultStyle, getPerfectDashProps, getShapeStyle } from '~shape/shape-styles'
5 12
 import getStroke from 'perfect-freehand'
6 13
 
@@ -26,13 +33,13 @@ export class Ellipse extends TLDrawShapeUtil<EllipseShape> {
26 33
     return next.radius !== prev.radius || next.style !== prev.style
27 34
   }
28 35
 
29
-  render(shape: EllipseShape, { isDarkMode, isBinding }: TLRenderInfo) {
36
+  render(shape: EllipseShape, { meta, isBinding }: TLDrawRenderInfo) {
30 37
     const {
31 38
       radius: [radiusX, radiusY],
32 39
       style,
33 40
     } = shape
34 41
 
35
-    const styles = getShapeStyle(style, isDarkMode)
42
+    const styles = getShapeStyle(style, meta.isDarkMode)
36 43
     const strokeWidth = +styles.strokeWidth
37 44
 
38 45
     const rx = Math.max(0, radiusX - strokeWidth / 2)

+ 11
- 4
packages/tldraw/src/shape/shapes/rectangle/rectangle.tsx Parādīt failu

@@ -1,8 +1,15 @@
1 1
 import * as React from 'react'
2
-import { TLBounds, Utils, Vec, TLTransformInfo, TLRenderInfo, Intersect } from '@tldraw/core'
2
+import { TLBounds, Utils, Vec, TLTransformInfo, Intersect } from '@tldraw/core'
3 3
 import getStroke from 'perfect-freehand'
4 4
 import { getPerfectDashProps, defaultStyle, getShapeStyle } from '~shape/shape-styles'
5
-import { RectangleShape, DashStyle, TLDrawShapeUtil, TLDrawShapeType, TLDrawToolType } from '~types'
5
+import {
6
+  RectangleShape,
7
+  DashStyle,
8
+  TLDrawShapeUtil,
9
+  TLDrawShapeType,
10
+  TLDrawToolType,
11
+  TLDrawRenderInfo,
12
+} from '~types'
6 13
 
7 14
 export class Rectangle extends TLDrawShapeUtil<RectangleShape> {
8 15
   type = TLDrawShapeType.Rectangle as const
@@ -27,9 +34,9 @@ export class Rectangle extends TLDrawShapeUtil<RectangleShape> {
27 34
     return next.size !== prev.size || next.style !== prev.style
28 35
   }
29 36
 
30
-  render(shape: RectangleShape, { isBinding, isDarkMode }: TLRenderInfo) {
37
+  render(shape: RectangleShape, { isBinding, meta }: TLDrawRenderInfo) {
31 38
     const { id, size, style } = shape
32
-    const styles = getShapeStyle(style, isDarkMode)
39
+    const styles = getShapeStyle(style, meta.isDarkMode)
33 40
     const strokeWidth = +styles.strokeWidth
34 41
 
35 42
     if (style.dash === DashStyle.Draw) {

+ 11
- 5
packages/tldraw/src/shape/shapes/text/text.tsx Parādīt failu

@@ -1,7 +1,13 @@
1 1
 import * as React from 'react'
2
-import { TLBounds, Utils, Vec, TLTransformInfo, TLRenderInfo, Intersect } from '@tldraw/core'
2
+import { TLBounds, Utils, Vec, TLTransformInfo, Intersect } from '@tldraw/core'
3 3
 import { getShapeStyle, getFontSize, getFontStyle, defaultStyle } from '~shape/shape-styles'
4
-import { TextShape, TLDrawShapeUtil, TLDrawShapeType, TLDrawToolType } from '~types'
4
+import {
5
+  TextShape,
6
+  TLDrawShapeUtil,
7
+  TLDrawShapeType,
8
+  TLDrawRenderInfo,
9
+  TLDrawToolType,
10
+} from '~types'
5 11
 import styled from '~styles'
6 12
 import TextAreaUtils from './text-utils'
7 13
 
@@ -77,17 +83,17 @@ export class Text extends TLDrawShapeUtil<TextShape> {
77 83
     shape: TextShape,
78 84
     {
79 85
       ref,
86
+      meta,
80 87
       isEditing,
81
-      isDarkMode,
82 88
       onTextBlur,
83 89
       onTextChange,
84 90
       onTextFocus,
85 91
       onTextKeyDown,
86 92
       onTextKeyUp,
87
-    }: TLRenderInfo
93
+    }: TLDrawRenderInfo
88 94
   ): JSX.Element {
89 95
     const { id, text, style } = shape
90
-    const styles = getShapeStyle(style, isDarkMode)
96
+    const styles = getShapeStyle(style, meta.isDarkMode)
91 97
     const font = getFontStyle(shape.style)
92 98
 
93 99
     const bounds = this.getBounds(shape)

+ 3
- 3
packages/tldraw/src/state/command/align/align.command.ts Parādīt failu

@@ -1,9 +1,9 @@
1 1
 import { Utils } from '@tldraw/core'
2
-import { AlignType } from '~types'
3
-import type { Data, Command } from '~types'
2
+import { AlignType, TLDrawCommand } from '~types'
3
+import type { Data } from '~types'
4 4
 import { TLDR } from '~state/tldr'
5 5
 
6
-export function align(data: Data, ids: string[], type: AlignType): Command {
6
+export function align(data: Data, ids: string[], type: AlignType): TLDrawCommand {
7 7
   const { currentPageId } = data.appState
8 8
   const initialShapes = ids.map((id) => TLDR.getShape(data, id, currentPageId))
9 9
 

+ 2
- 3
packages/tldraw/src/state/command/change-page/change-page.command.ts Parādīt failu

@@ -1,7 +1,6 @@
1
-import type { TLDrawShape, Data, Command } from '~types'
2
-import { TLDR } from '~state/tldr'
1
+import type { Data, TLDrawCommand } from '~types'
3 2
 
4
-export function changePage(data: Data, pageId: string): Command {
3
+export function changePage(data: Data, pageId: string): TLDrawCommand {
5 4
   return {
6 5
     id: 'change_page',
7 6
     before: {

+ 2
- 2
packages/tldraw/src/state/command/create-page/create-page.command.ts Parādīt failu

@@ -1,7 +1,7 @@
1
-import type { Data, Command } from '~types'
1
+import type { Data, TLDrawCommand } from '~types'
2 2
 import { Utils } from '@tldraw/core'
3 3
 
4
-export function createPage(data: Data): Command {
4
+export function createPage(data: Data): TLDrawCommand {
5 5
   const newId = Utils.uniqueId()
6 6
   const { currentPageId } = data.appState
7 7
 

+ 5
- 5
packages/tldraw/src/state/command/create/create.command.ts Parādīt failu

@@ -1,11 +1,11 @@
1
-import type { DeepPartial } from '~../../core/dist/types/utils/utils'
1
+import type { Patch } from 'rko'
2 2
 import { TLDR } from '~state/tldr'
3
-import type { TLDrawShape, Data, Command } from '~types'
3
+import type { TLDrawShape, Data, TLDrawCommand } from '~types'
4 4
 
5
-export function create(data: Data, shapes: TLDrawShape[]): Command {
5
+export function create(data: Data, shapes: TLDrawShape[]): TLDrawCommand {
6 6
   const { currentPageId } = data.appState
7
-  const beforeShapes: Record<string, DeepPartial<TLDrawShape> | undefined> = {}
8
-  const afterShapes: Record<string, DeepPartial<TLDrawShape> | undefined> = {}
7
+  const beforeShapes: Record<string, Patch<TLDrawShape> | undefined> = {}
8
+  const afterShapes: Record<string, Patch<TLDrawShape> | undefined> = {}
9 9
 
10 10
   shapes.forEach((shape) => {
11 11
     beforeShapes[shape.id] = undefined

+ 2
- 2
packages/tldraw/src/state/command/delete-page/delete-page.command.ts Parādīt failu

@@ -1,6 +1,6 @@
1
-import type { Data, Command } from '~types'
1
+import type { Data, TLDrawCommand } from '~types'
2 2
 
3
-export function deletePage(data: Data, pageId: string): Command {
3
+export function deletePage(data: Data, pageId: string): TLDrawCommand {
4 4
   const { currentPageId } = data.appState
5 5
 
6 6
   const pagesArr = Object.values(data.document.pages).sort(

+ 2
- 2
packages/tldraw/src/state/command/delete/delete.command.ts Parādīt failu

@@ -1,11 +1,11 @@
1 1
 import { TLDR } from '~state/tldr'
2
-import type { Data, Command, PagePartial } from '~types'
2
+import type { Data, TLDrawCommand, PagePartial } from '~types'
3 3
 
4 4
 // - [x] Delete shapes
5 5
 // - [x] Delete bindings too
6 6
 // - [ ] Update parents and possibly delete parents
7 7
 
8
-export function deleteShapes(data: Data, ids: string[]): Command {
8
+export function deleteShapes(data: Data, ids: string[]): TLDrawCommand {
9 9
   const { currentPageId } = data.appState
10 10
 
11 11
   const before: PagePartial = {

+ 2
- 2
packages/tldraw/src/state/command/distribute/distribute.command.ts Parādīt failu

@@ -1,8 +1,8 @@
1 1
 import { Utils } from '@tldraw/core'
2
-import { DistributeType, TLDrawShape, Data, Command } from '~types'
2
+import { DistributeType, TLDrawShape, Data, TLDrawCommand } from '~types'
3 3
 import { TLDR } from '~state/tldr'
4 4
 
5
-export function distribute(data: Data, ids: string[], type: DistributeType): Command {
5
+export function distribute(data: Data, ids: string[], type: DistributeType): TLDrawCommand {
6 6
   const { currentPageId } = data.appState
7 7
   const initialShapes = ids.map((id) => TLDR.getShape(data, id, currentPageId))
8 8
   const deltaMap = Object.fromEntries(getDistributions(initialShapes, type).map((d) => [d.id, d]))

+ 2
- 2
packages/tldraw/src/state/command/duplicate-page/duplicate-page.command.ts Parādīt failu

@@ -1,7 +1,7 @@
1
-import type { Data, Command } from '~types'
1
+import type { Data, TLDrawCommand } from '~types'
2 2
 import { Utils } from '@tldraw/core'
3 3
 
4
-export function duplicatePage(data: Data, pageId: string): Command {
4
+export function duplicatePage(data: Data, pageId: string): TLDrawCommand {
5 5
   const newId = Utils.uniqueId()
6 6
   const { currentPageId } = data.appState
7 7
 

+ 2
- 2
packages/tldraw/src/state/command/duplicate/duplicate.command.ts Parādīt failu

@@ -1,8 +1,8 @@
1 1
 import { Utils, Vec } from '@tldraw/core'
2 2
 import { TLDR } from '~state/tldr'
3
-import type { Data, Command } from '~types'
3
+import type { Data, TLDrawCommand } from '~types'
4 4
 
5
-export function duplicate(data: Data, ids: string[]): Command {
5
+export function duplicate(data: Data, ids: string[]): TLDrawCommand {
6 6
   const { currentPageId } = data.appState
7 7
   const delta = Vec.div([16, 16], TLDR.getCamera(data, currentPageId).zoom)
8 8
 

+ 2
- 2
packages/tldraw/src/state/command/flip/flip.command.ts Parādīt failu

@@ -1,9 +1,9 @@
1 1
 import { FlipType } from '~types'
2 2
 import { TLBoundsCorner, Utils } from '@tldraw/core'
3
-import type { Data, Command } from '~types'
3
+import type { Data, TLDrawCommand } from '~types'
4 4
 import { TLDR } from '~state/tldr'
5 5
 
6
-export function flip(data: Data, ids: string[], type: FlipType): Command {
6
+export function flip(data: Data, ids: string[], type: FlipType): TLDrawCommand {
7 7
   const { currentPageId } = data.appState
8 8
   const initialShapes = ids.map((id) => TLDR.getShape(data, id, currentPageId))
9 9
 

+ 2
- 2
packages/tldraw/src/state/command/move/move.command.ts Parādīt failu

@@ -1,7 +1,7 @@
1
-import { MoveType, Data, TLDrawShape, Command } from '~types'
1
+import { MoveType, Data, TLDrawShape, TLDrawCommand } from '~types'
2 2
 import { TLDR } from '~state/tldr'
3 3
 
4
-export function move(data: Data, ids: string[], type: MoveType): Command {
4
+export function move(data: Data, ids: string[], type: MoveType): TLDrawCommand {
5 5
   const { currentPageId } = data.appState
6 6
 
7 7
   // Get the unique parent ids for the selected elements

+ 2
- 2
packages/tldraw/src/state/command/rename-page/rename-page.command.ts Parādīt failu

@@ -1,6 +1,6 @@
1
-import type { Data, Command } from '~types'
1
+import type { Data, TLDrawCommand } from '~types'
2 2
 
3
-export function renamePage(data: Data, pageId: string, name: string): Command {
3
+export function renamePage(data: Data, pageId: string, name: string): TLDrawCommand {
4 4
   const page = data.document.pages[pageId]
5 5
   return {
6 6
     id: 'rename_page',

+ 2
- 2
packages/tldraw/src/state/command/rotate/rotate.command.ts Parādīt failu

@@ -1,10 +1,10 @@
1 1
 import { Utils, Vec } from '@tldraw/core'
2
-import type { Command, Data } from '~types'
2
+import type { TLDrawCommand, Data } from '~types'
3 3
 import { TLDR } from '~state/tldr'
4 4
 
5 5
 const PI2 = Math.PI * 2
6 6
 
7
-export function rotate(data: Data, ids: string[], delta = -PI2 / 4): Command {
7
+export function rotate(data: Data, ids: string[], delta = -PI2 / 4): TLDrawCommand {
8 8
   const { currentPageId } = data.appState
9 9
   const initialShapes = ids.map((id) => TLDR.getShape(data, id, currentPageId))
10 10
 

+ 2
- 2
packages/tldraw/src/state/command/stretch/stretch.command.ts Parādīt failu

@@ -1,9 +1,9 @@
1 1
 import { TLBoundsCorner, Utils } from '@tldraw/core'
2 2
 import { StretchType } from '~types'
3
-import type { Data, Command } from '~types'
3
+import type { Data, TLDrawCommand } from '~types'
4 4
 import { TLDR } from '~state/tldr'
5 5
 
6
-export function stretch(data: Data, ids: string[], type: StretchType): Command {
6
+export function stretch(data: Data, ids: string[], type: StretchType): TLDrawCommand {
7 7
   const { currentPageId } = data.appState
8 8
 
9 9
   const initialShapes = ids.map((id) => TLDR.getShape(data, id, currentPageId))

+ 2
- 2
packages/tldraw/src/state/command/style/style.command.ts Parādīt failu

@@ -1,7 +1,7 @@
1
-import type { ShapeStyles, Command, Data } from '~types'
1
+import type { ShapeStyles, TLDrawCommand, Data } from '~types'
2 2
 import { TLDR } from '~state/tldr'
3 3
 
4
-export function style(data: Data, ids: string[], changes: Partial<ShapeStyles>): Command {
4
+export function style(data: Data, ids: string[], changes: Partial<ShapeStyles>): TLDrawCommand {
5 5
   const { currentPageId } = data.appState
6 6
 
7 7
   const { before, after } = TLDR.mutateShapes(

+ 6
- 2
packages/tldraw/src/state/command/toggle-decoration/toggle-decoration.command.ts Parādīt failu

@@ -1,8 +1,12 @@
1 1
 import { Decoration } from '~types'
2
-import type { ArrowShape, Command, Data } from '~types'
2
+import type { ArrowShape, TLDrawCommand, Data } from '~types'
3 3
 import { TLDR } from '~state/tldr'
4 4
 
5
-export function toggleDecoration(data: Data, ids: string[], handleId: 'start' | 'end'): Command {
5
+export function toggleDecoration(
6
+  data: Data,
7
+  ids: string[],
8
+  handleId: 'start' | 'end'
9
+): TLDrawCommand {
6 10
   const { currentPageId } = data.appState
7 11
   const { before, after } = TLDR.mutateShapes<ArrowShape>(
8 12
     data,

+ 2
- 2
packages/tldraw/src/state/command/toggle/toggle.command.ts Parādīt failu

@@ -1,7 +1,7 @@
1
-import type { TLDrawShape, Data, Command } from '~types'
1
+import type { TLDrawShape, Data, TLDrawCommand } from '~types'
2 2
 import { TLDR } from '~state/tldr'
3 3
 
4
-export function toggle(data: Data, ids: string[], prop: keyof TLDrawShape): Command {
4
+export function toggle(data: Data, ids: string[], prop: keyof TLDrawShape): TLDrawCommand {
5 5
   const { currentPageId } = data.appState
6 6
   const initialShapes = ids.map((id) => TLDR.getShape(data, id, currentPageId))
7 7
   const isAllToggled = initialShapes.every((shape) => shape[prop])

+ 2
- 2
packages/tldraw/src/state/command/translate/translate.command.ts Parādīt failu

@@ -1,8 +1,8 @@
1 1
 import { Vec } from '@tldraw/core'
2
-import type { Data, Command, PagePartial } from '~types'
2
+import type { Data, TLDrawCommand, PagePartial } from '~types'
3 3
 import { TLDR } from '~state/tldr'
4 4
 
5
-export function translate(data: Data, ids: string[], delta: number[]): Command {
5
+export function translate(data: Data, ids: string[], delta: number[]): TLDrawCommand {
6 6
   const before: PagePartial = {
7 7
     shapes: {},
8 8
     bindings: {},

+ 2
- 3
packages/tldraw/src/state/session/sessions/brush/brush.session.ts Parādīt failu

@@ -1,8 +1,7 @@
1 1
 import { brushUpdater, Utils, Vec } from '@tldraw/core'
2
-import { Data, Session, TLDrawStatus } from '~types'
2
+import { Data, Session, TLDrawPatch, TLDrawStatus } from '~types'
3 3
 import { getShapeUtils } from '~shape'
4 4
 import { TLDR } from '~state/tldr'
5
-import type { DeepPartial } from '~../../core/dist/types/utils/utils'
6 5
 
7 6
 export class BrushSession implements Session {
8 7
   id = 'brush'
@@ -17,7 +16,7 @@ export class BrushSession implements Session {
17 16
 
18 17
   start = () => void null
19 18
 
20
-  update = (data: Data, point: number[], containMode = false): DeepPartial<Data> => {
19
+  update = (data: Data, point: number[], containMode = false): TLDrawPatch => {
21 20
     const { snapshot, origin } = this
22 21
     const { currentPageId } = data.appState
23 22
 

+ 2
- 2
packages/tldraw/src/state/session/sessions/translate/translate.session.ts Parādīt failu

@@ -1,5 +1,5 @@
1 1
 import { TLPageState, Utils, Vec } from '@tldraw/core'
2
-import { TLDrawShape, TLDrawBinding, Session, Data, Command, TLDrawStatus } from '~types'
2
+import { TLDrawShape, TLDrawBinding, Session, Data, TLDrawCommand, TLDrawStatus } from '~types'
3 3
 import { TLDR } from '~state/tldr'
4 4
 
5 5
 export class TranslateSession implements Session {
@@ -184,7 +184,7 @@ export class TranslateSession implements Session {
184 184
     }
185 185
   }
186 186
 
187
-  complete(data: Data): Command {
187
+  complete(data: Data): TLDrawCommand {
188 188
     const pageId = data.appState.currentPageId
189 189
 
190 190
     const { initialShapes, bindingsToDelete, clones, clonedBindings } = this.snapshot

+ 8
- 11
packages/tldraw/src/state/tldr.ts Parādīt failu

@@ -2,13 +2,14 @@ import { TLBounds, TLTransformInfo, Vec, Utils, TLPageState } from '@tldraw/core
2 2
 import { getShapeUtils } from '~shape'
3 3
 import type {
4 4
   Data,
5
-  DeepPartial,
6 5
   ShapeStyles,
7 6
   ShapesWithProp,
8 7
   TLDrawShape,
9 8
   TLDrawShapeUtil,
10 9
   TLDrawBinding,
11 10
   TLDrawPage,
11
+  TLDrawCommand,
12
+  TLDrawPatch,
12 13
 } from '~types'
13 14
 
14 15
 export class TLDR {
@@ -445,12 +446,8 @@ export class TLDR {
445 446
     }
446 447
   }
447 448
 
448
-  static createShapes(
449
-    data: Data,
450
-    shapes: TLDrawShape[],
451
-    pageId: string
452
-  ): { before: DeepPartial<Data>; after: DeepPartial<Data> } {
453
-    const before: DeepPartial<Data> = {
449
+  static createShapes(data: Data, shapes: TLDrawShape[], pageId: string): TLDrawCommand {
450
+    const before: TLDrawPatch = {
454 451
       document: {
455 452
         pages: {
456 453
           [pageId]: {
@@ -477,7 +474,7 @@ export class TLDR {
477 474
       },
478 475
     }
479 476
 
480
-    const after: DeepPartial<Data> = {
477
+    const after: TLDrawPatch = {
481 478
       document: {
482 479
         pages: {
483 480
           [pageId]: {
@@ -516,7 +513,7 @@ export class TLDR {
516 513
     data: Data,
517 514
     shapes: TLDrawShape[] | string[],
518 515
     pageId?: string
519
-  ): { before: DeepPartial<Data>; after: DeepPartial<Data> } {
516
+  ): TLDrawCommand {
520 517
     pageId = pageId ? pageId : data.appState.currentPageId
521 518
 
522 519
     const page = this.getPage(data, pageId)
@@ -526,7 +523,7 @@ export class TLDR {
526 523
         ? (shapes as string[])
527 524
         : (shapes as TLDrawShape[]).map((shape) => shape.id)
528 525
 
529
-    const before: DeepPartial<Data> = {
526
+    const before: TLDrawPatch = {
530 527
       document: {
531 528
         pages: {
532 529
           [pageId]: {
@@ -565,7 +562,7 @@ export class TLDR {
565 562
       },
566 563
     }
567 564
 
568
-    const after: DeepPartial<Data> = {
565
+    const after: TLDrawPatch = {
569 566
       document: {
570 567
         pages: {
571 568
           [pageId]: {

+ 19
- 26
packages/tldraw/src/types.ts Parādīt failu

@@ -1,9 +1,10 @@
1 1
 /* eslint-disable @typescript-eslint/no-explicit-any */
2 2
 /* eslint-disable @typescript-eslint/ban-types */
3
-import type { TLBinding } from '@tldraw/core'
3
+import type { TLBinding, TLRenderInfo } from '@tldraw/core'
4 4
 import { TLShape, TLShapeUtil, TLHandle } from '@tldraw/core'
5
-import type { TLPage, TLPageState, TLSettings } from '@tldraw/core'
5
+import type { TLPage, TLPageState } from '@tldraw/core'
6 6
 import type { StoreApi } from 'zustand'
7
+import type { Command, Patch } from 'rko'
7 8
 
8 9
 export type TLStore = StoreApi<Data>
9 10
 
@@ -17,12 +18,21 @@ export interface TLDrawDocument {
17 18
   pageStates: Record<string, TLPageState>
18 19
 }
19 20
 
20
-export interface TLDrawSettings extends TLSettings {
21
+export interface TLDrawSettings {
22
+  isDarkMode: boolean
23
+  isDebugMode: boolean
24
+  isPenMode: boolean
21 25
   isReadonlyMode: boolean
22 26
   nudgeDistanceSmall: number
23 27
   nudgeDistanceLarge: number
24 28
 }
25 29
 
30
+export interface TLDrawMeta {
31
+  isDarkMode: boolean
32
+}
33
+
34
+export type TLDrawRenderInfo = TLRenderInfo<TLDrawMeta>
35
+
26 36
 export interface Data {
27 37
   document: TLDrawDocument
28 38
   settings: TLDrawSettings
@@ -41,30 +51,13 @@ export interface Data {
41 51
   }
42 52
 }
43 53
 
44
-export type TLDrawPatch = DeepPartial<Data>
45
-
46
-export type PagePartial = {
47
-  shapes: DeepPartial<TLDrawPage['shapes']>
48
-  bindings: DeepPartial<TLDrawPage['bindings']>
49
-}
54
+export type TLDrawPatch = Patch<Data>
50 55
 
51
-export type DeepPartial<T> = T extends Function
52
-  ? T
53
-  : T extends object
54
-  ? T extends unknown[]
55
-    ? DeepPartial<T[number]>[]
56
-    : { [P in keyof T]?: DeepPartial<T[P]> }
57
-  : T
56
+export type TLDrawCommand = Command<Data>
58 57
 
59
-export interface Command {
60
-  id: string
61
-  before: TLDrawPatch
62
-  after: TLDrawPatch
63
-}
64
-
65
-export interface History {
66
-  pointer: number
67
-  stack: Command[]
58
+export type PagePartial = {
59
+  shapes: Patch<TLDrawPage['shapes']>
60
+  bindings: Patch<TLDrawPage['bindings']>
68 61
 }
69 62
 
70 63
 export interface SelectHistory {
@@ -77,7 +70,7 @@ export interface Session {
77 70
   status: TLDrawStatus
78 71
   start: (data: Readonly<Data>, ...args: any[]) => TLDrawPatch | undefined
79 72
   update: (data: Readonly<Data>, ...args: any[]) => TLDrawPatch | undefined
80
-  complete: (data: Readonly<Data>, ...args: any[]) => TLDrawPatch | Command | undefined
73
+  complete: (data: Readonly<Data>, ...args: any[]) => TLDrawPatch | TLDrawCommand | undefined
81 74
   cancel: (data: Readonly<Data>, ...args: any[]) => TLDrawPatch | undefined
82 75
 }
83 76
 

+ 1
- 0
tsconfig.base.json Parādīt failu

@@ -6,6 +6,7 @@
6 6
     "experimentalDecorators": true,
7 7
     "forceConsistentCasingInFileNames": true,
8 8
     "importsNotUsedAsValues": "error",
9
+    "stripInternal": true,
9 10
     "incremental": true,
10 11
     "importHelpers": true,
11 12
     "moduleResolution": "node",

+ 1
- 1
tsconfig.tsbuildinfo
Failā izmaiņas netiks attēlotas, jo tās ir par lielu
Parādīt failu


Notiek ielāde…
Atcelt
Saglabāt