@tldraw/commenting 0.0.0-bootstrap → 5.3.0-internal.1640468db8fd

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 (184) hide show
  1. package/commenting.css +284 -153
  2. package/dist-cjs/canvas/comment-body.js +1 -1
  3. package/dist-cjs/canvas/comment-body.js.map +2 -2
  4. package/dist-cjs/canvas/comment-drafts.js +54 -0
  5. package/dist-cjs/canvas/comment-drafts.js.map +7 -0
  6. package/dist-cjs/canvas/comment-render.js +2 -0
  7. package/dist-cjs/canvas/comment-render.js.map +2 -2
  8. package/dist-cjs/canvas/comment-tool.js +65 -12
  9. package/dist-cjs/canvas/comment-tool.js.map +2 -2
  10. package/dist-cjs/canvas/comments-filter-menu.js +54 -63
  11. package/dist-cjs/canvas/comments-filter-menu.js.map +2 -2
  12. package/dist-cjs/canvas/comments-overflow-menu.js +21 -27
  13. package/dist-cjs/canvas/comments-overflow-menu.js.map +2 -2
  14. package/dist-cjs/canvas/comments-overlay.js +304 -112
  15. package/dist-cjs/canvas/comments-overlay.js.map +2 -2
  16. package/dist-cjs/canvas/comments-sidebar.js +12 -18
  17. package/dist-cjs/canvas/comments-sidebar.js.map +2 -2
  18. package/dist-cjs/canvas/comments-visibility-toggle.js +66 -0
  19. package/dist-cjs/canvas/comments-visibility-toggle.js.map +7 -0
  20. package/dist-cjs/canvas/options.js +1 -0
  21. package/dist-cjs/canvas/options.js.map +2 -2
  22. package/dist-cjs/canvas/sidebar-filters.js +2 -2
  23. package/dist-cjs/canvas/sidebar-filters.js.map +2 -2
  24. package/dist-cjs/canvas/state.js +11 -0
  25. package/dist-cjs/canvas/state.js.map +2 -2
  26. package/dist-cjs/canvas/thread-state.js +8 -1
  27. package/dist-cjs/canvas/thread-state.js.map +2 -2
  28. package/dist-cjs/clustering/runtime.js +119 -7
  29. package/dist-cjs/clustering/runtime.js.map +2 -2
  30. package/dist-cjs/index.d.ts +126 -41
  31. package/dist-cjs/index.js +7 -1
  32. package/dist-cjs/index.js.map +2 -2
  33. package/dist-cjs/ui/avatar.js +14 -6
  34. package/dist-cjs/ui/avatar.js.map +2 -2
  35. package/dist-cjs/ui/byline.js +4 -4
  36. package/dist-cjs/ui/byline.js.map +2 -2
  37. package/dist-cjs/ui/comment-author.js +17 -0
  38. package/dist-cjs/ui/comment-author.js.map +7 -0
  39. package/dist-cjs/ui/comment-card.js +4 -4
  40. package/dist-cjs/ui/comment-card.js.map +2 -2
  41. package/dist-cjs/ui/comment-composer.js +92 -29
  42. package/dist-cjs/ui/comment-composer.js.map +2 -2
  43. package/dist-cjs/ui/comment-mention.js +1 -1
  44. package/dist-cjs/ui/comment-mention.js.map +2 -2
  45. package/dist-cjs/ui/comment-pin.js +23 -3
  46. package/dist-cjs/ui/comment-pin.js.map +2 -2
  47. package/dist-cjs/ui/comment-text.js +1 -1
  48. package/dist-cjs/ui/comment-text.js.map +2 -2
  49. package/dist-cjs/ui/comment-thread.js +6 -6
  50. package/dist-cjs/ui/comment-thread.js.map +2 -2
  51. package/dist-cjs/ui/comments-list.js +12 -12
  52. package/dist-cjs/ui/comments-list.js.map +2 -2
  53. package/dist-cjs/ui/count-badge.js +1 -1
  54. package/dist-cjs/ui/count-badge.js.map +2 -2
  55. package/dist-cjs/ui/empty-state.js +3 -3
  56. package/dist-cjs/ui/empty-state.js.map +2 -2
  57. package/dist-cjs/ui/format-time.js +3 -0
  58. package/dist-cjs/ui/format-time.js.map +2 -2
  59. package/dist-cjs/ui/mention-list.js +8 -8
  60. package/dist-cjs/ui/mention-list.js.map +2 -2
  61. package/dist-cjs/ui/mention-suggestion.js +3 -3
  62. package/dist-cjs/ui/mention-suggestion.js.map +2 -2
  63. package/dist-cjs/ui/mention.js +1 -1
  64. package/dist-cjs/ui/mention.js.map +2 -2
  65. package/dist-cjs/ui/reaction.js +11 -4
  66. package/dist-cjs/ui/reaction.js.map +2 -2
  67. package/dist-cjs/ui/reactions.js +10 -2
  68. package/dist-cjs/ui/reactions.js.map +2 -2
  69. package/dist-cjs/ui/send-button.js +1 -1
  70. package/dist-cjs/ui/send-button.js.map +2 -2
  71. package/dist-cjs/ui/tooltip-button.js +32 -0
  72. package/dist-cjs/ui/tooltip-button.js.map +7 -0
  73. package/dist-esm/canvas/comment-body.mjs +1 -1
  74. package/dist-esm/canvas/comment-body.mjs.map +2 -2
  75. package/dist-esm/canvas/comment-drafts.mjs +34 -0
  76. package/dist-esm/canvas/comment-drafts.mjs.map +7 -0
  77. package/dist-esm/canvas/comment-render.mjs +2 -0
  78. package/dist-esm/canvas/comment-render.mjs.map +2 -2
  79. package/dist-esm/canvas/comment-tool.mjs +67 -14
  80. package/dist-esm/canvas/comment-tool.mjs.map +2 -2
  81. package/dist-esm/canvas/comments-filter-menu.mjs +54 -63
  82. package/dist-esm/canvas/comments-filter-menu.mjs.map +2 -2
  83. package/dist-esm/canvas/comments-overflow-menu.mjs +22 -27
  84. package/dist-esm/canvas/comments-overflow-menu.mjs.map +2 -2
  85. package/dist-esm/canvas/comments-overlay.mjs +322 -114
  86. package/dist-esm/canvas/comments-overlay.mjs.map +2 -2
  87. package/dist-esm/canvas/comments-sidebar.mjs +15 -21
  88. package/dist-esm/canvas/comments-sidebar.mjs.map +2 -2
  89. package/dist-esm/canvas/comments-visibility-toggle.mjs +46 -0
  90. package/dist-esm/canvas/comments-visibility-toggle.mjs.map +7 -0
  91. package/dist-esm/canvas/options.mjs +1 -0
  92. package/dist-esm/canvas/options.mjs.map +2 -2
  93. package/dist-esm/canvas/sidebar-filters.mjs +2 -2
  94. package/dist-esm/canvas/sidebar-filters.mjs.map +2 -2
  95. package/dist-esm/canvas/state.mjs +11 -0
  96. package/dist-esm/canvas/state.mjs.map +2 -2
  97. package/dist-esm/canvas/thread-state.mjs +8 -1
  98. package/dist-esm/canvas/thread-state.mjs.map +2 -2
  99. package/dist-esm/clustering/runtime.mjs +119 -7
  100. package/dist-esm/clustering/runtime.mjs.map +2 -2
  101. package/dist-esm/index.d.mts +126 -41
  102. package/dist-esm/index.mjs +11 -1
  103. package/dist-esm/index.mjs.map +2 -2
  104. package/dist-esm/ui/avatar.mjs +14 -6
  105. package/dist-esm/ui/avatar.mjs.map +2 -2
  106. package/dist-esm/ui/byline.mjs +4 -4
  107. package/dist-esm/ui/byline.mjs.map +2 -2
  108. package/dist-esm/ui/comment-author.mjs +1 -0
  109. package/dist-esm/ui/comment-author.mjs.map +7 -0
  110. package/dist-esm/ui/comment-card.mjs +4 -4
  111. package/dist-esm/ui/comment-card.mjs.map +2 -2
  112. package/dist-esm/ui/comment-composer.mjs +93 -30
  113. package/dist-esm/ui/comment-composer.mjs.map +2 -2
  114. package/dist-esm/ui/comment-mention.mjs +1 -1
  115. package/dist-esm/ui/comment-mention.mjs.map +2 -2
  116. package/dist-esm/ui/comment-pin.mjs +23 -3
  117. package/dist-esm/ui/comment-pin.mjs.map +2 -2
  118. package/dist-esm/ui/comment-text.mjs +1 -1
  119. package/dist-esm/ui/comment-text.mjs.map +2 -2
  120. package/dist-esm/ui/comment-thread.mjs +6 -6
  121. package/dist-esm/ui/comment-thread.mjs.map +2 -2
  122. package/dist-esm/ui/comments-list.mjs +12 -12
  123. package/dist-esm/ui/comments-list.mjs.map +2 -2
  124. package/dist-esm/ui/count-badge.mjs +1 -1
  125. package/dist-esm/ui/count-badge.mjs.map +2 -2
  126. package/dist-esm/ui/empty-state.mjs +3 -3
  127. package/dist-esm/ui/empty-state.mjs.map +2 -2
  128. package/dist-esm/ui/format-time.mjs +3 -0
  129. package/dist-esm/ui/format-time.mjs.map +2 -2
  130. package/dist-esm/ui/mention-list.mjs +8 -8
  131. package/dist-esm/ui/mention-list.mjs.map +2 -2
  132. package/dist-esm/ui/mention-suggestion.mjs +3 -3
  133. package/dist-esm/ui/mention-suggestion.mjs.map +2 -2
  134. package/dist-esm/ui/mention.mjs +1 -1
  135. package/dist-esm/ui/mention.mjs.map +2 -2
  136. package/dist-esm/ui/reaction.mjs +11 -4
  137. package/dist-esm/ui/reaction.mjs.map +2 -2
  138. package/dist-esm/ui/reactions.mjs +10 -2
  139. package/dist-esm/ui/reactions.mjs.map +2 -2
  140. package/dist-esm/ui/send-button.mjs +1 -1
  141. package/dist-esm/ui/send-button.mjs.map +2 -2
  142. package/dist-esm/ui/tooltip-button.mjs +12 -0
  143. package/dist-esm/ui/tooltip-button.mjs.map +7 -0
  144. package/package.json +3 -3
  145. package/src/canvas/canvas.css +79 -36
  146. package/src/canvas/comment-body.tsx +1 -1
  147. package/src/canvas/comment-drafts.test.ts +55 -0
  148. package/src/canvas/comment-drafts.ts +46 -0
  149. package/src/canvas/comment-render.test.ts +1 -1
  150. package/src/canvas/comment-render.ts +7 -2
  151. package/src/canvas/comment-tool.tsx +98 -17
  152. package/src/canvas/comments-filter-menu.tsx +27 -33
  153. package/src/canvas/comments-overflow-menu.tsx +13 -21
  154. package/src/canvas/comments-overlay.tsx +441 -145
  155. package/src/canvas/comments-sidebar.tsx +27 -28
  156. package/src/canvas/comments-visibility-toggle.tsx +50 -0
  157. package/src/canvas/options.ts +25 -0
  158. package/src/canvas/sidebar-filters.ts +4 -3
  159. package/src/canvas/state.ts +22 -0
  160. package/src/canvas/thread-state.ts +16 -3
  161. package/src/clustering/runtime.test.ts +183 -7
  162. package/src/clustering/runtime.ts +164 -15
  163. package/src/index.ts +7 -0
  164. package/src/ui/avatar.tsx +15 -11
  165. package/src/ui/byline.tsx +6 -5
  166. package/src/ui/comment-author.ts +15 -0
  167. package/src/ui/comment-card.tsx +6 -5
  168. package/src/ui/comment-composer.tsx +122 -33
  169. package/src/ui/comment-mention.ts +2 -2
  170. package/src/ui/comment-pin.tsx +35 -4
  171. package/src/ui/comment-text.tsx +1 -1
  172. package/src/ui/comment-thread.tsx +8 -6
  173. package/src/ui/comments-list.tsx +19 -14
  174. package/src/ui/comments.css +205 -117
  175. package/src/ui/count-badge.tsx +1 -1
  176. package/src/ui/empty-state.tsx +3 -3
  177. package/src/ui/format-time.ts +5 -0
  178. package/src/ui/mention-list.tsx +13 -16
  179. package/src/ui/mention-suggestion.tsx +3 -3
  180. package/src/ui/mention.tsx +1 -1
  181. package/src/ui/reaction.tsx +6 -3
  182. package/src/ui/reactions.tsx +6 -2
  183. package/src/ui/send-button.tsx +1 -1
  184. package/src/ui/tooltip-button.tsx +20 -0
