@ermis-network/ermis-chat-react 1.0.0

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 (88) hide show
  1. package/dist/index.cjs +6593 -0
  2. package/dist/index.cjs.map +1 -0
  3. package/dist/index.css +3375 -0
  4. package/dist/index.css.map +1 -0
  5. package/dist/index.d.mts +1138 -0
  6. package/dist/index.d.ts +1138 -0
  7. package/dist/index.mjs +6500 -0
  8. package/dist/index.mjs.map +1 -0
  9. package/package.json +42 -0
  10. package/src/components/Avatar.tsx +102 -0
  11. package/src/components/Channel.tsx +77 -0
  12. package/src/components/ChannelHeader.tsx +85 -0
  13. package/src/components/ChannelInfo/AddMemberModal.tsx +204 -0
  14. package/src/components/ChannelInfo/ChannelInfo.tsx +455 -0
  15. package/src/components/ChannelInfo/ChannelInfoTabs.tsx +282 -0
  16. package/src/components/ChannelInfo/ChannelSettingsPanel.tsx +479 -0
  17. package/src/components/ChannelInfo/EditChannelModal.tsx +272 -0
  18. package/src/components/ChannelInfo/FileListItem.tsx +49 -0
  19. package/src/components/ChannelInfo/LinkListItem.tsx +62 -0
  20. package/src/components/ChannelInfo/MediaGridItem.tsx +90 -0
  21. package/src/components/ChannelInfo/MemberListItem.tsx +85 -0
  22. package/src/components/ChannelInfo/MessageSearchPanel.tsx +333 -0
  23. package/src/components/ChannelInfo/States.tsx +36 -0
  24. package/src/components/ChannelInfo/index.ts +10 -0
  25. package/src/components/ChannelInfo/utils.tsx +49 -0
  26. package/src/components/ChannelList.tsx +395 -0
  27. package/src/components/Dropdown.tsx +120 -0
  28. package/src/components/EditPreview.tsx +102 -0
  29. package/src/components/FilesPreview.tsx +108 -0
  30. package/src/components/ForwardMessageModal.tsx +234 -0
  31. package/src/components/MentionSuggestions.tsx +59 -0
  32. package/src/components/MessageActionsBox.tsx +186 -0
  33. package/src/components/MessageInput.tsx +513 -0
  34. package/src/components/MessageInputDefaults.tsx +50 -0
  35. package/src/components/MessageItem.tsx +218 -0
  36. package/src/components/MessageQuickReactions.tsx +73 -0
  37. package/src/components/MessageReactions.tsx +59 -0
  38. package/src/components/MessageRenderers.tsx +565 -0
  39. package/src/components/Modal.tsx +58 -0
  40. package/src/components/Panel.tsx +64 -0
  41. package/src/components/PinnedMessages.tsx +165 -0
  42. package/src/components/QuotedMessagePreview.tsx +55 -0
  43. package/src/components/ReadReceipts.tsx +80 -0
  44. package/src/components/ReplyPreview.tsx +98 -0
  45. package/src/components/TypingIndicator.tsx +57 -0
  46. package/src/components/VirtualMessageList.tsx +425 -0
  47. package/src/context/ChatProvider.tsx +73 -0
  48. package/src/hooks/useBannedState.ts +48 -0
  49. package/src/hooks/useBlockedState.ts +55 -0
  50. package/src/hooks/useChannel.ts +18 -0
  51. package/src/hooks/useChannelCapabilities.ts +42 -0
  52. package/src/hooks/useChannelData.ts +55 -0
  53. package/src/hooks/useChannelListUpdates.ts +224 -0
  54. package/src/hooks/useChannelMessages.ts +159 -0
  55. package/src/hooks/useChannelRowUpdates.ts +78 -0
  56. package/src/hooks/useChatClient.ts +11 -0
  57. package/src/hooks/useEmojiPicker.ts +53 -0
  58. package/src/hooks/useFileUpload.ts +128 -0
  59. package/src/hooks/useLoadMessages.ts +178 -0
  60. package/src/hooks/useMentions.ts +287 -0
  61. package/src/hooks/useMessageActions.ts +87 -0
  62. package/src/hooks/useMessageSend.ts +164 -0
  63. package/src/hooks/usePendingState.ts +63 -0
  64. package/src/hooks/useScrollToMessage.ts +155 -0
  65. package/src/hooks/useTypingIndicator.ts +86 -0
  66. package/src/index.ts +129 -0
  67. package/src/styles/_add-member-modal.css +122 -0
  68. package/src/styles/_base.css +32 -0
  69. package/src/styles/_channel-info.css +941 -0
  70. package/src/styles/_channel-list.css +217 -0
  71. package/src/styles/_dropdown.css +69 -0
  72. package/src/styles/_forward-modal.css +191 -0
  73. package/src/styles/_mentions.css +102 -0
  74. package/src/styles/_message-actions.css +61 -0
  75. package/src/styles/_message-bubble.css +656 -0
  76. package/src/styles/_message-input.css +389 -0
  77. package/src/styles/_message-list.css +416 -0
  78. package/src/styles/_message-quick-reactions.css +62 -0
  79. package/src/styles/_message-reactions.css +67 -0
  80. package/src/styles/_modal.css +113 -0
  81. package/src/styles/_panel.css +69 -0
  82. package/src/styles/_pinned-messages.css +140 -0
  83. package/src/styles/_search-panel.css +219 -0
  84. package/src/styles/_tokens.css +92 -0
  85. package/src/styles/_typing-indicator.css +59 -0
  86. package/src/styles/index.css +24 -0
  87. package/src/types.ts +955 -0
  88. package/src/utils.ts +242 -0
