@ermis-network/ermis-chat-react 1.0.1 → 1.0.3

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 (38) hide show
  1. package/dist/index.cjs +2501 -1249
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.css +1231 -134
  4. package/dist/index.css.map +1 -1
  5. package/dist/index.d.mts +306 -2
  6. package/dist/index.d.ts +306 -2
  7. package/dist/index.mjs +2427 -1181
  8. package/dist/index.mjs.map +1 -1
  9. package/package.json +2 -2
  10. package/src/components/ChannelHeader.tsx +50 -9
  11. package/src/components/ChannelInfo/AddMemberModal.tsx +48 -174
  12. package/src/components/ChannelList.tsx +9 -3
  13. package/src/components/CreateChannelModal.tsx +274 -0
  14. package/src/components/ErmisCallProvider.tsx +279 -0
  15. package/src/components/ErmisCallUI.tsx +634 -0
  16. package/src/components/MessageRenderers.tsx +37 -10
  17. package/src/components/Modal.tsx +2 -1
  18. package/src/components/UserPicker.tsx +377 -0
  19. package/src/context/ChatProvider.tsx +49 -1
  20. package/src/context/ErmisCallContext.tsx +37 -0
  21. package/src/hooks/useCallContext.ts +10 -0
  22. package/src/index.ts +27 -0
  23. package/src/styles/_add-member-modal.css +12 -29
  24. package/src/styles/_call-ui.css +743 -0
  25. package/src/styles/_channel-info.css +34 -34
  26. package/src/styles/_channel-list.css +7 -7
  27. package/src/styles/_create-channel-modal.css +183 -0
  28. package/src/styles/_message-bubble.css +108 -16
  29. package/src/styles/_message-input.css +4 -4
  30. package/src/styles/_message-list.css +11 -11
  31. package/src/styles/_modal.css +23 -36
  32. package/src/styles/_panel.css +1 -1
  33. package/src/styles/_search-panel.css +9 -9
  34. package/src/styles/_tokens.css +42 -0
  35. package/src/styles/_typing-indicator.css +15 -2
  36. package/src/styles/_user-picker.css +268 -0
  37. package/src/styles/index.css +3 -0
  38. package/src/types.ts +293 -1
@@ -344,7 +344,7 @@
344
344
  justify-content: center;
345
345
  gap: var(--ermis-spacing-sm);
346
346
  padding: var(--ermis-spacing-md) var(--ermis-spacing-lg);
