@lark-apaas/coding-template-nestjs-react-fullstack 0.1.56 → 0.1.57-alpha.20261103143319

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/package.json +1 -1
  2. package/template/client/src/components/business-ui/README.md +2 -0
  3. package/template/client/src/components/business-ui/record-comments/README.md +141 -0
  4. package/template/client/src/components/business-ui/record-comments/app-source.ts +93 -0
  5. package/template/client/src/components/business-ui/record-comments/assets/reaction-sprite.png +0 -0
  6. package/template/client/src/components/business-ui/record-comments/comment-panel.contract.ts +240 -0
  7. package/template/client/src/components/business-ui/record-comments/comment-panel.tsx +231 -0
  8. package/template/client/src/components/business-ui/record-comments/extensions.ts +129 -0
  9. package/template/client/src/components/business-ui/record-comments/index.ts +9 -0
  10. package/template/client/src/components/business-ui/record-comments/internal/composer.tsx +529 -0
  11. package/template/client/src/components/business-ui/record-comments/internal/content.tsx +213 -0
  12. package/template/client/src/components/business-ui/record-comments/internal/discussion.tsx +517 -0
  13. package/template/client/src/components/business-ui/record-comments/internal/editor.tsx +675 -0
  14. package/template/client/src/components/business-ui/record-comments/internal/icons.tsx +148 -0
  15. package/template/client/src/components/business-ui/record-comments/internal/images.tsx +155 -0
  16. package/template/client/src/components/business-ui/record-comments/internal/mentions.tsx +163 -0
  17. package/template/client/src/components/business-ui/record-comments/internal/model.ts +581 -0
  18. package/template/client/src/components/business-ui/record-comments/internal/mutations.ts +170 -0
  19. package/template/client/src/components/business-ui/record-comments/internal/reaction-catalog.ts +196 -0
  20. package/template/client/src/components/business-ui/record-comments/internal/reactions.tsx +681 -0
  21. package/template/client/src/components/business-ui/record-comments/internal/styles.css +1109 -0
  22. package/template/client/src/components/business-ui/record-comments/internal/suggestions.tsx +456 -0
  23. package/template/client/src/components/business-ui/record-comments/internal/view-types.ts +84 -0
  24. package/template/client/src/components/business-ui/record-comments/types.ts +118 -0
  25. package/template/package-lock.json +529 -13
  26. package/template/package.json +15 -4
