@tldraw/collaboration 0.0.0-bootstrap

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/README.md ADDED
@@ -0,0 +1,7 @@
1
+ # @tldraw/collaboration
2
+
3
+ tldraw's collaboration umbrella package. It re-exports the individual collaboration
4
+ packages so consumers can depend on a single entry point.
5
+
6
+ For now it re-exports [`@tldraw/commenting`](../commenting). Over time it will grow to
7
+ re-export the other collaboration packages as well.
@@ -0,0 +1,832 @@
1
+ /* THIS CSS FILE IS GENERATED! DO NOT EDIT. OR EDIT. I'M A COMMENT NOT A COP */
2
+ /* This file is created by the copy-css-files.mjs script in packages/collaboration. */
3
+ /* It combines the stylesheets of the collaboration umbrella's sub-packages. */
4
+
5
+ /* Real comment UI components. Co-located so styles travel to any view (studio,
6
+ canvas), and themed via tldraw's --tl-color tokens so they follow light/dark. */
7
+ .cmt-card {
8
+ position: relative;
9
+ display: flex;
10
+ gap: 10px;
11
+ padding: 12px;
12
+ width: 260px;
13
+ background: var(--tl-color-panel);
14
+ border: 1px solid var(--tl-color-divider);
15
+ border-radius: 12px;
16
+ }
17
+
18
+ /* hover-revealed controls (edit…) at the card's top-right */
19
+ .cmt-card__actions {
20
+ position: absolute;
21
+ top: 6px;
22
+ right: 6px;
23
+ display: flex;
24
+ gap: 2px;
25
+ opacity: 0;
26
+ }
27
+ .cmt-card:hover .cmt-card__actions,
28
+ .cmt-card:focus-within .cmt-card__actions {
29
+ opacity: 1;
30
+ }
31
+
32
+ .cmt-body {
33
+ flex: 1;
34
+ min-width: 0;
35
+ }
36
+
37
+ .cmt-head {
38
+ display: flex;
39
+ align-items: baseline;
40
+ gap: 6px;
41
+ }
42
+
43
+ .cmt-author {
44
+ font-weight: 600;
45
+ font-size: 13px;
46
+ color: var(--tl-color-text-1);
47
+ }
48
+
49
+ .cmt-time {
50
+ font-size: 11px;
51
+ color: var(--tl-color-text-3);
52
+ }
53
+
54
+ .cmt-text {
55
+ margin: 3px 0 0;
56
+ font-size: 13px;
57
+ line-height: 1.4;
58
+ color: var(--tl-color-text-1);
59
+ }
60
+
61
+ .cmt-edited {
62
+ font-style: italic;
63
+ }
64
+
65
+ /* rendered rich text inside a comment body — bare tags emitted by the comment renderer
66
+ (paragraphs, lists, code, highlight, links), matching the limited comment extension set. */
67
+ .cmt-text p {
68
+ margin: 0;
69
+ }
70
+
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 {
76
+ margin-top: 6px;
77
+ }
78
+
79
+ .cmt-text ul,
80
+ .cmt-text ol {
81
+ margin: 0;
82
+ padding-left: 18px;
83
+ }
84
+
85
+ .cmt-text code {
86
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
87
+ font-size: 0.92em;
88
+ background: var(--tl-color-muted-2);
89
+ border-radius: 3px;
90
+ padding: 0 3px;
91
+ }
92
+
93
+ .cmt-text mark {
94
+ background: color-mix(in srgb, #ffeb3b 60%, transparent);
95
+ color: inherit;
96
+ border-radius: 2px;
97
+ }
98
+
99
+ .cmt-text a {
100
+ color: var(--tl-color-selected);
101
+ text-decoration: underline;
102
+ }
103
+
104
+ .cmt-avatar {
105
+ width: 28px;
106
+ height: 28px;
107
+ border-radius: 50%;
108
+ background: var(--tl-color-selected);
109
+ color: #fff;
110
+ display: flex;
111
+ align-items: center;
112
+ justify-content: center;
113
+ font-size: 11px;
114
+ font-weight: 600;
115
+ flex-shrink: 0;
116
+ }
117
+
118
+ .cmt-avatar--image {
119
+ object-fit: cover;
120
+ background: none;
121
+ }
122
+
123
+ /* composer — an avatar beside a rounded-rect field holding the rich-text input and the send button.
124
+ Formatting is applied via markdown and keyboard shortcuts (no toolbar). The avatar aligns to the
125
+ top so it stays put as the field grows to multiple lines. */
126
+ .cmt-composer {
127
+ display: flex;
128
+ align-items: flex-start;
129
+ gap: 10px;
130
+ padding: 4px 0 8px 4px;
131
+ }
132
+
133
+ .cmt-composer__field {
134
+ flex: 1;
135
+ min-width: 0;
136
+ display: flex;
137
+ align-items: center;
138
+ gap: 6px;
139
+ padding: 3px 3px 3px 12px;
140
+ background: var(--tl-color-muted-2);
141
+ border: 1px solid var(--tl-color-divider);
142
+ border-radius: var(--tl-radius-3);
143
+ }
144
+
145
+ .cmt-composer__field:focus-within {
146
+ border-color: var(--tl-color-selected);
147
+ }
148
+
149
+ /* the editable area, with the placeholder overlaid while it's empty */
150
+ .cmt-composer__input-wrap {
151
+ position: relative;
152
+ flex: 1;
153
+ min-width: 0;
154
+ padding: 3px 0;
155
+ }
156
+
157
+ .cmt-input {
158
+ font: inherit;
159
+ font-size: 13px;
160
+ line-height: 1.4;
161
+ color: var(--tl-color-text-1);
162
+ outline: none;
163
+ min-height: 20px;
164
+ max-height: 40vh;
165
+ overflow-y: auto;
166
+ white-space: pre-wrap;
167
+ word-break: break-word;
168
+ }
169
+
170
+ .cmt-input p {
171
+ margin: 0;
172
+ }
173
+
174
+ .cmt-input p + p,
175
+ .cmt-input p + ul,
176
+ .cmt-input p + ol {
177
+ margin-top: 4px;
178
+ }
179
+
180
+ .cmt-input ul,
181
+ .cmt-input ol {
182
+ margin: 0;
183
+ padding-left: 18px;
184
+ }
185
+
186
+ .cmt-input__placeholder {
187
+ position: absolute;
188
+ top: 3px;
189
+ left: 0;
190
+ font-size: 13px;
191
+ line-height: 1.4;
192
+ color: var(--tl-color-text-3);
193
+ pointer-events: none;
194
+ }
195
+
196
+ .cmt-send {
197
+ border: 0;
198
+ border-radius: var(--tl-radius-2);
199
+ background: var(--tl-color-selected);
200
+ color: #fff;
201
+ font: inherit;
202
+ font-size: 12px;
203
+ font-weight: 600;
204
+ padding: 6px 12px;
205
+ cursor: pointer;
206
+ align-self: flex-end;
207
+ }
208
+
209
+ .cmt-send:hover,
210
+ .pseudo-hover .cmt-send {
211
+ background: color-mix(in srgb, var(--tl-color-selected) 88%, black);
212
+ }
213
+
214
+ .cmt-send:active,
215
+ .pseudo-active .cmt-send {
216
+ background: color-mix(in srgb, var(--tl-color-selected) 78%, black);
217
+ }
218
+
219
+ .cmt-send:focus-visible,
220
+ .pseudo-focus-visible .cmt-send {
221
+ outline: 2px solid var(--tl-color-selected);
222
+ outline-offset: 2px;
223
+ }
224
+
225
+ .cmt-send:disabled {
226
+ opacity: 0.45;
227
+ cursor: not-allowed;
228
+ }
229
+
230
+ /* pin */
231
+ .cmt-pin {
232
+ width: 34px;
233
+ height: 34px;
234
+ border-radius: 50% 50% 50% 3px;
235
+ background: var(--tl-color-selected);
236
+ color: #fff;
237
+ display: flex;
238
+ align-items: center;
239
+ justify-content: center;
240
+ font-size: 14px;
241
+ font-weight: 600;
242
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
243
+ cursor: pointer;
244
+ transition:
245
+ transform 0.08s ease,
246
+ box-shadow 0.08s ease;
247
+ }
248
+
249
+ .cmt-pin:hover,
250
+ .pseudo-hover .cmt-pin {
251
+ transform: scale(1.08);
252
+ box-shadow: 0 3px 10px rgba(0, 0, 0, 0.32);
253
+ }
254
+
255
+ /* open: the thread is showing — a selection ring marks the active pin */
256
+ .cmt-pin--open {
257
+ box-shadow:
258
+ 0 0 0 3px var(--tl-color-panel),
259
+ 0 0 0 5px var(--tl-color-selected),
260
+ 0 2px 6px rgba(0, 0, 0, 0.25);
261
+ }
262
+
263
+ /* resolved: a solid, muted grey (the default --tl-color-muted-1 is 10% black, so it goes
264
+ translucent over the canvas). Dark mode gets its own grey — the token's dark value is near-black. */
265
+ .cmt-pin--resolved {
266
+ background: #dfe0e1;
267
+ color: hsl(214, 8%, 42%);
268
+ }
269
+ .tl-theme__dark .cmt-pin--resolved {
270
+ background: hsl(240, 5%, 30%);
271
+ color: hsl(0, 0%, 72%);
272
+ }
273
+
274
+ /* count badge */
275
+ .cmt-count-badge {
276
+ width: 34px;
277
+ height: 34px;
278
+ border-radius: 50%;
279
+ display: flex;
280
+ align-items: center;
281
+ justify-content: center;
282
+ background: var(--tl-color-text-1);
283
+ color: var(--tl-color-panel);
284
+ font-size: 13px;
285
+ font-weight: 700;
286
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
287
+ user-select: none;
288
+ }
289
+
290
+ /* thread */
291
+ .cmt-thread {
292
+ display: flex;
293
+ flex-direction: column;
294
+ gap: 8px;
295
+ width: 300px;
296
+ }
297
+
298
+ .cmt-thread__head {
299
+ display: flex;
300
+ align-items: center;
301
+ gap: 8px;
302
+ font-size: 12px;
303
+ font-weight: 600;
304
+ color: var(--tl-color-text-3);
305
+ text-transform: uppercase;
306
+ letter-spacing: 0.04em;
307
+ }
308
+
309
+ .cmt-badge {
310
+ font-size: 10px;
311
+ font-weight: 600;
312
+ text-transform: none;
313
+ letter-spacing: 0;
314
+ color: #fff;
315
+ background: var(--tl-color-muted-1);
316
+ padding: 1px 6px;
317
+ border-radius: 999px;
318
+ }
319
+
320
+ /* reactions */
321
+ .cmt-reactions {
322
+ display: flex;
323
+ gap: 6px;
324
+ }
325
+
326
+ .cmt-reaction {
327
+ display: inline-flex;
328
+ align-items: center;
329
+ gap: 5px;
330
+ padding: 3px 9px;
331
+ border-radius: 999px;
332
+ border: 1px solid var(--tl-color-divider);
333
+ background: var(--tl-color-panel);
334
+ font: inherit;
335
+ font-size: 12px;
336
+ color: var(--tl-color-text-1);
337
+ cursor: pointer;
338
+ }
339
+
340
+ .cmt-reaction:hover,
341
+ .pseudo-hover .cmt-reaction {
342
+ border-color: var(--tl-color-selected);
343
+ }
344
+
345
+ .cmt-reaction--active {
346
+ border-color: var(--tl-color-selected);
347
+ background: color-mix(in srgb, var(--tl-color-selected) 12%, var(--tl-color-panel));
348
+ }
349
+
350
+ .cmt-reaction__count {
351
+ color: var(--tl-color-text-3);
352
+ }
353
+
354
+ .cmt-reaction--add {
355
+ color: var(--tl-color-text-3);
356
+ font-weight: 600;
357
+ }
358
+
359
+ /* mention */
360
+ .cmt-mention {
361
+ color: var(--tl-color-selected);
362
+ font-weight: 600;
363
+ background: color-mix(in srgb, var(--tl-color-selected) 12%, transparent);
364
+ padding: 0 4px;
365
+ border-radius: 4px;
366
+ }
367
+
368
+ /* mention picker */
369
+ .cmt-mention-list {
370
+ display: flex;
371
+ flex-direction: column;
372
+ gap: 1px;
373
+ padding: 4px;
374
+ width: 100%;
375
+ box-sizing: border-box;
376
+ max-height: 260px;
377
+ overflow-y: auto;
378
+ color: var(--tl-color-text-1, #1d1d1d);
379
+ background: var(--tl-color-panel, #fff);
380
+ border: 1px solid var(--tl-color-divider, rgba(0, 0, 0, 0.08));
381
+ border-radius: 10px;
382
+ box-shadow: var(--tl-shadow-2, 0 2px 12px rgba(0, 0, 0, 0.14));
383
+ }
384
+
385
+ .cmt-mention-list__item {
386
+ display: flex;
387
+ align-items: center;
388
+ gap: 8px;
389
+ padding: 6px 8px;
390
+ border: none;
391
+ background: transparent;
392
+ border-radius: 6px;
393
+ cursor: pointer;
394
+ text-align: left;
395
+ color: var(--tl-color-text-1);
396
+ font: inherit;
397
+ }
398
+
399
+ .cmt-mention-list__item--active,
400
+ .cmt-mention-list__item:hover {
401
+ background: var(--tl-color-muted-2, rgba(0, 0, 0, 0.06));
402
+ }
403
+
404
+ .cmt-mention-list__text {
405
+ display: flex;
406
+ flex-direction: column;
407
+ min-width: 0;
408
+ line-height: 1.3;
409
+ }
410
+
411
+ .cmt-mention-list__name {
412
+ font-size: 13px;
413
+ font-weight: 500;
414
+ white-space: nowrap;
415
+ overflow: hidden;
416
+ text-overflow: ellipsis;
417
+ }
418
+
419
+ .cmt-mention-list__you {
420
+ margin-left: 4px;
421
+ font-weight: 400;
422
+ color: var(--tl-color-text-3);
423
+ }
424
+
425
+ .cmt-mention-list__secondary {
426
+ font-size: 12px;
427
+ color: var(--tl-color-text-3);
428
+ white-space: nowrap;
429
+ overflow: hidden;
430
+ text-overflow: ellipsis;
431
+ }
432
+
433
+ .cmt-mention-list--empty {
434
+ padding: 8px 10px;
435
+ width: 100%;
436
+ box-sizing: border-box;
437
+ color: var(--tl-color-text-3);
438
+ font-size: 13px;
439
+ }
440
+
441
+ /* the @-picker popup — caret-anchored above the page, positioned by the suggestion plugin */
442
+ .cmt-mention-popup {
443
+ position: fixed;
444
+ z-index: var(--tl-layer-menus);
445
+ }
446
+
447
+ /* empty state */
448
+ .cmt-empty {
449
+ display: flex;
450
+ flex-direction: column;
451
+ align-items: center;
452
+ gap: 8px;
453
+ padding: 24px;
454
+ text-align: center;
455
+ width: 240px;
456
+ }
457
+
458
+ .cmt-empty__icon {
459
+ font-size: 28px;
460
+ }
461
+
462
+ .cmt-empty__message {
463
+ margin: 0;
464
+ color: var(--tl-color-text-3);
465
+ font-size: 13px;
466
+ line-height: 1.4;
467
+ }
468
+
469
+ /* a comment thread: an elevated panel — the same surface treatment as the toolbar — holding a
470
+ header, an optional resolved banner, the comments, and a reply composer */
471
+ .cmt-thread {
472
+ display: flex;
473
+ flex-direction: column;
474
+ gap: 6px;
475
+ width: 300px;
476
+ padding: 8px;
477
+ background: var(--tl-color-panel);
478
+ border-radius: var(--tl-radius-4);
479
+ box-shadow: var(--tl-shadow-2);
480
+ }
481
+ .cmt-thread__header {
482
+ display: flex;
483
+ align-items: center;
484
+ justify-content: space-between;
485
+ padding: 2px 2px 2px 4px;
486
+ }
487
+ .cmt-thread__title {
488
+ font-size: 12px;
489
+ font-weight: 600;
490
+ color: var(--tl-color-text-1);
491
+ }
492
+ .cmt-thread__actions {
493
+ display: flex;
494
+ gap: 2px;
495
+ }
496
+ .cmt-thread__action {
497
+ display: flex;
498
+ align-items: center;
499
+ justify-content: center;
500
+ width: 22px;
501
+ height: 22px;
502
+ padding: 0;
503
+ border: none;
504
+ border-radius: 6px;
505
+ background: transparent;
506
+ color: var(--tl-color-text-3);
507
+ font-size: 14px;
508
+ line-height: 1;
509
+ cursor: pointer;
510
+ }
511
+ .cmt-thread__action:hover {
512
+ background: var(--tl-color-muted-2);
513
+ color: var(--tl-color-text-1);
514
+ }
515
+ .cmt-thread__resolved {
516
+ padding: 6px 10px;
517
+ border-radius: 8px;
518
+ background: var(--tl-color-muted-2);
519
+ font-size: 12px;
520
+ color: var(--tl-color-text-3);
521
+ }
522
+ .cmt-thread__list {
523
+ display: flex;
524
+ flex-direction: column;
525
+ gap: 6px;
526
+ }
527
+ /* inside the panel, comments are plain content — no surrounding box; the composer's field carries
528
+ its own surface. */
529
+ .cmt-thread .cmt-card {
530
+ width: 100%;
531
+ padding: 6px 0 6px 4px;
532
+ background: transparent;
533
+ border: none;
534
+ }
535
+
536
+ /* comments list — thread summaries, one per row (used by the canvas sidebar) */
537
+ .cmt-list {
538
+ display: flex;
539
+ flex-direction: column;
540
+ width: 100%;
541
+ min-height: 0;
542
+ }
543
+ .cmt-list__header {
544
+ flex-shrink: 0;
545
+ display: flex;
546
+ align-items: center;
547
+ justify-content: space-between;
548
+ gap: 8px;
549
+ padding: 6px 6px 6px 14px;
550
+ border-bottom: 1px solid var(--tl-color-divider);
551
+ }
552
+ .cmt-list__header-title {
553
+ font-size: 11px;
554
+ font-weight: 600;
555
+ letter-spacing: 0.06em;
556
+ text-transform: uppercase;
557
+ color: var(--tl-color-text-3);
558
+ }
559
+
560
+ /* a small square icon button in the sidebar header (filter funnel, overflow …) */
561
+ .cmt-header-btn {
562
+ display: flex;
563
+ align-items: center;
564
+ justify-content: center;
565
+ width: 26px;
566
+ height: 26px;
567
+ padding: 0;
568
+ border: none;
569
+ border-radius: 6px;
570
+ background: transparent;
571
+ color: var(--tl-color-text-2);
572
+ cursor: pointer;
573
+ }
574
+ .cmt-header-btn:hover,
575
+ .cmt-header-btn[data-state='open'] {
576
+ background: var(--tl-color-muted-2);
577
+ color: var(--tl-color-text-1);
578
+ }
579
+ .cmt-list__header-actions {
580
+ display: flex;
581
+ align-items: center;
582
+ gap: 2px;
583
+ }
584
+
585
+ /* a menu row with a label and a right-aligned shortcut hint (overflow menu) */
586
+ .cmt-menu-item {
587
+ display: flex;
588
+ align-items: center;
589
+ justify-content: space-between;
590
+ gap: 24px;
591
+ width: 100%;
592
+ padding: 6px 8px;
593
+ border: none;
594
+ border-radius: 6px;
595
+ background: transparent;
596
+ font: inherit;
597
+ font-size: 13px;
598
+ color: var(--tl-color-text-1);
599
+ cursor: pointer;
600
+ }
601
+ .cmt-menu-item:hover {
602
+ background: var(--tl-color-muted-2);
603
+ }
604
+ .cmt-menu-item__shortcut {
605
+ color: var(--tl-color-text-3);
606
+ font-size: 12px;
607
+ }
608
+ .cmt-list__items {
609
+ flex: 1;
610
+ min-height: 0;
611
+ overflow-y: auto;
612
+ }
613
+ .cmt-list__empty {
614
+ padding: 20px 14px;
615
+ color: var(--tl-color-text-3);
616
+ font-size: 13px;
617
+ }
618
+ .cmt-list__item {
619
+ display: flex;
620
+ gap: 10px;
621
+ width: 100%;
622
+ padding: 12px 14px;
623
+ border: none;
624
+ border-bottom: 1px solid var(--tl-color-divider);
625
+ background: transparent;
626
+ font: inherit;
627
+ text-align: left;
628
+ cursor: pointer;
629
+ }
630
+ .cmt-list__item:hover {
631
+ background: var(--tl-color-muted-2);
632
+ }
633
+ .cmt-list__item--selected {
634
+ background: var(--tl-color-muted-1);
635
+ }
636
+ /* 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 {
639
+ opacity: 0.55;
640
+ }
641
+ .cmt-list__item-body {
642
+ flex: 1;
643
+ min-width: 0;
644
+ }
645
+ .cmt-list__item-preview {
646
+ margin-top: 2px;
647
+ font-size: 13px;
648
+ color: var(--tl-color-text-1);
649
+ overflow: hidden;
650
+ text-overflow: ellipsis;
651
+ display: -webkit-box;
652
+ -webkit-line-clamp: 2;
653
+ -webkit-box-orient: vertical;
654
+ }
655
+ /* meta line under the preview: page label and/or a resolved marker */
656
+ .cmt-list__item-meta {
657
+ display: flex;
658
+ align-items: center;
659
+ gap: 8px;
660
+ margin-top: 5px;
661
+ font-size: 11px;
662
+ color: var(--tl-color-text-3);
663
+ }
664
+ .cmt-list__item-resolved {
665
+ display: inline-flex;
666
+ align-items: center;
667
+ gap: 3px;
668
+ font-weight: 600;
669
+ }
670
+ .cmt-list__item-page {
671
+ display: inline-flex;
672
+ align-items: center;
673
+ padding: 1px 6px;
674
+ border-radius: 4px;
675
+ background: var(--tl-color-muted-2);
676
+ }
677
+ .cmt-list__item-count {
678
+ flex-shrink: 0;
679
+ align-self: center;
680
+ font-size: 12px;
681
+ color: var(--tl-color-text-3);
682
+ }
683
+
684
+ /* The comments layer is portaled into the editor container. Pins live in the canvas-in-front layer
685
+ (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
687
+ clipped. Click-through except on its own children. */
688
+ .cmt-canvas-layer {
689
+ position: absolute;
690
+ inset: 0;
691
+ z-index: var(--tl-layer-canvas-in-front);
692
+ pointer-events: none;
693
+ }
694
+
695
+ .cmt-canvas-pin,
696
+ .cmt-canvas-cluster,
697
+ .cmt-canvas-composer {
698
+ position: absolute;
699
+ }
700
+
701
+ .cmt-canvas-pin,
702
+ .cmt-canvas-composer {
703
+ pointer-events: auto;
704
+ }
705
+
706
+ /* Badges are clickable (zoom to the cluster's first split). */
707
+ .cmt-canvas-cluster {
708
+ transform: translate(-50%, -50%);
709
+ pointer-events: auto;
710
+ cursor: pointer;
711
+ }
712
+
713
+ .cmt-cluster-fade {
714
+ opacity: 1;
715
+ transition: opacity 150ms ease;
716
+ }
717
+
718
+ .cmt-cluster-fade--entering {
719
+ opacity: 0;
720
+ }
721
+
722
+ .cmt-cluster-fade--present {
723
+ opacity: 1;
724
+ }
725
+
726
+ .cmt-cluster-fade--exiting {
727
+ opacity: 0;
728
+ }
729
+
730
+ .cmt-cluster-fade--entering *,
731
+ .cmt-cluster-fade--exiting * {
732
+ pointer-events: none !important;
733
+ }
734
+
735
+ @media (prefers-reduced-motion: reduce) {
736
+ .cmt-cluster-fade {
737
+ transition: none;
738
+ }
739
+ }
740
+
741
+ /* The open thread (its pin + popover) sits above the other pins, so nearby markers don't
742
+ overlap its popover — they tuck behind it. */
743
+ .cmt-canvas-pin--open {
744
+ z-index: 1;
745
+ }
746
+
747
+ /* A region anchor's area: a dashed box under the pins, non-interactive so canvas events pass
748
+ through. Drawn for the live drag draft and for a region thread while hovered or open. */
749
+ .cmt-canvas-region {
750
+ position: absolute;
751
+ pointer-events: none;
752
+ border: 2px dashed var(--tl-color-selected);
753
+ border-radius: 6px;
754
+ background: color-mix(in srgb, var(--tl-color-selected) 10%, transparent);
755
+ }
756
+
757
+ /* A movable region body (the 'body'/'both' move modes): draggable to translate the whole region.
758
+ Interactive, so it captures the interior while shown — the tradeoff of dragging the body. */
759
+ .cmt-canvas-region--movable {
760
+ pointer-events: auto;
761
+ cursor: move;
762
+ }
763
+
764
+ /* Corner resize handles on a region box (three corners; the pin corner is the move handle). */
765
+ .cmt-canvas-region-handle {
766
+ position: absolute;
767
+ width: 9px;
768
+ height: 9px;
769
+ transform: translate(-50%, -50%);
770
+ background: var(--tl-color-panel);
771
+ border: 1.5px solid var(--tl-color-selected);
772
+ border-radius: 2px;
773
+ pointer-events: auto;
774
+ touch-action: none;
775
+ }
776
+
777
+ /* Centre the pin marker on its anchor point. */
778
+ .cmt-canvas-pin__marker {
779
+ width: max-content;
780
+ transform: translate(-50%, -50%);
781
+ cursor: grab;
782
+ touch-action: none;
783
+ }
784
+ .cmt-canvas-pin__marker:active {
785
+ cursor: grabbing;
786
+ }
787
+
788
+ /* The open thread's popover — portaled to the menus layer (above the UI), positioned at the pin. */
789
+ .cmt-canvas-popover {
790
+ position: absolute;
791
+ z-index: var(--tl-layer-menus);
792
+ pointer-events: auto;
793
+ }
794
+
795
+ /* The placement composer — a distinct floating view (portaled to the menus layer, below the click
796
+ point): a pencil "draft" avatar beside a pill field that is itself the surface (no wrapping
797
+ panel). Scoped here so the in-thread reply composer keeps its own squarer look. */
798
+ .cmt-canvas-composer {
799
+ position: absolute;
800
+ z-index: var(--tl-layer-menus);
801
+ pointer-events: auto;
802
+ transform: translateY(8px);
803
+ /* The rich-text editor has no intrinsic width (unlike the old <input>), so give the floating
804
+ placement composer a definite width or it collapses to nothing. */
805
+ width: 280px;
806
+ }
807
+ .cmt-canvas-composer .cmt-composer__field {
808
+ background: var(--tl-color-panel);
809
+ border-color: transparent;
810
+ border-radius: var(--tl-radius-4);
811
+ box-shadow: var(--tl-shadow-2);
812
+ }
813
+
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 {
819
+ position: absolute;
820
+ top: 56px;
821
+ right: 8px;
822
+ width: 280px;
823
+ max-height: calc(100% - 64px);
824
+ z-index: var(--tl-layer-panels);
825
+ pointer-events: auto;
826
+ display: flex;
827
+ background: var(--tl-color-panel);
828
+ border-radius: var(--tl-radius-4);
829
+ box-shadow: var(--tl-shadow-2);
830
+ overflow: hidden;
831
+ }
832
+
@@ -0,0 +1,4 @@
1
+
2
+ export * from "@tldraw/commenting";
3
+
4
+ export { }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
15
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
16
+ var index_exports = {};
17
+ module.exports = __toCommonJS(index_exports);
18
+ var import_utils = require("@tldraw/utils");
19
+ __reExport(index_exports, require("@tldraw/commenting"), module.exports);
20
+ (0, import_utils.registerTldrawLibraryVersion)(
21
+ "@tldraw/collaboration",
22
+ "0.0.0-bootstrap",
23
+ "cjs"
24
+ );
25
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts"],
4
+ "sourcesContent": ["import { registerTldrawLibraryVersion } from '@tldraw/utils'\n\n// The collaboration umbrella. For now it re-exports the commenting package; over time it\n// will re-export the other collaboration packages as well.\n\n// eslint-disable-next-line tldraw/no-export-star\nexport * from '@tldraw/commenting'\n\nregisterTldrawLibraryVersion(\n\t(globalThis as any).TLDRAW_LIBRARY_NAME,\n\t(globalThis as any).TLDRAW_LIBRARY_VERSION,\n\t(globalThis as any).TLDRAW_LIBRARY_MODULES\n)\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;AAAA;AAAA;AAAA,mBAA6C;AAM7C,0BAAc,+BANd;AAAA,IAQA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,4 @@
1
+
2
+ export * from "@tldraw/commenting";
3
+
4
+ export { }
@@ -0,0 +1,8 @@
1
+ import { registerTldrawLibraryVersion } from "@tldraw/utils";
2
+ export * from "@tldraw/commenting";
3
+ registerTldrawLibraryVersion(
4
+ "@tldraw/collaboration",
5
+ "0.0.0-bootstrap",
6
+ "esm"
7
+ );
8
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts"],
4
+ "sourcesContent": ["import { registerTldrawLibraryVersion } from '@tldraw/utils'\n\n// The collaboration umbrella. For now it re-exports the commenting package; over time it\n// will re-export the other collaboration packages as well.\n\n// eslint-disable-next-line tldraw/no-export-star\nexport * from '@tldraw/commenting'\n\nregisterTldrawLibraryVersion(\n\t(globalThis as any).TLDRAW_LIBRARY_NAME,\n\t(globalThis as any).TLDRAW_LIBRARY_VERSION,\n\t(globalThis as any).TLDRAW_LIBRARY_MODULES\n)\n"],
5
+ "mappings": "AAAA,SAAS,oCAAoC;AAM7C,cAAc;AAEd;AAAA,EACE;AAAA,EACA;AAAA,EACA;AACF;",
6
+ "names": []
7
+ }
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@tldraw/collaboration",
3
+ "description": "tldraw collaboration umbrella package.",
4
+ "version": "0.0.0-bootstrap",
5
+ "author": {
6
+ "name": "tldraw Inc.",
7
+ "email": "hello@tldraw.com"
8
+ },
9
+ "homepage": "https://tldraw.dev",
10
+ "license": "SEE LICENSE IN LICENSE.md",
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://github.com/tldraw/tldraw"
14
+ },
15
+ "bugs": {
16
+ "url": "https://github.com/tldraw/tldraw/issues"
17
+ },
18
+ "main": "dist-cjs/index.js",
19
+ "style": "./collaboration.css",
20
+ "files": [
21
+ "collaboration.css",
22
+ "dist-esm",
23
+ "dist-cjs",
24
+ "src"
25
+ ],
26
+ "scripts": {
27
+ "test-ci": "yarn run -T vitest run --passWithNoTests",
28
+ "test": "yarn run -T vitest --passWithNoTests",
29
+ "test-coverage": "yarn run -T vitest run --coverage --passWithNoTests",
30
+ "predev": "node ./scripts/copy-css-files.mjs",
31
+ "dev": "chokidar '../commenting/src/**/*.css' -c 'node ./scripts/copy-css-files.mjs'",
32
+ "prebuild": "node ./scripts/copy-css-files.mjs",
33
+ "build": "yarn run -T tsx ../../internal/scripts/build-package.ts",
34
+ "build-api": "yarn run -T tsx ../../internal/scripts/build-api.ts",
35
+ "prepack": "yarn run -T tsx ../../internal/scripts/prepack.ts",
36
+ "postpack": "../../internal/scripts/postpack.sh",
37
+ "pack-tarball": "yarn pack",
38
+ "lint": "yarn run -T tsx ../../internal/scripts/lint.ts"
39
+ },
40
+ "devDependencies": {
41
+ "@types/react": "^19.2.7",
42
+ "@types/react-dom": "^19.2.3",
43
+ "react": "^19.2.1",
44
+ "react-dom": "^19.2.1"
45
+ },
46
+ "peerDependencies": {
47
+ "react": "^18.2.0 || ^19.2.1",
48
+ "react-dom": "^18.2.0 || ^19.2.1"
49
+ },
50
+ "engines": {
51
+ "node": ">=22.12.0"
52
+ },
53
+ "dependencies": {
54
+ "@tldraw/commenting": "5.2.3",
55
+ "@tldraw/utils": "5.2.5"
56
+ },
57
+ "module": "dist-esm/index.mjs",
58
+ "source": "src/index.ts",
59
+ "exports": {
60
+ ".": {
61
+ "import": "./dist-esm/index.mjs",
62
+ "require": "./dist-cjs/index.js"
63
+ },
64
+ "./collaboration.css": "./collaboration.css"
65
+ }
66
+ }
package/src/index.ts ADDED
@@ -0,0 +1,13 @@
1
+ import { registerTldrawLibraryVersion } from '@tldraw/utils'
2
+
3
+ // The collaboration umbrella. For now it re-exports the commenting package; over time it
4
+ // will re-export the other collaboration packages as well.
5
+
6
+ // eslint-disable-next-line tldraw/no-export-star
7
+ export * from '@tldraw/commenting'
8
+
9
+ registerTldrawLibraryVersion(
10
+ (globalThis as any).TLDRAW_LIBRARY_NAME,
11
+ (globalThis as any).TLDRAW_LIBRARY_VERSION,
12
+ (globalThis as any).TLDRAW_LIBRARY_MODULES
13
+ )