@tldraw/tlschema 4.1.0-canary.e653ec63c99b → 4.1.0-canary.f2f81cd6fe2c
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/TLStore.js +3 -10
- package/dist-cjs/TLStore.js.map +2 -2
- package/dist-cjs/assets/TLBaseAsset.js.map +2 -2
- package/dist-cjs/assets/TLBookmarkAsset.js.map +2 -2
- package/dist-cjs/assets/TLImageAsset.js.map +2 -2
- package/dist-cjs/assets/TLVideoAsset.js.map +2 -2
- package/dist-cjs/bindings/TLArrowBinding.js.map +2 -2
- package/dist-cjs/bindings/TLBaseBinding.js.map +2 -2
- package/dist-cjs/createPresenceStateDerivation.js.map +2 -2
- package/dist-cjs/createTLSchema.js.map +2 -2
- package/dist-cjs/index.d.ts +4416 -223
- package/dist-cjs/index.js +1 -1
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/misc/TLColor.js.map +2 -2
- package/dist-cjs/misc/TLCursor.js.map +2 -2
- package/dist-cjs/misc/TLHandle.js.map +2 -2
- package/dist-cjs/misc/TLOpacity.js.map +2 -2
- package/dist-cjs/misc/TLRichText.js.map +2 -2
- package/dist-cjs/misc/TLScribble.js.map +2 -2
- package/dist-cjs/misc/geometry-types.js.map +2 -2
- package/dist-cjs/misc/id-validator.js.map +2 -2
- package/dist-cjs/records/TLAsset.js.map +2 -2
- package/dist-cjs/records/TLBinding.js.map +2 -2
- package/dist-cjs/records/TLCamera.js.map +2 -2
- package/dist-cjs/records/TLDocument.js.map +2 -2
- package/dist-cjs/records/TLInstance.js.map +2 -2
- package/dist-cjs/records/TLPage.js.map +2 -2
- package/dist-cjs/records/TLPageState.js.map +2 -2
- package/dist-cjs/records/TLPointer.js.map +2 -2
- package/dist-cjs/records/TLPresence.js.map +2 -2
- package/dist-cjs/records/TLRecord.js.map +1 -1
- package/dist-cjs/records/TLShape.js.map +2 -2
- package/dist-cjs/recordsWithProps.js.map +2 -2
- package/dist-cjs/shapes/ShapeWithCrop.js.map +1 -1
- package/dist-cjs/shapes/TLArrowShape.js.map +2 -2
- package/dist-cjs/shapes/TLBaseShape.js.map +2 -2
- package/dist-cjs/shapes/TLBookmarkShape.js.map +2 -2
- package/dist-cjs/shapes/TLDrawShape.js.map +2 -2
- package/dist-cjs/shapes/TLEmbedShape.js +0 -10
- package/dist-cjs/shapes/TLEmbedShape.js.map +2 -2
- package/dist-cjs/shapes/TLFrameShape.js.map +2 -2
- package/dist-cjs/shapes/TLGeoShape.js.map +2 -2
- package/dist-cjs/shapes/TLGroupShape.js.map +2 -2
- package/dist-cjs/shapes/TLHighlightShape.js.map +2 -2
- package/dist-cjs/shapes/TLImageShape.js.map +2 -2
- package/dist-cjs/shapes/TLLineShape.js.map +2 -2
- package/dist-cjs/shapes/TLNoteShape.js.map +2 -2
- package/dist-cjs/shapes/TLTextShape.js.map +2 -2
- package/dist-cjs/shapes/TLVideoShape.js.map +2 -2
- package/dist-cjs/store-migrations.js.map +2 -2
- package/dist-cjs/styles/TLColorStyle.js.map +2 -2
- package/dist-cjs/styles/TLDashStyle.js.map +2 -2
- package/dist-cjs/styles/TLFillStyle.js.map +2 -2
- package/dist-cjs/styles/TLFontStyle.js.map +2 -2
- package/dist-cjs/styles/TLHorizontalAlignStyle.js.map +2 -2
- package/dist-cjs/styles/TLSizeStyle.js.map +2 -2
- package/dist-cjs/styles/TLTextAlignStyle.js.map +2 -2
- package/dist-cjs/styles/TLVerticalAlignStyle.js.map +2 -2
- package/dist-cjs/translations/translations.js +1 -1
- package/dist-cjs/translations/translations.js.map +2 -2
- package/dist-cjs/util-types.js.map +1 -1
- package/dist-esm/TLStore.mjs +3 -10
- package/dist-esm/TLStore.mjs.map +2 -2
- package/dist-esm/assets/TLBaseAsset.mjs.map +2 -2
- package/dist-esm/assets/TLBookmarkAsset.mjs.map +2 -2
- package/dist-esm/assets/TLImageAsset.mjs.map +2 -2
- package/dist-esm/assets/TLVideoAsset.mjs.map +2 -2
- package/dist-esm/bindings/TLArrowBinding.mjs.map +2 -2
- package/dist-esm/bindings/TLBaseBinding.mjs.map +2 -2
- package/dist-esm/createPresenceStateDerivation.mjs.map +2 -2
- package/dist-esm/createTLSchema.mjs.map +2 -2
- package/dist-esm/index.d.mts +4416 -223
- package/dist-esm/index.mjs +1 -1
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/misc/TLColor.mjs.map +2 -2
- package/dist-esm/misc/TLCursor.mjs.map +2 -2
- package/dist-esm/misc/TLHandle.mjs.map +2 -2
- package/dist-esm/misc/TLOpacity.mjs.map +2 -2
- package/dist-esm/misc/TLRichText.mjs.map +2 -2
- package/dist-esm/misc/TLScribble.mjs.map +2 -2
- package/dist-esm/misc/geometry-types.mjs.map +2 -2
- package/dist-esm/misc/id-validator.mjs.map +2 -2
- package/dist-esm/records/TLAsset.mjs.map +2 -2
- package/dist-esm/records/TLBinding.mjs.map +2 -2
- package/dist-esm/records/TLCamera.mjs.map +2 -2
- package/dist-esm/records/TLDocument.mjs.map +2 -2
- package/dist-esm/records/TLInstance.mjs.map +2 -2
- package/dist-esm/records/TLPage.mjs.map +2 -2
- package/dist-esm/records/TLPageState.mjs.map +2 -2
- package/dist-esm/records/TLPointer.mjs.map +2 -2
- package/dist-esm/records/TLPresence.mjs.map +2 -2
- package/dist-esm/records/TLShape.mjs.map +2 -2
- package/dist-esm/recordsWithProps.mjs.map +2 -2
- package/dist-esm/shapes/TLArrowShape.mjs.map +2 -2
- package/dist-esm/shapes/TLBaseShape.mjs.map +2 -2
- package/dist-esm/shapes/TLBookmarkShape.mjs.map +2 -2
- package/dist-esm/shapes/TLDrawShape.mjs.map +2 -2
- package/dist-esm/shapes/TLEmbedShape.mjs +0 -10
- package/dist-esm/shapes/TLEmbedShape.mjs.map +2 -2
- package/dist-esm/shapes/TLFrameShape.mjs.map +2 -2
- package/dist-esm/shapes/TLGeoShape.mjs.map +2 -2
- package/dist-esm/shapes/TLGroupShape.mjs.map +2 -2
- package/dist-esm/shapes/TLHighlightShape.mjs.map +2 -2
- package/dist-esm/shapes/TLImageShape.mjs.map +2 -2
- package/dist-esm/shapes/TLLineShape.mjs.map +2 -2
- package/dist-esm/shapes/TLNoteShape.mjs.map +2 -2
- package/dist-esm/shapes/TLTextShape.mjs.map +2 -2
- package/dist-esm/shapes/TLVideoShape.mjs.map +2 -2
- package/dist-esm/store-migrations.mjs.map +2 -2
- package/dist-esm/styles/TLColorStyle.mjs.map +2 -2
- package/dist-esm/styles/TLDashStyle.mjs.map +2 -2
- package/dist-esm/styles/TLFillStyle.mjs.map +2 -2
- package/dist-esm/styles/TLFontStyle.mjs.map +2 -2
- package/dist-esm/styles/TLHorizontalAlignStyle.mjs.map +2 -2
- package/dist-esm/styles/TLSizeStyle.mjs.map +2 -2
- package/dist-esm/styles/TLTextAlignStyle.mjs.map +2 -2
- package/dist-esm/styles/TLVerticalAlignStyle.mjs.map +2 -2
- package/dist-esm/translations/translations.mjs +1 -1
- package/dist-esm/translations/translations.mjs.map +2 -2
- package/package.json +5 -5
- package/src/TLStore.test.ts +644 -0
- package/src/TLStore.ts +205 -20
- package/src/assets/TLBaseAsset.ts +90 -7
- package/src/assets/TLBookmarkAsset.test.ts +96 -0
- package/src/assets/TLBookmarkAsset.ts +52 -2
- package/src/assets/TLImageAsset.test.ts +213 -0
- package/src/assets/TLImageAsset.ts +60 -2
- package/src/assets/TLVideoAsset.test.ts +105 -0
- package/src/assets/TLVideoAsset.ts +93 -4
- package/src/bindings/TLArrowBinding.test.ts +55 -0
- package/src/bindings/TLArrowBinding.ts +132 -10
- package/src/bindings/TLBaseBinding.ts +140 -3
- package/src/createPresenceStateDerivation.test.ts +158 -0
- package/src/createPresenceStateDerivation.ts +71 -2
- package/src/createTLSchema.test.ts +181 -0
- package/src/createTLSchema.ts +164 -7
- package/src/index.ts +32 -0
- package/src/misc/TLColor.ts +50 -6
- package/src/misc/TLCursor.ts +110 -8
- package/src/misc/TLHandle.ts +86 -6
- package/src/misc/TLOpacity.ts +51 -2
- package/src/misc/TLRichText.ts +56 -3
- package/src/misc/TLScribble.ts +105 -5
- package/src/misc/geometry-types.ts +30 -2
- package/src/misc/id-validator.test.ts +50 -0
- package/src/misc/id-validator.ts +20 -1
- package/src/records/TLAsset.test.ts +234 -0
- package/src/records/TLAsset.ts +165 -8
- package/src/records/TLBinding.test.ts +22 -0
- package/src/records/TLBinding.ts +277 -11
- package/src/records/TLCamera.test.ts +19 -0
- package/src/records/TLCamera.ts +118 -7
- package/src/records/TLDocument.test.ts +35 -0
- package/src/records/TLDocument.ts +148 -8
- package/src/records/TLInstance.test.ts +201 -0
- package/src/records/TLInstance.ts +117 -9
- package/src/records/TLPage.test.ts +110 -0
- package/src/records/TLPage.ts +106 -8
- package/src/records/TLPageState.test.ts +228 -0
- package/src/records/TLPageState.ts +88 -7
- package/src/records/TLPointer.test.ts +63 -0
- package/src/records/TLPointer.ts +105 -7
- package/src/records/TLPresence.test.ts +190 -0
- package/src/records/TLPresence.ts +99 -5
- package/src/records/TLRecord.test.ts +70 -0
- package/src/records/TLRecord.ts +43 -1
- package/src/records/TLShape.test.ts +232 -0
- package/src/records/TLShape.ts +289 -12
- package/src/recordsWithProps.test.ts +188 -0
- package/src/recordsWithProps.ts +131 -2
- package/src/shapes/ShapeWithCrop.test.ts +18 -0
- package/src/shapes/ShapeWithCrop.ts +64 -2
- package/src/shapes/TLArrowShape.test.ts +505 -0
- package/src/shapes/TLArrowShape.ts +188 -10
- package/src/shapes/TLBaseShape.test.ts +142 -0
- package/src/shapes/TLBaseShape.ts +103 -4
- package/src/shapes/TLBookmarkShape.test.ts +122 -0
- package/src/shapes/TLBookmarkShape.ts +58 -4
- package/src/shapes/TLDrawShape.test.ts +177 -0
- package/src/shapes/TLDrawShape.ts +97 -6
- package/src/shapes/TLEmbedShape.test.ts +286 -0
- package/src/shapes/TLEmbedShape.ts +57 -14
- package/src/shapes/TLFrameShape.test.ts +71 -0
- package/src/shapes/TLFrameShape.ts +59 -4
- package/src/shapes/TLGeoShape.test.ts +247 -0
- package/src/shapes/TLGeoShape.ts +103 -7
- package/src/shapes/TLGroupShape.test.ts +59 -0
- package/src/shapes/TLGroupShape.ts +52 -4
- package/src/shapes/TLHighlightShape.test.ts +325 -0
- package/src/shapes/TLHighlightShape.ts +79 -4
- package/src/shapes/TLImageShape.test.ts +534 -0
- package/src/shapes/TLImageShape.ts +105 -5
- package/src/shapes/TLLineShape.test.ts +269 -0
- package/src/shapes/TLLineShape.ts +128 -8
- package/src/shapes/TLNoteShape.test.ts +1568 -0
- package/src/shapes/TLNoteShape.ts +97 -4
- package/src/shapes/TLTextShape.test.ts +407 -0
- package/src/shapes/TLTextShape.ts +94 -4
- package/src/shapes/TLVideoShape.test.ts +112 -0
- package/src/shapes/TLVideoShape.ts +99 -4
- package/src/store-migrations.test.ts +88 -0
- package/src/store-migrations.ts +47 -1
- package/src/styles/TLColorStyle.test.ts +439 -0
- package/src/styles/TLColorStyle.ts +228 -10
- package/src/styles/TLDashStyle.ts +54 -2
- package/src/styles/TLFillStyle.ts +54 -2
- package/src/styles/TLFontStyle.ts +72 -3
- package/src/styles/TLHorizontalAlignStyle.ts +55 -2
- package/src/styles/TLSizeStyle.ts +54 -2
- package/src/styles/TLTextAlignStyle.ts +52 -2
- package/src/styles/TLVerticalAlignStyle.ts +52 -2
- package/src/translations/translations.test.ts +378 -35
- package/src/translations/translations.ts +157 -10
- package/src/util-types.ts +51 -1
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
import { describe, expect, it, test } from 'vitest'
|
|
2
|
+
import {
|
|
3
|
+
defaultColorNames,
|
|
4
|
+
DefaultColorStyle,
|
|
5
|
+
DefaultColorThemePalette,
|
|
6
|
+
DefaultLabelColorStyle,
|
|
7
|
+
getColorValue,
|
|
8
|
+
getDefaultColorTheme,
|
|
9
|
+
isDefaultThemeColor,
|
|
10
|
+
TLDefaultColorStyle,
|
|
11
|
+
TLDefaultColorThemeColor,
|
|
12
|
+
} from './TLColorStyle'
|
|
13
|
+
|
|
14
|
+
describe('TLColorStyle', () => {
|
|
15
|
+
describe('defaultColorNames', () => {
|
|
16
|
+
it('should contain expected default colors', () => {
|
|
17
|
+
expect(defaultColorNames).toEqual([
|
|
18
|
+
'black',
|
|
19
|
+
'grey',
|
|
20
|
+
'light-violet',
|
|
21
|
+
'violet',
|
|
22
|
+
'blue',
|
|
23
|
+
'light-blue',
|
|
24
|
+
'yellow',
|
|
25
|
+
'orange',
|
|
26
|
+
'green',
|
|
27
|
+
'light-green',
|
|
28
|
+
'light-red',
|
|
29
|
+
'red',
|
|
30
|
+
'white',
|
|
31
|
+
])
|
|
32
|
+
})
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
describe('DefaultColorThemePalette', () => {
|
|
36
|
+
it('should contain all default colors for both themes', () => {
|
|
37
|
+
const lightTheme = DefaultColorThemePalette.lightMode
|
|
38
|
+
const darkTheme = DefaultColorThemePalette.darkMode
|
|
39
|
+
|
|
40
|
+
defaultColorNames.forEach((colorName) => {
|
|
41
|
+
expect(lightTheme).toHaveProperty(colorName)
|
|
42
|
+
expect(darkTheme).toHaveProperty(colorName)
|
|
43
|
+
})
|
|
44
|
+
})
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
describe('getDefaultColorTheme', () => {
|
|
48
|
+
it('should return light theme when isDarkMode is false', () => {
|
|
49
|
+
const result = getDefaultColorTheme({ isDarkMode: false })
|
|
50
|
+
expect(result).toBe(DefaultColorThemePalette.lightMode)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('should return dark theme when isDarkMode is true', () => {
|
|
54
|
+
const result = getDefaultColorTheme({ isDarkMode: true })
|
|
55
|
+
expect(result).toBe(DefaultColorThemePalette.darkMode)
|
|
56
|
+
})
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
describe('DefaultColorStyle', () => {
|
|
60
|
+
it('should validate all default color names', () => {
|
|
61
|
+
defaultColorNames.forEach((color) => {
|
|
62
|
+
expect(() => DefaultColorStyle.validate(color)).not.toThrow()
|
|
63
|
+
expect(DefaultColorStyle.validate(color)).toBe(color)
|
|
64
|
+
})
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
it('should reject invalid color names', () => {
|
|
68
|
+
const invalidColors = ['invalid', 'pink', 'purple', 'cyan', '']
|
|
69
|
+
|
|
70
|
+
invalidColors.forEach((color) => {
|
|
71
|
+
expect(() => DefaultColorStyle.validate(color)).toThrow()
|
|
72
|
+
})
|
|
73
|
+
})
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
describe('DefaultLabelColorStyle', () => {
|
|
77
|
+
it('should be a StyleProp with correct configuration', () => {
|
|
78
|
+
expect(DefaultLabelColorStyle.id).toBe('tldraw:labelColor')
|
|
79
|
+
expect(DefaultLabelColorStyle.defaultValue).toBe('black')
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
it('should validate all default color names', () => {
|
|
83
|
+
defaultColorNames.forEach((color) => {
|
|
84
|
+
expect(() => DefaultLabelColorStyle.validate(color)).not.toThrow()
|
|
85
|
+
expect(DefaultLabelColorStyle.validate(color)).toBe(color)
|
|
86
|
+
})
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it('should reject invalid color names', () => {
|
|
90
|
+
const invalidColors = ['invalid', 'pink', 'purple', 'cyan', '']
|
|
91
|
+
|
|
92
|
+
invalidColors.forEach((color) => {
|
|
93
|
+
expect(() => DefaultLabelColorStyle.validate(color)).toThrow()
|
|
94
|
+
})
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
it('should have values property with all default colors', () => {
|
|
98
|
+
expect(DefaultLabelColorStyle.values).toEqual(defaultColorNames)
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
it('should be separate from DefaultColorStyle', () => {
|
|
102
|
+
expect(DefaultColorStyle.id).not.toBe(DefaultLabelColorStyle.id)
|
|
103
|
+
expect(DefaultColorStyle).not.toBe(DefaultLabelColorStyle)
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
it('should allow different default values from DefaultColorStyle', () => {
|
|
107
|
+
const originalColorDefault = DefaultColorStyle.defaultValue
|
|
108
|
+
const originalLabelDefault = DefaultLabelColorStyle.defaultValue
|
|
109
|
+
|
|
110
|
+
DefaultColorStyle.setDefaultValue('red')
|
|
111
|
+
DefaultLabelColorStyle.setDefaultValue('blue')
|
|
112
|
+
|
|
113
|
+
expect(DefaultColorStyle.defaultValue).toBe('red')
|
|
114
|
+
expect(DefaultLabelColorStyle.defaultValue).toBe('blue')
|
|
115
|
+
expect(DefaultColorStyle.defaultValue).not.toBe(DefaultLabelColorStyle.defaultValue)
|
|
116
|
+
|
|
117
|
+
// Restore originals
|
|
118
|
+
DefaultColorStyle.setDefaultValue(originalColorDefault)
|
|
119
|
+
DefaultLabelColorStyle.setDefaultValue(originalLabelDefault)
|
|
120
|
+
})
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
describe('isDefaultThemeColor', () => {
|
|
124
|
+
it('should return true for all default color names', () => {
|
|
125
|
+
defaultColorNames.forEach((color) => {
|
|
126
|
+
expect(isDefaultThemeColor(color)).toBe(true)
|
|
127
|
+
})
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
it('should return false for invalid color names', () => {
|
|
131
|
+
const invalidColors = ['invalid', 'pink', 'purple', 'cyan', '', 'custom-color']
|
|
132
|
+
|
|
133
|
+
invalidColors.forEach((color) => {
|
|
134
|
+
expect(isDefaultThemeColor(color as TLDefaultColorStyle)).toBe(false)
|
|
135
|
+
})
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
it('should return false for hex colors', () => {
|
|
139
|
+
const hexColors = ['#ff0000', '#00ff00', '#0000ff', '#ffffff', '#000000']
|
|
140
|
+
|
|
141
|
+
hexColors.forEach((color) => {
|
|
142
|
+
expect(isDefaultThemeColor(color as TLDefaultColorStyle)).toBe(false)
|
|
143
|
+
})
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
it('should return false for CSS color names not in defaults', () => {
|
|
147
|
+
// Use CSS color names that are NOT in the default color list
|
|
148
|
+
const cssColors = ['aqua', 'fuchsia', 'lime', 'navy', 'silver']
|
|
149
|
+
|
|
150
|
+
cssColors.forEach((color) => {
|
|
151
|
+
expect(isDefaultThemeColor(color as TLDefaultColorStyle)).toBe(false)
|
|
152
|
+
})
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
it('should handle edge cases', () => {
|
|
156
|
+
expect(isDefaultThemeColor(null as any)).toBe(false)
|
|
157
|
+
expect(isDefaultThemeColor(undefined as any)).toBe(false)
|
|
158
|
+
expect(isDefaultThemeColor(123 as any)).toBe(false)
|
|
159
|
+
expect(isDefaultThemeColor({} as any)).toBe(false)
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
it('should be case sensitive', () => {
|
|
163
|
+
expect(isDefaultThemeColor('Black' as TLDefaultColorStyle)).toBe(false)
|
|
164
|
+
expect(isDefaultThemeColor('RED' as TLDefaultColorStyle)).toBe(false)
|
|
165
|
+
expect(isDefaultThemeColor('Blue' as TLDefaultColorStyle)).toBe(false)
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
it('should work as a type guard', () => {
|
|
169
|
+
const color: TLDefaultColorStyle = 'red'
|
|
170
|
+
|
|
171
|
+
if (isDefaultThemeColor(color)) {
|
|
172
|
+
// TypeScript should narrow the type here
|
|
173
|
+
expect(defaultColorNames.includes(color)).toBe(true)
|
|
174
|
+
}
|
|
175
|
+
})
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
describe('getColorValue', () => {
|
|
179
|
+
const lightTheme = DefaultColorThemePalette.lightMode
|
|
180
|
+
const darkTheme = DefaultColorThemePalette.darkMode
|
|
181
|
+
|
|
182
|
+
it('should return correct color values for default colors', () => {
|
|
183
|
+
expect(getColorValue(lightTheme, 'red', 'solid')).toBe('#e03131')
|
|
184
|
+
expect(getColorValue(lightTheme, 'blue', 'fill')).toBe('#4465e9')
|
|
185
|
+
expect(getColorValue(lightTheme, 'black', 'solid')).toBe('#1d1d1d')
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
it('should work with different variants', () => {
|
|
189
|
+
const variants: (keyof TLDefaultColorThemeColor)[] = [
|
|
190
|
+
'solid',
|
|
191
|
+
'semi',
|
|
192
|
+
'pattern',
|
|
193
|
+
'fill',
|
|
194
|
+
'frameHeadingStroke',
|
|
195
|
+
'frameHeadingFill',
|
|
196
|
+
'frameStroke',
|
|
197
|
+
'frameFill',
|
|
198
|
+
'frameText',
|
|
199
|
+
'noteFill',
|
|
200
|
+
'noteText',
|
|
201
|
+
'highlightSrgb',
|
|
202
|
+
'highlightP3',
|
|
203
|
+
]
|
|
204
|
+
|
|
205
|
+
variants.forEach((variant) => {
|
|
206
|
+
const result = getColorValue(lightTheme, 'red', variant)
|
|
207
|
+
expect(typeof result).toBe('string')
|
|
208
|
+
expect(result.length).toBeGreaterThan(0)
|
|
209
|
+
expect(result).toBe(lightTheme.red[variant])
|
|
210
|
+
})
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
it('should return different values for light and dark themes', () => {
|
|
214
|
+
// Use colors/variants that actually differ between themes
|
|
215
|
+
expect(getColorValue(lightTheme, 'black', 'solid')).not.toBe(
|
|
216
|
+
getColorValue(darkTheme, 'black', 'solid')
|
|
217
|
+
)
|
|
218
|
+
expect(getColorValue(lightTheme, 'white', 'solid')).not.toBe(
|
|
219
|
+
getColorValue(darkTheme, 'white', 'solid')
|
|
220
|
+
)
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
it('should pass through non-default colors unchanged', () => {
|
|
224
|
+
const customColors = ['#ff0000', '#00ff00', '#0000ff', 'custom-color', 'rgb(255, 0, 0)']
|
|
225
|
+
|
|
226
|
+
customColors.forEach((color) => {
|
|
227
|
+
expect(getColorValue(lightTheme, color as TLDefaultColorStyle, 'solid')).toBe(color)
|
|
228
|
+
expect(getColorValue(darkTheme, color as TLDefaultColorStyle, 'fill')).toBe(color)
|
|
229
|
+
})
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
it('should work with all default colors', () => {
|
|
233
|
+
defaultColorNames.forEach((colorName) => {
|
|
234
|
+
const lightResult = getColorValue(lightTheme, colorName, 'solid')
|
|
235
|
+
const darkResult = getColorValue(darkTheme, colorName, 'solid')
|
|
236
|
+
|
|
237
|
+
expect(typeof lightResult).toBe('string')
|
|
238
|
+
expect(typeof darkResult).toBe('string')
|
|
239
|
+
expect(lightResult).toBe(lightTheme[colorName].solid)
|
|
240
|
+
expect(darkResult).toBe(darkTheme[colorName].solid)
|
|
241
|
+
})
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
it('should handle edge cases gracefully', () => {
|
|
245
|
+
// Test with empty string
|
|
246
|
+
expect(getColorValue(lightTheme, '' as TLDefaultColorStyle, 'solid')).toBe('')
|
|
247
|
+
|
|
248
|
+
// Test with null/undefined (they should pass through)
|
|
249
|
+
expect(getColorValue(lightTheme, null as any, 'solid')).toBe(null)
|
|
250
|
+
expect(getColorValue(lightTheme, undefined as any, 'solid')).toBe(undefined)
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
it('should work consistently across all variants for a color', () => {
|
|
254
|
+
const color = 'blue'
|
|
255
|
+
const variants: (keyof TLDefaultColorThemeColor)[] = [
|
|
256
|
+
'solid',
|
|
257
|
+
'semi',
|
|
258
|
+
'pattern',
|
|
259
|
+
'fill',
|
|
260
|
+
'frameHeadingStroke',
|
|
261
|
+
'frameHeadingFill',
|
|
262
|
+
'frameStroke',
|
|
263
|
+
'frameFill',
|
|
264
|
+
'frameText',
|
|
265
|
+
'noteFill',
|
|
266
|
+
'noteText',
|
|
267
|
+
'highlightSrgb',
|
|
268
|
+
'highlightP3',
|
|
269
|
+
]
|
|
270
|
+
|
|
271
|
+
variants.forEach((variant) => {
|
|
272
|
+
const lightResult = getColorValue(lightTheme, color, variant)
|
|
273
|
+
const darkResult = getColorValue(darkTheme, color, variant)
|
|
274
|
+
|
|
275
|
+
expect(lightResult).toBe(lightTheme[color][variant])
|
|
276
|
+
expect(darkResult).toBe(darkTheme[color][variant])
|
|
277
|
+
})
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
it('should maintain consistency with isDefaultThemeColor', () => {
|
|
281
|
+
const testColors = [...defaultColorNames, '#ff0000', 'custom', 'invalid']
|
|
282
|
+
|
|
283
|
+
testColors.forEach((color) => {
|
|
284
|
+
const isDefault = isDefaultThemeColor(color as TLDefaultColorStyle)
|
|
285
|
+
const result = getColorValue(lightTheme, color as TLDefaultColorStyle, 'solid')
|
|
286
|
+
|
|
287
|
+
if (isDefault) {
|
|
288
|
+
// Should return the theme color value
|
|
289
|
+
expect(result).toBe(
|
|
290
|
+
(lightTheme[color as keyof typeof lightTheme] as TLDefaultColorThemeColor).solid
|
|
291
|
+
)
|
|
292
|
+
} else {
|
|
293
|
+
// Should pass through unchanged
|
|
294
|
+
expect(result).toBe(color)
|
|
295
|
+
}
|
|
296
|
+
})
|
|
297
|
+
})
|
|
298
|
+
})
|
|
299
|
+
|
|
300
|
+
describe('type safety and integration', () => {
|
|
301
|
+
it('should have proper TypeScript types', () => {
|
|
302
|
+
// Test that TLDefaultColorStyle is properly typed
|
|
303
|
+
const validColor: TLDefaultColorStyle = 'red'
|
|
304
|
+
expect(DefaultColorStyle.validate(validColor)).toBe('red')
|
|
305
|
+
})
|
|
306
|
+
|
|
307
|
+
it('should work with both color style props', () => {
|
|
308
|
+
const colorValue: TLDefaultColorStyle = 'blue'
|
|
309
|
+
const labelColorValue: TLDefaultColorStyle = 'white'
|
|
310
|
+
|
|
311
|
+
expect(DefaultColorStyle.validate(colorValue)).toBe('blue')
|
|
312
|
+
expect(DefaultLabelColorStyle.validate(labelColorValue)).toBe('white')
|
|
313
|
+
})
|
|
314
|
+
|
|
315
|
+
it('should integrate properly with theme system', () => {
|
|
316
|
+
const theme = getDefaultColorTheme({ isDarkMode: false })
|
|
317
|
+
const color: TLDefaultColorStyle = 'red'
|
|
318
|
+
|
|
319
|
+
if (isDefaultThemeColor(color)) {
|
|
320
|
+
const colorValue = getColorValue(theme, color, 'solid')
|
|
321
|
+
expect(typeof colorValue).toBe('string')
|
|
322
|
+
expect(colorValue).toBe(theme.red.solid)
|
|
323
|
+
}
|
|
324
|
+
})
|
|
325
|
+
|
|
326
|
+
it('should maintain consistent behavior across all exports', () => {
|
|
327
|
+
// Test that all parts work together correctly
|
|
328
|
+
const theme = getDefaultColorTheme({ isDarkMode: false })
|
|
329
|
+
|
|
330
|
+
defaultColorNames.forEach((colorName) => {
|
|
331
|
+
// Should validate in both style props
|
|
332
|
+
expect(DefaultColorStyle.validate(colorName)).toBe(colorName)
|
|
333
|
+
expect(DefaultLabelColorStyle.validate(colorName)).toBe(colorName)
|
|
334
|
+
|
|
335
|
+
// Should be recognized as default theme color
|
|
336
|
+
expect(isDefaultThemeColor(colorName)).toBe(true)
|
|
337
|
+
|
|
338
|
+
// Should resolve to theme color value
|
|
339
|
+
const colorValue = getColorValue(theme, colorName, 'solid')
|
|
340
|
+
expect(colorValue).toBe(theme[colorName].solid)
|
|
341
|
+
})
|
|
342
|
+
})
|
|
343
|
+
})
|
|
344
|
+
|
|
345
|
+
describe('error handling and edge cases', () => {
|
|
346
|
+
it('should handle malformed theme objects gracefully', () => {
|
|
347
|
+
// Create a partial theme for testing edge cases
|
|
348
|
+
const partialTheme = {
|
|
349
|
+
...DefaultColorThemePalette.lightMode,
|
|
350
|
+
red: {
|
|
351
|
+
...DefaultColorThemePalette.lightMode.red,
|
|
352
|
+
solid: undefined,
|
|
353
|
+
} as any,
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// getColorValue should still work but return undefined for this case
|
|
357
|
+
expect(getColorValue(partialTheme, 'red', 'solid')).toBe(undefined)
|
|
358
|
+
})
|
|
359
|
+
|
|
360
|
+
it('should handle very large color names', () => {
|
|
361
|
+
const longColorName = 'a'.repeat(1000)
|
|
362
|
+
expect(isDefaultThemeColor(longColorName as TLDefaultColorStyle)).toBe(false)
|
|
363
|
+
expect(
|
|
364
|
+
getColorValue(
|
|
365
|
+
DefaultColorThemePalette.lightMode,
|
|
366
|
+
longColorName as TLDefaultColorStyle,
|
|
367
|
+
'solid'
|
|
368
|
+
)
|
|
369
|
+
).toBe(longColorName)
|
|
370
|
+
})
|
|
371
|
+
|
|
372
|
+
it('should handle special characters in color values', () => {
|
|
373
|
+
const specialColors = ['color-with-dashes', 'color_with_underscores', 'color.with.dots']
|
|
374
|
+
|
|
375
|
+
specialColors.forEach((color) => {
|
|
376
|
+
expect(isDefaultThemeColor(color as TLDefaultColorStyle)).toBe(false)
|
|
377
|
+
expect(
|
|
378
|
+
getColorValue(DefaultColorThemePalette.lightMode, color as TLDefaultColorStyle, 'solid')
|
|
379
|
+
).toBe(color)
|
|
380
|
+
})
|
|
381
|
+
})
|
|
382
|
+
|
|
383
|
+
test('should maintain immutability of exported objects', () => {
|
|
384
|
+
const originalLightTheme = DefaultColorThemePalette.lightMode
|
|
385
|
+
const originalDarkTheme = DefaultColorThemePalette.darkMode
|
|
386
|
+
const originalColorNames = defaultColorNames
|
|
387
|
+
|
|
388
|
+
// These should be the same references
|
|
389
|
+
expect(getDefaultColorTheme({ isDarkMode: false })).toBe(originalLightTheme)
|
|
390
|
+
expect(getDefaultColorTheme({ isDarkMode: true })).toBe(originalDarkTheme)
|
|
391
|
+
|
|
392
|
+
// Arrays should maintain their values
|
|
393
|
+
expect(defaultColorNames).toEqual(originalColorNames)
|
|
394
|
+
expect(DefaultColorStyle.values).toEqual(originalColorNames)
|
|
395
|
+
})
|
|
396
|
+
})
|
|
397
|
+
|
|
398
|
+
describe('performance considerations', () => {
|
|
399
|
+
it('should validate colors efficiently', () => {
|
|
400
|
+
const start = performance.now()
|
|
401
|
+
|
|
402
|
+
for (let i = 0; i < 1000; i++) {
|
|
403
|
+
defaultColorNames.forEach((color) => {
|
|
404
|
+
DefaultColorStyle.validate(color)
|
|
405
|
+
isDefaultThemeColor(color)
|
|
406
|
+
})
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
const end = performance.now()
|
|
410
|
+
expect(end - start).toBeLessThan(100) // Should be fast
|
|
411
|
+
})
|
|
412
|
+
|
|
413
|
+
it('should resolve color values efficiently', () => {
|
|
414
|
+
const theme = DefaultColorThemePalette.lightMode
|
|
415
|
+
const start = performance.now()
|
|
416
|
+
|
|
417
|
+
for (let i = 0; i < 1000; i++) {
|
|
418
|
+
defaultColorNames.forEach((color) => {
|
|
419
|
+
getColorValue(theme, color, 'solid')
|
|
420
|
+
getColorValue(theme, color, 'fill')
|
|
421
|
+
})
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
const end = performance.now()
|
|
425
|
+
expect(end - start).toBeLessThan(50) // Should be very fast
|
|
426
|
+
})
|
|
427
|
+
|
|
428
|
+
it('should handle theme switching efficiently', () => {
|
|
429
|
+
const start = performance.now()
|
|
430
|
+
|
|
431
|
+
for (let i = 0; i < 1000; i++) {
|
|
432
|
+
getDefaultColorTheme({ isDarkMode: i % 2 === 0 })
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
const end = performance.now()
|
|
436
|
+
expect(end - start).toBeLessThan(10) // Should be extremely fast (just returns references)
|
|
437
|
+
})
|
|
438
|
+
})
|
|
439
|
+
})
|