@@ -0,0 +1,1109 @@
1
+ /* mention-appearance.css */
2
+ /* Match Feishu's primary / self / disabled @-person hover tokens. Keep these
3
+ scoped to person labels so the host application's accent theme cannot alter them. */
4
+ .replica-user-mention-label:hover {
5
+ background-color: rgb(20 86 240 / 10%);
6
+ }
7
+ .replica-user-mention-self:hover {
8
+ background-color: #336df4;
9
+ }
10
+ .replica-user-mention-disabled:hover {
11
+ background-color: rgb(31 35 41 / 10%);
12
+ }
13
+
14
+ /* mention-suggestions.css */
15
+ /* UD MentionPanel/index.less + OptionItem/index.less, scoped to the copied component. */
16
+ .replica-comment-mention-panel {
17
+ position: fixed;
18
+ z-index: 50;
19
+ display: flex;
20
+ flex-direction: column;
21
+ box-sizing: border-box;
22
+ overflow: hidden;
23
+ border: 1px solid var(--border);
24
+ border-radius: 6px;
25
+ background: var(--popover);
26
+ color: var(--foreground);
27
+ font-size: 12px;
28
+ line-height: 20px;
29
+ box-shadow: 0 6px 24px rgb(31 35 41 / 8%);
30
+ }
31
+ .replica-comment-mention-list-container {
32
+ display: flex;
33
+ flex: auto;
34
+ flex-direction: column;
35
+ min-height: 0;
36
+ overflow: hidden;
37
+ position: relative;
38
+ }
39
+ .replica-comment-mention-list {
40
+ min-height: 0;
41
+ overflow-y: auto;
42
+ overscroll-behavior: contain;
43
+ scrollbar-width: thin;
44
+ padding: 8px 0;
45
+ }
46
+ .replica-comment-mention-panel[data-loading] .replica-comment-mention-list {
47
+ overflow-y: hidden;
48
+ }
49
+ .replica-comment-mention-option-container {
50
+ margin-bottom: 2px;
51
+ }
52
+ .replica-comment-mention-option {
53
+ display: flex;
54
+ align-items: center;
55
+ height: 48px;
56
+ box-sizing: border-box;
57
+ padding: 4px 8px;
58
+ margin: 0 8px;
59
+ border-radius: 4px;
60
+ cursor: pointer;
61
+ }
62
+ .replica-comment-mention-option-container[aria-selected='true']
63
+ > .replica-comment-mention-option,
64
+ .replica-comment-mention-option:hover {
65
+ background: rgb(31 35 41 / 8%);
66
+ }
67
+ .replica-comment-mention-option-container[aria-selected='true']
68
+ .replica-comment-mention-title-content {
69
+ color: var(--primary);
70
+ }
71
+ .replica-comment-mention-avatar {
72
+ position: relative;
73
+ flex-shrink: 0;
74
+ margin-right: 8px;
75
+ }
76
+ .replica-comment-mention-main {
77
+ width: 100%;
78
+ min-width: 0;
79
+ overflow: hidden;
80
+ }
81
+ .replica-comment-mention-title {
82
+ display: flex;
83
+ font-size: 14px;
84
+ line-height: 22px;
85
+ color: var(--foreground);
86
+ }
87
+ .replica-comment-mention-title-content {
88
+ margin-right: 4px;
89
+ word-break: keep-all;
90
+ white-space: nowrap;
91
+ overflow: hidden;
92
+ text-overflow: ellipsis;
93
+ }
94
+ .replica-comment-mention-subtitle {
95
+ font-size: 12px;
96
+ line-height: 20px;
97
+ word-break: keep-all;
98
+ white-space: nowrap;
99
+ overflow: hidden;
100
+ text-overflow: ellipsis;
101
+ color: var(--muted-foreground);
102
+ }
103
+ .replica-comment-mention-text {
104
+ padding: 16px;
105
+ font-size: 14px;
106
+ line-height: 22px;
107
+ }
108
+ .replica-comment-mention-skeleton {
109
+ display: flex;
110
+ flex-direction: column;
111
+ padding-left: 16px;
112
+ overflow: hidden;
113
+ }
114
+ .replica-comment-mention-skeleton svg {
115
+ display: block;
116
+ width: 280px;
117
+ height: 40px;
118
+ flex-shrink: 0;
119
+ animation: replica-comment-mention-shimmer 1s ease-in-out infinite;
120
+ }
121
+ .replica-comment-mention-loading-mask {
122
+ position: absolute;
123
+ inset: 0;
124
+ z-index: 1;
125
+ display: flex;
126
+ align-items: center;
127
+ justify-content: center;
128
+ background: rgb(255 255 255 / 60%);
129
+ }
130
+ @keyframes replica-comment-mention-shimmer {
131
+ 50% {
132
+ opacity: 0.7;
133
+ }
134
+ }
135
+ @media (prefers-reduced-motion: reduce) {
136
+ .replica-comment-mention-skeleton svg {
137
+ animation: none;
138
+ }
139
+ }
140
+
141
+ /* comment-reactions.css */
142
+ /* Source: UD ReactionPanel/styles, EmojiPanel/styles, Reaction and ReactionDetail less. */
143
+ .replica-comment-reaction-emoji {
144
+ display: inline-block;
145
+ flex-shrink: 0;
146
+ vertical-align: top;
147
+ background-repeat: no-repeat;
148
+ user-select: none;
149
+ max-width: none;
150
+ }
151
+ .replica-comment-reaction-panel {
152
+ width: 344px;
153
+ max-width: calc(100vw - 26px);
154
+ overflow: hidden;
155
+ border: 1px solid var(--border);
156
+ border-radius: 8px;
157
+ background: var(--popover);
158
+ box-sizing: content-box;
159
+ }
160
+ .replica-comment-reaction-recent {
161
+ height: 64px;
162
+ padding: 4px 1px 8px;
163
+ overflow: hidden;
164
+ border-bottom: 1px solid var(--border);
165
+ background: var(--background);
166
+ box-sizing: border-box;
167
+ }
168
+ .replica-comment-reaction-used-title {
169
+ height: 22px;
170
+ padding: 0 12px;
171
+ color: var(--subtle-foreground);
172
+ font-size: 12px;
173
+ line-height: 20px;
174
+ }
175
+ .replica-comment-reaction-used-grid {
176
+ height: 28px;
177
+ margin-top: 2px;
178
+ padding: 0 14px 0 8px;
179
+ display: flex;
180
+ flex-wrap: wrap;
181
+ overflow: hidden;
182
+ }
183
+ .replica-comment-reaction-used-grid .replica-comment-reaction-choice {
184
+ flex-shrink: 0;
185
+ height: 28px;
186
+ width: auto;
187
+ margin-right: 11px;
188
+ margin-bottom: 20px;
189
+ padding: 0;
190
+ }
191
+ .replica-comment-reaction-scroll {
192
+ height: 276px;
193
+ overflow: hidden auto;
194
+ overscroll-behavior: contain;
195
+ scrollbar-width: thin;
196
+ }
197
+ .replica-comment-reaction-all-title {
198
+ padding: 8px 12px 0;
199
+ color: var(--subtle-foreground);
200
+ font-size: 12px;
201
+ line-height: 20px;
202
+ }
203
+ .replica-comment-reaction-grid {
204
+ display: flex;
205
+ flex-wrap: wrap;
206
+ padding: 4px 10px 10px;
207
+ }
208
+ .replica-comment-reaction-choice {
209
+ display: flex;
210
+ align-items: center;
211
+ justify-content: center;
212
+ height: 36px;
213
+ width: 36px;
214
+ cursor: pointer;
215
+ }
216
+ .replica-comment-reaction-choice .replica-comment-reaction-emoji {
217
+ transition: transform 300ms;
218
+ }
219
+ .replica-comment-reaction-choice:hover .replica-comment-reaction-emoji {
220
+ transform: scale(1.3);
221
+ }
222
+ .replica-comment-reaction-choice:focus-visible {
223
+ outline: 2px solid var(--primary);
224
+ border-radius: 4px;
225
+ outline-offset: -2px;
226
+ }
227
+ .replica-comment-reaction-badge {
228
+ position: relative;
229
+ display: inline-flex;
230
+ align-items: center;
231
+ max-width: 100%;
232
+ overflow: hidden;
233
+ padding: 2px 6px;
234
+ border-radius: 18px;
235
+ color: var(--subtle-foreground);
236
+ background: var(--muted);
237
+ font-size: 12px;
238
+ line-height: 18px;
239
+ }
240
+ .replica-comment-reaction-separator {
241
+ flex-shrink: 0;
242
+ width: 0;
243
+ height: 12px;
244
+ margin: 0 6px 0 4px;
245
+ border-left: 0.5px solid var(--border);
246
+ }
247
+ .replica-comment-reaction-users {
248
+ display: flex;
249
+ min-width: 0;
250
+ overflow: hidden;
251
+ white-space: nowrap;
252
+ }
253
+ .replica-comment-reaction-user {
254
+ height: 18px;
255
+ min-width: 0;
256
+ flex-shrink: 1;
257
+ white-space: pre;
258
+ overflow: hidden;
259
+ text-overflow: ellipsis;
260
+ font-size: 12px;
261
+ line-height: 18px;
262
+ }
263
+ .replica-comment-reaction-user:not(:last-child) {
264
+ margin-right: 5px;
265
+ }
266
+ .replica-comment-reaction-user:hover,
267
+ .replica-comment-reaction-more:hover {
268
+ color: var(--primary);
269
+ }
270
+ .replica-comment-reaction-more {
271
+ flex-shrink: 0;
272
+ margin-left: 5px;
273
+ white-space: nowrap;
274
+ }
275
+ .replica-comment-reaction-measure {
276
+ position: absolute;
277
+ visibility: hidden;
278
+ pointer-events: none;
279
+ display: flex;
280
+ width: max-content;
281
+ inset: 0 auto auto 0;
282
+ }
283
+ .replica-comment-reaction-measure .replica-comment-reaction-user {
284
+ display: inline-flex;
285
+ max-width: none;
286
+ }
287
+ .replica-comment-reaction-detail {
288
+ display: flex;
289
+ flex-direction: column;
290
+ justify-content: space-between;
291
+ height: min(475px, calc(100dvh - 140px));
292
+ width: min(600px, calc(100vw - 74px));
293
+ }
294
+ .replica-comment-reaction-tabs {
295
+ display: flex;
296
+ flex: none;
297
+ flex-wrap: wrap;
298
+ max-height: 172px;
299
+ overflow-y: auto;
300
+ }
301
+ .replica-comment-reaction-tabs > button {
302
+ display: flex;
303
+ align-items: center;
304
+ justify-content: center;
305
+ margin: 0 8px 12px;
306
+ height: 28px;
307
+ width: 60px;
308
+ border-radius: 14px;
309
+ background: var(--muted);
310
+ color: var(--subtle-foreground);
311
+ cursor: pointer;
312
+ font-size: 16px;
313
+ }
314
+ .replica-comment-reaction-tabs .replica-comment-reaction-emoji {
315
+ margin-right: 6px;
316
+ }
317
+ .replica-comment-reaction-tabs > button[aria-selected='true'] {
318
+ background: var(--primary);
319
+ color: white;
320
+ }
321
+ .replica-comment-reaction-detail-border {
322
+ position: relative;
323
+ flex: auto;
324
+ overflow: auto;
325
+ margin-top: 12px;
326
+ border: 1px solid var(--border);
327
+ }
328
+ .replica-comment-reaction-detail-border::before {
329
+ content: '';
330
+ position: absolute;
331
+ left: 50%;
332
+ top: 20px;
333
+ width: 1px;
334
+ height: calc(100% - 40px);
335
+ background: var(--border);
336
+ pointer-events: none;
337
+ }
338
+ .replica-comment-reaction-detail-users {
339
+ display: flex;
340
+ flex-wrap: wrap;
341
+ margin-top: 20px;
342
+ }
343
+ .replica-comment-reaction-person {
344
+ display: flex;
345
+ align-items: center;
346
+ width: calc(50% - 8px);
347
+ height: 52px;
348
+ padding: 10px 12px;
349
+ margin: 0 4px;
350
+ border-radius: 6px;
351
+ color: var(--foreground);
352
+ font-size: 14px;
353
+ }
354
+ .replica-comment-reaction-person:hover {
355
+ background: var(--comment-hover);
356
+ }
357
+ @media (prefers-reduced-motion: reduce) {
358
+ .replica-comment-reaction-choice .replica-comment-reaction-emoji {
359
+ transition: none;
360
+ }
361
+ }
362
+
363
+ /* discussion.css */
364
+ /* All rules belong to the replica. No original comment selectors are changed. */
365
+ .replica-discussion {
366
+ --replica-text: #1f2329;
367
+ --replica-secondary: #646a73;
368
+ --replica-placeholder: #8f959e;
369
+ --replica-primary: #1456f0;
370
+ --replica-line: #d0d3d6;
371
+ display: flex;
372
+ flex-direction: column;
373
+ width: 100%;
374
+ height: 100%;
375
+ min-height: 0;
376
+ color: var(--replica-text);
377
+ background: #fff;
378
+ font-family:
379
+ -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Tahoma, 'PingFang SC',
380
+ 'Microsoft Yahei', Arial, sans-serif;
381
+ font-size: 14px;
382
+ line-height: 22px;
383
+ color-scheme: light;
384
+ }
385
+ .replica-discussion *,
386
+ .replica-private-menu *,
387
+ .replica-action-menu * {
388
+ box-sizing: border-box;
389
+ }
390
+ .replica-discussion button,
391
+ .replica-action-menu button,
392
+ .replica-private-menu button {
393
+ cursor: pointer;
394
+ }
395
+ .replica-discussion button:disabled {
396
+ cursor: default;
397
+ }
398
+ .replica-discussion button:focus-visible {
399
+ outline: 2px solid var(--replica-primary);
400
+ outline-offset: 2px;
401
+ border-radius: 4px;
402
+ }
403
+ .replica-discussion-header {
404
+ display: flex;
405
+ align-items: center;
406
+ flex: none;
407
+ height: 36px;
408
+ padding: 0 16px;
409
+ font-size: 14px;
410
+ font-weight: 500;
411
+ color: #646a73;
412
+ }
413
+ .replica-discussion-list {
414
+ flex: 1 1 auto;
415
+ min-height: 0;
416
+ overflow-y: auto;
417
+ padding: 4px 8px;
418
+ scrollbar-width: thin;
419
+ overscroll-behavior: contain;
420
+ }
421
+ .replica-thread {
422
+ margin-bottom: 10px;
423
+ }
424
+ .replica-reply {
425
+ display: flex;
426
+ align-items: flex-start;
427
+ padding: 8px;
428
+ min-width: 0;
429
+ background: #fff;
430
+ }
431
+ .replica-reply:hover,
432
+ .replica-reply:focus-within {
433
+ background: #f5f6f7;
434
+ border-radius: 6px;
435
+ }
436
+ .replica-reply-target {
437
+ background: #f5f6ff;
438
+ border-radius: 6px;
439
+ }
440
+ .replica-reply-child {
441
+ margin: 4px 0 0 40px;
442
+ padding-left: 9px;
443
+ }
444
+ .replica-author-avatar {
445
+ width: 32px;
446
+ height: 32px;
447
+ flex: none;
448
+ position: relative;
449
+ overflow: hidden;
450
+ border-radius: 50%;
451
+ padding: 0;
452
+ }
453
+ .replica-author-avatar[data-small] {
454
+ width: 24px;
455
+ height: 24px;
456
+ }
457
+ .replica-author-avatar svg,
458
+ .replica-author-avatar img {
459
+ position: absolute;
460
+ inset: 0;
461
+ width: 100%;
462
+ height: 100%;
463
+ object-fit: cover;
464
+ }
465
+ .replica-reply-main {
466
+ flex: 1;
467
+ min-width: 0;
468
+ margin-left: 10px;
469
+ }
470
+ .replica-reply-info {
471
+ display: flex;
472
+ align-items: center;
473
+ min-width: 0;
474
+ height: 17px;
475
+ gap: 4px;
476
+ }
477
+ .replica-author-name {
478
+ overflow: hidden;
479
+ text-overflow: ellipsis;
480
+ white-space: nowrap;
481
+ flex: 0 1 auto;
482
+ font-weight: 500;
483
+ font-size: 14px;
484
+ line-height: 17px;
485
+ padding: 0;
486
+ color: #1f2329;
487
+ }
488
+ .replica-time {
489
+ font-size: 12px;
490
+ line-height: 17px;
491
+ color: #8f959e;
492
+ white-space: nowrap;
493
+ overflow: hidden;
494
+ text-overflow: ellipsis;
495
+ }
496
+ .replica-reply-controls {
497
+ margin-left: auto;
498
+ display: flex;
499
+ align-items: center;
500
+ gap: 10px;
501
+ height: 14px;
502
+ flex: none;
503
+ visibility: hidden;
504
+ color: #646a73;
505
+ }
506
+ .replica-reply:hover .replica-reply-controls,
507
+ .replica-reply:focus-within .replica-reply-controls,
508
+ .replica-reply[data-tools-open] .replica-reply-controls {
509
+ visibility: visible;
510
+ }
511
+ .replica-icon-button {
512
+ display: inline-flex;
513
+ align-items: center;
514
+ justify-content: center;
515
+ width: 14px;
516
+ height: 16px;
517
+ flex: none;
518
+ padding: 0;
519
+ border: 0;
520
+ color: #646a73;
521
+ background: transparent;
522
+ }
523
+ .replica-icon-button:hover {
524
+ color: #1f2329;
525
+ }
526
+ .replica-reply-body {
527
+ margin-top: 4px;
528
+ font-size: 14px;
529
+ line-height: 22px;
530
+ overflow-wrap: anywhere;
531
+ white-space: pre-wrap;
532
+ }
533
+ .replica-reply-body button,
534
+ .replica-reply-body a {
535
+ font-family: inherit;
536
+ }
537
+ .replica-reply-body > span > span {
538
+ vertical-align: top;
539
+ }
540
+ .replica-reactions:empty {
541
+ display: none;
542
+ }
543
+ .replica-reactions [data-replica-comment-reactions]:not(:empty) {
544
+ margin-top: 10px;
545
+ }
546
+ .replica-discussion .replica-comment-reaction-badge {
547
+ background: rgba(31, 35, 41, 0.05);
548
+ }
549
+ .replica-discussion-footer {
550
+ flex: none;
551
+ margin: 0 0 12px;
552
+ padding: 4px 24px;
553
+ }
554
+ .replica-composer-area {
555
+ position: relative;
556
+ }
557
+ .replica-composer {
558
+ border: 1px solid #d0d3d6;
559
+ border-radius: 6px;
560
+ min-height: 68px;
561
+ padding: 0 11px;
562
+ background: #fff;
563
+ color: #1f2329;
564
+ }
565
+ .replica-composer:hover {
566
+ border-color: #8f959e;
567
+ }
568
+ .replica-composer:focus-within {
569
+ border-color: #1456f0;
570
+ }
571
+ .replica-composer .replica-input > div:first-child {
572
+ padding: 8px 0 0;
573
+ border: 0;
574
+ border-radius: 0;
575
+ min-height: 30px;
576
+ background: transparent;
577
+ box-shadow: none;
578
+ }
579
+ .replica-composer .replica-input [role='textbox'] {
580
+ min-height: 22px;
581
+ max-height: 240px;
582
+ font-size: 14px;
583
+ line-height: 22px;
584
+ color: #1f2329;
585
+ }
586
+ .replica-composer .replica-input p[aria-hidden] {
587
+ top: 0;
588
+ translate: none;
589
+ transform: none;
590
+ color: #8f959e;
591
+ }
592
+ .replica-composer .replica-input button {
593
+ border: 0;
594
+ background: transparent;
595
+ box-shadow: none;
596
+ }
597
+ .replica-composer .replica-input button::after,
598
+ .replica-composer .replica-input button::before {
599
+ display: none;
600
+ }
601
+ .replica-composer-toolbar {
602
+ display: flex;
603
+ align-items: center;
604
+ justify-content: flex-end;
605
+ min-height: 36px;
606
+ padding: 11px 0 9px;
607
+ margin-right: 11px;
608
+ }
609
+ .replica-composer-tools {
610
+ display: flex;
611
+ align-items: center;
612
+ gap: 0;
613
+ }
614
+ .replica-composer-tools .replica-icon-button {
615
+ width: 16px;
616
+ color: #8f959e;
617
+ }
618
+ .replica-toolbar-divider {
619
+ width: 1px;
620
+ height: 16px;
621
+ background: #dee0e3;
622
+ margin: 0 8px;
623
+ }
624
+ .replica-send-button {
625
+ display: flex;
626
+ align-items: center;
627
+ justify-content: center;
628
+ width: 16px;
629
+ height: 16px;
630
+ padding: 0;
631
+ color: #1456f0;
632
+ }
633
+ .replica-send-button:disabled {
634
+ color: #bbbfc4;
635
+ }
636
+ .replica-composer-context {
637
+ display: flex;
638
+ align-items: center;
639
+ justify-content: space-between;
640
+ color: #646a73;
641
+ font-size: 12px;
642
+ line-height: 20px;
643
+ margin-bottom: 6px;
644
+ }
645
+ .replica-composer-context button {
646
+ display: flex;
647
+ }
648
+ .replica-private-hint {
649
+ display: flex;
650
+ align-items: center;
651
+ gap: 4px;
652
+ margin-right: auto;
653
+ font-size: 12px;
654
+ color: #8f959e;
655
+ }
656
+ .replica-private-marker {
657
+ flex: none;
658
+ color: #8f959e;
659
+ }
660
+ .replica-private-menu {
661
+ width: 278px;
662
+ max-width: calc(100vw - 24px);
663
+ padding: 12px 16px;
664
+ border-radius: 6px;
665
+ border: 1px solid #dee0e3;
666
+ background: #fff;
667
+ box-shadow: 0 4px 12px rgba(31, 35, 41, 0.12);
668
+ color: #1f2329;
669
+ }
670
+ .replica-private-heading {
671
+ display: flex;
672
+ align-items: center;
673
+ gap: 12px;
674
+ font-size: 14px;
675
+ line-height: 22px;
676
+ }
677
+ .replica-private-menu p {
678
+ margin: 8px 0 0 30px;
679
+ color: #8f959e;
680
+ font-size: 12px;
681
+ line-height: 20px;
682
+ }
683
+ .replica-switch {
684
+ position: relative;
685
+ width: 40px;
686
+ height: 22px;
687
+ padding: 2px;
688
+ border-radius: 11px;
689
+ margin-left: auto;
690
+ background: #bbbfc4;
691
+ flex: none;
692
+ }
693
+ .replica-switch span {
694
+ display: block;
695
+ height: 18px;
696
+ width: 18px;
697
+ border-radius: 50%;
698
+ background: #fff;
699
+ transition: transform 0.15s;
700
+ }
701
+ .replica-switch[aria-checked='true'] {
702
+ background: #1456f0;
703
+ }
704
+ .replica-switch[aria-checked='true'] span {
705
+ transform: translateX(18px);
706
+ }
707
+ .replica-composer-tools [aria-label='评论设置'] {
708
+ margin-left: 8px;
709
+ }
710
+ .replica-action-menu {
711
+ width: 120px;
712
+ padding: 2px 0;
713
+ background: #fff;
714
+ border: 1px solid #dee0e3;
715
+ border-radius: 6px;
716
+ box-shadow:
717
+ 0 8px 24px 8px rgb(31 35 41 / 4%),
718
+ 0 6px 12px rgb(31 35 41 / 4%),
719
+ 0 4px 8px -8px rgb(31 35 41 / 6%);
720
+ }
721
+ .replica-action-menu [role='menu'] {
722
+ display: flex;
723
+ flex-direction: column;
724
+ }
725
+ .replica-action-menu [role='menuitem'] {
726
+ display: flex;
727
+ align-items: center;
728
+ height: 30px;
729
+ padding: 4px 8px;
730
+ margin: 1px 3px;
731
+ width: calc(100% - 6px);
732
+ border-radius: 4px;
733
+ font-size: 14px;
734
+ line-height: 22px;
735
+ }
736
+ .replica-action-menu [role='menuitem']:hover {
737
+ background: #f2f3f5;
738
+ }
739
+ .replica-draft-images {
740
+ display: flex;
741
+ flex-wrap: wrap;
742
+ gap: 4px;
743
+ margin-top: 4px;
744
+ }
745
+ .replica-draft-image {
746
+ width: 64px;
747
+ height: 64px;
748
+ position: relative;
749
+ border: 1px solid #d0d3d6;
750
+ border-radius: 6px;
751
+ overflow: hidden;
752
+ }
753
+ .replica-draft-image img {
754
+ display: block;
755
+ width: 62px;
756
+ height: 62px;
757
+ object-fit: cover;
758
+ border-radius: 5px;
759
+ }
760
+ .replica-draft-image button {
761
+ position: absolute;
762
+ right: 0;
763
+ top: 0;
764
+ width: 24px;
765
+ height: 24px;
766
+ display: grid;
767
+ place-items: center;
768
+ border-radius: 6px;
769
+ color: #fff;
770
+ }
771
+ .replica-draft-image button span {
772
+ width: 18px;
773
+ height: 18px;
774
+ border-radius: 50%;
775
+ display: grid;
776
+ place-items: center;
777
+ background: rgb(31 35 41 / 60%);
778
+ }
779
+ .replica-message-images {
780
+ display: flex;
781
+ flex-wrap: wrap;
782
+ gap: 4px;
783
+ margin-top: 6px;
784
+ }
785
+ .replica-edit-area {
786
+ margin: 12px -2px 0 3px;
787
+ }
788
+ .replica-composer-edit {
789
+ display: grid;
790
+ grid-template-columns: minmax(0, 1fr) 16px;
791
+ align-items: start;
792
+ min-height: 32px;
793
+ background: transparent;
794
+ }
795
+ .replica-composer-edit .replica-input {
796
+ grid-column: 1;
797
+ grid-row: 1;
798
+ }
799
+ .replica-composer-edit .replica-input > div:first-child {
800
+ min-height: 30px;
801
+ padding: 4px 0 4px;
802
+ }
803
+ .replica-composer-edit .replica-composer-toolbar {
804
+ grid-column: 2;
805
+ grid-row: 1;
806
+ min-height: 30px;
807
+ padding: 7px 0;
808
+ margin: 0;
809
+ }
810
+ .replica-composer-edit .replica-draft-images {
811
+ grid-column: 1 / -1;
812
+ margin: 4px 0 8px;
813
+ }
814
+ .replica-edit-actions {
815
+ display: flex;
816
+ justify-content: flex-end;
817
+ gap: 8px;
818
+ margin-top: 12px;
819
+ }
820
+ .replica-edit-actions button {
821
+ min-width: 48px;
822
+ height: 28px;
823
+ border: 1px solid #d0d3d6;
824
+ border-radius: 6px;
825
+ padding: 3px 7px;
826
+ color: #1f2329;
827
+ background: #fff;
828
+ font-size: 12px;
829
+ line-height: 20px;
830
+ }
831
+ .replica-edit-actions button:last-child {
832
+ background: #1456f0;
833
+ color: #fff;
834
+ border-color: #1456f0;
835
+ }
836
+ .replica-edit-actions button:disabled {
837
+ opacity: 0.5;
838
+ }
839
+ .replica-reply-controls[hidden] {
840
+ display: none;
841
+ }
842
+ .replica-reply-linked {
843
+ background: #f5f6ff;
844
+ border-radius: 6px;
845
+ }
846
+
847
+ .replica-message-images button {
848
+ flex: none;
849
+ width: 64px;
850
+ height: 64px;
851
+ padding: 0;
852
+ border: 1px solid #d0d3d6;
853
+ overflow: hidden;
854
+ border-radius: 6px;
855
+ cursor: zoom-in;
856
+ }
857
+ .replica-message-images img {
858
+ display: block;
859
+ width: 62px;
860
+ height: 62px;
861
+ object-fit: cover;
862
+ border-radius: 5px;
863
+ }
864
+ .replica-image-backdrop {
865
+ background: rgb(0 0 0 / 85%);
866
+ }
867
+ .replica-image-viewer {
868
+ position: fixed;
869
+ inset: 0;
870
+ z-index: 51;
871
+ color: #fff;
872
+ outline: none;
873
+ font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', sans-serif;
874
+ }
875
+ .replica-image-canvas {
876
+ position: absolute;
877
+ inset: 0;
878
+ display: flex;
879
+ align-items: center;
880
+ justify-content: center;
881
+ overflow: hidden;
882
+ }
883
+ .replica-image-canvas img {
884
+ flex: none;
885
+ max-width: none;
886
+ cursor: grab;
887
+ touch-action: none;
888
+ user-select: none;
889
+ }
890
+ .replica-image-canvas img:active {
891
+ cursor: grabbing;
892
+ }
893
+ .replica-image-viewer button {
894
+ display: grid;
895
+ place-items: center;
896
+ padding: 0;
897
+ background: transparent;
898
+ color: #fff;
899
+ border: 0;
900
+ border-radius: 4px;
901
+ cursor: pointer;
902
+ }
903
+ .replica-image-viewer button:hover {
904
+ background: rgb(255 255 255 / 15%);
905
+ }
906
+ .replica-image-viewer button:disabled {
907
+ opacity: 0.3;
908
+ cursor: default;
909
+ }
910
+ .replica-image-viewer button:focus-visible {
911
+ outline: 2px solid #fff;
912
+ outline-offset: 2px;
913
+ }
914
+ .replica-viewer-close {
915
+ position: absolute;
916
+ right: 16px;
917
+ top: 16px;
918
+ width: 48px;
919
+ height: 48px;
920
+ }
921
+ .replica-viewer-prev,
922
+ .replica-viewer-next {
923
+ position: absolute;
924
+ top: calc(50% - 24px);
925
+ width: 48px;
926
+ height: 48px;
927
+ }
928
+ .replica-viewer-prev {
929
+ left: 16px;
930
+ }
931
+ .replica-viewer-next {
932
+ right: 16px;
933
+ }
934
+ .replica-viewer-toolbar {
935
+ position: absolute;
936
+ left: 50%;
937
+ bottom: 20px;
938
+ transform: translateX(-50%);
939
+ display: flex;
940
+ align-items: center;
941
+ height: 48px;
942
+ padding: 0 12px;
943
+ background: rgb(0 0 0 / 75%);
944
+ border-radius: 8px;
945
+ font-size: 14px;
946
+ }
947
+ .replica-viewer-toolbar button {
948
+ width: 36px;
949
+ height: 36px;
950
+ flex: none;
951
+ }
952
+ .replica-viewer-toolbar span {
953
+ min-width: 28px;
954
+ text-align: center;
955
+ }
956
+ .replica-viewer-toolbar .replica-viewer-ratio {
957
+ min-width: 48px;
958
+ }
959
+ .replica-viewer-toolbar i {
960
+ height: 16px;
961
+ width: 1px;
962
+ background: rgb(255 255 255 / 24%);
963
+ margin: 0 10px;
964
+ }
965
+ .replica-error {
966
+ color: #d83931;
967
+ font-size: 12px;
968
+ line-height: 20px;
969
+ margin-top: 4px;
970
+ }
971
+ .replica-empty {
972
+ color: #8f959e;
973
+ text-align: center;
974
+ padding: 48px 12px;
975
+ }
976
+ @media (hover: none) {
977
+ .replica-reply-controls {
978
+ visibility: visible;
979
+ }
980
+ }
981
+ @media (prefers-reduced-motion: reduce) {
982
+ .replica-switch span {
983
+ transition: none;
984
+ }
985
+ }
986
+
987
+ .replica-comment-panel {
988
+ display: flex;
989
+ flex-direction: column;
990
+ width: 100%;
991
+ height: 100%;
992
+ min-height: 0;
993
+ }
994
+ .replica-panel-status,
995
+ .replica-panel-pagination {
996
+ display: flex;
997
+ flex-wrap: wrap;
998
+ justify-content: center;
999
+ align-items: center;
1000
+ gap: 8px;
1001
+ padding: 12px 8px;
1002
+ font-size: 12px;
1003
+ color: var(--replica-secondary);
1004
+ }
1005
+ /* Match the existing empty-state footprint in auto-height hosts. Only the
1006
+ read-state slot is sized; populated lists still follow the host's layout. */
1007
+ .replica-comment-panel .replica-discussion-list:has(> .replica-panel-placeholder) {
1008
+ display: flex;
1009
+ flex-direction: column;
1010
+ height: 126px;
1011
+ }
1012
+ .replica-panel-status.replica-panel-placeholder {
1013
+ flex: 1 1 118px;
1014
+ height: 118px;
1015
+ min-height: 0;
1016
+ max-height: 118px;
1017
+ }
1018
+ .replica-panel-placeholder ~ .replica-panel-pagination {
1019
+ flex: 0 1 auto;
1020
+ min-height: 0;
1021
+ max-height: 100%;
1022
+ overflow-y: auto;
1023
+ overflow-wrap: anywhere;
1024
+ }
1025
+ .replica-panel-status-content {
1026
+ display: flex;
1027
+ flex-wrap: wrap;
1028
+ justify-content: center;
1029
+ align-items: center;
1030
+ gap: 8px;
1031
+ max-width: 100%;
1032
+ max-height: 100%;
1033
+ overflow-y: auto;
1034
+ overflow-wrap: anywhere;
1035
+ scrollbar-width: thin;
1036
+ }
1037
+ .replica-panel-placeholder[data-state='empty'] {
1038
+ color: var(--replica-placeholder);
1039
+ font-size: 14px;
1040
+ line-height: 22px;
1041
+ }
1042
+ .replica-panel-status button,
1043
+ .replica-panel-pagination button {
1044
+ color: var(--replica-primary);
1045
+ }
1046
+ .replica-panel-status[role='alert'] { color: #d92d20; }
1047
+ .replica-panel-solved {
1048
+ margin-left: 8px;
1049
+ font-size: 12px;
1050
+ color: var(--replica-secondary);
1051
+ }
1052
+
1053
+ .replica-reply:is([data-mutation-state="failed"], [data-mutation-state="uncertain"]) .replica-author-avatar {
1054
+ opacity: 0.4;
1055
+ }
1056
+ .replica-reply:is([data-mutation-state="failed"], [data-mutation-state="uncertain"]) .replica-author-name,
1057
+ .replica-reply:is([data-mutation-state="failed"], [data-mutation-state="uncertain"]) .replica-reply-body {
1058
+ color: var(--comment-failed-text, #bbbfc4);
1059
+ }
1060
+ .replica-mutation-error {
1061
+ display: flex;
1062
+ align-items: center;
1063
+ gap: 8px;
1064
+ margin-top: 8px;
1065
+ color: var(--muted-foreground);
1066
+ font-size: 12px;
1067
+ line-height: 20px;
1068
+ }
1069
+ .replica-mutation-error svg {
1070
+ flex: none;
1071
+ color: var(--comment-error, #ee5050);
1072
+ }
1073
+ .replica-mutation-error button {
1074
+ margin-left: 4px;
1075
+ color: var(--primary);
1076
+ cursor: pointer;
1077
+ }
1078
+ .replica-mutation-error button:hover {
1079
+ text-decoration: underline;
1080
+ }
1081
+ .replica-mutation-loading {
1082
+ display: inline;
1083
+ position: relative;
1084
+ top: 2px;
1085
+ padding: 5px 0 1px 5px;
1086
+ color: var(--replica-primary, #1456f0);
1087
+ }
1088
+ .replica-mutation-loading > svg {
1089
+ display: inline-block;
1090
+ width: 14px;
1091
+ height: 14px;
1092
+ vertical-align: baseline;
1093
+ animation: replica-mutation-spin 1.2s linear infinite;
1094
+ }
1095
+ .replica-mutation-loading circle {
1096
+ animation: replica-mutation-dash 2.5s ease-in-out infinite;
1097
+ }
1098
+ @keyframes replica-mutation-spin {
1099
+ to { transform: rotate(360deg); }
1100
+ }
1101
+ @keyframes replica-mutation-dash {
1102
+ 0% { stroke-dasharray: 1, 220; stroke-dashoffset: 0; }
1103
+ 50% { stroke-dasharray: 150, 220; stroke-dashoffset: -68; }
1104
+ 100% { stroke-dasharray: 150, 220; stroke-dashoffset: -218; }
1105
+ }
1106
+ @media (prefers-reduced-motion: reduce) {
1107
+ .replica-mutation-loading > svg,
1108
+ .replica-mutation-loading circle { animation: none; }
1109
+ }