@@ -1,6 +1,6 @@
1
1
  /* Real comment UI components. Co-located so styles travel to any view (studio,
2
2
  canvas), and themed via tldraw's --tl-color tokens so they follow light/dark. */
3
- .cmt-card {
3
+ .tlui-cmt-card {
4
4
  position: relative;
5
5
  display: flex;
6
6
  gap: 10px;
@@ -12,7 +12,7 @@
12
12
  }
13
13
 
14
14
  /* hover-revealed controls (edit…) at the card's top-right */
15
- .cmt-card__actions {
15
+ .tlui-cmt-card__actions {
16
16
  position: absolute;
17
17
  top: 6px;
18
18
  right: 6px;
@@ -20,65 +20,68 @@
20
20
  gap: 2px;
21
21
  opacity: 0;
22
22
  }
23
- .cmt-card:hover .cmt-card__actions,
24
- .cmt-card:focus-within .cmt-card__actions {
23
+ .tlui-cmt-card:hover .tlui-cmt-card__actions,
24
+ .tlui-cmt-card:focus-within .tlui-cmt-card__actions {
25
25
  opacity: 1;
26
26
  }
27
27
 
28
- .cmt-body {
28
+ .tlui-cmt-body {
29
29
  flex: 1;
30
30
  min-width: 0;
31
31
  }
32
32
 
33
- .cmt-head {
33
+ .tlui-cmt-head {
34
34
  display: flex;
35
- align-items: baseline;
35
+ align-items: center;
36
36
  gap: 6px;
37
37
  }
38
38
 
39
- .cmt-author {
39
+ .tlui-cmt-author {
40
40
  font-weight: 600;
41
41
  font-size: 13px;
42
42
  color: var(--tl-color-text-1);
43
43
  }
44
44
 
45
- .cmt-time {
46
- font-size: 11px;
45
+ .tlui-cmt-time {
46
+ font-size: 10px;
47
47
  color: var(--tl-color-text-3);
48
48
  }
49
49
 
50
- .cmt-text {
50
+ .tlui-cmt-text {
51
51
  margin: 3px 0 0;
52
52
  font-size: 13px;
53
53
  line-height: 1.4;
54
54
  color: var(--tl-color-text-1);
55
+ /* Break long unbroken strings (URLs, keyboard-mashing) so they wrap inside the card instead of
56
+ overflowing it. `anywhere` also lets the flex body shrink to the card width. */
57
+ overflow-wrap: anywhere;
55
58
  }
56
59
 
57
- .cmt-edited {
60
+ .tlui-cmt-edited {
58
61
  font-style: italic;
59
62
  }
60
63
 
61
64
  /* rendered rich text inside a comment body — bare tags emitted by the comment renderer
62
65
  (paragraphs, lists, code, highlight, links), matching the limited comment extension set. */
63
- .cmt-text p {
66
+ .tlui-cmt-text p {
64
67
  margin: 0;
65
68
  }
66
69
 
67
- .cmt-text p + p,
68
- .cmt-text p + ul,
69
- .cmt-text p + ol,
70
- .cmt-text ul + p,
71
- .cmt-text ol + p {
70
+ .tlui-cmt-text p + p,
71
+ .tlui-cmt-text p + ul,
72
+ .tlui-cmt-text p + ol,
73
+ .tlui-cmt-text ul + p,
74
+ .tlui-cmt-text ol + p {
72
75
  margin-top: 6px;
73
76
  }
74
77
 
75
- .cmt-text ul,
76
- .cmt-text ol {
78
+ .tlui-cmt-text ul,
79
+ .tlui-cmt-text ol {
77
80
  margin: 0;
78
81
  padding-left: 18px;
79
82
  }
80
83
 
81
- .cmt-text code {
84
+ .tlui-cmt-text code {
82
85
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
83
86
  font-size: 0.92em;
84
87
  background: var(--tl-color-muted-2);
@@ -86,18 +89,18 @@
86
89
  padding: 0 3px;
87
90
  }
88
91
 
89
- .cmt-text mark {
92
+ .tlui-cmt-text mark {
90
93
  background: color-mix(in srgb, #ffeb3b 60%, transparent);
91
94
  color: inherit;
92
95
  border-radius: 2px;
93
96
  }
94
97
 
95
- .cmt-text a {
98
+ .tlui-cmt-text a {
96
99
  color: var(--tl-color-selected);
97
100
  text-decoration: underline;
98
101
  }
99
102
 
100
- .cmt-avatar {
103
+ .tlui-cmt-avatar {
101
104
  width: 28px;
102
105
  height: 28px;
103
106
  border-radius: 50%;
@@ -111,7 +114,7 @@
111
114
  flex-shrink: 0;
112
115
  }
113
116
 
114
- .cmt-avatar--image {
117
+ .tlui-cmt-avatar--image {
115
118
  object-fit: cover;
116
119
  background: none;
117
120
  }
@@ -119,14 +122,14 @@
119
122
  /* composer — an avatar beside a rounded-rect field holding the rich-text input and the send button.
120
123
  Formatting is applied via markdown and keyboard shortcuts (no toolbar). The avatar aligns to the
121
124
  top so it stays put as the field grows to multiple lines. */
122
- .cmt-composer {
125
+ .tlui-cmt-composer {
123
126
  display: flex;
124
127
  align-items: flex-start;
125
128
  gap: 10px;
126
129
  padding: 4px 0 8px 4px;
127
130
  }
128
131
 
129
- .cmt-composer__field {
132
+ .tlui-cmt-composer__field {
130
133
  flex: 1;
131
134
  min-width: 0;
132
135
  display: flex;
@@ -138,19 +141,47 @@
138
141
  border-radius: var(--tl-radius-3);
139
142
  }
140
143
 
141
- .cmt-composer__field:focus-within {
144
+ .tlui-cmt-composer__field:focus-within {
142
145
  border-color: var(--tl-color-selected);
143
146
  }
144
147
 
148
+ /* Expanded: the content no longer fits on one line beside the send button, so the input takes
149
+ the full width and the send button drops to its own row, right-aligned. */
150
+ .tlui-cmt-composer__field--expanded {
151
+ flex-wrap: wrap;
152
+ }
153
+ .tlui-cmt-composer__field--expanded .tlui-cmt-composer__input-wrap {
154
+ flex-basis: 100%;
155
+ /* The field pads 12px left but only 3px right (the send button's inset). With the input
156
+ spanning the full width, give the text the same 12px on the right. */
157
+ padding-right: 9px;
158
+ }
159
+ .tlui-cmt-composer__field--expanded .tlui-cmt-send {
160
+ margin-left: auto;
161
+ }
162
+
145
163
  /* the editable area, with the placeholder overlaid while it's empty */
146
- .cmt-composer__input-wrap {
164
+ .tlui-cmt-composer__input-wrap {
147
165
  position: relative;
148
166
  flex: 1;
149
167
  min-width: 0;
150
168
  padding: 3px 0;
151
169
  }
152
170
 
153
- .cmt-input {
171
+ /* The hidden single-line measuring clone of the editor's content (see CommentComposer). */
172
+ .tlui-cmt-composer__mirror {
173
+ position: absolute;
174
+ top: 0;
175
+ left: 0;
176
+ visibility: hidden;
177
+ pointer-events: none;
178
+ white-space: nowrap;
179
+ width: max-content;
180
+ max-height: none;
181
+ overflow: visible;
182
+ }
183
+
184
+ .tlui-cmt-input {
154
185
  font: inherit;
155
186
  font-size: 13px;
156
187
  line-height: 1.4;
@@ -163,23 +194,23 @@
163
194
  word-break: break-word;
164
195
  }
165
196
 
166
- .cmt-input p {
197
+ .tlui-cmt-input p {
167
198
  margin: 0;
168
199
  }
169
200
 
170
- .cmt-input p + p,
171
- .cmt-input p + ul,
172
- .cmt-input p + ol {
201
+ .tlui-cmt-input p + p,
202
+ .tlui-cmt-input p + ul,
203
+ .tlui-cmt-input p + ol {
173
204
  margin-top: 4px;
174
205
  }
175
206
 
176
- .cmt-input ul,
177
- .cmt-input ol {
207
+ .tlui-cmt-input ul,
208
+ .tlui-cmt-input ol {
178
209
  margin: 0;
179
210
  padding-left: 18px;
180
211
  }
181
212
 
182
- .cmt-input__placeholder {
213
+ .tlui-cmt-input__placeholder {
183
214
  position: absolute;
184
215
  top: 3px;
185
216
  left: 0;
@@ -189,7 +220,7 @@
189
220
  pointer-events: none;
190
221
  }
191
222
 
192
- .cmt-send {
223
+ .tlui-cmt-send {
193
224
  border: 0;
194
225
  border-radius: var(--tl-radius-2);
195
226
  background: var(--tl-color-selected);
@@ -202,33 +233,33 @@
202
233
  align-self: flex-end;
203
234
  }
204
235
 
205
- .cmt-send:hover,
206
- .pseudo-hover .cmt-send {
236
+ .tlui-cmt-send:hover,
237
+ .pseudo-hover .tlui-cmt-send {
207
238
  background: color-mix(in srgb, var(--tl-color-selected) 88%, black);
208
239
  }
209
240
 
210
- .cmt-send:active,
211
- .pseudo-active .cmt-send {
241
+ .tlui-cmt-send:active,
242
+ .pseudo-active .tlui-cmt-send {
212
243
  background: color-mix(in srgb, var(--tl-color-selected) 78%, black);
213
244
  }
214
245
 
215
- .cmt-send:focus-visible,
216
- .pseudo-focus-visible .cmt-send {
246
+ .tlui-cmt-send:focus-visible,
247
+ .pseudo-focus-visible .tlui-cmt-send {
217
248
  outline: 2px solid var(--tl-color-selected);
218
249
  outline-offset: 2px;
219
250
  }
220
251
 
221
- .cmt-send:disabled {
252
+ .tlui-cmt-send:disabled {
222
253
  opacity: 0.45;
223
254
  cursor: not-allowed;
224
255
  }
225
256
 
226
257
  /* pin */
227
- .cmt-pin {
258
+ .tlui-cmt-pin {
228
259
  width: 34px;
229
260
  height: 34px;
230
261
  border-radius: 50% 50% 50% 3px;
231
- background: var(--tl-color-selected);
262
+ background: var(--tlui-cmt-pin-color, var(--tl-color-selected));
232
263
  color: #fff;
233
264
  display: flex;
234
265
  align-items: center;
@@ -242,33 +273,39 @@
242
273
  box-shadow 0.08s ease;
243
274
  }
244
275
 
245
- .cmt-pin:hover,
246
- .pseudo-hover .cmt-pin {
276
+ .tlui-cmt-pin:hover,
277
+ .pseudo-hover .tlui-cmt-pin {
247
278
  transform: scale(1.08);
279
+ }
280
+
281
+ /* The hover shadow is for closed pins only — an open pin keeps its selection ring, which this
282
+ box-shadow would otherwise override (the hover selector outranks the --open rule). */
283
+ .tlui-cmt-pin:not(.tlui-cmt-pin--open):hover,
284
+ .pseudo-hover .tlui-cmt-pin:not(.tlui-cmt-pin--open) {
248
285
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.32);
249
286
  }
250
287
 
251
- /* open: the thread is showing — a selection ring marks the active pin */
252
- .cmt-pin--open {
288
+ /* open: the thread is showing — a selection ring marks the active pin (in the pin's own tint) */
289
+ .tlui-cmt-pin--open {
253
290
  box-shadow:
254
291
  0 0 0 3px var(--tl-color-panel),
255
- 0 0 0 5px var(--tl-color-selected),
292
+ 0 0 0 5px var(--tlui-cmt-pin-color, var(--tl-color-selected)),
256
293
  0 2px 6px rgba(0, 0, 0, 0.25);
257
294
  }
258
295
 
259
296
  /* resolved: a solid, muted grey (the default --tl-color-muted-1 is 10% black, so it goes
260
297
  translucent over the canvas). Dark mode gets its own grey — the token's dark value is near-black. */
261
- .cmt-pin--resolved {
298
+ .tlui-cmt-pin--resolved {
262
299
  background: #dfe0e1;
263
300
  color: hsl(214, 8%, 42%);
264
301
  }
265
- .tl-theme__dark .cmt-pin--resolved {
302
+ .tl-theme__dark .tlui-cmt-pin--resolved {
266
303
  background: hsl(240, 5%, 30%);
267
304
  color: hsl(0, 0%, 72%);
268
305
  }
269
306
 
270
307
  /* count badge */
271
- .cmt-count-badge {
308
+ .tlui-cmt-count-badge {
272
309
  width: 34px;
273
310
  height: 34px;
274
311
  border-radius: 50%;
@@ -284,14 +321,14 @@
284
321
  }
285
322
 
286
323
  /* thread */
287
- .cmt-thread {
324
+ .tlui-cmt-thread {
288
325
  display: flex;
289
326
  flex-direction: column;
290
327
  gap: 8px;
291
328
  width: 300px;
292
329
  }
293
330
 
294
- .cmt-thread__head {
331
+ .tlui-cmt-thread__head {
295
332
  display: flex;
296
333
  align-items: center;
297
334
  gap: 8px;
@@ -302,7 +339,7 @@
302
339
  letter-spacing: 0.04em;
303
340
  }
304
341
 
305
- .cmt-badge {
342
+ .tlui-cmt-badge {
306
343
  font-size: 10px;
307
344
  font-weight: 600;
308
345
  text-transform: none;
@@ -314,12 +351,12 @@
314
351
  }
315
352
 
316
353
  /* reactions */
317
- .cmt-reactions {
354
+ .tlui-cmt-reactions {
318
355
  display: flex;
319
356
  gap: 6px;
320
357
  }
321
358
 
322
- .cmt-reaction {
359
+ .tlui-cmt-reaction {
323
360
  display: inline-flex;
324
361
  align-items: center;
325
362
  gap: 5px;
@@ -333,27 +370,27 @@
333
370
  cursor: pointer;
334
371
  }
335
372
 
336
- .cmt-reaction:hover,
337
- .pseudo-hover .cmt-reaction {
373
+ .tlui-cmt-reaction:hover,
374
+ .pseudo-hover .tlui-cmt-reaction {
338
375
  border-color: var(--tl-color-selected);
339
376
  }
340
377
 
341
- .cmt-reaction--active {
378
+ .tlui-cmt-reaction--active {
342
379
  border-color: var(--tl-color-selected);
343
380
  background: color-mix(in srgb, var(--tl-color-selected) 12%, var(--tl-color-panel));
344
381
  }
345
382
 
346
- .cmt-reaction__count {
383
+ .tlui-cmt-reaction__count {
347
384
  color: var(--tl-color-text-3);
348
385
  }
349
386
 
350
- .cmt-reaction--add {
387
+ .tlui-cmt-reaction--add {
351
388
  color: var(--tl-color-text-3);
352
389
  font-weight: 600;
353
390
  }
354
391
 
355
392
  /* mention */
356
- .cmt-mention {
393
+ .tlui-cmt-mention {
357
394
  color: var(--tl-color-selected);
358
395
  font-weight: 600;
359
396
  background: color-mix(in srgb, var(--tl-color-selected) 12%, transparent);
@@ -362,7 +399,7 @@
362
399
  }
363
400
 
364
401
  /* mention picker */
365
- .cmt-mention-list {
402
+ .tlui-cmt-mention-list {
366
403
  display: flex;
367
404
  flex-direction: column;
368
405
  gap: 1px;
@@ -378,7 +415,7 @@
378
415
  box-shadow: var(--tl-shadow-2, 0 2px 12px rgba(0, 0, 0, 0.14));
379
416
  }
380
417
 
381
- .cmt-mention-list__item {
418
+ .tlui-cmt-mention-list__item {
382
419
  display: flex;
383
420
  align-items: center;
384
421
  gap: 8px;
@@ -392,19 +429,19 @@
392
429
  font: inherit;
393
430
  }
394
431
 
395
- .cmt-mention-list__item--active,
396
- .cmt-mention-list__item:hover {
432
+ .tlui-cmt-mention-list__item--active,
433
+ .tlui-cmt-mention-list__item:hover {
397
434
  background: var(--tl-color-muted-2, rgba(0, 0, 0, 0.06));
398
435
  }
399
436
 
400
- .cmt-mention-list__text {
437
+ .tlui-cmt-mention-list__text {
401
438
  display: flex;
402
439
  flex-direction: column;
403
440
  min-width: 0;
404
441
  line-height: 1.3;
405
442
  }
406
443
 
407
- .cmt-mention-list__name {
444
+ .tlui-cmt-mention-list__name {
408
445
  font-size: 13px;
409
446
  font-weight: 500;
410
447
  white-space: nowrap;
@@ -412,13 +449,13 @@
412
449
  text-overflow: ellipsis;
413
450
  }
414
451
 
415
- .cmt-mention-list__you {
452
+ .tlui-cmt-mention-list__you {
416
453
  margin-left: 4px;
417
454
  font-weight: 400;
418
455
  color: var(--tl-color-text-3);
419
456
  }
420
457
 
421
- .cmt-mention-list__secondary {
458
+ .tlui-cmt-mention-list__secondary {
422
459
  font-size: 12px;
423
460
  color: var(--tl-color-text-3);
424
461
  white-space: nowrap;
@@ -426,7 +463,7 @@
426
463
  text-overflow: ellipsis;
427
464
  }
428
465
 
429
- .cmt-mention-list--empty {
466
+ .tlui-cmt-mention-list--empty {
430
467
  padding: 8px 10px;
431
468
  width: 100%;
432
469
  box-sizing: border-box;
@@ -435,13 +472,13 @@
435
472
  }
436
473
 
437
474
  /* the @-picker popup — caret-anchored above the page, positioned by the suggestion plugin */
438
- .cmt-mention-popup {
475
+ .tlui-cmt-mention-popup {
439
476
  position: fixed;
440
477
  z-index: var(--tl-layer-menus);
441
478
  }
442
479
 
443
480
  /* empty state */
444
- .cmt-empty {
481
+ .tlui-cmt-empty {
445
482
  display: flex;
446
483
  flex-direction: column;
447
484
  align-items: center;
@@ -451,11 +488,11 @@
451
488
  width: 240px;
452
489
  }
453
490
 
454
- .cmt-empty__icon {
491
+ .tlui-cmt-empty__icon {
455
492
  font-size: 28px;
456
493
  }
457
494
 
458
- .cmt-empty__message {
495
+ .tlui-cmt-empty__message {
459
496
  margin: 0;
460
497
  color: var(--tl-color-text-3);
461
498
  font-size: 13px;
@@ -464,7 +501,7 @@
464
501
 
465
502
  /* a comment thread: an elevated panel — the same surface treatment as the toolbar — holding a
466
503
  header, an optional resolved banner, the comments, and a reply composer */
467
- .cmt-thread {
504
+ .tlui-cmt-thread {
468
505
  display: flex;
469
506
  flex-direction: column;
470
507
  gap: 6px;
@@ -474,22 +511,22 @@
474
511
  border-radius: var(--tl-radius-4);
475
512
  box-shadow: var(--tl-shadow-2);
476
513
  }
477
- .cmt-thread__header {
514
+ .tlui-cmt-thread__header {
478
515
  display: flex;
479
516
  align-items: center;
480
517
  justify-content: space-between;
481
518
  padding: 2px 2px 2px 4px;
482
519
  }
483
- .cmt-thread__title {
520
+ .tlui-cmt-thread__title {
484
521
  font-size: 12px;
485
522
  font-weight: 600;
486
523
  color: var(--tl-color-text-1);
487
524
  }
488
- .cmt-thread__actions {
525
+ .tlui-cmt-thread__actions {
489
526
  display: flex;
490
527
  gap: 2px;
491
528
  }
492
- .cmt-thread__action {
529
+ .tlui-cmt-thread__action {
493
530
  display: flex;
494
531
  align-items: center;
495
532
  justify-content: center;
@@ -504,25 +541,57 @@
504
541
  line-height: 1;
505
542
  cursor: pointer;
506
543
  }
507
- .cmt-thread__action:hover {
544
+ .tlui-cmt-thread__action:hover {
508
545
  background: var(--tl-color-muted-2);
509
546
  color: var(--tl-color-text-1);
510
547
  }
511
- .cmt-thread__resolved {
548
+ .tlui-cmt-thread__resolved {
512
549
  padding: 6px 10px;
513
550
  border-radius: 8px;
514
551
  background: var(--tl-color-muted-2);
515
552
  font-size: 12px;
516
553
  color: var(--tl-color-text-3);
517
554
  }
518
- .cmt-thread__list {
555
+ .tlui-cmt-thread__list {
519
556
  display: flex;
520
557
  flex-direction: column;
521
558
  gap: 6px;
522
559
  }
560
+ /* Inside a thread, author identity is a small colour dot, no initial — the letter doesn't fit
561
+ at this size. */
562
+ .tlui-cmt-thread .tlui-cmt-avatar {
563
+ width: 14px;
564
+ height: 14px;
565
+ font-size: 0;
566
+ margin-top: 2px;
567
+ }
568
+
569
+ .tlui-cmt-thread .tlui-cmt-composer {
570
+ padding: 4px 0 0;
571
+ }
572
+ .tlui-cmt-thread .tlui-cmt-composer .tlui-cmt-avatar {
573
+ display: none;
574
+ }
575
+
576
+ /* The sidebar's rows use the same small colour dot as the thread view. */
577
+ .tlui-cmt-list .tlui-cmt-avatar {
578
+ width: 14px;
579
+ height: 14px;
580
+ font-size: 0;
581
+ margin-top: 2px;
582
+ }
583
+
584
+ /* The dot treatment is for colour-only identity — an image avatar stays full size. */
585
+ .tlui-cmt-thread .tlui-cmt-avatar--image,
586
+ .tlui-cmt-list .tlui-cmt-avatar--image {
587
+ width: 24px;
588
+ height: 24px;
589
+ margin-top: 0;
590
+ }
591
+
523
592
  /* inside the panel, comments are plain content — no surrounding box; the composer's field carries
524
593
  its own surface. */
525
- .cmt-thread .cmt-card {
594
+ .tlui-cmt-thread .tlui-cmt-card {
526
595
  width: 100%;
527
596
  padding: 6px 0 6px 4px;
528
597
  background: transparent;
@@ -530,13 +599,13 @@
530
599
  }
531
600
 
532
601
  /* comments list — thread summaries, one per row (used by the canvas sidebar) */
533
- .cmt-list {
602
+ .tlui-cmt-list {
534
603
  display: flex;
535
604
  flex-direction: column;
536
605
  width: 100%;
537
606
  min-height: 0;
538
607
  }
539
- .cmt-list__header {
608
+ .tlui-cmt-list__header {
540
609
  flex-shrink: 0;
541
610
  display: flex;
542
611
  align-items: center;
@@ -545,16 +614,14 @@
545
614
  padding: 6px 6px 6px 14px;
546
615
  border-bottom: 1px solid var(--tl-color-divider);
547
616
  }
548
- .cmt-list__header-title {
549
- font-size: 11px;
617
+ .tlui-cmt-list__header-title {
618
+ font-size: 13px;
550
619
  font-weight: 600;
551
- letter-spacing: 0.06em;
552
- text-transform: uppercase;
553
- color: var(--tl-color-text-3);
620
+ color: var(--tl-color-text-1);
554
621
  }
555
622
 
556
623
  /* a small square icon button in the sidebar header (filter funnel, overflow …) */
557
- .cmt-header-btn {
624
+ .tlui-cmt-header-btn {
558
625
  display: flex;
559
626
  align-items: center;
560
627
  justify-content: center;
@@ -567,19 +634,24 @@
567
634
  color: var(--tl-color-text-2);
568
635
  cursor: pointer;
569
636
  }
570
- .cmt-header-btn:hover,
571
- .cmt-header-btn[data-state='open'] {
637
+ .tlui-cmt-header-btn:hover,
638
+ .tlui-cmt-header-btn[data-state='open'] {
572
639
  background: var(--tl-color-muted-2);
573
640
  color: var(--tl-color-text-1);
574
641
  }
575
- .cmt-list__header-actions {
642
+ .tlui-cmt-list__header-actions {
576
643
  display: flex;
577
644
  align-items: center;
578
645
  gap: 2px;
579
646
  }
580
647
 
648
+ /* The commenting dropdowns' surface — a little air between the items and the menu edge. */
649
+ .tlui-cmt-menu {
650
+ padding: 4px;
651
+ }
652
+
581
653
  /* a menu row with a label and a right-aligned shortcut hint (overflow menu) */
582
- .cmt-menu-item {
654
+ .tlui-cmt-menu-item {
583
655
  display: flex;
584
656
  align-items: center;
585
657
  justify-content: space-between;
@@ -590,28 +662,33 @@
590
662
  border-radius: 6px;
591
663
  background: transparent;
592
664
  font: inherit;
593
- font-size: 13px;
665
+ font-size: 12px;
594
666
  color: var(--tl-color-text-1);
595
667
  cursor: pointer;
596
668
  }
597
- .cmt-menu-item:hover {
669
+ .tlui-cmt-menu-item:hover {
598
670
  background: var(--tl-color-muted-2);
599
671
  }
600
- .cmt-menu-item__shortcut {
672
+ /* Destructive menu entries (delete) — the same danger colour as tldraw's danger buttons. */
673
+ .tlui-cmt-menu-item--danger {
674
+ color: var(--tl-color-danger);
675
+ }
676
+
677
+ .tlui-cmt-menu-item__shortcut {
601
678
  color: var(--tl-color-text-3);
602
679
  font-size: 12px;
603
680
  }
604
- .cmt-list__items {
681
+ .tlui-cmt-list__items {
605
682
  flex: 1;
606
683
  min-height: 0;
607
684
  overflow-y: auto;
608
685
  }
609
- .cmt-list__empty {
686
+ .tlui-cmt-list__empty {
610
687
  padding: 20px 14px;
611
688
  color: var(--tl-color-text-3);
612
689
  font-size: 13px;
613
690
  }
614
- .cmt-list__item {
691
+ .tlui-cmt-list__item {
615
692
  display: flex;
616
693
  gap: 10px;
617
694
  width: 100%;
@@ -623,22 +700,30 @@
623
700
  text-align: left;
624
701
  cursor: pointer;
625
702
  }
626
- .cmt-list__item:hover {
703
+ .tlui-cmt-list__item:hover {
627
704
  background: var(--tl-color-muted-2);
628
705
  }
629
- .cmt-list__item--selected {
630
- background: var(--tl-color-muted-1);
706
+ /* Selected sits a step above hover so the open thread's row stays distinguishable while
707
+ pointing at other rows — but only a step: the muted-1 token (10%) reads too heavy here.
708
+ These rows sit on the opaque sidebar panel, so a translucent tint composes safely. */
709
+ .tlui-cmt-list__item--selected,
710
+ .tlui-cmt-list__item--selected:hover {
711
+ background: hsl(0, 0%, 0%, 5%);
712
+ }
713
+ .tl-theme__dark .tlui-cmt-list__item--selected,
714
+ .tl-theme__dark .tlui-cmt-list__item--selected:hover {
715
+ background: hsl(0, 0%, 100%, 5%);
631
716
  }
632
717
  /* resolved rows mute their content but keep the "Resolved" marker legible */
633
- .cmt-list__item[data-resolved] .cmt-head,
634
- .cmt-list__item[data-resolved] .cmt-list__item-preview {
718
+ .tlui-cmt-list__item[data-resolved] .tlui-cmt-head,
719
+ .tlui-cmt-list__item[data-resolved] .tlui-cmt-list__item-preview {
635
720
  opacity: 0.55;
636
721
  }
637
- .cmt-list__item-body {
722
+ .tlui-cmt-list__item-body {
638
723
  flex: 1;
639
724
  min-width: 0;
640
725
  }
641
- .cmt-list__item-preview {
726
+ .tlui-cmt-list__item-preview {
642
727
  margin-top: 2px;
643
728
  font-size: 13px;
644
729
  color: var(--tl-color-text-1);
@@ -647,9 +732,12 @@
647
732
  display: -webkit-box;
648
733
  -webkit-line-clamp: 2;
649
734
  -webkit-box-orient: vertical;
735
+ /* Long unbroken strings (URLs, mashed keys) wrap onto the clamped lines instead of clipping
736
+ mid-string — same treatment as the card body. */
737
+ overflow-wrap: anywhere;
650
738
  }
651
739
  /* meta line under the preview: page label and/or a resolved marker */
652
- .cmt-list__item-meta {
740
+ .tlui-cmt-list__item-meta {
653
741
  display: flex;
654
742
  align-items: center;
655
743
  gap: 8px;
@@ -657,20 +745,20 @@
657
745
  font-size: 11px;
658
746
  color: var(--tl-color-text-3);
659
747
  }
660
- .cmt-list__item-resolved {
748
+ .tlui-cmt-list__item-resolved {
661
749
  display: inline-flex;
662
750
  align-items: center;
663
751
  gap: 3px;
664
752
  font-weight: 600;
665
753
  }
666
- .cmt-list__item-page {
754
+ .tlui-cmt-list__item-page {
667
755
  display: inline-flex;
668
756
  align-items: center;
669
757
  padding: 1px 6px;
670
758
  border-radius: 4px;
671
759
  background: var(--tl-color-muted-2);
672
760
  }
673
- .cmt-list__item-count {
761
+ .tlui-cmt-list__item-count {
674
762
  flex-shrink: 0;
675
763
  align-self: center;
676
764
  font-size: 12px;