@ensembleapp/client-sdk 0.0.1

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.
@@ -0,0 +1,482 @@
1
+ :root[data-chat-widget],
2
+ [data-chat-widget] {
3
+ --chat-primary: #3b82f6;
4
+ --chat-primary-text: #ffffff;
5
+ --chat-primary-hover: #2563eb;
6
+ --chat-background: #ffffff;
7
+ --chat-border: #e5e7eb;
8
+ --chat-header-text: #ffffff;
9
+ --chat-user-text: #ffffff;
10
+ --chat-assistant-bg: #f3f4f6;
11
+ --chat-assistant-text: #111827;
12
+ --chat-font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
13
+ --chat-radius: 0.75rem;
14
+ --chat-input-bg: #ffffff;
15
+ --chat-input-text: #111827;
16
+ --chat-input-placeholder: #6b7280;
17
+ --chat-thought-border: #d1d5db;
18
+
19
+ /* font */
20
+ --chat-font-size: 0.925rem;
21
+ --chat-thought-font-size: 0.75rem;
22
+ }
23
+
24
+ .chat-widget {
25
+ display: flex;
26
+ flex-direction: column;
27
+ width: 100%;
28
+ height: 100%;
29
+ min-height: 24rem;
30
+ background: var(--chat-background);
31
+ border: 1px solid var(--chat-border);
32
+ border-radius: var(--chat-radius);
33
+ box-shadow: 0 20px 45px rgba(15, 23, 42, 0.12);
34
+ overflow: hidden;
35
+ font-family: var(--chat-font-family);
36
+ color: var(--chat-assistant-text);
37
+ }
38
+
39
+ .chat-widget__header {
40
+ display: flex;
41
+ align-items: center;
42
+ justify-content: space-between;
43
+ height: 40px;
44
+ padding: 0.75rem 1rem;
45
+ background: var(--chat-primary);
46
+ color: var(--chat-header-text);
47
+ }
48
+
49
+ .chat-widget__title {
50
+ margin: 0;
51
+ font-size: 0.875rem;
52
+ font-weight: 600;
53
+ }
54
+
55
+ .chat-widget__messages {
56
+ flex: 1;
57
+ overflow-y: auto;
58
+ padding: 1rem;
59
+ display: flex;
60
+ flex-direction: column;
61
+ gap: 1rem;
62
+ }
63
+
64
+ .chat-widget__message {
65
+ display: flex;
66
+ flex-direction: column;
67
+ gap: 0.5rem;
68
+ }
69
+
70
+ .chat-widget__message-row {
71
+ display: flex;
72
+ }
73
+
74
+ .chat-widget__message-row--user {
75
+ justify-content: flex-end;
76
+ }
77
+
78
+ .chat-widget__message-row--assistant {
79
+ justify-content: flex-start;
80
+ }
81
+
82
+ .chat-widget__bubble {
83
+ max-width: 90%;
84
+ padding: 0.5rem 0.75rem;
85
+ border-radius: calc(var(--chat-radius) * 0.65);
86
+ font-size: var(--chat-font-size);
87
+ }
88
+
89
+ .chat-widget__bubble--user {
90
+ background: var(--chat-primary);
91
+ color: var(--chat-user-text);
92
+ border-bottom-right-radius: 0.35rem;
93
+ }
94
+
95
+ .chat-widget__bubble--assistant {
96
+ background: var(--chat-assistant-bg);
97
+ color: var(--chat-assistant-text);
98
+ border-bottom-left-radius: 0.35rem;
99
+ }
100
+
101
+ /* customizing markdown styles */
102
+ .chat-widget__markdown {
103
+ /* reset to normal otherwise text will be funky */
104
+ white-space: normal;
105
+ font-size: var(--chat-font-size);
106
+ }
107
+
108
+ .chat-widget__markdown h1 {
109
+ font-size: calc(var(--chat-font-size) * 1.4);
110
+ }
111
+ .chat-widget__markdown h2 {
112
+ font-size: calc(var(--chat-font-size) * 1.25);
113
+ }
114
+ .chat-widget__markdown h3 {
115
+ font-size: calc(var(--chat-font-size) * 1.1);
116
+ }
117
+ .chat-widget__markdown h4 {
118
+ font-size: calc(var(--chat-font-size) * 1.05);
119
+ }
120
+ .chat-widget__markdown h5 {
121
+ font-size: calc(var(--chat-font-size) * 1);
122
+ }
123
+ .chat-widget__markdown h6 {
124
+ font-size: calc(var(--chat-font-size) * 0.95);
125
+ }
126
+
127
+ .chat-widget__anchor-button {
128
+ position: fixed;
129
+ bottom: 20px;
130
+ right: 20px;
131
+ display: inline-flex;
132
+ align-items: center;
133
+ gap: 0.5rem;
134
+ padding: 0.65rem 0.85rem;
135
+ background: var(--chat-primary);
136
+ color: var(--chat-primary-text);
137
+ border: none;
138
+ border-radius: 999px;
139
+ box-shadow: 0 10px 25px rgba(15, 23, 42, 0.2);
140
+ cursor: pointer;
141
+ font-weight: 600;
142
+ z-index: 99999;
143
+ }
144
+
145
+ .chat-widget__anchor-button:hover {
146
+ background: var(--chat-primary-hover);
147
+ }
148
+
149
+ .chat-widget__anchor--left {
150
+ right: auto;
151
+ left: 20px;
152
+ }
153
+
154
+ .chat-widget__anchor-icon {
155
+ width: 1.1rem;
156
+ height: 1.1rem;
157
+ }
158
+
159
+ .chat-widget__popup {
160
+ position: fixed;
161
+ bottom: 80px;
162
+ right: 20px;
163
+ z-index: 99998;
164
+ }
165
+
166
+ .chat-widget__anchor--left.chat-widget__popup {
167
+ right: auto;
168
+ left: 20px;
169
+ }
170
+
171
+ .chat-widget__popup-inner {
172
+ width: 384px;
173
+ max-width: calc(100vw - 40px);
174
+ height: 500px;
175
+ max-height: calc(100vh - 140px);
176
+ box-shadow: 0 20px 45px rgba(15, 23, 42, 0.12);
177
+ border-radius: 12px;
178
+ overflow: hidden;
179
+ }
180
+
181
+ .chat-widget__markdown table {
182
+ width: 100%;
183
+ border-collapse: collapse;
184
+ margin: 0.5rem 0;
185
+ }
186
+
187
+ .chat-widget__markdown th,
188
+ .chat-widget__markdown td {
189
+ border: 1px solid var(--chat-border);
190
+ padding: 0.5rem;
191
+ text-align: left;
192
+ vertical-align: top;
193
+ }
194
+
195
+ .chat-widget__markdown thead th {
196
+ background: var(--chat-assistant-bg);
197
+ color: var(--chat-assistant-text);
198
+ font-weight: 600;
199
+ }
200
+
201
+ .chat-widget__thoughts {
202
+ /* margin-left: 1rem; */
203
+ min-width: 0;
204
+ /* shrink the thoughts text proportionally */
205
+ --chat-font-size: var(--chat-thought-font-size);
206
+ }
207
+
208
+ .chat-widget__details {
209
+ border: 0;
210
+ }
211
+
212
+ .chat-widget__thoughts-summary {
213
+ list-style: none;
214
+ display: flex;
215
+ align-items: center;
216
+ gap: 0.35rem;
217
+ cursor: pointer;
218
+ color: #6b7280;
219
+ font-size: 0.8125rem;
220
+ }
221
+
222
+ .chat-widget__thoughts-summary:hover {
223
+ color: var(--chat-assistant-text);
224
+ }
225
+
226
+ .chat-widget__thoughts-icon-container {
227
+ display: flex;
228
+ border: 1px solid #d1d5db;
229
+ border-radius: 999px;
230
+ align-items: center;
231
+ justify-content: center;
232
+ width: 1rem;
233
+ height: 1rem;
234
+ }
235
+
236
+ .chat-widget__thoughts-icon {
237
+ width: 0.75rem;
238
+ height: 0.75rem;
239
+ transition: transform 0.2s ease;
240
+ }
241
+
242
+ .chat-widget__details[open] .chat-widget__thoughts-icon {
243
+ transform: rotate(90deg);
244
+ }
245
+
246
+ .chat-widget__thoughts-content {
247
+ margin-top: 0.5rem;
248
+ margin-left: 0.4rem;
249
+ padding: 0.75rem;
250
+ border-left: 2px solid var(--chat-thought-border);
251
+ border-color: var(--chat-primary);
252
+ /* background: rgba(148, 163, 184, 0.15);
253
+ border-radius: 0.5rem; */
254
+ max-width: 100%;
255
+ overflow-x: auto;
256
+ }
257
+
258
+ .chat-widget__thoughts-text {
259
+ margin: 0;
260
+ line-height: 1.5;
261
+ color: #4b5563;
262
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
263
+ white-space: pre-wrap;
264
+ word-break: break-word;
265
+ overflow-wrap: anywhere;
266
+ display: block;
267
+ }
268
+
269
+ .chat-widget__loading {
270
+ display: flex;
271
+ justify-content: flex-start;
272
+ }
273
+
274
+ .chat-widget__loading-bubble {
275
+ background: var(--chat-assistant-bg);
276
+ color: var(--chat-assistant-text);
277
+ border-radius: calc(var(--chat-radius) * 0.65);
278
+ border-bottom-left-radius: 0.35rem;
279
+ padding: 0.5rem 0.75rem;
280
+ }
281
+
282
+ .chat-widget__loading-dots {
283
+ display: flex;
284
+ gap: 0.35rem;
285
+ }
286
+
287
+ .chat-widget__loading-dot {
288
+ width: 0.5rem;
289
+ height: 0.5rem;
290
+ border-radius: 999px;
291
+ background: #9ca3af;
292
+ animation: chat-widget-bounce 1s infinite ease-in-out;
293
+ }
294
+
295
+ .chat-widget__loading-dot[data-delay="1"] {
296
+ animation-delay: 0.1s;
297
+ }
298
+
299
+ .chat-widget__loading-dot[data-delay="2"] {
300
+ animation-delay: 0.2s;
301
+ }
302
+
303
+ @keyframes chat-widget-bounce {
304
+ 0%, 80%, 100% {
305
+ transform: scale(0.6);
306
+ opacity: 0.4;
307
+ }
308
+ 40% {
309
+ transform: scale(1);
310
+ opacity: 1;
311
+ }
312
+ }
313
+
314
+ .chat-widget__input {
315
+ border-top: 1px solid var(--chat-border);
316
+ padding: 0.25rem 0 0.75rem;
317
+ background: var(--chat-input-bg);
318
+ }
319
+
320
+ .chat-widget__form {
321
+ position: relative;
322
+ }
323
+
324
+ .chat-widget__textarea {
325
+ width: 100%;
326
+ border: 0;
327
+ padding: 0.75rem 5.25rem 0.75rem 0.75rem;
328
+ background: transparent;
329
+ font-size: 0.925rem;
330
+ resize: none;
331
+ color: var(--chat-input-text);
332
+ font-family: inherit;
333
+ }
334
+
335
+ .chat-widget__textarea::placeholder {
336
+ color: var(--chat-input-placeholder);
337
+ }
338
+
339
+ .chat-widget__textarea:focus-visible {
340
+ outline: none;
341
+ }
342
+
343
+ .chat-widget__textarea:disabled {
344
+ opacity: 0.5;
345
+ cursor: not-allowed;
346
+ }
347
+
348
+ .chat-widget__toolbar {
349
+ position: absolute;
350
+ top: 0;
351
+ right: 3.75rem;
352
+ height: 100%;
353
+ display: flex;
354
+ align-items: center;
355
+ padding: 0 0.5rem;
356
+ border-right: 1px solid var(--chat-border);
357
+ }
358
+
359
+ .chat-widget__submit {
360
+ position: absolute;
361
+ top: 50%;
362
+ right: 0.75rem;
363
+ transform: translateY(-50%);
364
+ background: transparent;
365
+ border: 0;
366
+ width: 2.5rem;
367
+ height: 2.5rem;
368
+ display: grid;
369
+ place-items: center;
370
+ color: var(--chat-primary);
371
+ cursor: pointer;
372
+ }
373
+
374
+ .chat-widget__submit:disabled {
375
+ color: #9ca3af;
376
+ cursor: not-allowed;
377
+ }
378
+
379
+ .chat-widget__submit:not(:disabled):hover {
380
+ color: var(--chat-primary-hover);
381
+ }
382
+
383
+ .chat-widget__send-icon {
384
+ width: 1.2rem;
385
+ height: 1.2rem;
386
+ }
387
+
388
+ .chat-widget__mic-button {
389
+ position: relative;
390
+ border: none;
391
+ background: transparent;
392
+ width: 2.25rem;
393
+ height: 2.25rem;
394
+ display: grid;
395
+ place-items: center;
396
+ color: var(--chat-primary);
397
+ cursor: pointer;
398
+ border-radius: 999px;
399
+ }
400
+
401
+ .chat-widget__mic-button:disabled {
402
+ color: #9ca3af;
403
+ cursor: not-allowed;
404
+ }
405
+
406
+ .chat-widget__mic-button--active {
407
+ color: var(--chat-primary-hover);
408
+ background: rgba(59, 130, 246, 0.08);
409
+ }
410
+
411
+ .chat-widget__mic-icon {
412
+ width: 1rem;
413
+ height: 1rem;
414
+ }
415
+
416
+ .chat-widget__mic-bar {
417
+ position: absolute;
418
+ bottom: 0.1rem;
419
+ left: 50%;
420
+ width: 16px;
421
+ height: 2px;
422
+ border-radius: 999px;
423
+ background: rgba(148, 163, 184, 0.4);
424
+ overflow: hidden;
425
+ display: block;
426
+ transform: translateX(-50%);
427
+ pointer-events: none;
428
+ }
429
+
430
+ .chat-widget__mic-bar-fill {
431
+ display: block;
432
+ width: 100%;
433
+ height: 100%;
434
+ background: currentColor;
435
+ transform-origin: left;
436
+ transition: transform 0.12s linear;
437
+ }
438
+
439
+ .chat-widget__voice {
440
+ display: flex;
441
+ margin-top: 0.25rem;
442
+ }
443
+
444
+ .chat-widget__voice-button {
445
+ border: none;
446
+ background: none;
447
+ display: inline-flex;
448
+ align-items: center;
449
+ gap: 0.35rem;
450
+ padding: 0.1rem 0;
451
+ font-size: 0.8rem;
452
+ font-weight: 500;
453
+ color: var(--chat-primary);
454
+ cursor: pointer;
455
+ }
456
+
457
+ .chat-widget__voice-button:disabled {
458
+ color: #9ca3af;
459
+ cursor: not-allowed;
460
+ }
461
+
462
+ .chat-widget__voice-button--active {
463
+ color: var(--chat-primary-hover);
464
+ }
465
+
466
+ .chat-widget__voice-icon {
467
+ width: 0.95rem;
468
+ height: 0.95rem;
469
+ }
470
+
471
+ .chat-widget__voice-icon--spin {
472
+ animation: chat-widget-spin 1s linear infinite;
473
+ }
474
+
475
+ @keyframes chat-widget-spin {
476
+ 0% {
477
+ transform: rotate(0deg);
478
+ }
479
+ 100% {
480
+ transform: rotate(360deg);
481
+ }
482
+ }
@@ -0,0 +1,85 @@
1
+ /* Default widget styles - optional import for customers */
2
+
3
+ .chat-widget__person-card {
4
+ display: flex;
5
+ flex-direction: column;
6
+ gap: 0.75rem;
7
+ padding: 1rem;
8
+ background: #ffffff;
9
+ border: 1px solid #e5e7eb;
10
+ border-radius: 0.5rem;
11
+ box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
12
+ }
13
+
14
+ .chat-widget__person-card-header {
15
+ display: flex;
16
+ align-items: flex-start;
17
+ gap: 0.75rem;
18
+ }
19
+
20
+ .chat-widget__person-card-avatar {
21
+ width: 3rem;
22
+ height: 3rem;
23
+ border-radius: 9999px;
24
+ object-fit: cover;
25
+ flex-shrink: 0;
26
+ }
27
+
28
+ .chat-widget__person-card-info {
29
+ flex: 1;
30
+ min-width: 0;
31
+ }
32
+
33
+ .chat-widget__person-card-name {
34
+ font-weight: 600;
35
+ font-size: 1rem;
36
+ color: #111827;
37
+ margin-bottom: 0.25rem;
38
+ }
39
+
40
+ .chat-widget__person-card-details {
41
+ display: flex;
42
+ flex-direction: column;
43
+ gap: 0.25rem;
44
+ }
45
+
46
+ .chat-widget__person-card-details > div {
47
+ display: flex;
48
+ gap: 0.5rem;
49
+ font-size: 0.875rem;
50
+ }
51
+
52
+ .chat-widget__person-card-details span:first-child {
53
+ color: #6b7280;
54
+ font-weight: 500;
55
+ min-width: fit-content;
56
+ }
57
+
58
+ .chat-widget__person-card-details span:last-child {
59
+ color: #374151;
60
+ }
61
+
62
+ .chat-widget__link-widget {
63
+ display: inline-flex;
64
+ align-items: center;
65
+ padding: 0.5rem 0.75rem;
66
+ background: #f3f4f6;
67
+ border: 1px solid #d1d5db;
68
+ border-radius: 0.375rem;
69
+ color: #3b82f6;
70
+ text-decoration: none;
71
+ font-size: 0.875rem;
72
+ font-weight: 500;
73
+ transition: all 0.2s ease;
74
+ }
75
+
76
+ .chat-widget__link-widget:hover {
77
+ background: #e5e7eb;
78
+ border-color: #9ca3af;
79
+ color: #2563eb;
80
+ }
81
+
82
+ .chat-widget__link-widget:focus {
83
+ outline: 2px solid #3b82f6;
84
+ outline-offset: 2px;
85
+ }
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@ensembleapp/client-sdk",
3
+ "version": "0.0.1",
4
+ "description": "React client SDK for chat functionality",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "module": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ },
14
+ "./schemas": {
15
+ "import": "./dist/schemas.js",
16
+ "types": "./dist/schemas.d.ts"
17
+ },
18
+ "./styles": "./lib/components/ChatWidget.css",
19
+ "./default-widgets/styles": "./lib/widgets/default-widgets.css"
20
+ },
21
+ "files": [
22
+ "dist",
23
+ "lib/components/ChatWidget.css",
24
+ "lib/widgets/default-widgets.css"
25
+ ],
26
+ "scripts": {
27
+ "build": "tsup",
28
+ "build:widget": "tsup --config tsup.widget.config.ts",
29
+ "build:all": "npm run build && npm run build:widget",
30
+ "dev": "tsup --watch",
31
+ "typecheck": "tsc --noEmit",
32
+ "lint": "eslint lib/**/*.{ts,tsx}"
33
+ },
34
+ "peerDependencies": {
35
+ "react": ">=18.0.0",
36
+ "react-dom": ">=18.0.0"
37
+ },
38
+ "dependencies": {
39
+ "@ai-sdk/react": "^2.0.104",
40
+ "ai": "^5.0.104",
41
+ "clsx": "^2.1.1",
42
+ "dlv": "^1.1.3",
43
+ "lucide-react": "^0.553.0",
44
+ "react-markdown": "^10.1.0",
45
+ "postcss-import": "^15.1.0",
46
+ "postcss-nested": "^6.2.0",
47
+ "tailwind-merge": "^2.5.4"
48
+ },
49
+ "devDependencies": {
50
+ "@types/react": "^18.3.12",
51
+ "@types/react-dom": "^18.3.1",
52
+ "autoprefixer": "^10.4.22",
53
+ "eslint": "^9.15.0",
54
+ "postcss": "^8.5.0",
55
+ "postcss-js": "^4.1.0",
56
+ "tailwindcss": "^3.4.14",
57
+ "tsup": "^8.3.5",
58
+ "typescript": "^5.8.2"
59
+ },
60
+ "publishConfig": {
61
+ "access": "public"
62
+ }
63
+ }