@@ -0,0 +1,416 @@
1
+ /* ----------------------------------------------------------
2
+ Channel
3
+ ---------------------------------------------------------- */
4
+ .ermis-channel {
5
+ display: flex;
6
+ flex-direction: column;
7
+ flex: 1;
8
+ min-height: 0;
9
+ font-family: var(--ermis-font-family);
10
+ }
11
+
12
+ .ermis-channel__empty {
13
+ display: flex;
14
+ align-items: center;
15
+ justify-content: center;
16
+ flex: 1;
17
+ color: var(--ermis-text-muted);
18
+ font-size: var(--ermis-font-size-sm);
19
+ font-family: var(--ermis-font-family);
20
+ }
21
+
22
+ /* ----------------------------------------------------------
23
+ MessageList
24
+ ---------------------------------------------------------- */
25
+ .ermis-message-list {
26
+ display: flex;
27
+ flex-direction: column;
28
+ flex: 1;
29
+ font-family: var(--ermis-font-family);
30
+ gap: var(--ermis-spacing-xs);
31
+ position: relative;
32
+ }
33
+
34
+ .ermis-message-list__vlist {
35
+ display: flex !important;
36
+ flex-direction: column !important;
37
+ padding-left: 3rem;
38
+ padding-right: 3rem;
39
+ padding-top: var(--ermis-spacing-lg);
40
+ padding-bottom: var(--ermis-spacing-lg);
41
+ }
42
+
43
+ /* Push content to bottom when few messages, margin collapses when content overflows */
44
+ .ermis-message-list__vlist > div {
45
+ margin-top: auto;
46
+ }
47
+
48
+ /* Jump to latest button */
49
+ .ermis-message-list__jump-latest {
50
+ position: sticky;
51
+ bottom: var(--ermis-spacing-md);
52
+ align-self: center;
53
+ padding: var(--ermis-spacing-xs) var(--ermis-spacing-lg);
54
+ border: none;
55
+ border-radius: 999px;
56
+ background-color: var(--ermis-accent);
57
+ color: #fff;
58
+ font-size: var(--ermis-font-size-xs);
59
+ font-weight: 600;
60
+ font-family: var(--ermis-font-family);
61
+ cursor: pointer;
62
+ transition: background-color var(--ermis-transition), transform var(--ermis-transition);
63
+ z-index: 10;
64
+ }
65
+
66
+ .ermis-message-list__jump-latest:hover {
67
+ background-color: var(--ermis-accent-hover);
68
+ transform: translateY(-1px);
69
+ }
70
+
71
+ /* Pushes messages to bottom when few messages exist */
72
+ .ermis-message-list__spacer {
73
+ flex: 1;
74
+ }
75
+
76
+ /* --- Load more (pagination) --- */
77
+ .ermis-message-list__loading-more {
78
+ text-align: center;
79
+ padding: var(--ermis-spacing-sm);
80
+ color: var(--ermis-text-muted);
81
+ font-size: var(--ermis-font-size-xs);
82
+ }
83
+
84
+ .ermis-message-list__no-more {
85
+ text-align: center;
86
+ padding: var(--ermis-spacing-sm);
87
+ color: var(--ermis-text-muted);
88
+ font-size: var(--ermis-font-size-xs);
89
+ font-style: italic;
90
+ }
91
+
92
+ /* --- Date separator --- */
93
+ .ermis-message-list__date-separator {
94
+ display: flex;
95
+ align-items: center;
96
+ gap: var(--ermis-spacing-md);
97
+ padding: var(--ermis-spacing-md) 0;
98
+ margin: var(--ermis-spacing-xs) 0;
99
+ align-self: stretch;
100
+ }
101
+
102
+ .ermis-message-list__date-separator-line {
103
+ flex: 1;
104
+ height: 1px;
105
+ background-color: var(--ermis-border);
106
+ }
107
+
108
+ .ermis-message-list__date-separator-label {
109
+ font-size: var(--ermis-font-size-xs);
110
+ color: var(--ermis-text-muted);
111
+ white-space: nowrap;
112
+ font-weight: 500;
113
+ }
114
+
115
+ .ermis-message-list__empty {
116
+ display: flex;
117
+ flex-direction: column;
118
+ align-items: center;
119
+ justify-content: center;
120
+ flex: 1;
121
+ gap: var(--ermis-spacing-sm);
122
+ color: var(--ermis-text-muted);
123
+ font-family: var(--ermis-font-family);
124
+ padding: var(--ermis-spacing-lg);
125
+ user-select: none;
126
+ }
127
+
128
+ .ermis-message-list__empty-icon {
129
+ color: var(--ermis-accent);
130
+ opacity: 0.4;
131
+ margin-bottom: var(--ermis-spacing-xs);
132
+ }
133
+
134
+ .ermis-message-list__empty-title {
135
+ font-size: var(--ermis-font-size-base);
136
+ font-weight: 600;
137
+ color: var(--ermis-text-secondary);
138
+ }
139
+
140
+ .ermis-message-list__empty-subtitle {
141
+ font-size: var(--ermis-font-size-sm);
142
+ color: var(--ermis-text-muted);
143
+ }
144
+
145
+ /* --- Message item (other = left, own = right) --- */
146
+ .ermis-message-list__item {
147
+ display: flex;
148
+ align-items: flex-start;
149
+ gap: var(--ermis-spacing-sm);
150
+ width: 100%;
151
+ }
152
+
153
+ /* First message in a group: normal top margin */
154
+ .ermis-message-list__item--group-start {
155
+ padding-top: var(--ermis-spacing-md);
156
+ }
157
+
158
+ /* Continuation messages in a group: tight spacing */
159
+ .ermis-message-list__item--group-cont {
160
+ padding-top: 2px;
161
+ }
162
+
163
+ .ermis-message-list__item--other {
164
+ align-self: flex-start;
165
+ flex-direction: row;
166
+ }
167
+
168
+ .ermis-message-list__item--own {
169
+ align-self: flex-end;
170
+ flex-direction: row-reverse;
171
+ }
172
+
173
+ @keyframes ermis-highlight-fade {
174
+ 0% {
175
+ background-color: rgba(99, 102, 241, 0.15);
176
+ }
177
+ 100% {
178
+ background-color: transparent;
179
+ }
180
+ }
181
+
182
+ /* --- Fade-in animation for new messages --- */
183
+ /* Smooth scroll handles the "slide-up" for the entire list;
184
+ individual items only need a subtle fade-in. */
185
+ @keyframes ermis-message-fade-in {
186
+ 0% {
187
+ opacity: 0;
188
+ }
189
+ 100% {
190
+ opacity: 1;
191
+ }
192
+ }
193
+
194
+ .ermis-message-list__item--new {
195
+ animation: ermis-message-fade-in 0.35s ease-out forwards;
196
+ }
197
+
198
+ .ermis-message-list__item--highlighted {
199
+ position: relative;
200
+ }
201
+
202
+ .ermis-message-list__item--highlighted::before {
203
+ content: '';
204
+ position: absolute;
205
+ top: 0;
206
+ bottom: 0;
207
+ left: -3rem;
208
+ right: -3rem;
209
+ animation: ermis-highlight-fade 3s ease-out forwards;
210
+ pointer-events: none;
211
+ z-index: -1;
212
+ }
213
+
214
+ /* --- Optimistic UI: message status --- */
215
+ .ermis-message--sending {
216
+ opacity: 0.6;
217
+ pointer-events: none;
218
+ }
219
+
220
+ .ermis-message--error .ermis-message-bubble {
221
+ border: 1px solid #e74c3c;
222
+ }
223
+
224
+ /* --- Pinned Message Indicator --- */
225
+ .ermis-message-list__pinned-indicator {
226
+ position: absolute;
227
+ top: -5px;
228
+ color: #e74c3c;
229
+ z-index: 10;
230
+ pointer-events: none;
231
+ display: flex;
232
+ align-items: center;
233
+ justify-content: center;
234
+ padding: 0;
235
+ }
236
+
237
+ .ermis-message-list__pinned-indicator--own {
238
+ left: -10px;
239
+ transform: rotate(-45deg);
240
+ }
241
+
242
+ .ermis-message-list__pinned-indicator--other {
243
+ right: -10px;
244
+ transform: rotate(45deg);
245
+ }
246
+
247
+ /* ----------------------------------------------------------
248
+ Banned State
249
+ ---------------------------------------------------------- */
250
+
251
+ .ermis-message-list__banned-overlay {
252
+ display: flex;
253
+ flex-direction: column;
254
+ align-items: center;
255
+ justify-content: center;
256
+ min-height: calc(100dvh - 8rem);
257
+ gap: var(--ermis-spacing-md);
258
+ user-select: none;
259
+ }
260
+
261
+ .ermis-message-list__banned-overlay-icon {
262
+ color: #ef4444;
263
+ opacity: 0.6;
264
+ }
265
+
266
+ .ermis-message-list__banned-overlay-title {
267
+ font-size: var(--ermis-font-size-base);
268
+ font-weight: 600;
269
+ color: var(--ermis-text-primary);
270
+ }
271
+
272
+ .ermis-message-list__banned-overlay-subtitle {
273
+ font-size: var(--ermis-font-size-sm);
274
+ color: var(--ermis-text-muted);
275
+ }
276
+
277
+ /* ----------------------------------------------------------
278
+ Blocked State (messaging channels — user-initiated block)
279
+ Messages remain visible but actions are disabled.
280
+ ---------------------------------------------------------- */
281
+ .ermis-message-list--blocked .ermis-message-actions {
282
+ display: none;
283
+ }
284
+
285
+ .ermis-message-list--blocked .ermis-message-reactions__add-btn {
286
+ display: none;
287
+ }
288
+
289
+ /* Unblock button inside blocked overlay */
290
+ .ermis-message-list__unblock-btn {
291
+ margin-top: var(--ermis-spacing-md);
292
+ padding: var(--ermis-spacing-sm) var(--ermis-spacing-xl, 24px);
293
+ border: none;
294
+ border-radius: var(--ermis-radius-md, 8px);
295
+ background-color: var(--ermis-accent);
296
+ color: #fff;
297
+ font-size: var(--ermis-font-size-sm);
298
+ font-weight: 600;
299
+ font-family: var(--ermis-font-family);
300
+ cursor: pointer;
301
+ transition: background-color var(--ermis-transition), transform var(--ermis-transition);
302
+ }
303
+
304
+ .ermis-message-list__unblock-btn:hover {
305
+ background-color: var(--ermis-accent-hover);
306
+ transform: translateY(-1px);
307
+ }
308
+
309
+ .ermis-message-list__unblock-btn:active {
310
+ transform: translateY(0);
311
+ }
312
+
313
+ /* Pending Overlay */
314
+ .ermis-message-list__pending-overlay {
315
+ display: flex;
316
+ align-items: center;
317
+ justify-content: center;
318
+ min-height: calc(100dvh - 8rem);
319
+ padding: var(--ermis-spacing-xl);
320
+ }
321
+
322
+ .ermis-message-list__pending-card {
323
+ background-color: var(--ermis-bg-elevated, #ffffff);
324
+ border-radius: var(--ermis-radius-lg, 12px);
325
+ padding: var(--ermis-spacing-xxl, 32px);
326
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
327
+ display: flex;
328
+ flex-direction: column;
329
+ align-items: center;
330
+ text-align: center;
331
+ max-width: 400px;
332
+ width: 100%;
333
+ }
334
+
335
+ .ermis-message-list__pending-avatar {
336
+ margin-bottom: var(--ermis-spacing-lg, 16px);
337
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
338
+ }
339
+
340
+ .ermis-message-list__pending-overlay-title {
341
+ font-family: var(--ermis-font-family, sans-serif);
342
+ font-size: var(--ermis-font-size-md, 14px);
343
+ font-weight: 500;
344
+ color: var(--ermis-text-secondary, #666);
345
+ margin-bottom: var(--ermis-spacing-xs, 4px);
346
+ text-transform: uppercase;
347
+ letter-spacing: 0.5px;
348
+ }
349
+
350
+ .ermis-message-list__pending-channel-name {
351
+ font-family: var(--ermis-font-family, sans-serif);
352
+ font-size: var(--ermis-font-size-xl, 20px);
353
+ font-weight: 700;
354
+ color: var(--ermis-text, #333);
355
+ margin-bottom: var(--ermis-spacing-sm, 8px);
356
+ }
357
+
358
+ .ermis-message-list__pending-overlay-subtitle {
359
+ font-family: var(--ermis-font-family, sans-serif);
360
+ font-size: var(--ermis-font-size-sm, 14px);
361
+ color: var(--ermis-text-secondary, #666);
362
+ margin-bottom: var(--ermis-spacing-xl, 24px);
363
+ line-height: 1.5;
364
+ }
365
+
366
+ .ermis-message-list__pending-actions {
367
+ display: flex;
368
+ gap: var(--ermis-spacing-md, 12px);
369
+ width: 100%;
370
+ }
371
+
372
+ .ermis-message-list__accept-btn,
373
+ .ermis-message-list__reject-btn {
374
+ flex: 1;
375
+ padding: var(--ermis-spacing-sm, 10px) var(--ermis-spacing-md, 16px);
376
+ border-radius: var(--ermis-radius-md, 8px);
377
+ font-family: var(--ermis-font-family, sans-serif);
378
+ font-size: var(--ermis-font-size-md, 15px);
379
+ font-weight: 600;
380
+ cursor: pointer;
381
+ transition: all var(--ermis-transition, 0.2s ease);
382
+ }
383
+
384
+ .ermis-message-list__accept-btn {
385
+ border: none;
386
+ background-color: var(--ermis-accent, #005fff);
387
+ color: #fff;
388
+ box-shadow: 0 4px 10px rgba(0, 95, 255, 0.2);
389
+ }
390
+
391
+ .ermis-message-list__accept-btn:hover {
392
+ background-color: var(--ermis-accent-hover, #004ecc);
393
+ transform: translateY(-2px);
394
+ box-shadow: 0 6px 14px rgba(0, 95, 255, 0.3);
395
+ }
396
+
397
+ .ermis-message-list__accept-btn:active {
398
+ transform: translateY(0);
399
+ }
400
+
401
+ .ermis-message-list__reject-btn {
402
+ border: 1px solid var(--ermis-danger-border, #fecaca);
403
+ background-color: var(--ermis-danger-soft, #fef2f2);
404
+ color: var(--ermis-danger, #ef4444);
405
+ }
406
+
407
+ .ermis-message-list__reject-btn:hover {
408
+ background-color: var(--ermis-danger, #ef4444);
409
+ color: #fff;
410
+ border-color: var(--ermis-danger, #ef4444);
411
+ transform: translateY(-2px);
412
+ box-shadow: 0 6px 14px rgba(239, 68, 68, 0.3);
413
+ }
414
+ .ermis-message-list__reject-btn:active {
415
+ transform: translateY(0);
416
+ }
@@ -0,0 +1,62 @@
1
+ /* ============================================================
2
+ Message Quick Reactions (Hover popup)
3
+ ============================================================ */
4
+
5
+ .ermis-message-quick-reactions {
6
+ position: absolute;
7
+ bottom: calc(100% - 10px); /* hover right above the bubble */
8
+ display: flex;
9
+ align-items: center;
10
+ gap: 2px;
11
+ background-color: var(--ermis-bg-primary);
12
+ border: 1px solid var(--ermis-border);
13
+ padding: 4px;
14
+ border-radius: 20px;
15
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
16
+ opacity: 0;
17
+ visibility: hidden;
18
+ pointer-events: none;
19
+ transform: translateY(8px);
20
+ transition: opacity 0.2s ease, transform 0.2s ease;
21
+ z-index: 20;
22
+ }
23
+
24
+ /* Align based on ownership */
25
+ .ermis-message-quick-reactions {
26
+ left: 0;
27
+ }
28
+ .ermis-message-quick-reactions--own {
29
+ left: auto;
30
+ right: 0;
31
+ }
32
+
33
+ .ermis-message-list__bubble-wrapper:hover .ermis-message-quick-reactions {
34
+ opacity: 1;
35
+ visibility: visible;
36
+ pointer-events: auto;
37
+ transform: translateY(0);
38
+ }
39
+
40
+ .ermis-message-quick-reactions__btn {
41
+ display: flex;
42
+ align-items: center;
43
+ justify-content: center;
44
+ background: none;
45
+ border: none;
46
+ font-size: 18px;
47
+ line-height: 1;
48
+ width: 32px;
49
+ height: 32px;
50
+ border-radius: 50%;
51
+ cursor: pointer;
52
+ transition: transform 0.15s cubic-bezier(0.175, 0.885, 0.32, 1.275), background-color 0.15s;
53
+ }
54
+
55
+ .ermis-message-quick-reactions__btn:hover {
56
+ transform: scale(1.2);
57
+ background-color: var(--ermis-bg-hover);
58
+ }
59
+
60
+ .ermis-message-quick-reactions__btn--active {
61
+ background-color: var(--ermis-bg-active, rgba(99, 102, 241, 0.12));
62
+ }
@@ -0,0 +1,67 @@
1
+ /* ============================================================
2
+ Message Reactions
3
+ ============================================================ */
4
+ .ermis-message-reactions {
5
+ display: flex;
6
+ flex-wrap: wrap;
7
+ gap: 4px;
8
+ margin-bottom: 2px;
9
+ }
10
+
11
+ .ermis-message-reactions__item {
12
+ position: relative; /* For tooltip */
13
+ display: inline-flex;
14
+ align-items: center;
15
+ gap: 4px;
16
+ padding: 2px 6px;
17
+ border-radius: 12px;
18
+ background-color: var(--ermis-surface);
19
+ border: 1px solid var(--ermis-border);
20
+ font-size: 11px;
21
+ line-height: 1.2;
22
+ color: var(--ermis-text-secondary);
23
+ cursor: pointer;
24
+ transition: all 0.2s ease;
25
+ user-select: none;
26
+ }
27
+
28
+ /* Custom Tooltip */
29
+ .ermis-message-reactions__item::after {
30
+ content: attr(data-tooltip);
31
+ position: absolute;
32
+ bottom: 100%;
33
+ left: 50%;
34
+ transform: translateX(-50%);
35
+ background-color: rgba(0, 0, 0, 0.75);
36
+ color: #fff;
37
+ padding: 4px 8px;
38
+ border-radius: 6px;
39
+ font-size: 11px;
40
+ white-space: pre;
41
+ text-align: left;
42
+ pointer-events: none;
43
+ opacity: 0;
44
+ visibility: hidden;
45
+ transition: opacity 0.2s, visibility 0.2s;
46
+ margin-bottom: 6px;
47
+ z-index: 100;
48
+ }
49
+
50
+ .ermis-message-reactions__item:hover::after {
51
+ opacity: 1;
52
+ visibility: visible;
53
+ }
54
+
55
+ .ermis-message-reactions__item--active {
56
+ background-color: var(--ermis-bg-active, rgba(99, 102, 241, 0.12));
57
+ border-color: var(--ermis-accent);
58
+ color: var(--ermis-accent);
59
+ }
60
+
61
+ .ermis-message-reactions__emoji {
62
+ font-size: 14px;
63
+ }
64
+
65
+ .ermis-message-reactions__count {
66
+ font-weight: 600;
67
+ }
@@ -0,0 +1,113 @@
1
+ .ermis-modal-overlay {
2
+ position: fixed;
3
+ top: 0;
4
+ left: 0;
5
+ width: 100vw;
6
+ height: 100vh;
7
+ z-index: 1000;
8
+ background-color: rgba(0, 0, 0, 0.5);
9
+ backdrop-filter: blur(4px);
10
+ display: flex;
11
+ align-items: center;
12
+ justify-content: center;
13
+ animation: ermis-modal-fade-in 0.2s ease-out;
14
+ }
15
+
16
+ @keyframes ermis-modal-fade-in {
17
+ from { opacity: 0; }
18
+ to { opacity: 1; }
19
+ }
20
+
21
+ .ermis-modal-content {
22
+ background-color: var(--ermis-bg-surface, #ffffff);
23
+ border-radius: 12px;
24
+ width: 90%;
25
+ max-width: 480px;
26
+ max-height: 85vh;
27
+ display: flex;
28
+ flex-direction: column;
29
+ box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
30
+ overflow: hidden;
31
+ animation: ermis-modal-slide-up 0.2s cubic-bezier(0.16, 1, 0.3, 1);
32
+ border: 1px solid var(--ermis-border-color, #eaeaea);
33
+ }
34
+
35
+ [data-theme='dark'] .ermis-modal-content {
36
+ background-color: var(--ermis-bg-surface, #1e1e1e);
37
+ border: 1px solid var(--ermis-border-color, #333333);
38
+ }
39
+
40
+ @keyframes ermis-modal-slide-up {
41
+ from { opacity: 0; transform: translateY(20px) scale(0.98); }
42
+ to { opacity: 1; transform: translateY(0) scale(1); }
43
+ }
44
+
45
+ .ermis-modal-header {
46
+ padding: 16px 20px;
47
+ border-bottom: 1px solid var(--ermis-border-color, #eaeaea);
48
+ display: flex;
49
+ align-items: center;
50
+ justify-content: space-between;
51
+ flex-shrink: 0;
52
+ }
53
+
54
+ [data-theme='dark'] .ermis-modal-header {
55
+ border-bottom: 1px solid var(--ermis-border-color, #333333);
56
+ }
57
+
58
+ .ermis-modal-header h3 {
59
+ margin: 0;
60
+ font-size: 16px;
61
+ font-weight: 600;
62
+ color: var(--ermis-text-primary, #000000);
63
+ }
64
+
65
+ [data-theme='dark'] .ermis-modal-header h3 {
66
+ color: var(--ermis-text-primary, #ffffff);
67
+ }
68
+
69
+ .ermis-modal-close {
70
+ background: transparent;
71
+ border: none;
72
+ cursor: pointer;
73
+ color: var(--ermis-text-secondary, #666666);
74
+ padding: 4px;
75
+ border-radius: 4px;
76
+ display: flex;
77
+ align-items: center;
78
+ justify-content: center;
79
+ transition: background-color 0.15s ease, color 0.15s ease;
80
+ }
81
+
82
+ .ermis-modal-close:hover {
83
+ background-color: var(--ermis-bg-hover, #f0f0f0);
84
+ color: var(--ermis-text-primary, #000000);
85
+ }
86
+
87
+ [data-theme='dark'] .ermis-modal-close:hover {
88
+ background-color: var(--ermis-bg-hover, #2a2a2a);
89
+ color: var(--ermis-text-primary, #ffffff);
90
+ }
91
+
92
+ .ermis-modal-body {
93
+ padding: 20px;
94
+ display: flex;
95
+ flex-direction: column;
96
+ overflow: hidden;
97
+ flex: 1;
98
+ }
99
+
100
+ .ermis-modal-footer {
101
+ padding: 16px 20px;
102
+ border-top: 1px solid var(--ermis-border-color, #eaeaea);
103
+ display: flex;
104
+ justify-content: flex-end;
105
+ gap: 12px;
106
+ flex-shrink: 0;
107
+ background-color: var(--ermis-bg-base, #f9f9f9);
108
+ }
109
+
110
+ [data-theme='dark'] .ermis-modal-footer {
111
+ border-top: 1px solid var(--ermis-border-color, #333333);
112
+ background-color: var(--ermis-bg-base, #121212);
113
+ }
@@ -0,0 +1,69 @@
1
+ /* ==========================================================================
2
+ Panel — Reusable sliding overlay panel
3
+ ========================================================================== */
4
+
5
+ .ermis-panel {
6
+ position: absolute;
7
+ inset: 0;
8
+ z-index: 30;
9
+ display: flex;
10
+ flex-direction: column;
11
+ background: var(--ermis-bg-primary, #fff);
12
+ transform: translateX(100%);
13
+ transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
14
+ will-change: transform;
15
+ overflow: hidden;
16
+ }
17
+
18
+ .ermis-panel--open {
19
+ transform: translateX(0);
20
+ }
21
+
22
+ /* Header */
23
+ .ermis-panel__header {
24
+ display: flex;
25
+ align-items: center;
26
+ gap: 8px;
27
+ padding: 12px 16px;
28
+ border-bottom: 1px solid var(--ermis-border, rgba(0, 0, 0, 0.08));
29
+ flex-shrink: 0;
30
+ }
31
+
32
+ .ermis-panel__back {
33
+ display: flex;
34
+ align-items: center;
35
+ justify-content: center;
36
+ width: 32px;
37
+ height: 32px;
38
+ border: none;
39
+ background: none;
40
+ color: var(--ermis-text-secondary);
41
+ cursor: pointer;
42
+ border-radius: 8px;
43
+ flex-shrink: 0;
44
+ transition: background 0.15s, color 0.15s;
45
+ }
46
+
47
+ .ermis-panel__back:hover {
48
+ background: var(--ermis-bg-hover);
49
+ color: var(--ermis-text-primary);
50
+ }
51
+
52
+ .ermis-panel__title {
53
+ font-size: 15px;
54
+ font-weight: 600;
55
+ color: var(--ermis-text-primary);
56
+ margin: 0;
57
+ white-space: nowrap;
58
+ overflow: hidden;
59
+ text-overflow: ellipsis;
60
+ }
61
+
62
+ /* Body */
63
+ .ermis-panel__body {
64
+ flex: 1;
65
+ display: flex;
66
+ flex-direction: column;
67
+ overflow-y: auto;
68
+ overflow-x: hidden;
69
+ }