Przeglądaj źródła

[improvement] Migrations (#217)

* Add better migrations

* Improves migrations

* rename dev to example

* renames migrate

* Removes workers from git

* Remove rogue dependency

* Fix dropdown navigation by keyboard
main
Steve Ruiz 3 lat temu
rodzic
commit
fe2e3c81fe
No account linked to committer's email address
53 zmienionych plików z 518 dodań i 273 usunięć
  1. 4
    0
      .gitignore
  2. 149
    46
      README.md
  3. 0
    6
      dev/README.md
  4. 0
    0
      example/.env.local
  5. 0
    0
      example/LICENSE
  6. 6
    0
      example/README.md
  7. 0
    0
      example/esbuild.config.mjs
  8. 12
    11
      example/package.json
  9. 0
    0
      example/src/app.tsx
  10. 0
    0
      example/src/assets/local.tldr
  11. 0
    0
      example/src/basic.tsx
  12. 0
    0
      example/src/changing-id.tsx
  13. 0
    0
      example/src/components/editor.tsx
  14. 0
    0
      example/src/controlled.tsx
  15. 0
    0
      example/src/embedded.tsx
  16. 0
    0
      example/src/imperative.tsx
  17. 0
    0
      example/src/index.html
  18. 0
    0
      example/src/index.tsx
  19. 0
    0
      example/src/multiplayer/cursors.tsx
  20. 0
    0
      example/src/multiplayer/index.ts
  21. 1
    17
      example/src/multiplayer/multiplayer.tsx
  22. 0
    0
      example/src/no-size-embedded.tsx
  23. 0
    0
      example/src/styles.css
  24. 0
    0
      example/tsconfig.json
  25. 0
    0
      example/tsconfig.tsbuildinfo
  26. 2
    5
      package.json
  27. 149
    46
      packages/tldraw/README.md
  28. 1
    1
      packages/tldraw/package.json
  29. 3
    1
      packages/tldraw/src/components/ToolButton/ToolButton.tsx
  30. 15
    14
      packages/tldraw/src/components/TopPanel/ColorMenu.tsx
  31. 12
    9
      packages/tldraw/src/components/TopPanel/DashMenu.tsx
  32. 2
    0
      packages/tldraw/src/components/TopPanel/PageOptionsDialog.tsx
  33. 13
    9
      packages/tldraw/src/components/TopPanel/SizeMenu.tsx
  34. 4
    4
      packages/tldraw/src/shape-utils/arrow/__snapshots__/arrow.spec.tsx.snap
  35. 3
    3
      packages/tldraw/src/shape-utils/draw/__snapshots__/draw.spec.tsx.snap
  36. 3
    3
      packages/tldraw/src/shape-utils/ellipse/__snapshots__/ellipse.spec.tsx.snap
  37. 3
    3
      packages/tldraw/src/shape-utils/group/__snapshots__/group.spec.tsx.snap
  38. 3
    3
      packages/tldraw/src/shape-utils/rectangle/__snapshots__/rectangle.spec.tsx.snap
  39. 3
    3
      packages/tldraw/src/shape-utils/text/__snapshots__/text.spec.tsx.snap
  40. 6
    6
      packages/tldraw/src/state/__snapshots__/tlstate.spec.ts.snap
  41. 53
    0
      packages/tldraw/src/state/migrate.ts
  42. 10
    15
      packages/tldraw/src/state/tlstate.ts
  43. 0
    2
      packages/tldraw/src/state/tool/BaseTool/BaseTool.ts
  44. 0
    2
      packages/tldraw/src/state/tool/TextTool/TextTool.ts
  45. 8
    8
      packages/tldraw/src/test/migration.spec.ts
  46. 1
    0
      packages/tldraw/src/test/mock-document.tsx
  47. 25
    31
      packages/tldraw/src/types.ts
  48. 11
    0
      www/.babelrc
  49. 6
    18
      www/components/multiplayer-editor.tsx
  50. 2
    0
      www/public/workbox-a6b3f14f.js
  51. 1
    0
      www/public/workbox-a6b3f14f.js.map
  52. 1
    1
      www/tsconfig.json
  53. 6
    6
      yarn.lock

+ 4
- 0
.gitignore Wyświetl plik

8
 .DS_Store
8
 .DS_Store
9
 coverage
9
 coverage
10
 *.log
10
 *.log
11
+
12
+www/public/worker-*
13
+www/public/sw.js
14
+www/public/sw.js.map

+ 149
- 46
README.md Wyświetl plik

1
+<div style="text-align: center; transform: scale(.5);">
2
+  <img src="card-repo.png"/>
3
+</div>
4
+
1
 # @tldraw/tldraw
5
 # @tldraw/tldraw
2
 
6
 
3
-> `This library is not yet released and these docs are partially out of date!`
7
+This package contains the [tldraw](https://tldraw.com) editor as a React component named `<TLDraw>`. You can use this package to embed the editor in any React application.
4
 
8
 
5
-This package contains the [tldraw](https://tldraw.com) editor as a standalone React component.
9
+🎨 Want to build your own tldraw-ish app instead? Try [@tldraw/core](https://github.com/tldraw/core).
6
 
10
 
7
-## Installation
11
+💕 Love this library? Consider [becoming a sponsor](https://github.com/sponsors/steveruizok?frequency=recurring&sponsor=steveruizok).
8
 
12
 
9
-```bash
10
-npm i @tldraw/tldraw
11
-```
13
+## Installation
12
 
14
 
13
-or
15
+Use your package manager of choice to install `@tldraw/core` and its peer dependencies.
14
 
16
 
15
 ```bash
17
 ```bash
16
 yarn add @tldraw/tldraw
18
 yarn add @tldraw/tldraw
19
+# or
20
+npm i @tldraw/tldraw
17
 ```
21
 ```
18
 
22
 
19
 ## Usage
23
 ## Usage
28
 }
32
 }
29
 ```
33
 ```
30
 
34
 
35
+You can control the `TLDraw` component through props:
36
+
37
+```tsx
38
+import { TLDraw, TLDrawDocument } from '@tldraw/tldraw'
39
+
40
+function App() {
41
+  const myDocument: TLDrawDocument = {}
42
+
43
+  return <TLDraw document={document} />
44
+}
45
+```
46
+
47
+Or imperatively through the `TLDrawState` instance:
48
+
49
+```tsx
50
+import { TLDraw, TLDrawState } from '@tldraw/tldraw'
51
+
52
+function App() {
53
+  const handleMount = React.useCallback((tlstate: TLDrawState) => {
54
+    const myDocument: TLDrawDocument = {}
55
+
56
+    tlstate.loadDocument(myDocument).selectAll()
57
+  }, [])
58
+
59
+  return <TLDraw onMount={handleMount} />
60
+}
61
+```
62
+
31
 ## Documentation
63
 ## Documentation
32
 
64
 
33
 ### `TLDraw`
65
 ### `TLDraw`
34
 
66
 
35
-The `TLDraw` React component is the [tldraw](https://tldraw.com) editor exported as a standalone component. You can control the editor through props, or through the `TLDrawState`'s imperative API.
36
-
37
-| Prop            | Type                            | Description                                                                                                                                                             |
38
-| --------------- | ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
39
-| `id`            | `string`                        | (optional) An id under which to persist the component's state.                                                                                                          |
40
-| `document`      | `TLDrawDocument`                | (optional) An initial [`TLDrawDocument`](#tldrawdocument) object.                                                                                                       |
41
-| `currentPageId` | `string`                        | (optional) A current page id, referencing the `TLDrawDocument` object provided via the `document` prop.                                                                 |
42
-| `onMount`       | `(TLDrawState) => void`         | (optional) A callback function that will be called when the editor first mounts, receiving the current `TLDrawState`.                                                   |
43
-| `onChange`      | `(TLDrawState, string) => void` | (optional) A callback function that will be called whenever the `TLDrawState` updates. The update will include the current `TLDrawState` and the reason for the change. |
67
+The `TLDraw` React component is the [tldraw](https://tldraw.com) editor exported as a standalone component. You can control the editor through props, or through the `TLDrawState`'s imperative API. **All props are optional.**
68
+
69
+| Prop            | Type             | Description                                                                                                                                                  |
70
+| --------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
71
+| `id`            | `string`         | An id under which to persist the component's state.                                                                                                          |
72
+| `document`      | `TLDrawDocument` | An initial [`TLDrawDocument`](#tldrawdocument) object.                                                                                                       |
73
+| `currentPageId` | `string`         | A current page id, referencing the `TLDrawDocument` object provided via the `document` prop.                                                                 |
74
+| `onMount`       | `Function`       | A callback function that will be called when the editor first mounts, receiving the current `TLDrawState`.                                                   |
75
+| `onChange`      | `Function`       | A callback function that will be called whenever the `TLDrawState` updates. The update will include the current `TLDrawState` and the reason for the change. |
76
+| `onUserChange`  | `Function`       | A callback function that will be fired when the user's "presence" information changes.                                                                       |
77
+| `autofocus`     | `boolean`        | Whether the editor should immediately receive focus. Defaults to true.                                                                                       |
78
+| `showMenu`      | `boolean`        | Whether to show the menu.                                                                                                                                    |
79
+| `showPages`     | `boolean`        | Whether to show the pages menu.                                                                                                                              |
80
+| `showStyles`    | `boolean`        | Whether to show the styles menu.                                                                                                                             |
81
+| `showTools`     | `boolean`        | Whether to show the tools.                                                                                                                                   |
82
+| `showUI`        | `boolean`        | Whether to show any UI other than the canvas.                                                                                                                |
44
 
83
 
45
 ### `TLDrawDocument`
84
 ### `TLDrawDocument`
46
 
85
 
47
 A `TLDrawDocument` is an object with three properties:
86
 A `TLDrawDocument` is an object with three properties:
48
 
87
 
49
 - `id` - A unique ID for this document
88
 - `id` - A unique ID for this document
50
-- `pages` - A table of `TLPage` objects
89
+- `pages` - A table of `TLDrawPage` objects
51
 - `pageStates` - A table of `TLPageState` objects
90
 - `pageStates` - A table of `TLPageState` objects
91
+- `version` - The document's version, used internally for migrations.
52
 
92
 
53
 ```ts
93
 ```ts
94
+import { TLDrawDocument, TLDrawState } from '@tldraw/tldraw'
95
+
54
 const tldocument: TLDrawDocument = {
96
 const tldocument: TLDrawDocument = {
55
   id: 'doc',
97
   id: 'doc',
98
+  version: TLDrawState.version,
56
   pages: {
99
   pages: {
57
     page1: {
100
     page1: {
58
       id: 'page1',
101
       id: 'page1',
74
 }
117
 }
75
 ```
118
 ```
76
 
119
 
77
-**Important:** In the `pages` object, each `TLPage` object must be keyed under its `id` property. Likewise, each `TLPageState` object must be keyed under its `id`. In addition, each `TLPageState` object must have an `id` that matches its corresponding page.
120
+**Tip:** TLDraw is built [@tldraw/core](https://github.com/tldraw/core). The pages and pagestates in TLDraw are just objects containing `TLPage` and `TLPageState` objects from the core library. For more about these types, check out the [@tldraw/core](https://github.com/tldraw/core) documentation.
78
 
121
 
79
-In the example above, the page above with the id `page1`is at `tldocument.pages["page1"]`. Its corresponding page state has the same id (`page1`) and is at `tldocument.pageStates["page1"]`.
122
+**Important:** In the `pages` object, each `TLPage` object must be keyed under its `id` property. Likewise, each `TLPageState` object must be keyed under its `id`. In addition, each `TLPageState` object must have an `id` that matches its corresponding page.
80
 
123
 
81
 ### Shapes
124
 ### Shapes
82
 
125
 
83
 Your `TLPage` objects may include shapes: objects that fit one of the `TLDrawShape` interfaces listed below. All `TLDrawShapes` extends a common interface:
126
 Your `TLPage` objects may include shapes: objects that fit one of the `TLDrawShape` interfaces listed below. All `TLDrawShapes` extends a common interface:
84
 
127
 
85
-| Property              | Type         | Description                                                     |
86
-| --------------------- | ------------ | --------------------------------------------------------------- |
87
-| `id`                  | `string`     | A unique ID for the shape.                                      |
88
-| `name`                | `string`     | The shape's name.                                               |
89
-| `type`                | `string`     | The shape's type.                                               |
90
-| `parentId`            | `string`     | The ID of the shape's parent (a shape or its page).             |
91
-| `childIndex`          | `number`     | The shape's order within its parent's children, indexed from 1. |
92
-| `point`               | `number[]`   | The `[x, y]` position of the shape.                             |
93
-| `rotation`            | `number[]`   | (optional) The shape's rotation in radians.                     |
94
-| `children`            | `string[]`   | (optional) The shape's child shape ids.                         |
95
-| `handles`             | `TLHandle{}` | (optional) A table of `TLHandle` objects.                       |
96
-| `isLocked`            | `boolean`    | True if the shape is locked.                                    |
97
-| `isHidden`            | `boolean`    | True if the shape is hidden.                                    |
98
-| `isEditing`           | `boolean`    | True if the shape is currently editing.                         |
99
-| `isGenerated`         | `boolean`    | True if the shape is generated.                                 |
100
-| `isAspectRatioLocked` | `boolean`    | True if the shape's aspect ratio is locked.                     |
128
+| Property              | Type             | Description                                                     |
129
+| --------------------- | ---------------- | --------------------------------------------------------------- |
130
+| `id`                  | `string`         | A unique ID for the shape.                                      |
131
+| `name`                | `string`         | The shape's name.                                               |
132
+| `type`                | `string`         | The shape's type.                                               |
133
+| `parentId`            | `string`         | The ID of the shape's parent (a shape or its page).             |
134
+| `childIndex`          | `number`         | The shape's order within its parent's children, indexed from 1. |
135
+| `point`               | `number[]`       | The `[x, y]` position of the shape.                             |
136
+| `rotation`            | `number[]`       | (optional) The shape's rotation in radians.                     |
137
+| `children`            | `string[]`       | (optional) The shape's child shape ids.                         |
138
+| `handles`             | `TLDrawHandle{}` | (optional) A table of `TLHandle` objects.                       |
139
+| `isLocked`            | `boolean`        | (optional) True if the shape is locked.                         |
140
+| `isHidden`            | `boolean`        | (optional) True if the shape is hidden.                         |
141
+| `isEditing`           | `boolean`        | (optional) True if the shape is currently editing.              |
142
+| `isGenerated`         | `boolean`        | (optional) True if the shape is generated.                      |
143
+| `isAspectRatioLocked` | `boolean`        | (optional) True if the shape's aspect ratio is locked.          |
101
 
144
 
102
 > **Important:** In order for re-ordering to work correctly, a shape's `childIndex` values _must_ start from 1, not 0. The page or parent shape's "bottom-most" child should have a `childIndex` of 1.
145
 > **Important:** In order for re-ordering to work correctly, a shape's `childIndex` values _must_ start from 1, not 0. The page or parent shape's "bottom-most" child should have a `childIndex` of 1.
103
 
146
 
110
 | `color`    | `ColorStyle` | The shape's color.                      |
153
 | `color`    | `ColorStyle` | The shape's color.                      |
111
 | `isFilled` | `boolean`    | (optional) True if the shape is filled. |
154
 | `isFilled` | `boolean`    | (optional) True if the shape is filled. |
112
 
155
 
113
-#### Draw
156
+#### `DrawShape`
157
+
158
+A hand-drawn line.
114
 
159
 
115
 | Property | Type         | Description                               |
160
 | Property | Type         | Description                               |
116
 | -------- | ------------ | ----------------------------------------- |
161
 | -------- | ------------ | ----------------------------------------- |
117
 | `points` | `number[][]` | An array of points as `[x, y, pressure]`. |
162
 | `points` | `number[][]` | An array of points as `[x, y, pressure]`. |
118
 
163
 
119
-##### Rectangle
164
+##### `RectangleShape`
165
+
166
+A rectangular shape.
120
 
167
 
121
 | Property | Type       | Description                             |
168
 | Property | Type       | Description                             |
122
 | -------- | ---------- | --------------------------------------- |
169
 | -------- | ---------- | --------------------------------------- |
123
 | `size`   | `number[]` | The `[width, height]` of the rectangle. |
170
 | `size`   | `number[]` | The `[width, height]` of the rectangle. |
124
 
171
 
125
-#### Ellipse
172
+#### `EllipseShape`
173
+
174
+An elliptical shape.
126
 
175
 
127
 | Property | Type       | Description                         |
176
 | Property | Type       | Description                         |
128
 | -------- | ---------- | ----------------------------------- |
177
 | -------- | ---------- | ----------------------------------- |
129
 | `radius` | `number[]` | The `[x, y]` radius of the ellipse. |
178
 | `radius` | `number[]` | The `[x, y]` radius of the ellipse. |
130
 
179
 
131
-#### Arrow
180
+#### `ArrowShape`
181
+
182
+An arrow that can connect shapes.
183
+
184
+| Property      | Type     | Description                                                             |
185
+| ------------- | -------- | ----------------------------------------------------------------------- |
186
+| `handles`     | `object` | An object with three `TLHandle` properties: `start`, `end`, and `bend`. |
187
+| `decorations` | `object` | An object with two properties `start`, `end`, and `bend`.               |
188
+
189
+#### `TextShape`
190
+
191
+A line of text.
132
 
192
 
133
-| Property  | Type     | Description                                                             |
134
-| --------- | -------- | ----------------------------------------------------------------------- |
135
-| `handles` | `object` | An object with three `TLHandle` properties: `start`, `end`, and `bend`. |
193
+| Property | Type     | Description               |
194
+| -------- | -------- | ------------------------- |
195
+| `text`   | `string` | The shape's text content. |
196
+
197
+#### `StickyShape`
136
 
198
 
137
-#### Text
199
+A sticky note.
138
 
200
 
139
 | Property | Type     | Description               |
201
 | Property | Type     | Description               |
140
 | -------- | -------- | ------------------------- |
202
 | -------- | -------- | ------------------------- |
141
 | `text`   | `string` | The shape's text content. |
203
 | `text`   | `string` | The shape's text content. |
142
 
204
 
143
-## Development
205
+### Bindings
206
+
207
+A binding is a connection **from** one shape and **to** another shape. At the moment, only arrows may be bound "from". Most shapes may be bound "to", except other `ArrowShape` and `DrawShape`s.
208
+
209
+| Property   | Type             | Description                                              |
210
+| ---------- | ---------------- | -------------------------------------------------------- |
211
+| `id`       | `string`         | The binding's own unique ID.                             |
212
+| `fromId`   | `string`         | The id of the `ArrowShape` that the binding is bound to. |
213
+| `toId`     | `string`         | The id of the other shape that the binding is bound to.  |
214
+| `handleId` | `start` or `end` | The connected arrow handle.                              |
215
+| `distance` | `number`         | The distance from the bound point.                       |
216
+| `point`    | `number[]`       | A normalized point representing the bound point.         |
217
+
218
+## Local Development
219
+
220
+- Run `yarn` to install dependencies.
221
+
222
+- Run `yarn start` to start the development server for the package and for the example.
223
+
224
+- Open `localhost:5000` to view the example project.
225
+
226
+- Run `yarn test` to execute unit tests via [Jest](https://jestjs.io).
227
+
228
+- Run `yarn docs` to build the docs via [ts-doc](https://typedoc.org/).
229
+
230
+## Example
231
+
232
+See the `example` folder.
233
+
234
+## Community
235
+
236
+### Support
237
+
238
+Need help? Please [open an issue](https://github.com/tldraw/tldraw/issues/new) for support.
239
+
240
+### Discussion
241
+
242
+Want to connect with other devs? Visit the [Discord channel](https://discord.gg/s4FXZ6fppJ).
243
+
244
+### License
245
+
246
+This project is licensed under MIT. If you're using the library in a commercial product, please consider [becoming a sponsor](https://github.com/sponsors/steveruizok?frequency=recurring&sponsor=steveruizok).
144
 
247
 
145
-### Running unit tests
248
+## Author
146
 
249
 
147
-Run `nx test tldraw` to execute the unit tests via [Jest](https://jestjs.io).
250
+- [@steveruizok](https://twitter.com/steveruizok)

+ 0
- 6
dev/README.md Wyświetl plik

1
-# @tldraw/dev
2
-
3
-A very fast dev server.
4
-
5
-You probably do not need to start the server here: it is started as
6
-part of `yarn start` in the root directory.

dev/.env.local → example/.env.local Wyświetl plik


dev/LICENSE → example/LICENSE Wyświetl plik


+ 6
- 0
example/README.md Wyświetl plik

1
+# @tldraw/tldraw-example
2
+
3
+An example for @tldraw/tldraw with a very fast dev server.
4
+
5
+**Note:** You probably do not need to start the server here: it is started as
6
+part of `yarn start` in the root directory.

dev/esbuild.config.mjs → example/esbuild.config.mjs Wyświetl plik


dev/package.json → example/package.json Wyświetl plik

1
 {
1
 {
2
-  "name": "@tldraw/dev",
2
+  "name": "@tldraw/tldraw-example",
3
   "version": "0.1.1",
3
   "version": "0.1.1",
4
   "private": true,
4
   "private": true,
5
-  "description": "A tiny little drawing app (dev)",
5
+  "description": "A tiny little drawing app example.",
6
   "author": "@steveruizok",
6
   "author": "@steveruizok",
7
   "license": "MIT",
7
   "license": "MIT",
8
   "keywords": [
8
   "keywords": [
18
     "src"
18
     "src"
19
   ],
19
   ],
20
   "sideEffects": false,
20
   "sideEffects": false,
21
-  "dependencies": {
22
-    "@liveblocks/client": "^0.12.1",
23
-    "@liveblocks/react": "^0.12.1",
24
-    "@tldraw/tldraw": "^0.1.1",
21
+  "dependencies": {},
22
+  "peerDependencies": {
25
     "react": ">=16.8",
23
     "react": ">=16.8",
26
-    "react-dom": "^16.8 || ^17.0",
27
-    "react-router": "^5.2.1",
28
-    "react-router-dom": "^5.3.0"
24
+    "react-dom": "^16.8 || ^17.0"
29
   },
25
   },
30
   "devDependencies": {
26
   "devDependencies": {
31
     "@types/node": "^14.14.35",
27
     "@types/node": "^14.14.35",
36
     "create-serve": "1.0.1",
32
     "create-serve": "1.0.1",
37
     "esbuild": "^0.13.8",
33
     "esbuild": "^0.13.8",
38
     "rimraf": "3.0.2",
34
     "rimraf": "3.0.2",
39
-    "typescript": "4.2.3"
35
+    "typescript": "4.2.3",
36
+    "@liveblocks/client": "^0.12.1",
37
+    "@liveblocks/react": "^0.12.1",
38
+    "@tldraw/tldraw": "^0.1.1",
39
+    "react-router": "^5.2.1",
40
+    "react-router-dom": "^5.3.0"
40
   },
41
   },
41
   "gitHead": "a7dac0f83ad998e205c2aab58182cb4ba4e099a6"
42
   "gitHead": "a7dac0f83ad998e205c2aab58182cb4ba4e099a6"
42
-}
43
+}

dev/src/app.tsx → example/src/app.tsx Wyświetl plik


dev/src/assets/local.tldr → example/src/assets/local.tldr Wyświetl plik


dev/src/basic.tsx → example/src/basic.tsx Wyświetl plik


dev/src/changing-id.tsx → example/src/changing-id.tsx Wyświetl plik


dev/src/components/editor.tsx → example/src/components/editor.tsx Wyświetl plik


dev/src/controlled.tsx → example/src/controlled.tsx Wyświetl plik


dev/src/embedded.tsx → example/src/embedded.tsx Wyświetl plik


dev/src/imperative.tsx → example/src/imperative.tsx Wyświetl plik


dev/src/index.html → example/src/index.html Wyświetl plik


dev/src/index.tsx → example/src/index.tsx Wyświetl plik


dev/src/multiplayer/cursors.tsx → example/src/multiplayer/cursors.tsx Wyświetl plik


dev/src/multiplayer/index.ts → example/src/multiplayer/index.ts Wyświetl plik


dev/src/multiplayer/multiplayer.tsx → example/src/multiplayer/multiplayer.tsx Wyświetl plik

40
   const doc = useObject<{ uuid: string; document: TLDrawDocument }>('doc', {
40
   const doc = useObject<{ uuid: string; document: TLDrawDocument }>('doc', {
41
     uuid: docId,
41
     uuid: docId,
42
     document: {
42
     document: {
43
+      ...TLDrawState.defaultDocument,
43
       id: 'test-room',
44
       id: 'test-room',
44
-      pages: {
45
-        page: {
46
-          id: 'page',
47
-          shapes: {},
48
-          bindings: {},
49
-        },
50
-      },
51
-      pageStates: {
52
-        page: {
53
-          id: 'page',
54
-          selectedIds: [],
55
-          camera: {
56
-            point: [0, 0],
57
-            zoom: 1,
58
-          },
59
-        },
60
-      },
61
     },
45
     },
62
   })
46
   })
63
 
47
 

dev/src/no-size-embedded.tsx → example/src/no-size-embedded.tsx Wyświetl plik


dev/src/styles.css → example/src/styles.css Wyświetl plik


dev/tsconfig.json → example/tsconfig.json Wyświetl plik


dev/tsconfig.tsbuildinfo → example/tsconfig.tsbuildinfo Wyświetl plik


+ 2
- 5
package.json Wyświetl plik

10
   "license": "MIT",
10
   "license": "MIT",
11
   "workspaces": [
11
   "workspaces": [
12
     "packages/tldraw",
12
     "packages/tldraw",
13
-    "dev",
13
+    "example",
14
     "www"
14
     "www"
15
   ],
15
   ],
16
   "scripts": {
16
   "scripts": {
45
     "typedoc": "^0.22.3",
45
     "typedoc": "^0.22.3",
46
     "typescript": "^4.4.2"
46
     "typescript": "^4.4.2"
47
   },
47
   },
48
-  "dependencies": {
49
-    "www": "0.0.133"
50
-  },
51
   "prettier": {
48
   "prettier": {
52
     "trailingComma": "es5",
49
     "trailingComma": "es5",
53
     "singleQuote": true,
50
     "singleQuote": true,
80
       "\\~(.*)": "<rootDir>/packages/tldraw/src/$1"
77
       "\\~(.*)": "<rootDir>/packages/tldraw/src/$1"
81
     }
78
     }
82
   }
79
   }
83
-}
80
+}

+ 149
- 46
packages/tldraw/README.md Wyświetl plik

1
+<div style="text-align: center; transform: scale(.5);">
2
+  <img src="card-repo.png"/>
3
+</div>
4
+
1
 # @tldraw/tldraw
5
 # @tldraw/tldraw
2
 
6
 
3
-> `This library is not yet released and these docs are partially out of date!`
7
+This package contains the [tldraw](https://tldraw.com) editor as a React component named `<TLDraw>`. You can use this package to embed the editor in any React application.
4
 
8
 
5
-This package contains the [tldraw](https://tldraw.com) editor as a standalone React component.
9
+🎨 Want to build your own tldraw-ish app instead? Try [@tldraw/core](https://github.com/tldraw/core).
6
 
10
 
7
-## Installation
11
+💕 Love this library? Consider [becoming a sponsor](https://github.com/sponsors/steveruizok?frequency=recurring&sponsor=steveruizok).
8
 
12
 
9
-```bash
10
-npm i @tldraw/tldraw
11
-```
13
+## Installation
12
 
14
 
13
-or
15
+Use your package manager of choice to install `@tldraw/core` and its peer dependencies.
14
 
16
 
15
 ```bash
17
 ```bash
16
 yarn add @tldraw/tldraw
18
 yarn add @tldraw/tldraw
19
+# or
20
+npm i @tldraw/tldraw
17
 ```
21
 ```
18
 
22
 
19
 ## Usage
23
 ## Usage
28
 }
32
 }
29
 ```
33
 ```
30
 
34
 
35
+You can control the `TLDraw` component through props:
36
+
37
+```tsx
38
+import { TLDraw, TLDrawDocument } from '@tldraw/tldraw'
39
+
40
+function App() {
41
+  const myDocument: TLDrawDocument = {}
42
+
43
+  return <TLDraw document={document} />
44
+}
45
+```
46
+
47
+Or imperatively through the `TLDrawState` instance:
48
+
49
+```tsx
50
+import { TLDraw, TLDrawState } from '@tldraw/tldraw'
51
+
52
+function App() {
53
+  const handleMount = React.useCallback((tlstate: TLDrawState) => {
54
+    const myDocument: TLDrawDocument = {}
55
+
56
+    tlstate.loadDocument(myDocument).selectAll()
57
+  }, [])
58
+
59
+  return <TLDraw onMount={handleMount} />
60
+}
61
+```
62
+
31
 ## Documentation
63
 ## Documentation
32
 
64
 
33
 ### `TLDraw`
65
 ### `TLDraw`
34
 
66
 
35
-The `TLDraw` React component is the [tldraw](https://tldraw.com) editor exported as a standalone component. You can control the editor through props, or through the `TLDrawState`'s imperative API.
36
-
37
-| Prop            | Type                            | Description                                                                                                                                                             |
38
-| --------------- | ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
39
-| `id`            | `string`                        | (optional) An id under which to persist the component's state.                                                                                                          |
40
-| `document`      | `TLDrawDocument`                | (optional) An initial [`TLDrawDocument`](#tldrawdocument) object.                                                                                                       |
41
-| `currentPageId` | `string`                        | (optional) A current page id, referencing the `TLDrawDocument` object provided via the `document` prop.                                                                 |
42
-| `onMount`       | `(TLDrawState) => void`         | (optional) A callback function that will be called when the editor first mounts, receiving the current `TLDrawState`.                                                   |
43
-| `onChange`      | `(TLDrawState, string) => void` | (optional) A callback function that will be called whenever the `TLDrawState` updates. The update will include the current `TLDrawState` and the reason for the change. |
67
+The `TLDraw` React component is the [tldraw](https://tldraw.com) editor exported as a standalone component. You can control the editor through props, or through the `TLDrawState`'s imperative API. **All props are optional.**
68
+
69
+| Prop            | Type             | Description                                                                                                                                                  |
70
+| --------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
71
+| `id`            | `string`         | An id under which to persist the component's state.                                                                                                          |
72
+| `document`      | `TLDrawDocument` | An initial [`TLDrawDocument`](#tldrawdocument) object.                                                                                                       |
73
+| `currentPageId` | `string`         | A current page id, referencing the `TLDrawDocument` object provided via the `document` prop.                                                                 |
74
+| `onMount`       | `Function`       | A callback function that will be called when the editor first mounts, receiving the current `TLDrawState`.                                                   |
75
+| `onChange`      | `Function`       | A callback function that will be called whenever the `TLDrawState` updates. The update will include the current `TLDrawState` and the reason for the change. |
76
+| `onUserChange`  | `Function`       | A callback function that will be fired when the user's "presence" information changes.                                                                       |
77
+| `autofocus`     | `boolean`        | Whether the editor should immediately receive focus. Defaults to true.                                                                                       |
78
+| `showMenu`      | `boolean`        | Whether to show the menu.                                                                                                                                    |
79
+| `showPages`     | `boolean`        | Whether to show the pages menu.                                                                                                                              |
80
+| `showStyles`    | `boolean`        | Whether to show the styles menu.                                                                                                                             |
81
+| `showTools`     | `boolean`        | Whether to show the tools.                                                                                                                                   |
82
+| `showUI`        | `boolean`        | Whether to show any UI other than the canvas.                                                                                                                |
44
 
83
 
45
 ### `TLDrawDocument`
84
 ### `TLDrawDocument`
46
 
85
 
47
 A `TLDrawDocument` is an object with three properties:
86
 A `TLDrawDocument` is an object with three properties:
48
 
87
 
49
 - `id` - A unique ID for this document
88
 - `id` - A unique ID for this document
50
-- `pages` - A table of `TLPage` objects
89
+- `pages` - A table of `TLDrawPage` objects
51
 - `pageStates` - A table of `TLPageState` objects
90
 - `pageStates` - A table of `TLPageState` objects
91
+- `version` - The document's version, used internally for migrations.
52
 
92
 
53
 ```ts
93
 ```ts
94
+import { TLDrawDocument, TLDrawState } from '@tldraw/tldraw'
95
+
54
 const tldocument: TLDrawDocument = {
96
 const tldocument: TLDrawDocument = {
55
   id: 'doc',
97
   id: 'doc',
98
+  version: TLDrawState.version,
56
   pages: {
99
   pages: {
57
     page1: {
100
     page1: {
58
       id: 'page1',
101
       id: 'page1',
74
 }
117
 }
75
 ```
118
 ```
76
 
119
 
77
-**Important:** In the `pages` object, each `TLPage` object must be keyed under its `id` property. Likewise, each `TLPageState` object must be keyed under its `id`. In addition, each `TLPageState` object must have an `id` that matches its corresponding page.
120
+**Tip:** TLDraw is built [@tldraw/core](https://github.com/tldraw/core). The pages and pagestates in TLDraw are just objects containing `TLPage` and `TLPageState` objects from the core library. For more about these types, check out the [@tldraw/core](https://github.com/tldraw/core) documentation.
78
 
121
 
79
-In the example above, the page above with the id `page1`is at `tldocument.pages["page1"]`. Its corresponding page state has the same id (`page1`) and is at `tldocument.pageStates["page1"]`.
122
+**Important:** In the `pages` object, each `TLPage` object must be keyed under its `id` property. Likewise, each `TLPageState` object must be keyed under its `id`. In addition, each `TLPageState` object must have an `id` that matches its corresponding page.
80
 
123
 
81
 ### Shapes
124
 ### Shapes
82
 
125
 
83
 Your `TLPage` objects may include shapes: objects that fit one of the `TLDrawShape` interfaces listed below. All `TLDrawShapes` extends a common interface:
126
 Your `TLPage` objects may include shapes: objects that fit one of the `TLDrawShape` interfaces listed below. All `TLDrawShapes` extends a common interface:
84
 
127
 
85
-| Property              | Type         | Description                                                     |
86
-| --------------------- | ------------ | --------------------------------------------------------------- |
87
-| `id`                  | `string`     | A unique ID for the shape.                                      |
88
-| `name`                | `string`     | The shape's name.                                               |
89
-| `type`                | `string`     | The shape's type.                                               |
90
-| `parentId`            | `string`     | The ID of the shape's parent (a shape or its page).             |
91
-| `childIndex`          | `number`     | The shape's order within its parent's children, indexed from 1. |
92
-| `point`               | `number[]`   | The `[x, y]` position of the shape.                             |
93
-| `rotation`            | `number[]`   | (optional) The shape's rotation in radians.                     |
94
-| `children`            | `string[]`   | (optional) The shape's child shape ids.                         |
95
-| `handles`             | `TLHandle{}` | (optional) A table of `TLHandle` objects.                       |
96
-| `isLocked`            | `boolean`    | True if the shape is locked.                                    |
97
-| `isHidden`            | `boolean`    | True if the shape is hidden.                                    |
98
-| `isEditing`           | `boolean`    | True if the shape is currently editing.                         |
99
-| `isGenerated`         | `boolean`    | True if the shape is generated.                                 |
100
-| `isAspectRatioLocked` | `boolean`    | True if the shape's aspect ratio is locked.                     |
128
+| Property              | Type             | Description                                                     |
129
+| --------------------- | ---------------- | --------------------------------------------------------------- |
130
+| `id`                  | `string`         | A unique ID for the shape.                                      |
131
+| `name`                | `string`         | The shape's name.                                               |
132
+| `type`                | `string`         | The shape's type.                                               |
133
+| `parentId`            | `string`         | The ID of the shape's parent (a shape or its page).             |
134
+| `childIndex`          | `number`         | The shape's order within its parent's children, indexed from 1. |
135
+| `point`               | `number[]`       | The `[x, y]` position of the shape.                             |
136
+| `rotation`            | `number[]`       | (optional) The shape's rotation in radians.                     |
137
+| `children`            | `string[]`       | (optional) The shape's child shape ids.                         |
138
+| `handles`             | `TLDrawHandle{}` | (optional) A table of `TLHandle` objects.                       |
139
+| `isLocked`            | `boolean`        | (optional) True if the shape is locked.                         |
140
+| `isHidden`            | `boolean`        | (optional) True if the shape is hidden.                         |
141
+| `isEditing`           | `boolean`        | (optional) True if the shape is currently editing.              |
142
+| `isGenerated`         | `boolean`        | (optional) True if the shape is generated.                      |
143
+| `isAspectRatioLocked` | `boolean`        | (optional) True if the shape's aspect ratio is locked.          |
101
 
144
 
102
 > **Important:** In order for re-ordering to work correctly, a shape's `childIndex` values _must_ start from 1, not 0. The page or parent shape's "bottom-most" child should have a `childIndex` of 1.
145
 > **Important:** In order for re-ordering to work correctly, a shape's `childIndex` values _must_ start from 1, not 0. The page or parent shape's "bottom-most" child should have a `childIndex` of 1.
103
 
146
 
110
 | `color`    | `ColorStyle` | The shape's color.                      |
153
 | `color`    | `ColorStyle` | The shape's color.                      |
111
 | `isFilled` | `boolean`    | (optional) True if the shape is filled. |
154
 | `isFilled` | `boolean`    | (optional) True if the shape is filled. |
112
 
155
 
113
-#### Draw
156
+#### `DrawShape`
157
+
158
+A hand-drawn line.
114
 
159
 
115
 | Property | Type         | Description                               |
160
 | Property | Type         | Description                               |
116
 | -------- | ------------ | ----------------------------------------- |
161
 | -------- | ------------ | ----------------------------------------- |
117
 | `points` | `number[][]` | An array of points as `[x, y, pressure]`. |
162
 | `points` | `number[][]` | An array of points as `[x, y, pressure]`. |
118
 
163
 
119
-##### Rectangle
164
+##### `RectangleShape`
165
+
166
+A rectangular shape.
120
 
167
 
121
 | Property | Type       | Description                             |
168
 | Property | Type       | Description                             |
122
 | -------- | ---------- | --------------------------------------- |
169
 | -------- | ---------- | --------------------------------------- |
123
 | `size`   | `number[]` | The `[width, height]` of the rectangle. |
170
 | `size`   | `number[]` | The `[width, height]` of the rectangle. |
124
 
171
 
125
-#### Ellipse
172
+#### `EllipseShape`
173
+
174
+An elliptical shape.
126
 
175
 
127
 | Property | Type       | Description                         |
176
 | Property | Type       | Description                         |
128
 | -------- | ---------- | ----------------------------------- |
177
 | -------- | ---------- | ----------------------------------- |
129
 | `radius` | `number[]` | The `[x, y]` radius of the ellipse. |
178
 | `radius` | `number[]` | The `[x, y]` radius of the ellipse. |
130
 
179
 
131
-#### Arrow
180
+#### `ArrowShape`
181
+
182
+An arrow that can connect shapes.
183
+
184
+| Property      | Type     | Description                                                             |
185
+| ------------- | -------- | ----------------------------------------------------------------------- |
186
+| `handles`     | `object` | An object with three `TLHandle` properties: `start`, `end`, and `bend`. |
187
+| `decorations` | `object` | An object with two properties `start`, `end`, and `bend`.               |
188
+
189
+#### `TextShape`
190
+
191
+A line of text.
132
 
192
 
133
-| Property  | Type     | Description                                                             |
134
-| --------- | -------- | ----------------------------------------------------------------------- |
135
-| `handles` | `object` | An object with three `TLHandle` properties: `start`, `end`, and `bend`. |
193
+| Property | Type     | Description               |
194
+| -------- | -------- | ------------------------- |
195
+| `text`   | `string` | The shape's text content. |
196
+
197
+#### `StickyShape`
136
 
198
 
137
-#### Text
199
+A sticky note.
138
 
200
 
139
 | Property | Type     | Description               |
201
 | Property | Type     | Description               |
140
 | -------- | -------- | ------------------------- |
202
 | -------- | -------- | ------------------------- |
141
 | `text`   | `string` | The shape's text content. |
203
 | `text`   | `string` | The shape's text content. |
142
 
204
 
143
-## Development
205
+### Bindings
206
+
207
+A binding is a connection **from** one shape and **to** another shape. At the moment, only arrows may be bound "from". Most shapes may be bound "to", except other `ArrowShape` and `DrawShape`s.
208
+
209
+| Property   | Type             | Description                                              |
210
+| ---------- | ---------------- | -------------------------------------------------------- |
211
+| `id`       | `string`         | The binding's own unique ID.                             |
212
+| `fromId`   | `string`         | The id of the `ArrowShape` that the binding is bound to. |
213
+| `toId`     | `string`         | The id of the other shape that the binding is bound to.  |
214
+| `handleId` | `start` or `end` | The connected arrow handle.                              |
215
+| `distance` | `number`         | The distance from the bound point.                       |
216
+| `point`    | `number[]`       | A normalized point representing the bound point.         |
217
+
218
+## Local Development
219
+
220
+- Run `yarn` to install dependencies.
221
+
222
+- Run `yarn start` to start the development server for the package and for the example.
223
+
224
+- Open `localhost:5000` to view the example project.
225
+
226
+- Run `yarn test` to execute unit tests via [Jest](https://jestjs.io).
227
+
228
+- Run `yarn docs` to build the docs via [ts-doc](https://typedoc.org/).
229
+
230
+## Example
231
+
232
+See the `example` folder.
233
+
234
+## Community
235
+
236
+### Support
237
+
238
+Need help? Please [open an issue](https://github.com/tldraw/tldraw/issues/new) for support.
239
+
240
+### Discussion
241
+
242
+Want to connect with other devs? Visit the [Discord channel](https://discord.gg/s4FXZ6fppJ).
243
+
244
+### License
245
+
246
+This project is licensed under MIT. If you're using the library in a commercial product, please consider [becoming a sponsor](https://github.com/sponsors/steveruizok?frequency=recurring&sponsor=steveruizok).
144
 
247
 
145
-### Running unit tests
248
+## Author
146
 
249
 
147
-Run `nx test tldraw` to execute the unit tests via [Jest](https://jestjs.io).
250
+- [@steveruizok](https://twitter.com/steveruizok)

+ 1
- 1
packages/tldraw/package.json Wyświetl plik

50
     "@tldraw/vec": "^0.1.3",
50
     "@tldraw/vec": "^0.1.3",
51
     "perfect-freehand": "^1.0.16",
51
     "perfect-freehand": "^1.0.16",
52
     "react-hotkeys-hook": "^3.4.0",
52
     "react-hotkeys-hook": "^3.4.0",
53
-    "rko": "^0.5.25"
53
+    "rko": "^0.6.0"
54
   },
54
   },
55
   "devDependencies": {
55
   "devDependencies": {
56
     "tsconfig-replace-paths": "^0.0.5"
56
     "tsconfig-replace-paths": "^0.0.5"

+ 3
- 1
packages/tldraw/src/components/ToolButton/ToolButton.tsx Wyświetl plik

4
 import styled from '~styles'
4
 import styled from '~styles'
5
 
5
 
6
 export interface ToolButtonProps {
6
 export interface ToolButtonProps {
7
+  onClick?: () => void
7
   onSelect?: () => void
8
   onSelect?: () => void
8
   onDoubleClick?: () => void
9
   onDoubleClick?: () => void
9
   isActive?: boolean
10
   isActive?: boolean
12
 }
13
 }
13
 
14
 
14
 export const ToolButton = React.forwardRef<HTMLButtonElement, ToolButtonProps>(
15
 export const ToolButton = React.forwardRef<HTMLButtonElement, ToolButtonProps>(
15
-  ({ onSelect, onDoubleClick, isActive = false, variant, children, ...rest }, ref) => {
16
+  ({ onSelect, onClick, onDoubleClick, isActive = false, variant, children, ...rest }, ref) => {
16
     return (
17
     return (
17
       <StyledToolButton
18
       <StyledToolButton
18
         ref={ref}
19
         ref={ref}
19
         isActive={isActive}
20
         isActive={isActive}
20
         variant={variant}
21
         variant={variant}
22
+        onClick={onClick}
21
         onPointerDown={onSelect}
23
         onPointerDown={onSelect}
22
         onDoubleClick={onDoubleClick}
24
         onDoubleClick={onDoubleClick}
23
         bp={breakpoints}
25
         bp={breakpoints}

+ 15
- 14
packages/tldraw/src/components/TopPanel/ColorMenu.tsx Wyświetl plik

4
 import { useTheme, useTLDrawContext } from '~hooks'
4
 import { useTheme, useTLDrawContext } from '~hooks'
5
 import type { Data, ColorStyle } from '~types'
5
 import type { Data, ColorStyle } from '~types'
6
 import CircleIcon from '~components/icons/CircleIcon'
6
 import CircleIcon from '~components/icons/CircleIcon'
7
-import { DMContent, DMRadioItem, DMTriggerIcon } from '~components/DropdownMenu'
7
+import { DMContent, DMTriggerIcon } from '~components/DropdownMenu'
8
 import { BoxIcon } from '~components/icons'
8
 import { BoxIcon } from '~components/icons'
9
-import { IconButton } from '~components/IconButton'
10
 import { ToolButton } from '~components/ToolButton'
9
 import { ToolButton } from '~components/ToolButton'
11
-import { Tooltip } from '~components/Tooltip'
12
 
10
 
13
 const selectColor = (s: Data) => s.appState.selectedStyle.color
11
 const selectColor = (s: Data) => s.appState.selectedStyle.color
14
 
12
 
13
+const preventEvent = (e: Event) => e.preventDefault()
14
+
15
 export const ColorMenu = React.memo((): JSX.Element => {
15
 export const ColorMenu = React.memo((): JSX.Element => {
16
   const { theme } = useTheme()
16
   const { theme } = useTheme()
17
   const { tlstate, useSelector } = useTLDrawContext()
17
   const { tlstate, useSelector } = useTLDrawContext()
25
       </DMTriggerIcon>
25
       </DMTriggerIcon>
26
       <DMContent variant="grid">
26
       <DMContent variant="grid">
27
         {Object.keys(strokes[theme]).map((colorStyle: string) => (
27
         {Object.keys(strokes[theme]).map((colorStyle: string) => (
28
-          <ToolButton
29
-            key={colorStyle}
30
-            variant="icon"
31
-            isActive={color === colorStyle}
32
-            onSelect={() => tlstate.style({ color: colorStyle as ColorStyle })}
33
-          >
34
-            <BoxIcon
35
-              fill={strokes[theme][colorStyle as ColorStyle]}
36
-              stroke={strokes[theme][colorStyle as ColorStyle]}
37
-            />
38
-          </ToolButton>
28
+          <DropdownMenu.Item key={colorStyle} onSelect={preventEvent} asChild>
29
+            <ToolButton
30
+              variant="icon"
31
+              isActive={color === colorStyle}
32
+              onClick={() => tlstate.style({ color: colorStyle as ColorStyle })}
33
+            >
34
+              <BoxIcon
35
+                fill={strokes[theme][colorStyle as ColorStyle]}
36
+                stroke={strokes[theme][colorStyle as ColorStyle]}
37
+              />
38
+            </ToolButton>
39
+          </DropdownMenu.Item>
39
         ))}
40
         ))}
40
       </DMContent>
41
       </DMContent>
41
     </DropdownMenu.Root>
42
     </DropdownMenu.Root>

+ 12
- 9
packages/tldraw/src/components/TopPanel/DashMenu.tsx Wyświetl plik

15
 
15
 
16
 const selectDash = (s: Data) => s.appState.selectedStyle.dash
16
 const selectDash = (s: Data) => s.appState.selectedStyle.dash
17
 
17
 
18
+const preventEvent = (e: Event) => e.preventDefault()
19
+
18
 export const DashMenu = React.memo((): JSX.Element => {
20
 export const DashMenu = React.memo((): JSX.Element => {
19
   const { tlstate, useSelector } = useTLDrawContext()
21
   const { tlstate, useSelector } = useTLDrawContext()
20
 
22
 
24
     <DropdownMenu.Root dir="ltr">
26
     <DropdownMenu.Root dir="ltr">
25
       <DMTriggerIcon>{dashes[dash]}</DMTriggerIcon>
27
       <DMTriggerIcon>{dashes[dash]}</DMTriggerIcon>
26
       <DMContent variant="horizontal">
28
       <DMContent variant="horizontal">
27
-        {Object.keys(DashStyle).map((dashStyle) => (
28
-          <ToolButton
29
-            key={dashStyle}
30
-            variant="icon"
31
-            isActive={dash === dashStyle}
32
-            onSelect={() => tlstate.style({ dash: dashStyle as DashStyle })}
33
-          >
34
-            {dashes[dashStyle as DashStyle]}
35
-          </ToolButton>
29
+        {Object.values(DashStyle).map((dashStyle) => (
30
+          <DropdownMenu.Item key={dashStyle} onSelect={preventEvent} asChild>
31
+            <ToolButton
32
+              variant="icon"
33
+              isActive={dash === dashStyle}
34
+              onClick={() => tlstate.style({ dash: dashStyle as DashStyle })}
35
+            >
36
+              {dashes[dashStyle as DashStyle]}
37
+            </ToolButton>
38
+          </DropdownMenu.Item>
36
         ))}
39
         ))}
37
       </DMContent>
40
       </DMContent>
38
     </DropdownMenu.Root>
41
     </DropdownMenu.Root>

+ 2
- 0
packages/tldraw/src/components/TopPanel/PageOptionsDialog.tsx Wyświetl plik

128
   right: 0,
128
   right: 0,
129
   bottom: 0,
129
   bottom: 0,
130
   left: 0,
130
   left: 0,
131
+  width: '100%',
132
+  height: '100%',
131
 })
133
 })
132
 
134
 
133
 function DialogAction({ onSelect, ...rest }: RowButtonProps) {
135
 function DialogAction({ onSelect, ...rest }: RowButtonProps) {

+ 13
- 9
packages/tldraw/src/components/TopPanel/SizeMenu.tsx Wyświetl plik

2
 import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
2
 import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
3
 import { Data, SizeStyle } from '~types'
3
 import { Data, SizeStyle } from '~types'
4
 import { useTLDrawContext } from '~hooks'
4
 import { useTLDrawContext } from '~hooks'
5
-import { DMContent, DMTriggerIcon } from '~components/DropdownMenu'
5
+import { DMContent, DMItem, DMTriggerIcon } from '~components/DropdownMenu'
6
 import { ToolButton } from '~components/ToolButton'
6
 import { ToolButton } from '~components/ToolButton'
7
 import { SizeSmallIcon, SizeMediumIcon, SizeLargeIcon } from '~components/icons'
7
 import { SizeSmallIcon, SizeMediumIcon, SizeLargeIcon } from '~components/icons'
8
 
8
 
14
 
14
 
15
 const selectSize = (s: Data) => s.appState.selectedStyle.size
15
 const selectSize = (s: Data) => s.appState.selectedStyle.size
16
 
16
 
17
+const preventEvent = (e: Event) => e.preventDefault()
18
+
17
 export const SizeMenu = React.memo((): JSX.Element => {
19
 export const SizeMenu = React.memo((): JSX.Element => {
18
   const { tlstate, useSelector } = useTLDrawContext()
20
   const { tlstate, useSelector } = useTLDrawContext()
19
 
21
 
23
     <DropdownMenu.Root dir="ltr">
25
     <DropdownMenu.Root dir="ltr">
24
       <DMTriggerIcon>{sizes[size as SizeStyle]}</DMTriggerIcon>
26
       <DMTriggerIcon>{sizes[size as SizeStyle]}</DMTriggerIcon>
25
       <DMContent variant="horizontal">
27
       <DMContent variant="horizontal">
26
-        {Object.keys(SizeStyle).map((sizeStyle: string) => (
27
-          <ToolButton
28
-            key={sizeStyle}
29
-            isActive={size === sizeStyle}
30
-            onSelect={() => tlstate.style({ size: sizeStyle as SizeStyle })}
31
-          >
32
-            {sizes[sizeStyle as SizeStyle]}
33
-          </ToolButton>
28
+        {Object.values(SizeStyle).map((sizeStyle: string) => (
29
+          <DropdownMenu.Item key={sizeStyle} onSelect={preventEvent} asChild>
30
+            <ToolButton
31
+              isActive={size === sizeStyle}
32
+              variant="icon"
33
+              onClick={() => tlstate.style({ size: sizeStyle as SizeStyle })}
34
+            >
35
+              {sizes[sizeStyle as SizeStyle]}
36
+            </ToolButton>
37
+          </DropdownMenu.Item>
34
         ))}
38
         ))}
35
       </DMContent>
39
       </DMContent>
36
     </DropdownMenu.Root>
40
     </DropdownMenu.Root>

+ 4
- 4
packages/tldraw/src/shape-utils/arrow/__snapshots__/arrow.spec.tsx.snap Wyświetl plik

5
   "bend": 0,
5
   "bend": 0,
6
   "childIndex": 1,
6
   "childIndex": 1,
7
   "decorations": Object {
7
   "decorations": Object {
8
-    "end": "Arrow",
8
+    "end": "arrow",
9
   },
9
   },
10
   "handles": Object {
10
   "handles": Object {
11
     "bend": Object {
11
     "bend": Object {
44
   ],
44
   ],
45
   "rotation": 0,
45
   "rotation": 0,
46
   "style": Object {
46
   "style": Object {
47
-    "color": "Black",
48
-    "dash": "Draw",
47
+    "color": "black",
48
+    "dash": "draw",
49
     "isFilled": false,
49
     "isFilled": false,
50
-    "size": "Small",
50
+    "size": "small",
51
   },
51
   },
52
   "type": "arrow",
52
   "type": "arrow",
53
 }
53
 }

+ 3
- 3
packages/tldraw/src/shape-utils/draw/__snapshots__/draw.spec.tsx.snap Wyświetl plik

14
   "points": Array [],
14
   "points": Array [],
15
   "rotation": 0,
15
   "rotation": 0,
16
   "style": Object {
16
   "style": Object {
17
-    "color": "Black",
18
-    "dash": "Draw",
17
+    "color": "black",
18
+    "dash": "draw",
19
     "isFilled": false,
19
     "isFilled": false,
20
-    "size": "Small",
20
+    "size": "small",
21
   },
21
   },
22
   "type": "draw",
22
   "type": "draw",
23
 }
23
 }

+ 3
- 3
packages/tldraw/src/shape-utils/ellipse/__snapshots__/ellipse.spec.tsx.snap Wyświetl plik

16
   ],
16
   ],
17
   "rotation": 0,
17
   "rotation": 0,
18
   "style": Object {
18
   "style": Object {
19
-    "color": "Black",
20
-    "dash": "Draw",
19
+    "color": "black",
20
+    "dash": "draw",
21
     "isFilled": false,
21
     "isFilled": false,
22
-    "size": "Small",
22
+    "size": "small",
23
   },
23
   },
24
   "type": "ellipse",
24
   "type": "ellipse",
25
 }
25
 }

+ 3
- 3
packages/tldraw/src/shape-utils/group/__snapshots__/group.spec.tsx.snap Wyświetl plik

17
     100,
17
     100,
18
   ],
18
   ],
19
   "style": Object {
19
   "style": Object {
20
-    "color": "Black",
21
-    "dash": "Draw",
20
+    "color": "black",
21
+    "dash": "draw",
22
     "isFilled": false,
22
     "isFilled": false,
23
-    "size": "Small",
23
+    "size": "small",
24
   },
24
   },
25
   "type": "group",
25
   "type": "group",
26
 }
26
 }

+ 3
- 3
packages/tldraw/src/shape-utils/rectangle/__snapshots__/rectangle.spec.tsx.snap Wyświetl plik

16
     1,
16
     1,
17
   ],
17
   ],
18
   "style": Object {
18
   "style": Object {
19
-    "color": "Black",
20
-    "dash": "Draw",
19
+    "color": "black",
20
+    "dash": "draw",
21
     "isFilled": false,
21
     "isFilled": false,
22
-    "size": "Small",
22
+    "size": "small",
23
   },
23
   },
24
   "type": "rectangle",
24
   "type": "rectangle",
25
 }
25
 }

+ 3
- 3
packages/tldraw/src/shape-utils/text/__snapshots__/text.spec.tsx.snap Wyświetl plik

12
   ],
12
   ],
13
   "rotation": 0,
13
   "rotation": 0,
14
   "style": Object {
14
   "style": Object {
15
-    "color": "Black",
16
-    "dash": "Draw",
15
+    "color": "black",
16
+    "dash": "draw",
17
     "isFilled": false,
17
     "isFilled": false,
18
-    "size": "Small",
18
+    "size": "small",
19
   },
19
   },
20
   "text": " ",
20
   "text": " ",
21
   "type": "text",
21
   "type": "text",

+ 6
- 6
packages/tldraw/src/state/__snapshots__/tlstate.spec.ts.snap Wyświetl plik

33
                   200,
33
                   200,
34
                 ],
34
                 ],
35
                 "style": Object {
35
                 "style": Object {
36
-                  "color": "Black",
37
-                  "dash": "Draw",
36
+                  "color": "black",
37
+                  "dash": "draw",
38
                   "isFilled": false,
38
                   "isFilled": false,
39
-                  "size": "Small",
39
+                  "size": "small",
40
                 },
40
                 },
41
                 "type": "rectangle",
41
                 "type": "rectangle",
42
               },
42
               },
93
                   200,
93
                   200,
94
                 ],
94
                 ],
95
                 "style": Object {
95
                 "style": Object {
96
-                  "color": "Black",
97
-                  "dash": "Draw",
96
+                  "color": "black",
97
+                  "dash": "draw",
98
                   "isFilled": false,
98
                   "isFilled": false,
99
-                  "size": "Small",
99
+                  "size": "small",
100
                 },
100
                 },
101
                 "type": "rectangle",
101
                 "type": "rectangle",
102
               },
102
               },

+ 53
- 0
packages/tldraw/src/state/migrate.ts Wyświetl plik

1
+/* eslint-disable @typescript-eslint/ban-ts-comment */
2
+import { Decoration, TLDrawDocument, TLDrawShapeType } from '~types'
3
+
4
+export function migrate(document: TLDrawDocument, newVersion: number): TLDrawDocument {
5
+  const { version = 0 } = document
6
+
7
+  if (version === newVersion) return document
8
+
9
+  if (version <= 12) {
10
+    Object.values(document.pages).forEach((page) => {
11
+      Object.values(page.bindings).forEach((binding) => {
12
+        // eslint-disable-next-line @typescript-eslint/no-explicit-any
13
+        Object.assign(binding, (binding as any).meta)
14
+      })
15
+
16
+      Object.values(page.shapes).forEach((shape) => {
17
+        Object.entries(shape.style).forEach(([id, style]) => {
18
+          if (typeof style === 'string') {
19
+            // @ts-ignore
20
+            shape.style[id] = style.toLowerCase()
21
+          }
22
+        })
23
+
24
+        if (shape.type === TLDrawShapeType.Arrow) {
25
+          if (shape.decorations) {
26
+            Object.entries(shape.decorations).forEach(([id, decoration]) => {
27
+              if ((decoration as unknown) === 'Arrow') {
28
+                shape.decorations = {
29
+                  ...shape.decorations,
30
+                  [id]: Decoration.Arrow,
31
+                }
32
+              }
33
+            })
34
+          }
35
+        }
36
+      })
37
+    })
38
+  }
39
+
40
+  Object.values(document.pageStates).forEach((pageState) => {
41
+    pageState.selectedIds = pageState.selectedIds.filter((id) => {
42
+      return document.pages[pageState.id].shapes[id] !== undefined
43
+    })
44
+    pageState.bindingId = undefined
45
+    pageState.editingId = undefined
46
+    pageState.hoveredId = undefined
47
+    pageState.pointedId = undefined
48
+  })
49
+
50
+  document.version = newVersion
51
+
52
+  return document
53
+}

+ 10
- 15
packages/tldraw/src/state/tlstate.ts Wyświetl plik

47
 import { createTools, ToolType } from './tool'
47
 import { createTools, ToolType } from './tool'
48
 import type { BaseTool } from './tool/BaseTool'
48
 import type { BaseTool } from './tool/BaseTool'
49
 import { USER_COLORS, FIT_TO_SCREEN_PADDING } from '~constants'
49
 import { USER_COLORS, FIT_TO_SCREEN_PADDING } from '~constants'
50
+import { migrate } from './migrate'
50
 
51
 
51
 const uuid = Utils.uniqueId()
52
 const uuid = Utils.uniqueId()
52
 
53
 
100
     onUserChange?: (tlstate: TLDrawState, user: TLDrawUser) => void
101
     onUserChange?: (tlstate: TLDrawState, user: TLDrawUser) => void
101
   ) {
102
   ) {
102
     super(TLDrawState.defaultState, id, TLDrawState.version, (prev, next) => {
103
     super(TLDrawState.defaultState, id, TLDrawState.version, (prev, next) => {
103
-      Object.values(prev.document.pages).forEach((page) => {
104
-        Object.values(page.bindings).forEach((binding) => {
105
-          if ('meta' in binding) {
106
-            // @ts-ignore
107
-            Object.assign(binding, binding.meta)
108
-          }
109
-        })
110
-      })
111
-
112
       return {
104
       return {
113
         ...next,
105
         ...next,
114
         document: { ...next.document, ...prev.document },
106
         document: { ...next.document, ...prev.document },
115
       }
107
       }
116
     })
108
     })
117
 
109
 
110
+    this.loadDocument(this.document)
111
+    this.patchState({ document: migrate(this.document, TLDrawState.version) })
112
+
118
     this._onChange = onChange
113
     this._onChange = onChange
119
     this._onMount = onMount
114
     this._onMount = onMount
120
     this._onUserChange = onUserChange
115
     this._onUserChange = onUserChange
130
         appState: {
125
         appState: {
131
           status: TLDrawStatus.Idle,
126
           status: TLDrawStatus.Idle,
132
         },
127
         },
128
+        document: migrate(this.document, TLDrawState.version),
133
       })
129
       })
134
     } catch (e) {
130
     } catch (e) {
135
       console.error('The data appears to be corrupted. Resetting!', e)
131
       console.error('The data appears to be corrupted. Resetting!', e)
641
           ...this.appState,
637
           ...this.appState,
642
           currentPageId: Object.keys(document.pages)[0],
638
           currentPageId: Object.keys(document.pages)[0],
643
         },
639
         },
644
-        document,
640
+        document: migrate(document, TLDrawState.version),
645
       })
641
       })
646
       return this
642
       return this
647
     }
643
     }
709
         ...this.state,
705
         ...this.state,
710
         appState: nextAppState,
706
         appState: nextAppState,
711
         document: {
707
         document: {
712
-          ...document,
708
+          ...migrate(document, TLDrawState.version),
713
           pageStates: currentPageStates,
709
           pageStates: currentPageStates,
714
         },
710
         },
715
       },
711
       },
803
     return this.replaceState(
799
     return this.replaceState(
804
       {
800
       {
805
         ...TLDrawState.defaultState,
801
         ...TLDrawState.defaultState,
806
-        document,
802
+        document: migrate(document, TLDrawState.version),
807
         appState: {
803
         appState: {
808
           ...TLDrawState.defaultState.appState,
804
           ...TLDrawState.defaultState.appState,
809
           currentPageId: Object.keys(document.pages)[0],
805
           currentPageId: Object.keys(document.pages)[0],
1068
       Utils.deepClone(this.getShape(id, this.currentPageId))
1064
       Utils.deepClone(this.getShape(id, this.currentPageId))
1069
     )
1065
     )
1070
 
1066
 
1071
-    console.log(copyingShapes.length)
1072
-
1073
     if (copyingShapes.length === 0) return this
1067
     if (copyingShapes.length === 0) return this
1074
 
1068
 
1075
     const copyingBindings: TLDrawBinding[] = Object.values(this.page.bindings).filter(
1069
     const copyingBindings: TLDrawBinding[] = Object.values(this.page.bindings).filter(
2463
     }
2457
     }
2464
   }
2458
   }
2465
 
2459
 
2466
-  static version = 11
2460
+  static version = 12.5
2467
 
2461
 
2468
   static defaultDocument: TLDrawDocument = {
2462
   static defaultDocument: TLDrawDocument = {
2469
     id: 'doc',
2463
     id: 'doc',
2464
+    version: 12.4,
2470
     pages: {
2465
     pages: {
2471
       page: {
2466
       page: {
2472
         id: 'page',
2467
         id: 'page',

+ 0
- 2
packages/tldraw/src/state/tool/BaseTool/BaseTool.ts Wyświetl plik

46
   }
46
   }
47
 
47
 
48
   onCancel = () => {
48
   onCancel = () => {
49
-    console.log('cancelling')
50
-
51
     if (this.status === Status.Idle) {
49
     if (this.status === Status.Idle) {
52
       this.state.selectTool('select')
50
       this.state.selectTool('select')
53
     } else {
51
     } else {

+ 0
- 2
packages/tldraw/src/state/tool/TextTool/TextTool.ts Wyświetl plik

11
   stopEditingShape = () => {
11
   stopEditingShape = () => {
12
     this.setStatus(Status.Idle)
12
     this.setStatus(Status.Idle)
13
 
13
 
14
-    console.log(this.state.appState.isToolLocked)
15
-
16
     if (!this.state.appState.isToolLocked) {
14
     if (!this.state.appState.isToolLocked) {
17
       this.state.selectTool('select')
15
       this.state.selectTool('select')
18
     }
16
     }

+ 8
- 8
packages/tldraw/src/test/migration.spec.ts Wyświetl plik

5
 
5
 
6
 describe('When migrating bindings', () => {
6
 describe('When migrating bindings', () => {
7
   it('migrates', () => {
7
   it('migrates', () => {
8
-    Object.values((oldDoc as unknown as TLDrawDocument).pages).forEach((page) => {
9
-      Object.values(page.bindings).forEach((binding) => {
10
-        if ('meta' in binding) {
11
-          // @ts-ignore
12
-          Object.assign(binding, binding.meta)
13
-        }
14
-      })
15
-    })
8
+    // Object.values((oldDoc as unknown as TLDrawDocument).pages).forEach((page) => {
9
+    //   Object.values(page.bindings).forEach((binding) => {
10
+    //     if ('meta' in binding) {
11
+    //       // @ts-ignore
12
+    //       Object.assign(binding, binding.meta)
13
+    //     }
14
+    //   })
15
+    // })
16
 
16
 
17
     new TLDrawState().loadDocument(oldDoc as unknown as TLDrawDocument)
17
     new TLDrawState().loadDocument(oldDoc as unknown as TLDrawDocument)
18
   })
18
   })

+ 1
- 0
packages/tldraw/src/test/mock-document.tsx Wyświetl plik

1
 import { TLDrawDocument, ColorStyle, DashStyle, SizeStyle, TLDrawShapeType } from '~types'
1
 import { TLDrawDocument, ColorStyle, DashStyle, SizeStyle, TLDrawShapeType } from '~types'
2
 
2
 
3
 export const mockDocument: TLDrawDocument = {
3
 export const mockDocument: TLDrawDocument = {
4
+  version: 0,
4
   id: 'doc',
5
   id: 'doc',
5
   pages: {
6
   pages: {
6
     page1: {
7
     page1: {

+ 25
- 31
packages/tldraw/src/types.ts Wyświetl plik

9
   TLHandle,
9
   TLHandle,
10
   TLBounds,
10
   TLBounds,
11
   TLSnapLine,
11
   TLSnapLine,
12
-  TLComponentProps,
13
 } from '@tldraw/core'
12
 } from '@tldraw/core'
14
 import type { TLPage, TLUser, TLPageState } from '@tldraw/core'
13
 import type { TLPage, TLUser, TLPageState } from '@tldraw/core'
15
 import type { StoreApi } from 'zustand'
14
 import type { StoreApi } from 'zustand'
28
   transformOrigin: number[]
27
   transformOrigin: number[]
29
 }
28
 }
30
 
29
 
31
-export type TLDrawComponentProps<T extends TLDrawShape, E extends Element = any> = TLComponentProps<
32
-  T,
33
-  E,
34
-  TLDrawMeta
35
->
36
-
37
 // old
30
 // old
38
 export type TLStore = StoreApi<Data>
31
 export type TLStore = StoreApi<Data>
39
 
32
 
45
   id: string
38
   id: string
46
   pages: Record<string, TLDrawPage>
39
   pages: Record<string, TLDrawPage>
47
   pageStates: Record<string, TLPageState>
40
   pageStates: Record<string, TLPageState>
41
+  version: number
48
 }
42
 }
49
 
43
 
50
 export interface TLDrawSettings {
44
 export interface TLDrawSettings {
229
 }
223
 }
230
 
224
 
231
 export enum Decoration {
225
 export enum Decoration {
232
-  Arrow = 'Arrow',
226
+  Arrow = 'arrow',
233
 }
227
 }
234
 
228
 
235
 export interface TLDrawBaseShape extends TLShape {
229
 export interface TLDrawBaseShape extends TLShape {
304
 export type TLDrawBinding = ArrowBinding
298
 export type TLDrawBinding = ArrowBinding
305
 
299
 
306
 export enum ColorStyle {
300
 export enum ColorStyle {
307
-  White = 'White',
308
-  LightGray = 'LightGray',
309
-  Gray = 'Gray',
310
-  Black = 'Black',
311
-  Green = 'Green',
312
-  Cyan = 'Cyan',
313
-  Blue = 'Blue',
314
-  Indigo = 'Indigo',
315
-  Violet = 'Violet',
316
-  Red = 'Red',
317
-  Orange = 'Orange',
318
-  Yellow = 'Yellow',
301
+  White = 'white',
302
+  LightGray = 'lightGray',
303
+  Gray = 'gray',
304
+  Black = 'black',
305
+  Green = 'green',
306
+  Cyan = 'cyan',
307
+  Blue = 'blue',
308
+  Indigo = 'indigo',
309
+  Violet = 'violet',
310
+  Red = 'red',
311
+  Orange = 'orange',
312
+  Yellow = 'yellow',
319
 }
313
 }
320
 
314
 
321
 export enum SizeStyle {
315
 export enum SizeStyle {
322
-  Small = 'Small',
323
-  Medium = 'Medium',
324
-  Large = 'Large',
316
+  Small = 'small',
317
+  Medium = 'medium',
318
+  Large = 'large',
325
 }
319
 }
326
 
320
 
327
 export enum DashStyle {
321
 export enum DashStyle {
328
-  Draw = 'Draw',
329
-  Solid = 'Solid',
330
-  Dashed = 'Dashed',
331
-  Dotted = 'Dotted',
322
+  Draw = 'draw',
323
+  Solid = 'solid',
324
+  Dashed = 'dashed',
325
+  Dotted = 'dotted',
332
 }
326
 }
333
 
327
 
334
 export enum FontSize {
328
 export enum FontSize {
335
-  Small = 'Small',
336
-  Medium = 'Medium',
337
-  Large = 'Large',
338
-  ExtraLarge = 'ExtraLarge',
329
+  Small = 'small',
330
+  Medium = 'medium',
331
+  Large = 'large',
332
+  ExtraLarge = 'extraLarge',
339
 }
333
 }
340
 
334
 
341
 export type ShapeStyles = {
335
 export type ShapeStyles = {

+ 11
- 0
www/.babelrc Wyświetl plik

1
+{
2
+  "presets": [
3
+    [
4
+      "next/babel",
5
+      {
6
+        "preset-env": { "targets": { "node": true } }
7
+      }
8
+    ]
9
+  ],
10
+  "plugins": []
11
+}

+ 6
- 18
www/components/multiplayer-editor.tsx Wyświetl plik

37
     uuid: docId,
37
     uuid: docId,
38
     document: {
38
     document: {
39
       id: 'test-room',
39
       id: 'test-room',
40
-      pages: {
41
-        page: {
42
-          id: 'page',
43
-          shapes: {},
44
-          bindings: {},
45
-        },
46
-      },
47
-      pageStates: {
48
-        page: {
49
-          id: 'page',
50
-          selectedIds: [],
51
-          camera: {
52
-            point: [0, 0],
53
-            zoom: 1,
54
-          },
55
-        },
56
-      },
40
+      ...TLDrawState.defaultDocument,
57
     },
41
     },
58
   })
42
   })
59
 
43
 
156
     doc.subscribe(handleDocumentUpdates)
140
     doc.subscribe(handleDocumentUpdates)
157
 
141
 
158
     // Load the shared document
142
     // Load the shared document
159
-    tlstate.loadDocument(doc.toObject().document)
143
+    const newDocument = doc.toObject().document
144
+
145
+    if (newDocument) {
146
+      tlstate.loadDocument(newDocument)
147
+    }
160
 
148
 
161
     return () => {
149
     return () => {
162
       window.removeEventListener('beforeunload', handleExit)
150
       window.removeEventListener('beforeunload', handleExit)

+ 2
- 0
www/public/workbox-a6b3f14f.js
Plik diff jest za duży
Wyświetl plik


+ 1
- 0
www/public/workbox-a6b3f14f.js.map
Plik diff jest za duży
Wyświetl plik


+ 1
- 1
www/tsconfig.json Wyświetl plik

1
 {
1
 {
2
   "compilerOptions": {
2
   "compilerOptions": {
3
     "composite": true,
3
     "composite": true,
4
-    "target": "es5",
4
+    "target": "es6",
5
     "lib": ["dom", "dom.iterable", "esnext"],
5
     "lib": ["dom", "dom.iterable", "esnext"],
6
     "allowJs": true,
6
     "allowJs": true,
7
     "skipLibCheck": true,
7
     "skipLibCheck": true,

+ 6
- 6
yarn.lock Wyświetl plik

9920
     iconv-lite "0.4.24"
9920
     iconv-lite "0.4.24"
9921
     unpipe "1.0.0"
9921
     unpipe "1.0.0"
9922
 
9922
 
9923
-react-dom@17.0.2, "react-dom@^16.8 || ^17.0":
9923
+react-dom@17.0.2:
9924
   version "17.0.2"
9924
   version "17.0.2"
9925
   resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23"
9925
   resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23"
9926
   integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==
9926
   integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==
10008
     invariant "^2.2.4"
10008
     invariant "^2.2.4"
10009
     tslib "^1.0.0"
10009
     tslib "^1.0.0"
10010
 
10010
 
10011
-react@17.0.2, react@>=16.8:
10011
+react@17.0.2:
10012
   version "17.0.2"
10012
   version "17.0.2"
10013
   resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
10013
   resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
10014
   integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==
10014
   integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==
10445
     hash-base "^3.0.0"
10445
     hash-base "^3.0.0"
10446
     inherits "^2.0.1"
10446
     inherits "^2.0.1"
10447
 
10447
 
10448
-rko@^0.5.25:
10449
-  version "0.5.25"
10450
-  resolved "https://registry.yarnpkg.com/rko/-/rko-0.5.25.tgz#1095803900e3f912f6adf8a1c113b8227d3d88bf"
10451
-  integrity sha512-HU6M3PxK3VEqrr6QZKAsqO98juQX24kEgJkKSdFJhw8U/DBUGAnU/fgyxNIaTw7TCI7vjIy/RzBEXf5I4sijKg==
10448
+rko@^0.6.0:
10449
+  version "0.6.0"
10450
+  resolved "https://registry.yarnpkg.com/rko/-/rko-0.6.0.tgz#fa640384b4e82fdcd90fc58c958256148c4eb10c"
10451
+  integrity sha512-u05SAiyz02Sw+QyGaQb3NGPXf3xXxQ9AwNG+tItHx2MpAsPEEH84NqYDyG9jem/ji/FPQPQHuRKcy2MHb1a1Ow==
10452
   dependencies:
10452
   dependencies:
10453
     idb-keyval "^5.1.3"
10453
     idb-keyval "^5.1.3"
10454
     zustand "^3.5.9"
10454
     zustand "^3.5.9"

Ładowanie…
Anuluj
Zapisz