@helpway/react 0.15.3 → 0.17.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.
- package/dist/index.d.ts +73 -7
- package/dist/index.js +1190 -874
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
- package/src/themed/styles.css +110 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@helpway/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "Official React SDK for Helpway — drop-in AI chat support widget with headless hooks for custom UIs.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"helpway",
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
"scripts": {
|
|
41
41
|
"build": "tsup",
|
|
42
42
|
"typecheck": "tsc --noEmit",
|
|
43
|
+
"test": "bun test",
|
|
43
44
|
"sync:icons": "bun scripts/sync-icons.ts",
|
|
44
45
|
"prepublishOnly": "bun run build",
|
|
45
46
|
"prepack": "bun run build && bun scripts/apply-publish-config.ts",
|
|
@@ -51,9 +52,10 @@
|
|
|
51
52
|
"zustand": "^5.0.11"
|
|
52
53
|
},
|
|
53
54
|
"devDependencies": {
|
|
55
|
+
"@central-icons-react/round-outlined-radius-2-stroke-2": "^1.1.213",
|
|
56
|
+
"@happy-dom/global-registrator": "^20.14.0",
|
|
54
57
|
"@types/react": "^19.1.6",
|
|
55
58
|
"@types/react-dom": "^19.1.6",
|
|
56
|
-
"@central-icons-react/round-outlined-radius-2-stroke-2": "^1.1.213",
|
|
57
59
|
"react-dom": "^19.1.6",
|
|
58
60
|
"tsup": "^8.3.5",
|
|
59
61
|
"typescript": "~5.9.3"
|
package/src/themed/styles.css
CHANGED
|
@@ -98,6 +98,15 @@
|
|
|
98
98
|
border-radius: inherit;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
+
/* A host `agentAvatar` brings its own shape and colour: every box that holds
|
|
102
|
+
one drops its tile radius and fill so the host's mark is not framed by a
|
|
103
|
+
rounded square it did not ask for. */
|
|
104
|
+
.hw-widget :is(.hw-header-bot-icon, .hw-hero-bot-icon, .hw-conv-card-avatar, .hw-event-avatar, .hw-bubble-icon--bot):has(> .hw-agent-custom) {
|
|
105
|
+
border-radius: 50%;
|
|
106
|
+
background: transparent;
|
|
107
|
+
padding: 0;
|
|
108
|
+
}
|
|
109
|
+
|
|
101
110
|
/* ── Focus Styles ──────────────────────────────── */
|
|
102
111
|
.hw-widget :focus-visible {
|
|
103
112
|
outline: 2px solid var(--hw-primary);
|
|
@@ -219,7 +228,7 @@
|
|
|
219
228
|
transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.2s ease;
|
|
220
229
|
}
|
|
221
230
|
|
|
222
|
-
.hw-bubble-icon svg {
|
|
231
|
+
.hw-bubble-icon svg:not(.hw-agent-custom svg) {
|
|
223
232
|
width: 22px;
|
|
224
233
|
height: 22px;
|
|
225
234
|
}
|
|
@@ -478,7 +487,10 @@
|
|
|
478
487
|
justify-content: center;
|
|
479
488
|
border-radius: 10px;
|
|
480
489
|
}
|
|
481
|
-
|
|
490
|
+
/* Direct children only (the Helpway mark, a preset icon): a host `agentAvatar`
|
|
491
|
+
brings its own SVG and sizing, which this must not resize. */
|
|
492
|
+
.hw-hero-bot-icon > svg,
|
|
493
|
+
.hw-hero-bot-icon > .hw-agent-icon > svg {
|
|
482
494
|
width: 32px;
|
|
483
495
|
height: 32px;
|
|
484
496
|
}
|
|
@@ -599,7 +611,8 @@
|
|
|
599
611
|
chain — exactly the cascade behavior we want. */
|
|
600
612
|
background: var(--hw-agent-bg, var(--hw-agent-bg-default, transparent));
|
|
601
613
|
}
|
|
602
|
-
.hw-header-bot-icon svg
|
|
614
|
+
.hw-header-bot-icon > svg,
|
|
615
|
+
.hw-header-bot-icon > .hw-agent-icon > svg {
|
|
603
616
|
width: 24px;
|
|
604
617
|
height: 24px;
|
|
605
618
|
}
|
|
@@ -893,7 +906,7 @@
|
|
|
893
906
|
height: 32px;
|
|
894
907
|
border-radius: 8px;
|
|
895
908
|
}
|
|
896
|
-
.hw-recent-row .hw-conv-card-avatar svg {
|
|
909
|
+
.hw-recent-row .hw-conv-card-avatar svg:not(.hw-agent-custom svg) {
|
|
897
910
|
width: 18px;
|
|
898
911
|
height: 18px;
|
|
899
912
|
}
|
|
@@ -995,7 +1008,7 @@
|
|
|
995
1008
|
flex-shrink: 0;
|
|
996
1009
|
overflow: hidden;
|
|
997
1010
|
}
|
|
998
|
-
.hw-conv-card-avatar svg {
|
|
1011
|
+
.hw-conv-card-avatar svg:not(.hw-agent-custom svg) {
|
|
999
1012
|
width: 20px;
|
|
1000
1013
|
height: 20px;
|
|
1001
1014
|
}
|
|
@@ -2755,7 +2768,7 @@
|
|
|
2755
2768
|
background: none;
|
|
2756
2769
|
}
|
|
2757
2770
|
.hw-preview.hw-preview--anchored .hw-preview-avatar img,
|
|
2758
|
-
.hw-preview.hw-preview--anchored .hw-preview-avatar svg {
|
|
2771
|
+
.hw-preview.hw-preview--anchored .hw-preview-avatar svg:not(.hw-agent-custom svg) {
|
|
2759
2772
|
width: 100%;
|
|
2760
2773
|
height: 100%;
|
|
2761
2774
|
object-fit: contain;
|
|
@@ -2807,7 +2820,7 @@
|
|
|
2807
2820
|
overflow: hidden;
|
|
2808
2821
|
}
|
|
2809
2822
|
|
|
2810
|
-
.hw-preview-avatar svg {
|
|
2823
|
+
.hw-preview-avatar svg:not(.hw-agent-custom svg) {
|
|
2811
2824
|
width: 16px;
|
|
2812
2825
|
height: 16px;
|
|
2813
2826
|
}
|
|
@@ -2903,6 +2916,62 @@
|
|
|
2903
2916
|
margin-top: 0;
|
|
2904
2917
|
}
|
|
2905
2918
|
|
|
2919
|
+
/* ── Awaiting-reply marker ───────────────────────────────
|
|
2920
|
+
A state, not an alert. It sits on a row next to product chrome and must not
|
|
2921
|
+
compete with the primary action, so: muted ink, no accent colour, no pill.
|
|
2922
|
+
Labelled rather than counted — a bare number in a coloured badge reads as
|
|
2923
|
+
"unread" and says nothing about what it counts, while these three words say
|
|
2924
|
+
the thing that decides whether the visitor comes back. */
|
|
2925
|
+
.hw-awaiting {
|
|
2926
|
+
margin-top: 2px;
|
|
2927
|
+
padding-left: 44px;
|
|
2928
|
+
font-size: 11px;
|
|
2929
|
+
line-height: 1.4;
|
|
2930
|
+
color: var(--hw-text-3, var(--hw-text-muted));
|
|
2931
|
+
}
|
|
2932
|
+
|
|
2933
|
+
/* ── Closed-state dock ───────────────────────────────────
|
|
2934
|
+
One owner for the strip above the launcher.
|
|
2935
|
+
|
|
2936
|
+
The incoming-reply card and the announcement stack were two independent
|
|
2937
|
+
absolute pins on the same anchor — both `bottom: calc(100% + 12px); right: 0`
|
|
2938
|
+
— so whenever a visitor had an unread reply AND unseen announced content,
|
|
2939
|
+
the two cards drew on top of each other. Neither was readable and the one
|
|
2940
|
+
underneath was unclickable. Nothing in either component could detect the
|
|
2941
|
+
other, which is the tell: the bug is that the region had no owner, not that
|
|
2942
|
+
one of the cards was positioned wrong.
|
|
2943
|
+
|
|
2944
|
+
The dock pins once; its children lay out in flow. Order in the markup is the
|
|
2945
|
+
priority order and it is deliberate — an actual reply from a person sits
|
|
2946
|
+
nearest the launcher, where the thumb already is, and announcements stack
|
|
2947
|
+
above it. Right-aligned rather than stretched because the two cards are
|
|
2948
|
+
different widths (300px vs 340px) and a shared left edge would read as one
|
|
2949
|
+
ragged surface instead of two cards. */
|
|
2950
|
+
.hw-preview-dock {
|
|
2951
|
+
position: absolute;
|
|
2952
|
+
bottom: calc(100% + 12px);
|
|
2953
|
+
right: 0;
|
|
2954
|
+
display: flex;
|
|
2955
|
+
flex-direction: column;
|
|
2956
|
+
align-items: flex-end;
|
|
2957
|
+
gap: 8px;
|
|
2958
|
+
/* Empty dock must not sit over the page. With no children it has zero size,
|
|
2959
|
+
but the gaps between cards are dead space either way — the cards take
|
|
2960
|
+
their own events back below. */
|
|
2961
|
+
pointer-events: none;
|
|
2962
|
+
}
|
|
2963
|
+
|
|
2964
|
+
/* Docked children give up their own pin — two classes, so this wins over the
|
|
2965
|
+
single-class `.hw-preview` / `.hw-preview-stack` rules whatever the source
|
|
2966
|
+
order. */
|
|
2967
|
+
.hw-preview-dock > .hw-preview,
|
|
2968
|
+
.hw-preview-dock > .hw-preview-stack {
|
|
2969
|
+
position: relative;
|
|
2970
|
+
bottom: auto;
|
|
2971
|
+
right: auto;
|
|
2972
|
+
pointer-events: auto;
|
|
2973
|
+
}
|
|
2974
|
+
|
|
2906
2975
|
/* ── Preview closing animation ──────────────────────────── */
|
|
2907
2976
|
.hw-preview--closing {
|
|
2908
2977
|
animation: hw-preview-out 0.2s ease-in forwards;
|
|
@@ -2936,6 +3005,30 @@
|
|
|
2936
3005
|
width: 100%;
|
|
2937
3006
|
}
|
|
2938
3007
|
|
|
3008
|
+
/* ── Overflow row ────────────────────────────────────────
|
|
3009
|
+
What is left when the announcement stack is clipped. Deliberately not a
|
|
3010
|
+
card: a fourth bordered box would be the volume problem it exists to
|
|
3011
|
+
solve. A single quiet line, right-aligned with the cards above it, that
|
|
3012
|
+
opens the next unread update. */
|
|
3013
|
+
.hw-preview-more {
|
|
3014
|
+
align-self: flex-end;
|
|
3015
|
+
padding: 4px 10px;
|
|
3016
|
+
border: 0;
|
|
3017
|
+
border-radius: 999px;
|
|
3018
|
+
background: var(--hw-bg);
|
|
3019
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08), inset 0 0 0 1px var(--hw-border);
|
|
3020
|
+
color: var(--hw-text-2);
|
|
3021
|
+
font: inherit;
|
|
3022
|
+
font-size: 12px;
|
|
3023
|
+
line-height: 1.4;
|
|
3024
|
+
cursor: pointer;
|
|
3025
|
+
transition: background 0.12s, color 0.12s;
|
|
3026
|
+
}
|
|
3027
|
+
.hw-preview-more:hover {
|
|
3028
|
+
background: var(--hw-bg-hover);
|
|
3029
|
+
color: var(--hw-text);
|
|
3030
|
+
}
|
|
3031
|
+
|
|
2939
3032
|
/* ── Announcement preview modifier ─────────────────────── */
|
|
2940
3033
|
.hw-preview--announcement {
|
|
2941
3034
|
width: 340px;
|
|
@@ -5380,6 +5473,16 @@
|
|
|
5380
5473
|
gap: 8px;
|
|
5381
5474
|
padding: 2px 0 8px;
|
|
5382
5475
|
}
|
|
5476
|
+
/* Host agent avatar at the bar's start; bottom-aligned with the actions so it
|
|
5477
|
+
stays on the first line's baseline row when the field grows. */
|
|
5478
|
+
.hw-dock-lead {
|
|
5479
|
+
flex: none;
|
|
5480
|
+
display: grid;
|
|
5481
|
+
place-items: center;
|
|
5482
|
+
width: 32px;
|
|
5483
|
+
height: 32px;
|
|
5484
|
+
margin-left: -8px;
|
|
5485
|
+
}
|
|
5383
5486
|
.hw-dock-actions {
|
|
5384
5487
|
flex: none;
|
|
5385
5488
|
display: flex;
|