@tldraw/collaboration 0.0.0-bootstrap → 5.3.0-internal.41291fb579ed

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/collaboration.css CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  /* Real comment UI components. Co-located so styles travel to any view (studio,
6
6
  canvas), and themed via tldraw's --tl-color tokens so they follow light/dark. */
7
- .cmt-card {
7
+ .tlui-cmt-card {
8
8
  position: relative;
9
9
  display: flex;
10
10
  gap: 10px;
@@ -16,7 +16,7 @@
16
16
  }
17
17
 
18
18
  /* hover-revealed controls (edit…) at the card's top-right */
19
- .cmt-card__actions {
19
+ .tlui-cmt-card__actions {
20
20
  position: absolute;
21
21
  top: 6px;
22
22
  right: 6px;
@@ -24,65 +24,68 @@
24
24
  gap: 2px;
25
25
  opacity: 0;
26
26
  }
27
- .cmt-card:hover .cmt-card__actions,
28
- .cmt-card:focus-within .cmt-card__actions {
27
+ .tlui-cmt-card:hover .tlui-cmt-card__actions,
28
+ .tlui-cmt-card:focus-within .tlui-cmt-card__actions {
29
29
  opacity: 1;
30
30
  }
31
31
 
32
- .cmt-body {
32
+ .tlui-cmt-body {
33
33
  flex: 1;
34
34
  min-width: 0;
35
35
  }
36
36
 
37
- .cmt-head {
37
+ .tlui-cmt-head {
38
38
  display: flex;
39
- align-items: baseline;
39
+ align-items: center;
40
40
  gap: 6px;
41
41
  }
42
42
 
43
- .cmt-author {
43
+ .tlui-cmt-author {
44
44
  font-weight: 600;
45
45
  font-size: 13px;
46
46
  color: var(--tl-color-text-1);
47
47
  }
48
48
 
49
- .cmt-time {
50
- font-size: 11px;
49
+ .tlui-cmt-time {
50
+ font-size: 10px;
51
51
  color: var(--tl-color-text-3);
52
52
  }
53
53
 
54
- .cmt-text {
54
+ .tlui-cmt-text {
55
55
  margin: 3px 0 0;
56
56
  font-size: 13px;
57
57
  line-height: 1.4;
58
58
  color: var(--tl-color-text-1);
59
+ /* Break long unbroken strings (URLs, keyboard-mashing) so they wrap inside the card instead of
60
+ overflowing it. `anywhere` also lets the flex body shrink to the card width. */
61
+ overflow-wrap: anywhere;
59
62
  }
60
63
 
61
- .cmt-edited {
64
+ .tlui-cmt-edited {
62
65
  font-style: italic;
63
66
  }
64
67
 
65
68
  /* rendered rich text inside a comment body — bare tags emitted by the comment renderer
66
69
  (paragraphs, lists, code, highlight, links), matching the limited comment extension set. */
67
- .cmt-text p {
70
+ .tlui-cmt-text p {
68
71
  margin: 0;
69
72
  }
70
73
 
71
- .cmt-text p + p,
72
- .cmt-text p + ul,
73
- .cmt-text p + ol,
74
- .cmt-text ul + p,
75
- .cmt-text ol + p {
74
+ .tlui-cmt-text p + p,
75
+ .tlui-cmt-text p + ul,
76
+ .tlui-cmt-text p + ol,
77
+ .tlui-cmt-text ul + p,
78
+ .tlui-cmt-text ol + p {
76
79
  margin-top: 6px;
77
80
  }
78
81
 
79
- .cmt-text ul,
80
- .cmt-text ol {
82
+ .tlui-cmt-text ul,
83
+ .tlui-cmt-text ol {
81
84
  margin: 0;
82
85
  padding-left: 18px;
83
86
  }
84
87
 
85
- .cmt-text code {
88
+ .tlui-cmt-text code {
86
89
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
87
90
  font-size: 0.92em;
88
91
  background: var(--tl-color-muted-2);
@@ -90,18 +93,18 @@
90
93
  padding: 0 3px;
91
94
  }
92
95
 
93
- .cmt-text mark {
96
+ .tlui-cmt-text mark {
94
97
  background: color-mix(in srgb, #ffeb3b 60%, transparent);
95
98
  color: inherit;
96
99
  border-radius: 2px;
97
100
  }
98
101
 
99
- .cmt-text a {
102
+ .tlui-cmt-text a {
100
103
  color: var(--tl-color-selected);
101
104
  text-decoration: underline;
102
105
  }
103
106
 
104
- .cmt-avatar {
107
+ .tlui-cmt-avatar {
105
108
  width: 28px;
106
109
  height: 28px;
107
110
  border-radius: 50%;
@@ -115,7 +118,7 @@
115
118
  flex-shrink: 0;
116
119
  }
117
120
 
118
- .cmt-avatar--image {
121
+ .tlui-cmt-avatar--image {
119
122
  object-fit: cover;
120
123
  background: none;
121
124
  }
@@ -123,14 +126,14 @@
123
126
  /* composer — an avatar beside a rounded-rect field holding the rich-text input and the send button.
124
127
  Formatting is applied via markdown and keyboard shortcuts (no toolbar). The avatar aligns to the
125
128
  top so it stays put as the field grows to multiple lines. */
126
- .cmt-composer {
129
+ .tlui-cmt-composer {
127
130
  display: flex;
128
131
  align-items: flex-start;
129
132
  gap: 10px;
130
133
  padding: 4px 0 8px 4px;
131
134
  }
132
135
 
133
- .cmt-composer__field {
136
+ .tlui-cmt-composer__field {
134
137
  flex: 1;
135
138
  min-width: 0;
136
139
  display: flex;
@@ -142,19 +145,47 @@
142
145
  border-radius: var(--tl-radius-3);
143
146
  }
144
147
 
145
- .cmt-composer__field:focus-within {
148
+ .tlui-cmt-composer__field:focus-within {
146
149
  border-color: var(--tl-color-selected);
147
150
  }
148
151
 
152
+ /* Expanded: the content no longer fits on one line beside the send button, so the input takes
153
+ the full width and the send button drops to its own row, right-aligned. */
154
+ .tlui-cmt-composer__field--expanded {
155
+ flex-wrap: wrap;
156
+ }
157
+ .tlui-cmt-composer__field--expanded .tlui-cmt-composer__input-wrap {
158
+ flex-basis: 100%;
159
+ /* The field pads 12px left but only 3px right (the send button's inset). With the input
160
+ spanning the full width, give the text the same 12px on the right. */
161
+ padding-right: 9px;
162
+ }
163
+ .tlui-cmt-composer__field--expanded .tlui-cmt-send {
164
+ margin-left: auto;
165
+ }
166
+
149
167
  /* the editable area, with the placeholder overlaid while it's empty */
150
- .cmt-composer__input-wrap {
168
+ .tlui-cmt-composer__input-wrap {
151
169
  position: relative;
152
170
  flex: 1;
153
171
  min-width: 0;
154
172
  padding: 3px 0;
155
173
  }
156
174
 
157
- .cmt-input {
175
+ /* The hidden single-line measuring clone of the editor's content (see CommentComposer). */
176
+ .tlui-cmt-composer__mirror {
177
+ position: absolute;
178
+ top: 0;
179
+ left: 0;
180
+ visibility: hidden;
181
+ pointer-events: none;
182
+ white-space: nowrap;
183
+ width: max-content;
184
+ max-height: none;
185
+ overflow: visible;
186
+ }
187
+
188
+ .tlui-cmt-input {
158
189
  font: inherit;
159
190
  font-size: 13px;
160
191
  line-height: 1.4;
@@ -167,23 +198,23 @@
167
198
  word-break: break-word;
168
199
  }
169
200
 
170
- .cmt-input p {
201
+ .tlui-cmt-input p {
171
202
  margin: 0;
172
203
  }
173
204
 
174
- .cmt-input p + p,
175
- .cmt-input p + ul,
176
- .cmt-input p + ol {
205
+ .tlui-cmt-input p + p,
206
+ .tlui-cmt-input p + ul,
207
+ .tlui-cmt-input p + ol {
177
208
  margin-top: 4px;
178
209
  }
179
210
 
180
- .cmt-input ul,
181
- .cmt-input ol {
211
+ .tlui-cmt-input ul,
212
+ .tlui-cmt-input ol {
182
213
  margin: 0;
183
214
  padding-left: 18px;
184
215
  }
185
216
 
186
- .cmt-input__placeholder {
217
+ .tlui-cmt-input__placeholder {
187
218
  position: absolute;
188
219
  top: 3px;
189
220
  left: 0;
@@ -193,7 +224,7 @@
193
224
  pointer-events: none;
194
225
  }
195
226
 
196
- .cmt-send {
227
+ .tlui-cmt-send {
197
228
  border: 0;
198
229
  border-radius: var(--tl-radius-2);
199
230
  background: var(--tl-color-selected);
@@ -206,33 +237,33 @@
206
237
  align-self: flex-end;
207
238
  }
208
239
 
209
- .cmt-send:hover,
210
- .pseudo-hover .cmt-send {
240
+ .tlui-cmt-send:hover,
241
+ .pseudo-hover .tlui-cmt-send {
211
242
  background: color-mix(in srgb, var(--tl-color-selected) 88%, black);
212
243
  }
213
244
 
214
- .cmt-send:active,
215
- .pseudo-active .cmt-send {
245
+ .tlui-cmt-send:active,
246
+ .pseudo-active .tlui-cmt-send {
216
247
  background: color-mix(in srgb, var(--tl-color-selected) 78%, black);
217
248
  }
218
249
 
219
- .cmt-send:focus-visible,
220
- .pseudo-focus-visible .cmt-send {
250
+ .tlui-cmt-send:focus-visible,
251
+ .pseudo-focus-visible .tlui-cmt-send {
221
252
  outline: 2px solid var(--tl-color-selected);
222
253
  outline-offset: 2px;
223
254
  }
224
255
 
225
- .cmt-send:disabled {
256
+ .tlui-cmt-send:disabled {
226
257
  opacity: 0.45;
227
258
  cursor: not-allowed;
228
259
  }
229
260
 
230
261
  /* pin */
231
- .cmt-pin {
262
+ .tlui-cmt-pin {
232
263
  width: 34px;
233
264
  height: 34px;
234
265
  border-radius: 50% 50% 50% 3px;
235
- background: var(--tl-color-selected);
266
+ background: var(--tlui-cmt-pin-color, var(--tl-color-selected));
236
267
  color: #fff;
237
268
  display: flex;
238
269
  align-items: center;
@@ -246,33 +277,39 @@
246
277
  box-shadow 0.08s ease;
247
278
  }
248
279
 
249
- .cmt-pin:hover,
250
- .pseudo-hover .cmt-pin {
280
+ .tlui-cmt-pin:hover,
281
+ .pseudo-hover .tlui-cmt-pin {
251
282
  transform: scale(1.08);
283
+ }
284
+
285
+ /* The hover shadow is for closed pins only — an open pin keeps its selection ring, which this
286
+ box-shadow would otherwise override (the hover selector outranks the --open rule). */
287
+ .tlui-cmt-pin:not(.tlui-cmt-pin--open):hover,
288
+ .pseudo-hover .tlui-cmt-pin:not(.tlui-cmt-pin--open) {
252
289
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.32);
253
290
  }
254
291
 
255
- /* open: the thread is showing — a selection ring marks the active pin */
256
- .cmt-pin--open {
292
+ /* open: the thread is showing — a selection ring marks the active pin (in the pin's own tint) */
293
+ .tlui-cmt-pin--open {
257
294
  box-shadow:
258
295
  0 0 0 3px var(--tl-color-panel),
259
- 0 0 0 5px var(--tl-color-selected),
296
+ 0 0 0 5px var(--tlui-cmt-pin-color, var(--tl-color-selected)),
260
297
  0 2px 6px rgba(0, 0, 0, 0.25);
261
298
  }
262
299
 
263
300
  /* resolved: a solid, muted grey (the default --tl-color-muted-1 is 10% black, so it goes
264
301
  translucent over the canvas). Dark mode gets its own grey — the token's dark value is near-black. */
265
- .cmt-pin--resolved {
302
+ .tlui-cmt-pin--resolved {
266
303
  background: #dfe0e1;
267
304
  color: hsl(214, 8%, 42%);
268
305
  }
269
- .tl-theme__dark .cmt-pin--resolved {
306
+ .tl-theme__dark .tlui-cmt-pin--resolved {
270
307
  background: hsl(240, 5%, 30%);
271
308
  color: hsl(0, 0%, 72%);
272
309
  }
273
310
 
274
311
  /* count badge */
275
- .cmt-count-badge {
312
+ .tlui-cmt-count-badge {
276
313
  width: 34px;
277
314
  height: 34px;
278
315
  border-radius: 50%;
@@ -288,14 +325,14 @@
288
325
  }
289
326
 
290
327
  /* thread */
291
- .cmt-thread {
328
+ .tlui-cmt-thread {
292
329
  display: flex;
293
330
  flex-direction: column;
294
331
  gap: 8px;
295
332
  width: 300px;
296
333
  }
297
334
 
298
- .cmt-thread__head {
335
+ .tlui-cmt-thread__head {
299
336
  display: flex;
300
337
  align-items: center;
301
338
  gap: 8px;
@@ -306,7 +343,7 @@
306
343
  letter-spacing: 0.04em;
307
344
  }
308
345
 
309
- .cmt-badge {
346
+ .tlui-cmt-badge {
310
347
  font-size: 10px;
311
348
  font-weight: 600;
312
349
  text-transform: none;
@@ -318,12 +355,12 @@
318
355
  }
319
356
 
320
357
  /* reactions */
321
- .cmt-reactions {
358
+ .tlui-cmt-reactions {
322
359
  display: flex;
323
360
  gap: 6px;
324
361
  }
325
362
 
326
- .cmt-reaction {
363
+ .tlui-cmt-reaction {
327
364
  display: inline-flex;
328
365
  align-items: center;
329
366
  gap: 5px;
@@ -337,27 +374,27 @@
337
374
  cursor: pointer;
338
375
  }
339
376
 
340
- .cmt-reaction:hover,
341
- .pseudo-hover .cmt-reaction {
377
+ .tlui-cmt-reaction:hover,
378
+ .pseudo-hover .tlui-cmt-reaction {
342
379
  border-color: var(--tl-color-selected);
343
380
  }
344
381
 
345
- .cmt-reaction--active {
382
+ .tlui-cmt-reaction--active {
346
383
  border-color: var(--tl-color-selected);
347
384
  background: color-mix(in srgb, var(--tl-color-selected) 12%, var(--tl-color-panel));
348
385
  }
349
386
 
350
- .cmt-reaction__count {
387
+ .tlui-cmt-reaction__count {
351
388
  color: var(--tl-color-text-3);
352
389
  }
353
390
 
354
- .cmt-reaction--add {
391
+ .tlui-cmt-reaction--add {
355
392
  color: var(--tl-color-text-3);
356
393
  font-weight: 600;
357
394
  }
358
395
 
359
396
  /* mention */
360
- .cmt-mention {
397
+ .tlui-cmt-mention {
361
398
  color: var(--tl-color-selected);
362
399
  font-weight: 600;
363
400
  background: color-mix(in srgb, var(--tl-color-selected) 12%, transparent);
@@ -366,7 +403,7 @@
366
403
  }
367
404
 
368
405
  /* mention picker */
369
- .cmt-mention-list {
406
+ .tlui-cmt-mention-list {
370
407
  display: flex;
371
408
  flex-direction: column;
372
409
  gap: 1px;
@@ -382,7 +419,7 @@
382
419
  box-shadow: var(--tl-shadow-2, 0 2px 12px rgba(0, 0, 0, 0.14));
383
420
  }
384
421
 
385
- .cmt-mention-list__item {
422
+ .tlui-cmt-mention-list__item {
386
423
  display: flex;
387
424
  align-items: center;
388
425
  gap: 8px;
@@ -396,19 +433,19 @@
396
433
  font: inherit;
397
434
  }
398
435
 
399
- .cmt-mention-list__item--active,
400
- .cmt-mention-list__item:hover {
436
+ .tlui-cmt-mention-list__item--active,
437
+ .tlui-cmt-mention-list__item:hover {
401
438
  background: var(--tl-color-muted-2, rgba(0, 0, 0, 0.06));
402
439
  }
403
440
 
404
- .cmt-mention-list__text {
441
+ .tlui-cmt-mention-list__text {
405
442
  display: flex;
406
443
  flex-direction: column;
407
444
  min-width: 0;
408
445
  line-height: 1.3;
409
446
  }
410
447
 
411
- .cmt-mention-list__name {
448
+ .tlui-cmt-mention-list__name {
412
449
  font-size: 13px;
413
450
  font-weight: 500;
414
451
  white-space: nowrap;
@@ -416,13 +453,13 @@
416
453
  text-overflow: ellipsis;
417
454
  }
418
455
 
419
- .cmt-mention-list__you {
456
+ .tlui-cmt-mention-list__you {
420
457
  margin-left: 4px;
421
458
  font-weight: 400;
422
459
  color: var(--tl-color-text-3);
423
460
  }
424
461
 
425
- .cmt-mention-list__secondary {
462
+ .tlui-cmt-mention-list__secondary {
426
463
  font-size: 12px;
427
464
  color: var(--tl-color-text-3);
428
465
  white-space: nowrap;
@@ -430,7 +467,7 @@
430
467
  text-overflow: ellipsis;
431
468
  }
432
469
 
433
- .cmt-mention-list--empty {
470
+ .tlui-cmt-mention-list--empty {
434
471
  padding: 8px 10px;
435
472
  width: 100%;
436
473
  box-sizing: border-box;
@@ -439,13 +476,13 @@
439
476
  }
440
477
 
441
478
  /* the @-picker popup — caret-anchored above the page, positioned by the suggestion plugin */
442
- .cmt-mention-popup {
479
+ .tlui-cmt-mention-popup {
443
480
  position: fixed;
444
481
  z-index: var(--tl-layer-menus);
445
482
  }
446
483
 
447
484
  /* empty state */
448
- .cmt-empty {
485
+ .tlui-cmt-empty {
449
486
  display: flex;
450
487
  flex-direction: column;
451
488
  align-items: center;
@@ -455,11 +492,11 @@
455
492
  width: 240px;
456
493
  }
457
494
 
458
- .cmt-empty__icon {
495
+ .tlui-cmt-empty__icon {
459
496
  font-size: 28px;
460
497
  }
461
498
 
462
- .cmt-empty__message {
499
+ .tlui-cmt-empty__message {
463
500
  margin: 0;
464
501
  color: var(--tl-color-text-3);
465
502
  font-size: 13px;
@@ -468,7 +505,7 @@
468
505
 
469
506
  /* a comment thread: an elevated panel — the same surface treatment as the toolbar — holding a
470
507
  header, an optional resolved banner, the comments, and a reply composer */
471
- .cmt-thread {
508
+ .tlui-cmt-thread {
472
509
  display: flex;
473
510
  flex-direction: column;
474
511
  gap: 6px;
@@ -478,22 +515,22 @@
478
515
  border-radius: var(--tl-radius-4);
479
516
  box-shadow: var(--tl-shadow-2);
480
517
  }
481
- .cmt-thread__header {
518
+ .tlui-cmt-thread__header {
482
519
  display: flex;
483
520
  align-items: center;
484
521
  justify-content: space-between;
485
522
  padding: 2px 2px 2px 4px;
486
523
  }
487
- .cmt-thread__title {
524
+ .tlui-cmt-thread__title {
488
525
  font-size: 12px;
489
526
  font-weight: 600;
490
527
  color: var(--tl-color-text-1);
491
528
  }
492
- .cmt-thread__actions {
529
+ .tlui-cmt-thread__actions {
493
530
  display: flex;
494
531
  gap: 2px;
495
532
  }
496
- .cmt-thread__action {
533
+ .tlui-cmt-thread__action {
497
534
  display: flex;
498
535
  align-items: center;
499
536
  justify-content: center;
@@ -508,25 +545,57 @@
508
545
  line-height: 1;
509
546
  cursor: pointer;
510
547
  }
511
- .cmt-thread__action:hover {
548
+ .tlui-cmt-thread__action:hover {
512
549
  background: var(--tl-color-muted-2);
513
550
  color: var(--tl-color-text-1);
514
551
  }
515
- .cmt-thread__resolved {
552
+ .tlui-cmt-thread__resolved {
516
553
  padding: 6px 10px;
517
554
  border-radius: 8px;
518
555
  background: var(--tl-color-muted-2);
519
556
  font-size: 12px;
520
557
  color: var(--tl-color-text-3);
521
558
  }
522
- .cmt-thread__list {
559
+ .tlui-cmt-thread__list {
523
560
  display: flex;
524
561
  flex-direction: column;
525
562
  gap: 6px;
526
563
  }
564
+ /* Inside a thread, author identity is a small colour dot, no initial — the letter doesn't fit
565
+ at this size. */
566
+ .tlui-cmt-thread .tlui-cmt-avatar {
567
+ width: 14px;
568
+ height: 14px;
569
+ font-size: 0;
570
+ margin-top: 2px;
571
+ }
572
+
573
+ .tlui-cmt-thread .tlui-cmt-composer {
574
+ padding: 4px 0 0;
575
+ }
576
+ .tlui-cmt-thread .tlui-cmt-composer .tlui-cmt-avatar {
577
+ display: none;
578
+ }
579
+
580
+ /* The sidebar's rows use the same small colour dot as the thread view. */
581
+ .tlui-cmt-list .tlui-cmt-avatar {
582
+ width: 14px;
583
+ height: 14px;
584
+ font-size: 0;
585
+ margin-top: 2px;
586
+ }
587
+
588
+ /* The dot treatment is for colour-only identity — an image avatar stays full size. */
589
+ .tlui-cmt-thread .tlui-cmt-avatar--image,
590
+ .tlui-cmt-list .tlui-cmt-avatar--image {
591
+ width: 24px;
592
+ height: 24px;
593
+ margin-top: 0;
594
+ }
595
+
527
596
  /* inside the panel, comments are plain content — no surrounding box; the composer's field carries
528
597
  its own surface. */
529
- .cmt-thread .cmt-card {
598
+ .tlui-cmt-thread .tlui-cmt-card {
530
599
  width: 100%;
531
600
  padding: 6px 0 6px 4px;
532
601
  background: transparent;
@@ -534,13 +603,13 @@
534
603
  }
535
604
 
536
605
  /* comments list — thread summaries, one per row (used by the canvas sidebar) */
537
- .cmt-list {
606
+ .tlui-cmt-list {
538
607
  display: flex;
539
608
  flex-direction: column;
540
609
  width: 100%;
541
610
  min-height: 0;
542
611
  }
543
- .cmt-list__header {
612
+ .tlui-cmt-list__header {
544
613
  flex-shrink: 0;
545
614
  display: flex;
546
615
  align-items: center;
@@ -549,16 +618,14 @@
549
618
  padding: 6px 6px 6px 14px;
550
619
  border-bottom: 1px solid var(--tl-color-divider);
551
620
  }
552
- .cmt-list__header-title {
553
- font-size: 11px;
621
+ .tlui-cmt-list__header-title {
622
+ font-size: 13px;
554
623
  font-weight: 600;
555
- letter-spacing: 0.06em;
556
- text-transform: uppercase;
557
- color: var(--tl-color-text-3);
624
+ color: var(--tl-color-text-1);
558
625
  }
559
626
 
560
627
  /* a small square icon button in the sidebar header (filter funnel, overflow …) */
561
- .cmt-header-btn {
628
+ .tlui-cmt-header-btn {
562
629
  display: flex;
563
630
  align-items: center;
564
631
  justify-content: center;
@@ -571,19 +638,24 @@
571
638
  color: var(--tl-color-text-2);
572
639
  cursor: pointer;
573
640
  }
574
- .cmt-header-btn:hover,
575
- .cmt-header-btn[data-state='open'] {
641
+ .tlui-cmt-header-btn:hover,
642
+ .tlui-cmt-header-btn[data-state='open'] {
576
643
  background: var(--tl-color-muted-2);
577
644
  color: var(--tl-color-text-1);
578
645
  }
579
- .cmt-list__header-actions {
646
+ .tlui-cmt-list__header-actions {
580
647
  display: flex;
581
648
  align-items: center;
582
649
  gap: 2px;
583
650
  }
584
651
 
652
+ /* The commenting dropdowns' surface — a little air between the items and the menu edge. */
653
+ .tlui-cmt-menu {
654
+ padding: 4px;
655
+ }
656
+
585
657
  /* a menu row with a label and a right-aligned shortcut hint (overflow menu) */
586
- .cmt-menu-item {
658
+ .tlui-cmt-menu-item {
587
659
  display: flex;
588
660
  align-items: center;
589
661
  justify-content: space-between;
@@ -594,28 +666,33 @@
594
666
  border-radius: 6px;
595
667
  background: transparent;
596
668
  font: inherit;
597
- font-size: 13px;
669
+ font-size: 12px;
598
670
  color: var(--tl-color-text-1);
599
671
  cursor: pointer;
600
672
  }
601
- .cmt-menu-item:hover {
673
+ .tlui-cmt-menu-item:hover {
602
674
  background: var(--tl-color-muted-2);
603
675
  }
604
- .cmt-menu-item__shortcut {
676
+ /* Destructive menu entries (delete) — the same danger colour as tldraw's danger buttons. */
677
+ .tlui-cmt-menu-item--danger {
678
+ color: var(--tl-color-danger);
679
+ }
680
+
681
+ .tlui-cmt-menu-item__shortcut {
605
682
  color: var(--tl-color-text-3);
606
683
  font-size: 12px;
607
684
  }
608
- .cmt-list__items {
685
+ .tlui-cmt-list__items {
609
686
  flex: 1;
610
687
  min-height: 0;
611
688
  overflow-y: auto;
612
689
  }
613
- .cmt-list__empty {
690
+ .tlui-cmt-list__empty {
614
691
  padding: 20px 14px;
615
692
  color: var(--tl-color-text-3);
616
693
  font-size: 13px;
617
694
  }
618
- .cmt-list__item {
695
+ .tlui-cmt-list__item {
619
696
  display: flex;
620
697
  gap: 10px;
621
698
  width: 100%;
@@ -627,22 +704,30 @@
627
704
  text-align: left;
628
705
  cursor: pointer;
629
706
  }
630
- .cmt-list__item:hover {
707
+ .tlui-cmt-list__item:hover {
631
708
  background: var(--tl-color-muted-2);
632
709
  }
633
- .cmt-list__item--selected {
634
- background: var(--tl-color-muted-1);
710
+ /* Selected sits a step above hover so the open thread's row stays distinguishable while
711
+ pointing at other rows — but only a step: the muted-1 token (10%) reads too heavy here.
712
+ These rows sit on the opaque sidebar panel, so a translucent tint composes safely. */
713
+ .tlui-cmt-list__item--selected,
714
+ .tlui-cmt-list__item--selected:hover {
715
+ background: hsl(0, 0%, 0%, 5%);
716
+ }
717
+ .tl-theme__dark .tlui-cmt-list__item--selected,
718
+ .tl-theme__dark .tlui-cmt-list__item--selected:hover {
719
+ background: hsl(0, 0%, 100%, 5%);
635
720
  }
636
721
  /* resolved rows mute their content but keep the "Resolved" marker legible */
637
- .cmt-list__item[data-resolved] .cmt-head,
638
- .cmt-list__item[data-resolved] .cmt-list__item-preview {
722
+ .tlui-cmt-list__item[data-resolved] .tlui-cmt-head,
723
+ .tlui-cmt-list__item[data-resolved] .tlui-cmt-list__item-preview {
639
724
  opacity: 0.55;
640
725
  }
641
- .cmt-list__item-body {
726
+ .tlui-cmt-list__item-body {
642
727
  flex: 1;
643
728
  min-width: 0;
644
729
  }
645
- .cmt-list__item-preview {
730
+ .tlui-cmt-list__item-preview {
646
731
  margin-top: 2px;
647
732
  font-size: 13px;
648
733
  color: var(--tl-color-text-1);
@@ -651,9 +736,12 @@
651
736
  display: -webkit-box;
652
737
  -webkit-line-clamp: 2;
653
738
  -webkit-box-orient: vertical;
739
+ /* Long unbroken strings (URLs, mashed keys) wrap onto the clamped lines instead of clipping
740
+ mid-string — same treatment as the card body. */
741
+ overflow-wrap: anywhere;
654
742
  }
655
743
  /* meta line under the preview: page label and/or a resolved marker */
656
- .cmt-list__item-meta {
744
+ .tlui-cmt-list__item-meta {
657
745
  display: flex;
658
746
  align-items: center;
659
747
  gap: 8px;
@@ -661,20 +749,20 @@
661
749
  font-size: 11px;
662
750
  color: var(--tl-color-text-3);
663
751
  }
664
- .cmt-list__item-resolved {
752
+ .tlui-cmt-list__item-resolved {
665
753
  display: inline-flex;
666
754
  align-items: center;
667
755
  gap: 3px;
668
756
  font-weight: 600;
669
757
  }
670
- .cmt-list__item-page {
758
+ .tlui-cmt-list__item-page {
671
759
  display: inline-flex;
672
760
  align-items: center;
673
761
  padding: 1px 6px;
674
762
  border-radius: 4px;
675
763
  background: var(--tl-color-muted-2);
676
764
  }
677
- .cmt-list__item-count {
765
+ .tlui-cmt-list__item-count {
678
766
  flex-shrink: 0;
679
767
  align-self: center;
680
768
  font-size: 12px;
@@ -683,70 +771,76 @@
683
771
 
684
772
  /* The comments layer is portaled into the editor container. Pins live in the canvas-in-front layer
685
773
  (beneath the UI panels at z-index 300), so the toolbar and style panel draw over them; the open
686
- thread's popover portals up to the menus layer separately (`.cmt-canvas-popover`) so it isn't
774
+ thread's popover portals up to the menus layer separately (`.tlui-cmt-canvas-popover`) so it isn't
687
775
  clipped. Click-through except on its own children. */
688
- .cmt-canvas-layer {
776
+ .tlui-cmt-canvas-layer {
689
777
  position: absolute;
690
778
  inset: 0;
691
779
  z-index: var(--tl-layer-canvas-in-front);
692
780
  pointer-events: none;
693
781
  }
694
782
 
695
- .cmt-canvas-pin,
696
- .cmt-canvas-cluster,
697
- .cmt-canvas-composer {
783
+ .tlui-cmt-canvas-pin,
784
+ .tlui-cmt-canvas-cluster,
785
+ .tlui-cmt-canvas-composer {
698
786
  position: absolute;
699
787
  }
700
788
 
701
- .cmt-canvas-pin,
702
- .cmt-canvas-composer {
789
+ .tlui-cmt-canvas-composer {
703
790
  pointer-events: auto;
704
791
  }
705
792
 
793
+ /* The pin's only interactive surface is the square hit layer below — the wrapper itself is
794
+ inert. Its box sits at the anchor point, not over the (translated) visual, so letting it take
795
+ events would put a phantom hit zone beside the pin. */
796
+ .tlui-cmt-canvas-pin {
797
+ pointer-events: none;
798
+ }
799
+
706
800
  /* Badges are clickable (zoom to the cluster's first split). */
707
- .cmt-canvas-cluster {
801
+ .tlui-cmt-canvas-cluster {
708
802
  transform: translate(-50%, -50%);
709
803
  pointer-events: auto;
710
804
  cursor: pointer;
711
805
  }
712
806
 
713
- .cmt-cluster-fade {
807
+ .tlui-cmt-cluster-fade {
714
808
  opacity: 1;
715
809
  transition: opacity 150ms ease;
716
810
  }
717
811
 
718
- .cmt-cluster-fade--entering {
812
+ .tlui-cmt-cluster-fade--entering {
719
813
  opacity: 0;
720
814
  }
721
815
 
722
- .cmt-cluster-fade--present {
816
+ .tlui-cmt-cluster-fade--present {
723
817
  opacity: 1;
724
818
  }
725
819
 
726
- .cmt-cluster-fade--exiting {
820
+ .tlui-cmt-cluster-fade--exiting {
727
821
  opacity: 0;
728
822
  }
729
823
 
730
- .cmt-cluster-fade--entering *,
731
- .cmt-cluster-fade--exiting * {
824
+ .tlui-cmt-cluster-fade--entering *,
825
+ .tlui-cmt-cluster-fade--exiting * {
732
826
  pointer-events: none !important;
733
827
  }
734
828
 
735
829
  @media (prefers-reduced-motion: reduce) {
736
- .cmt-cluster-fade {
830
+ .tlui-cmt-cluster-fade {
737
831
  transition: none;
738
832
  }
739
833
  }
740
834
 
741
835
  /* The open thread (its pin + popover) sits above the other pins, so nearby markers don't
742
836
  overlap its popover — they tuck behind it. */
743
- .cmt-canvas-pin--open {
837
+ .tlui-cmt-canvas-pin--open {
744
838
  z-index: 1;
745
839
  }
746
840
 
747
841
  /* A region anchor's area: a dashed box under the pins, non-interactive so canvas events pass
748
842
  through. Drawn for the live drag draft and for a region thread while hovered or open. */
749
- .cmt-canvas-region {
843
+ .tlui-cmt-canvas-region {
750
844
  position: absolute;
751
845
  pointer-events: none;
752
846
  border: 2px dashed var(--tl-color-selected);
@@ -756,13 +850,13 @@
756
850
 
757
851
  /* A movable region body (the 'body'/'both' move modes): draggable to translate the whole region.
758
852
  Interactive, so it captures the interior while shown — the tradeoff of dragging the body. */
759
- .cmt-canvas-region--movable {
853
+ .tlui-cmt-canvas-region--movable {
760
854
  pointer-events: auto;
761
855
  cursor: move;
762
856
  }
763
857
 
764
858
  /* Corner resize handles on a region box (three corners; the pin corner is the move handle). */
765
- .cmt-canvas-region-handle {
859
+ .tlui-cmt-canvas-region-handle {
766
860
  position: absolute;
767
861
  width: 9px;
768
862
  height: 9px;
@@ -774,19 +868,47 @@
774
868
  touch-action: none;
775
869
  }
776
870
 
777
- /* Centre the pin marker on its anchor point. */
778
- .cmt-canvas-pin__marker {
871
+ /* Anchor the pin by its bottom-left corner, so the marker's one sharp corner (the pin shape's
872
+ 3px bottom-left) points at the exact anchor point. */
873
+ .tlui-cmt-canvas-pin__marker {
874
+ position: relative;
779
875
  width: max-content;
780
- transform: translate(-50%, -50%);
781
- cursor: grab;
876
+ transform: translate(0, -100%);
877
+ /* Default at rest, like hovering a shape; the editor's move cursor while dragging (below). */
878
+ cursor: var(--tl-cursor-default);
782
879
  touch-action: none;
880
+ pointer-events: none;
881
+ }
882
+
883
+ /* Dragging a pin shows the same move cursor as dragging a shape. */
884
+ .tlui-cmt-canvas-pin--dragging .tlui-cmt-canvas-pin__marker {
885
+ cursor: var(--tl-cursor-move);
783
886
  }
784
- .cmt-canvas-pin__marker:active {
785
- cursor: grabbing;
887
+
888
+ /* The predictable hit area: a fixed square over the marker's box, and the only part of the pin
889
+ that takes pointer events. Events over it target the marker (a pseudo-element's events report
890
+ its originating element), so the marker's handlers and :hover keep working — but the hit area
891
+ no longer stretches with pin content or scales with the hover transform. */
892
+ .tlui-cmt-canvas-pin__marker::after {
893
+ content: '';
894
+ position: absolute;
895
+ inset: 0;
896
+ pointer-events: auto;
897
+ }
898
+
899
+ /* With the hit layer targeting the marker, the pin visual is never the hovered element itself
900
+ (`:hover` matches the target and its ancestors, and the pin is the marker's child) — so the
901
+ canvas pin's hover styling keys off the marker. The hover shadow is for closed pins only: an
902
+ open pin keeps its selection ring, which the shadow would otherwise override. */
903
+ .tlui-cmt-canvas-pin__marker:hover .tlui-cmt-pin {
904
+ transform: scale(1.08);
905
+ }
906
+ .tlui-cmt-canvas-pin__marker:hover .tlui-cmt-pin:not(.tlui-cmt-pin--open) {
907
+ box-shadow: 0 3px 10px rgba(0, 0, 0, 0.32);
786
908
  }
787
909
 
788
910
  /* The open thread's popover — portaled to the menus layer (above the UI), positioned at the pin. */
789
- .cmt-canvas-popover {
911
+ .tlui-cmt-canvas-popover {
790
912
  position: absolute;
791
913
  z-index: var(--tl-layer-menus);
792
914
  pointer-events: auto;
@@ -795,32 +917,41 @@
795
917
  /* The placement composer — a distinct floating view (portaled to the menus layer, below the click
796
918
  point): a pencil "draft" avatar beside a pill field that is itself the surface (no wrapping
797
919
  panel). Scoped here so the in-thread reply composer keeps its own squarer look. */
798
- .cmt-canvas-composer {
920
+ .tlui-cmt-canvas-composer {
799
921
  position: absolute;
800
922
  z-index: var(--tl-layer-menus);
801
923
  pointer-events: auto;
802
- transform: translateY(8px);
924
+ /* Anchor the draft avatar bottom-left like the pins it becomes: it is 34px wide and sits 4px
925
+ into the row, so its bottom-left corner is 4px right of and 4 + 34 = 38px below the
926
+ composer's top-left corner. */
927
+ transform: translate(-4px, -38px);
803
928
  /* The rich-text editor has no intrinsic width (unlike the old <input>), so give the floating
804
929
  placement composer a definite width or it collapses to nothing. */
805
930
  width: 280px;
806
931
  }
807
- .cmt-canvas-composer .cmt-composer__field {
932
+
933
+ /* A region placement centres the draft avatar on the region's pin corner — the pin it becomes
934
+ straddles that corner. The avatar's centre sits 4 + 34/2 = 21px into the composer. */
935
+ .tlui-cmt-canvas-composer--region {
936
+ transform: translate(-21px, -21px);
937
+ }
938
+ .tlui-cmt-canvas-composer .tlui-cmt-composer__field {
808
939
  background: var(--tl-color-panel);
809
940
  border-color: transparent;
810
941
  border-radius: var(--tl-radius-4);
811
942
  box-shadow: var(--tl-shadow-2);
812
943
  }
813
944
 
814
- /* The comments list panel — a right-side surface shown while the comment tool is active. Below
815
- the popover layer, so an open thread still draws over it. Sits under the top-right share panel
816
- (top offset clears its ~48px height) and sizes to its content, scrolling past max-height rather
817
- than stretching the full canvas height. */
818
- .cmt-canvas-sidebar {
945
+ /* The comments list panel — a right-side surface shown while the comments sidebar is open. Below
946
+ the popover layer, so an open thread still draws over it. Its top aligns flush with the style
947
+ panel (48px from the top, clearing the share panel) and it sizes to its content, scrolling past
948
+ max-height rather than stretching the full canvas height. */
949
+ .tlui-cmt-canvas-sidebar {
819
950
  position: absolute;
820
- top: 56px;
951
+ top: 48px;
821
952
  right: 8px;
822
953
  width: 280px;
823
- max-height: calc(100% - 64px);
954
+ max-height: calc(100% - 56px);
824
955
  z-index: var(--tl-layer-panels);
825
956
  pointer-events: auto;
826
957
  display: flex;
package/dist-cjs/index.js CHANGED
@@ -19,7 +19,7 @@ var import_utils = require("@tldraw/utils");
19
19
  __reExport(index_exports, require("@tldraw/commenting"), module.exports);
20
20
  (0, import_utils.registerTldrawLibraryVersion)(
21
21
  "@tldraw/collaboration",
22
- "0.0.0-bootstrap",
22
+ "5.3.0-internal.41291fb579ed",
23
23
  "cjs"
24
24
  );
25
25
  //# sourceMappingURL=index.js.map
@@ -2,7 +2,7 @@ import { registerTldrawLibraryVersion } from "@tldraw/utils";
2
2
  export * from "@tldraw/commenting";
3
3
  registerTldrawLibraryVersion(
4
4
  "@tldraw/collaboration",
5
- "0.0.0-bootstrap",
5
+ "5.3.0-internal.41291fb579ed",
6
6
  "esm"
7
7
  );
8
8
  //# sourceMappingURL=index.mjs.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tldraw/collaboration",
3
3
  "description": "tldraw collaboration umbrella package.",
4
- "version": "0.0.0-bootstrap",
4
+ "version": "5.3.0-internal.41291fb579ed",
5
5
  "author": {
6
6
  "name": "tldraw Inc.",
7
7
  "email": "hello@tldraw.com"
@@ -51,8 +51,8 @@
51
51
  "node": ">=22.12.0"
52
52
  },
53
53
  "dependencies": {
54
- "@tldraw/commenting": "5.2.3",
55
- "@tldraw/utils": "5.2.5"
54
+ "@tldraw/commenting": "5.3.0-internal.41291fb579ed",
55
+ "@tldraw/utils": "5.3.0-internal.41291fb579ed"
56
56
  },
57
57
  "module": "dist-esm/index.mjs",
58
58
  "source": "src/index.ts",