@bootstrapware/answers 0.1.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.
@@ -0,0 +1,621 @@
1
+ .bsw-an {
2
+ --bsw-an-bg: #f6f6f1;
3
+ --bsw-an-panel: #fff;
4
+ --bsw-an-line: #e4e4dc;
5
+ --bsw-an-muted: #6b6b60;
6
+ --bsw-an-fg: #1a1a14;
7
+ --bsw-an-accent: #c8ef00;
8
+ --bsw-an-accent-fg: #1a1a14;
9
+ --bsw-an-radius: 12px;
10
+ position: relative;
11
+ box-sizing: border-box;
12
+ display: flex;
13
+ flex-direction: column;
14
+ width: 100%;
15
+ max-width: 100%;
16
+ min-width: 0;
17
+ min-height: 24rem;
18
+ font-family: inherit, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
19
+ color: var(--bsw-an-fg);
20
+ background: var(--bsw-an-bg);
21
+ border: 1px solid var(--bsw-an-line);
22
+ border-radius: var(--bsw-an-radius);
23
+ overflow: hidden;
24
+ }
25
+
26
+ /* Explicit theme only. No prefers-color-scheme. */
27
+ .bsw-an[data-theme="dark"] {
28
+ --bsw-an-bg: #161714;
29
+ --bsw-an-panel: #22241c;
30
+ --bsw-an-fg: #f4f4ee;
31
+ --bsw-an-muted: #b3b4aa;
32
+ --bsw-an-line: #4a4c42;
33
+ --bsw-an-accent: #c8ef00;
34
+ --bsw-an-accent-fg: #161714;
35
+ --bsw-an-radius: 12px;
36
+ }
37
+
38
+ .bsw-an *,
39
+ .bsw-an *::before,
40
+ .bsw-an *::after {
41
+ box-sizing: border-box;
42
+ }
43
+
44
+ .bsw-an__header {
45
+ display: flex;
46
+ gap: 0.7rem;
47
+ align-items: center;
48
+ padding: 0.85rem 1rem;
49
+ background: var(--bsw-an-panel);
50
+ border-bottom: 1px solid var(--bsw-an-line);
51
+ }
52
+
53
+ .bsw-an__mark {
54
+ flex: 0 0 auto;
55
+ display: grid;
56
+ place-items: center;
57
+ width: 1.7rem;
58
+ height: 1.7rem;
59
+ border-radius: 8px;
60
+ background: var(--bsw-an-accent);
61
+ box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--bsw-an-fg) 10%, transparent);
62
+ }
63
+
64
+ .bsw-an__mark::after {
65
+ content: "?";
66
+ font-size: 0.95rem;
67
+ font-weight: 800;
68
+ line-height: 1;
69
+ color: var(--bsw-an-accent-fg);
70
+ }
71
+
72
+ .bsw-an__heading {
73
+ min-width: 0;
74
+ display: flex;
75
+ flex-direction: column;
76
+ gap: 0.1rem;
77
+ }
78
+
79
+ .bsw-an__title {
80
+ margin: 0;
81
+ font-size: 0.95rem;
82
+ font-weight: 650;
83
+ letter-spacing: -0.01em;
84
+ line-height: 1.2;
85
+ }
86
+
87
+ .bsw-an__note,
88
+ .bsw-an__empty,
89
+ .bsw-an__count,
90
+ .bsw-an__excerpt,
91
+ .bsw-an__status,
92
+ .bsw-an__thanks {
93
+ margin: 0;
94
+ color: var(--bsw-an-muted);
95
+ font-size: 0.8rem;
96
+ line-height: 1.4;
97
+ }
98
+
99
+ .bsw-an__log {
100
+ flex: 1;
101
+ min-height: 8rem;
102
+ overflow: auto;
103
+ padding: 1rem 0.85rem 0.85rem;
104
+ }
105
+
106
+ .bsw-an__empty {
107
+ margin: 1.5rem 0.5rem;
108
+ padding: 1.1rem 1rem;
109
+ text-align: center;
110
+ background: var(--bsw-an-panel);
111
+ border: 1px dashed var(--bsw-an-line);
112
+ border-radius: calc(var(--bsw-an-radius) - 2px);
113
+ line-height: 1.5;
114
+ }
115
+
116
+ .bsw-an__turns {
117
+ list-style: none;
118
+ margin: 0;
119
+ padding: 0;
120
+ display: flex;
121
+ flex-direction: column;
122
+ gap: 1rem;
123
+ }
124
+
125
+ .bsw-an__turn {
126
+ display: flex;
127
+ flex-direction: column;
128
+ gap: 0.55rem;
129
+ }
130
+
131
+ .bsw-an__row {
132
+ display: flex;
133
+ flex-direction: column;
134
+ gap: 0.4rem;
135
+ max-width: 88%;
136
+ min-width: 0;
137
+ }
138
+
139
+ .bsw-an__row--visitor {
140
+ align-self: flex-end;
141
+ align-items: flex-end;
142
+ }
143
+
144
+ .bsw-an__row--reply {
145
+ align-self: flex-start;
146
+ align-items: flex-start;
147
+ max-width: 92%;
148
+ }
149
+
150
+ .bsw-an__question,
151
+ .bsw-an__answer,
152
+ .bsw-an__fallback,
153
+ .bsw-an__status {
154
+ overflow-wrap: anywhere;
155
+ }
156
+
157
+ .bsw-an__question {
158
+ margin: 0;
159
+ padding: 0.55rem 0.8rem;
160
+ font-weight: 600;
161
+ line-height: 1.4;
162
+ background: color-mix(in srgb, var(--bsw-an-accent) 34%, var(--bsw-an-panel));
163
+ border-radius: 1.05rem 1.05rem 0.3rem 1.05rem;
164
+ }
165
+
166
+ .bsw-an__answer,
167
+ .bsw-an__fallback,
168
+ .bsw-an__status {
169
+ margin: 0;
170
+ padding: 0.7rem 0.85rem;
171
+ line-height: 1.5;
172
+ background: var(--bsw-an-panel);
173
+ border: 1px solid var(--bsw-an-line);
174
+ border-radius: 0.3rem 1.05rem 1.05rem 1.05rem;
175
+ }
176
+
177
+ .bsw-an__fallback {
178
+ color: var(--bsw-an-muted);
179
+ }
180
+
181
+ .bsw-an__answer p,
182
+ .bsw-an__fallback,
183
+ .bsw-an__excerpt {
184
+ margin: 0;
185
+ }
186
+
187
+ .bsw-an__answer p + p,
188
+ .bsw-an__answer p + ul,
189
+ .bsw-an__answer ul + p {
190
+ margin-top: 0.45rem;
191
+ }
192
+
193
+ .bsw-an__answer ul {
194
+ margin: 0.25rem 0 0;
195
+ padding-inline-start: 1.1rem;
196
+ }
197
+
198
+ .bsw-an__answer a,
199
+ .bsw-an__source a {
200
+ color: var(--bsw-an-fg);
201
+ font-weight: 700;
202
+ }
203
+
204
+ .bsw-an__answer code {
205
+ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
206
+ font-size: 0.92em;
207
+ background: color-mix(in srgb, var(--bsw-an-fg) 6%, var(--bsw-an-panel));
208
+ border-radius: 4px;
209
+ padding: 0.05rem 0.25rem;
210
+ }
211
+
212
+ .bsw-an__excerpt {
213
+ display: -webkit-box;
214
+ -webkit-box-orient: vertical;
215
+ -webkit-line-clamp: 3;
216
+ line-clamp: 3;
217
+ overflow: hidden;
218
+ overflow-wrap: anywhere;
219
+ }
220
+
221
+ .bsw-an__sources-wrap {
222
+ width: 100%;
223
+ }
224
+
225
+ .bsw-an__sources-toggle {
226
+ display: inline-flex;
227
+ align-items: center;
228
+ gap: 0.35rem;
229
+ cursor: pointer;
230
+ list-style: none;
231
+ font-size: 0.75rem;
232
+ font-weight: 650;
233
+ color: var(--bsw-an-muted);
234
+ background: var(--bsw-an-panel);
235
+ border: 1px solid var(--bsw-an-line);
236
+ border-radius: 999px;
237
+ padding: 0.22rem 0.65rem 0.22rem 0.5rem;
238
+ }
239
+
240
+ .bsw-an__sources-toggle::-webkit-details-marker {
241
+ display: none;
242
+ }
243
+
244
+ .bsw-an__sources-toggle::before {
245
+ content: "";
246
+ width: 0.4rem;
247
+ height: 0.4rem;
248
+ border-inline-end: 1.5px solid currentColor;
249
+ border-bottom: 1.5px solid currentColor;
250
+ transform: rotate(-45deg);
251
+ translate: 0 -0.05rem;
252
+ }
253
+
254
+ .bsw-an__sources-wrap[open] .bsw-an__sources-toggle::before {
255
+ transform: rotate(45deg);
256
+ translate: 0 -0.12rem;
257
+ }
258
+
259
+ .bsw-an__sources-toggle:focus-visible {
260
+ outline: 2px solid var(--bsw-an-accent);
261
+ outline-offset: 2px;
262
+ }
263
+
264
+ .bsw-an__sources {
265
+ list-style: none;
266
+ margin: 0.4rem 0 0;
267
+ padding: 0;
268
+ display: flex;
269
+ flex-direction: column;
270
+ gap: 0.4rem;
271
+ }
272
+
273
+ .bsw-an__source {
274
+ border-inline-start: 3px solid var(--bsw-an-accent);
275
+ background: var(--bsw-an-panel);
276
+ border: 1px solid var(--bsw-an-line);
277
+ border-inline-start-width: 3px;
278
+ border-inline-start-color: var(--bsw-an-accent);
279
+ border-radius: 0 10px 10px 0;
280
+ padding: 0.5rem 0.7rem;
281
+ }
282
+
283
+ .bsw-an__source-title {
284
+ font-weight: 650;
285
+ font-size: 0.85rem;
286
+ }
287
+
288
+ .bsw-an__feedback {
289
+ display: flex;
290
+ flex-wrap: wrap;
291
+ gap: 0.3rem;
292
+ align-items: center;
293
+ color: var(--bsw-an-muted);
294
+ font-size: 0.75rem;
295
+ }
296
+
297
+ .bsw-an__composer {
298
+ position: relative;
299
+ display: flex;
300
+ flex-direction: column;
301
+ gap: 0.45rem;
302
+ padding: 0.75rem 0.85rem 0.85rem;
303
+ border-top: 1px solid var(--bsw-an-line);
304
+ background: var(--bsw-an-panel);
305
+ }
306
+
307
+ .bsw-an__composer-row {
308
+ display: flex;
309
+ gap: 0.5rem;
310
+ align-items: flex-end;
311
+ }
312
+
313
+ .bsw-an__label {
314
+ position: absolute;
315
+ width: 1px;
316
+ height: 1px;
317
+ padding: 0;
318
+ margin: -1px;
319
+ overflow: hidden;
320
+ clip: rect(0, 0, 0, 0);
321
+ white-space: nowrap;
322
+ border: 0;
323
+ }
324
+
325
+ .bsw-an__textarea {
326
+ flex: 1 1 auto;
327
+ width: 100%;
328
+ min-height: 2.75rem;
329
+ max-height: 8rem;
330
+ border: 1px solid var(--bsw-an-line);
331
+ border-radius: 14px;
332
+ padding: 0.55rem 0.75rem;
333
+ font: inherit;
334
+ line-height: 1.4;
335
+ color: var(--bsw-an-fg);
336
+ background: var(--bsw-an-bg);
337
+ resize: none;
338
+ }
339
+
340
+ .bsw-an__button {
341
+ flex: 0 0 auto;
342
+ align-self: flex-end;
343
+ border: 1px solid transparent;
344
+ border-radius: 999px;
345
+ background: var(--bsw-an-accent);
346
+ color: var(--bsw-an-accent-fg);
347
+ font: inherit;
348
+ font-weight: 700;
349
+ padding: 0.5rem 0.95rem;
350
+ cursor: pointer;
351
+ }
352
+
353
+ .bsw-an__button--ghost {
354
+ background: transparent;
355
+ color: var(--bsw-an-fg);
356
+ border-color: var(--bsw-an-line);
357
+ font-weight: 600;
358
+ padding: 0.2rem 0.5rem;
359
+ font-size: 0.75rem;
360
+ }
361
+
362
+ .bsw-an__button:disabled {
363
+ cursor: not-allowed;
364
+ opacity: 0.6;
365
+ }
366
+
367
+ .bsw-an__button:focus-visible,
368
+ .bsw-an__textarea:focus-visible {
369
+ outline: 2px solid var(--bsw-an-accent);
370
+ outline-offset: 2px;
371
+ }
372
+
373
+ .bsw-an__error {
374
+ margin: 0;
375
+ color: var(--bsw-an-fg);
376
+ font-weight: 700;
377
+ font-size: 0.8rem;
378
+ }
379
+
380
+ .bsw-an__dots {
381
+ display: inline-flex;
382
+ gap: 0.18rem;
383
+ margin-inline-end: 0.45rem;
384
+ vertical-align: middle;
385
+ }
386
+
387
+ .bsw-an__dots i {
388
+ width: 0.35rem;
389
+ height: 0.35rem;
390
+ border-radius: 999px;
391
+ background: var(--bsw-an-muted);
392
+ animation: bsw-an-dot 1s ease-in-out infinite;
393
+ }
394
+
395
+ .bsw-an__dots i:nth-child(2) {
396
+ animation-delay: 0.15s;
397
+ }
398
+
399
+ .bsw-an__dots i:nth-child(3) {
400
+ animation-delay: 0.3s;
401
+ }
402
+
403
+ @keyframes bsw-an-dot {
404
+ 0%,
405
+ 80%,
406
+ 100% {
407
+ opacity: 0.35;
408
+ transform: translateY(0);
409
+ }
410
+ 40% {
411
+ opacity: 1;
412
+ transform: translateY(-2px);
413
+ }
414
+ }
415
+
416
+ .bsw-an-frame {
417
+ --frame-bg: #f6f6f1;
418
+ --frame-fg: #1a1a14;
419
+ --frame-line: #e4e4dc;
420
+ --frame-accent: #c8ef00;
421
+ --frame-accent-fg: #1a1a14;
422
+ position: fixed;
423
+ z-index: 40;
424
+ right: var(--bsw-an-frame-launcher-right, 1.25rem);
425
+ bottom: var(--bsw-an-frame-launcher-bottom, 1.25rem);
426
+ font-family: inherit, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
427
+ }
428
+
429
+ .bsw-an-frame[data-theme="dark"] {
430
+ --frame-bg: #161714;
431
+ --frame-fg: #f4f4ee;
432
+ --frame-line: #4a4c42;
433
+ --frame-accent: #c8ef00;
434
+ --frame-accent-fg: #161714;
435
+ }
436
+
437
+ .bsw-an--launcher-host {
438
+ width: auto;
439
+ min-height: 0;
440
+ border: 0;
441
+ background: transparent;
442
+ }
443
+
444
+ .bsw-an--launcher-closed {
445
+ border: 0;
446
+ background: transparent;
447
+ }
448
+
449
+ .bsw-an--launcher-open,
450
+ .bsw-an-frame--window.bsw-an-frame--open,
451
+ .bsw-an-frame--launcher.bsw-an-frame--open {
452
+ display: flex;
453
+ flex-direction: column;
454
+ right: var(--bsw-an-frame-launcher-right, 0.75rem);
455
+ bottom: var(--bsw-an-frame-launcher-bottom, 0.75rem);
456
+ width: min(24rem, calc(100vw - 1.5rem));
457
+ height: min(40rem, calc(100dvh - 1.5rem));
458
+ max-height: calc(100dvh - 1.5rem);
459
+ }
460
+
461
+ .bsw-an-frame--modal.bsw-an-frame--open {
462
+ top: 0.75rem;
463
+ right: auto;
464
+ bottom: auto;
465
+ left: 50%;
466
+ display: flex;
467
+ flex-direction: column;
468
+ width: min(36rem, calc(100vw - 1.5rem));
469
+ height: min(44rem, calc(100dvh - 1.5rem));
470
+ max-height: calc(100dvh - 1.5rem);
471
+ overflow: hidden;
472
+ transform: translateX(-50%);
473
+ }
474
+
475
+ .bsw-an-frame__backdrop {
476
+ position: fixed;
477
+ inset: 0;
478
+ z-index: 0;
479
+ border: 0;
480
+ padding: 0;
481
+ background: rgb(26 26 20 / 0.4);
482
+ cursor: pointer;
483
+ }
484
+
485
+ .bsw-an-frame__panel {
486
+ position: relative;
487
+ z-index: 1;
488
+ display: flex;
489
+ flex-direction: column;
490
+ min-height: 0;
491
+ max-height: 100%;
492
+ }
493
+
494
+ .bsw-an--launcher-open .bsw-an-frame__panel,
495
+ .bsw-an-frame--window.bsw-an-frame--open .bsw-an-frame__panel,
496
+ .bsw-an-frame--modal.bsw-an-frame--open .bsw-an-frame__panel {
497
+ flex: 1 1 auto;
498
+ }
499
+
500
+ .bsw-an-frame__panel[hidden] {
501
+ display: none;
502
+ }
503
+
504
+ .bsw-an--launcher-open .bsw-an,
505
+ .bsw-an-frame--window.bsw-an-frame--open .bsw-an,
506
+ .bsw-an-frame--modal.bsw-an-frame--open .bsw-an {
507
+ flex: 1 1 auto;
508
+ height: auto;
509
+ min-height: 0;
510
+ max-height: 100%;
511
+ box-shadow: 0 22px 56px rgb(26 26 20 / 0.18);
512
+ }
513
+
514
+ .bsw-an-frame__panel .bsw-an__header {
515
+ padding-inline-end: 3rem;
516
+ }
517
+
518
+ @media (max-width: 420px) {
519
+ .bsw-an--launcher-open,
520
+ .bsw-an-frame--window.bsw-an-frame--open,
521
+ .bsw-an-frame--launcher.bsw-an-frame--open,
522
+ .bsw-an-frame--modal.bsw-an-frame--open {
523
+ right: 0.5rem;
524
+ width: calc(100vw - 1rem);
525
+ }
526
+
527
+ .bsw-an-frame--modal.bsw-an-frame--open {
528
+ right: auto;
529
+ }
530
+
531
+ .bsw-an__header,
532
+ .bsw-an__composer,
533
+ .bsw-an__log {
534
+ padding: 0.7rem;
535
+ }
536
+
537
+ .bsw-an-frame__panel .bsw-an__header {
538
+ padding-inline-end: 2.75rem;
539
+ }
540
+
541
+ .bsw-an__textarea {
542
+ min-height: 2.5rem;
543
+ }
544
+ }
545
+
546
+ .bsw-an-frame__close,
547
+ .bsw-an-frame__trigger,
548
+ .bsw-an-frame__fab {
549
+ font: inherit;
550
+ cursor: pointer;
551
+ }
552
+
553
+ .bsw-an-frame__close {
554
+ position: absolute;
555
+ top: 0.7rem;
556
+ right: 0.7rem;
557
+ z-index: 3;
558
+ width: 2rem;
559
+ height: 2rem;
560
+ margin: 0;
561
+ display: grid;
562
+ place-items: center;
563
+ border: 1px solid var(--frame-line);
564
+ background: var(--frame-bg);
565
+ color: var(--frame-fg);
566
+ border-radius: 999px;
567
+ padding: 0;
568
+ font-size: 0.7rem;
569
+ font-weight: 700;
570
+ line-height: 1;
571
+ }
572
+
573
+ .bsw-an-frame__trigger {
574
+ display: inline-flex;
575
+ align-items: center;
576
+ border: 1px solid var(--frame-line);
577
+ background: var(--frame-bg);
578
+ color: var(--frame-fg);
579
+ border-radius: 999px;
580
+ padding: 0.5rem 0.95rem;
581
+ font-weight: 650;
582
+ box-shadow: 0 10px 28px rgb(26 26 20 / 0.14);
583
+ }
584
+
585
+ .bsw-an-frame__fab {
586
+ width: 3.5rem;
587
+ height: 3.5rem;
588
+ border: 0;
589
+ border-radius: 999px;
590
+ background: var(--frame-accent);
591
+ color: var(--frame-accent-fg);
592
+ font-weight: 700;
593
+ box-shadow: 0 12px 28px rgb(26 26 20 / 0.16);
594
+ }
595
+
596
+ .bsw-an-frame__close-label {
597
+ position: absolute;
598
+ width: 1px;
599
+ height: 1px;
600
+ padding: 0;
601
+ margin: -1px;
602
+ overflow: hidden;
603
+ clip: rect(0, 0, 0, 0);
604
+ white-space: nowrap;
605
+ border: 0;
606
+ }
607
+
608
+ .bsw-an-frame__close:focus-visible,
609
+ .bsw-an-frame__trigger:focus-visible,
610
+ .bsw-an-frame__fab:focus-visible {
611
+ outline: 2px solid var(--frame-fg);
612
+ outline-offset: 2px;
613
+ }
614
+
615
+ @media (prefers-reduced-motion: reduce) {
616
+ .bsw-an *,
617
+ .bsw-an-frame * {
618
+ animation: none !important;
619
+ transition: none !important;
620
+ }
621
+ }
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@bootstrapware/answers",
3
+ "version": "0.1.0",
4
+ "description": "Embeddable source-backed Q&A. Local sample, BYO adapter, or a later Hosted runtime.",
5
+ "license": "MIT",
6
+ "private": false,
7
+ "type": "module",
8
+ "sideEffects": [
9
+ "**/*.css"
10
+ ],
11
+ "main": "./dist/index.js",
12
+ "module": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "import": "./dist/index.js"
18
+ },
19
+ "./styles.css": "./dist/styles.css",
20
+ "./answers.iife.js": "./dist/answers.iife.js"
21
+ },
22
+ "files": [
23
+ "dist",
24
+ "README.md",
25
+ "LICENSE",
26
+ "AGENTS.md",
27
+ "CHANGELOG.md"
28
+ ],
29
+ "homepage": "https://bootstrapware.co/answers/docs",
30
+ "keywords": [
31
+ "answers",
32
+ "q&a",
33
+ "citations",
34
+ "react",
35
+ "saas",
36
+ "embed"
37
+ ],
38
+ "peerDependencies": {
39
+ "react": ">=18",
40
+ "react-dom": ">=18"
41
+ },
42
+ "devDependencies": {
43
+ "@testing-library/react": "^16.3.2",
44
+ "@testing-library/user-event": "^14.6.5",
45
+ "@types/react": "^19.1.8",
46
+ "@types/react-dom": "^19.1.6",
47
+ "happy-dom": "17.4.4",
48
+ "react": "^19.1.0",
49
+ "react-dom": "^19.1.0",
50
+ "tsup": "^8.5.0",
51
+ "typescript": "^5.8.3",
52
+ "vitest": "^3.2.4",
53
+ "@bootstrapware/sdk": "0.1.1"
54
+ },
55
+ "scripts": {
56
+ "build": "node ./scripts/clean-dist.mjs && tsup && node ./scripts/copy-css.mjs",
57
+ "typecheck": "tsc --noEmit",
58
+ "test": "vitest run",
59
+ "lint": "tsc --noEmit"
60
+ }
61
+ }