347
- color: var(--ermis-text-secondary, #9ca3af);
347
+ color: var(--ermis-text-secondary);
348
348
  font-size: var(--ermis-font-size-sm);
349
349
  font-weight: 500;
350
350
  user-select: none;
@@ -360,14 +360,14 @@
360
360
  ---------------------------------------------------------- */
361
361
  .ermis-message-input__keyword-banner {
362
362
  padding: var(--ermis-spacing-sm) var(--ermis-spacing-md);
363
- background-color: var(--ermis-bg-danger-light, #fee2e2);
363
+ background-color: var(--ermis-bg-hover);
364
364
  border-radius: var(--ermis-radius-md) var(--ermis-radius-md) 0 0;
365
365
  font-size: var(--ermis-font-size-sm, 13px);
366
- color: var(--ermis-text-danger, #ef4444);
366
+ color: var(--ermis-color-danger);
367
367
  display: flex;
368
368
  align-items: center;
369
369
  gap: var(--ermis-spacing-sm);
370
- border-bottom: 1px solid var(--ermis-border-danger, #fca5a5);
370
+ border-bottom: 1px solid var(--ermis-color-danger);
371
371
  }
372
372
 
373
373
  .ermis-message-input__permission-banner,
@@ -320,7 +320,7 @@
320
320
  }
321
321
 
322
322
  .ermis-message-list__pending-card {
323
- background-color: var(--ermis-bg-elevated, #ffffff);
323
+ background-color: var(--ermis-bg-primary);
324
324
  border-radius: var(--ermis-radius-lg, 12px);
325
325
  padding: var(--ermis-spacing-xxl, 32px);
326
326
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
@@ -341,7 +341,7 @@
341
341
  font-family: var(--ermis-font-family, sans-serif);
342
342
  font-size: var(--ermis-font-size-md, 14px);
343
343
  font-weight: 500;
344
- color: var(--ermis-text-secondary, #666);
344
+ color: var(--ermis-text-secondary);
345
345
  margin-bottom: var(--ermis-spacing-xs, 4px);
346
346
  text-transform: uppercase;
347
347
  letter-spacing: 0.5px;
@@ -351,14 +351,14 @@
351
351
  font-family: var(--ermis-font-family, sans-serif);
352
352
  font-size: var(--ermis-font-size-xl, 20px);
353
353
  font-weight: 700;
354
- color: var(--ermis-text, #333);
354
+ color: var(--ermis-text-primary);
355
355
  margin-bottom: var(--ermis-spacing-sm, 8px);
356
356
  }
357
357
 
358
358
  .ermis-message-list__pending-overlay-subtitle {
359
359
  font-family: var(--ermis-font-family, sans-serif);
360
360
  font-size: var(--ermis-font-size-sm, 14px);
361
- color: var(--ermis-text-secondary, #666);
361
+ color: var(--ermis-text-secondary);
362
362
  margin-bottom: var(--ermis-spacing-xl, 24px);
363
363
  line-height: 1.5;
364
364
  }
@@ -383,13 +383,13 @@
383
383
 
384
384
  .ermis-message-list__accept-btn {
385
385
  border: none;
386
- background-color: var(--ermis-accent, #005fff);
386
+ background-color: var(--ermis-accent);
387
387
  color: #fff;
388
388
  box-shadow: 0 4px 10px rgba(0, 95, 255, 0.2);
389
389
  }
390
390
 
391
391
  .ermis-message-list__accept-btn:hover {
392
- background-color: var(--ermis-accent-hover, #004ecc);
392
+ background-color: var(--ermis-accent-hover);
393
393
  transform: translateY(-2px);
394
394
  box-shadow: 0 6px 14px rgba(0, 95, 255, 0.3);
395
395
  }
@@ -399,15 +399,15 @@
399
399
  }
400
400
 
401
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);
402
+ border: 1px solid var(--ermis-color-danger);
403
+ background-color: var(--ermis-bg-hover);
404
+ color: var(--ermis-color-danger);
405
405
  }
406
406
 
407
407
  .ermis-message-list__reject-btn:hover {
408
- background-color: var(--ermis-danger, #ef4444);
408
+ background-color: var(--ermis-color-danger);
409
409
  color: #fff;
410
- border-color: var(--ermis-danger, #ef4444);
410
+ border-color: var(--ermis-color-danger);
411
411
  transform: translateY(-2px);
412
412
  box-shadow: 0 6px 14px rgba(239, 68, 68, 0.3);
413
413
  }
@@ -14,12 +14,16 @@
14
14
  }
15
15
 
16
16
  @keyframes ermis-modal-fade-in {
17
- from { opacity: 0; }
18
- to { opacity: 1; }
17
+ from {
18
+ opacity: 0;
19
+ }
20
+ to {
21
+ opacity: 1;
22
+ }
19
23
  }
20
24
 
21
25
  .ermis-modal-content {
22
- background-color: var(--ermis-bg-surface, #ffffff);
26
+ background-color: var(--ermis-bg-primary);
23
27
  border-radius: 12px;
24
28
  width: 90%;
25
29
  max-width: 480px;
@@ -29,48 +33,41 @@
29
33
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
30
34
  overflow: hidden;
31
35
  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);
36
+ border: 1px solid var(--ermis-border);
38
37
  }
39
38
 
40
39
  @keyframes ermis-modal-slide-up {
41
- from { opacity: 0; transform: translateY(20px) scale(0.98); }
42
- to { opacity: 1; transform: translateY(0) scale(1); }
40
+ from {
41
+ opacity: 0;
42
+ transform: translateY(20px) scale(0.98);
43
+ }
44
+ to {
45
+ opacity: 1;
46
+ transform: translateY(0) scale(1);
47
+ }
43
48
  }
44
49
 
45
50
  .ermis-modal-header {
46
51
  padding: 16px 20px;
47
- border-bottom: 1px solid var(--ermis-border-color, #eaeaea);
52
+ border-bottom: 1px solid var(--ermis-border);
48
53
  display: flex;
49
54
  align-items: center;
50
55
  justify-content: space-between;
51
56
  flex-shrink: 0;
52
57
  }
53
58
 
54
- [data-theme='dark'] .ermis-modal-header {
55
- border-bottom: 1px solid var(--ermis-border-color, #333333);
56
- }
57
-
58
59
  .ermis-modal-header h3 {
59
60
  margin: 0;
60
61
  font-size: 16px;
61
62
  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);
63
+ color: var(--ermis-text-primary);
67
64
  }
68
65
 
69
66
  .ermis-modal-close {
70
67
  background: transparent;
71
68
  border: none;
72
69
  cursor: pointer;
73
- color: var(--ermis-text-secondary, #666666);
70
+ color: var(--ermis-text-secondary);
74
71
  padding: 4px;
75
72
  border-radius: 4px;
76
73
  display: flex;
@@ -80,13 +77,8 @@
80
77
  }
81
78
 
82
79
  .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);
80
+ background-color: var(--ermis-bg-hover);
81
+ color: var(--ermis-text-primary);
90
82
  }
91
83
 
92
84
  .ermis-modal-body {
@@ -99,15 +91,10 @@
99
91
 
100
92
  .ermis-modal-footer {
101
93
  padding: 16px 20px;
102
- border-top: 1px solid var(--ermis-border-color, #eaeaea);
94
+ border-top: 1px solid var(--ermis-border);
103
95
  display: flex;
104
96
  justify-content: flex-end;
105
97
  gap: 12px;
106
98
  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);
99
+ background-color: var(--ermis-bg-secondary);
113
100
  }
@@ -8,7 +8,7 @@
8
8
  z-index: 30;
9
9
  display: flex;
10
10
  flex-direction: column;
11
- background: var(--ermis-bg-primary, #fff);
11
+ background: var(--ermis-bg-primary);
12
12
  transform: translateX(100%);
13
13
  transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
14
14
  will-change: transform;
@@ -14,13 +14,13 @@
14
14
  align-items: center;
15
15
  gap: 8px;
16
16
  padding: 6px 12px;
17
- background: var(--ermis-bg-secondary, #f5f5f5);
17
+ background: var(--ermis-bg-secondary);
18
18
  border-radius: 20px;
19
19
  transition: background 0.15s;
20
20
  }
21
21
 
22
22
  .ermis-search-panel__input-wrap:focus-within {
23
- background: var(--ermis-bg-hover, #ebebeb);
23
+ background: var(--ermis-bg-hover);
24
24
  }
25
25
 
26
26
  .ermis-search-panel__input-icon {
@@ -39,7 +39,7 @@
39
39
  }
40
40
 
41
41
  .ermis-search-panel__input::placeholder {
42
- color: var(--ermis-text-tertiary, #999);
42
+ color: var(--ermis-text-muted);
43
43
  }
44
44
 
45
45
  .ermis-search-panel__input-clear {
@@ -49,7 +49,7 @@
49
49
  width: 20px;
50
50
  height: 20px;
51
51
  border: none;
52
- background: var(--ermis-text-tertiary, #999);
52
+ background: var(--ermis-text-muted);
53
53
  color: #fff;
54
54
  border-radius: 50%;
55
55
  cursor: pointer;
@@ -77,7 +77,7 @@
77
77
  justify-content: center;
78
78
  gap: 12px;
79
79
  padding: 48px 16px;
80
- color: var(--ermis-text-tertiary, #999);
80
+ color: var(--ermis-text-muted);
81
81
  text-align: center;
82
82
  font-size: 14px;
83
83
  }
@@ -99,7 +99,7 @@
99
99
  width: 24px;
100
100
  height: 24px;
101
101
  border: 2.5px solid var(--ermis-border, rgba(0, 0, 0, 0.08));
102
- border-top-color: var(--ermis-color-primary, #005fff);
102
+ border-top-color: var(--ermis-accent);
103
103
  border-radius: 50%;
104
104
  animation: ermis-spin 0.7s linear infinite;
105
105
  }
@@ -120,7 +120,7 @@
120
120
  align-items: center;
121
121
  justify-content: center;
122
122
  padding: 48px 16px;
123
- color: var(--ermis-text-tertiary, #999);
123
+ color: var(--ermis-text-muted);
124
124
  font-size: 14px;
125
125
  }
126
126
 
@@ -173,7 +173,7 @@
173
173
 
174
174
  .ermis-search-panel__result-time {
175
175
  font-size: 11px;
176
- color: var(--ermis-text-tertiary, #999);
176
+ color: var(--ermis-text-muted);
177
177
  white-space: nowrap;
178
178
  flex-shrink: 0;
179
179
  }
@@ -213,7 +213,7 @@
213
213
  align-items: center;
214
214
  justify-content: center;
215
215
  padding: 24px 16px;
216
- color: var(--ermis-text-tertiary, #999);
216
+ color: var(--ermis-text-muted);
217
217
  font-size: 13px;
218
218
  text-align: center;
219
219
  }
@@ -19,6 +19,12 @@
19
19
  --ermis-text-secondary: #9ca3af;
20
20
  --ermis-text-muted: #6b7280;
21
21
 
22
+ /* Semantic Colors */
23
+ --ermis-color-danger: #ef4444;
24
+ --ermis-color-danger-hover: #dc2626;
25
+ --ermis-color-success: #22c55e;
26
+ --ermis-color-success-hover: #16a34a;
27
+
22
28
  /* Message bubbles */
23
29
  --ermis-bubble-own-bg: var(--ermis-accent);
24
30
  --ermis-bubble-own-text: #ffffff;
@@ -56,6 +62,21 @@
56
62
  /* Transitions */
57
63
  --ermis-transition: 150ms ease;
58
64
 
65
+ /* Signal messages (call events) */
66
+ --ermis-signal-success: #54D62C;
67
+ --ermis-signal-missed: #FF4842;
68
+ --ermis-signal-bg: rgba(255, 255, 255, 0.04);
69
+ --ermis-signal-own-success: #86EFAC;
70
+ --ermis-signal-own-missed: #FCA5A5;
71
+ --ermis-signal-own-bg: rgba(255, 255, 255, 0.12);
72
+ --ermis-signal-own-duration: rgba(255, 255, 255, 0.6);
73
+
74
+ /* Call UI */
75
+ --ermis-call-bg: linear-gradient(135deg, #0f0f1a 0%, #1a1a2e 50%, #16213e 100%);
76
+ --ermis-call-glass: rgba(255, 255, 255, 0.06);
77
+ --ermis-call-glass-border: rgba(255, 255, 255, 0.1);
78
+ --ermis-call-pulse: rgba(99, 102, 241, 0.4);
79
+
59
80
  color: var(--ermis-text-primary);
60
81
  font-family: var(--ermis-font-family);
61
82
  }
@@ -75,6 +96,12 @@
75
96
  --ermis-text-secondary: #6b7280;
76
97
  --ermis-text-muted: #9ca3af;
77
98
 
99
+ /* Semantic Colors */
100
+ --ermis-color-danger: #ef4444;
101
+ --ermis-color-danger-hover: #dc2626;
102
+ --ermis-color-success: #10b981;
103
+ --ermis-color-success-hover: #059669;
104
+
78
105
  /* Message bubbles */
79
106
  --ermis-bubble-own-bg: var(--ermis-accent);
80
107
  --ermis-bubble-own-text: #ffffff;
@@ -89,4 +116,19 @@
89
116
  --ermis-quote-own-border: rgba(255, 255, 255, 0.6);
90
117
  --ermis-quote-own-author: rgba(255, 255, 255, 0.95);
91
118
  --ermis-quote-own-text: rgba(255, 255, 255, 0.8);
119
+
120
+ /* Signal messages (call events) */
121
+ --ermis-signal-success: #229A16;
122
+ --ermis-signal-missed: #B72136;
123
+ --ermis-signal-bg: rgba(0, 0, 0, 0.03);
124
+ --ermis-signal-own-success: #86EFAC;
125
+ --ermis-signal-own-missed: #FCA5A5;
126
+ --ermis-signal-own-bg: rgba(255, 255, 255, 0.12);
127
+ --ermis-signal-own-duration: rgba(255, 255, 255, 0.6);
128
+
129
+ /* Call UI */
130
+ --ermis-call-bg: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 50%, #dee2e6 100%);
131
+ --ermis-call-glass: rgba(0, 0, 0, 0.04);
132
+ --ermis-call-glass-border: rgba(0, 0, 0, 0.08);
133
+ --ermis-call-pulse: rgba(99, 102, 241, 0.3);
92
134
  }
@@ -10,7 +10,7 @@
10
10
  padding: 0 16px;
11
11
  height: 24px;
12
12
  font-size: 12px;
13
- color: var(--ermis-color-text-secondary, #8e8e93);
13
+ color: var(--ermis-text-secondary);
14
14
  overflow: hidden;
15
15
  }
16
16
 
@@ -18,13 +18,25 @@
18
18
  display: flex;
19
19
  align-items: center;
20
20
  gap: 3px;
21
+ animation: ermis-typing-appear 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
22
+ }
23
+
24
+ @keyframes ermis-typing-appear {
25
+ 0% {
26
+ opacity: 0;
27
+ transform: translateY(8px);
28
+ }
29
+ 100% {
30
+ opacity: 1;
31
+ transform: translateY(0);
32
+ }
21
33
  }
22
34
 
23
35
  .ermis-typing-indicator__dot {
24
36
  width: 5px;
25
37
  height: 5px;
26
38
  border-radius: 50%;
27
- background-color: var(--ermis-color-text-secondary, #8e8e93);
39
+ background-color: var(--ermis-text-secondary);
28
40
  animation: ermis-typing-bounce 1.4s infinite ease-in-out both;
29
41
  }
30
42
 
@@ -56,4 +68,5 @@
56
68
  white-space: nowrap;
57
69
  overflow: hidden;
58
70
  text-overflow: ellipsis;
71
+ animation: ermis-typing-appear 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
59
72
  }
@@ -0,0 +1,268 @@
1
+ /* ============================================================
2
+ UserPicker – Reusable User Selection Component
3
+ BEM: .ermis-user-picker__{element}--{modifier}
4
+ ============================================================ */
5
+
6
+ /* ---------- Root container ---------- */
7
+ .ermis-user-picker {
8
+ display: flex;
9
+ flex-direction: column;
10
+ gap: var(--ermis-spacing-md, 0.75rem);
11
+ }
12
+
13
+ /* ---------- Selected Users Chip Box ---------- */
14
+ .ermis-user-picker__selected-box {
15
+ display: flex;
16
+ flex-wrap: wrap;
17
+ gap: var(--ermis-spacing-xs, 0.25rem);
18
+ padding: var(--ermis-spacing-sm, 0.5rem);
19
+ border-radius: var(--ermis-radius-md, 0.5rem);
20
+ background-color: var(--ermis-bg-secondary);
21
+ border: 1px solid var(--ermis-border, rgba(255, 255, 255, 0.08));
22
+ min-height: 40px;
23
+ max-height: 120px;
24
+ overflow-y: auto;
25
+ }
26
+
27
+ .ermis-user-picker__selected-box:empty {
28
+ display: none;
29
+ }
30
+
31
+ .ermis-user-picker__selected-box::-webkit-scrollbar {
32
+ width: 4px;
33
+ }
34
+ .ermis-user-picker__selected-box::-webkit-scrollbar-track {
35
+ background: transparent;
36
+ }
37
+ .ermis-user-picker__selected-box::-webkit-scrollbar-thumb {
38
+ background: var(--ermis-border, rgba(255, 255, 255, 0.08));
39
+ border-radius: var(--ermis-radius-full, 9999px);
40
+ }
41
+
42
+ .ermis-user-picker__chip {
43
+ display: inline-flex;
44
+ align-items: center;
45
+ gap: var(--ermis-spacing-xs, 0.25rem);
46
+ padding: 2px 8px 2px 2px;
47
+ border-radius: var(--ermis-radius-full, 9999px);
48
+ background-color: var(--ermis-bg-active, rgba(99, 102, 241, 0.12));
49
+ color: var(--ermis-text-primary);
50
+ font-size: var(--ermis-font-size-xs, 0.75rem);
51
+ font-weight: 500;
52
+ line-height: 1;
53
+ white-space: nowrap;
54
+ transition: background-color var(--ermis-transition, 150ms ease);
55
+ animation: ermis-user-picker-chip-in 0.2s cubic-bezier(0.16, 1, 0.3, 1);
56
+ }
57
+
58
+ @keyframes ermis-user-picker-chip-in {
59
+ from { opacity: 0; transform: scale(0.85); }
60
+ to { opacity: 1; transform: scale(1); }
61
+ }
62
+
63
+ .ermis-user-picker__chip:hover {
64
+ background-color: var(--ermis-accent);
65
+ color: #ffffff;
66
+ }
67
+
68
+ .ermis-user-picker__chip-name {
69
+ max-width: 100px;
70
+ overflow: hidden;
71
+ text-overflow: ellipsis;
72
+ }
73
+
74
+ .ermis-user-picker__chip-remove {
75
+ display: inline-flex;
76
+ align-items: center;
77
+ justify-content: center;
78
+ width: 16px;
79
+ height: 16px;
80
+ border: none;
81
+ background: none;
82
+ color: inherit;
83
+ cursor: pointer;
84
+ padding: 0;
85
+ border-radius: var(--ermis-radius-full, 9999px);
86
+ opacity: 0.7;
87
+ transition: opacity var(--ermis-transition, 150ms ease);
88
+ }
89
+
90
+ .ermis-user-picker__chip-remove:hover {
91
+ opacity: 1;
92
+ }
93
+
94
+ .ermis-user-picker__selected-empty {
95
+ display: flex;
96
+ align-items: center;
97
+ justify-content: center;
98
+ width: 100%;
99
+ color: var(--ermis-text-muted);
100
+ font-size: var(--ermis-font-size-xs, 0.75rem);
101
+ }
102
+
103
+ /* ---------- Search Input ---------- */
104
+ .ermis-user-picker__search {
105
+ position: relative;
106
+ display: flex;
107
+ align-items: center;
108
+ }
109
+
110
+ .ermis-user-picker__search svg {
111
+ position: absolute;
112
+ left: 12px;
113
+ color: var(--ermis-text-muted);
114
+ pointer-events: none;
115
+ }
116
+
117
+ .ermis-user-picker__search input {
118
+ width: 100%;
119
+ padding: 10px 12px 10px 38px;
120
+ border-radius: var(--ermis-radius-md, 0.5rem);
121
+ border: 1px solid var(--ermis-border, rgba(255, 255, 255, 0.08));
122
+ background-color: var(--ermis-bg-secondary);
123
+ color: var(--ermis-text-primary);
124
+ font-size: var(--ermis-font-size-sm, 0.875rem);
125
+ font-family: inherit;
126
+ transition: border-color var(--ermis-transition, 150ms ease), box-shadow var(--ermis-transition, 150ms ease);
127
+ outline: none;
128
+ }
129
+
130
+ .ermis-user-picker__search input::placeholder {
131
+ color: var(--ermis-text-muted);
132
+ }
133
+
134
+ .ermis-user-picker__search input:focus {
135
+ border-color: var(--ermis-accent);
136
+ box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.2);
137
+ }
138
+
139
+ /* ---------- List Container ---------- */
140
+ .ermis-user-picker__list {
141
+ overflow: hidden;
142
+ height: 360px;
143
+ border-radius: var(--ermis-radius-md, 0.5rem);
144
+ }
145
+
146
+ /* ---------- User Row ---------- */
147
+ .ermis-user-picker__item {
148
+ display: flex;
149
+ align-items: center;
150
+ gap: var(--ermis-spacing-md, 0.75rem);
151
+ padding: 8px 12px;
152
+ border-radius: var(--ermis-radius-md, 0.5rem);
153
+ cursor: pointer;
154
+ transition: background-color var(--ermis-transition, 150ms ease);
155
+ user-select: none;
156
+ }
157
+
158
+ .ermis-user-picker__item:hover {
159
+ background-color: var(--ermis-bg-hover, rgba(255, 255, 255, 0.04));
160
+ }
161
+
162
+ .ermis-user-picker__item--selected {
163
+ background-color: var(--ermis-bg-active, rgba(99, 102, 241, 0.12));
164
+ }
165
+
166
+ .ermis-user-picker__item--selected:hover {
167
+ background-color: var(--ermis-bg-active, rgba(99, 102, 241, 0.12));
168
+ }
169
+
170
+ .ermis-user-picker__item--disabled {
171
+ opacity: 0.45;
172
+ cursor: not-allowed;
173
+ pointer-events: none;
174
+ }
175
+
176
+ /* ---------- Radio / Checkbox ---------- */
177
+ .ermis-user-picker__input {
178
+ position: relative;
179
+ width: 18px;
180
+ height: 18px;
181
+ min-width: 18px;
182
+ border: 2px solid var(--ermis-border, rgba(255, 255, 255, 0.08));
183
+ background: transparent;
184
+ transition: all var(--ermis-transition, 150ms ease);
185
+ display: flex;
186
+ align-items: center;
187
+ justify-content: center;
188
+ flex-shrink: 0;
189
+ }
190
+
191
+ .ermis-user-picker__input--radio {
192
+ border-radius: var(--ermis-radius-full, 9999px);
193
+ }
194
+
195
+ .ermis-user-picker__input--checkbox {
196
+ border-radius: var(--ermis-radius-sm, 0.375rem);
197
+ }
198
+
199
+ .ermis-user-picker__input--checked {
200
+ background-color: var(--ermis-accent);
201
+ border-color: var(--ermis-accent);
202
+ }
203
+
204
+ .ermis-user-picker__input--checked svg {
205
+ color: #ffffff;
206
+ }
207
+
208
+ /* ---------- User Info ---------- */
209
+ .ermis-user-picker__info {
210
+ flex: 1;
211
+ min-width: 0;
212
+ display: flex;
213
+ flex-direction: column;
214
+ gap: 2px;
215
+ }
216
+
217
+ .ermis-user-picker__name {
218
+ font-size: var(--ermis-font-size-sm, 0.875rem);
219
+ font-weight: 500;
220
+ color: var(--ermis-text-primary);
221
+ white-space: nowrap;
222
+ overflow: hidden;
223
+ text-overflow: ellipsis;
224
+ }
225
+
226
+ .ermis-user-picker__detail {
227
+ font-size: var(--ermis-font-size-xs, 0.75rem);
228
+ color: var(--ermis-text-muted);
229
+ white-space: nowrap;
230
+ overflow: hidden;
231
+ text-overflow: ellipsis;
232
+ }
233
+
234
+ /* ---------- Loading / Empty ---------- */
235
+ .ermis-user-picker__loading,
236
+ .ermis-user-picker__empty {
237
+ display: flex;
238
+ align-items: center;
239
+ justify-content: center;
240
+ padding: 32px 0;
241
+ color: var(--ermis-text-muted);
242
+ font-size: var(--ermis-font-size-sm, 0.875rem);
243
+ }
244
+
245
+ .ermis-user-picker__load-more {
246
+ display: flex;
247
+ align-items: center;
248
+ justify-content: center;
249
+ padding: 12px 0;
250
+ color: var(--ermis-text-muted);
251
+ font-size: var(--ermis-font-size-xs, 0.75rem);
252
+ }
253
+
254
+ /* ---------- Spinner keyframes ---------- */
255
+ .ermis-user-picker__spinner {
256
+ display: inline-block;
257
+ width: 16px;
258
+ height: 16px;
259
+ border: 2px solid var(--ermis-border, rgba(255, 255, 255, 0.08));
260
+ border-top-color: var(--ermis-accent);
261
+ border-radius: var(--ermis-radius-full, 9999px);
262
+ animation: ermis-user-picker-spin 0.6s linear infinite;
263
+ margin-right: var(--ermis-spacing-sm, 0.5rem);
264
+ }
265
+
266
+ @keyframes ermis-user-picker-spin {
267
+ to { transform: rotate(360deg); }
268
+ }
@@ -22,3 +22,6 @@
22
22
  @import './_channel-info.css';
23
23
  @import './_add-member-modal.css';
24
24
  @import './_search-panel.css';
25
+ @import './_user-picker.css';
26
+ @import './_create-channel-modal.css';
27
+ @import './_call-ui.css';