@tldraw/collaboration 5.3.0-next.d7d8ced023d5 → 5.3.0-next.dec36c5c2930

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
@@ -198,6 +198,15 @@
198
198
  overflow-wrap: anywhere;
199
199
  }
200
200
 
201
+ /* A comment body is read-only but its text must stay selectable so it can be copied. tldraw's
202
+ container sets `user-select: none` on every descendant (`.tl-container *`) to keep canvas gestures
203
+ from selecting UI text, so the body and its rendered children have to opt back in. */
204
+ .tlui-cmt-text,
205
+ .tlui-cmt-text * {
206
+ -webkit-user-select: text;
207
+ user-select: text;
208
+ }
209
+
201
210
  .tlui-cmt-edited {
202
211
  font-style: italic;
203
212
  }
@@ -311,8 +320,6 @@
311
320
  pointer-events: none;
312
321
  white-space: nowrap;
313
322
  width: max-content;
314
- max-height: none;
315
- overflow: visible;
316
323
  }
317
324
 
318
325
  .tlui-cmt-input {
@@ -352,6 +359,17 @@
352
359
  pointer-events: none;
353
360
  }
354
361
 
362
+ /* iOS Safari zooms the whole page in when a text input with a sub-16px font takes focus, and doesn't
363
+ zoom back out. Raising the font to 16px on touch devices suppresses that without disabling
364
+ pinch-zoom of the canvas (which a `maximum-scale` viewport lock would). Must come after both base
365
+ rules above: a media query adds no specificity, so it only wins the placeholder on source order. */
366
+ @media (pointer: coarse) {
367
+ .tlui-cmt-input,
368
+ .tlui-cmt-input__placeholder {
369
+ font-size: 16px;
370
+ }
371
+ }
372
+
355
373
  /* A bare up-arrow icon button (matching the placement composer): no fill by default, a grey square
356
374
  on hover, grey while there's nothing to send and dark once there is. */
357
375
  .tlui-cmt-send {
@@ -528,12 +546,17 @@
528
546
  font-size: 10px;
529
547
  font-weight: 400;
530
548
  color: var(--tl-color-text-1);
549
+ }
550
+
551
+ /* An inert pill renders as a span (e.g. in a notification row); only the button variant is
552
+ clickable, so only it gets the pointer cursor and hover shade. */
553
+ button.tlui-cmt-reaction {
531
554
  cursor: pointer;
532
555
  }
533
556
 
534
557
  /* Hover deepens the grey — no border to tint now. Mixing toward the text colour is theme-aware:
535
558
  it darkens the fill in light mode and lightens it in dark, tracking the pill's own contrast. */
536
- .tlui-cmt-reaction:hover {
559
+ button.tlui-cmt-reaction:hover {
537
560
  background: var(--tl-color-muted-1);
538
561
  }
539
562
 
@@ -543,14 +566,15 @@
543
566
  background: color-mix(in srgb, var(--tl-color-selected) 28%, var(--tl-color-panel));
544
567
  }
545
568
 
