From bfc8b6a9014fb0e7e84561bb685a3e6d73c61414 Mon Sep 17 00:00:00 2001 From: alex Date: Wed, 24 Apr 2024 15:36:08 +0100 Subject: [PATCH] fix migration exports (#3586) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We're missing the export for `createShapePropsMigrationIds`, so lets add it. This also fixes some other bits that were used in examples but not exported properly from tldraw. ### Change Type - [x] `sdk` — Changes the tldraw SDK - [x] `bugfix` — Bug fix ### Release Notes - Expose `createShapePropsMigrationIds`, `defaultEditorAssetUrls`, `PORTRAIT_BREAKPOINT`, `useDefaultColorTheme`, & `getPerfectDashProps` --- .eslintrc.js | 3 +- apps/dotcom/src/utils/assetUrls.ts | 1 - .../CardShape/card-shape-migrations.ts | 3 +- .../src/examples/exploded/ExplodedExample.tsx | 2 +- .../image-annotator/ImageAnnotationEditor.tsx | 2 +- .../src/examples/pdf-editor/PdfEditor.tsx | 2 +- .../ShapeWithMigrationsExample.tsx | 140 +++--- .../ShapeWithTldrawStylesExample.tsx | 2 +- .../src/examples/slides/SlideShapeUtil.tsx | 2 +- .../SpeechBubble/SpeechBubbleUtil.tsx | 2 +- apps/examples/src/misc/EndToEndApi.tsx | 2 +- apps/vscode/editor/src/app.tsx | 4 +- packages/tldraw/api-report.md | 62 +++ packages/tldraw/api/api.json | 475 +++++++++++++++++- packages/tldraw/src/index.ts | 10 +- .../src/lib/shapes/shared/ShapeFill.tsx | 1 + .../lib/shapes/shared/getPerfectDashProps.ts | 1 + packages/tldraw/src/lib/ui/constants.ts | 1 + packages/tlschema/api-report.md | 5 + packages/tlschema/api/api.json | 106 ++++ packages/tlschema/src/index.ts | 1 + scripts/lib/eslint-plugin.ts | 44 ++ 22 files changed, 782 insertions(+), 89 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 64fab1966..374c45544 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -46,12 +46,12 @@ module.exports = { 'react-hooks/rules-of-hooks': 'error', 'react-hooks/exhaustive-deps': 'error', 'import/no-extraneous-dependencies': 'error', - 'import/no-internal-modules': ['error', { forbid: ['@tldraw/*/**', 'tldraw/**'] }], '@typescript-eslint/consistent-type-exports': [ 'error', { fixMixedExportsWithInlineTypeSpecifier: true }, ], 'local/no-export-star': 'error', + 'local/no-internal-imports': 'error', 'no-only-tests/no-only-tests': 'error', 'no-restricted-syntax': [ 'error', @@ -99,7 +99,6 @@ module.exports = { { files: ['apps/examples/**/*'], rules: { - 'import/no-internal-modules': 'off', 'no-restricted-syntax': 'off', }, }, diff --git a/apps/dotcom/src/utils/assetUrls.ts b/apps/dotcom/src/utils/assetUrls.ts index d3616dde2..84ac31694 100644 --- a/apps/dotcom/src/utils/assetUrls.ts +++ b/apps/dotcom/src/utils/assetUrls.ts @@ -1,4 +1,3 @@ -// eslint-disable-next-line import/no-internal-modules import { getAssetUrlsByImport } from '@tldraw/assets/imports.vite' export const assetUrls = getAssetUrlsByImport() diff --git a/apps/examples/src/examples/custom-config/CardShape/card-shape-migrations.ts b/apps/examples/src/examples/custom-config/CardShape/card-shape-migrations.ts index 9fa1186c0..9e032e506 100644 --- a/apps/examples/src/examples/custom-config/CardShape/card-shape-migrations.ts +++ b/apps/examples/src/examples/custom-config/CardShape/card-shape-migrations.ts @@ -1,5 +1,4 @@ -import { createShapePropsMigrationIds } from '@tldraw/tlschema/src/records/TLShape' -import { createShapePropsMigrationSequence } from 'tldraw' +import { createShapePropsMigrationIds, createShapePropsMigrationSequence } from 'tldraw' const versions = createShapePropsMigrationIds( // this must match the shape type in the shape definition diff --git a/apps/examples/src/examples/exploded/ExplodedExample.tsx b/apps/examples/src/examples/exploded/ExplodedExample.tsx index 5f9d0e09b..8a8fa7812 100644 --- a/apps/examples/src/examples/exploded/ExplodedExample.tsx +++ b/apps/examples/src/examples/exploded/ExplodedExample.tsx @@ -9,12 +9,12 @@ import { TldrawSelectionBackground, TldrawSelectionForeground, TldrawUi, + defaultEditorAssetUrls, defaultShapeTools, defaultShapeUtils, defaultTools, usePreloadAssets, } from 'tldraw' -import { defaultEditorAssetUrls } from 'tldraw/src/lib/utils/static-assets/assetUrls' import 'tldraw/tldraw.css' // There's a guide at the bottom of this file! diff --git a/apps/examples/src/examples/image-annotator/ImageAnnotationEditor.tsx b/apps/examples/src/examples/image-annotator/ImageAnnotationEditor.tsx index 827a545a3..5c2ebb941 100644 --- a/apps/examples/src/examples/image-annotator/ImageAnnotationEditor.tsx +++ b/apps/examples/src/examples/image-annotator/ImageAnnotationEditor.tsx @@ -3,6 +3,7 @@ import { AssetRecordType, Box, Editor, + PORTRAIT_BREAKPOINT, SVGContainer, TLImageShape, TLShapeId, @@ -16,7 +17,6 @@ import { useBreakpoint, useEditor, } from 'tldraw' -import { PORTRAIT_BREAKPOINT } from 'tldraw/src/lib/ui/constants' import { AnnotatorImage } from './types' // TODO: diff --git a/apps/examples/src/examples/pdf-editor/PdfEditor.tsx b/apps/examples/src/examples/pdf-editor/PdfEditor.tsx index 8a56ea07f..99086838e 100644 --- a/apps/examples/src/examples/pdf-editor/PdfEditor.tsx +++ b/apps/examples/src/examples/pdf-editor/PdfEditor.tsx @@ -1,6 +1,7 @@ import { useCallback, useEffect, useMemo } from 'react' import { Box, + PORTRAIT_BREAKPOINT, SVGContainer, TLImageShape, TLShapeId, @@ -15,7 +16,6 @@ import { useBreakpoint, useEditor, } from 'tldraw' -import { PORTRAIT_BREAKPOINT } from 'tldraw/src/lib/ui/constants' import { ExportPdfButton } from './ExportPdfButton' import { Pdf } from './PdfPicker' diff --git a/apps/examples/src/examples/shape-with-migrations/ShapeWithMigrationsExample.tsx b/apps/examples/src/examples/shape-with-migrations/ShapeWithMigrationsExample.tsx index 42d72fac5..79885eb22 100644 --- a/apps/examples/src/examples/shape-with-migrations/ShapeWithMigrationsExample.tsx +++ b/apps/examples/src/examples/shape-with-migrations/ShapeWithMigrationsExample.tsx @@ -6,6 +6,8 @@ import { TLOnResizeHandler, TLStoreSnapshot, Tldraw, + createShapePropsMigrationIds, + createShapePropsMigrationSequence, resizeBox, } from 'tldraw' import 'tldraw/tldraw.css' @@ -22,6 +24,31 @@ export type IMyShape = TLBaseShape< } > +// [1] +const versions = createShapePropsMigrationIds( + // this must match the shape type in the shape definition + 'myshape', + { + AddColor: 1, + } +) + +// [2] +export const cardShapeMigrations = createShapePropsMigrationSequence({ + sequence: [ + { + id: versions.AddColor, + up(props) { + // it is safe to mutate the props object here + props.color = 'lightblue' + }, + down(props) { + delete props.color + }, + }, + ], +}) + export class MigratedShapeUtil extends BaseBoxShapeUtil { static override type = 'myshape' as const @@ -31,31 +58,8 @@ export class MigratedShapeUtil extends BaseBoxShapeUtil { color: T.string, } - // [1] - static override migrations = { - firstVersion: 0, - currentVersion: 1, - migrators: { - 1: { - up(shape: IMyShape) { - return { - ...shape, - props: { - ...shape.props, - color: 'lightblue', - }, - } - }, - down(shape: IMyShape) { - const { color: _, ...propsWithoutColor } = shape.props - return { - ...shape, - props: propsWithoutColor, - } - }, - }, - }, - } + // [3] + static override migrations = cardShapeMigrations getDefaultProps(): IMyShape['props'] { return { @@ -104,59 +108,56 @@ export default function ShapeWithMigrationsExample() { /* Introduction: -Sometimes you'll want to update the way a shape works in your application without -breaking older versions of the shape that a user may have stored or persisted in -memory. +Sometimes you'll want to update the way a shape works in your application without breaking older +versions of the shape that a user may have stored or persisted in memory. -This example shows how you can use our migrations system to upgrade (or downgrade) -user's data between different versions. Most of the code above is general "custom -shape" code—see our custom shape example for more details. +This example shows how you can use our migrations system to upgrade (or downgrade) user's data +between different versions. Most of the code above is general "custom shape" code—see our custom +shape example for more details. -[1] -To define migrations, we can override the migrations property of our shape util. Each migration -had two parts: an `up` migration and `down` migration. In this case, the `up` migration adds -the `color` prop to the shape, and the `down` migration removes it. +[1] First, we need IDs for each migration. List each change with its version number. Once you've +added a migration, it should not change again. -In some cases (mainly in multiplayer sessions) a peer or server may need to take a later -version of a shape and migrate it down to an older version—in this case, it would run the -down migrations in order to get it to the needed version. +[2] Next, we create a migration sequence. This is where we actually write our migration logic. Each +migration had three parts: an `id` (created in [1]), an `up` migration and `down` migration. In this +case, the `up` migration adds the `color` prop to the shape, and the `down` migration removes it. + +In some cases (mainly in multiplayer sessions) a peer or server may need to take a later version of +a shape and migrate it down to an older version—in this case, it would run the down migrations in +order to get it to the needed version. + +[3] Finally, we add our migrations to the ShapeUtil. This tells tldraw about the migrations so they +can be used with your shapes. How it works: -Each time the editor's store creates a snapshot (`editor.store.createSnapshot`), it -serializes all of the records (the snapshot's `store`) as well as versions of each -record that it contains (the snapshot's `scena`). When the editor loads a snapshot, -it compares its current schema with the snapshot's schema to determine which migrations -to apply to each record. +Each time the editor's store creates a snapshot (`editor.store.createSnapshot`), it serializes all +of the records (the snapshot's `store`) as well as versions of each record that it contains (the +snapshot's `scena`). When the editor loads a snapshot, it compares its current schema with the +snapshot's schema to determine which migrations to apply to each record. -In this example, we have a snapshot (snapshot.json) that we created in version 0, -however our shape now has a 'color' prop that was added in version 1. +In this example, we have a snapshot (snapshot.json) that we created in version 0, however our shape +now has a 'color' prop that was added in version 1. The snapshot looks something like this: ```json{ { - "store": { - "shape:BqG5uIAa9ig2-ukfnxwBX": { + "store": { + "shape:BqG5uIAa9ig2-ukfnxwBX": { + ..., + "props": { + "w": 300, + "h": 300 + }, + }, + }, + "schema": { + ..., + "sequences": { ..., - "props": { - "w": 300, - "h": 300 - }, - }, - "schema": { - ..., - "recordVersions": { - ..., - "shape": { - "version": 3, - "subTypeKey": "type", - "subTypeVersions": { - ..., - "myshape": 0 - } - } - } + "com.tldraw.shape.arrow": 4, + "com.tldraw.shape.myshape": 0 } } } @@ -166,9 +167,8 @@ Note that the shape in the snapshot doesn't have a 'color' prop. Note also that the schema's version for this shape is 0. -When the editor loads the snapshot, it will compare the serialzied schema's version with -its current schema's version for the shape, which is 1 as defined in our shape's migrations. -Since the serialized version is older than its current version, it will use our migration -to bring it up to date: it will run the migration's `up` function, which will add the 'color' -prop to the shape. +When the editor loads the snapshot, it will compare the serialzied schema's version with its current +schema's version for the shape, which is 1 as defined in our shape's migrations. Since the +serialized version is older than its current version, it will use our migration to bring it up to +date: it will run the migration's `up` function, which will add the 'color' prop to the shape. */ diff --git a/apps/examples/src/examples/shape-with-tldraw-styles/ShapeWithTldrawStylesExample.tsx b/apps/examples/src/examples/shape-with-tldraw-styles/ShapeWithTldrawStylesExample.tsx index 150c0b2ae..9f79f5ca5 100644 --- a/apps/examples/src/examples/shape-with-tldraw-styles/ShapeWithTldrawStylesExample.tsx +++ b/apps/examples/src/examples/shape-with-tldraw-styles/ShapeWithTldrawStylesExample.tsx @@ -8,8 +8,8 @@ import { TLDefaultColorStyle, TLDefaultSizeStyle, Tldraw, + useDefaultColorTheme, } from 'tldraw' -import { useDefaultColorTheme } from 'tldraw/src/lib/shapes/shared/ShapeFill' import 'tldraw/tldraw.css' // There's a guide at the bottom of this file! diff --git a/apps/examples/src/examples/slides/SlideShapeUtil.tsx b/apps/examples/src/examples/slides/SlideShapeUtil.tsx index 7f826024a..e2c01542b 100644 --- a/apps/examples/src/examples/slides/SlideShapeUtil.tsx +++ b/apps/examples/src/examples/slides/SlideShapeUtil.tsx @@ -8,10 +8,10 @@ import { T, TLBaseShape, TLOnResizeHandler, + getPerfectDashProps, resizeBox, useValue, } from 'tldraw' -import { getPerfectDashProps } from 'tldraw/src/lib/shapes/shared/getPerfectDashProps' import { moveToSlide, useSlides } from './useSlides' export type SlideShape = TLBaseShape< diff --git a/apps/examples/src/examples/speech-bubble/SpeechBubble/SpeechBubbleUtil.tsx b/apps/examples/src/examples/speech-bubble/SpeechBubble/SpeechBubbleUtil.tsx index 7d63acdc3..1c0d3e1f0 100644 --- a/apps/examples/src/examples/speech-bubble/SpeechBubble/SpeechBubbleUtil.tsx +++ b/apps/examples/src/examples/speech-bubble/SpeechBubble/SpeechBubbleUtil.tsx @@ -22,9 +22,9 @@ import { ZERO_INDEX_KEY, resizeBox, structuredClone, + useDefaultColorTheme, vecModelValidator, } from 'tldraw' -import { useDefaultColorTheme } from 'tldraw/src/lib/shapes/shared/ShapeFill' import { getSpeechBubbleVertices, getTailIntersectionPoint } from './helpers' // Copied from tldraw/tldraw diff --git a/apps/examples/src/misc/EndToEndApi.tsx b/apps/examples/src/misc/EndToEndApi.tsx index 42f2eabab..b5a6e60a9 100644 --- a/apps/examples/src/misc/EndToEndApi.tsx +++ b/apps/examples/src/misc/EndToEndApi.tsx @@ -1,4 +1,4 @@ -import { TLExportType } from 'tldraw/src/lib/utils/export/exportAs' +import { TLExportType } from 'tldraw' export interface EndToEndApi { exportAsSvg: () => void diff --git a/apps/vscode/editor/src/app.tsx b/apps/vscode/editor/src/app.tsx index 1b6195d01..be1bc9261 100644 --- a/apps/vscode/editor/src/app.tsx +++ b/apps/vscode/editor/src/app.tsx @@ -1,6 +1,3 @@ -// eslint-disable-next-line import/no-internal-modules -import 'tldraw/tldraw.css' -// eslint-disable-next-line import/no-internal-modules import { getAssetUrlsByImport } from '@tldraw/assets/imports' import { useCallback, useEffect, useMemo, useState } from 'react' import { @@ -13,6 +10,7 @@ import { TldrawUiMenuGroup, setRuntimeOverrides, } from 'tldraw' +import 'tldraw/tldraw.css' import { VscodeMessage } from '../../messages' import '../public/index.css' import { ChangeResponder } from './ChangeResponder' diff --git a/packages/tldraw/api-report.md b/packages/tldraw/api-report.md index d48e31f58..a5a6b46d1 100644 --- a/packages/tldraw/api-report.md +++ b/packages/tldraw/api-report.md @@ -63,6 +63,8 @@ import { TLCancelEvent } from '@tldraw/editor'; import { TLClickEvent } from '@tldraw/editor'; import { TLClickEventInfo } from '@tldraw/editor'; import { TLDefaultColorTheme } from '@tldraw/editor'; +import { TLDefaultColorThemeColor } from '@tldraw/editor'; +import { TLDefaultDashStyle } from '@tldraw/editor'; import { TLDefaultFillStyle } from '@tldraw/editor'; import { TLDefaultFontStyle } from '@tldraw/editor'; import { TLDefaultHorizontalAlignStyle } from '@tldraw/editor'; @@ -372,6 +374,9 @@ export function DefaultDebugMenu({ children }: TLUiDebugMenuProps): JSX_2.Elemen // @public (undocumented) export function DefaultDebugMenuContent(): JSX_2.Element; +// @public (undocumented) +export let defaultEditorAssetUrls: TLEditorAssetUrls; + // @public (undocumented) export function DefaultHelperButtons({ children }: TLUiHelperButtonsProps): JSX_2.Element; @@ -835,6 +840,19 @@ export function getEmbedInfo(inputUrl: string): TLEmbedResult; // @public (undocumented) export function getOccludedChildren(editor: Editor, parent: TLShape): TLShapeId[]; +// @public (undocumented) +export function getPerfectDashProps(totalLength: number, strokeWidth: number, opts?: Partial<{ + closed: boolean; + end: 'none' | 'outset' | 'skip'; + lengthRatio: number; + snap: number; + start: 'none' | 'outset' | 'skip'; + style: TLDefaultDashStyle; +}>): { + strokeDasharray: string; + strokeDashoffset: string; +}; + // @public (undocumented) export function getSvgAsImage(svgString: string, isSafari: boolean, options: { height: number; @@ -1216,6 +1234,26 @@ export function parseTldrawJsonFile({ json, schema, }: { // @public (undocumented) export function PasteMenuItem(): JSX_2.Element; +// @public (undocumented) +export enum PORTRAIT_BREAKPOINT { + // (undocumented) + DESKTOP = 7, + // (undocumented) + MOBILE = 4, + // (undocumented) + MOBILE_SM = 3, + // (undocumented) + MOBILE_XS = 2, + // (undocumented) + MOBILE_XXS = 1, + // (undocumented) + TABLET = 6, + // (undocumented) + TABLET_SM = 5, + // (undocumented) + ZERO = 0 +} + // @public (undocumented) export function PreferencesGroup(): JSX_2.Element; @@ -1720,6 +1758,9 @@ export type TldrawUiProps = Expand; +// @public (undocumented) +export type TLExportType = 'jpeg' | 'json' | 'png' | 'svg' | 'webp'; + // @public (undocumented) export interface TLUiActionItem { // (undocumented) @@ -2486,6 +2527,27 @@ export function useCopyAs(): (ids: TLShapeId[], format?: TLCopyType) => void; // @public (undocumented) export const useCurrentTranslation: () => TLUiTranslation; +// @public (undocumented) +export function useDefaultColorTheme(): { + "light-blue": TLDefaultColorThemeColor; + "light-green": TLDefaultColorThemeColor; + "light-red": TLDefaultColorThemeColor; + "light-violet": TLDefaultColorThemeColor; + background: string; + black: TLDefaultColorThemeColor; + blue: TLDefaultColorThemeColor; + green: TLDefaultColorThemeColor; + grey: TLDefaultColorThemeColor; + id: "dark" | "light"; + orange: TLDefaultColorThemeColor; + red: TLDefaultColorThemeColor; + solid: string; + text: string; + violet: TLDefaultColorThemeColor; + white: TLDefaultColorThemeColor; + yellow: TLDefaultColorThemeColor; +}; + // @public (undocumented) export function useDefaultHelpers(): { addDialog: (dialog: Omit & { diff --git a/packages/tldraw/api/api.json b/packages/tldraw/api/api.json index 1210a98fc..63e0a868f 100644 --- a/packages/tldraw/api/api.json +++ b/packages/tldraw/api/api.json @@ -3358,6 +3358,30 @@ "parameters": [], "name": "DefaultDebugMenuContent" }, + { + "kind": "Variable", + "canonicalReference": "tldraw!defaultEditorAssetUrls:var", + "docComment": "/**\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "defaultEditorAssetUrls: " + }, + { + "kind": "Reference", + "text": "TLEditorAssetUrls", + "canonicalReference": "tldraw!~TLEditorAssetUrls:type" + } + ], + "fileUrlPath": "packages/tldraw/src/lib/utils/static-assets/assetUrls.ts", + "isReadonly": false, + "releaseTag": "Public", + "name": "defaultEditorAssetUrls", + "variableTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + } + }, { "kind": "Function", "canonicalReference": "tldraw!DefaultHelperButtons:function(1)", @@ -6450,7 +6474,7 @@ { "kind": "Reference", "text": "TLExportType", - "canonicalReference": "tldraw!~TLExportType:type" + "canonicalReference": "tldraw!TLExportType:type" }, { "kind": "Content", @@ -9202,6 +9226,97 @@ ], "name": "getOccludedChildren" }, + { + "kind": "Function", + "canonicalReference": "tldraw!getPerfectDashProps:function(1)", + "docComment": "/**\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export declare function getPerfectDashProps(totalLength: " + }, + { + "kind": "Content", + "text": "number" + }, + { + "kind": "Content", + "text": ", strokeWidth: " + }, + { + "kind": "Content", + "text": "number" + }, + { + "kind": "Content", + "text": ", opts?: " + }, + { + "kind": "Reference", + "text": "Partial", + "canonicalReference": "!Partial:type" + }, + { + "kind": "Content", + "text": "<{\n closed: boolean;\n end: 'none' | 'outset' | 'skip';\n lengthRatio: number;\n snap: number;\n start: 'none' | 'outset' | 'skip';\n style: " + }, + { + "kind": "Reference", + "text": "TLDefaultDashStyle", + "canonicalReference": "@tldraw/tlschema!TLDefaultDashStyle:type" + }, + { + "kind": "Content", + "text": ";\n}>" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Content", + "text": "{\n strokeDasharray: string;\n strokeDashoffset: string;\n}" + }, + { + "kind": "Content", + "text": ";" + } + ], + "fileUrlPath": "packages/tldraw/src/lib/shapes/shared/getPerfectDashProps.ts", + "returnTypeTokenRange": { + "startIndex": 10, + "endIndex": 11 + }, + "releaseTag": "Public", + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "totalLength", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": false + }, + { + "parameterName": "strokeWidth", + "parameterTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "isOptional": false + }, + { + "parameterName": "opts", + "parameterTypeTokenRange": { + "startIndex": 5, + "endIndex": 9 + }, + "isOptional": true + } + ], + "name": "getPerfectDashProps" + }, { "kind": "Function", "canonicalReference": "tldraw!getSvgAsImage:function(1)", @@ -13950,6 +14065,191 @@ "parameters": [], "name": "PasteMenuItem" }, + { + "kind": "Enum", + "canonicalReference": "tldraw!PORTRAIT_BREAKPOINT:enum", + "docComment": "/**\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export declare enum PORTRAIT_BREAKPOINT " + } + ], + "fileUrlPath": "packages/tldraw/src/lib/ui/constants.ts", + "releaseTag": "Public", + "name": "PORTRAIT_BREAKPOINT", + "preserveMemberOrder": false, + "members": [ + { + "kind": "EnumMember", + "canonicalReference": "tldraw!PORTRAIT_BREAKPOINT.DESKTOP:member", + "docComment": "", + "excerptTokens": [ + { + "kind": "Content", + "text": "DESKTOP = " + }, + { + "kind": "Content", + "text": "7" + } + ], + "initializerTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "releaseTag": "Public", + "name": "DESKTOP" + }, + { + "kind": "EnumMember", + "canonicalReference": "tldraw!PORTRAIT_BREAKPOINT.MOBILE:member", + "docComment": "", + "excerptTokens": [ + { + "kind": "Content", + "text": "MOBILE = " + }, + { + "kind": "Content", + "text": "4" + } + ], + "initializerTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "releaseTag": "Public", + "name": "MOBILE" + }, + { + "kind": "EnumMember", + "canonicalReference": "tldraw!PORTRAIT_BREAKPOINT.MOBILE_SM:member", + "docComment": "", + "excerptTokens": [ + { + "kind": "Content", + "text": "MOBILE_SM = " + }, + { + "kind": "Content", + "text": "3" + } + ], + "initializerTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "releaseTag": "Public", + "name": "MOBILE_SM" + }, + { + "kind": "EnumMember", + "canonicalReference": "tldraw!PORTRAIT_BREAKPOINT.MOBILE_XS:member", + "docComment": "", + "excerptTokens": [ + { + "kind": "Content", + "text": "MOBILE_XS = " + }, + { + "kind": "Content", + "text": "2" + } + ], + "initializerTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "releaseTag": "Public", + "name": "MOBILE_XS" + }, + { + "kind": "EnumMember", + "canonicalReference": "tldraw!PORTRAIT_BREAKPOINT.MOBILE_XXS:member", + "docComment": "", + "excerptTokens": [ + { + "kind": "Content", + "text": "MOBILE_XXS = " + }, + { + "kind": "Content", + "text": "1" + } + ], + "initializerTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "releaseTag": "Public", + "name": "MOBILE_XXS" + }, + { + "kind": "EnumMember", + "canonicalReference": "tldraw!PORTRAIT_BREAKPOINT.TABLET:member", + "docComment": "", + "excerptTokens": [ + { + "kind": "Content", + "text": "TABLET = " + }, + { + "kind": "Content", + "text": "6" + } + ], + "initializerTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "releaseTag": "Public", + "name": "TABLET" + }, + { + "kind": "EnumMember", + "canonicalReference": "tldraw!PORTRAIT_BREAKPOINT.TABLET_SM:member", + "docComment": "", + "excerptTokens": [ + { + "kind": "Content", + "text": "TABLET_SM = " + }, + { + "kind": "Content", + "text": "5" + } + ], + "initializerTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "releaseTag": "Public", + "name": "TABLET_SM" + }, + { + "kind": "EnumMember", + "canonicalReference": "tldraw!PORTRAIT_BREAKPOINT.ZERO:member", + "docComment": "", + "excerptTokens": [ + { + "kind": "Content", + "text": "ZERO = " + }, + { + "kind": "Content", + "text": "0" + } + ], + "initializerTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "releaseTag": "Public", + "name": "ZERO" + } + ] + }, { "kind": "Function", "canonicalReference": "tldraw!PreferencesGroup:function(1)", @@ -19960,6 +20260,32 @@ "endIndex": 7 } }, + { + "kind": "TypeAlias", + "canonicalReference": "tldraw!TLExportType:type", + "docComment": "/**\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export type TLExportType = " + }, + { + "kind": "Content", + "text": "'jpeg' | 'json' | 'png' | 'svg' | 'webp'" + }, + { + "kind": "Content", + "text": ";" + } + ], + "fileUrlPath": "packages/tldraw/src/lib/utils/export/exportAs.ts", + "releaseTag": "Public", + "name": "TLExportType", + "typeTokenRange": { + "startIndex": 1, + "endIndex": 2 + } + }, { "kind": "Interface", "canonicalReference": "tldraw!TLUiActionItem:interface", @@ -27339,6 +27665,151 @@ "parameters": [], "name": "useCurrentTranslation" }, + { + "kind": "Function", + "canonicalReference": "tldraw!useDefaultColorTheme:function(1)", + "docComment": "/**\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export declare function useDefaultColorTheme(): " + }, + { + "kind": "Content", + "text": "{\n \"light-blue\": import(\"@tldraw/editor\")." + }, + { + "kind": "Reference", + "text": "TLDefaultColorThemeColor", + "canonicalReference": "@tldraw/tlschema!TLDefaultColorThemeColor:type" + }, + { + "kind": "Content", + "text": ";\n \"light-green\": import(\"@tldraw/editor\")." + }, + { + "kind": "Reference", + "text": "TLDefaultColorThemeColor", + "canonicalReference": "@tldraw/tlschema!TLDefaultColorThemeColor:type" + }, + { + "kind": "Content", + "text": ";\n \"light-red\": import(\"@tldraw/editor\")." + }, + { + "kind": "Reference", + "text": "TLDefaultColorThemeColor", + "canonicalReference": "@tldraw/tlschema!TLDefaultColorThemeColor:type" + }, + { + "kind": "Content", + "text": ";\n \"light-violet\": import(\"@tldraw/editor\")." + }, + { + "kind": "Reference", + "text": "TLDefaultColorThemeColor", + "canonicalReference": "@tldraw/tlschema!TLDefaultColorThemeColor:type" + }, + { + "kind": "Content", + "text": ";\n background: string;\n black: import(\"@tldraw/editor\")." + }, + { + "kind": "Reference", + "text": "TLDefaultColorThemeColor", + "canonicalReference": "@tldraw/tlschema!TLDefaultColorThemeColor:type" + }, + { + "kind": "Content", + "text": ";\n blue: import(\"@tldraw/editor\")." + }, + { + "kind": "Reference", + "text": "TLDefaultColorThemeColor", + "canonicalReference": "@tldraw/tlschema!TLDefaultColorThemeColor:type" + }, + { + "kind": "Content", + "text": ";\n green: import(\"@tldraw/editor\")." + }, + { + "kind": "Reference", + "text": "TLDefaultColorThemeColor", + "canonicalReference": "@tldraw/tlschema!TLDefaultColorThemeColor:type" + }, + { + "kind": "Content", + "text": ";\n grey: import(\"@tldraw/editor\")." + }, + { + "kind": "Reference", + "text": "TLDefaultColorThemeColor", + "canonicalReference": "@tldraw/tlschema!TLDefaultColorThemeColor:type" + }, + { + "kind": "Content", + "text": ";\n id: \"dark\" | \"light\";\n orange: import(\"@tldraw/editor\")." + }, + { + "kind": "Reference", + "text": "TLDefaultColorThemeColor", + "canonicalReference": "@tldraw/tlschema!TLDefaultColorThemeColor:type" + }, + { + "kind": "Content", + "text": ";\n red: import(\"@tldraw/editor\")." + }, + { + "kind": "Reference", + "text": "TLDefaultColorThemeColor", + "canonicalReference": "@tldraw/tlschema!TLDefaultColorThemeColor:type" + }, + { + "kind": "Content", + "text": ";\n solid: string;\n text: string;\n violet: import(\"@tldraw/editor\")." + }, + { + "kind": "Reference", + "text": "TLDefaultColorThemeColor", + "canonicalReference": "@tldraw/tlschema!TLDefaultColorThemeColor:type" + }, + { + "kind": "Content", + "text": ";\n white: import(\"@tldraw/editor\")." + }, + { + "kind": "Reference", + "text": "TLDefaultColorThemeColor", + "canonicalReference": "@tldraw/tlschema!TLDefaultColorThemeColor:type" + }, + { + "kind": "Content", + "text": ";\n yellow: import(\"@tldraw/editor\")." + }, + { + "kind": "Reference", + "text": "TLDefaultColorThemeColor", + "canonicalReference": "@tldraw/tlschema!TLDefaultColorThemeColor:type" + }, + { + "kind": "Content", + "text": ";\n}" + }, + { + "kind": "Content", + "text": ";" + } + ], + "fileUrlPath": "packages/tldraw/src/lib/shapes/shared/ShapeFill.tsx", + "returnTypeTokenRange": { + "startIndex": 1, + "endIndex": 28 + }, + "releaseTag": "Public", + "overloadIndex": 1, + "parameters": [], + "name": "useDefaultColorTheme" + }, { "kind": "Function", "canonicalReference": "tldraw!useDefaultHelpers:function(1)", @@ -27625,7 +28096,7 @@ { "kind": "Reference", "text": "TLExportType", - "canonicalReference": "tldraw!~TLExportType:type" + "canonicalReference": "tldraw!TLExportType:type" }, { "kind": "Content", diff --git a/packages/tldraw/src/index.ts b/packages/tldraw/src/index.ts index 6f37098e5..03e5643ab 100644 --- a/packages/tldraw/src/index.ts +++ b/packages/tldraw/src/index.ts @@ -32,7 +32,9 @@ export { LineShapeTool } from './lib/shapes/line/LineShapeTool' export { LineShapeUtil } from './lib/shapes/line/LineShapeUtil' export { NoteShapeTool } from './lib/shapes/note/NoteShapeTool' export { NoteShapeUtil } from './lib/shapes/note/NoteShapeUtil' +export { useDefaultColorTheme } from './lib/shapes/shared/ShapeFill' export { TextLabel } from './lib/shapes/shared/TextLabel' +export { getPerfectDashProps } from './lib/shapes/shared/getPerfectDashProps' export { TextShapeTool } from './lib/shapes/text/TextShapeTool' export { TextShapeUtil } from './lib/shapes/text/TextShapeUtil' export { VideoShapeUtil } from './lib/shapes/video/VideoShapeUtil' @@ -48,6 +50,7 @@ export { TldrawUi, type TldrawUiBaseProps, type TldrawUiProps } from './lib/ui/T export { setDefaultUiAssetUrls, type TLUiAssetUrlOverrides } from './lib/ui/assetUrls' export { OfflineIndicator } from './lib/ui/components/OfflineIndicator/OfflineIndicator' export { Spinner } from './lib/ui/components/Spinner' +export { PORTRAIT_BREAKPOINT } from './lib/ui/constants' export { TldrawUiContextProvider, type TldrawUiContextProviderProps, @@ -115,9 +118,12 @@ export { export { getEmbedInfo } from './lib/utils/embeds/embeds' export { copyAs } from './lib/utils/export/copyAs' export { exportToBlob, getSvgAsImage } from './lib/utils/export/export' -export { exportAs } from './lib/utils/export/exportAs' +export { exportAs, type TLExportType } from './lib/utils/export/exportAs' export { fitFrameToContent, removeFrame } from './lib/utils/frames/frames' -export { setDefaultEditorAssetUrls } from './lib/utils/static-assets/assetUrls' +export { + defaultEditorAssetUrls, + setDefaultEditorAssetUrls, +} from './lib/utils/static-assets/assetUrls' export { truncateStringWithEllipsis } from './lib/utils/text/text' export { buildFromV1Document, diff --git a/packages/tldraw/src/lib/shapes/shared/ShapeFill.tsx b/packages/tldraw/src/lib/shapes/shared/ShapeFill.tsx index abf831b0e..dfc58ae3e 100644 --- a/packages/tldraw/src/lib/shapes/shared/ShapeFill.tsx +++ b/packages/tldraw/src/lib/shapes/shared/ShapeFill.tsx @@ -18,6 +18,7 @@ export interface ShapeFillProps { theme: TLDefaultColorTheme } +/** @public */ export function useDefaultColorTheme() { return getDefaultColorTheme({ isDarkMode: useIsDarkMode() }) } diff --git a/packages/tldraw/src/lib/shapes/shared/getPerfectDashProps.ts b/packages/tldraw/src/lib/shapes/shared/getPerfectDashProps.ts index ecac502fa..d3a36eeeb 100644 --- a/packages/tldraw/src/lib/shapes/shared/getPerfectDashProps.ts +++ b/packages/tldraw/src/lib/shapes/shared/getPerfectDashProps.ts @@ -1,5 +1,6 @@ import { TLDefaultDashStyle } from '@tldraw/editor' +/** @public */ export function getPerfectDashProps( totalLength: number, strokeWidth: number, diff --git a/packages/tldraw/src/lib/ui/constants.ts b/packages/tldraw/src/lib/ui/constants.ts index 2cd8056e5..f39bbafbf 100644 --- a/packages/tldraw/src/lib/ui/constants.ts +++ b/packages/tldraw/src/lib/ui/constants.ts @@ -2,6 +2,7 @@ export const PORTRAIT_BREAKPOINTS = [0, 390, 428, 468, 580, 640, 840, 1023] // Mapping for above array -- needs to be kept in sync! +/** @public */ export enum PORTRAIT_BREAKPOINT { ZERO = 0, MOBILE_XXS = 1, diff --git a/packages/tlschema/api-report.md b/packages/tlschema/api-report.md index 86936de6c..ef8fe79b8 100644 --- a/packages/tlschema/api-report.md +++ b/packages/tlschema/api-report.md @@ -142,6 +142,11 @@ export const createPresenceStateDerivation: ($user: Signal<{ // @public (undocumented) export function createShapeId(id?: string): TLShapeId; +// @public (undocumented) +export function createShapePropsMigrationIds>(shapeType: S, ids: T): { + [k in keyof T]: `com.tldraw.shape.${S}/${T[k]}`; +}; + // @public (undocumented) export function createShapePropsMigrationSequence(migrations: TLShapePropsMigrations): TLShapePropsMigrations; diff --git a/packages/tlschema/api/api.json b/packages/tlschema/api/api.json index 94c56e457..1aa0ca10f 100644 --- a/packages/tlschema/api/api.json +++ b/packages/tlschema/api/api.json @@ -1114,6 +1114,112 @@ ], "name": "createShapeId" }, + { + "kind": "Function", + "canonicalReference": "@tldraw/tlschema!createShapePropsMigrationIds:function(1)", + "docComment": "/**\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export declare function createShapePropsMigrationIds" + }, + { + "kind": "Content", + "text": ">(shapeType: " + }, + { + "kind": "Content", + "text": "S" + }, + { + "kind": "Content", + "text": ", ids: " + }, + { + "kind": "Content", + "text": "T" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Content", + "text": "{\n [k in keyof T]: `com.tldraw.shape.${S}/${T[k]}`;\n}" + }, + { + "kind": "Content", + "text": ";" + } + ], + "fileUrlPath": "packages/tlschema/src/records/TLShape.ts", + "returnTypeTokenRange": { + "startIndex": 10, + "endIndex": 11 + }, + "releaseTag": "Public", + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "shapeType", + "parameterTypeTokenRange": { + "startIndex": 6, + "endIndex": 7 + }, + "isOptional": false + }, + { + "parameterName": "ids", + "parameterTypeTokenRange": { + "startIndex": 8, + "endIndex": 9 + }, + "isOptional": false + } + ], + "typeParameters": [ + { + "typeParameterName": "S", + "constraintTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "defaultTypeTokenRange": { + "startIndex": 0, + "endIndex": 0 + } + }, + { + "typeParameterName": "T", + "constraintTokenRange": { + "startIndex": 3, + "endIndex": 5 + }, + "defaultTypeTokenRange": { + "startIndex": 0, + "endIndex": 0 + } + } + ], + "name": "createShapePropsMigrationIds" + }, { "kind": "Function", "canonicalReference": "@tldraw/tlschema!createShapePropsMigrationSequence:function(1)", diff --git a/packages/tlschema/src/index.ts b/packages/tlschema/src/index.ts index a4c61e4d7..fde1f809a 100644 --- a/packages/tlschema/src/index.ts +++ b/packages/tlschema/src/index.ts @@ -52,6 +52,7 @@ export { InstancePresenceRecordType, type TLInstancePresence } from './records/T export { type TLRecord } from './records/TLRecord' export { createShapeId, + createShapePropsMigrationIds, createShapePropsMigrationSequence, getShapePropKeysByStyle, isShape, diff --git a/scripts/lib/eslint-plugin.ts b/scripts/lib/eslint-plugin.ts index 389ddb82e..83946e268 100644 --- a/scripts/lib/eslint-plugin.ts +++ b/scripts/lib/eslint-plugin.ts @@ -59,4 +59,48 @@ exports.rules = { }, defaultOptions: [], }), + 'no-internal-imports': ESLintUtils.RuleCreator.withoutDocs({ + create(context) { + return { + ImportDeclaration(node) { + const path = node.source.value + + const parts = path.split('/') + + switch (parts[0]) { + case 'tldraw': + // 'tldraw' + if (parts.length === 1) return + // 'tldraw/**/*.css' + if (path.endsWith('.css')) return + break + case '@tldraw': + // '@tldraw/*' + if (parts.length === 2) return + // '@tldraw/**/*.css' + if (path.endsWith('.css')) return + // '@tldraw/assets/*' + if (parts[1] === 'assets' && parts.length === 3) return + break + default: + return + } + + context.report({ + messageId: 'internal', + node: node.source, + data: { path }, + }) + }, + } + }, + meta: { + messages: { + internal: "Don't import from internal tldraw source ({{path}})", + }, + type: 'problem', + schema: [], + }, + defaultOptions: [], + }), }