Enforce readonly mode (#714)

* Enforce readonly mode

* Fix test for React 18

* Move to dev
This commit is contained in:
Steve Ruiz 2022-06-09 16:00:47 +01:00 committed by GitHub
parent d919bd273e
commit d52d91b367
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 179 additions and 22 deletions

View file

@ -47,6 +47,7 @@
"@radix-ui/react-icons": "^1.1.1", "@radix-ui/react-icons": "^1.1.1",
"@radix-ui/react-tooltip": "^0.1.7", "@radix-ui/react-tooltip": "^0.1.7",
"@stitches/react": "^1.2.8", "@stitches/react": "^1.2.8",
"@testing-library/react": "^13.3.0",
"@tldraw/core": "^1.14.0-next.0", "@tldraw/core": "^1.14.0-next.0",
"@tldraw/intersect": "^1.7.1", "@tldraw/intersect": "^1.7.1",
"@tldraw/vec": "^1.7.0", "@tldraw/vec": "^1.7.0",
@ -61,7 +62,7 @@
}, },
"devDependencies": { "devDependencies": {
"@swc-node/jest": "^1.4.3", "@swc-node/jest": "^1.4.3",
"@testing-library/jest-dom": "^5.16.2", "@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^12.1.2", "@testing-library/react": "^12.1.2",
"@tldraw/core": "*", "@tldraw/core": "*",
"@tldraw/intersect": "*", "@tldraw/intersect": "*",
@ -105,4 +106,4 @@
} }
}, },
"gitHead": "4b1137849ad07da36fc8f0f19cb64e7535a79296" "gitHead": "4b1137849ad07da36fc8f0f19cb64e7535a79296"
} }

View file

