@tldraw/commenting 0.0.0-bootstrap → 5.3.0-canary.04044ed9e96d
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 +0 -2
- package/commenting.css +1152 -350
- package/dist-cjs/canvas/anchor-lifecycle.js +148 -0
- package/dist-cjs/canvas/anchor-lifecycle.js.map +7 -0
- package/dist-cjs/{ui/avatar.js → canvas/canvas-events.js} +14 -22
- package/dist-cjs/canvas/canvas-events.js.map +7 -0
- package/dist-cjs/canvas/cluster-badge.js +121 -0
- package/dist-cjs/canvas/cluster-badge.js.map +7 -0
- package/dist-cjs/canvas/cluster-fade.js +85 -0
- package/dist-cjs/canvas/cluster-fade.js.map +7 -0
- package/dist-cjs/canvas/cluster-input.js +53 -3
- package/dist-cjs/canvas/cluster-input.js.map +2 -2
- package/dist-cjs/canvas/cluster-model.js +252 -0
- package/dist-cjs/canvas/cluster-model.js.map +7 -0
- package/dist-cjs/canvas/comment-body.js +1 -1
- package/dist-cjs/canvas/comment-body.js.map +2 -2
- package/dist-cjs/canvas/comment-drafts.js +54 -0
- package/dist-cjs/canvas/comment-drafts.js.map +7 -0
- package/dist-cjs/canvas/comment-mutations.js +152 -0
- package/dist-cjs/canvas/comment-mutations.js.map +7 -0
- package/dist-cjs/canvas/comment-reactions.js +160 -0
- package/dist-cjs/canvas/comment-reactions.js.map +7 -0
- package/dist-cjs/canvas/comment-render.js +9 -6
- package/dist-cjs/canvas/comment-render.js.map +2 -2
- package/dist-cjs/canvas/comment-store.js +19 -9
- package/dist-cjs/canvas/comment-store.js.map +2 -2
- package/dist-cjs/canvas/comment-tool.js +63 -14
- package/dist-cjs/canvas/comment-tool.js.map +2 -2
- package/dist-cjs/canvas/comments-filter-menu.js +17 -37
- package/dist-cjs/canvas/comments-filter-menu.js.map +2 -2
- package/dist-cjs/canvas/comments-overflow-menu.js +25 -22
- package/dist-cjs/canvas/comments-overflow-menu.js.map +2 -2
- package/dist-cjs/canvas/comments-overlay.js +151 -989
- package/dist-cjs/canvas/comments-overlay.js.map +3 -3
- package/dist-cjs/canvas/comments-sidebar.js +49 -41
- package/dist-cjs/canvas/comments-sidebar.js.map +2 -2
- package/dist-cjs/canvas/comments-visibility-toggle.js +45 -0
- package/dist-cjs/canvas/comments-visibility-toggle.js.map +7 -0
- package/dist-cjs/canvas/context.js +17 -0
- package/dist-cjs/canvas/context.js.map +7 -0
- package/dist-cjs/canvas/hooks.js +28 -3
- package/dist-cjs/canvas/hooks.js.map +2 -2
- package/dist-cjs/canvas/license.js.map +1 -1
- package/dist-cjs/canvas/mobile-placement.js +91 -0
- package/dist-cjs/canvas/mobile-placement.js.map +7 -0
- package/dist-cjs/canvas/options.js +57 -2
- package/dist-cjs/canvas/options.js.map +2 -2
- package/dist-cjs/canvas/pending-composer.js +134 -0
- package/dist-cjs/canvas/pending-composer.js.map +7 -0
- package/dist-cjs/canvas/pin-stacking.js +81 -0
- package/dist-cjs/canvas/pin-stacking.js.map +7 -0
- package/dist-cjs/canvas/region-box.js +113 -0
- package/dist-cjs/canvas/region-box.js.map +7 -0
- package/dist-cjs/canvas/sidebar-filters.js +2 -2
- package/dist-cjs/canvas/sidebar-filters.js.map +2 -2
- package/dist-cjs/canvas/state.js +28 -14
- package/dist-cjs/canvas/state.js.map +2 -2
- package/dist-cjs/canvas/thread-pin.js +304 -0
- package/dist-cjs/canvas/thread-pin.js.map +7 -0
- package/dist-cjs/canvas/thread-preview.js +177 -0
- package/dist-cjs/canvas/thread-preview.js.map +7 -0
- package/dist-cjs/canvas/thread-stack.js +199 -0
- package/dist-cjs/canvas/thread-stack.js.map +7 -0
- package/dist-cjs/canvas/thread-state.js +82 -21
- package/dist-cjs/canvas/thread-state.js.map +2 -2
- package/dist-cjs/canvas/thread-view.js +450 -0
- package/dist-cjs/canvas/thread-view.js.map +7 -0
- package/dist-cjs/clustering/computeClusterTable.js +6 -6
- package/dist-cjs/clustering/computeClusterTable.js.map +2 -2
- package/dist-cjs/clustering/replay.js +89 -22
- package/dist-cjs/clustering/replay.js.map +3 -3
- package/dist-cjs/clustering/runtime.js +126 -7
- package/dist-cjs/clustering/runtime.js.map +2 -2
- package/dist-cjs/clustering/types.js.map +1 -1
- package/dist-cjs/index.d.ts +904 -353
- package/dist-cjs/index.js +52 -28
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/ui/byline.js +10 -6
- package/dist-cjs/ui/byline.js.map +2 -2
- package/dist-cjs/ui/comment-card.js +15 -8
- package/dist-cjs/ui/comment-card.js.map +2 -2
- package/dist-cjs/ui/comment-composer.js +124 -39
- package/dist-cjs/ui/comment-composer.js.map +2 -2
- package/dist-cjs/ui/comment-pin.js +11 -2
- package/dist-cjs/ui/comment-pin.js.map +2 -2
- package/dist-cjs/ui/comment-thread.js +9 -7
- package/dist-cjs/ui/comment-thread.js.map +2 -2
- package/dist-cjs/ui/comments-list.js +39 -40
- package/dist-cjs/ui/comments-list.js.map +2 -2
- package/dist-cjs/ui/count-badge.js +3 -2
- package/dist-cjs/ui/count-badge.js.map +2 -2
- package/dist-cjs/ui/emoji-picker.js +54 -0
- package/dist-cjs/ui/emoji-picker.js.map +7 -0
- package/dist-cjs/ui/empty-state.js +3 -3
- package/dist-cjs/ui/empty-state.js.map +2 -2
- package/dist-cjs/ui/format-time.js +16 -1
- package/dist-cjs/ui/format-time.js.map +2 -2
- package/dist-cjs/ui/icons.js +115 -0
- package/dist-cjs/ui/icons.js.map +7 -0
- package/dist-cjs/ui/reaction-picker.js +71 -0
- package/dist-cjs/ui/reaction-picker.js.map +7 -0
- package/dist-cjs/ui/reaction.js +58 -6
- package/dist-cjs/ui/reaction.js.map +2 -2
- package/dist-cjs/ui/reactions.js +20 -7
- package/dist-cjs/ui/reactions.js.map +2 -2
- package/dist-cjs/ui/{mention.js → reply-count.js} +9 -11
- package/dist-cjs/ui/reply-count.js.map +7 -0
- package/dist-cjs/ui/send-button.js +13 -1
- package/dist-cjs/ui/send-button.js.map +2 -2
- package/dist-cjs/ui/{comment-text.js → visual-viewport.js} +12 -9
- package/dist-cjs/ui/visual-viewport.js.map +7 -0
- package/dist-esm/canvas/anchor-lifecycle.mjs +128 -0
- package/dist-esm/canvas/anchor-lifecycle.mjs.map +7 -0
- package/dist-esm/canvas/canvas-events.mjs +15 -0
- package/dist-esm/canvas/canvas-events.mjs.map +7 -0
- package/dist-esm/canvas/cluster-badge.mjs +106 -0
- package/dist-esm/canvas/cluster-badge.mjs.map +7 -0
- package/dist-esm/canvas/cluster-fade.mjs +65 -0
- package/dist-esm/canvas/cluster-fade.mjs.map +7 -0
- package/dist-esm/canvas/cluster-input.mjs +54 -4
- package/dist-esm/canvas/cluster-input.mjs.map +2 -2
- package/dist-esm/canvas/cluster-model.mjs +236 -0
- package/dist-esm/canvas/cluster-model.mjs.map +7 -0
- package/dist-esm/canvas/comment-body.mjs +1 -1
- package/dist-esm/canvas/comment-body.mjs.map +2 -2
- package/dist-esm/canvas/comment-drafts.mjs +34 -0
- package/dist-esm/canvas/comment-drafts.mjs.map +7 -0
- package/dist-esm/canvas/comment-mutations.mjs +132 -0
- package/dist-esm/canvas/comment-mutations.mjs.map +7 -0
- package/dist-esm/canvas/comment-reactions.mjs +145 -0
- package/dist-esm/canvas/comment-reactions.mjs.map +7 -0
- package/dist-esm/canvas/comment-render.mjs +10 -7
- package/dist-esm/canvas/comment-render.mjs.map +2 -2
- package/dist-esm/canvas/comment-store.mjs +19 -9
- package/dist-esm/canvas/comment-store.mjs.map +2 -2
- package/dist-esm/canvas/comment-tool.mjs +66 -17
- package/dist-esm/canvas/comment-tool.mjs.map +2 -2
- package/dist-esm/canvas/comments-filter-menu.mjs +17 -36
- package/dist-esm/canvas/comments-filter-menu.mjs.map +2 -2
- package/dist-esm/canvas/comments-overflow-menu.mjs +27 -22
- package/dist-esm/canvas/comments-overflow-menu.mjs.map +2 -2
- package/dist-esm/canvas/comments-overlay.mjs +157 -1010
- package/dist-esm/canvas/comments-overlay.mjs.map +3 -3
- package/dist-esm/canvas/comments-sidebar.mjs +53 -46
- package/dist-esm/canvas/comments-sidebar.mjs.map +2 -2
- package/dist-esm/canvas/comments-visibility-toggle.mjs +25 -0
- package/dist-esm/canvas/comments-visibility-toggle.mjs.map +7 -0
- package/dist-esm/canvas/context.mjs +1 -0
- package/dist-esm/canvas/context.mjs.map +7 -0
- package/dist-esm/canvas/hooks.mjs +35 -5
- package/dist-esm/canvas/hooks.mjs.map +2 -2
- package/dist-esm/canvas/license.mjs.map +1 -1
- package/dist-esm/canvas/mobile-placement.mjs +71 -0
- package/dist-esm/canvas/mobile-placement.mjs.map +7 -0
- package/dist-esm/canvas/options.mjs +59 -3
- package/dist-esm/canvas/options.mjs.map +2 -2
- package/dist-esm/canvas/pending-composer.mjs +126 -0
- package/dist-esm/canvas/pending-composer.mjs.map +7 -0
- package/dist-esm/canvas/pin-stacking.mjs +61 -0
- package/dist-esm/canvas/pin-stacking.mjs.map +7 -0
- package/dist-esm/canvas/region-box.mjs +93 -0
- package/dist-esm/canvas/region-box.mjs.map +7 -0
- package/dist-esm/canvas/sidebar-filters.mjs +2 -2
- package/dist-esm/canvas/sidebar-filters.mjs.map +2 -2
- package/dist-esm/canvas/state.mjs +29 -19
- package/dist-esm/canvas/state.mjs.map +2 -2
- package/dist-esm/canvas/thread-pin.mjs +310 -0
- package/dist-esm/canvas/thread-pin.mjs.map +7 -0
- package/dist-esm/canvas/thread-preview.mjs +163 -0
- package/dist-esm/canvas/thread-preview.mjs.map +7 -0
- package/dist-esm/canvas/thread-stack.mjs +189 -0
- package/dist-esm/canvas/thread-stack.mjs.map +7 -0
- package/dist-esm/canvas/thread-state.mjs +86 -22
- package/dist-esm/canvas/thread-state.mjs.map +2 -2
- package/dist-esm/canvas/thread-view.mjs +461 -0
- package/dist-esm/canvas/thread-view.mjs.map +7 -0
- package/dist-esm/clustering/computeClusterTable.mjs +6 -6
- package/dist-esm/clustering/computeClusterTable.mjs.map +2 -2
- package/dist-esm/clustering/replay.mjs +89 -22
- package/dist-esm/clustering/replay.mjs.map +3 -3
- package/dist-esm/clustering/runtime.mjs +126 -7
- package/dist-esm/clustering/runtime.mjs.map +2 -2
- package/dist-esm/index.d.mts +904 -353
- package/dist-esm/index.mjs +102 -43
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/ui/byline.mjs +11 -7
- package/dist-esm/ui/byline.mjs.map +2 -2
- package/dist-esm/ui/comment-card.mjs +15 -8
- package/dist-esm/ui/comment-card.mjs.map +2 -2
- package/dist-esm/ui/comment-composer.mjs +135 -39
- package/dist-esm/ui/comment-composer.mjs.map +2 -2
- package/dist-esm/ui/comment-pin.mjs +11 -2
- package/dist-esm/ui/comment-pin.mjs.map +2 -2
- package/dist-esm/ui/comment-thread.mjs +9 -7
- package/dist-esm/ui/comment-thread.mjs.map +2 -2
- package/dist-esm/ui/comments-list.mjs +51 -50
- package/dist-esm/ui/comments-list.mjs.map +2 -2
- package/dist-esm/ui/count-badge.mjs +3 -2
- package/dist-esm/ui/count-badge.mjs.map +2 -2
- package/dist-esm/ui/emoji-picker.mjs +34 -0
- package/dist-esm/ui/emoji-picker.mjs.map +7 -0
- package/dist-esm/ui/empty-state.mjs +3 -3
- package/dist-esm/ui/empty-state.mjs.map +2 -2
- package/dist-esm/ui/format-time.mjs +16 -1
- package/dist-esm/ui/format-time.mjs.map +2 -2
- package/dist-esm/ui/icons.mjs +95 -0
- package/dist-esm/ui/icons.mjs.map +7 -0
- package/dist-esm/ui/reaction-picker.mjs +59 -0
- package/dist-esm/ui/reaction-picker.mjs.map +7 -0
- package/dist-esm/ui/reaction.mjs +59 -7
- package/dist-esm/ui/reaction.mjs.map +2 -2
- package/dist-esm/ui/reactions.mjs +21 -8
- package/dist-esm/ui/reactions.mjs.map +2 -2
- package/dist-esm/ui/reply-count.mjs +9 -0
- package/dist-esm/ui/reply-count.mjs.map +7 -0
- package/dist-esm/ui/send-button.mjs +13 -1
- package/dist-esm/ui/send-button.mjs.map +2 -2
- package/dist-esm/ui/visual-viewport.mjs +12 -0
- package/dist-esm/ui/visual-viewport.mjs.map +7 -0
- package/package.json +6 -6
- package/src/canvas/anchor-lifecycle.test.ts +290 -0
- package/src/canvas/anchor-lifecycle.ts +191 -0
- package/src/canvas/canvas-events.ts +18 -0
- package/src/canvas/canvas.css +464 -55
- package/src/canvas/cluster-badge.tsx +133 -0
- package/src/canvas/cluster-fade.ts +102 -0
- package/src/canvas/cluster-input.test.ts +178 -36
- package/src/canvas/cluster-input.ts +95 -9
- package/src/canvas/cluster-model.ts +378 -0
- package/src/canvas/comment-body.tsx +1 -1
- package/src/canvas/comment-drafts.test.ts +55 -0
- package/src/canvas/comment-drafts.ts +46 -0
- package/src/canvas/comment-mutations.test.ts +452 -0
- package/src/canvas/comment-mutations.ts +299 -0
- package/src/canvas/comment-reactions.test.ts +154 -0
- package/src/canvas/comment-reactions.tsx +246 -0
- package/src/canvas/comment-render.test.ts +1 -1
- package/src/canvas/comment-render.ts +17 -13
- package/src/canvas/comment-store.ts +68 -33
- package/src/canvas/comment-tool.test.ts +162 -0
- package/src/canvas/comment-tool.tsx +103 -25
- package/src/canvas/comments-filter-menu.tsx +20 -36
- package/src/canvas/comments-overflow-menu.tsx +17 -19
- package/src/canvas/comments-overlay.tsx +252 -1369
- package/src/canvas/comments-sidebar.test.ts +45 -0
- package/src/canvas/comments-sidebar.tsx +112 -73
- package/src/canvas/comments-visibility-toggle.tsx +25 -0
- package/src/canvas/context.ts +48 -0
- package/src/canvas/hooks.test.ts +94 -0
- package/src/canvas/hooks.ts +66 -11
- package/src/canvas/license.ts +1 -1
- package/src/canvas/mobile-placement.ts +115 -0
- package/src/canvas/options.test.ts +176 -4
- package/src/canvas/options.ts +276 -18
- package/src/canvas/pending-composer.tsx +157 -0
- package/src/canvas/pin-stacking.test.ts +224 -0
- package/src/canvas/pin-stacking.ts +103 -0
- package/src/canvas/region-box.tsx +124 -0
- package/src/canvas/sidebar-filters.ts +4 -3
- package/src/canvas/state.ts +88 -39
- package/src/canvas/thread-pin.tsx +418 -0
- package/src/canvas/thread-preview.test.ts +91 -0
- package/src/canvas/thread-preview.tsx +294 -0
- package/src/canvas/thread-stack.tsx +242 -0
- package/src/canvas/thread-state.test.ts +260 -0
- package/src/canvas/thread-state.ts +171 -37
- package/src/canvas/thread-view.test.ts +72 -0
- package/src/canvas/thread-view.tsx +614 -0
- package/src/clustering/computeClusterTable.test.ts +24 -23
- package/src/clustering/computeClusterTable.ts +17 -8
- package/src/clustering/replay.test.ts +0 -7
- package/src/clustering/replay.ts +131 -32
- package/src/clustering/runtime.test.ts +267 -13
- package/src/clustering/runtime.ts +176 -19
- package/src/clustering/schedule.test.ts +0 -6
- package/src/clustering/screen-offsets.test.ts +171 -0
- package/src/clustering/types.ts +19 -9
- package/src/index.ts +91 -42
- package/src/ui/byline.tsx +21 -9
- package/src/ui/comment-card.tsx +20 -10
- package/src/ui/comment-composer.tsx +178 -56
- package/src/ui/comment-pin.tsx +13 -2
- package/src/ui/comment-thread.tsx +13 -6
- package/src/ui/comments-list.test.ts +31 -0
- package/src/ui/comments-list.tsx +82 -47
- package/src/ui/comments.css +577 -294
- package/src/ui/count-badge.tsx +9 -2
- package/src/ui/emoji-picker.test.ts +25 -0
- package/src/ui/emoji-picker.tsx +76 -0
- package/src/ui/empty-state.tsx +3 -3
- package/src/ui/format-time.test.ts +69 -0
- package/src/ui/format-time.ts +27 -2
- package/src/ui/icons.tsx +116 -0
- package/src/ui/reaction-picker.tsx +102 -0
- package/src/ui/reaction.tsx +125 -6
- package/src/ui/reactions.tsx +69 -10
- package/src/ui/reply-count.ts +16 -0
- package/src/ui/send-button.tsx +13 -3
- package/src/ui/visual-viewport.test.ts +36 -0
- package/src/ui/visual-viewport.ts +27 -0
- package/dist-cjs/canvas/region-options.js +0 -49
- package/dist-cjs/canvas/region-options.js.map +0 -7
- package/dist-cjs/ui/avatar.js.map +0 -7
- package/dist-cjs/ui/comment-mention.js +0 -42
- package/dist-cjs/ui/comment-mention.js.map +0 -7
- package/dist-cjs/ui/comment-text.js.map +0 -7
- package/dist-cjs/ui/mention-list.js +0 -70
- package/dist-cjs/ui/mention-list.js.map +0 -7
- package/dist-cjs/ui/mention-suggestion.js +0 -206
- package/dist-cjs/ui/mention-suggestion.js.map +0 -7
- package/dist-cjs/ui/mention.js.map +0 -7
- package/dist-cjs/ui/render-markdown.js +0 -63
- package/dist-cjs/ui/render-markdown.js.map +0 -7
- package/dist-esm/canvas/region-options.mjs +0 -29
- package/dist-esm/canvas/region-options.mjs.map +0 -7
- package/dist-esm/ui/avatar.mjs +0 -23
- package/dist-esm/ui/avatar.mjs.map +0 -7
- package/dist-esm/ui/comment-mention.mjs +0 -22
- package/dist-esm/ui/comment-mention.mjs.map +0 -7
- package/dist-esm/ui/comment-text.mjs +0 -9
- package/dist-esm/ui/comment-text.mjs.map +0 -7
- package/dist-esm/ui/mention-list.mjs +0 -50
- package/dist-esm/ui/mention-list.mjs.map +0 -7
- package/dist-esm/ui/mention-suggestion.mjs +0 -186
- package/dist-esm/ui/mention-suggestion.mjs.map +0 -7
- package/dist-esm/ui/mention.mjs +0 -11
- package/dist-esm/ui/mention.mjs.map +0 -7
- package/dist-esm/ui/render-markdown.mjs +0 -45
- package/dist-esm/ui/render-markdown.mjs.map +0 -7
- package/src/canvas/region-options.ts +0 -57
- package/src/ui/avatar.tsx +0 -31
- package/src/ui/comment-mention.ts +0 -47
- package/src/ui/comment-text.tsx +0 -12
- package/src/ui/mention-list.tsx +0 -106
- package/src/ui/mention-suggestion.test.ts +0 -18
- package/src/ui/mention-suggestion.tsx +0 -285
- package/src/ui/mention.tsx +0 -9
- package/src/ui/render-markdown.tsx +0 -72
package/src/ui/comments.css
CHANGED
|
@@ -1,84 +1,114 @@
|
|
|
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
|
-
|
|
7
|
-
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
gap: 8px;
|
|
8
|
+
padding: 8px;
|
|
8
9
|
width: 260px;
|
|
9
10
|
background: var(--tl-color-panel);
|
|
10
11
|
border: 1px solid var(--tl-color-divider);
|
|
11
|
-
border-radius:
|
|
12
|
+
border-radius: var(--tl-radius-3);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/* The avatar lives in the byline row (see Byline), so the body text below indents to line up with
|
|
16
|
+
the name — the avatar's width plus the head's gap. */
|
|
17
|
+
.tlui-cmt-body {
|
|
18
|
+
padding-left: calc(28px + 6px);
|
|
12
19
|
}
|
|
13
20
|
|
|
14
|
-
/* hover-revealed controls (edit…) at the card's top-right */
|
|
15
|
-
.cmt-card__actions {
|
|
21
|
+
/* hover-revealed controls (edit, react…) stacked at the card's top-right */
|
|
22
|
+
.tlui-cmt-card__actions {
|
|
16
23
|
position: absolute;
|
|
17
24
|
top: 6px;
|
|
18
25
|
right: 6px;
|
|
19
26
|
display: flex;
|
|
20
|
-
gap:
|
|
27
|
+
gap: 0;
|
|
21
28
|
opacity: 0;
|
|
22
29
|
}
|
|
23
|
-
.cmt-card:hover .cmt-card__actions,
|
|
24
|
-
.cmt-card:focus-within .cmt-card__actions
|
|
30
|
+
.tlui-cmt-card:hover .tlui-cmt-card__actions,
|
|
31
|
+
.tlui-cmt-card:focus-within .tlui-cmt-card__actions,
|
|
32
|
+
/* an open menu is portaled out of the card, so neither :hover nor :focus-within survives moving
|
|
33
|
+
the pointer into it — keep the controls up while their menu is open */
|
|
34
|
+
.tlui-cmt-card__actions:has([data-state='open']) {
|
|
25
35
|
opacity: 1;
|
|
26
36
|
}
|
|
27
37
|
|
|
28
|
-
.cmt-body {
|
|
38
|
+
.tlui-cmt-body {
|
|
29
39
|
flex: 1;
|
|
30
40
|
min-width: 0;
|
|
31
41
|
}
|
|
32
42
|
|
|
33
|
-
.cmt-head {
|
|
43
|
+
.tlui-cmt-head {
|
|
34
44
|
display: flex;
|
|
35
|
-
align-items:
|
|
45
|
+
align-items: center;
|
|
36
46
|
gap: 6px;
|
|
37
47
|
}
|
|
38
48
|
|
|
39
|
-
.cmt-author {
|
|
40
|
-
font-weight:
|
|
41
|
-
font-size:
|
|
49
|
+
.tlui-cmt-author {
|
|
50
|
+
font-weight: 500;
|
|
51
|
+
font-size: 12px;
|
|
42
52
|
color: var(--tl-color-text-1);
|
|
53
|
+
/* a long name ellipsizes rather than pushing the time out or running under the actions */
|
|
54
|
+
min-width: 0;
|
|
55
|
+
overflow: hidden;
|
|
56
|
+
text-overflow: ellipsis;
|
|
57
|
+
white-space: nowrap;
|
|
43
58
|
}
|
|
44
59
|
|
|
45
|
-
.cmt-time {
|
|
46
|
-
font-size:
|
|
60
|
+
.tlui-cmt-time {
|
|
61
|
+
font-size: 12px;
|
|
47
62
|
color: var(--tl-color-text-3);
|
|
63
|
+
flex-shrink: 0;
|
|
64
|
+
white-space: nowrap;
|
|
48
65
|
}
|
|
49
66
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
67
|
+
/* In the hover preview a long comment truncates with an ellipsis rather than growing the card —
|
|
68
|
+
~7 lines (≈120px at this line height). Preview only. */
|
|
69
|
+
.tlui-cmt-canvas-preview--thread .tlui-cmt-text {
|
|
70
|
+
display: -webkit-box;
|
|
71
|
+
-webkit-box-orient: vertical;
|
|
72
|
+
-webkit-line-clamp: 7;
|
|
73
|
+
line-clamp: 7;
|
|
74
|
+
overflow: hidden;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.tlui-cmt-text {
|
|
78
|
+
margin: 0 0 6px;
|
|
79
|
+
font-size: 12px;
|
|
53
80
|
line-height: 1.4;
|
|
54
81
|
color: var(--tl-color-text-1);
|
|
82
|
+
/* Break long unbroken strings (URLs, keyboard-mashing) so they wrap inside the card instead of
|
|
83
|
+
overflowing it. `anywhere` also lets the flex body shrink to the card width. */
|
|
84
|
+
overflow-wrap: anywhere;
|
|
55
85
|
}
|
|
56
86
|
|
|
57
|
-
.cmt-edited {
|
|
87
|
+
.tlui-cmt-edited {
|
|
58
88
|
font-style: italic;
|
|
59
89
|
}
|
|
60
90
|
|
|
61
91
|
/* rendered rich text inside a comment body — bare tags emitted by the comment renderer
|
|
62
92
|
(paragraphs, lists, code, highlight, links), matching the limited comment extension set. */
|
|
63
|
-
.cmt-text p {
|
|
93
|
+
.tlui-cmt-text p {
|
|
64
94
|
margin: 0;
|
|
65
95
|
}
|
|
66
96
|
|
|
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 {
|
|
97
|
+
.tlui-cmt-text p + p,
|
|
98
|
+
.tlui-cmt-text p + ul,
|
|
99
|
+
.tlui-cmt-text p + ol,
|
|
100
|
+
.tlui-cmt-text ul + p,
|
|
101
|
+
.tlui-cmt-text ol + p {
|
|
72
102
|
margin-top: 6px;
|
|
73
103
|
}
|
|
74
104
|
|
|
75
|
-
.cmt-text ul,
|
|
76
|
-
.cmt-text ol {
|
|
105
|
+
.tlui-cmt-text ul,
|
|
106
|
+
.tlui-cmt-text ol {
|
|
77
107
|
margin: 0;
|
|
78
108
|
padding-left: 18px;
|
|
79
109
|
}
|
|
80
110
|
|
|
81
|
-
.cmt-text code {
|
|
111
|
+
.tlui-cmt-text code {
|
|
82
112
|
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
83
113
|
font-size: 0.92em;
|
|
84
114
|
background: var(--tl-color-muted-2);
|
|
@@ -86,212 +116,272 @@
|
|
|
86
116
|
padding: 0 3px;
|
|
87
117
|
}
|
|
88
118
|
|
|
89
|
-
.cmt-text mark {
|
|
119
|
+
.tlui-cmt-text mark {
|
|
90
120
|
background: color-mix(in srgb, #ffeb3b 60%, transparent);
|
|
91
121
|
color: inherit;
|
|
92
122
|
border-radius: 2px;
|
|
93
123
|
}
|
|
94
124
|
|
|
95
|
-
.cmt-text a {
|
|
125
|
+
.tlui-cmt-text a {
|
|
96
126
|
color: var(--tl-color-selected);
|
|
97
127
|
text-decoration: underline;
|
|
98
128
|
}
|
|
99
129
|
|
|
100
|
-
.
|
|
101
|
-
|
|
102
|
-
height: 28px;
|
|
103
|
-
border-radius: 50%;
|
|
104
|
-
background: var(--tl-color-selected);
|
|
105
|
-
color: #fff;
|
|
106
|
-
display: flex;
|
|
107
|
-
align-items: center;
|
|
108
|
-
justify-content: center;
|
|
109
|
-
font-size: 11px;
|
|
110
|
-
font-weight: 600;
|
|
111
|
-
flex-shrink: 0;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
.cmt-avatar--image {
|
|
115
|
-
object-fit: cover;
|
|
116
|
-
background: none;
|
|
117
|
-
}
|
|
130
|
+
/* Avatar and mention styles live in @tldraw/mentions (src/mention.css) and are bundled into
|
|
131
|
+
commenting.css by copy-css-files.mjs. */
|
|
118
132
|
|
|
119
133
|
/* composer — an avatar beside a rounded-rect field holding the rich-text input and the send button.
|
|
120
134
|
Formatting is applied via markdown and keyboard shortcuts (no toolbar). The avatar aligns to the
|
|
121
135
|
top so it stays put as the field grows to multiple lines. */
|
|
122
|
-
.cmt-composer {
|
|
136
|
+
.tlui-cmt-composer {
|
|
123
137
|
display: flex;
|
|
124
138
|
align-items: flex-start;
|
|
125
139
|
gap: 10px;
|
|
126
140
|
padding: 4px 0 8px 4px;
|
|
127
141
|
}
|
|
128
142
|
|
|
129
|
-
.cmt-composer__field {
|
|
143
|
+
.tlui-cmt-composer__field {
|
|
130
144
|
flex: 1;
|
|
131
145
|
min-width: 0;
|
|
132
146
|
display: flex;
|
|
133
147
|
align-items: center;
|
|
134
148
|
gap: 6px;
|
|
135
|
-
padding: 3px 3px 3px
|
|
136
|
-
background: var(--tl-color-muted-
|
|
149
|
+
padding: 3px 3px 3px 8px;
|
|
150
|
+
background: var(--tl-color-muted-0);
|
|
137
151
|
border: 1px solid var(--tl-color-divider);
|
|
138
|
-
border-radius: var(--tl-radius-
|
|
152
|
+
border-radius: var(--tl-radius-2);
|
|
153
|
+
/* The whole field reads as the text input — clicking its empty area focuses the editor
|
|
154
|
+
(see CommentComposer). The send button restores its own pointer cursor. */
|
|
155
|
+
cursor: text;
|
|
139
156
|
}
|
|
140
157
|
|
|
141
|
-
.cmt-composer__field:focus-within {
|
|
158
|
+
.tlui-cmt-composer__field:focus-within {
|
|
142
159
|
border-color: var(--tl-color-selected);
|
|
160
|
+
background: var(--tl-color-panel);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/* Expanded: the content no longer fits on one line beside the send button, so the input takes
|
|
164
|
+
the full width and the send button drops to its own row, right-aligned. */
|
|
165
|
+
.tlui-cmt-composer__field--expanded {
|
|
166
|
+
flex-wrap: wrap;
|
|
167
|
+
/* No vertical gap between the input and the send-button row it wraps onto. */
|
|
168
|
+
row-gap: 0;
|
|
169
|
+
}
|
|
170
|
+
.tlui-cmt-composer__field--expanded .tlui-cmt-composer__input-wrap {
|
|
171
|
+
flex-basis: 100%;
|
|
172
|
+
/* The field pads 8px left but only 3px right (the send button's inset). With the input
|
|
173
|
+
spanning the full width, give the text the same 8px on the right. */
|
|
174
|
+
padding-right: 5px;
|
|
175
|
+
}
|
|
176
|
+
.tlui-cmt-composer__field--expanded .tlui-cmt-send {
|
|
177
|
+
margin-left: auto;
|
|
143
178
|
}
|
|
144
179
|
|
|
145
180
|
/* the editable area, with the placeholder overlaid while it's empty */
|
|
146
|
-
.cmt-composer__input-wrap {
|
|
181
|
+
.tlui-cmt-composer__input-wrap {
|
|
147
182
|
position: relative;
|
|
148
183
|
flex: 1;
|
|
149
184
|
min-width: 0;
|
|
150
|
-
|
|
185
|
+
/* Frames the input's line height symmetrically so the text sits centred in the field. Paired
|
|
186
|
+
with the input's min-height, which equals its line height (no gap for the text to top-align
|
|
187
|
+
into). Keeps the field's overall height. */
|
|
188
|
+
padding: 4.5px 0;
|
|
151
189
|
}
|
|
152
190
|
|
|
153
|
-
|
|
191
|
+
/* The hidden single-line measuring clone of the editor's content (see CommentComposer). */
|
|
192
|
+
.tlui-cmt-composer__mirror {
|
|
193
|
+
position: absolute;
|
|
194
|
+
top: 0;
|
|
195
|
+
left: 0;
|
|
196
|
+
visibility: hidden;
|
|
197
|
+
pointer-events: none;
|
|
198
|
+
white-space: nowrap;
|
|
199
|
+
width: max-content;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.tlui-cmt-input {
|
|
154
203
|
font: inherit;
|
|
155
|
-
font-size:
|
|
204
|
+
font-size: 12px;
|
|
156
205
|
line-height: 1.4;
|
|
157
206
|
color: var(--tl-color-text-1);
|
|
158
207
|
outline: none;
|
|
159
|
-
min-height:
|
|
160
|
-
max-height: 40vh;
|
|
161
|
-
overflow-y: auto;
|
|
208
|
+
min-height: 17px;
|
|
162
209
|
white-space: pre-wrap;
|
|
163
210
|
word-break: break-word;
|
|
164
211
|
}
|
|
165
212
|
|
|
166
|
-
.cmt-input p {
|
|
213
|
+
.tlui-cmt-input p {
|
|
167
214
|
margin: 0;
|
|
168
215
|
}
|
|
169
216
|
|
|
170
|
-
.cmt-input p + p,
|
|
171
|
-
.cmt-input p + ul,
|
|
172
|
-
.cmt-input p + ol {
|
|
217
|
+
.tlui-cmt-input p + p,
|
|
218
|
+
.tlui-cmt-input p + ul,
|
|
219
|
+
.tlui-cmt-input p + ol {
|
|
173
220
|
margin-top: 4px;
|
|
174
221
|
}
|
|
175
222
|
|
|
176
|
-
.cmt-input ul,
|
|
177
|
-
.cmt-input ol {
|
|
223
|
+
.tlui-cmt-input ul,
|
|
224
|
+
.tlui-cmt-input ol {
|
|
178
225
|
margin: 0;
|
|
179
226
|
padding-left: 18px;
|
|
180
227
|
}
|
|
181
228
|
|
|
182
|
-
.cmt-input__placeholder {
|
|
229
|
+
.tlui-cmt-input__placeholder {
|
|
183
230
|
position: absolute;
|
|
184
|
-
top:
|
|
231
|
+
top: 4.5px;
|
|
185
232
|
left: 0;
|
|
186
|
-
font-size:
|
|
233
|
+
font-size: 12px;
|
|
187
234
|
line-height: 1.4;
|
|
188
235
|
color: var(--tl-color-text-3);
|
|
189
236
|
pointer-events: none;
|
|
190
237
|
}
|
|
191
238
|
|
|
192
|
-
|
|
239
|
+
/* iOS Safari zooms the whole page in when a text input with a sub-16px font takes focus, and doesn't
|
|
240
|
+
zoom back out. Raising the font to 16px on touch devices suppresses that without disabling
|
|
241
|
+
pinch-zoom of the canvas (which a `maximum-scale` viewport lock would). Must come after both base
|
|
242
|
+
rules above: a media query adds no specificity, so it only wins the placeholder on source order. */
|
|
243
|
+
@media (pointer: coarse) {
|
|
244
|
+
.tlui-cmt-input,
|
|
245
|
+
.tlui-cmt-input__placeholder {
|
|
246
|
+
font-size: 16px;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/* A bare up-arrow icon button (matching the placement composer): no fill by default, a grey square
|
|
251
|
+
on hover, grey while there's nothing to send and dark once there is. */
|
|
252
|
+
.tlui-cmt-send {
|
|
253
|
+
flex-shrink: 0;
|
|
254
|
+
display: inline-flex;
|
|
255
|
+
align-items: center;
|
|
256
|
+
justify-content: center;
|
|
257
|
+
width: 28px;
|
|
258
|
+
height: 28px;
|
|
193
259
|
border: 0;
|
|
194
260
|
border-radius: var(--tl-radius-2);
|
|
195
|
-
background:
|
|
196
|
-
color:
|
|
197
|
-
font: inherit;
|
|
198
|
-
font-size: 12px;
|
|
199
|
-
font-weight: 600;
|
|
200
|
-
padding: 6px 12px;
|
|
261
|
+
background: transparent;
|
|
262
|
+
color: var(--tl-color-text-3);
|
|
201
263
|
cursor: pointer;
|
|
202
|
-
align-self:
|
|
264
|
+
align-self: center;
|
|
203
265
|
}
|
|
204
266
|
|
|
205
|
-
.cmt-send:
|
|
206
|
-
|
|
207
|
-
|
|
267
|
+
.tlui-cmt-send:not(:disabled) {
|
|
268
|
+
color: var(--tl-color-text-1);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.tlui-cmt-send:hover:not(:disabled) {
|
|
272
|
+
background: var(--tl-color-muted-2);
|
|
208
273
|
}
|
|
209
274
|
|
|
210
|
-
.cmt-send:active,
|
|
211
|
-
.pseudo-active .cmt-send {
|
|
212
|
-
background:
|
|
275
|
+
.tlui-cmt-send:active:not(:disabled),
|
|
276
|
+
.pseudo-active .tlui-cmt-send:not(:disabled) {
|
|
277
|
+
background: var(--tl-color-muted-1);
|
|
213
278
|
}
|
|
214
279
|
|
|
215
|
-
.cmt-send:focus-visible,
|
|
216
|
-
.pseudo-focus-visible .cmt-send {
|
|
280
|
+
.tlui-cmt-send:focus-visible,
|
|
281
|
+
.pseudo-focus-visible .tlui-cmt-send {
|
|
217
282
|
outline: 2px solid var(--tl-color-selected);
|
|
218
283
|
outline-offset: 2px;
|
|
219
284
|
}
|
|
220
285
|
|
|
221
|
-
.cmt-send:disabled {
|
|
222
|
-
|
|
286
|
+
.tlui-cmt-send:disabled {
|
|
287
|
+
background: transparent;
|
|
288
|
+
color: var(--tl-color-text-3);
|
|
223
289
|
cursor: not-allowed;
|
|
224
290
|
}
|
|
225
291
|
|
|
226
|
-
/* pin
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
292
|
+
/* The shared marker treatment. To the pointer a comment pin and a count badge are the same
|
|
293
|
+
object — a token sitting on the canvas — so they rest and lift identically; everything shared
|
|
294
|
+
lives here so the two can't drift apart. */
|
|
295
|
+
.tlui-cmt-marker {
|
|
296
|
+
box-shadow: var(--tlui-cmt-marker-shadow);
|
|
297
|
+
cursor: pointer;
|
|
298
|
+
transition:
|
|
299
|
+
transform var(--tlui-cmt-marker-transition),
|
|
300
|
+
box-shadow var(--tlui-cmt-marker-transition);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.tlui-cmt-marker:hover {
|
|
304
|
+
transform: scale(var(--tlui-cmt-marker-hover-scale));
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/* The hover shadow is for closed markers only — an open one keeps its selection ring, which this
|
|
308
|
+
box-shadow would otherwise override (the hover selector outranks the --open rule). */
|
|
309
|
+
.tlui-cmt-marker:not(.tlui-cmt-marker--open):hover {
|
|
310
|
+
box-shadow: var(--tlui-cmt-marker-shadow-hover);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/* Count badges don't react to hover — no scale, no shadow lift. Only pins do. */
|
|
314
|
+
.tlui-cmt-count-badge:hover {
|
|
315
|
+
transform: none;
|
|
316
|
+
box-shadow: var(--tlui-cmt-marker-shadow);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/* Pins don't scale on hover — only the shadow lifts. */
|
|
320
|
+
.tlui-cmt-pin:hover {
|
|
321
|
+
transform: none;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/* open: the thread (or a stack's list) is showing — the active marker just keeps its lift shadow,
|
|
325
|
+
no selection ring. */
|
|
326
|
+
.tlui-cmt-marker--open {
|
|
327
|
+
box-shadow: var(--tlui-cmt-marker-shadow);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/* pin — a canvas marker: a white teardrop holding the author's avatar circle, so a thread is
|
|
331
|
+
identifiable at a glance. */
|
|
332
|
+
.tlui-cmt-pin {
|
|
333
|
+
--tlui-cmt-marker-size: var(--tlui-cmt-pin-size);
|
|
334
|
+
width: var(--tlui-cmt-marker-size);
|
|
335
|
+
height: var(--tlui-cmt-marker-size);
|
|
336
|
+
border-radius: 50% 50% 50% 0;
|
|
337
|
+
background: var(--tl-color-panel);
|
|
232
338
|
color: #fff;
|
|
233
339
|
display: flex;
|
|
234
340
|
align-items: center;
|
|
235
341
|
justify-content: center;
|
|
236
342
|
font-size: 14px;
|
|
237
343
|
font-weight: 600;
|
|
238
|
-
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
|
|
239
|
-
cursor: pointer;
|
|
240
|
-
transition:
|
|
241
|
-
transform 0.08s ease,
|
|
242
|
-
box-shadow 0.08s ease;
|
|
243
344
|
}
|
|
244
|
-
|
|
245
|
-
.cmt-pin
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.32);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/* open: the thread is showing — a selection ring marks the active pin */
|
|
252
|
-
.cmt-pin--open {
|
|
253
|
-
box-shadow:
|
|
254
|
-
0 0 0 3px var(--tl-color-panel),
|
|
255
|
-
0 0 0 5px var(--tl-color-selected),
|
|
256
|
-
0 2px 6px rgba(0, 0, 0, 0.25);
|
|
345
|
+
/* The pin holds the author's 22px avatar circle, centred in its 28px face. */
|
|
346
|
+
.tlui-cmt-pin .tlui-cmt-avatar {
|
|
347
|
+
width: 22px;
|
|
348
|
+
height: 22px;
|
|
257
349
|
}
|
|
258
350
|
|
|
259
351
|
/* resolved: a solid, muted grey (the default --tl-color-muted-1 is 10% black, so it goes
|
|
260
352
|
translucent over the canvas). Dark mode gets its own grey — the token's dark value is near-black. */
|
|
261
|
-
.cmt-pin--resolved {
|
|
353
|
+
.tlui-cmt-pin--resolved {
|
|
262
354
|
background: #dfe0e1;
|
|
263
355
|
color: hsl(214, 8%, 42%);
|
|
264
356
|
}
|
|
265
|
-
.tl-theme__dark .cmt-pin--resolved {
|
|
357
|
+
.tl-theme__dark .tlui-cmt-pin--resolved {
|
|
266
358
|
background: hsl(240, 5%, 30%);
|
|
267
359
|
color: hsl(0, 0%, 72%);
|
|
268
360
|
}
|
|
269
361
|
|
|
270
|
-
/* count badge */
|
|
271
|
-
.cmt-count-badge {
|
|
272
|
-
width:
|
|
273
|
-
height:
|
|
362
|
+
/* count badge — the same marker as a pin. */
|
|
363
|
+
.tlui-cmt-count-badge {
|
|
364
|
+
width: var(--tlui-cmt-marker-size);
|
|
365
|
+
height: var(--tlui-cmt-marker-size);
|
|
274
366
|
border-radius: 50%;
|
|
275
367
|
display: flex;
|
|
276
368
|
align-items: center;
|
|
277
369
|
justify-content: center;
|
|
278
370
|
background: var(--tl-color-text-1);
|
|
279
371
|
color: var(--tl-color-panel);
|
|
280
|
-
font-size:
|
|
372
|
+
font-size: 12px;
|
|
281
373
|
font-weight: 700;
|
|
282
|
-
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
|
|
283
374
|
user-select: none;
|
|
284
375
|
}
|
|
285
376
|
|
|
286
377
|
/* thread */
|
|
287
|
-
.cmt-thread {
|
|
378
|
+
.tlui-cmt-thread {
|
|
288
379
|
display: flex;
|
|
289
380
|
flex-direction: column;
|
|
290
|
-
gap: 8px;
|
|
291
381
|
width: 300px;
|
|
292
382
|
}
|
|
293
383
|
|
|
294
|
-
.cmt-thread__head {
|
|
384
|
+
.tlui-cmt-thread__head {
|
|
295
385
|
display: flex;
|
|
296
386
|
align-items: center;
|
|
297
387
|
gap: 8px;
|
|
@@ -302,7 +392,7 @@
|
|
|
302
392
|
letter-spacing: 0.04em;
|
|
303
393
|
}
|
|
304
394
|
|
|
305
|
-
.cmt-badge {
|
|
395
|
+
.tlui-cmt-badge {
|
|
306
396
|
font-size: 10px;
|
|
307
397
|
font-weight: 600;
|
|
308
398
|
text-transform: none;
|
|
@@ -314,134 +404,111 @@
|
|
|
314
404
|
}
|
|
315
405
|
|
|
316
406
|
/* reactions */
|
|
317
|
-
.cmt-reactions {
|
|
407
|
+
.tlui-cmt-reactions {
|
|
318
408
|
display: flex;
|
|
319
|
-
|
|
409
|
+
flex-wrap: wrap;
|
|
410
|
+
gap: 4px;
|
|
411
|
+
margin-top: 6px;
|
|
320
412
|
}
|
|
321
413
|
|
|
322
|
-
.cmt-reaction {
|
|
414
|
+
.tlui-cmt-reaction {
|
|
323
415
|
display: inline-flex;
|
|
324
416
|
align-items: center;
|
|
325
|
-
gap:
|
|
326
|
-
padding:
|
|
327
|
-
border
|
|
328
|
-
border:
|
|
329
|
-
background: var(--tl-color-
|
|
417
|
+
gap: 4px;
|
|
418
|
+
padding: 2px 6px;
|
|
419
|
+
border: none;
|
|
420
|
+
border-radius: var(--tl-radius-1);
|
|
421
|
+
background: var(--tl-color-muted-2);
|
|
330
422
|
font: inherit;
|
|
331
|
-
font-size:
|
|
423
|
+
font-size: 10px;
|
|
424
|
+
font-weight: 400;
|
|
332
425
|
color: var(--tl-color-text-1);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/* An inert pill renders as a span (e.g. in a notification row); only the button variant is
|
|
429
|
+
clickable, so only it gets the pointer cursor and hover shade. */
|
|
430
|
+
button.tlui-cmt-reaction {
|
|
333
431
|
cursor: pointer;
|
|
334
432
|
}
|
|
335
433
|
|
|
336
|
-
.
|
|
337
|
-
|
|
338
|
-
|
|
434
|
+
/* Hover deepens the grey — no border to tint now. Mixing toward the text colour is theme-aware:
|
|
435
|
+
it darkens the fill in light mode and lightens it in dark, tracking the pill's own contrast. */
|
|
436
|
+
button.tlui-cmt-reaction:hover {
|
|
437
|
+
background: var(--tl-color-muted-1);
|
|
339
438
|
}
|
|
340
439
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
440
|
+
/* a reaction you're part of fills with the selection colour, so "I reacted with this" stands out
|
|
441
|
+
from the grey pills of reactions you haven't joined. */
|
|
442
|
+
.tlui-cmt-reaction--active {
|
|
443
|
+
background: color-mix(in srgb, var(--tl-color-selected) 28%, var(--tl-color-panel));
|
|
344
444
|
}
|
|
345
445
|
|
|
346
|
-
.cmt-
|
|
347
|
-
|
|
446
|
+
button.tlui-cmt-reaction--active:hover {
|
|
447
|
+
background: color-mix(in srgb, var(--tl-color-selected) 38%, var(--tl-color-panel));
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/* The emoji renders larger than the 10px count, but its pinned line-height keeps the pill the
|
|
451
|
+
count's height — the glyph overflows the line box rather than growing it. */
|
|
452
|
+
.tlui-cmt-reaction__emoji {
|
|
453
|
+
font-size: 13px;
|
|
454
|
+
line-height: 10px;
|
|
348
455
|
}
|
|
349
456
|
|
|
350
|
-
.cmt-
|
|
457
|
+
.tlui-cmt-reaction__count {
|
|
351
458
|
color: var(--tl-color-text-3);
|
|
352
|
-
font-
|
|
459
|
+
font-variant-numeric: tabular-nums;
|
|
353
460
|
}
|
|
354
461
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
color: var(--tl-color-selected);
|
|
358
|
-
font-weight: 600;
|
|
359
|
-
background: color-mix(in srgb, var(--tl-color-selected) 12%, transparent);
|
|
360
|
-
padding: 0 4px;
|
|
361
|
-
border-radius: 4px;
|
|
462
|
+
.tlui-cmt-reaction--active .tlui-cmt-reaction__count {
|
|
463
|
+
color: var(--tl-color-text-1);
|
|
362
464
|
}
|
|
363
465
|
|
|
364
|
-
/*
|
|
365
|
-
.cmt-
|
|
366
|
-
display:
|
|
367
|
-
|
|
368
|
-
gap:
|
|
466
|
+
/* emoji picker */
|
|
467
|
+
.tlui-cmt-emoji-picker {
|
|
468
|
+
display: grid;
|
|
469
|
+
grid-template-columns: repeat(5, 40px);
|
|
470
|
+
gap: 0;
|
|
369
471
|
padding: 4px;
|
|
370
|
-
width: 100%;
|
|
371
|
-
box-sizing: border-box;
|
|
372
|
-
max-height: 260px;
|
|
373
|
-
overflow-y: auto;
|
|
374
|
-
color: var(--tl-color-text-1, #1d1d1d);
|
|
375
|
-
background: var(--tl-color-panel, #fff);
|
|
376
|
-
border: 1px solid var(--tl-color-divider, rgba(0, 0, 0, 0.08));
|
|
377
|
-
border-radius: 10px;
|
|
378
|
-
box-shadow: var(--tl-shadow-2, 0 2px 12px rgba(0, 0, 0, 0.14));
|
|
379
472
|
}
|
|
380
473
|
|
|
381
|
-
.cmt-
|
|
474
|
+
.tlui-cmt-emoji-picker__item {
|
|
475
|
+
position: relative;
|
|
382
476
|
display: flex;
|
|
383
477
|
align-items: center;
|
|
384
|
-
|
|
385
|
-
|
|
478
|
+
justify-content: center;
|
|
479
|
+
width: 40px;
|
|
480
|
+
height: 40px;
|
|
481
|
+
padding: 0;
|
|
386
482
|
border: none;
|
|
387
|
-
background:
|
|
388
|
-
border-radius: 6px;
|
|
389
|
-
cursor: pointer;
|
|
390
|
-
text-align: left;
|
|
391
|
-
color: var(--tl-color-text-1);
|
|
483
|
+
background: none;
|
|
392
484
|
font: inherit;
|
|
485
|
+
font-size: 21px;
|
|
486
|
+
line-height: 1;
|
|
487
|
+
cursor: pointer;
|
|
393
488
|
}
|
|
394
489
|
|
|
395
|
-
|
|
396
|
-
.
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
min-width: 0;
|
|
404
|
-
line-height: 1.3;
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
.cmt-mention-list__name {
|
|
408
|
-
font-size: 13px;
|
|
409
|
-
font-weight: 500;
|
|
410
|
-
white-space: nowrap;
|
|
411
|
-
overflow: hidden;
|
|
412
|
-
text-overflow: ellipsis;
|
|
490
|
+
/* Inset wash behind the glyph — the 40px hit cells tile edge-to-edge, the squares sit 4px apart,
|
|
491
|
+
like the thread action buttons. Sits under the emoji so an opaque selected fill can't hide it. */
|
|
492
|
+
.tlui-cmt-emoji-picker__item::after {
|
|
493
|
+
content: '';
|
|
494
|
+
position: absolute;
|
|
495
|
+
inset: 2px;
|
|
496
|
+
z-index: -1;
|
|
497
|
+
border-radius: var(--tl-radius-2);
|
|
413
498
|
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
margin-left: 4px;
|
|
417
|
-
font-weight: 400;
|
|
418
|
-
color: var(--tl-color-text-3);
|
|
499
|
+
.tlui-cmt-emoji-picker__item:hover {
|
|
500
|
+
z-index: 1;
|
|
419
501
|
}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
font-size: 12px;
|
|
423
|
-
color: var(--tl-color-text-3);
|
|
424
|
-
white-space: nowrap;
|
|
425
|
-
overflow: hidden;
|
|
426
|
-
text-overflow: ellipsis;
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
.cmt-mention-list--empty {
|
|
430
|
-
padding: 8px 10px;
|
|
431
|
-
width: 100%;
|
|
432
|
-
box-sizing: border-box;
|
|
433
|
-
color: var(--tl-color-text-3);
|
|
434
|
-
font-size: 13px;
|
|
502
|
+
.tlui-cmt-emoji-picker__item:hover::after {
|
|
503
|
+
background: var(--tl-color-muted-2);
|
|
435
504
|
}
|
|
436
505
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
position: fixed;
|
|
440
|
-
z-index: var(--tl-layer-menus);
|
|
506
|
+
.tlui-cmt-emoji-picker__item--active::after {
|
|
507
|
+
background: color-mix(in srgb, var(--tl-color-selected) 28%, var(--tl-color-panel));
|
|
441
508
|
}
|
|
442
509
|
|
|
443
510
|
/* empty state */
|
|
444
|
-
.cmt-empty {
|
|
511
|
+
.tlui-cmt-empty {
|
|
445
512
|
display: flex;
|
|
446
513
|
flex-direction: column;
|
|
447
514
|
align-items: center;
|
|
@@ -451,92 +518,260 @@
|
|
|
451
518
|
width: 240px;
|
|
452
519
|
}
|
|
453
520
|
|
|
454
|
-
.cmt-empty__icon {
|
|
521
|
+
.tlui-cmt-empty__icon {
|
|
455
522
|
font-size: 28px;
|
|
456
523
|
}
|
|
457
524
|
|
|
458
|
-
.cmt-empty__message {
|
|
525
|
+
.tlui-cmt-empty__message {
|
|
459
526
|
margin: 0;
|
|
460
527
|
color: var(--tl-color-text-3);
|
|
461
|
-
font-size:
|
|
528
|
+
font-size: 12px;
|
|
462
529
|
line-height: 1.4;
|
|
463
530
|
}
|
|
464
531
|
|
|
465
|
-
/* a comment thread: an elevated panel
|
|
466
|
-
|
|
467
|
-
|
|
532
|
+
/* a comment thread: an elevated panel holding a header, an optional resolved banner, the
|
|
533
|
+
comments, and a reply composer */
|
|
534
|
+
/* The thread panel's layout metrics live on the container because two separate portals need them:
|
|
535
|
+
the panel itself, and the canvas hover preview, which has to land its first comment on exactly
|
|
536
|
+
the pixel the panel would. Deriving the preview's offset from these means the two can't drift —
|
|
537
|
+
retune the padding or the header here and the preview follows. */
|
|
538
|
+
.tl-container {
|
|
539
|
+
/* Everything that has to line up against a pin — its preview's bridge, the draft composer's
|
|
540
|
+
offsets, `PIN_SIZE` in thread-view.tsx — derives from this, so the pin's size stays one
|
|
541
|
+
number. */
|
|
542
|
+
--tlui-cmt-pin-size: 28px;
|
|
543
|
+
/* A cluster badge and a stack badge are this square — the same size as a pin, so the marker
|
|
544
|
+
kinds read as one family. The hover preview measures its bridge against it, so the bridge
|
|
545
|
+
stops at the marker's edge instead of covering it. Mirrored by `MARKER_SIZE` in
|
|
546
|
+
thread-view.tsx. */
|
|
547
|
+
--tlui-cmt-marker-size: var(--tlui-cmt-pin-size);
|
|
548
|
+
/* How a marker sits, lifts, and rings. Shared so a pin and a badge respond identically.
|
|
549
|
+
shadow-3's depth without its `inset 1px panel-contrast` edge — that inset reads as a white
|
|
550
|
+
border on a coloured pin (it's invisible on the panel-white menus shadow-3 is meant for). */
|
|
551
|
+
--tlui-cmt-marker-shadow: 0px 1px 2px hsl(0, 0%, 0%, 28%), 0px 2px 6px hsl(0, 0%, 0%, 14%);
|
|
552
|
+
--tlui-cmt-marker-shadow-hover: var(--tlui-cmt-marker-shadow);
|
|
553
|
+
--tlui-cmt-marker-hover-scale: 1.08;
|
|
554
|
+
--tlui-cmt-marker-transition: 0.08s ease;
|
|
555
|
+
--tlui-cmt-thread-padding: 12px;
|
|
556
|
+
--tlui-cmt-thread-gap: 0px;
|
|
557
|
+
/* Hit-area width of one .tlui-cmt-thread__action button (drawn as a 32px square inset 4px). */
|
|
558
|
+
--tlui-cmt-thread-action-size: 40px;
|
|
559
|
+
/* A floating pill's edge — its hairline ring is the only thing separating it from the panel it
|
|
560
|
+
overlaps, so the ring is a theme token rather than a literal black: a near-black hairline
|
|
561
|
+
vanishes on a dark panel, where the divider token lightens instead. The drop below it stays
|
|
562
|
+
literal; a soft dark blur reads on both themes. */
|
|
563
|
+
--tlui-cmt-pill-shadow: 0 0 0 1px var(--tl-color-divider), 0 1px 3px hsl(0, 0%, 0%, 0.05);
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
.tlui-cmt-thread {
|
|
567
|
+
position: relative;
|
|
468
568
|
display: flex;
|
|
469
569
|
flex-direction: column;
|
|
470
|
-
gap: 6px;
|
|
471
570
|
width: 300px;
|
|
472
|
-
padding: 8px;
|
|
473
571
|
background: var(--tl-color-panel);
|
|
474
572
|
border-radius: var(--tl-radius-4);
|
|
475
|
-
box-shadow: var(--tl-shadow-
|
|
573
|
+
box-shadow: var(--tl-shadow-3);
|
|
476
574
|
}
|
|
477
|
-
|
|
575
|
+
/* A pill of its own, floating above the panel's top-right corner and overlapping its top edge. */
|
|
576
|
+
.tlui-cmt-thread__header {
|
|
577
|
+
position: absolute;
|
|
578
|
+
right: 10px;
|
|
579
|
+
bottom: calc(100% - 15px);
|
|
478
580
|
display: flex;
|
|
581
|
+
gap: 2px;
|
|
582
|
+
padding: 2px;
|
|
583
|
+
background: var(--tl-color-panel);
|
|
584
|
+
border-radius: var(--tl-radius-3);
|
|
585
|
+
box-shadow: var(--tlui-cmt-pill-shadow);
|
|
586
|
+
transition: opacity 0.1s ease;
|
|
587
|
+
}
|
|
588
|
+
/* The first comment's hover actions surface right where the header pill sits, so hide the pill
|
|
589
|
+
while that comment is hovered — one pill in the corner, never two stacked. */
|
|
590
|
+
.tlui-cmt-thread:has(.tlui-cmt-thread__list > :first-child:hover)
|
|
591
|
+
.tlui-cmt-thread__header:not(:has(.tlui-cmt-thread__title)) {
|
|
592
|
+
opacity: 0;
|
|
593
|
+
pointer-events: none;
|
|
594
|
+
}
|
|
595
|
+
/* A title puts the header back in the panel, in flow. The pill above is tuned for the actions-only
|
|
596
|
+
case tldraw itself uses: right-anchored and only as wide as its buttons, so a title inside it
|
|
597
|
+
would grow leftwards off the panel's edge and float over whatever sits above. `header` is public
|
|
598
|
+
API (see `CommentThreadProps`), so it has to keep laying out sensibly for anyone passing one. */
|
|
599
|
+
.tlui-cmt-thread__header:has(.tlui-cmt-thread__title) {
|
|
600
|
+
position: static;
|
|
479
601
|
align-items: center;
|
|
480
|
-
|
|
481
|
-
|
|
602
|
+
padding: 0;
|
|
603
|
+
background: none;
|
|
604
|
+
border-radius: 0;
|
|
605
|
+
box-shadow: none;
|
|
482
606
|
}
|
|
483
|
-
.cmt-thread__title {
|
|
607
|
+
.tlui-cmt-thread__title {
|
|
608
|
+
padding: 10px 12px;
|
|
484
609
|
font-size: 12px;
|
|
485
|
-
|
|
610
|
+
line-height: 20px;
|
|
611
|
+
font-weight: 500;
|
|
486
612
|
color: var(--tl-color-text-1);
|
|
487
613
|
}
|
|
488
|
-
.cmt-thread__actions {
|
|
489
|
-
display: flex;
|
|
490
|
-
gap: 2px;
|
|
491
|
-
}
|
|
492
|
-
.cmt-thread__action {
|
|
614
|
+
.tlui-cmt-thread__actions {
|
|
493
615
|
display: flex;
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
616
|
+
gap: 0;
|
|
617
|
+
/* Right-align the actions whether or not the header has a title (it currently has none, so
|
|
618
|
+
space-between alone would leave them at the left). */
|
|
619
|
+
margin-left: auto;
|
|
620
|
+
}
|
|
621
|
+
/* These are TldrawUiButtons (type="icon"), so the 40px box, the 32px ::after square carrying the
|
|
622
|
+
hover wash, and the hover z-index flip all come from .tlui-button — the hit area (not the
|
|
623
|
+
::after) is what's clickable, and it never reaches past its row. Only the bits that differ from
|
|
624
|
+
a toolbar button are set here, at .tlui-button's specificity + 1 so stylesheet order can't
|
|
625
|
+
decide the winner. */
|
|
626
|
+
.tlui-button.tlui-cmt-thread__action {
|
|
627
|
+
width: 40px;
|
|
498
628
|
padding: 0;
|
|
499
|
-
border: none;
|
|
500
629
|
border-radius: 6px;
|
|
501
|
-
background: transparent;
|
|
502
630
|
color: var(--tl-color-text-3);
|
|
503
631
|
font-size: 14px;
|
|
504
632
|
line-height: 1;
|
|
505
|
-
cursor: pointer;
|
|
506
633
|
}
|
|
507
|
-
.
|
|
508
|
-
|
|
634
|
+
/* Overlap each button 4px into the previous so the 32px visual squares sit 4px apart, not 8px.
|
|
635
|
+
Left-only, so the last button's hit area still stops at its row's right edge. */
|
|
636
|
+
.tlui-cmt-thread__action + .tlui-cmt-thread__action {
|
|
637
|
+
margin-left: -4px;
|
|
638
|
+
}
|
|
639
|
+
.tlui-button.tlui-cmt-thread__action:hover {
|
|
509
640
|
color: var(--tl-color-text-1);
|
|
510
641
|
}
|
|
511
|
-
.cmt-
|
|
642
|
+
.tlui-button.tlui-cmt-thread__action--danger:hover {
|
|
643
|
+
color: var(--tl-color-danger);
|
|
644
|
+
}
|
|
645
|
+
.tlui-cmt-thread__resolved {
|
|
646
|
+
margin: 4px 12px;
|
|
512
647
|
padding: 6px 10px;
|
|
513
648
|
border-radius: 8px;
|
|
514
649
|
background: var(--tl-color-muted-2);
|
|
515
650
|
font-size: 12px;
|
|
516
651
|
color: var(--tl-color-text-3);
|
|
517
652
|
}
|
|
518
|
-
.cmt-thread__list {
|
|
653
|
+
.tlui-cmt-thread__list {
|
|
519
654
|
display: flex;
|
|
520
655
|
flex-direction: column;
|
|
521
|
-
gap:
|
|
656
|
+
gap: var(--tlui-cmt-thread-gap);
|
|
657
|
+
}
|
|
658
|
+
/* When nothing follows the list (a resolved thread has no composer or footer) the last comment
|
|
659
|
+
would sit against the panel's rounded bottom — restore the trailing inset the composer supplies. */
|
|
660
|
+
.tlui-cmt-thread__list:last-child {
|
|
661
|
+
padding-bottom: 12px;
|
|
662
|
+
}
|
|
663
|
+
/* The footer slot sits where the composer would — its content (e.g. a sign-in prompt) sits at
|
|
664
|
+
the thread's trailing edge, like the composer's send button. */
|
|
665
|
+
.tlui-cmt-thread__footer {
|
|
666
|
+
display: flex;
|
|
667
|
+
justify-content: flex-end;
|
|
668
|
+
padding: 4px 2px 2px;
|
|
669
|
+
}
|
|
670
|
+
/* Inside a thread, author identity is a small colour dot, no initial — the letter doesn't fit
|
|
671
|
+
at this size. */
|
|
672
|
+
.tlui-cmt-thread .tlui-cmt-avatar,
|
|
673
|
+
.tlui-cmt-canvas-preview--thread .tlui-cmt-avatar,
|
|
674
|
+
.tlui-cmt-canvas-preview--list .tlui-cmt-avatar,
|
|
675
|
+
.tlui-cmt-stack-list .tlui-cmt-avatar {
|
|
676
|
+
width: 12px;
|
|
677
|
+
height: 12px;
|
|
678
|
+
font-size: 0;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
.tlui-cmt-thread .tlui-cmt-composer {
|
|
682
|
+
padding: 12px;
|
|
683
|
+
}
|
|
684
|
+
.tlui-cmt-thread .tlui-cmt-composer .tlui-cmt-avatar {
|
|
685
|
+
display: none;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/* The sidebar's rows use the same small colour dot as the thread view. */
|
|
689
|
+
.tlui-cmt-list .tlui-cmt-avatar {
|
|
690
|
+
width: 14px;
|
|
691
|
+
height: 14px;
|
|
692
|
+
font-size: 0;
|
|
693
|
+
margin-top: 2px;
|
|
694
|
+
}
|
|
695
|
+
/* The sidebar row already leads with its own avatar (the flex row's first column); the byline's
|
|
696
|
+
avatar — added for the canvas thread views — would double it, so hide the byline's inside a row. */
|
|
697
|
+
.tlui-cmt-list .tlui-cmt-head .tlui-cmt-avatar {
|
|
698
|
+
display: none;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
/* The dot treatment is for colour-only identity — an image avatar stays full size. */
|
|
702
|
+
.tlui-cmt-thread .tlui-cmt-avatar--image,
|
|
703
|
+
.tlui-cmt-canvas-preview--thread .tlui-cmt-avatar--image,
|
|
704
|
+
.tlui-cmt-canvas-preview--list .tlui-cmt-avatar--image,
|
|
705
|
+
.tlui-cmt-stack-list .tlui-cmt-avatar--image {
|
|
706
|
+
/* Match the 12px colour dot's width so the body's calc(12px + 6px) indent still lines up under
|
|
707
|
+
the byline name when the author has an image rather than a dot. */
|
|
708
|
+
width: 12px;
|
|
709
|
+
height: 12px;
|
|
710
|
+
margin-top: 0;
|
|
522
711
|
}
|
|
712
|
+
.tlui-cmt-list .tlui-cmt-avatar--image {
|
|
713
|
+
width: 24px;
|
|
714
|
+
height: 24px;
|
|
715
|
+
margin-top: 0;
|
|
716
|
+
}
|
|
717
|
+
|
|
523
718
|
/* inside the panel, comments are plain content — no surrounding box; the composer's field carries
|
|
524
|
-
its own surface.
|
|
525
|
-
|
|
719
|
+
its own surface. The hover preview is the same panel without a header, so its comment is laid
|
|
720
|
+
out by the same rule rather than a copy of it. */
|
|
721
|
+
.tlui-cmt-thread .tlui-cmt-card,
|
|
722
|
+
.tlui-cmt-canvas-preview--thread .tlui-cmt-card {
|
|
526
723
|
width: 100%;
|
|
527
|
-
|
|
724
|
+
gap: 0;
|
|
725
|
+
padding: 0 var(--tlui-cmt-thread-padding);
|
|
528
726
|
background: transparent;
|
|
529
727
|
border: none;
|
|
530
728
|
}
|
|
729
|
+
/* The avatar is a 12px dot, so the body lines up 12px + the head's 6px gap in from the row. */
|
|
730
|
+
.tlui-cmt-thread .tlui-cmt-body,
|
|
731
|
+
.tlui-cmt-canvas-preview--thread .tlui-cmt-body,
|
|
732
|
+
.tlui-cmt-canvas-preview--list .tlui-cmt-body,
|
|
733
|
+
.tlui-cmt-stack-list .tlui-cmt-body {
|
|
734
|
+
padding-left: calc(12px + 6px);
|
|
735
|
+
}
|
|
736
|
+
/* Inside a panel the actions float as their own pill — the same pill the thread header is, in the
|
|
737
|
+
same corner (which is why the header hides while the first comment is hovered). It sits just
|
|
738
|
+
above the card's top edge rather than on the byline. */
|
|
739
|
+
/* Line the card actions up with the header actions: flush to the full-width card's right edge (the
|
|
740
|
+
panel edge, matching the header ✕) and flush on the 40px byline row, so the 40px buttons fill it. */
|
|
741
|
+
.tlui-cmt-thread .tlui-cmt-card .tlui-cmt-card__actions {
|
|
742
|
+
top: 0;
|
|
743
|
+
right: 0;
|
|
744
|
+
}
|
|
745
|
+
/* The byline row is 40px: on the opened thread it fits the action pills (react/edit/delete) that
|
|
746
|
+
float in its corner without the text running underneath; previews and collapsed cards carry the
|
|
747
|
+
same height so every comment row reads identically, solo or in a stack. */
|
|
748
|
+
.tlui-cmt-thread .tlui-cmt-card .tlui-cmt-head,
|
|
749
|
+
.tlui-cmt-canvas-preview--thread .tlui-cmt-card .tlui-cmt-head,
|
|
750
|
+
.tlui-cmt-canvas-preview--list .tlui-cmt-card .tlui-cmt-head,
|
|
751
|
+
.tlui-cmt-stack-list .tlui-cmt-card .tlui-cmt-head {
|
|
752
|
+
min-height: 40px;
|
|
753
|
+
}
|
|
754
|
+
/* Reserve head room only for pills that actually rendered (one child / two children) — pill count
|
|
755
|
+
is a permissions question (canModifyComment), not ownership, and empty slots (read-only viewers)
|
|
756
|
+
keep the full row. Sized from the 40px hit areas (4px overlap), minus the card padding the
|
|
757
|
+
right:0 pills sit over; text stops 4px shy of the visible square. */
|
|
758
|
+
.tlui-cmt-thread .tlui-cmt-card:has(.tlui-cmt-card__actions > *) .tlui-cmt-head {
|
|
759
|
+
padding-right: calc(var(--tlui-cmt-thread-action-size) - var(--tlui-cmt-thread-padding));
|
|
760
|
+
}
|
|
761
|
+
.tlui-cmt-thread .tlui-cmt-card:has(.tlui-cmt-card__actions > * + *) .tlui-cmt-head {
|
|
762
|
+
padding-right: calc(
|
|
763
|
+
2 * var(--tlui-cmt-thread-action-size) - 4px - var(--tlui-cmt-thread-padding)
|
|
764
|
+
);
|
|
765
|
+
}
|
|
531
766
|
|
|
532
767
|
/* comments list — thread summaries, one per row (used by the canvas sidebar) */
|
|
533
|
-
.cmt-list {
|
|
768
|
+
.tlui-cmt-list {
|
|
534
769
|
display: flex;
|
|
535
770
|
flex-direction: column;
|
|
536
771
|
width: 100%;
|
|
537
772
|
min-height: 0;
|
|
538
773
|
}
|
|
539
|
-
.cmt-list__header {
|
|
774
|
+
.tlui-cmt-list__header {
|
|
540
775
|
flex-shrink: 0;
|
|
541
776
|
display: flex;
|
|
542
777
|
align-items: center;
|
|
@@ -545,73 +780,102 @@
|
|
|
545
780
|
padding: 6px 6px 6px 14px;
|
|
546
781
|
border-bottom: 1px solid var(--tl-color-divider);
|
|
547
782
|
}
|
|
548
|
-
.cmt-list__header-title {
|
|
549
|
-
font-size:
|
|
550
|
-
font-weight:
|
|
551
|
-
|
|
552
|
-
text-transform: uppercase;
|
|
553
|
-
color: var(--tl-color-text-3);
|
|
783
|
+
.tlui-cmt-list__header-title {
|
|
784
|
+
font-size: 12px;
|
|
785
|
+
font-weight: 500;
|
|
786
|
+
color: var(--tl-color-text-1);
|
|
554
787
|
}
|
|
555
788
|
|
|
556
|
-
/*
|
|
557
|
-
.
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
789
|
+
/* A small square icon button in the sidebar header (filter funnel, overflow …). Also a
|
|
790
|
+
TldrawUiButton, but a bespoke 26px size — so it has to override .tlui-button's 40px box, and
|
|
791
|
+
`min-width` in particular would otherwise beat `width`. Selectors carry .tlui-button so
|
|
792
|
+
stylesheet order can't decide the winner. */
|
|
793
|
+
.tlui-button.tlui-cmt-header-btn {
|
|
561
794
|
width: 26px;
|
|
795
|
+
min-width: 26px;
|
|
562
796
|
height: 26px;
|
|
563
797
|
padding: 0;
|
|
564
|
-
border: none;
|
|
565
798
|
border-radius: 6px;
|
|
566
|
-
background: transparent;
|
|
567
799
|
color: var(--tl-color-text-2);
|
|
568
|
-
cursor: pointer;
|
|
569
800
|
}
|
|
570
|
-
|
|
571
|
-
|
|
801
|
+
/* Same hit-target expansion as the thread actions, tiled the same way — this row's gap is 2px too
|
|
802
|
+
(see `.tlui-cmt-list__header-actions`). Unlike the thread actions, the hover fill sits on the
|
|
803
|
+
button itself, so .tlui-button's ::after wash is cleared and the pseudo-element is left doing
|
|
804
|
+
nothing but widening the hit area. */
|
|
805
|
+
.tlui-button.tlui-cmt-header-btn::after {
|
|
806
|
+
inset: -6px -1px;
|
|
807
|
+
background: none;
|
|
808
|
+
}
|
|
809
|
+
.tlui-button.tlui-cmt-header-btn:first-child::after {
|
|
810
|
+
left: -6px;
|
|
811
|
+
}
|
|
812
|
+
.tlui-button.tlui-cmt-header-btn:last-child::after {
|
|
813
|
+
right: -6px;
|
|
814
|
+
}
|
|
815
|
+
.tlui-button.tlui-cmt-header-btn:hover,
|
|
816
|
+
.tlui-button.tlui-cmt-header-btn[data-state='open'] {
|
|
572
817
|
background: var(--tl-color-muted-2);
|
|
573
818
|
color: var(--tl-color-text-1);
|
|
574
819
|
}
|
|
575
|
-
.cmt-list__header-actions {
|
|
820
|
+
.tlui-cmt-list__header-actions {
|
|
576
821
|
display: flex;
|
|
577
822
|
align-items: center;
|
|
578
823
|
gap: 2px;
|
|
579
824
|
}
|
|
580
825
|
|
|
826
|
+
/* The commenting dropdowns' surface — a little air between the items and the menu edge. */
|
|
827
|
+
.tlui-cmt-menu {
|
|
828
|
+
min-width: 100px;
|
|
829
|
+
padding: 4px;
|
|
830
|
+
}
|
|
831
|
+
|
|
581
832
|
/* a menu row with a label and a right-aligned shortcut hint (overflow menu) */
|
|
582
|
-
.cmt-menu-item {
|
|
833
|
+
.tlui-cmt-menu-item {
|
|
834
|
+
position: relative;
|
|
583
835
|
display: flex;
|
|
584
836
|
align-items: center;
|
|
585
837
|
justify-content: space-between;
|
|
586
838
|
gap: 24px;
|
|
587
839
|
width: 100%;
|
|
588
|
-
|
|
840
|
+
min-height: 40px;
|
|
841
|
+
padding: 0 10px;
|
|
589
842
|
border: none;
|
|
590
|
-
border-radius: 6px;
|
|
591
843
|
background: transparent;
|
|
592
844
|
font: inherit;
|
|
593
|
-
font-size:
|
|
845
|
+
font-size: 12px;
|
|
594
846
|
color: var(--tl-color-text-1);
|
|
595
847
|
cursor: pointer;
|
|
596
848
|
}
|
|
597
|
-
|
|
849
|
+
/* 36px visual inset within the 40px row — the hover wash the action and emoji buttons use. */
|
|
850
|
+
.tlui-cmt-menu-item::after {
|
|
851
|
+
content: '';
|
|
852
|
+
position: absolute;
|
|
853
|
+
inset: 2px;
|
|
854
|
+
border-radius: var(--tl-radius-2);
|
|
855
|
+
}
|
|
856
|
+
.tlui-cmt-menu-item:hover::after {
|
|
598
857
|
background: var(--tl-color-muted-2);
|
|
599
858
|
}
|
|
600
|
-
|
|
859
|
+
/* Destructive menu entries (delete) — the same danger colour as tldraw's danger buttons. */
|
|
860
|
+
.tlui-cmt-menu-item--danger {
|
|
861
|
+
color: var(--tl-color-danger);
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
.tlui-cmt-menu-item__shortcut {
|
|
601
865
|
color: var(--tl-color-text-3);
|
|
602
866
|
font-size: 12px;
|
|
603
867
|
}
|
|
604
|
-
.cmt-list__items {
|
|
868
|
+
.tlui-cmt-list__items {
|
|
605
869
|
flex: 1;
|
|
606
870
|
min-height: 0;
|
|
607
871
|
overflow-y: auto;
|
|
608
872
|
}
|
|
609
|
-
.cmt-list__empty {
|
|
873
|
+
.tlui-cmt-list__empty {
|
|
610
874
|
padding: 20px 14px;
|
|
611
875
|
color: var(--tl-color-text-3);
|
|
612
|
-
font-size:
|
|
876
|
+
font-size: 12px;
|
|
613
877
|
}
|
|
614
|
-
.cmt-list__item {
|
|
878
|
+
.tlui-cmt-list__item {
|
|
615
879
|
display: flex;
|
|
616
880
|
gap: 10px;
|
|
617
881
|
width: 100%;
|
|
@@ -622,34 +886,48 @@
|
|
|
622
886
|
font: inherit;
|
|
623
887
|
text-align: left;
|
|
624
888
|
cursor: pointer;
|
|
889
|
+
/* rows can render as anchors (for open-in-new-tab); keep them looking like list rows */
|
|
890
|
+
color: inherit;
|
|
891
|
+
text-decoration: none;
|
|
625
892
|
}
|
|
626
|
-
.cmt-list__item:hover {
|
|
893
|
+
.tlui-cmt-list__item:hover {
|
|
627
894
|
background: var(--tl-color-muted-2);
|
|
628
895
|
}
|
|
629
|
-
|
|
630
|
-
|
|
896
|
+
/* Selected sits a step above hover so the open thread's row stays distinguishable while
|
|
897
|
+
pointing at other rows — but only a step: the muted-1 token (10%) reads too heavy here.
|
|
898
|
+
These rows sit on the opaque sidebar panel, so a translucent tint composes safely. */
|
|
899
|
+
.tlui-cmt-list__item--selected,
|
|
900
|
+
.tlui-cmt-list__item--selected:hover {
|
|
901
|
+
background: hsl(0, 0%, 0%, 5%);
|
|
902
|
+
}
|
|
903
|
+
.tl-theme__dark .tlui-cmt-list__item--selected,
|
|
904
|
+
.tl-theme__dark .tlui-cmt-list__item--selected:hover {
|
|
905
|
+
background: hsl(0, 0%, 100%, 5%);
|
|
631
906
|
}
|
|
632
907
|
/* 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 {
|
|
908
|
+
.tlui-cmt-list__item[data-resolved] .tlui-cmt-head,
|
|
909
|
+
.tlui-cmt-list__item[data-resolved] .tlui-cmt-list__item-preview {
|
|
635
910
|
opacity: 0.55;
|
|
636
911
|
}
|
|
637
|
-
.cmt-list__item-body {
|
|
912
|
+
.tlui-cmt-list__item-body {
|
|
638
913
|
flex: 1;
|
|
639
914
|
min-width: 0;
|
|
640
915
|
}
|
|
641
|
-
.cmt-list__item-preview {
|
|
916
|
+
.tlui-cmt-list__item-preview {
|
|
642
917
|
margin-top: 2px;
|
|
643
|
-
font-size:
|
|
918
|
+
font-size: 12px;
|
|
644
919
|
color: var(--tl-color-text-1);
|
|
645
920
|
overflow: hidden;
|
|
646
921
|
text-overflow: ellipsis;
|
|
647
922
|
display: -webkit-box;
|
|
648
923
|
-webkit-line-clamp: 2;
|
|
649
924
|
-webkit-box-orient: vertical;
|
|
925
|
+
/* Long unbroken strings (URLs, mashed keys) wrap onto the clamped lines instead of clipping
|
|
926
|
+
mid-string — same treatment as the card body. */
|
|
927
|
+
overflow-wrap: anywhere;
|
|
650
928
|
}
|
|
651
929
|
/* meta line under the preview: page label and/or a resolved marker */
|
|
652
|
-
.cmt-list__item-meta {
|
|
930
|
+
.tlui-cmt-list__item-meta {
|
|
653
931
|
display: flex;
|
|
654
932
|
align-items: center;
|
|
655
933
|
gap: 8px;
|
|
@@ -657,22 +935,27 @@
|
|
|
657
935
|
font-size: 11px;
|
|
658
936
|
color: var(--tl-color-text-3);
|
|
659
937
|
}
|
|
660
|
-
.cmt-list__item-resolved {
|
|
938
|
+
.tlui-cmt-list__item-resolved {
|
|
661
939
|
display: inline-flex;
|
|
662
940
|
align-items: center;
|
|
663
941
|
gap: 3px;
|
|
664
942
|
font-weight: 600;
|
|
665
943
|
}
|
|
666
|
-
.cmt-list__item-page {
|
|
944
|
+
.tlui-cmt-list__item-page {
|
|
667
945
|
display: inline-flex;
|
|
668
946
|
align-items: center;
|
|
669
947
|
padding: 1px 6px;
|
|
670
948
|
border-radius: 4px;
|
|
671
949
|
background: var(--tl-color-muted-2);
|
|
672
950
|
}
|
|
673
|
-
.cmt-list__item-
|
|
674
|
-
|
|
675
|
-
align-
|
|
951
|
+
.tlui-cmt-list__item-replies {
|
|
952
|
+
display: inline-flex;
|
|
953
|
+
align-items: center;
|
|
954
|
+
}
|
|
955
|
+
/* reply count under a preview card's opening comment — the thread continues past what's shown */
|
|
956
|
+
.tlui-cmt-card__replies {
|
|
957
|
+
display: block;
|
|
958
|
+
margin-top: 6px;
|
|
676
959
|
font-size: 12px;
|
|
677
960
|
color: var(--tl-color-text-3);
|
|
678
961
|
}
|