546
- .tlui-cmt-reaction--active:hover {
569
+ button.tlui-cmt-reaction--active:hover {
547
570
  background: color-mix(in srgb, var(--tl-color-selected) 38%, var(--tl-color-panel));
548
571
  }
549
572
 
550
- /* the emoji sits at the same 10px as the count beside it */
573
+ /* The emoji renders larger than the 10px count, but its pinned line-height keeps the pill the
574
+ count's height — the glyph overflows the line box rather than growing it. */
551
575
  .tlui-cmt-reaction__emoji {
552
- font-size: 10px;
553
- line-height: 1;
576
+ font-size: 13px;
577
+ line-height: 10px;
554
578
  }
555
579
 
556
580
  .tlui-cmt-reaction__count {
@@ -653,7 +677,8 @@
653
677
  --tlui-cmt-marker-transition: 0.08s ease;
654
678
  --tlui-cmt-thread-padding: 12px;
655
679
  --tlui-cmt-thread-gap: 0px;
656
- --tlui-cmt-thread-action-size: 26px;
680
+ /* Hit-area width of one .tlui-cmt-thread__action button (drawn as a 32px square inset 4px). */
681
+ --tlui-cmt-thread-action-size: 40px;
657
682
  /* A floating pill's edge — its hairline ring is the only thing separating it from the panel it
658
683
  overlaps, so the ring is a theme token rather than a literal black: a near-black hairline
659
684
  vanishes on a dark panel, where the divider token lightens instead. The drop below it stays
@@ -716,47 +741,28 @@
716
741
  space-between alone would leave them at the left). */
717
742
  margin-left: auto;
718
743
  }
719
- /* Follows tldraw's toolbar buttons (.tlui-button), used by both the header and card actions: the
720
- button is the 40px hit target that tiles with its neighbours; its 32px ::after is the visual
721
- square carrying the hover wash, so the hit area (not the ::after) is what's clickable and it
722
- never reaches past its row. */
723
- .tlui-cmt-thread__action {
724
- position: relative;
725
- display: flex;
726
- align-items: center;
727
- justify-content: center;
744
+ /* These are TldrawUiButtons (type="icon"), so the 40px box, the 32px ::after square carrying the
745
+ hover wash, and the hover z-index flip all come from .tlui-button — the hit area (not the
746
+ ::after) is what's clickable, and it never reaches past its row. Only the bits that differ from
747
+ a toolbar button are set here, at .tlui-button's specificity + 1 so stylesheet order can't
748
+ decide the winner. */
749
+ .tlui-button.tlui-cmt-thread__action {
728
750
  width: 40px;
729
- height: 40px;
730
751
  padding: 0;
731
- border: none;
732
752
  border-radius: 6px;
733
- background: transparent;
734
753
  color: var(--tl-color-text-3);
735
754
  font-size: 14px;
736
755
  line-height: 1;
737
- cursor: pointer;
738
756
  }
739
757
  /* Overlap each button 4px into the previous so the 32px visual squares sit 4px apart, not 8px.
740
758
  Left-only, so the last button's hit area still stops at its row's right edge. */
741
759
  .tlui-cmt-thread__action + .tlui-cmt-thread__action {
742
760
  margin-left: -4px;
743
761
  }
744
- .tlui-cmt-thread__action::after {
745
- content: '';
746
- position: absolute;
747
- inset: 4px;
748
- border-radius: var(--tl-radius-2);
749
- }
750
- .tlui-cmt-thread__action:hover {
762
+ .tlui-button.tlui-cmt-thread__action:hover {
751
763
  color: var(--tl-color-text-1);
752
- /* Raise the hovered button above its overlapping neighbours so its 40px hit area wins the
753
- overlap zone — the same z-index flip tldraw's own toolbar buttons use. */
754
- z-index: 1;
755
- }
756
- .tlui-cmt-thread__action:hover::after {
757
- background: var(--tl-color-muted-2);
758
764
  }
759
- .tlui-cmt-thread__action--danger:hover {
765
+ .tlui-button.tlui-cmt-thread__action--danger:hover {
760
766
  color: var(--tl-color-danger);
761
767
  }
762
768
  .tlui-cmt-thread__resolved {
@@ -839,7 +845,7 @@
839
845
  .tlui-cmt-canvas-preview--thread .tlui-cmt-card {
840
846
  width: 100%;
841
847
  gap: 0;
842
- padding: 0 12px;
848
+ padding: 0 var(--tlui-cmt-thread-padding);
843
849
  background: transparent;
844
850
  border: none;
845
851
  }
@@ -868,14 +874,17 @@
868
874
  .tlui-cmt-stack-list .tlui-cmt-card .tlui-cmt-head {
869
875
  min-height: 40px;
870
876
  }
871
- /* Only the opened thread's comments actually carry the pills, so only they reserve room for them.
872
- Derived from the action size so it can't drift: n buttons + (n−1) 2px gaps + the pill's 2px
873
- padding either side + its 2px right inset. One button (react) on others' comments. */
874
- .tlui-cmt-thread .tlui-cmt-card .tlui-cmt-head {
875
- padding-right: calc(var(--tlui-cmt-thread-action-size) + 6px);
877
+ /* Reserve head room only for pills that actually rendered (one child / two children) — pill count
878
+ is a permissions question (canModifyComment), not ownership, and empty slots (read-only viewers)
879
+ keep the full row. Sized from the 40px hit areas (4px overlap), minus the card padding the
880
+ right:0 pills sit over; text stops 4px shy of the visible square. */
881
+ .tlui-cmt-thread .tlui-cmt-card:has(.tlui-cmt-card__actions > *) .tlui-cmt-head {
882
+ padding-right: calc(var(--tlui-cmt-thread-action-size) - var(--tlui-cmt-thread-padding));
876
883
  }
877
- .tlui-cmt-thread .tlui-cmt-card--you .tlui-cmt-head {
878
- padding-right: calc(3 * var(--tlui-cmt-thread-action-size) + 10px);
884
+ .tlui-cmt-thread .tlui-cmt-card:has(.tlui-cmt-card__actions > * + *) .tlui-cmt-head {
885
+ padding-right: calc(
886
+ 2 * var(--tlui-cmt-thread-action-size) - 4px - var(--tlui-cmt-thread-padding)
887
+ );
879
888
  }
880
889
 
881
890
  /* comments list — thread summaries, one per row (used by the canvas sidebar) */
@@ -891,7 +900,7 @@
891
900
  align-items: center;
892
901
  justify-content: space-between;
893
902
  gap: 8px;
894
- padding: 6px 6px 6px 14px;
903
+ padding: 2px 2px 2px 14px;
895
904
  border-bottom: 1px solid var(--tl-color-divider);
896
905
  }
897
906
  .tlui-cmt-list__header-title {
@@ -900,43 +909,28 @@
900
909
  color: var(--tl-color-text-1);
901
910
  }
902
911
 
903
- /* a small square icon button in the sidebar header (filter funnel, overflow …) */
904
- .tlui-cmt-header-btn {
905
- position: relative;
906
- display: flex;
907
- align-items: center;
908
- justify-content: center;
909
- width: 26px;
910
- height: 26px;
912
+ /* An icon button in the sidebar header (filter funnel, overflow …). Sized like the thread actions:
913
+ a TldrawUiButton (type="icon") left at its native 40px box, with .tlui-button's 32px ::after
914
+ square carrying the hover wash. Only the bits that differ are set here, at .tlui-button's
915
+ specificity + 1 so stylesheet order can't decide the winner. */
916
+ .tlui-button.tlui-cmt-header-btn {
917
+ width: 40px;
911
918
  padding: 0;
912
- border: none;
913
919
  border-radius: 6px;
914
- background: transparent;
915
920
  color: var(--tl-color-text-2);
916
- cursor: pointer;
917
- }
918
- /* Same hit-target expansion as the thread actions, tiled the same way — this row's gap is 2px too
919
- (see `.tlui-cmt-list__header-actions`). */
920
- .tlui-cmt-header-btn::after {
921
- content: '';
922
- position: absolute;
923
- inset: -6px -1px;
924
- }
925
- .tlui-cmt-header-btn:first-child::after {
926
- left: -6px;
927
921
  }
928
- .tlui-cmt-header-btn:last-child::after {
929
- right: -6px;
922
+ /* Overlap each button 4px into the previous so the 32px visual squares sit 4px apart, not 8px —
923
+ the same tiling the thread actions use. */
924
+ .tlui-cmt-header-btn + .tlui-cmt-header-btn {
925
+ margin-left: -4px;
930
926
  }
931
- .tlui-cmt-header-btn:hover,
932
- .tlui-cmt-header-btn[data-state='open'] {
933
- background: var(--tl-color-muted-2);
927
+ .tlui-button.tlui-cmt-header-btn:hover,
928
+ .tlui-button.tlui-cmt-header-btn[data-state='open'] {
934
929
  color: var(--tl-color-text-1);
935
930
  }
936
931
  .tlui-cmt-list__header-actions {
937
932
  display: flex;
938
933
  align-items: center;
939
- gap: 2px;
940
934
  }
941
935
 
942
936
  /* The commenting dropdowns' surface — a little air between the items and the menu edge. */
@@ -992,6 +986,7 @@
992
986
  font-size: 12px;
993
987
  }
994
988
  .tlui-cmt-list__item {
989
+ position: relative;
995
990
  display: flex;
996
991
  gap: 10px;
997
992
  width: 100%;
@@ -1006,18 +1001,27 @@
1006
1001
  color: inherit;
1007
1002
  text-decoration: none;
1008
1003
  }
1009
- .tlui-cmt-list__item:hover {
1004
+ /* The highlight is an inset, rounded wash like tldraw's buttons and menu items — not an
1005
+ edge-to-edge band — so a comment row lights up the same way every other interactive row does. */
1006
+ .tlui-cmt-list__item::after {
1007
+ content: '';
1008
+ position: absolute;
1009
+ inset: 4px;
1010
+ border-radius: var(--tl-radius-2);
1011
+ pointer-events: none;
1012
+ }
1013
+ .tlui-cmt-list__item:hover::after {
1010
1014
  background: var(--tl-color-muted-2);
1011
1015
  }
1012
1016
  /* Selected sits a step above hover so the open thread's row stays distinguishable while
1013
1017
  pointing at other rows — but only a step: the muted-1 token (10%) reads too heavy here.
1014
1018
  These rows sit on the opaque sidebar panel, so a translucent tint composes safely. */
1015
- .tlui-cmt-list__item--selected,
1016
- .tlui-cmt-list__item--selected:hover {
1019
+ .tlui-cmt-list__item--selected::after,
1020
+ .tlui-cmt-list__item--selected:hover::after {
1017
1021
  background: hsl(0, 0%, 0%, 5%);
1018
1022
  }
1019
- .tl-theme__dark .tlui-cmt-list__item--selected,
1020
- .tl-theme__dark .tlui-cmt-list__item--selected:hover {
1023
+ .tl-theme__dark .tlui-cmt-list__item--selected::after,
1024
+ .tl-theme__dark .tlui-cmt-list__item--selected:hover::after {
1021
1025
  background: hsl(0, 0%, 100%, 5%);
1022
1026
  }
1023
1027
  /* resolved rows mute their content but keep the "Resolved" marker legible */
@@ -1076,10 +1080,11 @@
1076
1080
  color: var(--tl-color-text-3);
1077
1081
  }
1078
1082
 
1079
- /* The comments layer is portaled into the editor container. Pins live in the canvas-in-front layer
1080
- (beneath the UI panels at z-index 300), so the toolbar and style panel draw over them; the open
1081
- thread's popover portals up to the menus layer separately (`.tlui-cmt-canvas-popover`) so it isn't
1082
- clipped. Click-through except on its own children. */
1083
+ /* The comments layer renders through `EditorPortal`, so its pieces can pick their own layer rather
1084
+ than the one the component is mounted in. Pins live in the canvas-in-front layer (beneath the UI
1085
+ panels at z-index 300), so the toolbar and style panel draw over them; the open thread's popover
1086
+ goes to the menus layer instead (`.tlui-cmt-canvas-popover`) so it isn't clipped. Click-through
1087
+ except on its own children. */
1083
1088
  .tlui-cmt-canvas-layer {
1084
1089
  position: absolute;
1085
1090
  inset: 0;
@@ -1423,13 +1428,6 @@
1423
1428
  background: color-mix(in srgb, var(--tl-color-selected) 10%, transparent);
1424
1429
  }
1425
1430
 
1426
- /* A movable region body (the 'body'/'both' move modes): draggable to translate the whole region.
1427
- Interactive, so it captures the interior while shown — the tradeoff of dragging the body. */
1428
- .tlui-cmt-canvas-region--movable {
1429
- pointer-events: auto;
1430
- cursor: move;
1431
- }
1432
-
1433
1431
  /* Corner resize handles on a region box (three corners; the pin corner is the move handle). */
1434
1432
  .tlui-cmt-canvas-region-handle {
1435
1433
  position: absolute;
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
- "5.3.0-next.d7d8ced023d5",
22
+ "5.3.0-next.dec36c5c2930",
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
- "5.3.0-next.d7d8ced023d5",
5
+ "5.3.0-next.dec36c5c2930",
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": "5.3.0-next.d7d8ced023d5",
4
+ "version": "5.3.0-next.dec36c5c2930",
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.3.0-next.d7d8ced023d5",
55
- "@tldraw/utils": "5.3.0-next.d7d8ced023d5"
54
+ "@tldraw/commenting": "5.3.0-next.dec36c5c2930",
55
+ "@tldraw/utils": "5.3.0-next.dec36c5c2930"
56
56
  },
57
57
  "module": "dist-esm/index.mjs",
58
58
  "source": "src/index.ts",