@ -223,6 +223,11 @@ export function Tldraw({
// Toggle the app's readOnly mode when the `readOnly` prop changes. // Toggle the app's readOnly mode when the `readOnly` prop changes.
React.useEffect(() => { React.useEffect(() => {
app.readOnly = readOnly app.readOnly = readOnly
if (!readOnly) {
app.selectNone()
app.cancelSession()
app.setEditingId()
}
}, [app, readOnly]) }, [app, readOnly])
// Toggle the app's darkMode when the `darkMode` prop changes. // Toggle the app's darkMode when the `darkMode` prop changes.

View file

@ -1758,9 +1758,11 @@ export class TldrawApp extends StateManager<TDSnapshot> {
e?.preventDefault() e?.preventDefault()
this.copy(ids, e) this.copy(ids, e)
if (!this.readOnly) { if (!this.readOnly) {
this.delete(ids) this.delete(ids)
} }
return this return this
} }
@ -1769,6 +1771,8 @@ export class TldrawApp extends StateManager<TDSnapshot> {
* @param ids The ids of the shapes to copy. * @param ids The ids of the shapes to copy.
*/ */
copy = (ids = this.selectedIds, e?: ClipboardEvent): this => { copy = (ids = this.selectedIds, e?: ClipboardEvent): this => {
// Allow when in readOnly mode
e?.preventDefault() e?.preventDefault()
this.clipboard = this.getClipboard(ids) this.clipboard = this.getClipboard(ids)

View file

@ -36,8 +36,9 @@ export class DrawTool extends BaseTool {
/* ----------------- Event Handlers ----------------- */ /* ----------------- Event Handlers ----------------- */
onPointerDown: TLPointerEventHandler = (info) => { onPointerDown: TLPointerEventHandler = info => {
if (this.status !== Status.Idle) return if (this.status !== Status.Idle) return
if (this.app.readOnly) return
const { const {
currentPoint, currentPoint,
appState: { currentPageId, currentStyle }, appState: { currentPageId, currentStyle },
@ -66,6 +67,8 @@ export class DrawTool extends BaseTool {
} }
onPointerMove: TLPointerEventHandler = () => { onPointerMove: TLPointerEventHandler = () => {
if (this.app.readOnly) return
switch (this.status) { switch (this.status) {
case Status.Extending: case Status.Extending:
case Status.Creating: { case Status.Creating: {

View file

@ -10,6 +10,7 @@ export class EllipseTool extends BaseTool {
/* ----------------- Event Handlers ----------------- */ /* ----------------- Event Handlers ----------------- */
onPointerDown: TLPointerEventHandler = () => { onPointerDown: TLPointerEventHandler = () => {
if (this.app.readOnly) return
if (this.status !== Status.Idle) return if (this.status !== Status.Idle) return
const { const {

View file

@ -18,12 +18,14 @@ export class EraseTool extends BaseTool {
/* ----------------- Event Handlers ----------------- */ /* ----------------- Event Handlers ----------------- */
onPointerDown: TLPointerEventHandler = () => { onPointerDown: TLPointerEventHandler = () => {
if (this.app.readOnly) return
if (this.status !== Status.Idle) return if (this.status !== Status.Idle) return
this.setStatus(Status.Pointing) this.setStatus(Status.Pointing)
} }
onPointerMove: TLPointerEventHandler = (info) => { onPointerMove: TLPointerEventHandler = (info) => {
if (this.app.readOnly) return
switch (this.status) { switch (this.status) {
case Status.Pointing: { case Status.Pointing: {
if (Vec.dist(info.origin, info.point) > DEAD_ZONE) { if (Vec.dist(info.origin, info.point) > DEAD_ZONE) {
@ -40,6 +42,7 @@ export class EraseTool extends BaseTool {
} }
onPointerUp: TLPointerEventHandler = () => { onPointerUp: TLPointerEventHandler = () => {
if (this.app.readOnly) return
switch (this.status) { switch (this.status) {
case Status.Pointing: { case Status.Pointing: {
const shapeIdsAtPoint = this.app.shapes const shapeIdsAtPoint = this.app.shapes

View file

@ -10,6 +10,7 @@ export class LineTool extends BaseTool {
/* ----------------- Event Handlers ----------------- */ /* ----------------- Event Handlers ----------------- */
onPointerDown: TLPointerEventHandler = () => { onPointerDown: TLPointerEventHandler = () => {
if (this.app.readOnly) return
if (this.status !== Status.Idle) return if (this.status !== Status.Idle) return
const { const {

View file

@ -10,6 +10,7 @@ export class RectangleTool extends BaseTool {
/* ----------------- Event Handlers ----------------- */ /* ----------------- Event Handlers ----------------- */
onPointerDown: TLPointerEventHandler = () => { onPointerDown: TLPointerEventHandler = () => {
if (this.app.readOnly) return
if (this.status !== Status.Idle) return if (this.status !== Status.Idle) return
const { const {

View file

@ -50,7 +50,7 @@ export class SelectTool extends BaseTool<Status> {
/* --------------------- Methods -------------------- */ /* --------------------- Methods -------------------- */
private deselect(id: string) { private deselect(id: string) {
this.app.select(...this.app.selectedIds.filter((oid) => oid !== id)) this.app.select(...this.app.selectedIds.filter(oid => oid !== id))
} }
private select(id: string) { private select(id: string) {
@ -59,7 +59,7 @@ export class SelectTool extends BaseTool<Status> {
private pushSelect(id: string) { private pushSelect(id: string) {
const shape = this.app.getShape(id) const shape = this.app.getShape(id)
this.app.select(...this.app.selectedIds.filter((oid) => oid !== shape.parentId), id) this.app.select(...this.app.selectedIds.filter(oid => oid !== shape.parentId), id)
} }
private selectNone() { private selectNone() {
@ -77,7 +77,7 @@ export class SelectTool extends BaseTool<Status> {
clonePaint = (point: number[]) => { clonePaint = (point: number[]) => {
if (this.app.selectedIds.length === 0) return if (this.app.selectedIds.length === 0) return
const shapes = this.app.selectedIds.map((id) => this.app.getShape(id)) const shapes = this.app.selectedIds.map(id => this.app.getShape(id))
const bounds = Utils.expandBounds(Utils.getCommonBounds(shapes.map(TLDR.getBounds)), 16) const bounds = Utils.expandBounds(Utils.getCommonBounds(shapes.map(TLDR.getBounds)), 16)
@ -92,7 +92,7 @@ export class SelectTool extends BaseTool<Status> {
const centeredBounds = Utils.centerBounds(bounds, gridPoint) const centeredBounds = Utils.centerBounds(bounds, gridPoint)
const hit = this.app.shapes.some((shape) => const hit = this.app.shapes.some(shape =>
TLDR.getShapeUtil(shape).hitTestBounds(shape, centeredBounds) TLDR.getShapeUtil(shape).hitTestBounds(shape, centeredBounds)
) )
@ -187,6 +187,8 @@ export class SelectTool extends BaseTool<Status> {
break break
} }
case 'Tab': { case 'Tab': {
if (this.app.readOnly) return
if ( if (
!this.app.pageState.editingId && !this.app.pageState.editingId &&
this.status === Status.Idle && this.status === Status.Idle &&
@ -213,6 +215,8 @@ export class SelectTool extends BaseTool<Status> {
break break
} }
case 'Enter': { case 'Enter': {
if (this.app.readOnly) return
const { pageState } = this.app const { pageState } = this.app
if (pageState.selectedIds.length === 1 && !pageState.editingId) { if (pageState.selectedIds.length === 1 && !pageState.editingId) {
this.app.setEditingId(pageState.selectedIds[0]) this.app.setEditingId(pageState.selectedIds[0])
@ -239,7 +243,8 @@ export class SelectTool extends BaseTool<Status> {
// Pointer Events (generic) // Pointer Events (generic)
onPointerMove: TLPointerEventHandler = (info, e) => { onPointerMove: TLPointerEventHandler = () => {
if (this.app.readOnly) return
const { originPoint, currentPoint } = this.app const { originPoint, currentPoint } = this.app
switch (this.status) { switch (this.status) {
@ -260,7 +265,7 @@ export class SelectTool extends BaseTool<Status> {
} else { } else {
// Stat a transform session // Stat a transform session
this.setStatus(Status.Transforming) this.setStatus(Status.Transforming)
const idsToTransform = this.app.selectedIds.flatMap((id) => const idsToTransform = this.app.selectedIds.flatMap(id =>
TLDR.getDocumentBranch(this.app.state, id, this.app.currentPageId) TLDR.getDocumentBranch(this.app.state, id, this.app.currentPageId)
) )
if (idsToTransform.length === 1) { if (idsToTransform.length === 1) {
@ -367,7 +372,7 @@ export class SelectTool extends BaseTool<Status> {
} }
} }
onPointerUp: TLPointerEventHandler = (info) => { onPointerUp: TLPointerEventHandler = info => {
if (this.status === Status.TranslatingClone || this.status === Status.PointingClone) { if (this.status === Status.TranslatingClone || this.status === Status.PointingClone) {
if (this.pointedId) { if (this.pointedId) {
this.app.completeSession() this.app.completeSession()
@ -420,6 +425,7 @@ export class SelectTool extends BaseTool<Status> {
// Canvas // Canvas
onDoubleClickCanvas: TLCanvasEventHandler = () => { onDoubleClickCanvas: TLCanvasEventHandler = () => {
if (this.app.readOnly) return
// Needs debugging // Needs debugging
// const { currentPoint } = this.app // const { currentPoint } = this.app
// this.app.selectTool(TDShapeType.Text) // this.app.selectTool(TDShapeType.Text)
@ -523,7 +529,9 @@ export class SelectTool extends BaseTool<Status> {
} }
} }
onDoubleClickShape: TLPointerEventHandler = (info) => { onDoubleClickShape: TLPointerEventHandler = info => {
if (this.app.readOnly) return
const shape = this.app.getShape(info.target) const shape = this.app.getShape(info.target)
if (shape.isLocked) { if (shape.isLocked) {
@ -548,17 +556,17 @@ export class SelectTool extends BaseTool<Status> {
this.app.select(info.target) this.app.select(info.target)
} }
onRightPointShape: TLPointerEventHandler = (info) => { onRightPointShape: TLPointerEventHandler = info => {
if (!this.app.isSelected(info.target)) { if (!this.app.isSelected(info.target)) {
this.app.select(info.target) this.app.select(info.target)
} }
} }
onHoverShape: TLPointerEventHandler = (info) => { onHoverShape: TLPointerEventHandler = info => {
this.app.setHoveredId(info.target) this.app.setHoveredId(info.target)
} }
onUnhoverShape: TLPointerEventHandler = (info) => { onUnhoverShape: TLPointerEventHandler = info => {
const { currentPageId: oldCurrentPageId } = this.app const { currentPageId: oldCurrentPageId } = this.app
// Wait a frame; and if we haven't changed the hovered id, // Wait a frame; and if we haven't changed the hovered id,
@ -575,7 +583,7 @@ export class SelectTool extends BaseTool<Status> {
/* --------------------- Bounds --------------------- */ /* --------------------- Bounds --------------------- */
onPointBounds: TLBoundsEventHandler = (info) => { onPointBounds: TLBoundsEventHandler = info => {
if (info.metaKey) { if (info.metaKey) {
if (!info.shiftKey) { if (!info.shiftKey) {
this.selectNone() this.selectNone()
@ -604,12 +612,12 @@ export class SelectTool extends BaseTool<Status> {
/* ----------------- Bounds Handles ----------------- */ /* ----------------- Bounds Handles ----------------- */
onPointBoundsHandle: TLBoundsHandleEventHandler = (info) => { onPointBoundsHandle: TLBoundsHandleEventHandler = info => {
this.pointedBoundsHandle = info.target this.pointedBoundsHandle = info.target
this.setStatus(Status.PointingBoundsHandle) this.setStatus(Status.PointingBoundsHandle)
} }
onDoubleClickBoundsHandle: TLBoundsHandleEventHandler = (info) => { onDoubleClickBoundsHandle: TLBoundsHandleEventHandler = info => {
switch (info.target) { switch (info.target) {
case 'center': case 'center':
case 'left': case 'left':
@ -642,12 +650,12 @@ export class SelectTool extends BaseTool<Status> {
/* --------------------- Handles -------------------- */ /* --------------------- Handles -------------------- */
onPointHandle: TLPointerEventHandler = (info) => { onPointHandle: TLPointerEventHandler = info => {
this.pointedHandleId = info.target as 'start' | 'end' this.pointedHandleId = info.target as 'start' | 'end'
this.setStatus(Status.PointingHandle) this.setStatus(Status.PointingHandle)
} }
onDoubleClickHandle: TLPointerEventHandler = (info) => { onDoubleClickHandle: TLPointerEventHandler = info => {
if (info.target === 'bend') { if (info.target === 'bend') {
const { selectedIds } = this.app const { selectedIds } = this.app
if (selectedIds.length !== 1) return if (selectedIds.length !== 1) return
@ -670,7 +678,7 @@ export class SelectTool extends BaseTool<Status> {
/* ---------------------- Misc ---------------------- */ /* ---------------------- Misc ---------------------- */
onShapeClone: TLShapeCloneHandler = (info) => { onShapeClone: TLShapeCloneHandler = info => {
const selectedShapeId = this.app.selectedIds[0] const selectedShapeId = this.app.selectedIds[0]
const clonedShape = this.getShapeClone(selectedShapeId, info.target) const clonedShape = this.getShapeClone(selectedShapeId, info.target)

View file

@ -13,6 +13,7 @@ export class StickyTool extends BaseTool {
/* ----------------- Event Handlers ----------------- */ /* ----------------- Event Handlers ----------------- */
onPointerDown: TLPointerEventHandler = () => { onPointerDown: TLPointerEventHandler = () => {
if (this.app.readOnly) return
if (this.status === Status.Creating) { if (this.status === Status.Creating) {
this.setStatus(Status.Idle) this.setStatus(Status.Idle)
@ -58,6 +59,7 @@ export class StickyTool extends BaseTool {
} }
onPointerUp: TLPointerEventHandler = () => { onPointerUp: TLPointerEventHandler = () => {
if (this.app.readOnly) return
if (this.status === Status.Creating) { if (this.status === Status.Creating) {
this.setStatus(Status.Idle) this.setStatus(Status.Idle)
this.app.completeSession() this.app.completeSession()

View file

@ -51,6 +51,7 @@ export class TextTool extends BaseTool {
} }
onPointShape: TLPointerEventHandler = (info) => { onPointShape: TLPointerEventHandler = (info) => {
if (this.app.readOnly) return
const shape = this.app.getShape(info.target) const shape = this.app.getShape(info.target)
if (shape.type === TDShapeType.Text) { if (shape.type === TDShapeType.Text) {
this.setStatus(Status.Idle) this.setStatus(Status.Idle)
@ -59,6 +60,7 @@ export class TextTool extends BaseTool {
} }
onShapeBlur = () => { onShapeBlur = () => {
if (this.app.readOnly) return
this.stopEditingShape() this.stopEditingShape()
} }
} }

View file

@ -10,6 +10,7 @@ export class TriangleTool extends BaseTool {
/* ----------------- Event Handlers ----------------- */ /* ----------------- Event Handlers ----------------- */
onPointerDown: TLPointerEventHandler = () => { onPointerDown: TLPointerEventHandler = () => {
if (this.app.readOnly) return
if (this.status !== Status.Idle) return if (this.status !== Status.Idle) return
const { const {

129
yarn.lock
View file

@ -2193,6 +2193,22 @@
"@babel/runtime" "^7.13.10" "@babel/runtime" "^7.13.10"
"@radix-ui/react-primitive" "0.1.4" "@radix-ui/react-primitive" "0.1.4"
"@radix-ui/react-checkbox@^0.1.5":
version "0.1.5"
resolved "https://registry.yarnpkg.com/@radix-ui/react-checkbox/-/react-checkbox-0.1.5.tgz#3a6bd54ba1720c8e5c03852acf460e35dfbe9da3"
integrity sha512-M8Y4dSXsKSbF+FryG5VvZKr/1MukMVG7swq9p5s7wYb8Rvn0UM0rQ5w8BWmSWSV4BL/gbJdhwVCznwXXlgZRZg==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/primitive" "0.1.0"
"@radix-ui/react-compose-refs" "0.1.0"
"@radix-ui/react-context" "0.1.1"
"@radix-ui/react-label" "0.1.5"
"@radix-ui/react-presence" "0.1.2"
"@radix-ui/react-primitive" "0.1.4"
"@radix-ui/react-use-controllable-state" "0.1.0"
"@radix-ui/react-use-previous" "0.1.1"
"@radix-ui/react-use-size" "0.1.1"
"@radix-ui/react-collection@0.1.4": "@radix-ui/react-collection@0.1.4":
version "0.1.4" version "0.1.4"
resolved "https://registry.yarnpkg.com/@radix-ui/react-collection/-/react-collection-0.1.4.tgz#734061ffd5bb93e88889d49b87391a73a63824c9" resolved "https://registry.yarnpkg.com/@radix-ui/react-collection/-/react-collection-0.1.4.tgz#734061ffd5bb93e88889d49b87391a73a63824c9"
@ -2308,6 +2324,17 @@
"@babel/runtime" "^7.13.10" "@babel/runtime" "^7.13.10"
"@radix-ui/react-use-layout-effect" "0.1.0" "@radix-ui/react-use-layout-effect" "0.1.0"
"@radix-ui/react-label@0.1.5":
version "0.1.5"
resolved "https://registry.yarnpkg.com/@radix-ui/react-label/-/react-label-0.1.5.tgz#12cd965bfc983e0148121d4c99fb8e27a917c45c"
integrity sha512-Au9+n4/DhvjR0IHhvZ1LPdx/OW+3CGDie30ZyCkbSHIuLp4/CV4oPPGBwJ1vY99Jog3zyQhsGww9MXj8O9Aj/A==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-compose-refs" "0.1.0"
"@radix-ui/react-context" "0.1.1"
"@radix-ui/react-id" "0.1.5"
"@radix-ui/react-primitive" "0.1.4"
"@radix-ui/react-menu@0.1.6": "@radix-ui/react-menu@0.1.6":
version "0.1.6" version "0.1.6"
resolved "https://registry.yarnpkg.com/@radix-ui/react-menu/-/react-menu-0.1.6.tgz#7f9521a10f6a9cd819b33b33d5ed9538d79b2e75" resolved "https://registry.yarnpkg.com/@radix-ui/react-menu/-/react-menu-0.1.6.tgz#7f9521a10f6a9cd819b33b33d5ed9538d79b2e75"
@ -2373,6 +2400,23 @@
"@babel/runtime" "^7.13.10" "@babel/runtime" "^7.13.10"
"@radix-ui/react-slot" "0.1.2" "@radix-ui/react-slot" "0.1.2"
"@radix-ui/react-radio-group@^0.1.5":
version "0.1.5"
resolved "https://registry.yarnpkg.com/@radix-ui/react-radio-group/-/react-radio-group-0.1.5.tgz#ca8a676123a18b44804aff10af46129e2c2b37c3"
integrity sha512-ybgHsmh/V2crKvK6xZ56dpPul7b+vyxcq7obWqHbr5W6Ca11wdm0E7lS0i/Y6pgfIKYOWIARmZYDpRMEeRCPOw==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/primitive" "0.1.0"
"@radix-ui/react-compose-refs" "0.1.0"
"@radix-ui/react-context" "0.1.1"
"@radix-ui/react-label" "0.1.5"
"@radix-ui/react-presence" "0.1.2"
"@radix-ui/react-primitive" "0.1.4"
"@radix-ui/react-roving-focus" "0.1.5"
"@radix-ui/react-use-controllable-state" "0.1.0"
"@radix-ui/react-use-previous" "0.1.1"
"@radix-ui/react-use-size" "0.1.1"
"@radix-ui/react-roving-focus@0.1.5": "@radix-ui/react-roving-focus@0.1.5":
version "0.1.5" version "0.1.5"
resolved "https://registry.yarnpkg.com/@radix-ui/react-roving-focus/-/react-roving-focus-0.1.5.tgz#cc48d17a36b56f253d54905b0fd60ee134cb97ee" resolved "https://registry.yarnpkg.com/@radix-ui/react-roving-focus/-/react-roving-focus-0.1.5.tgz#cc48d17a36b56f253d54905b0fd60ee134cb97ee"
@ -2851,6 +2895,20 @@
lz-string "^1.4.4" lz-string "^1.4.4"
pretty-format "^27.0.2" pretty-format "^27.0.2"
"@testing-library/dom@^8.5.0":
version "8.13.0"
resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.13.0.tgz#bc00bdd64c7d8b40841e27a70211399ad3af46f5"
integrity sha512-9VHgfIatKNXQNaZTtLnalIy0jNZzY35a4S3oi08YAt9Hv1VsfZ/DfA45lM8D/UhtHBGJ4/lGwp0PZkVndRkoOQ==
dependencies:
"@babel/code-frame" "^7.10.4"
"@babel/runtime" "^7.12.5"
"@types/aria-query" "^4.2.0"
aria-query "^5.0.0"
chalk "^4.1.0"
dom-accessibility-api "^0.5.9"
lz-string "^1.4.4"
pretty-format "^27.0.2"
"@testing-library/jest-dom@^5.16.2": "@testing-library/jest-dom@^5.16.2":
version "5.16.2" version "5.16.2"
resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.16.2.tgz#f329b36b44aa6149cd6ced9adf567f8b6aa1c959" resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.16.2.tgz#f329b36b44aa6149cd6ced9adf567f8b6aa1c959"
@ -2866,6 +2924,21 @@
lodash "^4.17.15" lodash "^4.17.15"
redent "^3.0.0" redent "^3.0.0"
"@testing-library/jest-dom@^5.16.4":
version "5.16.4"
resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.16.4.tgz#938302d7b8b483963a3ae821f1c0808f872245cd"
integrity sha512-Gy+IoFutbMQcky0k+bqqumXZ1cTGswLsFqmNLzNdSKkU9KGV2u9oXhukCbbJ9/LRPKiqwxEE8VpV/+YZlfkPUA==
dependencies:
"@babel/runtime" "^7.9.2"
"@types/testing-library__jest-dom" "^5.9.1"
aria-query "^5.0.0"
chalk "^3.0.0"
css "^3.0.0"
css.escape "^1.5.1"
dom-accessibility-api "^0.5.6"
lodash "^4.17.15"
redent "^3.0.0"
"@testing-library/react@^12.1.2": "@testing-library/react@^12.1.2":
version "12.1.2" version "12.1.2"
resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-12.1.2.tgz#f1bc9a45943461fa2a598bb4597df1ae044cfc76" resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-12.1.2.tgz#f1bc9a45943461fa2a598bb4597df1ae044cfc76"
@ -2874,6 +2947,53 @@
"@babel/runtime" "^7.12.5" "@babel/runtime" "^7.12.5"
"@testing-library/dom" "^8.0.0" "@testing-library/dom" "^8.0.0"
"@testing-library/react@^13.3.0":
version "13.3.0"
resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-13.3.0.tgz#bf298bfbc5589326bbcc8052b211f3bb097a97c5"
integrity sha512-DB79aA426+deFgGSjnf5grczDPiL4taK3hFaa+M5q7q20Kcve9eQottOG5kZ74KEr55v0tU2CQormSSDK87zYQ==
dependencies:
"@babel/runtime" "^7.12.5"
"@testing-library/dom" "^8.5.0"
"@types/react-dom" "^18.0.0"
"@tldraw/core@*", "@tldraw/core@^1.13.1":
version "1.13.1"
resolved "https://registry.yarnpkg.com/@tldraw/core/-/core-1.13.1.tgz#b56f919b23f941dfe1842238131ccee7da19e2cd"
integrity sha512-tvQGi5Up2WriLVTtJbWNanchd03hUX5e3g/iRPptOacDlygQTX6XtfBa+4VA0F3vDwzoxeCTe2smpNMTbhKM1g==
dependencies:
"@tldraw/intersect" "^1.7.1"
"@tldraw/vec" "^1.7.0"
"@use-gesture/react" "^10.2.14"
mobx-react-lite "^3.2.3"
perfect-freehand "^1.1.0"
resize-observer-polyfill "^1.5.1"
"@tldraw/tldraw@*":
version "1.15.1"
resolved "https://registry.yarnpkg.com/@tldraw/tldraw/-/tldraw-1.15.1.tgz#f27cd992e96dd68f1ad3243e04c5964a19db6b2b"
integrity sha512-76RBv5urQAi/PBKfnENxfS/pZkwkJD5/LfCioreWAo8+ZYit0wRGzF8e5uii1INEibPpz/hgQz6W/4SU64m8vA==
dependencies:
"@radix-ui/react-alert-dialog" "^0.1.7"
"@radix-ui/react-checkbox" "^0.1.5"
"@radix-ui/react-context-menu" "^0.1.6"
"@radix-ui/react-dropdown-menu" "^0.1.6"
"@radix-ui/react-icons" "^1.1.1"
"@radix-ui/react-radio-group" "^0.1.5"
"@radix-ui/react-tooltip" "^0.1.7"
"@stitches/react" "^1.2.8"
"@tldraw/core" "^1.13.1"
"@tldraw/intersect" "^1.7.1"
"@tldraw/vec" "^1.7.0"
"@types/lz-string" "^1.3.34"
idb-keyval "^6.1.0"
lz-string "^1.4.4"
perfect-freehand "^1.1.0"
react-error-boundary "^3.1.4"
react-hotkey-hook "^1.0.2"
react-hotkeys-hook "^3.4.4"
tslib "^2.3.1"
zustand "^3.6.9"
"@tootallnate/once@1": "@tootallnate/once@1":
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"
@ -3116,7 +3236,7 @@
dependencies: dependencies:
"@types/react" "*" "@types/react" "*"
"@types/react-dom@^18.0.5": "@types/react-dom@^18.0.0", "@types/react-dom@^18.0.5":
version "18.0.5" version "18.0.5"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.5.tgz#330b2d472c22f796e5531446939eacef8378444a" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.5.tgz#330b2d472c22f796e5531446939eacef8378444a"
integrity sha512-OWPWTUrY/NIrjsAPkAk1wW9LZeIjSvkXRhclsFO8CZcZGCOg2G0YZy4ft+rOyYxy8B7ui5iZzi9OkDebZ7/QSA== integrity sha512-OWPWTUrY/NIrjsAPkAk1wW9LZeIjSvkXRhclsFO8CZcZGCOg2G0YZy4ft+rOyYxy8B7ui5iZzi9OkDebZ7/QSA==
@ -9509,6 +9629,11 @@ react-feather@^2.0.9:
dependencies: dependencies:
prop-types "^15.7.2" prop-types "^15.7.2"
react-hotkey-hook@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/react-hotkey-hook/-/react-hotkey-hook-1.0.2.tgz#ca17a3f806092027eaaf41fd2f111afd9926e3ab"
integrity sha512-95GiOW8ORMqbBQ23+VHMF0giRmpiI8sFHPjbOR/e64zWI0QT+QO3Q/022c0HNBS/LrQsbGdjm64BNMah0WvlnA==
react-hotkeys-hook@^3.4.4: react-hotkeys-hook@^3.4.4:
version "3.4.4" version "3.4.4"
resolved "https://registry.yarnpkg.com/react-hotkeys-hook/-/react-hotkeys-hook-3.4.4.tgz#52ba5d8ef5e47cc2e776c70a9036d518e0993d51" resolved "https://registry.yarnpkg.com/react-hotkeys-hook/-/react-hotkeys-hook-3.4.4.tgz#52ba5d8ef5e47cc2e776c70a9036d518e0993d51"
@ -10861,7 +10986,7 @@ tsconfig-replace-paths@^0.0.11:
globby "^10.0.1" globby "^10.0.1"
json5 "^2.2.0" json5 "^2.2.0"
tslib@2.4.0, tslib@^2.4.0: tslib@2.4.0, tslib@^2.3.1, tslib@^2.4.0:
version "2.4.0" version "2.4.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==