tldraw 3.16.0-canary.f293c3bb58f5 → 3.16.0-canary.f31480866d04

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 (205) hide show
  1. package/dist-cjs/index.d.ts +153 -102
  2. package/dist-cjs/index.js +29 -14
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/Tldraw.js +12 -2
  5. package/dist-cjs/lib/Tldraw.js.map +2 -2
  6. package/dist-cjs/lib/defaultExternalContentHandlers.js +5 -4
  7. package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
  8. package/dist-cjs/lib/shapes/arrow/arrowLabel.js +6 -0
  9. package/dist-cjs/lib/shapes/arrow/arrowLabel.js.map +3 -3
  10. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +6 -0
  11. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
  12. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +3 -0
  13. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js.map +2 -2
  14. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +1 -3
  15. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +2 -2
  16. package/dist-cjs/lib/shapes/shared/useEditablePlainText.js +0 -2
  17. package/dist-cjs/lib/shapes/shared/useEditablePlainText.js.map +2 -2
  18. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js +0 -2
  19. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js.map +2 -2
  20. package/dist-cjs/lib/ui/TldrawUi.js +13 -12
  21. package/dist-cjs/lib/ui/TldrawUi.js.map +2 -2
  22. package/dist-cjs/lib/ui/components/{FollowingIndicator.js → DefaultFollowingIndicator.js} +6 -6
  23. package/dist-cjs/lib/ui/components/DefaultFollowingIndicator.js.map +7 -0
  24. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +5 -5
  25. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +1 -1
  26. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js +9 -4
  27. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js.map +2 -2
  28. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +255 -316
  29. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js.map +2 -2
  30. package/dist-cjs/lib/ui/components/{primitives/TldrawUiButtonPicker.js → StylePanel/StylePanelButtonPicker.js} +52 -45
  31. package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js.map +7 -0
  32. package/dist-cjs/lib/ui/components/StylePanel/StylePanelContext.js +68 -0
  33. package/dist-cjs/lib/ui/components/StylePanel/StylePanelContext.js.map +7 -0
  34. package/dist-cjs/lib/ui/components/StylePanel/{DoubleDropdownPicker.js → StylePanelDoubleDropdownPicker.js} +23 -22
  35. package/dist-cjs/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.js.map +7 -0
  36. package/dist-cjs/lib/ui/components/StylePanel/{DropdownPicker.js → StylePanelDropdownPicker.js} +23 -20
  37. package/dist-cjs/lib/ui/components/StylePanel/StylePanelDropdownPicker.js.map +7 -0
  38. package/dist-cjs/lib/ui/components/StylePanel/StylePanelSubheading.js +28 -0
  39. package/dist-cjs/lib/ui/components/StylePanel/StylePanelSubheading.js.map +7 -0
  40. package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js +3 -2
  41. package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js.map +2 -2
  42. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js +38 -9
  43. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js.map +2 -2
  44. package/dist-cjs/lib/ui/components/Toolbar/DefaultVideoToolbarContent.js +15 -3
  45. package/dist-cjs/lib/ui/components/Toolbar/DefaultVideoToolbarContent.js.map +2 -2
  46. package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js +3 -3
  47. package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js.map +2 -2
  48. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +10 -1
  49. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +2 -2
  50. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +17 -4
  51. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
  52. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +2 -0
  53. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
  54. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +7 -0
  55. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
  56. package/dist-cjs/lib/ui/context/actions.js +7 -8
  57. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  58. package/dist-cjs/lib/ui/context/components.js +2 -0
  59. package/dist-cjs/lib/ui/context/components.js.map +2 -2
  60. package/dist-cjs/lib/ui/context/events.js.map +1 -1
  61. package/dist-cjs/lib/ui/hooks/useExportAs.js +3 -2
  62. package/dist-cjs/lib/ui/hooks/useExportAs.js.map +2 -2
  63. package/dist-cjs/lib/ui/hooks/useTools.js +1 -1
  64. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  65. package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
  66. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +2 -0
  67. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
  68. package/dist-cjs/lib/ui/kbd-utils.js +9 -3
  69. package/dist-cjs/lib/ui/kbd-utils.js.map +2 -2
  70. package/dist-cjs/lib/ui/version.js +3 -3
  71. package/dist-cjs/lib/ui/version.js.map +1 -1
  72. package/dist-cjs/lib/utils/export/copyAs.js +1 -2
  73. package/dist-cjs/lib/utils/export/copyAs.js.map +2 -2
  74. package/dist-cjs/lib/utils/export/export.js +0 -20
  75. package/dist-cjs/lib/utils/export/export.js.map +2 -2
  76. package/dist-cjs/lib/utils/export/exportAs.js +1 -2
  77. package/dist-cjs/lib/utils/export/exportAs.js.map +2 -2
  78. package/dist-esm/index.d.mts +153 -102
  79. package/dist-esm/index.mjs +57 -29
  80. package/dist-esm/index.mjs.map +2 -2
  81. package/dist-esm/lib/Tldraw.mjs +14 -4
  82. package/dist-esm/lib/Tldraw.mjs.map +2 -2
  83. package/dist-esm/lib/defaultExternalContentHandlers.mjs +5 -4
  84. package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
  85. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs +6 -0
  86. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs.map +3 -3
  87. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +6 -0
  88. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
  89. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +3 -0
  90. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +2 -2
  91. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs +1 -3
  92. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
  93. package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs +0 -2
  94. package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs.map +2 -2
  95. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs +0 -2
  96. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs.map +2 -2
  97. package/dist-esm/lib/ui/TldrawUi.mjs +13 -12
  98. package/dist-esm/lib/ui/TldrawUi.mjs.map +2 -2
  99. package/dist-esm/lib/ui/components/{FollowingIndicator.mjs → DefaultFollowingIndicator.mjs} +3 -3
  100. package/dist-esm/lib/ui/components/DefaultFollowingIndicator.mjs.map +7 -0
  101. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +5 -5
  102. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +1 -1
  103. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs +14 -5
  104. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs.map +2 -2
  105. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs +257 -320
  106. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs.map +2 -2
  107. package/dist-esm/lib/ui/components/{primitives/TldrawUiButtonPicker.mjs → StylePanel/StylePanelButtonPicker.mjs} +54 -43
  108. package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs.map +7 -0
  109. package/dist-esm/lib/ui/components/StylePanel/StylePanelContext.mjs +48 -0
  110. package/dist-esm/lib/ui/components/StylePanel/StylePanelContext.mjs.map +7 -0
  111. package/dist-esm/lib/ui/components/StylePanel/{DoubleDropdownPicker.mjs → StylePanelDoubleDropdownPicker.mjs} +20 -19
  112. package/dist-esm/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.mjs.map +7 -0
  113. package/dist-esm/lib/ui/components/StylePanel/{DropdownPicker.mjs → StylePanelDropdownPicker.mjs} +20 -17
  114. package/dist-esm/lib/ui/components/StylePanel/StylePanelDropdownPicker.mjs.map +7 -0
  115. package/dist-esm/lib/ui/components/StylePanel/StylePanelSubheading.mjs +8 -0
  116. package/dist-esm/lib/ui/components/StylePanel/StylePanelSubheading.mjs.map +7 -0
  117. package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs +3 -2
  118. package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs.map +2 -2
  119. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs +38 -9
  120. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs.map +2 -2
  121. package/dist-esm/lib/ui/components/Toolbar/DefaultVideoToolbarContent.mjs +15 -3
  122. package/dist-esm/lib/ui/components/Toolbar/DefaultVideoToolbarContent.mjs.map +2 -2
  123. package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs +3 -3
  124. package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs.map +2 -2
  125. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs +10 -1
  126. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs.map +2 -2
  127. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs +17 -4
  128. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs.map +2 -2
  129. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +2 -0
  130. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
  131. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +7 -0
  132. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
  133. package/dist-esm/lib/ui/context/actions.mjs +7 -8
  134. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  135. package/dist-esm/lib/ui/context/components.mjs +2 -0
  136. package/dist-esm/lib/ui/context/components.mjs.map +2 -2
  137. package/dist-esm/lib/ui/context/events.mjs.map +1 -1
  138. package/dist-esm/lib/ui/hooks/useExportAs.mjs +3 -2
  139. package/dist-esm/lib/ui/hooks/useExportAs.mjs.map +2 -2
  140. package/dist-esm/lib/ui/hooks/useTools.mjs +1 -1
  141. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  142. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +2 -0
  143. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
  144. package/dist-esm/lib/ui/kbd-utils.mjs +9 -3
  145. package/dist-esm/lib/ui/kbd-utils.mjs.map +2 -2
  146. package/dist-esm/lib/ui/version.mjs +3 -3
  147. package/dist-esm/lib/ui/version.mjs.map +1 -1
  148. package/dist-esm/lib/utils/export/copyAs.mjs +1 -2
  149. package/dist-esm/lib/utils/export/copyAs.mjs.map +2 -2
  150. package/dist-esm/lib/utils/export/export.mjs +0 -20
  151. package/dist-esm/lib/utils/export/export.mjs.map +2 -2
  152. package/dist-esm/lib/utils/export/exportAs.mjs +1 -2
  153. package/dist-esm/lib/utils/export/exportAs.mjs.map +2 -2
  154. package/package.json +3 -3
  155. package/src/index.ts +41 -22
  156. package/src/lib/Tldraw.tsx +15 -2
  157. package/src/lib/defaultExternalContentHandlers.ts +12 -4
  158. package/src/lib/shapes/arrow/arrowLabel.ts +8 -0
  159. package/src/lib/shapes/frame/FrameShapeUtil.tsx +8 -0
  160. package/src/lib/shapes/image/ImageShapeUtil.tsx +3 -0
  161. package/src/lib/shapes/shared/PlainTextLabel.tsx +0 -6
  162. package/src/lib/shapes/shared/useEditablePlainText.ts +0 -6
  163. package/src/lib/shapes/shared/useImageOrVideoAsset.ts +0 -7
  164. package/src/lib/ui/TldrawUi.tsx +16 -10
  165. package/src/lib/ui/components/{FollowingIndicator.tsx → DefaultFollowingIndicator.tsx} +2 -1
  166. package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +5 -5
  167. package/src/lib/ui/components/StylePanel/DefaultStylePanel.tsx +27 -13
  168. package/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx +260 -381
  169. package/src/lib/ui/components/{primitives/TldrawUiButtonPicker.tsx → StylePanel/StylePanelButtonPicker.tsx} +63 -50
  170. package/src/lib/ui/components/StylePanel/StylePanelContext.tsx +63 -0
  171. package/src/lib/ui/components/StylePanel/{DoubleDropdownPicker.tsx → StylePanelDoubleDropdownPicker.tsx} +28 -19
  172. package/src/lib/ui/components/StylePanel/StylePanelDropdownPicker.tsx +119 -0
  173. package/src/lib/ui/components/StylePanel/StylePanelSubheading.tsx +9 -0
  174. package/src/lib/ui/components/Toolbar/AltTextEditor.tsx +4 -3
  175. package/src/lib/ui/components/Toolbar/DefaultImageToolbarContent.tsx +32 -15
  176. package/src/lib/ui/components/Toolbar/DefaultVideoToolbarContent.tsx +12 -4
  177. package/src/lib/ui/components/Toolbar/LinkEditor.tsx +5 -5
  178. package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +6 -1
  179. package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +50 -30
  180. package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +3 -0
  181. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +10 -0
  182. package/src/lib/ui/context/actions.tsx +7 -8
  183. package/src/lib/ui/context/components.tsx +3 -0
  184. package/src/lib/ui/context/events.tsx +1 -1
  185. package/src/lib/ui/hooks/useExportAs.ts +3 -2
  186. package/src/lib/ui/hooks/useTools.tsx +1 -1
  187. package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +2 -0
  188. package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +2 -0
  189. package/src/lib/ui/kbd-utils.ts +10 -3
  190. package/src/lib/ui/version.ts +3 -3
  191. package/src/lib/ui.css +16 -2
  192. package/src/lib/utils/export/copyAs.ts +1 -24
  193. package/src/lib/utils/export/export.ts +0 -36
  194. package/src/lib/utils/export/exportAs.ts +1 -32
  195. package/src/test/custom-clipping.test.ts +436 -0
  196. package/tldraw.css +32 -5
  197. package/dist-cjs/lib/ui/components/FollowingIndicator.js.map +0 -7
  198. package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js.map +0 -7
  199. package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js.map +0 -7
  200. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map +0 -7
  201. package/dist-esm/lib/ui/components/FollowingIndicator.mjs.map +0 -7
  202. package/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs.map +0 -7
  203. package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs.map +0 -7
  204. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map +0 -7
  205. package/src/lib/ui/components/StylePanel/DropdownPicker.tsx +0 -110
