Fix meta examples (#2379)
This PR fixes a bug in our meta examples. ### Change Type - [x] `patch` — Bug fix
This commit is contained in:
parent
530596ac5d
commit
16316ac2a0
7 changed files with 58 additions and 20 deletions
|
@ -1,11 +1,11 @@
|
||||||
import { Tldraw } from '@tldraw/tldraw'
|
import { TLShape, Tldraw, track, useEditor } from '@tldraw/tldraw'
|
||||||
import '@tldraw/tldraw/tldraw.css'
|
import '@tldraw/tldraw/tldraw.css'
|
||||||
|
|
||||||
export default function OnChangeShapeMetaExample() {
|
export default function OnChangeShapeMetaExample() {
|
||||||
return (
|
return (
|
||||||
<div className="tldraw__editor">
|
<div className="tldraw__editor">
|
||||||
<Tldraw
|
<Tldraw
|
||||||
persistenceKey="tldraw_example"
|
persistenceKey="tldraw_change_meta_example"
|
||||||
onMount={(editor) => {
|
onMount={(editor) => {
|
||||||
// See the "meta-on-create" example for more about setting the
|
// See the "meta-on-create" example for more about setting the
|
||||||
// initial meta for a shape.
|
// initial meta for a shape.
|
||||||
|
@ -20,14 +20,33 @@ export default function OnChangeShapeMetaExample() {
|
||||||
// all shapes whenever they are updated.
|
// all shapes whenever they are updated.
|
||||||
editor.sideEffects.registerBeforeChangeHandler('shape', (_prev, next, source) => {
|
editor.sideEffects.registerBeforeChangeHandler('shape', (_prev, next, source) => {
|
||||||
if (source !== 'user') return next
|
if (source !== 'user') return next
|
||||||
next.meta = {
|
return {
|
||||||
|
...next,
|
||||||
|
meta: {
|
||||||
updatedBy: editor.user.getId(),
|
updatedBy: editor.user.getId(),
|
||||||
updatedAt: Date.now(),
|
updatedAt: Date.now(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
return next
|
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
|
<MetaUiHelper />
|
||||||
|
</Tldraw>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ShapeWithMyMeta = TLShape & { meta: { updatedBy: string; updatedAt: string } }
|
||||||
|
|
||||||
|
export const MetaUiHelper = track(function MetaUiHelper() {
|
||||||
|
const editor = useEditor()
|
||||||
|
const onlySelectedShape = editor.getOnlySelectedShape() as ShapeWithMyMeta | null
|
||||||
|
|
||||||
|
return (
|
||||||
|
<pre style={{ position: 'absolute', zIndex: 300, top: 64, left: 12, margin: 0 }}>
|
||||||
|
{onlySelectedShape
|
||||||
|
? JSON.stringify(onlySelectedShape.meta, null, 2)
|
||||||
|
: 'Select one shape to see its meta data.'}
|
||||||
|
</pre>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
|
@ -7,4 +7,4 @@ Add custom metadata to shapes when they're changed.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
In this example, we add updatedAt metadata to shapes when they're updated.
|
We can update a shape's metadata whenever it changes. A UI displays the current selected shape's metadata. Create a shape, select it, and move it around. The metadata will updated any time the shape changes.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Tldraw } from '@tldraw/tldraw'
|
import { TLShape, Tldraw, track, useEditor } from '@tldraw/tldraw'
|
||||||
import '@tldraw/tldraw/tldraw.css'
|
import '@tldraw/tldraw/tldraw.css'
|
||||||
|
|
||||||
export default function OnCreateShapeMetaExample() {
|
export default function OnCreateShapeMetaExample() {
|
||||||
|
@ -17,7 +17,24 @@ export default function OnCreateShapeMetaExample() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
|
<MetaUiHelper />
|
||||||
|
</Tldraw>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ShapeWithMyMeta = TLShape & { meta: { updatedBy: string; updatedAt: string } }
|
||||||
|
|
||||||
|
export const MetaUiHelper = track(function MetaUiHelper() {
|
||||||
|
const editor = useEditor()
|
||||||
|
const onlySelectedShape = editor.getOnlySelectedShape() as ShapeWithMyMeta | null
|
||||||
|
|
||||||
|
return (
|
||||||
|
<pre style={{ position: 'absolute', zIndex: 300, top: 64, left: 12, margin: 0 }}>
|
||||||
|
{onlySelectedShape
|
||||||
|
? JSON.stringify(onlySelectedShape.meta, null, 2)
|
||||||
|
: 'Select one shape to see its meta data.'}
|
||||||
|
</pre>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
|
@ -7,4 +7,4 @@ Add custom metadata to shapes when they're created.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
In this example, we add createdBy and createdAt metadata to shapes when they're created.
|
We can update a shape's metadata whenever it is created. A UI displays the current selected shape's metadata. Create a shape and select it. The metadata will display its created at / created by data.
|
||||||
|
|
|
@ -7,4 +7,4 @@ Add a label to shapes with the meta property.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Select a shape and try changing its label. The label is stored in the shape's meta property, which can be used to add custom data to any shape.
|
We can update a shape's metadata using a custom UI. Create a shape, select it, and edit the `label` metadata. The label is stored in the shape's meta property, which can be used to add custom data to any shape.
|
||||||
|
|
|
@ -26,10 +26,6 @@ export const ShapeLabelUiWithHelper = track(function ShapeLabelUiWithHelper() {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
const onlySelectedShape = editor.getOnlySelectedShape() as ShapeWithMyMeta | null
|
const onlySelectedShape = editor.getOnlySelectedShape() as ShapeWithMyMeta | null
|
||||||
|
|
||||||
if (!onlySelectedShape) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
function onChange(e: React.ChangeEvent<HTMLInputElement>) {
|
function onChange(e: React.ChangeEvent<HTMLInputElement>) {
|
||||||
if (onlySelectedShape) {
|
if (onlySelectedShape) {
|
||||||
const { id, type, meta } = onlySelectedShape
|
const { id, type, meta } = onlySelectedShape
|
||||||
|
@ -42,7 +38,12 @@ export const ShapeLabelUiWithHelper = track(function ShapeLabelUiWithHelper() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ position: 'absolute', zIndex: 300, top: 64, left: 12 }}>
|
<div style={{ position: 'absolute', zIndex: 300, top: 64, left: 12 }}>
|
||||||
shape label: <input value={onlySelectedShape.meta.label} onChange={onChange} />
|
<pre style={{ margin: '0 0 16px 0' }}>
|
||||||
|
{onlySelectedShape
|
||||||
|
? JSON.stringify(onlySelectedShape.meta, null, 2)
|
||||||
|
: 'Select one shape to see / edit its meta data.'}
|
||||||
|
</pre>
|
||||||
|
{onlySelectedShape && <input value={onlySelectedShape.meta.label} onChange={onChange} />}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
|
@ -382,12 +382,12 @@ export class Store<R extends UnknownRecord = UnknownRecord, Props = unknown> {
|
||||||
const recordAtom = (map ?? currentMap)[record.id as IdOf<R>]
|
const recordAtom = (map ?? currentMap)[record.id as IdOf<R>]
|
||||||
|
|
||||||
if (recordAtom) {
|
if (recordAtom) {
|
||||||
if (beforeUpdate) record = beforeUpdate(recordAtom.get(), record, source)
|
|
||||||
|
|
||||||
// If we already have an atom for this record, update its value.
|
// If we already have an atom for this record, update its value.
|
||||||
|
|
||||||
const initialValue = recordAtom.__unsafe__getWithoutCapture()
|
const initialValue = recordAtom.__unsafe__getWithoutCapture()
|
||||||
|
|
||||||
|
// If we have a beforeUpdate callback, run it against the initial and next records
|
||||||
|
if (beforeUpdate) record = beforeUpdate(initialValue, record, source)
|
||||||
|
|
||||||
// Validate the record
|
// Validate the record
|
||||||
record = this.schema.validateRecord(
|
record = this.schema.validateRecord(
|
||||||
this,
|
this,
|
||||||
|
@ -402,6 +402,7 @@ export class Store<R extends UnknownRecord = UnknownRecord, Props = unknown> {
|
||||||
const finalValue = recordAtom.__unsafe__getWithoutCapture()
|
const finalValue = recordAtom.__unsafe__getWithoutCapture()
|
||||||
|
|
||||||
// If the value has changed, assign it to updates.
|
// If the value has changed, assign it to updates.
|
||||||
|
// todo: is this always going to be true?
|
||||||
if (initialValue !== finalValue) {
|
if (initialValue !== finalValue) {
|
||||||
didChange = true
|
didChange = true
|
||||||
updates[record.id] = [initialValue, finalValue]
|
updates[record.id] = [initialValue, finalValue]
|
||||||
|
|
Loading…
Reference in a new issue