@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.
Files changed (79) hide show
  1. package/dist-cjs/assets/TLBaseAsset.js +4 -3
  2. package/dist-cjs/assets/TLBaseAsset.js.map +2 -2
  3. package/dist-cjs/assets/TLBookmarkAsset.js +9 -7
  4. package/dist-cjs/assets/TLBookmarkAsset.js.map +2 -2
  5. package/dist-cjs/assets/TLImageAsset.js +12 -10
  6. package/dist-cjs/assets/TLImageAsset.js.map +2 -2
  7. package/dist-cjs/assets/TLVideoAsset.js +11 -9
  8. package/dist-cjs/assets/TLVideoAsset.js.map +2 -2
  9. package/dist-cjs/createTLSchema.js +10 -4
  10. package/dist-cjs/createTLSchema.js.map +2 -2
  11. package/dist-cjs/index.d.ts +601 -343
  12. package/dist-cjs/index.js +17 -7
  13. package/dist-cjs/index.js.map +2 -2
  14. package/dist-cjs/records/TLAsset.js +29 -14
  15. package/dist-cjs/records/TLAsset.js.map +2 -2
  16. package/dist-cjs/shapes/TLFrameShape.js +3 -1
  17. package/dist-cjs/shapes/TLFrameShape.js.map +2 -2
  18. package/dist-cjs/shapes/TLNoteShape.js +12 -2
  19. package/dist-cjs/shapes/TLNoteShape.js.map +2 -2
  20. package/dist-cjs/styles/StyleProp.js +38 -1
  21. package/dist-cjs/styles/StyleProp.js.map +2 -2
  22. package/dist-cjs/styles/TLColorStyle.js +36 -487
  23. package/dist-cjs/styles/TLColorStyle.js.map +2 -2
  24. package/dist-cjs/styles/TLDashStyle.js +1 -1
  25. package/dist-cjs/styles/TLDashStyle.js.map +2 -2
  26. package/dist-cjs/styles/TLFontFace.js +17 -0
  27. package/dist-cjs/styles/TLFontFace.js.map +7 -0
  28. package/dist-cjs/styles/TLFontStyle.js +36 -1
  29. package/dist-cjs/styles/TLFontStyle.js.map +2 -2
  30. package/dist-cjs/styles/TLTheme.js +17 -0
  31. package/dist-cjs/styles/TLTheme.js.map +7 -0
  32. package/dist-esm/assets/TLBaseAsset.mjs +4 -3
  33. package/dist-esm/assets/TLBaseAsset.mjs.map +2 -2
  34. package/dist-esm/assets/TLBookmarkAsset.mjs +9 -7
  35. package/dist-esm/assets/TLBookmarkAsset.mjs.map +2 -2
  36. package/dist-esm/assets/TLImageAsset.mjs +12 -10
  37. package/dist-esm/assets/TLImageAsset.mjs.map +2 -2
  38. package/dist-esm/assets/TLVideoAsset.mjs +11 -9
  39. package/dist-esm/assets/TLVideoAsset.mjs.map +2 -2
  40. package/dist-esm/createTLSchema.mjs +17 -8
  41. package/dist-esm/createTLSchema.mjs.map +2 -2
  42. package/dist-esm/index.d.mts +601 -343
  43. package/dist-esm/index.mjs +28 -14
  44. package/dist-esm/index.mjs.map +2 -2
  45. package/dist-esm/records/TLAsset.mjs +29 -14
  46. package/dist-esm/records/TLAsset.mjs.map +2 -2
  47. package/dist-esm/shapes/TLFrameShape.mjs +3 -1
  48. package/dist-esm/shapes/TLFrameShape.mjs.map +2 -2
  49. package/dist-esm/shapes/TLNoteShape.mjs +12 -2
  50. package/dist-esm/shapes/TLNoteShape.mjs.map +2 -2
  51. package/dist-esm/styles/StyleProp.mjs +38 -1
  52. package/dist-esm/styles/StyleProp.mjs.map +2 -2
  53. package/dist-esm/styles/TLColorStyle.mjs +36 -487
  54. package/dist-esm/styles/TLColorStyle.mjs.map +2 -2
  55. package/dist-esm/styles/TLDashStyle.mjs +1 -1
  56. package/dist-esm/styles/TLDashStyle.mjs.map +2 -2
  57. package/dist-esm/styles/TLFontFace.mjs +1 -0
  58. package/dist-esm/styles/TLFontFace.mjs.map +7 -0
  59. package/dist-esm/styles/TLFontStyle.mjs +36 -1
  60. package/dist-esm/styles/TLFontStyle.mjs.map +2 -2
  61. package/dist-esm/styles/TLTheme.mjs +1 -0
  62. package/dist-esm/styles/TLTheme.mjs.map +7 -0
  63. package/package.json +5 -5
  64. package/src/assets/TLBaseAsset.ts +25 -28
  65. package/src/assets/TLBookmarkAsset.ts +13 -33
  66. package/src/assets/TLImageAsset.ts +16 -42
  67. package/src/assets/TLVideoAsset.ts +15 -40
  68. package/src/createTLSchema.ts +54 -15
  69. package/src/index.ts +31 -11
  70. package/src/migrations.test.ts +22 -0
  71. package/src/records/TLAsset.ts +139 -74
  72. package/src/shapes/TLFrameShape.ts +3 -1
  73. package/src/shapes/TLNoteShape.ts +19 -5
  74. package/src/styles/StyleProp.ts +42 -5
  75. package/src/styles/TLColorStyle.ts +55 -698
  76. package/src/styles/TLDashStyle.ts +1 -1
  77. package/src/styles/TLFontFace.ts +65 -0
  78. package/src/styles/TLFontStyle.ts +53 -4
  79. package/src/styles/TLTheme.ts +240 -0