@@ -0,0 +1,436 @@
1
+ import {
2
+ atom,
3
+ BaseBoxShapeUtil,
4
+ Circle2d,
5
+ createShapeId,
6
+ Geometry2d,
7
+ RecordProps,
8
+ resizeBox,
9
+ StateNode,
10
+ T,
11
+ TLBaseShape,
12
+ TLEventHandlers,
13
+ TLGeoShape,
14
+ TLResizeInfo,
15
+ TLShape,
16
+ TLTextShape,
17
+ toRichText,
18
+ Vec,
19
+ } from '@tldraw/editor'
20
+ import { TestEditor } from './TestEditor'
21
+
22
+ // Custom Circle Clip Shape Definition
23
+ export type CircleClipShape = TLBaseShape<
24
+ 'circle-clip',
25
+ {
26
+ w: number
27
+ h: number
28
+ }
29
+ >
30
+
31
+ export const isClippingEnabled$ = atom('isClippingEnabled', true)
32
+
33
+ export class CircleClipShapeUtil extends BaseBoxShapeUtil<CircleClipShape> {
34
+ static override type = 'circle-clip' as const
35
+ static override props: RecordProps<CircleClipShape> = {
36
+ w: T.number,
37
+ h: T.number,
38
+ }
39
+
40
+ override canBind() {
41
+ return false
42
+ }
43
+
44
+ override canReceiveNewChildrenOfType(shape: TLShape) {
45
+ return !shape.isLocked
46
+ }
47
+
48
+ override getDefaultProps(): CircleClipShape['props'] {
49
+ return {
50
+ w: 200,
51
+ h: 200,
52
+ }
53
+ }
54
+
55
+ override getGeometry(shape: CircleClipShape): Geometry2d {
56
+ const radius = Math.min(shape.props.w, shape.props.h) / 2
57
+ return new Circle2d({
58
+ radius,
59
+ x: shape.props.w / 2 - radius,
60
+ y: shape.props.h / 2 - radius,
61
+ isFilled: true,
62
+ })
63
+ }
64
+
65
+ override getClipPath(shape: CircleClipShape): Vec[] | undefined {
66
+ // Generate a polygon approximation of the circle
67
+ const centerX = shape.props.w / 2
68
+ const centerY = shape.props.h / 2
69
+ const radius = Math.min(shape.props.w, shape.props.h) / 2
70
+ const segments = 48 // More segments = smoother circle
71
+
72
+ const points: Vec[] = []
73
+ for (let i = 0; i < segments; i++) {
74
+ const angle = (i / segments) * Math.PI * 2
75
+ const x = centerX + Math.cos(angle) * radius
76
+ const y = centerY + Math.sin(angle) * radius
77
+ points.push(new Vec(x, y))
78
+ }
79
+
80
+ return points
81
+ }
82
+
83
+ override shouldClipChild(_child: TLShape): boolean {
84
+ // For now, clip all children - we removed the onlyClipText feature for simplicity
85
+ return isClippingEnabled$.get()
86
+ }
87
+
88
+ override component(_shape: CircleClipShape) {
89
+ // For testing purposes, we'll just return null
90
+ // In a real implementation, this would return JSX
91
+ return null as any
92
+ }
93
+
94
+ override indicator(_shape: CircleClipShape) {
95
+ // For testing purposes, we'll just return null
96
+ // In a real implementation, this would return JSX
97
+ return null as any
98
+ }
99
+
100
+ override onResize(shape: CircleClipShape, info: TLResizeInfo<CircleClipShape>) {
101
+ return resizeBox(shape, info)
102
+ }
103
+ }
104
+
105
+ export class CircleClipShapeTool extends StateNode {
106
+ static override id = 'circle-clip'
107
+
108
+ override onEnter(): void {
109
+ this.editor.setCursor({ type: 'cross', rotation: 0 })
110
+ }
111
+
112
+ override onPointerDown(info: Parameters<TLEventHandlers['onPointerDown']>[0]) {
113
+ if (info.target === 'canvas') {
114
+ const { originPagePoint } = this.editor.inputs
115
+
116
+ this.editor.createShape<CircleClipShape>({
117
+ type: 'circle-clip',
118
+ x: originPagePoint.x - 100,
119
+ y: originPagePoint.y - 100,
120
+ props: {
121
+ w: 200,
122
+ h: 200,
123
+ },
124
+ })
125
+ }
126
+ }
127
+ }
128
+
129
+ let editor: TestEditor
130
+
131
+ afterEach(() => {
132
+ editor?.dispose()
133
+ })
134
+
135
+ const ids = {
136
+ circleClip1: createShapeId('circleClip1'),
137
+ circleClip2: createShapeId('circleClip2'),
138
+ text1: createShapeId('text1'),
139
+ geo1: createShapeId('geo1'),
140
+ geo2: createShapeId('geo2'),
141
+ }
142
+
143
+ beforeEach(() => {
144
+ editor = new TestEditor({
145
+ shapeUtils: [CircleClipShapeUtil],
146
+ tools: [CircleClipShapeTool],
147
+ })
148
+
149
+ // Reset clipping state
150
+ isClippingEnabled$.set(true)
151
+ })
152
+
153
+ describe('CircleClipShapeUtil', () => {
154
+ describe('shape creation and properties', () => {
155
+ it('should create a circle clip shape with default properties', () => {
156
+ editor.createShape<CircleClipShape>({
157
+ id: ids.circleClip1,
158
+ type: 'circle-clip',
159
+ x: 100,
160
+ y: 100,
161
+ props: {
162
+ w: 200,
163
+ h: 200,
164
+ },
165
+ })
166
+
167
+ const shape = editor.getShape<CircleClipShape>(ids.circleClip1)
168
+ expect(shape).toBeDefined()
169
+ expect(shape!.type).toBe('circle-clip')
170
+ expect(shape!.props.w).toBe(200)
171
+ expect(shape!.props.h).toBe(200)
172
+ })
173
+
174
+ it('should use default props when not specified', () => {
175
+ editor.createShape<CircleClipShape>({
176
+ id: ids.circleClip1,
177
+ type: 'circle-clip',
178
+ x: 100,
179
+ y: 100,
180
+ props: {},
181
+ })
182
+
183
+ const shape = editor.getShape<CircleClipShape>(ids.circleClip1)
184
+ expect(shape!.props.w).toBe(200) // default from getDefaultProps
185
+ expect(shape!.props.h).toBe(200) // default from getDefaultProps
186
+ })
187
+ })
188
+
189
+ describe('geometry and clipping', () => {
190
+ it('should generate correct circle geometry', () => {
191
+ editor.createShape<CircleClipShape>({
192
+ id: ids.circleClip1,
193
+ type: 'circle-clip',
194
+ x: 100,
195
+ y: 100,
196
+ props: {
197
+ w: 200,
198
+ h: 200,
199
+ },
200
+ })
201
+
202
+ const shape = editor.getShape<CircleClipShape>(ids.circleClip1)
203
+ const util = editor.getShapeUtil<CircleClipShape>('circle-clip')
204
+ const geometry = util.getGeometry(shape!)
205
+
206
+ expect(geometry).toBeDefined()
207
+ expect(geometry.bounds).toBeDefined()
208
+ expect(geometry.bounds.width).toBe(200)
209
+ expect(geometry.bounds.height).toBe(200)
210
+ })
211
+
212
+ it('should generate clip path for circle', () => {
213
+ editor.createShape<CircleClipShape>({
214
+ id: ids.circleClip1,
215
+ type: 'circle-clip',
216
+ x: 100,
217
+ y: 100,
218
+ props: {
219
+ w: 200,
220
+ h: 200,
221
+ },
222
+ })
223
+
224
+ const shape = editor.getShape<CircleClipShape>(ids.circleClip1)
225
+ const util = editor.getShapeUtil<CircleClipShape>('circle-clip')
226
+ const clipPath = util.getClipPath?.(shape!)
227
+ if (!clipPath) throw new Error('Clip path is undefined')
228
+
229
+ expect(clipPath).toBeDefined()
230
+ expect(Array.isArray(clipPath)).toBe(true)
231
+ expect(clipPath.length).toBeGreaterThan(0)
232
+
233
+ // Should be a polygon approximation of a circle
234
+ // Check that points are roughly in a circle pattern
235
+ const centerX = 100 // shape.x
236
+ const centerY = 100 // shape.y
237
+ const radius = 100 // min(w, h) / 2
238
+
239
+ clipPath.forEach((point) => {
240
+ const distance = Math.sqrt(Math.pow(point.x - centerX, 2) + Math.pow(point.y - centerY, 2))
241
+ expect(distance).toBeCloseTo(radius, 0)
242
+ })
243
+ })
244
+ })
245
+
246
+ describe('child clipping behavior', () => {
247
+ it('should clip children when clipping is enabled', () => {
248
+ editor.createShape<CircleClipShape>({
249
+ id: ids.circleClip1,
250
+ type: 'circle-clip',
251
+ x: 100,
252
+ y: 100,
253
+ props: {
254
+ w: 200,
255
+ h: 200,
256
+ },
257
+ })
258
+
259
+ editor.createShape<TLTextShape>({
260
+ id: ids.text1,
261
+ type: 'text',
262
+ x: 0,
263
+ y: 0,
264
+ parentId: ids.circleClip1,
265
+ props: {
266
+ richText: toRichText('Test text'),
267
+ },
268
+ })
269
+
270
+ const util = editor.getShapeUtil<CircleClipShape>('circle-clip')
271
+ const textShape = editor.getShape<TLTextShape>(ids.text1)
272
+
273
+ // Clipping should be enabled by default
274
+ expect(isClippingEnabled$.get()).toBe(true)
275
+ expect(util.shouldClipChild?.(textShape!)).toBe(true)
276
+ expect(editor.getShapeClipPath(ids.text1)).toBeDefined()
277
+ })
278
+
279
+ it('should not clip children when clipping is disabled', () => {
280
+ isClippingEnabled$.set(false)
281
+
282
+ editor.createShape<CircleClipShape>({
283
+ id: ids.circleClip1,
284
+ type: 'circle-clip',
285
+ x: 100,
286
+ y: 100,
287
+ props: {
288
+ w: 200,
289
+ h: 200,
290
+ },
291
+ })
292
+
293
+ editor.createShape<TLTextShape>({
294
+ id: ids.text1,
295
+ type: 'text',
296
+ x: 0,
297
+ y: 0,
298
+ parentId: ids.circleClip1,
299
+ props: {
300
+ richText: toRichText('Test text'),
301
+ },
302
+ })
303
+
304
+ const util = editor.getShapeUtil<CircleClipShape>('circle-clip')
305
+ const textShape = editor.getShape<TLTextShape>(ids.text1)
306
+
307
+ expect(isClippingEnabled$.get()).toBe(false)
308
+ expect(util.shouldClipChild?.(textShape!)).toBe(false)
309
+ expect(editor.getShapeClipPath(ids.text1)).toBeUndefined()
310
+ })
311
+ })
312
+ })
313
+
314
+ describe('Integration tests', () => {
315
+ it('should create and manage circle clip shapes with children', () => {
316
+ // Create circle clip shape
317
+ editor.createShape<CircleClipShape>({
318
+ id: ids.circleClip1,
319
+ type: 'circle-clip',
320
+ x: 100,
321
+ y: 100,
322
+ props: {
323
+ w: 200,
324
+ h: 200,
325
+ },
326
+ })
327
+
328
+ // Add text child
329
+ editor.createShape<TLTextShape>({
330
+ id: ids.text1,
331
+ type: 'text',
332
+ x: 50,
333
+ y: 50,
334
+ parentId: ids.circleClip1,
335
+ props: {
336
+ richText: toRichText('Clipped text'),
337
+ },
338
+ })
339
+
340
+ // Add geo child
341
+ editor.createShape<TLGeoShape>({
342
+ id: ids.geo1,
343
+ type: 'geo',
344
+ x: 150,
345
+ y: 150,
346
+ parentId: ids.circleClip1,
347
+ props: {
348
+ w: 50,
349
+ h: 50,
350
+ },
351
+ })
352
+
353
+ const circleClipShape = editor.getShape<CircleClipShape>(ids.circleClip1)
354
+ const textShape = editor.getShape<TLTextShape>(ids.text1)
355
+ const geoShape = editor.getShape<TLGeoShape>(ids.geo1)
356
+
357
+ expect(circleClipShape).toBeDefined()
358
+ expect(textShape!.parentId).toBe(ids.circleClip1)
359
+ expect(geoShape!.parentId).toBe(ids.circleClip1)
360
+
361
+ // Verify clipping behavior
362
+ const util = editor.getShapeUtil<CircleClipShape>('circle-clip')
363
+ expect(util.shouldClipChild?.(textShape!)).toBe(true)
364
+ expect(util.shouldClipChild?.(geoShape!)).toBe(true)
365
+ expect(editor.getShapeClipPath(ids.text1)).toBeDefined()
366
+ expect(editor.getShapeClipPath(ids.geo1)).toBeDefined()
367
+
368
+ // Test clipping toggle
369
+ isClippingEnabled$.set(false)
370
+ expect(util.shouldClipChild?.(textShape!)).toBe(false)
371
+ expect(util.shouldClipChild?.(geoShape!)).toBe(false)
372
+ expect(editor.getShapeClipPath(ids.text1)).toBeUndefined()
373
+ expect(editor.getShapeClipPath(ids.geo1)).toBeUndefined()
374
+ })
375
+
376
+ it('should handle multiple circle clip shapes independently', () => {
377
+ // Create two circle clip shapes
378
+ editor.createShape<CircleClipShape>({
379
+ id: ids.circleClip1,
380
+ type: 'circle-clip',
381
+ x: 100,
382
+ y: 100,
383
+ props: {
384
+ w: 200,
385
+ h: 200,
386
+ },
387
+ })
388
+
389
+ editor.createShape<CircleClipShape>({
390
+ id: ids.circleClip2,
391
+ type: 'circle-clip',
392
+ x: 400,
393
+ y: 100,
394
+ props: {
395
+ w: 150,
396
+ h: 150,
397
+ },
398
+ })
399
+
400
+ // Add children to both
401
+ editor.createShape<TLTextShape>({
402
+ id: ids.text1,
403
+ type: 'text',
404
+ x: 0,
405
+ y: 0,
406
+ parentId: ids.circleClip1,
407
+ props: {
408
+ richText: toRichText('First clip'),
409
+ },
410
+ })
411
+
412
+ editor.createShape<TLTextShape>({
413
+ id: ids.geo1,
414
+ type: 'text',
415
+ x: 0,
416
+ y: 0,
417
+ parentId: ids.circleClip2,
418
+ props: {
419
+ richText: toRichText('Second clip'),
420
+ },
421
+ })
422
+
423
+ const util = editor.getShapeUtil<CircleClipShape>('circle-clip')
424
+ const text1 = editor.getShape<TLTextShape>(ids.text1)
425
+ const text2 = editor.getShape<TLTextShape>(ids.geo1)
426
+
427
+ // Both should be clipped when enabled
428
+ expect(util.shouldClipChild?.(text1!)).toBe(true)
429
+ expect(util.shouldClipChild?.(text2!)).toBe(true)
430
+
431
+ // Both should not be clipped when disabled
432
+ isClippingEnabled$.set(false)
433
+ expect(util.shouldClipChild?.(text1!)).toBe(false)
434
+ expect(util.shouldClipChild?.(text2!)).toBe(false)
435
+ })
436
+ })
package/tldraw.css CHANGED
@@ -33,6 +33,7 @@
33
33
  --tl-layer-watermark: 200;
