[feature] add meta
property to records (#1627)
This PR adds a `meta` property to shapes and other records. It adds it to: - asset - camera - document - instance - instancePageState - instancePresence - page - pointer - rootShape ## Setting meta This data can generally be added wherever you would normally update the corresponding record. An exception exists for shapes, which can be updated using a partial of the `meta` in the same way that we update shapes with a partial of `props`. ```ts this.updateShapes([{ id: myShape.id, type: "geo", meta: { nemesis: "steve", special: true } ]) ``` ## `Editor.getInitialMetaForShape` The `Editor.getInitialMetaForShape` method is kind of a hack to set the initial meta property for newly created shapes. You can set it externally. Escape hatch! ### Change Type - [x] `minor` — New feature ### Test Plan todo - [ ] Unit Tests (todo) ### Release Notes - todo
This commit is contained in:
parent
3e07f70440
commit
fd29006538
39 changed files with 594 additions and 95 deletions
49
apps/examples/src/17-shape-meta/ShapeMetaExample.tsx
Normal file
49
apps/examples/src/17-shape-meta/ShapeMetaExample.tsx
Normal file
|
@ -0,0 +1,49 @@
|
|||
import { TLShape, Tldraw, track, useEditor } from '@tldraw/tldraw'
|
||||
import '@tldraw/tldraw/tldraw.css'
|
||||
|
||||
export default function ShapeMetaExample() {
|
||||
return (
|
||||
<div className="tldraw__editor">
|
||||
<Tldraw
|
||||
persistenceKey="shape_meta_example"
|
||||
autoFocus
|
||||
onMount={(editor) => {
|
||||
editor.getInitialMetaForShape = (shape) => {
|
||||
return { label: `My ${shape.type} shape` }
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ShapeLabelUiWithHelper />
|
||||
</Tldraw>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// By default, the TLShape type's meta property is { [key: string]: any }, but we can type it
|
||||
// by unioning the type with a new type that has a meta property of our choosing.
|
||||
type ShapeWithMyMeta = TLShape & { meta: { label: string } }
|
||||
|
||||
export const ShapeLabelUiWithHelper = track(function ShapeLabelUiWithHelper() {
|
||||
const editor = useEditor()
|
||||
const onlySelectedShape = editor.onlySelectedShape as ShapeWithMyMeta | null
|
||||
|
||||
if (!onlySelectedShape) {
|
||||
return null
|
||||
}
|
||||
|
||||
function onChange(e: React.ChangeEvent<HTMLInputElement>) {
|
||||
if (onlySelectedShape) {
|
||||
const { id, type, meta } = onlySelectedShape
|
||||
|
||||
editor.updateShapes<ShapeWithMyMeta>([
|
||||
{ id, type, meta: { ...meta, label: e.currentTarget.value } },
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ position: 'absolute', zIndex: 300, top: 64, left: 12 }}>
|
||||
shape label: <input value={onlySelectedShape.meta.label} onChange={onChange} />
|
||||
</div>
|
||||
)
|
||||
})
|
Loading…
Add table
Add a link
Reference in a new issue