@@ -1749,6 +1749,28 @@ describe('Add font size adjustment to notes', () => {
1749
1749
  })
1750
1750
  })
1751
1751
 
1752
+ describe('Make font size adjustment a ratio on notes', () => {
1753
+ const { up, down } = getTestMigration(noteShapeVersions.MakeFontSizeAdjustmentRatio)
1754
+
1755
+ test('up converts zero to 1 (no adjustment)', () => {
1756
+ expect(up({ props: { fontSizeAdjustment: 0 } })).toEqual({
1757
+ props: { fontSizeAdjustment: 1 },
1758
+ })
1759
+ })
1760
+
1761
+ test('up converts non-zero to null (needs recomputation)', () => {
1762
+ expect(up({ props: { fontSizeAdjustment: 18 } })).toEqual({
1763
+ props: { fontSizeAdjustment: null },
1764
+ })
1765
+ })
1766
+
1767
+ test('down works as expected', () => {
1768
+ expect(down({ props: { fontSizeAdjustment: null } })).toEqual({
1769
+ props: { fontSizeAdjustment: 0 },
1770
+ })
1771
+ })
1772
+ })
1773
+
1752
1774
  describe('removes can move camera', () => {
1753
1775
  const { up, down } = getTestMigration(instanceVersions.RemoveCanMoveCamera)
1754
1776
 
@@ -4,20 +4,22 @@ import {
4
4
  createRecordType,
5
5
  RecordId,
6
6
  } from '@tldraw/store'
7
+ import { mapObjectMapValues } from '@tldraw/utils'
7
8
  import { T } from '@tldraw/validate'
8
- import { TLBaseAsset } from '../assets/TLBaseAsset'
9
- import { bookmarkAssetValidator, TLBookmarkAsset } from '../assets/TLBookmarkAsset'
10
- import { imageAssetValidator, TLImageAsset } from '../assets/TLImageAsset'
11
- import { TLVideoAsset, videoAssetValidator } from '../assets/TLVideoAsset'
9
+ import { createAssetValidator, TLBaseAsset } from '../assets/TLBaseAsset'
10
+ import { TLBookmarkAsset } from '../assets/TLBookmarkAsset'
11
+ import { TLImageAsset } from '../assets/TLImageAsset'
12
+ import { TLVideoAsset } from '../assets/TLVideoAsset'
13
+ import { SchemaPropsInfo } from '../createTLSchema'
14
+ import { TLPropsMigrations } from '../recordsWithProps'
12
15
  import { ExtractShapeByProps } from './TLShape'
13
16
 
14
17
  /**
15
- * Union type representing all possible asset types in tldraw.
16
- * Assets represent external resources like images, videos, or bookmarks that can be referenced by shapes.
18
+ * The default set of asset types that are available in the editor.
17
19
  *
18
20
  * @example
19
21
  * ```ts
20
- * const imageAsset: TLAsset = {
22
+ * const imageAsset: TLDefaultAsset = {
21
23
  * id: 'asset:image123',
22
24
  * typeName: 'asset',
23
25
  * type: 'image',
@@ -26,41 +28,69 @@ import { ExtractShapeByProps } from './TLShape'
26
28
  * w: 800,
27
29
  * h: 600,
28
30
  * mimeType: 'image/jpeg',
29
- * isAnimated: false
31
+ * isAnimated: false,
32
+ * name: 'image.jpg',
30
33
  * },
31
- * meta: {}
34
+ * meta: {},
32
35
  * }
33
36
  * ```
34
37
  *
35
38
  * @public
36
39
  */
37
- export type TLAsset = TLImageAsset | TLVideoAsset | TLBookmarkAsset
40
+ export type TLDefaultAsset = TLImageAsset | TLVideoAsset | TLBookmarkAsset
38
41
 
39
42
  /**
40
- * Validator for TLAsset records that ensures runtime type safety.
41
- * Uses a discriminated union based on the 'type' field to validate different asset types.
43
+ * A type for an asset that is available in the editor but whose type is
44
+ * unknown—either one of the editor's default assets or else a custom asset.
45
+ *
46
+ * @public
47
+ */
48
+ export type TLUnknownAsset = TLBaseAsset<string, object>
49
+
50
+ /** @public */
51
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
52
+ export interface TLGlobalAssetPropsMap {}
53
+
54
+ /** @public */
55
+ // prettier-ignore
56
+ export type TLIndexedAssets = {
57
+ [K in keyof TLGlobalAssetPropsMap | TLDefaultAsset['type'] as K extends TLDefaultAsset['type']
58
+ ? K extends keyof TLGlobalAssetPropsMap
59
+ ? TLGlobalAssetPropsMap[K] extends null | undefined
60
+ ? never
61
+ : K
62
+ : K
63
+ : K]: K extends TLDefaultAsset['type']
64
+ ? K extends keyof TLGlobalAssetPropsMap
65
+ ? TLBaseAsset<K, TLGlobalAssetPropsMap[K]>
66
+ : Extract<TLDefaultAsset, { type: K }>
67
+ : TLBaseAsset<K, TLGlobalAssetPropsMap[K & keyof TLGlobalAssetPropsMap]>
68
+ }
69
+
70
+ /**
71
+ * The set of all assets that are available in the editor.
72
+ *
73
+ * This is the primary asset type used throughout tldraw. It includes both the
74
+ * built-in default assets and any custom assets registered via
75
+ * {@link TLGlobalAssetPropsMap} augmentation.
76
+ *
77
+ * You can use this type without a type argument to work with any asset, or pass
78
+ * a specific asset type string (e.g., `'image'`, `'video'`, `'bookmark'`) to
79
+ * narrow down to that specific asset type.
42
80
  *
43
81
  * @example
44
82
  * ```ts
45
- * // Validation happens automatically when assets are stored
46
- * try {
47
- * const validatedAsset = assetValidator.validate(assetData)
48
- * store.put([validatedAsset])
49
- * } catch (error) {
50
- * console.error('Asset validation failed:', error.message)
83
+ * // Register a custom asset type
84
+ * declare module '@tldraw/tlschema' {
85
+ * interface TLGlobalAssetPropsMap {
86
+ * file: { name: string; size: number; mimeType: string; src: string | null }
87
+ * }
51
88
  * }
52
89
  * ```
53
90
  *
54
91
  * @public
55
92
  */
56
- export const assetValidator: T.Validator<TLAsset> = T.model(
57
- 'asset',
58
- T.union('type', {
59
- image: imageAssetValidator,
60
- video: videoAssetValidator,
61
- bookmark: bookmarkAssetValidator,
62
- })
63
- )
93
+ export type TLAsset<K extends keyof TLIndexedAssets = keyof TLIndexedAssets> = TLIndexedAssets[K]
64
94
 
65
95
  /**
66
96
  * Migration version identifiers for asset record schema evolution.
@@ -87,7 +117,7 @@ export const assetVersions = createMigrationIds('com.tldraw.asset', {
87
117
  * // Migration is applied automatically when loading old documents
88
118
  * const migratedStore = migrator.migrateStoreSnapshot({
89
119
  * schema: oldSchema,
90
- * store: oldStoreSnapshot
120
+ * store: oldStoreSnapshot,
91
121
  * })
92
122
  * ```
93
123
  *
@@ -117,8 +147,8 @@ export const assetMigrations = createRecordMigrationSequence({
117
147
  * id: 'asset:image123',
118
148
  * type: 'image',
119
149
  * props: {
120
- * w: 800 // Only updating width
121
- * }
150
+ * w: 800, // Only updating width
151
+ * },
122
152
  * }
123
153
  *
124
154
  * // Use in asset updates
@@ -137,32 +167,46 @@ export type TLAssetPartial<T extends TLAsset = TLAsset> = T extends T
137
167
  : never
138
168
 
139
169
  /**
140
- * Record type definition for TLAsset with validation and default properties.
141
- * Configures assets as document-scoped records that persist across sessions.
170
+ * Creates the record type definition for assets based on registered asset schemas.
171
+ * This function follows the same pattern as `createShapeRecordType` and `createBindingRecordType`.
172
+ *
173
+ * @param assets - Record of asset type names to their schema configuration
174
+ * @returns A configured record type for assets with validation
142
175
  *
143
176
  * @example
144
177
  * ```ts
145
- * // Create a new asset record
146
- * const assetRecord = AssetRecordType.create({
147
- * id: 'asset:image123',
148
- * type: 'image',
149
- * props: {
150
- * src: 'https://example.com/image.jpg',
151
- * w: 800,
152
- * h: 600,
153
- * mimeType: 'image/jpeg',
154
- * isAnimated: false
155
- * }
178
+ * const AssetRecordType = createAssetRecordType({
179
+ * image: { migrations: imageAssetMigrations, props: imageAssetProps },
180
+ * video: { migrations: videoAssetMigrations, props: videoAssetProps },
181
+ * bookmark: { migrations: bookmarkAssetMigrations, props: bookmarkAssetProps },
156
182
  * })
157
- *
158
- * // Store the asset
159
- * store.put([assetRecord])
160
183
  * ```
161
184
  *
185
+ * @internal
186
+ */
187
+ export function createAssetRecordType(assets: Record<string, SchemaPropsInfo>) {
188
+ return createRecordType('asset', {
189
+ scope: 'document',
190
+ validator: T.model(
191
+ 'asset',
192
+ T.union(
193
+ 'type',
194
+ mapObjectMapValues(assets, (type, { props, meta }) =>
195
+ createAssetValidator(type, props, meta)
196
+ )
197
+ )
198
+ ),
199
+ }).withDefaultProperties(() => ({
200
+ meta: {},
201
+ }))
202
+ }
203
+
204
+ /**
205
+ * Record type definition for default TLAsset records with document scope and default metadata.
206
+ *
162
207
  * @public
163
208
  */
164
209
  export const AssetRecordType = createRecordType<TLAsset>('asset', {
165
- validator: assetValidator,
166
210
  scope: 'document',
167
211
  }).withDefaultProperties(() => ({
168
212
  meta: {},
@@ -170,27 +214,15 @@ export const AssetRecordType = createRecordType<TLAsset>('asset', {
170
214
 
171
215
  /**
172
216
  * Branded string type for asset record identifiers.
173
- * Prevents mixing asset IDs with other types of record IDs at compile time.
217
+ * Prevents mixing asset IDs with other record IDs at compile time.
174
218
  *
175
219
  * @example
176
220
  * ```ts
177
- * import { createAssetId } from '@tldraw/tlschema'
178
- *
179
- * // Create a new asset ID
180
- * const assetId: TLAssetId = createAssetId()
181
- *
182
- * // Use in asset records
183
- * const asset: TLAsset = {
184
- * id: assetId,
185
- * // ... other properties
186
- * }
187
- *
188
- * // Reference in shapes
189
- * const imageShape: TLImageShape = {
221
+ * const imageShape = {
222
+ * type: 'image',
190
223
  * props: {
191
- * assetId: assetId,
192
- * // ... other properties
193
- * }
224
+ * assetId: 'asset:image123' as TLAssetId,
225
+ * },
194
226
  * }
195
227
  * ```
196
228
  *
@@ -204,22 +236,55 @@ export type TLAssetId = RecordId<TLBaseAsset<any, any>>
204
236
  *
205
237
  * @example
206
238
  * ```ts
207
- * // Function that works with any asset-based shape
208
239
  * function handleAssetShape(shape: TLAssetShape) {
209
240
  * const assetId = shape.props.assetId
210
- * if (assetId) {
211
- * const asset = editor.getAsset(assetId)
212
- * // Handle the asset...
213
- * }
241
+ * if (!assetId) return
242
+ * const asset = editor.getAsset(assetId)
243
+ * // Handle the asset...
214
244
  * }
215
- *
216
- * // Use with image or video shapes
217
- * const imageShape: TLImageShape = { props: { assetId: 'asset:img1' } }
218
- * const videoShape: TLVideoShape = { props: { assetId: 'asset:vid1' } }
219
- * handleAssetShape(imageShape) // Works
220
- * handleAssetShape(videoShape) // Works
221
245
  * ```
222
246
  *
223
247
  * @public
224
248
  */
225
249
  export type TLAssetShape = ExtractShapeByProps<{ assetId: TLAssetId }>
250
+
251
+ /**
252
+ * Creates a migration sequence for asset properties.
253
+ *
254
+ * @example
255
+ * ```ts
256
+ * const migrations = createAssetPropsMigrationSequence({
257
+ * sequence: [
258
+ * { id: 'com.myapp.asset.custom/1', up: (props) => { props.newField = '' } },
259
+ * ],
260
+ * })
261
+ * ```
262
+ *
263
+ * @public
264
+ */
265
+ export function createAssetPropsMigrationSequence(
266
+ migrations: TLPropsMigrations
267
+ ): TLPropsMigrations {
268
+ return migrations
269
+ }
270
+
271
+ /**
272
+ * Creates properly formatted migration IDs for asset properties.
273
+ *
274
+ * @example
275
+ * ```ts
276
+ * const assetPropsVersions = createAssetPropsMigrationIds('file', {
277
+ * AddFoo: 1,
278
+ * RenameBar: 2,
279
+ * })
280
+ * // => { AddFoo: 'com.tldraw.asset.file/1', RenameBar: 'com.tldraw.asset.file/2' }
281
+ * ```
282
+ *
283
+ * @public
284
+ */
285
+ export function createAssetPropsMigrationIds<S extends string, T extends Record<string, number>>(
286
+ assetType: S,
287
+ ids: T
288
+ ): { [k in keyof T]: `com.tldraw.asset.${S}/${T[k]}` } {
289
+ return mapObjectMapValues(ids, (_k, v) => `com.tldraw.asset.${assetType}/${v}`) as any
290
+ }
@@ -69,7 +69,9 @@ export const frameShapeProps: RecordProps<TLFrameShape> = {
69
69
  // style prop by default, so instead of a proper style we just supply an equivalent validator.
70
70
  // Check `FrameShapeUtil.configure` for how we replace this with the original
71
71
  // `DefaultColorStyle` style when the option is turned on.
72
- color: T.literalEnum(...DefaultColorStyle.values),
72
+ // We delegate to DefaultColorStyle.validate so custom colors from themes are
73
+ // picked up automatically.
74
+ color: { validate: (v: unknown) => DefaultColorStyle.validate(v) as TLDefaultColorStyle },
73
75
  }
74
76
 
75
77
  const Versions = createShapePropsMigrationIds('frame', {
@@ -31,7 +31,7 @@ import { TLBaseShape } from './TLBaseShape'
31
31
  * labelColor: 'black',
32
32
  * size: 'm',
33
33
  * font: 'draw',
34
- * fontSizeAdjustment: 0,
34
+ * fontSizeAdjustment: null,
35
35
  * align: 'middle',
36
36
  * verticalAlign: 'middle',
37
37
  * growY: 0,
@@ -50,8 +50,8 @@ export interface TLNoteShapeProps {
50
50
  size: TLDefaultSizeStyle
51
51
  /** Font family style for the note text */
52
52
  font: TLDefaultFontStyle
53
- /** Adjustment to the base font size (positive increases, negative decreases) */
54
- fontSizeAdjustment: number
53
+ /** Ratio to scale the base font size when text needs to shrink to fit. Null means needs recomputation, 1 means no adjustment, and values less than 1 indicate shrinkage. */
54
+ fontSizeAdjustment: number | null
55
55
  /** Horizontal alignment of text within the note */
56
56
  align: TLDefaultHorizontalAlignStyle
57
57
  /** Vertical alignment of text within the note */
@@ -91,7 +91,7 @@ export interface TLNoteShapeProps {
91
91
  * labelColor: 'black',
92
92
  * size: 's',
93
93
  * font: 'sans',
94
- * fontSizeAdjustment: 2,
94
+ * fontSizeAdjustment: 0.85,
95
95
  * align: 'start',
96
96
  * verticalAlign: 'start',
97
97
  * growY: 50,
@@ -125,7 +125,7 @@ export const noteShapeProps: RecordProps<TLNoteShape> = {
125
125
  labelColor: DefaultLabelColorStyle,
126
126
  size: DefaultSizeStyle,
127
127
  font: DefaultFontStyle,
128
- fontSizeAdjustment: T.positiveNumber,
128
+ fontSizeAdjustment: T.positiveNumber.nullable(),
129
129
  align: DefaultHorizontalAlignStyle,
130
130
  verticalAlign: DefaultVerticalAlignStyle,
131
131
  growY: T.positiveNumber,
@@ -147,6 +147,7 @@ const Versions = createShapePropsMigrationIds('note', {
147
147
  AddRichText: 9,
148
148
  AddRichTextAttrs: 10,
149
149
  AddFirstEditedBy: 11,
150
+ MakeFontSizeAdjustmentRatio: 12,
150
151
  })
151
152
 
152
153
  /**
@@ -278,5 +279,18 @@ export const noteShapeMigrations = createShapePropsMigrationSequence({
278
279
  delete props.textFirstEditedBy
279
280
  },
280
281
  },
282
+ {
283
+ id: Versions.MakeFontSizeAdjustmentRatio,
284
+ up: (props) => {
285
+ // Old system stored 0 for "no adjustment" or an absolute pixel font size.
286
+ // New system stores a ratio (1 = no adjustment, <1 = shrunk).
287
+ // We can convert 0 → 1 (no adjustment), but non-zero values need
288
+ // recomputation (null) since we don't know the base font size here.
289
+ props.fontSizeAdjustment = props.fontSizeAdjustment === 0 ? 1 : null
290
+ },
291
+ down: (props) => {
292
+ props.fontSizeAdjustment = 0
293
+ },
294
+ },
281
295
  ],
282
296
  })
@@ -111,12 +111,49 @@ export class StyleProp<Type> implements T.Validatable<Type> {
111
111
  */
112
112
  export class EnumStyleProp<T> extends StyleProp<T> {
113
113
  /** @internal */
114
- constructor(
115
- id: string,
116
- defaultValue: T,
117
- readonly values: readonly T[]
118
- ) {
114
+ constructor(id: string, defaultValue: T, values: readonly T[]) {
119
115
  super(id, defaultValue, T.literalEnum(...values))
116
+ this.values = [...values]
117
+ }
118
+
119
+ readonly values: T[]
120
+
121
+ /**
122
+ * Add new values to this enum style prop at runtime. This is useful for extending
123
+ * the built-in styles with custom values (e.g. adding custom colors). Be sure to
124
+ * also modify the associated types.
125
+ *
126
+ * @param newValues - The new values to add.
127
+ *
128
+ * @public
129
+ */
130
+ addValues(...newValues: T[]): void {
131
+ for (const v of newValues) {
132
+ if (!this.values.includes(v)) {
133
+ this.values.push(v)
134
+ }
135
+ }
136
+ // Rebuild the validator with the updated values
137
+ ;(this as any).type = T.literalEnum(...this.values)
138
+ }
139
+
140
+ /**
141
+ * Remove values from this enum style prop at runtime. This is useful for narrowing
142
+ * the built-in styles with custom values (e.g. adding custom colors). Be sure to
143
+ * also modify the associated types.
144
+ *
145
+ * @param valuesToRemove - The values to remove.
146
+ *
147
+ * @public
148
+ */
149
+ removeValues(...valuesToRemove: T[]): void {
150
+ for (const v of valuesToRemove) {
151
+ if (this.values.includes(v)) {
152
+ this.values.splice(this.values.indexOf(v), 1)
153
+ }
154
+ }
155
+ // Rebuild the validator with the updated values
156
+ ;(this as any).type = T.literalEnum(...this.values)
120
157
  }
121
158
  }
122
159