@tldraw/tlschema 4.6.0-next.d8328a2dcc3d → 4.6.0-next.e390fde97eab
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cjs/assets/TLBaseAsset.js +4 -3
- package/dist-cjs/assets/TLBaseAsset.js.map +2 -2
- package/dist-cjs/assets/TLBookmarkAsset.js +9 -7
- package/dist-cjs/assets/TLBookmarkAsset.js.map +2 -2
- package/dist-cjs/assets/TLImageAsset.js +12 -10
- package/dist-cjs/assets/TLImageAsset.js.map +2 -2
- package/dist-cjs/assets/TLVideoAsset.js +11 -9
- package/dist-cjs/assets/TLVideoAsset.js.map +2 -2
- package/dist-cjs/createTLSchema.js +10 -4
- package/dist-cjs/createTLSchema.js.map +2 -2
- package/dist-cjs/index.d.ts +601 -343
- package/dist-cjs/index.js +17 -7
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/records/TLAsset.js +29 -14
- package/dist-cjs/records/TLAsset.js.map +2 -2
- package/dist-cjs/shapes/TLFrameShape.js +3 -1
- package/dist-cjs/shapes/TLFrameShape.js.map +2 -2
- package/dist-cjs/shapes/TLNoteShape.js +12 -2
- package/dist-cjs/shapes/TLNoteShape.js.map +2 -2
- package/dist-cjs/styles/StyleProp.js +38 -1
- package/dist-cjs/styles/StyleProp.js.map +2 -2
- package/dist-cjs/styles/TLColorStyle.js +36 -487
- package/dist-cjs/styles/TLColorStyle.js.map +2 -2
- package/dist-cjs/styles/TLDashStyle.js +1 -1
- package/dist-cjs/styles/TLDashStyle.js.map +2 -2
- package/dist-cjs/styles/TLFontFace.js +17 -0
- package/dist-cjs/styles/TLFontFace.js.map +7 -0
- package/dist-cjs/styles/TLFontStyle.js +36 -1
- package/dist-cjs/styles/TLFontStyle.js.map +2 -2
- package/dist-cjs/styles/TLTheme.js +17 -0
- package/dist-cjs/styles/TLTheme.js.map +7 -0
- package/dist-esm/assets/TLBaseAsset.mjs +4 -3
- package/dist-esm/assets/TLBaseAsset.mjs.map +2 -2
- package/dist-esm/assets/TLBookmarkAsset.mjs +9 -7
- package/dist-esm/assets/TLBookmarkAsset.mjs.map +2 -2
- package/dist-esm/assets/TLImageAsset.mjs +12 -10
- package/dist-esm/assets/TLImageAsset.mjs.map +2 -2
- package/dist-esm/assets/TLVideoAsset.mjs +11 -9
- package/dist-esm/assets/TLVideoAsset.mjs.map +2 -2
- package/dist-esm/createTLSchema.mjs +17 -8
- package/dist-esm/createTLSchema.mjs.map +2 -2
- package/dist-esm/index.d.mts +601 -343
- package/dist-esm/index.mjs +28 -14
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/records/TLAsset.mjs +29 -14
- package/dist-esm/records/TLAsset.mjs.map +2 -2
- package/dist-esm/shapes/TLFrameShape.mjs +3 -1
- package/dist-esm/shapes/TLFrameShape.mjs.map +2 -2
- package/dist-esm/shapes/TLNoteShape.mjs +12 -2
- package/dist-esm/shapes/TLNoteShape.mjs.map +2 -2
- package/dist-esm/styles/StyleProp.mjs +38 -1
- package/dist-esm/styles/StyleProp.mjs.map +2 -2
- package/dist-esm/styles/TLColorStyle.mjs +36 -487
- package/dist-esm/styles/TLColorStyle.mjs.map +2 -2
- package/dist-esm/styles/TLDashStyle.mjs +1 -1
- package/dist-esm/styles/TLDashStyle.mjs.map +2 -2
- package/dist-esm/styles/TLFontFace.mjs +1 -0
- package/dist-esm/styles/TLFontFace.mjs.map +7 -0
- package/dist-esm/styles/TLFontStyle.mjs +36 -1
- package/dist-esm/styles/TLFontStyle.mjs.map +2 -2
- package/dist-esm/styles/TLTheme.mjs +1 -0
- package/dist-esm/styles/TLTheme.mjs.map +7 -0
- package/package.json +5 -5
- package/src/assets/TLBaseAsset.ts +25 -28
- package/src/assets/TLBookmarkAsset.ts +13 -33
- package/src/assets/TLImageAsset.ts +16 -42
- package/src/assets/TLVideoAsset.ts +15 -40
- package/src/createTLSchema.ts +54 -15
- package/src/index.ts +31 -11
- package/src/migrations.test.ts +22 -0
- package/src/records/TLAsset.ts +139 -74
- package/src/shapes/TLFrameShape.ts +3 -1
- package/src/shapes/TLNoteShape.ts +19 -5
- package/src/styles/StyleProp.ts +42 -5
- package/src/styles/TLColorStyle.ts +55 -698
- package/src/styles/TLDashStyle.ts +1 -1
- package/src/styles/TLFontFace.ts +65 -0
- package/src/styles/TLFontStyle.ts +53 -4
- package/src/styles/TLTheme.ts +240 -0
|
@@ -9,8 +9,43 @@ const DefaultFontFamilies = {
|
|
|
9
9
|
serif: "'tldraw_serif', serif",
|
|
10
10
|
mono: "'tldraw_mono', monospace"
|
|
11
11
|
};
|
|
12
|
+
function isFontEntry(value) {
|
|
13
|
+
return typeof value === "object" && value !== null && "fontFamily" in value;
|
|
14
|
+
}
|
|
15
|
+
function registerFontsFromThemes(definitions) {
|
|
16
|
+
const fontNames = /* @__PURE__ */ new Set();
|
|
17
|
+
for (const def of Object.values(definitions)) {
|
|
18
|
+
if (!def.fonts) continue;
|
|
19
|
+
for (const [key, value] of Object.entries(def.fonts)) {
|
|
20
|
+
if (isFontEntry(value)) {
|
|
21
|
+
fontNames.add(key);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
const toAdd = [...fontNames].filter((v) => !DefaultFontStyle.values.includes(v));
|
|
26
|
+
if (toAdd.length > 0) {
|
|
27
|
+
DefaultFontStyle.addValues(...toAdd);
|
|
28
|
+
}
|
|
29
|
+
const toRemove = DefaultFontStyle.values.filter((v) => !fontNames.has(v));
|
|
30
|
+
if (toRemove.length > 0) {
|
|
31
|
+
DefaultFontStyle.removeValues(...toRemove);
|
|
32
|
+
}
|
|
33
|
+
if (process.env.NODE_ENV !== "production") {
|
|
34
|
+
for (const def of Object.values(definitions)) {
|
|
35
|
+
for (const font of fontNames) {
|
|
36
|
+
if (!def.fonts || !(font in def.fonts)) {
|
|
37
|
+
console.warn(
|
|
38
|
+
`Theme '${def.id}' is missing font '${font}'. Shapes using this font won't render correctly in this theme.`
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
12
45
|
export {
|
|
13
46
|
DefaultFontFamilies,
|
|
14
|
-
DefaultFontStyle
|
|
47
|
+
DefaultFontStyle,
|
|
48
|
+
isFontEntry,
|
|
49
|
+
registerFontsFromThemes
|
|
15
50
|
};
|
|
16
51
|
//# sourceMappingURL=TLFontStyle.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/styles/TLFontStyle.ts"],
|
|
4
|
-
"sourcesContent": ["import {
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import { StyleProp } from './StyleProp'\nimport { TLThemeFont, TLThemeFonts, TLThemes } from './TLTheme'\n\n/**\n * Default font style property used by tldraw shapes for text styling.\n * Controls which typeface is used for text content within shapes.\n *\n * Available values:\n * - `draw` - Hand-drawn, sketchy font style\n * - `sans` - Clean sans-serif font\n * - `serif` - Traditional serif font\n * - `mono` - Monospace font for code-like text\n *\n * @example\n * ```ts\n * import { DefaultFontStyle } from '@tldraw/tlschema'\n *\n * // Use in shape props definition\n * interface MyTextShapeProps {\n * font: typeof DefaultFontStyle\n * // other props...\n * }\n *\n * // Create a text shape with monospace font\n * const textShape = {\n * // ... other properties\n * props: {\n * font: 'mono' as const,\n * // ... other props\n * }\n * }\n * ```\n *\n * @public\n */\nexport const DefaultFontStyle = StyleProp.defineEnum('tldraw:font', {\n\tdefaultValue: 'draw',\n\tvalues: ['draw', 'sans', 'serif', 'mono'],\n})\n\n/**\n * The names of all available font styles, derived from {@link TLThemeFonts}.\n * Extend {@link TLThemeFonts} to add custom font names.\n *\n * @example\n * ```ts\n * import { TLDefaultFontStyle } from '@tldraw/tlschema'\n *\n * // Valid font style values\n * const drawFont: TLDefaultFontStyle = 'draw'\n * const sansFont: TLDefaultFontStyle = 'sans'\n * const serifFont: TLDefaultFontStyle = 'serif'\n * const monoFont: TLDefaultFontStyle = 'mono'\n *\n * // Use in a function parameter\n * function setTextFont(font: TLDefaultFontStyle) {\n * // Apply font style to text\n * }\n * ```\n *\n * @public\n */\nexport type TLDefaultFontStyle = keyof TLThemeFonts & string\n\n/**\n * Mapping of font style names to their corresponding CSS font-family declarations.\n * These are the actual CSS font families used when rendering text with each font style.\n *\n * @example\n * ```ts\n * import { DefaultFontFamilies, TLDefaultFontStyle } from '@tldraw/tlschema'\n *\n * // Get CSS font family for a font style\n * const fontStyle: TLDefaultFontStyle = 'mono'\n * const cssFamily = DefaultFontFamilies[fontStyle] // \"'tldraw_mono', monospace\"\n *\n * // Apply to DOM element\n * element.style.fontFamily = DefaultFontFamilies.sans\n * ```\n *\n * @public\n */\nexport const DefaultFontFamilies = {\n\tdraw: \"'tldraw_draw', sans-serif\",\n\tsans: \"'tldraw_sans', sans-serif\",\n\tserif: \"'tldraw_serif', serif\",\n\tmono: \"'tldraw_mono', monospace\",\n}\n\n/** @internal */\nexport function isFontEntry(value: unknown): value is TLThemeFont {\n\treturn typeof value === 'object' && value !== null && 'fontFamily' in value\n}\n\n/**\n * Scan theme definitions and sync font registrations to match.\n * A font entry is any key in `TLThemeFonts` whose value is a {@link TLThemeFont}\n * object (i.e. has a `fontFamily` property).\n *\n * Fonts present in themes but not yet registered will be added.\n * Fonts currently registered but absent from all themes will be removed.\n *\n * @public\n */\nexport function registerFontsFromThemes(definitions: TLThemes): void {\n\tconst fontNames = new Set<string>()\n\tfor (const def of Object.values(definitions)) {\n\t\tif (!def.fonts) continue\n\t\tfor (const [key, value] of Object.entries(def.fonts)) {\n\t\t\tif (isFontEntry(value)) {\n\t\t\t\tfontNames.add(key)\n\t\t\t}\n\t\t}\n\t}\n\n\tconst toAdd = [...fontNames].filter((v) => !DefaultFontStyle.values.includes(v as any))\n\tif (toAdd.length > 0) {\n\t\tDefaultFontStyle.addValues(...(toAdd as any))\n\t}\n\n\tconst toRemove = DefaultFontStyle.values.filter((v) => !fontNames.has(v as string))\n\tif (toRemove.length > 0) {\n\t\tDefaultFontStyle.removeValues(...toRemove)\n\t}\n\n\tif (process.env.NODE_ENV !== 'production') {\n\t\tfor (const def of Object.values(definitions)) {\n\t\t\tfor (const font of fontNames) {\n\t\t\t\tif (!def.fonts || !(font in def.fonts)) {\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`Theme '${def.id}' is missing font '${font}'. Shapes using this font won't render correctly in this theme.`\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,iBAAiB;AAmCnB,MAAM,mBAAmB,UAAU,WAAW,eAAe;AAAA,EACnE,cAAc;AAAA,EACd,QAAQ,CAAC,QAAQ,QAAQ,SAAS,MAAM;AACzC,CAAC;AA4CM,MAAM,sBAAsB;AAAA,EAClC,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AACP;AAGO,SAAS,YAAY,OAAsC;AACjE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,gBAAgB;AACvE;AAYO,SAAS,wBAAwB,aAA6B;AACpE,QAAM,YAAY,oBAAI,IAAY;AAClC,aAAW,OAAO,OAAO,OAAO,WAAW,GAAG;AAC7C,QAAI,CAAC,IAAI,MAAO;AAChB,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,KAAK,GAAG;AACrD,UAAI,YAAY,KAAK,GAAG;AACvB,kBAAU,IAAI,GAAG;AAAA,MAClB;AAAA,IACD;AAAA,EACD;AAEA,QAAM,QAAQ,CAAC,GAAG,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,iBAAiB,OAAO,SAAS,CAAQ,CAAC;AACtF,MAAI,MAAM,SAAS,GAAG;AACrB,qBAAiB,UAAU,GAAI,KAAa;AAAA,EAC7C;AAEA,QAAM,WAAW,iBAAiB,OAAO,OAAO,CAAC,MAAM,CAAC,UAAU,IAAI,CAAW,CAAC;AAClF,MAAI,SAAS,SAAS,GAAG;AACxB,qBAAiB,aAAa,GAAG,QAAQ;AAAA,EAC1C;AAEA,MAAI,QAAQ,IAAI,aAAa,cAAc;AAC1C,eAAW,OAAO,OAAO,OAAO,WAAW,GAAG;AAC7C,iBAAW,QAAQ,WAAW;AAC7B,YAAI,CAAC,IAAI,SAAS,EAAE,QAAQ,IAAI,QAAQ;AACvC,kBAAQ;AAAA,YACP,UAAU,IAAI,EAAE,sBAAsB,IAAI;AAAA,UAC3C;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,EACD;AACD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=TLTheme.mjs.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tldraw/tlschema",
|
|
3
3
|
"description": "tldraw infinite canvas SDK (schema).",
|
|
4
|
-
"version": "4.6.0-next.
|
|
4
|
+
"version": "4.6.0-next.e390fde97eab",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "tldraw Inc.",
|
|
7
7
|
"email": "hello@tldraw.com"
|
|
@@ -50,10 +50,10 @@
|
|
|
50
50
|
"vitest": "^3.2.4"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@tldraw/state": "4.6.0-next.
|
|
54
|
-
"@tldraw/store": "4.6.0-next.
|
|
55
|
-
"@tldraw/utils": "4.6.0-next.
|
|
56
|
-
"@tldraw/validate": "4.6.0-next.
|
|
53
|
+
"@tldraw/state": "4.6.0-next.e390fde97eab",
|
|
54
|
+
"@tldraw/store": "4.6.0-next.e390fde97eab",
|
|
55
|
+
"@tldraw/utils": "4.6.0-next.e390fde97eab",
|
|
56
|
+
"@tldraw/validate": "4.6.0-next.e390fde97eab"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
59
|
"react": "^18.2.0 || ^19.2.1",
|
|
@@ -68,7 +68,8 @@ export const assetIdValidator = idValidator<TLAssetId>('asset')
|
|
|
68
68
|
* base properties (id, typeName, type, meta) and the type-specific props.
|
|
69
69
|
*
|
|
70
70
|
* @param type - The asset type identifier (e.g., 'image', 'video', 'bookmark')
|
|
71
|
-
* @param props -
|
|
71
|
+
* @param props - A validator or per-key validator record for the asset's type-specific properties
|
|
72
|
+
* @param meta - An optional per-key validator record for the asset's meta properties
|
|
72
73
|
* @returns A complete validator for the asset record type
|
|
73
74
|
*
|
|
74
75
|
* @example
|
|
@@ -83,45 +84,41 @@ export const assetIdValidator = idValidator<TLAssetId>('asset')
|
|
|
83
84
|
* description?: string
|
|
84
85
|
* }>
|
|
85
86
|
*
|
|
86
|
-
* // Create validator
|
|
87
|
-
* const customAssetValidator = createAssetValidator('custom',
|
|
87
|
+
* // Create validator using a per-key record (recommended)
|
|
88
|
+
* const customAssetValidator = createAssetValidator('custom', {
|
|
88
89
|
* url: T.string,
|
|
89
90
|
* title: T.string,
|
|
90
91
|
* description: T.string.optional()
|
|
91
|
-
* })
|
|
92
|
-
*
|
|
93
|
-
* // Use the validator
|
|
94
|
-
* const assetData = {
|
|
95
|
-
* id: 'asset:custom123',
|
|
96
|
-
* typeName: 'asset' as const,
|
|
97
|
-
* type: 'custom' as const,
|
|
98
|
-
* props: {
|
|
99
|
-
* url: 'https://example.com',
|
|
100
|
-
* title: 'My Custom Asset'
|
|
101
|
-
* },
|
|
102
|
-
* meta: {}
|
|
103
|
-
* }
|
|
92
|
+
* })
|
|
104
93
|
*
|
|
105
|
-
*
|
|
94
|
+
* // Or using a T.object validator
|
|
95
|
+
* const customAssetValidator2 = createAssetValidator('custom', T.object({
|
|
96
|
+
* url: T.string,
|
|
97
|
+
* title: T.string,
|
|
98
|
+
* description: T.string.optional()
|
|
99
|
+
* }))
|
|
106
100
|
* ```
|
|
107
101
|
*
|
|
108
102
|
* @public
|
|
109
103
|
*/
|
|
110
|
-
export function createAssetValidator<
|
|
104
|
+
export function createAssetValidator<
|
|
105
|
+
Type extends string,
|
|
106
|
+
Props extends JsonObject,
|
|
107
|
+
Meta extends JsonObject = JsonObject,
|
|
108
|
+
>(
|
|
111
109
|
type: Type,
|
|
112
|
-
props
|
|
110
|
+
props?: T.Validator<Props> | { [K in keyof Props]: T.Validatable<Props[K]> },
|
|
111
|
+
meta?: { [K in keyof Meta]: T.Validatable<Meta[K]> }
|
|
113
112
|
) {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
meta: JsonObject
|
|
120
|
-
}>({
|
|
113
|
+
// Determine if props is a Validator instance or a per-key record
|
|
114
|
+
const propsValidator =
|
|
115
|
+
props instanceof T.Validator ? props : props ? T.object(props) : (T.jsonValue as any)
|
|
116
|
+
|
|
117
|
+
return T.object<TLBaseAsset<Type, Props>>({
|
|
121
118
|
id: assetIdValidator,
|
|
122
119
|
typeName: T.literal('asset'),
|
|
123
120
|
type: T.literal(type),
|
|
124
|
-
props,
|
|
125
|
-
meta: T.jsonValue as T.ObjectValidator<JsonObject
|
|
121
|
+
props: propsValidator,
|
|
122
|
+
meta: meta ? T.object(meta) : (T.jsonValue as T.ObjectValidator<JsonObject>),
|
|
126
123
|
})
|
|
127
124
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createMigrationIds, createRecordMigrationSequence } from '@tldraw/store'
|
|
2
2
|
import { T } from '@tldraw/validate'
|
|
3
|
-
import {
|
|
3
|
+
import { RecordProps } from '../recordsWithProps'
|
|
4
4
|
import { TLBaseAsset, createAssetValidator } from './TLBaseAsset'
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -18,39 +18,19 @@ export type TLBookmarkAsset = TLBaseAsset<
|
|
|
18
18
|
}
|
|
19
19
|
>
|
|
20
20
|
|
|
21
|
-
/**
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
* props: {
|
|
32
|
-
* title: 'Example Website',
|
|
33
|
-
* description: 'A great example site',
|
|
34
|
-
* image: 'https://example.com/preview.jpg',
|
|
35
|
-
* favicon: 'https://example.com/favicon.ico',
|
|
36
|
-
* src: 'https://example.com'
|
|
37
|
-
* }
|
|
38
|
-
* }
|
|
39
|
-
*
|
|
40
|
-
* const isValid = bookmarkAssetValidator.isValid(bookmarkData)
|
|
41
|
-
* ```
|
|
42
|
-
*
|
|
43
|
-
* @public
|
|
44
|
-
*/
|
|
21
|
+
/** @public */
|
|
22
|
+
export const bookmarkAssetProps = {
|
|
23
|
+
title: T.string,
|
|
24
|
+
description: T.string,
|
|
25
|
+
image: T.string,
|
|
26
|
+
favicon: T.string,
|
|
27
|
+
src: T.srcUrl.nullable(),
|
|
28
|
+
} satisfies RecordProps<TLBookmarkAsset>
|
|
29
|
+
|
|
30
|
+
/** Validator for bookmark assets. @public */
|
|
45
31
|
export const bookmarkAssetValidator: T.Validator<TLBookmarkAsset> = createAssetValidator(
|
|
46
32
|
'bookmark',
|
|
47
|
-
T.object(
|
|
48
|
-
title: T.string,
|
|
49
|
-
description: T.string,
|
|
50
|
-
image: T.string,
|
|
51
|
-
favicon: T.string,
|
|
52
|
-
src: T.srcUrl.nullable(),
|
|
53
|
-
})
|
|
33
|
+
T.object(bookmarkAssetProps)
|
|
54
34
|
)
|
|
55
35
|
|
|
56
36
|
const Versions = createMigrationIds('com.tldraw.asset.bookmark', {
|
|
@@ -91,7 +71,7 @@ export { Versions as bookmarkAssetVersions }
|
|
|
91
71
|
export const bookmarkAssetMigrations = createRecordMigrationSequence({
|
|
92
72
|
sequenceId: 'com.tldraw.asset.bookmark',
|
|
93
73
|
recordType: 'asset',
|
|
94
|
-
filter: (asset) => (asset as
|
|
74
|
+
filter: (asset) => (asset as TLBookmarkAsset).type === 'bookmark',
|
|
95
75
|
sequence: [
|
|
96
76
|
{
|
|
97
77
|
id: Versions.MakeUrlsValid,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createMigrationIds, createRecordMigrationSequence } from '@tldraw/store'
|
|
2
2
|
import { T } from '@tldraw/validate'
|
|
3
|
-
import {
|
|
3
|
+
import { RecordProps } from '../recordsWithProps'
|
|
4
4
|
import { TLBaseAsset, createAssetValidator } from './TLBaseAsset'
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -21,48 +21,22 @@ export type TLImageAsset = TLBaseAsset<
|
|
|
21
21
|
}
|
|
22
22
|
>
|
|
23
23
|
|
|
24
|
-
/**
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
* w: 800,
|
|
38
|
-
* h: 600,
|
|
39
|
-
* name: 'photo.jpg',
|
|
40
|
-
* isAnimated: false,
|
|
41
|
-
* mimeType: 'image/jpeg',
|
|
42
|
-
* src: 'https://example.com/photo.jpg',
|
|
43
|
-
* fileSize: 156000
|
|
44
|
-
* },
|
|
45
|
-
* meta: {}
|
|
46
|
-
* }
|
|
47
|
-
*
|
|
48
|
-
* // Validate the asset
|
|
49
|
-
* const isValid = imageAssetValidator.validate(imageAsset)
|
|
50
|
-
* ```
|
|
51
|
-
*
|
|
52
|
-
* @public
|
|
53
|
-
*/
|
|
24
|
+
/** @public */
|
|
25
|
+
export const imageAssetProps = {
|
|
26
|
+
w: T.number,
|
|
27
|
+
h: T.number,
|
|
28
|
+
name: T.string,
|
|
29
|
+
isAnimated: T.boolean,
|
|
30
|
+
mimeType: T.string.nullable(),
|
|
31
|
+
src: T.srcUrl.nullable(),
|
|
32
|
+
fileSize: T.nonZeroNumber.optional(),
|
|
33
|
+
pixelRatio: T.positiveNumber.optional(),
|
|
34
|
+
} satisfies RecordProps<TLImageAsset>
|
|
35
|
+
|
|
36
|
+
/** Validator for image assets. @public */
|
|
54
37
|
export const imageAssetValidator: T.Validator<TLImageAsset> = createAssetValidator(
|
|
55
38
|
'image',
|
|
56
|
-
T.object(
|
|
57
|
-
w: T.number,
|
|
58
|
-
h: T.number,
|
|
59
|
-
name: T.string,
|
|
60
|
-
isAnimated: T.boolean,
|
|
61
|
-
mimeType: T.string.nullable(),
|
|
62
|
-
src: T.srcUrl.nullable(),
|
|
63
|
-
fileSize: T.nonZeroNumber.optional(),
|
|
64
|
-
pixelRatio: T.positiveNumber.optional(),
|
|
65
|
-
})
|
|
39
|
+
T.object(imageAssetProps)
|
|
66
40
|
)
|
|
67
41
|
|
|
68
42
|
const Versions = createMigrationIds('com.tldraw.asset.image', {
|
|
@@ -109,7 +83,7 @@ export { Versions as imageAssetVersions }
|
|
|
109
83
|
export const imageAssetMigrations = createRecordMigrationSequence({
|
|
110
84
|
sequenceId: 'com.tldraw.asset.image',
|
|
111
85
|
recordType: 'asset',
|
|
112
|
-
filter: (asset) => (asset as
|
|
86
|
+
filter: (asset) => (asset as TLImageAsset).type === 'image',
|
|
113
87
|
sequence: [
|
|
114
88
|
{
|
|
115
89
|
id: Versions.AddIsAnimated,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createMigrationIds, createRecordMigrationSequence } from '@tldraw/store'
|
|
2
2
|
import { T } from '@tldraw/validate'
|
|
3
|
-
import {
|
|
3
|
+
import { RecordProps } from '../recordsWithProps'
|
|
4
4
|
import { TLBaseAsset, createAssetValidator } from './TLBaseAsset'
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -52,46 +52,21 @@ export type TLVideoAsset = TLBaseAsset<
|
|
|
52
52
|
}
|
|
53
53
|
>
|
|
54
54
|
|
|
55
|
-
/**
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
* typeName: 'asset',
|
|
68
|
-
* type: 'video',
|
|
69
|
-
* props: {
|
|
70
|
-
* w: 1920,
|
|
71
|
-
* h: 1080,
|
|
72
|
-
* name: 'video.mp4',
|
|
73
|
-
* isAnimated: true,
|
|
74
|
-
* mimeType: 'video/mp4',
|
|
75
|
-
* src: 'https://example.com/video.mp4',
|
|
76
|
-
* fileSize: 1024000
|
|
77
|
-
* },
|
|
78
|
-
* meta: {}
|
|
79
|
-
* })
|
|
80
|
-
* ```
|
|
81
|
-
*
|
|
82
|
-
* @public
|
|
83
|
-
*/
|
|
55
|
+
/** @public */
|
|
56
|
+
export const videoAssetProps = {
|
|
57
|
+
w: T.number,
|
|
58
|
+
h: T.number,
|
|
59
|
+
name: T.string,
|
|
60
|
+
isAnimated: T.boolean,
|
|
61
|
+
mimeType: T.string.nullable(),
|
|
62
|
+
src: T.srcUrl.nullable(),
|
|
63
|
+
fileSize: T.number.optional(),
|
|
64
|
+
} satisfies RecordProps<TLVideoAsset>
|
|
65
|
+
|
|
66
|
+
/** Validator for video assets. @public */
|
|
84
67
|
export const videoAssetValidator: T.Validator<TLVideoAsset> = createAssetValidator(
|
|
85
68
|
'video',
|
|
86
|
-
T.object(
|
|
87
|
-
w: T.number,
|
|
88
|
-
h: T.number,
|
|
89
|
-
name: T.string,
|
|
90
|
-
isAnimated: T.boolean,
|
|
91
|
-
mimeType: T.string.nullable(),
|
|
92
|
-
src: T.srcUrl.nullable(),
|
|
93
|
-
fileSize: T.number.optional(),
|
|
94
|
-
})
|
|
69
|
+
T.object(videoAssetProps)
|
|
95
70
|
)
|
|
96
71
|
|
|
97
72
|
const Versions = createMigrationIds('com.tldraw.asset.video', {
|
|
@@ -137,7 +112,7 @@ export { Versions as videoAssetVersions }
|
|
|
137
112
|
export const videoAssetMigrations = createRecordMigrationSequence({
|
|
138
113
|
sequenceId: 'com.tldraw.asset.video',
|
|
139
114
|
recordType: 'asset',
|
|
140
|
-
filter: (asset) => (asset as
|
|
115
|
+
filter: (asset) => (asset as TLVideoAsset).type === 'video',
|
|
141
116
|
sequence: [
|
|
142
117
|
{
|
|
143
118
|
id: Versions.AddIsAnimated,
|
package/src/createTLSchema.ts
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import { LegacyMigrations, MigrationSequence, StoreSchema, StoreValidator } from '@tldraw/store'
|
|
2
2
|
import { objectMapValues } from '@tldraw/utils'
|
|
3
3
|
import { T } from '@tldraw/validate'
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { TLBaseAsset } from './assets/TLBaseAsset'
|
|
5
|
+
import { bookmarkAssetMigrations, bookmarkAssetProps } from './assets/TLBookmarkAsset'
|
|
6
|
+
import { imageAssetMigrations, imageAssetProps } from './assets/TLImageAsset'
|
|
7
|
+
import { videoAssetMigrations, videoAssetProps } from './assets/TLVideoAsset'
|
|
7
8
|
import { arrowBindingMigrations, arrowBindingProps } from './bindings/TLArrowBinding'
|
|
8
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
TLDefaultAsset,
|
|
11
|
+
TLUnknownAsset,
|
|
12
|
+
assetMigrations,
|
|
13
|
+
createAssetRecordType,
|
|
14
|
+
} from './records/TLAsset'
|
|
9
15
|
import { TLBinding, TLDefaultBinding, createBindingRecordType } from './records/TLBinding'
|
|
10
16
|
import { CameraRecordType, cameraMigrations } from './records/TLCamera'
|
|
11
17
|
import {
|
|
@@ -48,7 +54,7 @@ import { StyleProp } from './styles/StyleProp'
|
|
|
48
54
|
import { TLStoreProps, createIntegrityChecker, onValidationFailure } from './TLStore'
|
|
49
55
|
|
|
50
56
|
/**
|
|
51
|
-
* Configuration information for a schema type (shape or
|
|
57
|
+
* Configuration information for a schema type (shape, binding, or asset), including its properties,
|
|
52
58
|
* metadata, and migration sequences for data evolution over time.
|
|
53
59
|
*
|
|
54
60
|
* @public
|
|
@@ -73,12 +79,12 @@ export interface SchemaPropsInfo {
|
|
|
73
79
|
migrations?: LegacyMigrations | TLPropsMigrations | MigrationSequence
|
|
74
80
|
|
|
75
81
|
/**
|
|
76
|
-
* Validation schema for the shape or
|
|
82
|
+
* Validation schema for the shape, binding, or asset properties.
|
|
77
83
|
*/
|
|
78
84
|
props?: Record<string, StoreValidator<any>>
|
|
79
85
|
|
|
80
86
|
/**
|
|
81
|
-
* Validation schema for metadata fields.
|
|
87
|
+
* Validation schema for metadata fields.
|
|
82
88
|
*/
|
|
83
89
|
meta?: Record<string, StoreValidator<any>>
|
|
84
90
|
}
|
|
@@ -195,6 +201,30 @@ export const defaultBindingSchemas = {
|
|
|
195
201
|
arrow: { migrations: arrowBindingMigrations, props: arrowBindingProps },
|
|
196
202
|
} satisfies { [T in TLDefaultBinding['type']]: SchemaPropsInfo }
|
|
197
203
|
|
|
204
|
+
/**
|
|
205
|
+
* Default asset schema configurations for all built-in tldraw asset types.
|
|
206
|
+
*
|
|
207
|
+
* @public
|
|
208
|
+
* @example
|
|
209
|
+
* ```ts
|
|
210
|
+
* import { createTLSchema, defaultAssetSchemas } from '@tldraw/tlschema'
|
|
211
|
+
*
|
|
212
|
+
* const schema = createTLSchema({
|
|
213
|
+
* assets: defaultAssetSchemas,
|
|
214
|
+
* })
|
|
215
|
+
* ```
|
|
216
|
+
*/
|
|
217
|
+
export const defaultAssetSchemas = {
|
|
218
|
+
image: { migrations: imageAssetMigrations, props: imageAssetProps },
|
|
219
|
+
video: { migrations: videoAssetMigrations, props: videoAssetProps },
|
|
220
|
+
bookmark: { migrations: bookmarkAssetMigrations, props: bookmarkAssetProps },
|
|
221
|
+
} satisfies {
|
|
222
|
+
[T in TLDefaultAsset['type']]: {
|
|
223
|
+
migrations: SchemaPropsInfo['migrations']
|
|
224
|
+
props: RecordProps<TLBaseAsset<T, Extract<TLDefaultAsset, { type: T }>['props']>>
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
198
228
|
/**
|
|
199
229
|
* Configuration for extending the user record type with custom metadata
|
|
200
230
|
* validators and migration sequences.
|
|
@@ -232,12 +262,13 @@ export interface UserSchemaInfo {
|
|
|
232
262
|
* validation, and migration sequences for all record types in a tldraw application.
|
|
233
263
|
*
|
|
234
264
|
* The schema includes all core record types (pages, cameras, instances, etc.) plus the
|
|
235
|
-
* shape, binding, and custom record types you specify. Style properties are
|
|
236
|
-
* collected from all shapes to ensure consistency across the application.
|
|
265
|
+
* shape, binding, asset, and custom record types you specify. Style properties are
|
|
266
|
+
* automatically collected from all shapes to ensure consistency across the application.
|
|
237
267
|
*
|
|
238
268
|
* @param options - Configuration options for the schema
|
|
239
269
|
* - shapes - Shape schema configurations. Defaults to defaultShapeSchemas if not provided
|
|
240
270
|
* - bindings - Binding schema configurations. Defaults to defaultBindingSchemas if not provided
|
|
271
|
+
* - assets - Asset schema configurations. Defaults to defaultAssetSchemas if not provided
|
|
241
272
|
* - user - Custom user record configuration with meta validators and migrations
|
|
242
273
|
* - records - Custom record type configurations. These are additional record types beyond
|
|
243
274
|
* the built-in shapes, bindings, assets, etc.
|
|
@@ -247,10 +278,15 @@ export interface UserSchemaInfo {
|
|
|
247
278
|
* @public
|
|
248
279
|
* @example
|
|
249
280
|
* ```ts
|
|
250
|
-
* import {
|
|
281
|
+
* import {
|
|
282
|
+
* createTLSchema,
|
|
283
|
+
* defaultShapeSchemas,
|
|
284
|
+
* defaultBindingSchemas,
|
|
285
|
+
* defaultAssetSchemas,
|
|
286
|
+
* } from '@tldraw/tlschema'
|
|
251
287
|
* import { Store } from '@tldraw/store'
|
|
252
288
|
*
|
|
253
|
-
* // Create schema with all default shapes and
|
|
289
|
+
* // Create schema with all default shapes, bindings, and assets
|
|
254
290
|
* const schema = createTLSchema()
|
|
255
291
|
*
|
|
256
292
|
* // Create schema with custom shapes added
|
|
@@ -262,6 +298,8 @@ export interface UserSchemaInfo {
|
|
|
262
298
|
* migrations: myCustomShapeMigrations,
|
|
263
299
|
* },
|
|
264
300
|
* },
|
|
301
|
+
* bindings: defaultBindingSchemas,
|
|
302
|
+
* assets: defaultAssetSchemas,
|
|
265
303
|
* })
|
|
266
304
|
*
|
|
267
305
|
* // Create schema with custom user metadata
|
|
@@ -301,12 +339,14 @@ export interface UserSchemaInfo {
|
|
|
301
339
|
export function createTLSchema({
|
|
302
340
|
shapes = defaultShapeSchemas,
|
|
303
341
|
bindings = defaultBindingSchemas,
|
|
342
|
+
assets = defaultAssetSchemas,
|
|
304
343
|
user,
|
|
305
344
|
records = {},
|
|
306
345
|
migrations,
|
|
307
346
|
}: {
|
|
308
347
|
shapes?: Record<string, SchemaPropsInfo>
|
|
309
348
|
bindings?: Record<string, SchemaPropsInfo>
|
|
349
|
+
assets?: Record<string, SchemaPropsInfo>
|
|
310
350
|
user?: UserSchemaInfo
|
|
311
351
|
records?: Record<string, CustomRecordInfo>
|
|
312
352
|
migrations?: readonly MigrationSequence[]
|
|
@@ -323,6 +363,7 @@ export function createTLSchema({
|
|
|
323
363
|
|
|
324
364
|
const ShapeRecordType = createShapeRecordType(shapes)
|
|
325
365
|
const BindingRecordType = createBindingRecordType(bindings)
|
|
366
|
+
const _AssetRecordType = createAssetRecordType(assets)
|
|
326
367
|
const InstanceRecordType = createInstanceRecordType(stylesById)
|
|
327
368
|
const CustomUserRecordType = user ? createUserRecordType(user) : UserRecordType
|
|
328
369
|
|
|
@@ -353,7 +394,7 @@ export function createTLSchema({
|
|
|
353
394
|
|
|
354
395
|
return StoreSchema.create(
|
|
355
396
|
{
|
|
356
|
-
asset:
|
|
397
|
+
asset: _AssetRecordType,
|
|
357
398
|
binding: BindingRecordType,
|
|
358
399
|
camera: CameraRecordType,
|
|
359
400
|
document: DocumentRecordType,
|
|
@@ -380,10 +421,8 @@ export function createTLSchema({
|
|
|
380
421
|
rootShapeMigrations,
|
|
381
422
|
|
|
382
423
|
userMigrations,
|
|
383
|
-
bookmarkAssetMigrations,
|
|
384
|
-
imageAssetMigrations,
|
|
385
|
-
videoAssetMigrations,
|
|
386
424
|
|
|
425
|
+
...processPropsMigrations<TLUnknownAsset>('asset', assets),
|
|
387
426
|
...processPropsMigrations<TLShape>('shape', shapes),
|
|
388
427
|
...processPropsMigrations<TLBinding>('binding', bindings),
|
|
389
428
|
...processCustomRecordMigrations(records),
|
package/src/index.ts
CHANGED
|
@@ -32,9 +32,13 @@
|
|
|
32
32
|
|
|
33
33
|
import { registerTldrawLibraryVersion } from '@tldraw/utils'
|
|
34
34
|
export { assetIdValidator, createAssetValidator, type TLBaseAsset } from './assets/TLBaseAsset'
|
|
35
|
-
export {
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
export {
|
|
36
|
+
bookmarkAssetMigrations,
|
|
37
|
+
bookmarkAssetProps,
|
|
38
|
+
type TLBookmarkAsset,
|
|
39
|
+
} from './assets/TLBookmarkAsset'
|
|
40
|
+
export { imageAssetMigrations, imageAssetProps, type TLImageAsset } from './assets/TLImageAsset'
|
|
41
|
+
export { videoAssetMigrations, videoAssetProps, type TLVideoAsset } from './assets/TLVideoAsset'
|
|
38
42
|
export {
|
|
39
43
|
arrowBindingMigrations,
|
|
40
44
|
arrowBindingProps,
|
|
@@ -56,6 +60,7 @@ export {
|
|
|
56
60
|
} from './createPresenceStateDerivation'
|
|
57
61
|
export {
|
|
58
62
|
createTLSchema,
|
|
63
|
+
defaultAssetSchemas,
|
|
59
64
|
defaultBindingSchemas,
|
|
60
65
|
defaultShapeSchemas,
|
|
61
66
|
type SchemaPropsInfo,
|
|
@@ -82,11 +87,17 @@ export { scribbleValidator, TL_SCRIBBLE_STATES, type TLScribble } from './misc/T
|
|
|
82
87
|
export {
|
|
83
88
|
assetMigrations,
|
|
84
89
|
AssetRecordType,
|
|
85
|
-
|
|
90
|
+
createAssetPropsMigrationIds,
|
|
91
|
+
createAssetPropsMigrationSequence,
|
|
92
|
+
createAssetRecordType,
|
|
86
93
|
type TLAsset,
|
|
87
94
|
type TLAssetId,
|
|
88
95
|
type TLAssetPartial,
|
|
89
96
|
type TLAssetShape,
|
|
97
|
+
type TLDefaultAsset,
|
|
98
|
+
type TLGlobalAssetPropsMap,
|
|
99
|
+
type TLIndexedAssets,
|
|
100
|
+
type TLUnknownAsset,
|
|
90
101
|
} from './records/TLAsset'
|
|
91
102
|
export {
|
|
92
103
|
createBindingId,
|
|
@@ -290,21 +301,18 @@ export {
|
|
|
290
301
|
} from './shapes/TLVideoShape'
|
|
291
302
|
export { EnumStyleProp, StyleProp, type StylePropValue } from './styles/StyleProp'
|
|
292
303
|
export {
|
|
293
|
-
defaultColorNames,
|
|
294
304
|
DefaultColorStyle,
|
|
295
|
-
|
|
296
|
-
DefaultLabelColorStyle,
|
|
297
|
-
getColorValue,
|
|
298
|
-
getDefaultColorTheme,
|
|
305
|
+
registerColorsFromThemes,
|
|
299
306
|
type TLDefaultColorStyle,
|
|
300
|
-
type TLDefaultColorTheme,
|
|
301
|
-
type TLDefaultColorThemeColor,
|
|
302
307
|
} from './styles/TLColorStyle'
|
|
303
308
|
export { DefaultDashStyle, type TLDefaultDashStyle } from './styles/TLDashStyle'
|
|
304
309
|
export { DefaultFillStyle, type TLDefaultFillStyle } from './styles/TLFillStyle'
|
|
310
|
+
export { type TLFontFace, type TLFontFaceSource } from './styles/TLFontFace'
|
|
305
311
|
export {
|
|
306
312
|
DefaultFontFamilies,
|
|
307
313
|
DefaultFontStyle,
|
|
314
|
+
isFontEntry,
|
|
315
|
+
registerFontsFromThemes,
|
|
308
316
|
type TLDefaultFontStyle,
|
|
309
317
|
} from './styles/TLFontStyle'
|
|
310
318
|
export {
|
|
@@ -313,6 +321,18 @@ export {
|
|
|
313
321
|
} from './styles/TLHorizontalAlignStyle'
|
|
314
322
|
export { DefaultSizeStyle, type TLDefaultSizeStyle } from './styles/TLSizeStyle'
|
|
315
323
|
export { DefaultTextAlignStyle, type TLDefaultTextAlignStyle } from './styles/TLTextAlignStyle'
|
|
324
|
+
export {
|
|
325
|
+
type TLDefaultColor,
|
|
326
|
+
type TLRemovedDefaultThemeColors,
|
|
327
|
+
type TLTheme,
|
|
328
|
+
type TLThemeColors,
|
|
329
|
+
type TLThemeDefaultColors,
|
|
330
|
+
type TLThemeFont,
|
|
331
|
+
type TLThemeFonts,
|
|
332
|
+
type TLThemeId,
|
|
333
|
+
type TLThemes,
|
|
334
|
+
type TLThemeUiColorKeys,
|
|
335
|
+
} from './styles/TLTheme'
|
|
316
336
|
export {
|
|
317
337
|
DefaultVerticalAlignStyle,
|
|
318
338
|
type TLDefaultVerticalAlignStyle,
|