34
34
  --tl-layer-canvas-shapes: 300;
35
35
  --tl-layer-canvas-overlays: 500;
36
+ --tl-layer-canvas-in-front: 600;
36
37
  --tl-layer-canvas-blocker: 10000;
37
38
 
38
39
  /* Canvas overlays z-index */
@@ -301,6 +302,13 @@ input,
301
302
  contain: strict;
302
303
  }
303
304
 
305
+ .tl-canvas__in-front {
306
+ position: absolute;
307
+ inset: 0;
308
+ pointer-events: none;
309
+ z-index: var(--tl-layer-canvas-in-front);
310
+ }
311
+
304
312
  .tl-shapes {
305
313
  position: relative;
306
314
  z-index: var(--tl-layer-canvas-shapes);
@@ -685,11 +693,17 @@ input,
685
693
  }
686
694
 
687
695
  .tl-text-measure {
688
- position: absolute;
689
696
  z-index: var(--tl-layer-canvas-hidden);
697
+ opacity: 0;
698
+ visibility: hidden;
699
+
700
+ /* pointer-events: all; */
701
+ /* opacity: 1; */
702
+ /* z-index: 99999; */
703
+
704
+ position: absolute;
690
705
  top: 0px;
691
706
  left: 0px;
692
- opacity: 0;
693
707
  width: max-content;
694
708
  box-sizing: border-box;
695
709
  pointer-events: none;
@@ -700,7 +714,6 @@ input,
700
714
  border: none;
701
715
  user-select: none;
702
716
  contain: style paint;
703
- visibility: hidden;
704
717
  /* N.B. This property, while discouraged ("intended for Document Type Definition (DTD) designers") is necessary for ensuring correct mixed RTL/LTR behavior when exporting SVGs. */
705
718
  unicode-bidi: plaintext;
706
719
  -webkit-user-select: none;
@@ -2790,9 +2803,23 @@ it from receiving any pointer events or affecting the cursor. */
2790
2803
  flex-direction: column;
2791
2804
  }
2792
2805
 
2793
- .tlui-style-panel__section:nth-of-type(n + 2):not(:last-child) {
2806
+ /*
2807
+ add a border to the bottom of all but the last section. we have to handle empty sections too, which
2808
+ are hidden and shouldn't be counted
2809
+ */
2810
+ .tlui-style-panel__section:not(:nth-last-child(-n + 1 of .tlui-style-panel__section:not(:empty))) {
2794
2811
  border-bottom: 1px solid var(--tl-color-divider);
2795
2812
  }
2813
+ /*
2814
+ if a section ends with a slider and we're adding a border, we need some extra space for visual
2815
+ balance. we need to handle empty sections as above. is this the most complex css selector in all of
2816
+ tldraw? probably.
2817
+ */
2818
+ .tlui-style-panel__section:has(.tlui-slider__container:last-child):not(
2819
+ :nth-last-child(-n + 1 of .tlui-style-panel__section:not(:empty))
2820
+ ) {
2821
+ margin-bottom: 7px;
2822
+ }
2796
2823
 
2797
2824
  .tlui-style-panel__section:empty {
2798
2825
  display: none;
@@ -2804,7 +2831,7 @@ it from receiving any pointer events or affecting the cursor. */
2804
2831
  }
2805
2832
 
2806
2833
  .tlui-style-panel__dropdown-picker:only-child {
2807
- width: 100%;
2834
+ flex: 1;
2808
2835
  }
2809
2836
 
2810
2837
  .tlui-style-panel__double-select-picker {
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/lib/ui/components/FollowingIndicator.tsx"],
4
- "sourcesContent": ["import { useEditor, usePresence, useValue } from '@tldraw/editor'\n\nexport function FollowingIndicator() {\n\tconst editor = useEditor()\n\tconst followingUserId = useValue('follow', () => editor.getInstanceState().followingUserId, [\n\t\teditor,\n\t])\n\tif (!followingUserId) return null\n\treturn <FollowingIndicatorInner userId={followingUserId} />\n}\n\nfunction FollowingIndicatorInner({ userId }: { userId: string }) {\n\tconst presence = usePresence(userId)\n\tif (!presence) return null\n\treturn <div className=\"tlui-following-indicator\" style={{ borderColor: presence.color }} />\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAQQ;AARR,oBAAiD;AAE1C,SAAS,qBAAqB;AACpC,QAAM,aAAS,yBAAU;AACzB,QAAM,sBAAkB,wBAAS,UAAU,MAAM,OAAO,iBAAiB,EAAE,iBAAiB;AAAA,IAC3F;AAAA,EACD,CAAC;AACD,MAAI,CAAC,gBAAiB,QAAO;AAC7B,SAAO,4CAAC,2BAAwB,QAAQ,iBAAiB;AAC1D;AAEA,SAAS,wBAAwB,EAAE,OAAO,GAAuB;AAChE,QAAM,eAAW,2BAAY,MAAM;AACnC,MAAI,CAAC,SAAU,QAAO;AACtB,SAAO,4CAAC,SAAI,WAAU,4BAA2B,OAAO,EAAE,aAAa,SAAS,MAAM,GAAG;AAC1F;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../src/lib/ui/components/StylePanel/DoubleDropdownPicker.tsx"],
4
- "sourcesContent": ["import { SharedStyle, StyleProp, tlmenus, useEditor } from '@tldraw/editor'\nimport * as React from 'react'\nimport { StyleValuesForUi } from '../../../styles'\nimport { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'\nimport {\n\tTldrawUiPopover,\n\tTldrawUiPopoverContent,\n\tTldrawUiPopoverTrigger,\n} from '../primitives/TldrawUiPopover'\nimport { TldrawUiToolbar, TldrawUiToolbarButton } from '../primitives/TldrawUiToolbar'\nimport { TldrawUiMenuContextProvider } from '../primitives/menus/TldrawUiMenuContext'\n\ninterface DoubleDropdownPickerProps<T extends string> {\n\tuiTypeA: string\n\tuiTypeB: string\n\tlabel: TLUiTranslationKey | Exclude<string, TLUiTranslationKey>\n\tlabelA: TLUiTranslationKey | Exclude<string, TLUiTranslationKey>\n\tlabelB: TLUiTranslationKey | Exclude<string, TLUiTranslationKey>\n\titemsA: StyleValuesForUi<T>\n\titemsB: StyleValuesForUi<T>\n\tstyleA: StyleProp<T>\n\tstyleB: StyleProp<T>\n\tvalueA: SharedStyle<T>\n\tvalueB: SharedStyle<T>\n\tonValueChange(style: StyleProp<T>, value: T): void\n}\n\nfunction DoubleDropdownPickerInner<T extends string>({\n\tlabel,\n\tuiTypeA,\n\tuiTypeB,\n\tlabelA,\n\tlabelB,\n\titemsA,\n\titemsB,\n\tstyleA,\n\tstyleB,\n\tvalueA,\n\tvalueB,\n\tonValueChange,\n}: DoubleDropdownPickerProps<T>) {\n\tconst editor = useEditor()\n\tconst msg = useTranslation()\n\tconst [isOpenA, setIsOpenA] = React.useState(false)\n\tconst [isOpenB, setIsOpenB] = React.useState(false)\n\n\tconst iconA = React.useMemo(\n\t\t() =>\n\t\t\titemsA.find((item) => valueA.type === 'shared' && valueA.value === item.value)?.icon ??\n\t\t\t'mixed',\n\t\t[itemsA, valueA]\n\t)\n\tconst iconB = React.useMemo(\n\t\t() =>\n\t\t\titemsB.find((item) => valueB.type === 'shared' && valueB.value === item.value)?.icon ??\n\t\t\t'mixed',\n\t\t[itemsB, valueB]\n\t)\n\n\tif (valueA === undefined && valueB === undefined) return null\n\n\tconst idA = `style panel ${uiTypeA} A`\n\tconst idB = `style panel ${uiTypeB} B`\n\treturn (\n\t\t<div className=\"tlui-style-panel__double-select-picker\">\n\t\t\t<div title={msg(label)} className=\"tlui-style-panel__double-select-picker-label\">\n\t\t\t\t{msg(label)}\n\t\t\t</div>\n\t\t\t<TldrawUiToolbar orientation=\"horizontal\" label={msg(label)}>\n\t\t\t\t<TldrawUiPopover id={idA} open={isOpenA} onOpenChange={setIsOpenA}>\n\t\t\t\t\t<TldrawUiPopoverTrigger>\n\t\t\t\t\t\t<TldrawUiToolbarButton\n\t\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\t\tdata-testid={`style.${uiTypeA}`}\n\t\t\t\t\t\t\ttitle={\n\t\t\t\t\t\t\t\tmsg(labelA) +\n\t\t\t\t\t\t\t\t' \u2014 ' +\n\t\t\t\t\t\t\t\t(valueA === null || valueA.type === 'mixed'\n\t\t\t\t\t\t\t\t\t? msg('style-panel.mixed')\n\t\t\t\t\t\t\t\t\t: msg(`${uiTypeA}-style.${valueA.value}` as TLUiTranslationKey))\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<TldrawUiButtonIcon icon={iconA} small invertIcon />\n\t\t\t\t\t\t</TldrawUiToolbarButton>\n\t\t\t\t\t</TldrawUiPopoverTrigger>\n\t\t\t\t\t<TldrawUiPopoverContent side=\"left\" align=\"center\" sideOffset={80} alignOffset={0}>\n\t\t\t\t\t\t<TldrawUiToolbar orientation=\"grid\" label={msg(labelA)}>\n\t\t\t\t\t\t\t<TldrawUiMenuContextProvider type=\"icons\" sourceId=\"style-panel\">\n\t\t\t\t\t\t\t\t{itemsA.map((item) => {\n\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t<TldrawUiToolbarButton\n\t\t\t\t\t\t\t\t\t\t\tdata-testid={`style.${uiTypeA}.${item.value}`}\n\t\t\t\t\t\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\t\t\t\t\t\tkey={item.value}\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t\t\tonValueChange(styleA, item.value)\n\t\t\t\t\t\t\t\t\t\t\t\ttlmenus.deleteOpenMenu(idA, editor.contextId)\n\t\t\t\t\t\t\t\t\t\t\t\tsetIsOpenA(false)\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\ttitle={`${msg(labelA)} \u2014 ${msg(`${uiTypeA}-style.${item.value}`)}`}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<TldrawUiButtonIcon icon={item.icon} invertIcon />\n\t\t\t\t\t\t\t\t\t\t</TldrawUiToolbarButton>\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t</TldrawUiMenuContextProvider>\n\t\t\t\t\t\t</TldrawUiToolbar>\n\t\t\t\t\t</TldrawUiPopoverContent>\n\t\t\t\t</TldrawUiPopover>\n\t\t\t\t<TldrawUiPopover id={idB} open={isOpenB} onOpenChange={setIsOpenB}>\n\t\t\t\t\t<TldrawUiPopoverTrigger>\n\t\t\t\t\t\t<TldrawUiToolbarButton\n\t\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\t\tdata-testid={`style.${uiTypeB}`}\n\t\t\t\t\t\t\ttitle={\n\t\t\t\t\t\t\t\tmsg(labelB) +\n\t\t\t\t\t\t\t\t' \u2014 ' +\n\t\t\t\t\t\t\t\t(valueB === null || valueB.type === 'mixed'\n\t\t\t\t\t\t\t\t\t? msg('style-panel.mixed')\n\t\t\t\t\t\t\t\t\t: msg(`${uiTypeB}-style.${valueB.value}` as TLUiTranslationKey))\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<TldrawUiButtonIcon icon={iconB} small />\n\t\t\t\t\t\t</TldrawUiToolbarButton>\n\t\t\t\t\t</TldrawUiPopoverTrigger>\n\t\t\t\t\t<TldrawUiPopoverContent side=\"left\" align=\"center\" sideOffset={116} alignOffset={0}>\n\t\t\t\t\t\t<TldrawUiToolbar orientation=\"grid\" label={msg(labelB)}>\n\t\t\t\t\t\t\t<TldrawUiMenuContextProvider type=\"icons\" sourceId=\"style-panel\">\n\t\t\t\t\t\t\t\t{itemsB.map((item) => {\n\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t<TldrawUiToolbarButton\n\t\t\t\t\t\t\t\t\t\t\tkey={item.value}\n\t\t\t\t\t\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\t\t\t\t\t\ttitle={`${msg(labelB)} \u2014 ${msg(`${uiTypeB}-style.${item.value}` as TLUiTranslationKey)}`}\n\t\t\t\t\t\t\t\t\t\t\tdata-testid={`style.${uiTypeB}.${item.value}`}\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t\t\tonValueChange(styleB, item.value)\n\t\t\t\t\t\t\t\t\t\t\t\ttlmenus.deleteOpenMenu(idB, editor.contextId)\n\t\t\t\t\t\t\t\t\t\t\t\tsetIsOpenB(false)\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<TldrawUiButtonIcon icon={item.icon} />\n\t\t\t\t\t\t\t\t\t\t</TldrawUiToolbarButton>\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t</TldrawUiMenuContextProvider>\n\t\t\t\t\t\t</TldrawUiToolbar>\n\t\t\t\t\t</TldrawUiPopoverContent>\n\t\t\t\t</TldrawUiPopover>\n\t\t\t</TldrawUiToolbar>\n\t\t</div>\n\t)\n}\n\n// need to memo like this to get generics\nexport const DoubleDropdownPicker = React.memo(\n\tDoubleDropdownPickerInner\n) as typeof DoubleDropdownPickerInner\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../src/lib/ui/components/StylePanel/DropdownPicker.tsx"],
4
- "sourcesContent": ["import { SharedStyle, StyleProp, tlmenus, useEditor } from '@tldraw/editor'\nimport * as React from 'react'\nimport { StyleValuesForUi } from '../../../styles'\nimport { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TLUiIconType } from '../../icon-types'\nimport { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'\nimport { TldrawUiButtonLabel } from '../primitives/Button/TldrawUiButtonLabel'\nimport {\n\tTldrawUiPopover,\n\tTldrawUiPopoverContent,\n\tTldrawUiPopoverTrigger,\n} from '../primitives/TldrawUiPopover'\nimport { TldrawUiToolbar, TldrawUiToolbarButton } from '../primitives/TldrawUiToolbar'\nimport { TldrawUiMenuContextProvider } from '../primitives/menus/TldrawUiMenuContext'\n\ninterface DropdownPickerProps<T extends string> {\n\tid: string\n\tlabel?: TLUiTranslationKey | Exclude<string, TLUiTranslationKey>\n\tuiType: string\n\tstylePanelType: string\n\tstyle: StyleProp<T>\n\tvalue: SharedStyle<T>\n\titems: StyleValuesForUi<T>\n\ttype: 'icon' | 'tool' | 'menu'\n\tonValueChange(style: StyleProp<T>, value: T): void\n}\n\nfunction DropdownPickerInner<T extends string>({\n\tid,\n\tlabel,\n\tuiType,\n\tstylePanelType,\n\tstyle,\n\titems,\n\ttype,\n\tvalue,\n\tonValueChange,\n}: DropdownPickerProps<T>) {\n\tconst msg = useTranslation()\n\tconst editor = useEditor()\n\tconst [isOpen, setIsOpen] = React.useState(false)\n\n\tconst icon = React.useMemo(\n\t\t() => items.find((item) => value.type === 'shared' && item.value === value.value)?.icon,\n\t\t[items, value]\n\t)\n\n\tconst stylePanelName = msg(`style-panel.${stylePanelType}` as TLUiTranslationKey)\n\n\tconst titleStr =\n\t\tvalue.type === 'mixed'\n\t\t\t? msg('style-panel.mixed')\n\t\t\t: stylePanelName + ' \u2014 ' + msg(`${uiType}-style.${value.value}` as TLUiTranslationKey)\n\tconst labelStr = label ? msg(label) : ''\n\n\tconst popoverId = `style panel ${id}`\n\treturn (\n\t\t<TldrawUiPopover\n\t\t\tid={popoverId}\n\t\t\topen={isOpen}\n\t\t\tonOpenChange={setIsOpen}\n\t\t\tclassName=\"tlui-style-panel__dropdown-picker\"\n\t\t>\n\t\t\t<TldrawUiPopoverTrigger>\n\t\t\t\t<TldrawUiToolbarButton\n\t\t\t\t\ttype={type}\n\t\t\t\t\tdata-testid={`style.${uiType}`}\n\t\t\t\t\tdata-direction=\"left\"\n\t\t\t\t\ttitle={titleStr}\n\t\t\t\t>\n\t\t\t\t\t{labelStr && <TldrawUiButtonLabel>{labelStr}</TldrawUiButtonLabel>}\n\t\t\t\t\t<TldrawUiButtonIcon icon={(icon as TLUiIconType) ?? 'mixed'} />\n\t\t\t\t</TldrawUiToolbarButton>\n\t\t\t</TldrawUiPopoverTrigger>\n\t\t\t<TldrawUiPopoverContent side=\"left\" align=\"center\">\n\t\t\t\t<TldrawUiToolbar orientation={items.length > 4 ? 'grid' : 'horizontal'} label={labelStr}>\n\t\t\t\t\t<TldrawUiMenuContextProvider type=\"icons\" sourceId=\"style-panel\">\n\t\t\t\t\t\t{items.map((item) => {\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<TldrawUiToolbarButton\n\t\t\t\t\t\t\t\t\tkey={item.value}\n\t\t\t\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\t\t\t\tdata-testid={`style.${uiType}.${item.value}`}\n\t\t\t\t\t\t\t\t\ttitle={\n\t\t\t\t\t\t\t\t\t\tstylePanelName +\n\t\t\t\t\t\t\t\t\t\t' \u2014 ' +\n\t\t\t\t\t\t\t\t\t\tmsg(`${uiType}-style.${item.value}` as TLUiTranslationKey)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tisActive={icon === item.icon}\n\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\teditor.markHistoryStoppingPoint('select style dropdown item')\n\t\t\t\t\t\t\t\t\t\tonValueChange(style, item.value)\n\t\t\t\t\t\t\t\t\t\ttlmenus.deleteOpenMenu(popoverId, editor.contextId)\n\t\t\t\t\t\t\t\t\t\tsetIsOpen(false)\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<TldrawUiButtonIcon icon={item.icon} />\n\t\t\t\t\t\t\t\t</TldrawUiToolbarButton>\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t})}\n\t\t\t\t\t</TldrawUiMenuContextProvider>\n\t\t\t\t</TldrawUiToolbar>\n\t\t\t</TldrawUiPopoverContent>\n\t\t</TldrawUiPopover>\n\t)\n}\n\n// need to export like this to get generics\nexport const DropdownPicker = React.memo(DropdownPickerInner) as typeof DropdownPickerInner\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAiEI;AAjEJ,oBAA2D;AAC3D,YAAuB;AAGvB,4BAA+B;AAE/B,gCAAmC;AACnC,iCAAoC;AACpC,6BAIO;AACP,6BAAuD;AACvD,iCAA4C;AAc5C,SAAS,oBAAsC;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAA2B;AAC1B,QAAM,UAAM,sCAAe;AAC3B,QAAM,aAAS,yBAAU;AACzB,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAAS,KAAK;AAEhD,QAAM,OAAO,MAAM;AAAA,IAClB,MAAM,MAAM,KAAK,CAAC,SAAS,MAAM,SAAS,YAAY,KAAK,UAAU,MAAM,KAAK,GAAG;AAAA,IACnF,CAAC,OAAO,KAAK;AAAA,EACd;AAEA,QAAM,iBAAiB,IAAI,eAAe,cAAc,EAAwB;AAEhF,QAAM,WACL,MAAM,SAAS,UACZ,IAAI,mBAAmB,IACvB,iBAAiB,aAAQ,IAAI,GAAG,MAAM,UAAU,MAAM,KAAK,EAAwB;AACvF,QAAM,WAAW,QAAQ,IAAI,KAAK,IAAI;AAEtC,QAAM,YAAY,eAAe,EAAE;AACnC,SACC;AAAA,IAAC;AAAA;AAAA,MACA,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,cAAc;AAAA,MACd,WAAU;AAAA,MAEV;AAAA,oDAAC,iDACA;AAAA,UAAC;AAAA;AAAA,YACA;AAAA,YACA,eAAa,SAAS,MAAM;AAAA,YAC5B,kBAAe;AAAA,YACf,OAAO;AAAA,YAEN;AAAA,0BAAY,4CAAC,kDAAqB,oBAAS;AAAA,cAC5C,4CAAC,gDAAmB,MAAO,QAAyB,SAAS;AAAA;AAAA;AAAA,QAC9D,GACD;AAAA,QACA,4CAAC,iDAAuB,MAAK,QAAO,OAAM,UACzC,sDAAC,0CAAgB,aAAa,MAAM,SAAS,IAAI,SAAS,cAAc,OAAO,UAC9E,sDAAC,0DAA4B,MAAK,SAAQ,UAAS,eACjD,gBAAM,IAAI,CAAC,SAAS;AACpB,iBACC;AAAA,YAAC;AAAA;AAAA,cAEA,MAAK;AAAA,cACL,eAAa,SAAS,MAAM,IAAI,KAAK,KAAK;AAAA,cAC1C,OACC,iBACA,aACA,IAAI,GAAG,MAAM,UAAU,KAAK,KAAK,EAAwB;AAAA,cAE1D,UAAU,SAAS,KAAK;AAAA,cACxB,SAAS,MAAM;AACd,uBAAO,yBAAyB,4BAA4B;AAC5D,8BAAc,OAAO,KAAK,KAAK;AAC/B,sCAAQ,eAAe,WAAW,OAAO,SAAS;AAClD,0BAAU,KAAK;AAAA,cAChB;AAAA,cAEA,sDAAC,gDAAmB,MAAM,KAAK,MAAM;AAAA;AAAA,YAhBhC,KAAK;AAAA,UAiBX;AAAA,QAEF,CAAC,GACF,GACD,GACD;AAAA;AAAA;AAAA,EACD;AAEF;AAGO,MAAM,iBAAiB,MAAM,KAAK,mBAAmB;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../src/lib/ui/components/primitives/TldrawUiButtonPicker.tsx"],
4
- "sourcesContent": ["import {\n\tDefaultColorStyle,\n\tgetColorValue,\n\tSharedStyle,\n\tStyleProp,\n\tTLDefaultColorStyle,\n\tTLDefaultColorTheme,\n\tuseEditor,\n} from '@tldraw/editor'\nimport { memo, ReactElement, useMemo, useRef } from 'react'\nimport { StyleValuesForUi } from '../../../styles'\nimport { PORTRAIT_BREAKPOINT } from '../../constants'\nimport { useBreakpoint } from '../../context/breakpoints'\nimport { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButtonIcon } from './Button/TldrawUiButtonIcon'\nimport { TldrawUiToolbarToggleGroup, TldrawUiToolbarToggleItem } from './TldrawUiToolbar'\nimport { TldrawUiGrid, TldrawUiRow } from './layout'\n\n/** @public */\nexport interface TLUiButtonPickerProps<T extends string> {\n\ttitle: string\n\tuiType: string\n\tstyle: StyleProp<T>\n\tvalue: SharedStyle<T>\n\titems: StyleValuesForUi<T>\n\ttheme: TLDefaultColorTheme\n\tonValueChange(style: StyleProp<T>, value: T): void\n\tonHistoryMark?(id: string): void\n}\n\n/** @public */\nexport const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker<T extends string>(\n\tprops: TLUiButtonPickerProps<T>\n) {\n\tconst {\n\t\tuiType,\n\t\titems,\n\t\ttitle,\n\t\tstyle,\n\t\tvalue,\n\t\t// columns = clamp(items.length, 2, 4),\n\t\tonValueChange,\n\t\tonHistoryMark,\n\t\ttheme,\n\t} = props\n\tconst editor = useEditor()\n\tconst msg = useTranslation()\n\tconst breakpoint = useBreakpoint()\n\n\tconst rPointing = useRef(false)\n\tconst rPointingOriginalActiveElement = useRef<HTMLElement | null>(null)\n\n\tconst {\n\t\thandleButtonClick,\n\t\thandleButtonPointerDown,\n\t\thandleButtonPointerEnter,\n\t\thandleButtonPointerUp,\n\t} = useMemo(() => {\n\t\tconst handlePointerUp = () => {\n\t\t\trPointing.current = false\n\t\t\twindow.removeEventListener('pointerup', handlePointerUp)\n\n\t\t\t// This is fun little micro-optimization to make sure that the focus\n\t\t\t// is retained on a text label. That way, you can continue typing\n\t\t\t// after selecting a style.\n\t\t\tconst origActiveEl = rPointingOriginalActiveElement.current\n\t\t\tif (\n\t\t\t\torigActiveEl &&\n\t\t\t\t(['TEXTAREA', 'INPUT'].includes(origActiveEl.nodeName) || origActiveEl.isContentEditable)\n\t\t\t) {\n\t\t\t\torigActiveEl.focus()\n\t\t\t} else if (breakpoint >= PORTRAIT_BREAKPOINT.TABLET_SM) {\n\t\t\t\teditor.getContainer().focus()\n\t\t\t}\n\t\t\trPointingOriginalActiveElement.current = null\n\t\t}\n\n\t\tconst handleButtonClick = (e: React.PointerEvent<HTMLButtonElement>) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tif (value.type === 'shared' && value.value === id) return\n\n\t\t\tonHistoryMark?.('point picker item')\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\tconst handleButtonPointerDown = (e: React.PointerEvent<HTMLButtonElement>) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\n\t\t\tonHistoryMark?.('point picker item')\n\t\t\tonValueChange(style, id as T)\n\n\t\t\trPointing.current = true\n\t\t\trPointingOriginalActiveElement.current = document.activeElement as HTMLElement\n\t\t\twindow.addEventListener('pointerup', handlePointerUp) // see TLD-658\n\t\t}\n\n\t\tconst handleButtonPointerEnter = (e: React.PointerEvent<HTMLButtonElement>) => {\n\t\t\tif (!rPointing.current) return\n\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\tconst handleButtonPointerUp = (e: React.PointerEvent<HTMLButtonElement>) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tif (value.type === 'shared' && value.value === id) return\n\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\treturn {\n\t\t\thandleButtonClick,\n\t\t\thandleButtonPointerDown,\n\t\t\thandleButtonPointerEnter,\n\t\t\thandleButtonPointerUp,\n\t\t}\n\t}, [editor, breakpoint, value, onHistoryMark, onValueChange, style])\n\n\tconst Wrapper = items.length > 4 ? TldrawUiGrid : TldrawUiRow\n\n\treturn (\n\t\t<Wrapper asChild>\n\t\t\t<TldrawUiToolbarToggleGroup\n\t\t\t\tdata-testid={`style.${uiType}`}\n\t\t\t\ttype=\"single\"\n\t\t\t\tvalue={value.type === 'shared' ? value.value : undefined}\n\t\t\t>\n\t\t\t\t{items.map((item) => {\n\t\t\t\t\tconst label = title + ' \u2014 ' + msg(`${uiType}-style.${item.value}` as TLUiTranslationKey)\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<TldrawUiToolbarToggleItem\n\t\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\t\tkey={item.value}\n\t\t\t\t\t\t\tdata-id={item.value}\n\t\t\t\t\t\t\tdata-testid={`style.${uiType}.${item.value}`}\n\t\t\t\t\t\t\taria-label={label}\n\t\t\t\t\t\t\tvalue={item.value}\n\t\t\t\t\t\t\tdata-state={value.type === 'shared' && value.value === item.value ? 'on' : 'off'}\n\t\t\t\t\t\t\tdata-isactive={value.type === 'shared' && value.value === item.value}\n\t\t\t\t\t\t\ttitle={label}\n\t\t\t\t\t\t\tstyle={\n\t\t\t\t\t\t\t\tstyle === (DefaultColorStyle as StyleProp<unknown>)\n\t\t\t\t\t\t\t\t\t? { color: getColorValue(theme, item.value as TLDefaultColorStyle, 'solid') }\n\t\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tonPointerEnter={handleButtonPointerEnter}\n\t\t\t\t\t\t\tonPointerDown={handleButtonPointerDown}\n\t\t\t\t\t\t\tonPointerUp={handleButtonPointerUp}\n\t\t\t\t\t\t\tonClick={handleButtonClick}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<TldrawUiButtonIcon icon={item.icon} />\n\t\t\t\t\t\t</TldrawUiToolbarToggleItem>\n\t\t\t\t\t)\n\t\t\t\t})}\n\t\t\t</TldrawUiToolbarToggleGroup>\n\t\t</Wrapper>\n\t)\n}) as <T extends string>(props: TLUiButtonPickerProps<T>) => ReactElement\n"],
5
- "mappings": "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",
6
- "names": ["TldrawUiButtonPicker", "handleButtonClick", "handleButtonPointerDown", "handleButtonPointerEnter", "handleButtonPointerUp"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/lib/ui/components/FollowingIndicator.tsx"],
4
- "sourcesContent": ["import { useEditor, usePresence, useValue } from '@tldraw/editor'\n\nexport function FollowingIndicator() {\n\tconst editor = useEditor()\n\tconst followingUserId = useValue('follow', () => editor.getInstanceState().followingUserId, [\n\t\teditor,\n\t])\n\tif (!followingUserId) return null\n\treturn <FollowingIndicatorInner userId={followingUserId} />\n}\n\nfunction FollowingIndicatorInner({ userId }: { userId: string }) {\n\tconst presence = usePresence(userId)\n\tif (!presence) return null\n\treturn <div className=\"tlui-following-indicator\" style={{ borderColor: presence.color }} />\n}\n"],
5
- "mappings": "AAQQ;AARR,SAAS,WAAW,aAAa,gBAAgB;AAE1C,SAAS,qBAAqB;AACpC,QAAM,SAAS,UAAU;AACzB,QAAM,kBAAkB,SAAS,UAAU,MAAM,OAAO,iBAAiB,EAAE,iBAAiB;AAAA,IAC3F;AAAA,EACD,CAAC;AACD,MAAI,CAAC,gBAAiB,QAAO;AAC7B,SAAO,oBAAC,2BAAwB,QAAQ,iBAAiB;AAC1D;AAEA,SAAS,wBAAwB,EAAE,OAAO,GAAuB;AAChE,QAAM,WAAW,YAAY,MAAM;AACnC,MAAI,CAAC,SAAU,QAAO;AACtB,SAAO,oBAAC,SAAI,WAAU,4BAA2B,OAAO,EAAE,aAAa,SAAS,MAAM,GAAG;AAC1F;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../src/lib/ui/components/StylePanel/DoubleDropdownPicker.tsx"],
4
- "sourcesContent": ["import { SharedStyle, StyleProp, tlmenus, useEditor } from '@tldraw/editor'\nimport * as React from 'react'\nimport { StyleValuesForUi } from '../../../styles'\nimport { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'\nimport {\n\tTldrawUiPopover,\n\tTldrawUiPopoverContent,\n\tTldrawUiPopoverTrigger,\n} from '../primitives/TldrawUiPopover'\nimport { TldrawUiToolbar, TldrawUiToolbarButton } from '../primitives/TldrawUiToolbar'\nimport { TldrawUiMenuContextProvider } from '../primitives/menus/TldrawUiMenuContext'\n\ninterface DoubleDropdownPickerProps<T extends string> {\n\tuiTypeA: string\n\tuiTypeB: string\n\tlabel: TLUiTranslationKey | Exclude<string, TLUiTranslationKey>\n\tlabelA: TLUiTranslationKey | Exclude<string, TLUiTranslationKey>\n\tlabelB: TLUiTranslationKey | Exclude<string, TLUiTranslationKey>\n\titemsA: StyleValuesForUi<T>\n\titemsB: StyleValuesForUi<T>\n\tstyleA: StyleProp<T>\n\tstyleB: StyleProp<T>\n\tvalueA: SharedStyle<T>\n\tvalueB: SharedStyle<T>\n\tonValueChange(style: StyleProp<T>, value: T): void\n}\n\nfunction DoubleDropdownPickerInner<T extends string>({\n\tlabel,\n\tuiTypeA,\n\tuiTypeB,\n\tlabelA,\n\tlabelB,\n\titemsA,\n\titemsB,\n\tstyleA,\n\tstyleB,\n\tvalueA,\n\tvalueB,\n\tonValueChange,\n}: DoubleDropdownPickerProps<T>) {\n\tconst editor = useEditor()\n\tconst msg = useTranslation()\n\tconst [isOpenA, setIsOpenA] = React.useState(false)\n\tconst [isOpenB, setIsOpenB] = React.useState(false)\n\n\tconst iconA = React.useMemo(\n\t\t() =>\n\t\t\titemsA.find((item) => valueA.type === 'shared' && valueA.value === item.value)?.icon ??\n\t\t\t'mixed',\n\t\t[itemsA, valueA]\n\t)\n\tconst iconB = React.useMemo(\n\t\t() =>\n\t\t\titemsB.find((item) => valueB.type === 'shared' && valueB.value === item.value)?.icon ??\n\t\t\t'mixed',\n\t\t[itemsB, valueB]\n\t)\n\n\tif (valueA === undefined && valueB === undefined) return null\n\n\tconst idA = `style panel ${uiTypeA} A`\n\tconst idB = `style panel ${uiTypeB} B`\n\treturn (\n\t\t<div className=\"tlui-style-panel__double-select-picker\">\n\t\t\t<div title={msg(label)} className=\"tlui-style-panel__double-select-picker-label\">\n\t\t\t\t{msg(label)}\n\t\t\t</div>\n\t\t\t<TldrawUiToolbar orientation=\"horizontal\" label={msg(label)}>\n\t\t\t\t<TldrawUiPopover id={idA} open={isOpenA} onOpenChange={setIsOpenA}>\n\t\t\t\t\t<TldrawUiPopoverTrigger>\n\t\t\t\t\t\t<TldrawUiToolbarButton\n\t\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\t\tdata-testid={`style.${uiTypeA}`}\n\t\t\t\t\t\t\ttitle={\n\t\t\t\t\t\t\t\tmsg(labelA) +\n\t\t\t\t\t\t\t\t' \u2014 ' +\n\t\t\t\t\t\t\t\t(valueA === null || valueA.type === 'mixed'\n\t\t\t\t\t\t\t\t\t? msg('style-panel.mixed')\n\t\t\t\t\t\t\t\t\t: msg(`${uiTypeA}-style.${valueA.value}` as TLUiTranslationKey))\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<TldrawUiButtonIcon icon={iconA} small invertIcon />\n\t\t\t\t\t\t</TldrawUiToolbarButton>\n\t\t\t\t\t</TldrawUiPopoverTrigger>\n\t\t\t\t\t<TldrawUiPopoverContent side=\"left\" align=\"center\" sideOffset={80} alignOffset={0}>\n\t\t\t\t\t\t<TldrawUiToolbar orientation=\"grid\" label={msg(labelA)}>\n\t\t\t\t\t\t\t<TldrawUiMenuContextProvider type=\"icons\" sourceId=\"style-panel\">\n\t\t\t\t\t\t\t\t{itemsA.map((item) => {\n\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t<TldrawUiToolbarButton\n\t\t\t\t\t\t\t\t\t\t\tdata-testid={`style.${uiTypeA}.${item.value}`}\n\t\t\t\t\t\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\t\t\t\t\t\tkey={item.value}\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t\t\tonValueChange(styleA, item.value)\n\t\t\t\t\t\t\t\t\t\t\t\ttlmenus.deleteOpenMenu(idA, editor.contextId)\n\t\t\t\t\t\t\t\t\t\t\t\tsetIsOpenA(false)\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\ttitle={`${msg(labelA)} \u2014 ${msg(`${uiTypeA}-style.${item.value}`)}`}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<TldrawUiButtonIcon icon={item.icon} invertIcon />\n\t\t\t\t\t\t\t\t\t\t</TldrawUiToolbarButton>\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t</TldrawUiMenuContextProvider>\n\t\t\t\t\t\t</TldrawUiToolbar>\n\t\t\t\t\t</TldrawUiPopoverContent>\n\t\t\t\t</TldrawUiPopover>\n\t\t\t\t<TldrawUiPopover id={idB} open={isOpenB} onOpenChange={setIsOpenB}>\n\t\t\t\t\t<TldrawUiPopoverTrigger>\n\t\t\t\t\t\t<TldrawUiToolbarButton\n\t\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\t\tdata-testid={`style.${uiTypeB}`}\n\t\t\t\t\t\t\ttitle={\n\t\t\t\t\t\t\t\tmsg(labelB) +\n\t\t\t\t\t\t\t\t' \u2014 ' +\n\t\t\t\t\t\t\t\t(valueB === null || valueB.type === 'mixed'\n\t\t\t\t\t\t\t\t\t? msg('style-panel.mixed')\n\t\t\t\t\t\t\t\t\t: msg(`${uiTypeB}-style.${valueB.value}` as TLUiTranslationKey))\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<TldrawUiButtonIcon icon={iconB} small />\n\t\t\t\t\t\t</TldrawUiToolbarButton>\n\t\t\t\t\t</TldrawUiPopoverTrigger>\n\t\t\t\t\t<TldrawUiPopoverContent side=\"left\" align=\"center\" sideOffset={116} alignOffset={0}>\n\t\t\t\t\t\t<TldrawUiToolbar orientation=\"grid\" label={msg(labelB)}>\n\t\t\t\t\t\t\t<TldrawUiMenuContextProvider type=\"icons\" sourceId=\"style-panel\">\n\t\t\t\t\t\t\t\t{itemsB.map((item) => {\n\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t<TldrawUiToolbarButton\n\t\t\t\t\t\t\t\t\t\t\tkey={item.value}\n\t\t\t\t\t\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\t\t\t\t\t\ttitle={`${msg(labelB)} \u2014 ${msg(`${uiTypeB}-style.${item.value}` as TLUiTranslationKey)}`}\n\t\t\t\t\t\t\t\t\t\t\tdata-testid={`style.${uiTypeB}.${item.value}`}\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t\t\tonValueChange(styleB, item.value)\n\t\t\t\t\t\t\t\t\t\t\t\ttlmenus.deleteOpenMenu(idB, editor.contextId)\n\t\t\t\t\t\t\t\t\t\t\t\tsetIsOpenB(false)\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<TldrawUiButtonIcon icon={item.icon} />\n\t\t\t\t\t\t\t\t\t\t</TldrawUiToolbarButton>\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t</TldrawUiMenuContextProvider>\n\t\t\t\t\t\t</TldrawUiToolbar>\n\t\t\t\t\t</TldrawUiPopoverContent>\n\t\t\t\t</TldrawUiPopover>\n\t\t\t</TldrawUiToolbar>\n\t\t</div>\n\t)\n}\n\n// need to memo like this to get generics\nexport const DoubleDropdownPicker = React.memo(\n\tDoubleDropdownPickerInner\n) as typeof DoubleDropdownPickerInner\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../src/lib/ui/components/StylePanel/DropdownPicker.tsx"],
4
- "sourcesContent": ["import { SharedStyle, StyleProp, tlmenus, useEditor } from '@tldraw/editor'\nimport * as React from 'react'\nimport { StyleValuesForUi } from '../../../styles'\nimport { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TLUiIconType } from '../../icon-types'\nimport { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'\nimport { TldrawUiButtonLabel } from '../primitives/Button/TldrawUiButtonLabel'\nimport {\n\tTldrawUiPopover,\n\tTldrawUiPopoverContent,\n\tTldrawUiPopoverTrigger,\n} from '../primitives/TldrawUiPopover'\nimport { TldrawUiToolbar, TldrawUiToolbarButton } from '../primitives/TldrawUiToolbar'\nimport { TldrawUiMenuContextProvider } from '../primitives/menus/TldrawUiMenuContext'\n\ninterface DropdownPickerProps<T extends string> {\n\tid: string\n\tlabel?: TLUiTranslationKey | Exclude<string, TLUiTranslationKey>\n\tuiType: string\n\tstylePanelType: string\n\tstyle: StyleProp<T>\n\tvalue: SharedStyle<T>\n\titems: StyleValuesForUi<T>\n\ttype: 'icon' | 'tool' | 'menu'\n\tonValueChange(style: StyleProp<T>, value: T): void\n}\n\nfunction DropdownPickerInner<T extends string>({\n\tid,\n\tlabel,\n\tuiType,\n\tstylePanelType,\n\tstyle,\n\titems,\n\ttype,\n\tvalue,\n\tonValueChange,\n}: DropdownPickerProps<T>) {\n\tconst msg = useTranslation()\n\tconst editor = useEditor()\n\tconst [isOpen, setIsOpen] = React.useState(false)\n\n\tconst icon = React.useMemo(\n\t\t() => items.find((item) => value.type === 'shared' && item.value === value.value)?.icon,\n\t\t[items, value]\n\t)\n\n\tconst stylePanelName = msg(`style-panel.${stylePanelType}` as TLUiTranslationKey)\n\n\tconst titleStr =\n\t\tvalue.type === 'mixed'\n\t\t\t? msg('style-panel.mixed')\n\t\t\t: stylePanelName + ' \u2014 ' + msg(`${uiType}-style.${value.value}` as TLUiTranslationKey)\n\tconst labelStr = label ? msg(label) : ''\n\n\tconst popoverId = `style panel ${id}`\n\treturn (\n\t\t<TldrawUiPopover\n\t\t\tid={popoverId}\n\t\t\topen={isOpen}\n\t\t\tonOpenChange={setIsOpen}\n\t\t\tclassName=\"tlui-style-panel__dropdown-picker\"\n\t\t>\n\t\t\t<TldrawUiPopoverTrigger>\n\t\t\t\t<TldrawUiToolbarButton\n\t\t\t\t\ttype={type}\n\t\t\t\t\tdata-testid={`style.${uiType}`}\n\t\t\t\t\tdata-direction=\"left\"\n\t\t\t\t\ttitle={titleStr}\n\t\t\t\t>\n\t\t\t\t\t{labelStr && <TldrawUiButtonLabel>{labelStr}</TldrawUiButtonLabel>}\n\t\t\t\t\t<TldrawUiButtonIcon icon={(icon as TLUiIconType) ?? 'mixed'} />\n\t\t\t\t</TldrawUiToolbarButton>\n\t\t\t</TldrawUiPopoverTrigger>\n\t\t\t<TldrawUiPopoverContent side=\"left\" align=\"center\">\n\t\t\t\t<TldrawUiToolbar orientation={items.length > 4 ? 'grid' : 'horizontal'} label={labelStr}>\n\t\t\t\t\t<TldrawUiMenuContextProvider type=\"icons\" sourceId=\"style-panel\">\n\t\t\t\t\t\t{items.map((item) => {\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<TldrawUiToolbarButton\n\t\t\t\t\t\t\t\t\tkey={item.value}\n\t\t\t\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\t\t\t\tdata-testid={`style.${uiType}.${item.value}`}\n\t\t\t\t\t\t\t\t\ttitle={\n\t\t\t\t\t\t\t\t\t\tstylePanelName +\n\t\t\t\t\t\t\t\t\t\t' \u2014 ' +\n\t\t\t\t\t\t\t\t\t\tmsg(`${uiType}-style.${item.value}` as TLUiTranslationKey)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tisActive={icon === item.icon}\n\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\teditor.markHistoryStoppingPoint('select style dropdown item')\n\t\t\t\t\t\t\t\t\t\tonValueChange(style, item.value)\n\t\t\t\t\t\t\t\t\t\ttlmenus.deleteOpenMenu(popoverId, editor.contextId)\n\t\t\t\t\t\t\t\t\t\tsetIsOpen(false)\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<TldrawUiButtonIcon icon={item.icon} />\n\t\t\t\t\t\t\t\t</TldrawUiToolbarButton>\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t})}\n\t\t\t\t\t</TldrawUiMenuContextProvider>\n\t\t\t\t</TldrawUiToolbar>\n\t\t\t</TldrawUiPopoverContent>\n\t\t</TldrawUiPopover>\n\t)\n}\n\n// need to export like this to get generics\nexport const DropdownPicker = React.memo(DropdownPickerInner) as typeof DropdownPickerInner\n"],
5
- "mappings": "AAiEI,SAMc,KANd;AAjEJ,SAAiC,SAAS,iBAAiB;AAC3D,YAAY,WAAW;AAGvB,SAAS,sBAAsB;AAE/B,SAAS,0BAA0B;AACnC,SAAS,2BAA2B;AACpC;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,iBAAiB,6BAA6B;AACvD,SAAS,mCAAmC;AAc5C,SAAS,oBAAsC;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAA2B;AAC1B,QAAM,MAAM,eAAe;AAC3B,QAAM,SAAS,UAAU;AACzB,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAAS,KAAK;AAEhD,QAAM,OAAO,MAAM;AAAA,IAClB,MAAM,MAAM,KAAK,CAAC,SAAS,MAAM,SAAS,YAAY,KAAK,UAAU,MAAM,KAAK,GAAG;AAAA,IACnF,CAAC,OAAO,KAAK;AAAA,EACd;AAEA,QAAM,iBAAiB,IAAI,eAAe,cAAc,EAAwB;AAEhF,QAAM,WACL,MAAM,SAAS,UACZ,IAAI,mBAAmB,IACvB,iBAAiB,aAAQ,IAAI,GAAG,MAAM,UAAU,MAAM,KAAK,EAAwB;AACvF,QAAM,WAAW,QAAQ,IAAI,KAAK,IAAI;AAEtC,QAAM,YAAY,eAAe,EAAE;AACnC,SACC;AAAA,IAAC;AAAA;AAAA,MACA,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,cAAc;AAAA,MACd,WAAU;AAAA,MAEV;AAAA,4BAAC,0BACA;AAAA,UAAC;AAAA;AAAA,YACA;AAAA,YACA,eAAa,SAAS,MAAM;AAAA,YAC5B,kBAAe;AAAA,YACf,OAAO;AAAA,YAEN;AAAA,0BAAY,oBAAC,uBAAqB,oBAAS;AAAA,cAC5C,oBAAC,sBAAmB,MAAO,QAAyB,SAAS;AAAA;AAAA;AAAA,QAC9D,GACD;AAAA,QACA,oBAAC,0BAAuB,MAAK,QAAO,OAAM,UACzC,8BAAC,mBAAgB,aAAa,MAAM,SAAS,IAAI,SAAS,cAAc,OAAO,UAC9E,8BAAC,+BAA4B,MAAK,SAAQ,UAAS,eACjD,gBAAM,IAAI,CAAC,SAAS;AACpB,iBACC;AAAA,YAAC;AAAA;AAAA,cAEA,MAAK;AAAA,cACL,eAAa,SAAS,MAAM,IAAI,KAAK,KAAK;AAAA,cAC1C,OACC,iBACA,aACA,IAAI,GAAG,MAAM,UAAU,KAAK,KAAK,EAAwB;AAAA,cAE1D,UAAU,SAAS,KAAK;AAAA,cACxB,SAAS,MAAM;AACd,uBAAO,yBAAyB,4BAA4B;AAC5D,8BAAc,OAAO,KAAK,KAAK;AAC/B,wBAAQ,eAAe,WAAW,OAAO,SAAS;AAClD,0BAAU,KAAK;AAAA,cAChB;AAAA,cAEA,8BAAC,sBAAmB,MAAM,KAAK,MAAM;AAAA;AAAA,YAhBhC,KAAK;AAAA,UAiBX;AAAA,QAEF,CAAC,GACF,GACD,GACD;AAAA;AAAA;AAAA,EACD;AAEF;AAGO,MAAM,iBAAiB,MAAM,KAAK,mBAAmB;",
6
- "names": []
7
- }