@wallavi/widget 1.7.2 → 1.9.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.mts CHANGED
@@ -110,6 +110,7 @@ interface ChatWidgetConfig {
110
110
  watermarkLogoUrl?: string;
111
111
  footer?: string | null;
112
112
  theme?: "light" | "dark";
113
+ widgetLayout?: "bubble" | "center";
113
114
  showThinking?: boolean;
114
115
  regenerateMessage?: boolean;
115
116
  /**
package/dist/index.d.ts CHANGED
@@ -110,6 +110,7 @@ interface ChatWidgetConfig {
110
110
  watermarkLogoUrl?: string;
111
111
  footer?: string | null;
112
112
  theme?: "light" | "dark";
113
+ widgetLayout?: "bubble" | "center";
113
114
  showThinking?: boolean;
114
115
  regenerateMessage?: boolean;
115
116
  /**
package/dist/index.js CHANGED
@@ -61,6 +61,36 @@ function styleInject(css, { insertAt } = {}) {
61
61
  styleInject(".ww-pointer-events-none {\n pointer-events: none;\n}\n.ww-absolute {\n position: absolute;\n}\n.ww-relative {\n position: relative;\n}\n.ww-inset-0 {\n inset: 0px;\n}\n.ww-inset-4 {\n inset: 1rem;\n}\n.ww-inset-8 {\n inset: 2rem;\n}\n.ww-left-2\\.5 {\n left: 0.625rem;\n}\n.ww-top-1\\/2 {\n top: 50%;\n}\n.ww-z-50 {\n z-index: 50;\n}\n.ww-z-\\[100\\] {\n z-index: 100;\n}\n.ww-mb-1 {\n margin-bottom: 0.25rem;\n}\n.ww-mb-12 {\n margin-bottom: 3rem;\n}\n.ww-mb-2 {\n margin-bottom: 0.5rem;\n}\n.ww-ml-0\\.5 {\n margin-left: 0.125rem;\n}\n.ww-mt-0\\.5 {\n margin-top: 0.125rem;\n}\n.ww-mt-1 {\n margin-top: 0.25rem;\n}\n.ww-block {\n display: block;\n}\n.ww-inline-block {\n display: inline-block;\n}\n.ww-flex {\n display: flex;\n}\n.ww-inline-flex {\n display: inline-flex;\n}\n.ww-grid {\n display: grid;\n}\n.ww-hidden {\n display: none;\n}\n.ww-h-10 {\n height: 2.5rem;\n}\n.ww-h-16 {\n height: 4rem;\n}\n.ww-h-2 {\n height: 0.5rem;\n}\n.ww-h-2\\.5 {\n height: 0.625rem;\n}\n.ww-h-20 {\n height: 5rem;\n}\n.ww-h-3 {\n height: 0.75rem;\n}\n.ww-h-3\\.5 {\n height: 0.875rem;\n}\n.ww-h-4 {\n height: 1rem;\n}\n.ww-h-40 {\n height: 10rem;\n}\n.ww-h-48 {\n height: 12rem;\n}\n.ww-h-6 {\n height: 1.5rem;\n}\n.ww-h-7 {\n height: 1.75rem;\n}\n.ww-h-8 {\n height: 2rem;\n}\n.ww-h-full {\n height: 100%;\n}\n.ww-max-h-32 {\n max-height: 8rem;\n}\n.ww-max-h-48 {\n max-height: 12rem;\n}\n.ww-max-h-\\[168px\\] {\n max-height: 168px;\n}\n.ww-max-h-\\[180px\\] {\n max-height: 180px;\n}\n.ww-w-0\\.5 {\n width: 0.125rem;\n}\n.ww-w-10 {\n width: 2.5rem;\n}\n.ww-w-16 {\n width: 4rem;\n}\n.ww-w-2 {\n width: 0.5rem;\n}\n.ww-w-2\\.5 {\n width: 0.625rem;\n}\n.ww-w-20 {\n width: 5rem;\n}\n.ww-w-3 {\n width: 0.75rem;\n}\n.ww-w-3\\.5 {\n width: 0.875rem;\n}\n.ww-w-4 {\n width: 1rem;\n}\n.ww-w-48 {\n width: 12rem;\n}\n.ww-w-6 {\n width: 1.5rem;\n}\n.ww-w-7 {\n width: 1.75rem;\n}\n.ww-w-8 {\n width: 2rem;\n}\n.ww-w-fit {\n width: -moz-fit-content;\n width: fit-content;\n}\n.ww-w-full {\n width: 100%;\n}\n.ww-min-w-0 {\n min-width: 0px;\n}\n.ww-max-w-\\[120px\\] {\n max-width: 120px;\n}\n.ww-max-w-\\[200px\\] {\n max-width: 200px;\n}\n.ww-max-w-\\[78\\%\\] {\n max-width: 78%;\n}\n.ww-max-w-\\[82\\%\\] {\n max-width: 82%;\n}\n.ww-max-w-none {\n max-width: none;\n}\n.ww-flex-1 {\n flex: 1 1 0%;\n}\n.ww-shrink-0 {\n flex-shrink: 0;\n}\n.ww-rotate-180 {\n --tw-rotate: 180deg;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.ww-scale-100 {\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.ww-scale-105 {\n --tw-scale-x: 1.05;\n --tw-scale-y: 1.05;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.ww-scale-110 {\n --tw-scale-x: 1.1;\n --tw-scale-y: 1.1;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.ww-scale-90 {\n --tw-scale-x: .9;\n --tw-scale-y: .9;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n@keyframes ww-ping {\n 75%, 100% {\n transform: scale(2);\n opacity: 0;\n }\n}\n.ww-animate-ping {\n animation: ww-ping 1s cubic-bezier(0, 0, 0.2, 1) infinite;\n}\n@keyframes ww-pulse {\n 50% {\n opacity: .5;\n }\n}\n.ww-animate-pulse {\n animation: ww-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n}\n@keyframes ww-spin {\n to {\n transform: rotate(360deg);\n }\n}\n.ww-animate-spin {\n animation: ww-spin 1s linear infinite;\n}\n.ww-cursor-default {\n cursor: default;\n}\n.ww-cursor-pointer {\n cursor: pointer;\n}\n.ww-touch-none {\n touch-action: none;\n}\n.ww-select-none {\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n}\n.ww-resize-none {\n resize: none;\n}\n.ww-grid-cols-2 {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n}\n.ww-flex-col {\n flex-direction: column;\n}\n.ww-flex-wrap {\n flex-wrap: wrap;\n}\n.ww-items-start {\n align-items: flex-start;\n}\n.ww-items-end {\n align-items: flex-end;\n}\n.ww-items-center {\n align-items: center;\n}\n.ww-justify-end {\n justify-content: flex-end;\n}\n.ww-justify-center {\n justify-content: center;\n}\n.ww-justify-between {\n justify-content: space-between;\n}\n.ww-gap-0\\.5 {\n gap: 0.125rem;\n}\n.ww-gap-1 {\n gap: 0.25rem;\n}\n.ww-gap-1\\.5 {\n gap: 0.375rem;\n}\n.ww-gap-2 {\n gap: 0.5rem;\n}\n.ww-gap-2\\.5 {\n gap: 0.625rem;\n}\n.ww-gap-4 {\n gap: 1rem;\n}\n.ww-gap-6 {\n gap: 1.5rem;\n}\n.ww-gap-8 {\n gap: 2rem;\n}\n.ww-divide-y > :not([hidden]) ~ :not([hidden]) {\n --tw-divide-y-reverse: 0;\n border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));\n border-bottom-width: calc(1px * var(--tw-divide-y-reverse));\n}\n.ww-divide-border\\/40 > :not([hidden]) ~ :not([hidden]) {\n border-color: hsl(var(--border) / 0.4);\n}\n.ww-overflow-hidden {\n overflow: hidden;\n}\n.ww-overflow-y-auto {\n overflow-y: auto;\n}\n.ww-overscroll-contain {\n overscroll-behavior: contain;\n}\n.ww-overscroll-none {\n overscroll-behavior: none;\n}\n.ww-truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.ww-whitespace-pre-wrap {\n white-space: pre-wrap;\n}\n.ww-rounded {\n border-radius: 0.25rem;\n}\n.ww-rounded-2xl {\n border-radius: 1rem;\n}\n.ww-rounded-full {\n border-radius: 9999px;\n}\n.ww-rounded-lg {\n border-radius: var(--radius);\n}\n.ww-rounded-xl {\n border-radius: 0.75rem;\n}\n.ww-rounded-tl-none {\n border-top-left-radius: 0px;\n}\n.ww-rounded-tl-sm {\n border-top-left-radius: calc(var(--radius) - 4px);\n}\n.ww-rounded-tr-sm {\n border-top-right-radius: calc(var(--radius) - 4px);\n}\n.ww-border {\n border-width: 1px;\n}\n.ww-border-2 {\n border-width: 2px;\n}\n.ww-border-b {\n border-bottom-width: 1px;\n}\n.ww-border-l-2 {\n border-left-width: 2px;\n}\n.ww-border-t {\n border-top-width: 1px;\n}\n.ww-border-background {\n border-color: hsl(var(--background));\n}\n.ww-border-black\\/10 {\n border-color: rgb(0 0 0 / 0.1);\n}\n.ww-border-border {\n border-color: hsl(var(--border));\n}\n.ww-border-border\\/30 {\n border-color: hsl(var(--border) / 0.3);\n}\n.ww-border-border\\/40 {\n border-color: hsl(var(--border) / 0.4);\n}\n.ww-border-border\\/50 {\n border-color: hsl(var(--border) / 0.5);\n}\n.ww-border-border\\/60 {\n border-color: hsl(var(--border) / 0.6);\n}\n.ww-border-border\\/80 {\n border-color: hsl(var(--border) / 0.8);\n}\n.ww-border-muted {\n border-color: hsl(var(--muted));\n}\n.ww-border-muted-foreground\\/30 {\n border-color: hsl(var(--muted-foreground) / 0.3);\n}\n.ww-border-red-200 {\n --tw-border-opacity: 1;\n border-color: rgb(254 202 202 / var(--tw-border-opacity, 1));\n}\n.ww-border-transparent {\n border-color: transparent;\n}\n.ww-border-white\\/20 {\n border-color: rgb(255 255 255 / 0.2);\n}\n.ww-bg-background {\n background-color: hsl(var(--background));\n}\n.ww-bg-background\\/20 {\n background-color: hsl(var(--background) / 0.2);\n}\n.ww-bg-background\\/90 {\n background-color: hsl(var(--background) / 0.9);\n}\n.ww-bg-background\\/95 {\n background-color: hsl(var(--background) / 0.95);\n}\n.ww-bg-black\\/10 {\n background-color: rgb(0 0 0 / 0.1);\n}\n.ww-bg-emerald-400 {\n --tw-bg-opacity: 1;\n background-color: rgb(52 211 153 / var(--tw-bg-opacity, 1));\n}\n.ww-bg-emerald-500 {\n --tw-bg-opacity: 1;\n background-color: rgb(16 185 129 / var(--tw-bg-opacity, 1));\n}\n.ww-bg-emerald-500\\/10 {\n background-color: rgb(16 185 129 / 0.1);\n}\n.ww-bg-emerald-500\\/20 {\n background-color: rgb(16 185 129 / 0.2);\n}\n.ww-bg-foreground\\/20 {\n background-color: hsl(var(--foreground) / 0.2);\n}\n.ww-bg-foreground\\/5 {\n background-color: hsl(var(--foreground) / 0.05);\n}\n.ww-bg-foreground\\/60 {\n background-color: hsl(var(--foreground) / 0.6);\n}\n.ww-bg-muted {\n background-color: hsl(var(--muted));\n}\n.ww-bg-muted-foreground\\/10 {\n background-color: hsl(var(--muted-foreground) / 0.1);\n}\n.ww-bg-muted\\/30 {\n background-color: hsl(var(--muted) / 0.3);\n}\n.ww-bg-muted\\/40 {\n background-color: hsl(var(--muted) / 0.4);\n}\n.ww-bg-muted\\/50 {\n background-color: hsl(var(--muted) / 0.5);\n}\n.ww-bg-muted\\/60 {\n background-color: hsl(var(--muted) / 0.6);\n}\n.ww-bg-primary {\n background-color: hsl(var(--primary));\n}\n.ww-bg-primary\\/5 {\n background-color: hsl(var(--primary) / 0.05);\n}\n.ww-bg-purple-500\\/20 {\n background-color: rgb(168 85 247 / 0.2);\n}\n.ww-bg-purple-500\\/30 {\n background-color: rgb(168 85 247 / 0.3);\n}\n.ww-bg-red-50 {\n --tw-bg-opacity: 1;\n background-color: rgb(254 242 242 / var(--tw-bg-opacity, 1));\n}\n.ww-bg-transparent {\n background-color: transparent;\n}\n.ww-bg-white\\/10 {\n background-color: rgb(255 255 255 / 0.1);\n}\n.ww-bg-white\\/15 {\n background-color: rgb(255 255 255 / 0.15);\n}\n.ww-fill-current {\n fill: currentColor;\n}\n.ww-object-cover {\n -o-object-fit: cover;\n object-fit: cover;\n}\n.ww-p-0\\.5 {\n padding: 0.125rem;\n}\n.ww-p-1\\.5 {\n padding: 0.375rem;\n}\n.ww-p-3 {\n padding: 0.75rem;\n}\n.ww-px-1 {\n padding-left: 0.25rem;\n padding-right: 0.25rem;\n}\n.ww-px-2 {\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n}\n.ww-px-3 {\n padding-left: 0.75rem;\n padding-right: 0.75rem;\n}\n.ww-px-3\\.5 {\n padding-left: 0.875rem;\n padding-right: 0.875rem;\n}\n.ww-px-4 {\n padding-left: 1rem;\n padding-right: 1rem;\n}\n.ww-py-0\\.5 {\n padding-top: 0.125rem;\n padding-bottom: 0.125rem;\n}\n.ww-py-1 {\n padding-top: 0.25rem;\n padding-bottom: 0.25rem;\n}\n.ww-py-1\\.5 {\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n}\n.ww-py-2 {\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n}\n.ww-py-2\\.5 {\n padding-top: 0.625rem;\n padding-bottom: 0.625rem;\n}\n.ww-py-3 {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n}\n.ww-py-4 {\n padding-top: 1rem;\n padding-bottom: 1rem;\n}\n.ww-pb-1\\.5 {\n padding-bottom: 0.375rem;\n}\n.ww-pb-2 {\n padding-bottom: 0.5rem;\n}\n.ww-pb-4 {\n padding-bottom: 1rem;\n}\n.ww-pl-2 {\n padding-left: 0.5rem;\n}\n.ww-pl-7 {\n padding-left: 1.75rem;\n}\n.ww-pr-0\\.5 {\n padding-right: 0.125rem;\n}\n.ww-pr-3 {\n padding-right: 0.75rem;\n}\n.ww-pt-2 {\n padding-top: 0.5rem;\n}\n.ww-pt-5 {\n padding-top: 1.25rem;\n}\n.ww-text-left {\n text-align: left;\n}\n.ww-text-center {\n text-align: center;\n}\n.ww-align-middle {\n vertical-align: middle;\n}\n.ww-text-\\[10\\.5px\\] {\n font-size: 10.5px;\n}\n.ww-text-\\[10px\\] {\n font-size: 10px;\n}\n.ww-text-\\[11px\\] {\n font-size: 11px;\n}\n.ww-text-\\[12\\.5px\\] {\n font-size: 12.5px;\n}\n.ww-text-\\[13px\\] {\n font-size: 13px;\n}\n.ww-text-\\[8px\\] {\n font-size: 8px;\n}\n.ww-text-sm {\n font-size: 0.875rem;\n line-height: 1.25rem;\n}\n.ww-text-xs {\n font-size: 0.75rem;\n line-height: 1rem;\n}\n.ww-font-medium {\n font-weight: 500;\n}\n.ww-font-semibold {\n font-weight: 600;\n}\n.ww-uppercase {\n text-transform: uppercase;\n}\n.ww-leading-none {\n line-height: 1;\n}\n.ww-leading-relaxed {\n line-height: 1.625;\n}\n.ww-leading-snug {\n line-height: 1.375;\n}\n.ww-leading-tight {\n line-height: 1.25;\n}\n.ww-tracking-wide {\n letter-spacing: 0.025em;\n}\n.ww-tracking-widest {\n letter-spacing: 0.1em;\n}\n.ww-text-black\\/40 {\n color: rgb(0 0 0 / 0.4);\n}\n.ww-text-black\\/60 {\n color: rgb(0 0 0 / 0.6);\n}\n.ww-text-destructive {\n color: hsl(var(--destructive));\n}\n.ww-text-destructive\\/70 {\n color: hsl(var(--destructive) / 0.7);\n}\n.ww-text-emerald-500 {\n --tw-text-opacity: 1;\n color: rgb(16 185 129 / var(--tw-text-opacity, 1));\n}\n.ww-text-foreground {\n color: hsl(var(--foreground));\n}\n.ww-text-foreground\\/60 {\n color: hsl(var(--foreground) / 0.6);\n}\n.ww-text-foreground\\/70 {\n color: hsl(var(--foreground) / 0.7);\n}\n.ww-text-foreground\\/80 {\n color: hsl(var(--foreground) / 0.8);\n}\n.ww-text-muted-foreground {\n color: hsl(var(--muted-foreground));\n}\n.ww-text-muted-foreground\\/40 {\n color: hsl(var(--muted-foreground) / 0.4);\n}\n.ww-text-muted-foreground\\/50 {\n color: hsl(var(--muted-foreground) / 0.5);\n}\n.ww-text-muted-foreground\\/70 {\n color: hsl(var(--muted-foreground) / 0.7);\n}\n.ww-text-muted-foreground\\/80 {\n color: hsl(var(--muted-foreground) / 0.8);\n}\n.ww-text-primary {\n color: hsl(var(--primary));\n}\n.ww-text-primary-foreground {\n color: hsl(var(--primary-foreground));\n}\n.ww-text-primary\\/70 {\n color: hsl(var(--primary) / 0.7);\n}\n.ww-text-primary\\/80 {\n color: hsl(var(--primary) / 0.8);\n}\n.ww-text-red-400 {\n --tw-text-opacity: 1;\n color: rgb(248 113 113 / var(--tw-text-opacity, 1));\n}\n.ww-text-red-500 {\n --tw-text-opacity: 1;\n color: rgb(239 68 68 / var(--tw-text-opacity, 1));\n}\n.ww-text-red-600 {\n --tw-text-opacity: 1;\n color: rgb(220 38 38 / var(--tw-text-opacity, 1));\n}\n.ww-text-white {\n --tw-text-opacity: 1;\n color: rgb(255 255 255 / var(--tw-text-opacity, 1));\n}\n.ww-text-white\\/60 {\n color: rgb(255 255 255 / 0.6);\n}\n.ww-text-white\\/80 {\n color: rgb(255 255 255 / 0.8);\n}\n.ww-line-through {\n text-decoration-line: line-through;\n}\n.ww-no-underline {\n text-decoration-line: none;\n}\n.ww-decoration-foreground\\/20 {\n text-decoration-color: hsl(var(--foreground) / 0.2);\n}\n.ww-opacity-100 {\n opacity: 1;\n}\n.ww-opacity-25 {\n opacity: 0.25;\n}\n.ww-opacity-30 {\n opacity: 0.3;\n}\n.ww-opacity-40 {\n opacity: 0.4;\n}\n.ww-opacity-60 {\n opacity: 0.6;\n}\n.ww-opacity-70 {\n opacity: 0.7;\n}\n.ww-opacity-75 {\n opacity: 0.75;\n}\n.ww-opacity-80 {\n opacity: 0.8;\n}\n.ww-opacity-90 {\n opacity: 0.9;\n}\n.ww-shadow-2xl {\n --tw-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);\n --tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);\n box-shadow:\n var(--tw-ring-offset-shadow, 0 0 #0000),\n var(--tw-ring-shadow, 0 0 #0000),\n var(--tw-shadow);\n}\n.ww-shadow-lg {\n --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);\n box-shadow:\n var(--tw-ring-offset-shadow, 0 0 #0000),\n var(--tw-ring-shadow, 0 0 #0000),\n var(--tw-shadow);\n}\n.ww-shadow-md {\n --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);\n box-shadow:\n var(--tw-ring-offset-shadow, 0 0 #0000),\n var(--tw-ring-shadow, 0 0 #0000),\n var(--tw-shadow);\n}\n.ww-shadow-sm {\n --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);\n box-shadow:\n var(--tw-ring-offset-shadow, 0 0 #0000),\n var(--tw-ring-shadow, 0 0 #0000),\n var(--tw-shadow);\n}\n.ww-shadow-xl {\n --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);\n box-shadow:\n var(--tw-ring-offset-shadow, 0 0 #0000),\n var(--tw-ring-shadow, 0 0 #0000),\n var(--tw-shadow);\n}\n.ww-outline-none {\n outline: 2px solid transparent;\n outline-offset: 2px;\n}\n.ww-ring-2 {\n --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);\n box-shadow:\n var(--tw-ring-offset-shadow),\n var(--tw-ring-shadow),\n var(--tw-shadow, 0 0 #0000);\n}\n.ww-ring-inset {\n --tw-ring-inset: inset;\n}\n.ww-ring-primary\\/20 {\n --tw-ring-color: hsl(var(--primary) / 0.2);\n}\n.ww-ring-primary\\/60 {\n --tw-ring-color: hsl(var(--primary) / 0.6);\n}\n.ww-backdrop-blur-sm {\n --tw-backdrop-blur: blur(4px);\n backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);\n}\n.ww-backdrop-blur-xl {\n --tw-backdrop-blur: blur(24px);\n backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);\n}\n.ww-transition-all {\n transition-property: all;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.ww-transition-colors {\n transition-property:\n color,\n background-color,\n border-color,\n text-decoration-color,\n fill,\n stroke;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.ww-transition-opacity {\n transition-property: opacity;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.ww-transition-shadow {\n transition-property: box-shadow;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.ww-transition-transform {\n transition-property: transform;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.ww-duration-1000 {\n transition-duration: 1000ms;\n}\n.ww-duration-200 {\n transition-duration: 200ms;\n}\n.ww-duration-300 {\n transition-duration: 300ms;\n}\n.ww-duration-500 {\n transition-duration: 500ms;\n}\n.ww-duration-700 {\n transition-duration: 700ms;\n}\n@keyframes enter {\n from {\n opacity: var(--tw-enter-opacity, 1);\n transform: translate3d(var(--tw-enter-translate-x, 0), var(--tw-enter-translate-y, 0), 0) scale3d(var(--tw-enter-scale, 1), var(--tw-enter-scale, 1), var(--tw-enter-scale, 1)) rotate(var(--tw-enter-rotate, 0));\n }\n}\n@keyframes exit {\n to {\n opacity: var(--tw-exit-opacity, 1);\n transform: translate3d(var(--tw-exit-translate-x, 0), var(--tw-exit-translate-y, 0), 0) scale3d(var(--tw-exit-scale, 1), var(--tw-exit-scale, 1), var(--tw-exit-scale, 1)) rotate(var(--tw-exit-rotate, 0));\n }\n}\n.ww-duration-1000 {\n animation-duration: 1000ms;\n}\n.ww-duration-200 {\n animation-duration: 200ms;\n}\n.ww-duration-300 {\n animation-duration: 300ms;\n}\n.ww-duration-500 {\n animation-duration: 500ms;\n}\n.ww-duration-700 {\n animation-duration: 700ms;\n}\n.wallavi-widget *,\n.wallavi-widget *::before,\n.wallavi-widget *::after {\n box-sizing: border-box;\n border-width: 0;\n border-style: solid;\n}\n.wallavi-widget button {\n -moz-appearance: none;\n appearance: none;\n -webkit-appearance: none;\n background: transparent;\n border: none;\n cursor: pointer;\n}\n.wallavi-widget textarea,\n.wallavi-widget input,\n.wallavi-widget select {\n font-family: inherit;\n font-size: inherit;\n}\n.wallavi-widget img,\n.wallavi-widget video {\n max-width: 100%;\n height: auto;\n}\n.wallavi-widget .lk-control-bar {\n background: transparent !important;\n border: none !important;\n box-shadow: none !important;\n padding: 0 !important;\n gap: 1.5rem !important;\n justify-content: center !important;\n}\n.wallavi-widget .lk-button {\n background: rgba(25, 25, 28, 0.05) !important;\n border-radius: 9999px !important;\n padding: 1.25rem !important;\n color: var(--ww-fg, #19191c) !important;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1) !important;\n border: 1px solid rgba(25, 25, 28, 0.1) !important;\n}\n.wallavi-widget .lk-button:hover {\n background: rgba(25, 25, 28, 0.1) !important;\n transform: scale(1.05) !important;\n}\n.wallavi-widget .lk-disconnect-button {\n background: #ef4444 !important;\n color: white !important;\n border: none !important;\n}\n.wallavi-widget .lk-disconnect-button:hover {\n background: #dc2626 !important;\n}\n.wallavi-widget .lk-device-menu {\n bottom: 100% !important;\n top: auto !important;\n margin-bottom: 1rem !important;\n max-width: 250px !important;\n width: -moz-max-content !important;\n width: max-content !important;\n left: 50% !important;\n transform: translateX(-50%) !important;\n background: #ffffff !important;\n border-radius: 16px !important;\n box-shadow: 0 20px 40px -10px rgba(0, 0, 0, 0.15), 0 10px 20px -10px rgba(0, 0, 0, 0.1) !important;\n z-index: 1000 !important;\n overflow: hidden !important;\n border: 1px solid rgba(0, 0, 0, 0.05) !important;\n padding: 0.5rem !important;\n}\n.wallavi-widget .lk-device-menu > li {\n padding: 0.75rem 1rem !important;\n font-size: 0.875rem !important;\n color: #19191c !important;\n white-space: nowrap !important;\n overflow: hidden !important;\n text-overflow: ellipsis !important;\n border-radius: 8px !important;\n transition: background 0.15s !important;\n}\n.wallavi-widget .lk-device-menu > li:hover {\n background: rgba(0, 0, 0, 0.05) !important;\n}\n.wallavi-widget .lk-device-menu > li.lk-active {\n background: rgba(0, 0, 0, 0.08) !important;\n font-weight: 600 !important;\n}\n.placeholder\\:ww-text-muted-foreground\\/40::-moz-placeholder {\n color: hsl(var(--muted-foreground) / 0.4);\n}\n.placeholder\\:ww-text-muted-foreground\\/40::placeholder {\n color: hsl(var(--muted-foreground) / 0.4);\n}\n.placeholder\\:ww-text-muted-foreground\\/50::-moz-placeholder {\n color: hsl(var(--muted-foreground) / 0.5);\n}\n.placeholder\\:ww-text-muted-foreground\\/50::placeholder {\n color: hsl(var(--muted-foreground) / 0.5);\n}\n.focus-within\\:ww-ring-1:focus-within {\n --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);\n box-shadow:\n var(--tw-ring-offset-shadow),\n var(--tw-ring-shadow),\n var(--tw-shadow, 0 0 #0000);\n}\n.focus-within\\:ww-ring-ring\\/40:focus-within {\n --tw-ring-color: hsl(var(--ring) / 0.4);\n}\n.hover\\:-ww-translate-y-1:hover {\n --tw-translate-y: -0.25rem;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.hover\\:ww-border-primary\\/40:hover {\n border-color: hsl(var(--primary) / 0.4);\n}\n.hover\\:ww-bg-accent:hover {\n background-color: hsl(var(--accent));\n}\n.hover\\:ww-bg-foreground\\/10:hover {\n background-color: hsl(var(--foreground) / 0.1);\n}\n.hover\\:ww-bg-foreground\\/30:hover {\n background-color: hsl(var(--foreground) / 0.3);\n}\n.hover\\:ww-bg-muted:hover {\n background-color: hsl(var(--muted));\n}\n.hover\\:ww-bg-white\\/10:hover {\n background-color: rgb(255 255 255 / 0.1);\n}\n.hover\\:ww-text-accent-foreground:hover {\n color: hsl(var(--accent-foreground));\n}\n.hover\\:ww-text-foreground:hover {\n color: hsl(var(--foreground));\n}\n.hover\\:ww-text-primary:hover {\n color: hsl(var(--primary));\n}\n.hover\\:ww-opacity-80:hover {\n opacity: 0.8;\n}\n.hover\\:ww-opacity-85:hover {\n opacity: 0.85;\n}\n.hover\\:ww-shadow-sm:hover {\n --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);\n box-shadow:\n var(--tw-ring-offset-shadow, 0 0 #0000),\n var(--tw-ring-shadow, 0 0 #0000),\n var(--tw-shadow);\n}\n.hover\\:ww-shadow-xl:hover {\n --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);\n box-shadow:\n var(--tw-ring-offset-shadow, 0 0 #0000),\n var(--tw-ring-shadow, 0 0 #0000),\n var(--tw-shadow);\n}\n.focus\\:ww-ring-1:focus {\n --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);\n box-shadow:\n var(--tw-ring-offset-shadow),\n var(--tw-ring-shadow),\n var(--tw-shadow, 0 0 #0000);\n}\n.focus\\:ww-ring-ring\\/40:focus {\n --tw-ring-color: hsl(var(--ring) / 0.4);\n}\n.active\\:ww-scale-\\[0\\.98\\]:active {\n --tw-scale-x: 0.98;\n --tw-scale-y: 0.98;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.disabled\\:ww-pointer-events-none:disabled {\n pointer-events: none;\n}\n.disabled\\:ww-opacity-40:disabled {\n opacity: 0.4;\n}\n.disabled\\:ww-opacity-50:disabled {\n opacity: 0.5;\n}\n.dark\\:ww-border-red-800:is(.ww-dark *) {\n --tw-border-opacity: 1;\n border-color: rgb(153 27 27 / var(--tw-border-opacity, 1));\n}\n.dark\\:ww-bg-red-950:is(.ww-dark *) {\n --tw-bg-opacity: 1;\n background-color: rgb(69 10 10 / var(--tw-bg-opacity, 1));\n}\n.dark\\:ww-text-red-400:is(.ww-dark *) {\n --tw-text-opacity: 1;\n color: rgb(248 113 113 / var(--tw-text-opacity, 1));\n}\n");
62
62
  var twMerge = tailwindMerge.extendTailwindMerge({ prefix: "ww-" });
63
63
  var cn = (...inputs) => twMerge(clsx.clsx(inputs));
64
+ async function getFreshClerkToken() {
65
+ if (typeof window === "undefined") return null;
66
+ const clerk = window.Clerk;
67
+ if (!clerk?.session) return null;
68
+ try {
69
+ let token = await clerk.session.getToken();
70
+ if (token) {
71
+ const payloadBase64 = token.split(".")[1];
72
+ if (payloadBase64) {
73
+ const payloadJson = JSON.parse(
74
+ atob(payloadBase64.replace(/-/g, "+").replace(/_/g, "/"))
75
+ );
76
+ const exp = payloadJson.exp;
77
+ if (exp && typeof exp === "number") {
78
+ const nowSeconds = Math.floor(Date.now() / 1e3);
79
+ if (exp - nowSeconds < 30) {
80
+ token = await clerk.session.getToken({ skipCache: true });
81
+ }
82
+ }
83
+ }
84
+ }
85
+ return token;
86
+ } catch (e) {
87
+ try {
88
+ return await clerk.session.getToken();
89
+ } catch {
90
+ return null;
91
+ }
92
+ }
93
+ }
64
94
 
65
95
  // src/lib/types.ts
66
96
  function getContrastColor(hex) {
@@ -262,13 +292,11 @@ function useVoiceCall({
262
292
  try {
263
293
  const isPrivate = Boolean(workspaceId);
264
294
  const url = isPrivate ? `${API_URL}/api/threads/${threadId}/livekit-token?agentId=${encodeURIComponent(agentId)}` : `${API_URL}/api/chat/livekit-token?agentId=${encodeURIComponent(agentId)}&threadId=${encodeURIComponent(threadId)}`;
295
+ const token2 = isPrivate ? await getFreshClerkToken() : null;
265
296
  const res = await fetch(url, {
266
- headers: isPrivate && typeof window !== "undefined" ? (
267
- // @ts-ignore
268
- {
269
- Authorization: `Bearer ${await window.Clerk?.session?.getToken()}`
270
- }
271
- ) : {}
297
+ headers: {
298
+ ...token2 ? { Authorization: `Bearer ${token2}` } : {}
299
+ }
272
300
  });
273
301
  const data = await res.json();
274
302
  if (!res.ok) throw new Error(data.error || "Failed to start call");
@@ -349,6 +377,10 @@ function useChat({
349
377
  if (proto.path.startsWith("/")) onNavigateRef.current?.(proto.path);
350
378
  return;
351
379
  }
380
+ if (proto.type === "client-action") {
381
+ executeDeclarativeSteps(proto.steps, onNavigateRef.current);
382
+ return;
383
+ }
352
384
  if (proto.type === "debug-trace") {
353
385
  setDebugTraces((prev) => [
354
386
  ...prev,
@@ -364,7 +396,7 @@ function useChat({
364
396
  async (opts) => {
365
397
  const { input: userInput, msgId, extraMetadata, attachments } = opts;
366
398
  const isPrivate = Boolean(workspaceId);
367
- const token = isPrivate && typeof window !== "undefined" ? await window.Clerk?.session?.getToken() : null;
399
+ const token = isPrivate ? await getFreshClerkToken() : null;
368
400
  const url = isPrivate ? `${API_URL2}/api/threads/${threadId}/stream` : `${API_URL2}/api/chat/stream`;
369
401
  const res = await fetch(url, {
370
402
  method: "POST",
@@ -496,7 +528,7 @@ function useChat({
496
528
  void (async () => {
497
529
  try {
498
530
  const isPrivate = Boolean(workspaceId);
499
- const token = isPrivate && typeof window !== "undefined" ? await window.Clerk?.session?.getToken() : null;
531
+ const token = isPrivate ? await getFreshClerkToken() : null;
500
532
  const url = isPrivate ? `${API_URL2}/api/threads/${threadId}/messages` : `${API_URL2}/api/chat/messages?agentId=${encodeURIComponent(agentId)}&threadId=${encodeURIComponent(threadId)}`;
501
533
  const res = await fetch(url, {
502
534
  headers: {
@@ -727,6 +759,82 @@ function useChat({
727
759
  voiceCall
728
760
  };
729
761
  }
762
+ function executeDeclarativeSteps(steps, onNavigate) {
763
+ if (typeof window === "undefined" || !Array.isArray(steps)) return;
764
+ for (const step of steps) {
765
+ try {
766
+ const { action, selector, value, payload } = step;
767
+ switch (action) {
768
+ case "scroll_into_view": {
769
+ if (!selector) break;
770
+ const el = document.querySelector(selector);
771
+ el?.scrollIntoView({ behavior: "smooth", block: "center" });
772
+ break;
773
+ }
774
+ case "click": {
775
+ if (!selector) break;
776
+ const el = document.querySelector(selector);
777
+ el?.click();
778
+ break;
779
+ }
780
+ case "focus": {
781
+ if (!selector) break;
782
+ const el = document.querySelector(selector);
783
+ el?.focus();
784
+ break;
785
+ }
786
+ case "add_class": {
787
+ if (!selector || !value) break;
788
+ const el = document.querySelector(selector);
789
+ if (el) el.classList.add(...value.split(/\s+/).filter(Boolean));
790
+ break;
791
+ }
792
+ case "remove_class": {
793
+ if (!selector || !value) break;
794
+ const el = document.querySelector(selector);
795
+ if (el) el.classList.remove(...value.split(/\s+/).filter(Boolean));
796
+ break;
797
+ }
798
+ case "fill_value": {
799
+ if (!selector) break;
800
+ const el = document.querySelector(selector);
801
+ if (el) {
802
+ el.value = value ?? "";
803
+ el.dispatchEvent(new Event("input", { bubbles: true }));
804
+ el.dispatchEvent(new Event("change", { bubbles: true }));
805
+ }
806
+ break;
807
+ }
808
+ case "dispatch_event": {
809
+ if (!value) break;
810
+ const detail = payload ?? {};
811
+ window.dispatchEvent(new CustomEvent(value, { detail }));
812
+ break;
813
+ }
814
+ case "navigate": {
815
+ if (value) {
816
+ if (onNavigate) {
817
+ onNavigate(value);
818
+ } else {
819
+ window.location.href = value;
820
+ }
821
+ }
822
+ break;
823
+ }
824
+ default:
825
+ console.warn(
826
+ `[Wallavi Widget] Unknown declarative action: ${action}`
827
+ );
828
+ }
829
+ } catch (err) {
830
+ console.error(
831
+ "[Wallavi Widget] Failed to execute declarative step:",
832
+ step,
833
+ err
834
+ );
835
+ }
836
+ }
837
+ }
730
838
  function getPreferredMimeType() {
731
839
  if (typeof MediaRecorder === "undefined") return "";
732
840
  const candidates = [
@@ -2566,6 +2674,7 @@ var EMPTY = {
2566
2674
  autoOpen: false,
2567
2675
  keyboardShortcut: false,
2568
2676
  position: "bottom-right",
2677
+ widgetLayout: "bubble",
2569
2678
  bubbleSize: 52,
2570
2679
  panelWidth: 360,
2571
2680
  panelHeight: 580,
@@ -2605,6 +2714,8 @@ function useAutoConfig(agentId, enabled) {
2605
2714
  remote.showThinking = cfg.showThinking;
2606
2715
  if (cfg.regenerateMessage != null)
2607
2716
  remote.regenerateMessage = cfg.regenerateMessage;
2717
+ if (cfg.widgetLayout)
2718
+ remote.widgetLayout = cfg.widgetLayout;
2608
2719
  if (cfg.enableVoice != null)
2609
2720
  remote.enableVoice = cfg.enableVoice;
2610
2721
  setResult({
@@ -2613,6 +2724,7 @@ function useAutoConfig(agentId, enabled) {
2613
2724
  autoOpen: Boolean(cfg.autoOpen),
2614
2725
  keyboardShortcut: Boolean(cfg.keyboardShortcut),
2615
2726
  position: cfg.alignChatBubbleButton === "left" ? "bottom-left" : "bottom-right",
2727
+ widgetLayout: cfg.widgetLayout === "center" ? "center" : "bubble",
2616
2728
  bubbleSize: typeof cfg.bubbleSize === "number" ? cfg.bubbleSize : 52,
2617
2729
  panelWidth: typeof cfg.panelWidth === "number" ? cfg.panelWidth : 360,
2618
2730
  panelHeight: typeof cfg.panelHeight === "number" ? cfg.panelHeight : 580,
@@ -3071,6 +3183,7 @@ function BubbleWidget({
3071
3183
  !inboxToken && autoConfig
3072
3184
  );
3073
3185
  const resolvedPosition = remote.position ?? positionProp;
3186
+ const resolvedLayout = remote.widgetLayout ?? chatProps.widgetLayout ?? "bubble";
3074
3187
  const resolvedBubbleIcon = remote.bubbleIconUrl ?? bubbleIconUrlProp;
3075
3188
  const resolvedAutoOpen = remote.autoOpen || autoOpenProp;
3076
3189
  const resolvedKeyboardShortcut = remote.keyboardShortcut || keyboardShortcutProp;
@@ -3138,83 +3251,108 @@ function BubbleWidget({
3138
3251
  typeof window !== "undefined" ? window.innerWidth - 40 : expandedWidth
3139
3252
  ) : resolvedWidth;
3140
3253
  const panelHeight = expanded ? expandedHeight : resolvedHeight;
3141
- return /* @__PURE__ */ jsxRuntime.jsxs(
3142
- "div",
3143
- {
3144
- style: {
3145
- position: "fixed",
3146
- bottom: 20,
3147
- [isLeft ? "left" : "right"]: 20,
3148
- zIndex: 9999,
3149
- display: "flex",
3150
- flexDirection: "column",
3151
- alignItems: isLeft ? "flex-start" : "flex-end",
3152
- gap: 12
3153
- },
3154
- children: [
3155
- /* @__PURE__ */ jsxRuntime.jsx(
3156
- "div",
3157
- {
3158
- ref: panelRef,
3159
- "aria-hidden": !open,
3160
- style: {
3161
- display: open ? "block" : "none",
3162
- width: panelWidth,
3163
- height: panelHeight,
3164
- transition: "width 0.3s ease, height 0.3s ease"
3165
- },
3166
- children: /* @__PURE__ */ jsxRuntime.jsx(
3167
- ChatWidget,
3168
- {
3169
- ...mergedConfig,
3170
- agentId: inboxToken ? "support" : chatProps.agentId ?? "",
3171
- customBackend: inboxToken ? supportBackend : mergedConfig.customBackend,
3172
- onClose: handleClose,
3173
- onExpand: toggleExpanded,
3174
- expanded,
3175
- className: cn("ww-shadow-2xl ww-h-full", panelClassName)
3176
- }
3177
- )
3178
- }
3179
- ),
3180
- !hideBubble && /* @__PURE__ */ jsxRuntime.jsx(
3181
- "button",
3182
- {
3183
- onClick: () => setOpen((v) => !v),
3184
- title: open ? "Close chat" : "Open chat",
3185
- style: {
3186
- width: resolvedBubbleSize,
3187
- height: resolvedBubbleSize,
3188
- borderRadius: "50%",
3189
- border: "1px solid rgba(0,0,0,0.1)",
3190
- boxShadow: "0 4px 16px rgba(0,0,0,0.16)",
3191
- cursor: "pointer",
3192
- overflow: "hidden",
3193
- display: "flex",
3194
- alignItems: "center",
3195
- justifyContent: "center",
3196
- transition: "transform 0.2s ease, box-shadow 0.2s ease",
3197
- background: open ? "#19191c" : "#ffffff",
3198
- color: open ? "#ffffff" : "#19191c"
3199
- },
3200
- children: open ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { style: { width: 20, height: 20 } }) : resolvedBubbleIcon ? /* @__PURE__ */ jsxRuntime.jsx(
3201
- "img",
3202
- {
3203
- src: resolvedBubbleIcon,
3204
- alt: "",
3205
- style: {
3206
- width: "100%",
3207
- height: "100%",
3208
- objectFit: "cover",
3209
- display: "block"
3254
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3255
+ resolvedLayout === "center" && open && /* @__PURE__ */ jsxRuntime.jsx(
3256
+ "div",
3257
+ {
3258
+ onClick: handleClose,
3259
+ style: {
3260
+ position: "fixed",
3261
+ inset: 0,
3262
+ background: "rgba(0, 0, 0, 0.4)",
3263
+ backdropFilter: "blur(4px)",
3264
+ zIndex: 9998
3265
+ }
3266
+ }
3267
+ ),
3268
+ /* @__PURE__ */ jsxRuntime.jsxs(
3269
+ "div",
3270
+ {
3271
+ style: {
3272
+ position: "fixed",
3273
+ bottom: 20,
3274
+ [isLeft ? "left" : "right"]: 20,
3275
+ zIndex: 9999,
3276
+ display: "flex",
3277
+ flexDirection: "column",
3278
+ alignItems: isLeft ? "flex-start" : "flex-end",
3279
+ gap: 12
3280
+ },
3281
+ children: [
3282
+ /* @__PURE__ */ jsxRuntime.jsx(
3283
+ "div",
3284
+ {
3285
+ ref: panelRef,
3286
+ "aria-hidden": !open,
3287
+ style: resolvedLayout === "center" ? {
3288
+ display: open ? "block" : "none",
3289
+ position: "fixed",
3290
+ top: "50%",
3291
+ left: "50%",
3292
+ transform: "translate(-50%, -50%)",
3293
+ zIndex: 9999,
3294
+ width: panelWidth,
3295
+ height: panelHeight,
3296
+ transition: "width 0.3s ease, height 0.3s ease"
3297
+ } : {
3298
+ display: open ? "block" : "none",
3299
+ width: panelWidth,
3300
+ height: panelHeight,
3301
+ transition: "width 0.3s ease, height 0.3s ease"
3302
+ },
3303
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3304
+ ChatWidget,
3305
+ {
3306
+ ...mergedConfig,
3307
+ agentId: inboxToken ? "support" : chatProps.agentId ?? "",
3308
+ customBackend: inboxToken ? supportBackend : mergedConfig.customBackend,
3309
+ onClose: handleClose,
3310
+ onExpand: toggleExpanded,
3311
+ expanded,
3312
+ className: cn("ww-shadow-2xl ww-h-full", panelClassName)
3210
3313
  }
3211
- }
3212
- ) : /* @__PURE__ */ jsxRuntime.jsx(DefaultIcon, {})
3213
- }
3214
- )
3215
- ]
3216
- }
3217
- );
3314
+ )
3315
+ }
3316
+ ),
3317
+ !hideBubble && /* @__PURE__ */ jsxRuntime.jsx(
3318
+ "button",
3319
+ {
3320
+ onClick: () => setOpen((v) => !v),
3321
+ title: open ? "Close chat" : "Open chat",
3322
+ style: {
3323
+ width: resolvedBubbleSize,
3324
+ height: resolvedBubbleSize,
3325
+ borderRadius: "50%",
3326
+ border: "1px solid rgba(0,0,0,0.1)",
3327
+ boxShadow: "0 4px 16px rgba(0,0,0,0.16)",
3328
+ cursor: "pointer",
3329
+ overflow: "hidden",
3330
+ display: "flex",
3331
+ alignItems: "center",
3332
+ justifyContent: "center",
3333
+ transition: "transform 0.2s ease, box-shadow 0.2s ease",
3334
+ background: open ? "#19191c" : "#ffffff",
3335
+ color: open ? "#ffffff" : "#19191c"
3336
+ },
3337
+ children: open ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { style: { width: 20, height: 20 } }) : resolvedBubbleIcon ? /* @__PURE__ */ jsxRuntime.jsx(
3338
+ "img",
3339
+ {
3340
+ src: resolvedBubbleIcon,
3341
+ alt: "",
3342
+ style: {
3343
+ width: "100%",
3344
+ height: "100%",
3345
+ objectFit: "cover",
3346
+ display: "block"
3347
+ }
3348
+ }
3349
+ ) : /* @__PURE__ */ jsxRuntime.jsx(DefaultIcon, {})
3350
+ }
3351
+ )
3352
+ ]
3353
+ }
3354
+ )
3355
+ ] });
3218
3356
  }
3219
3357
 
3220
3358
  exports.BubbleWidget = BubbleWidget;
package/dist/index.mjs CHANGED
@@ -35,6 +35,36 @@ function styleInject(css, { insertAt } = {}) {
35
35
  styleInject(".ww-pointer-events-none {\n pointer-events: none;\n}\n.ww-absolute {\n position: absolute;\n}\n.ww-relative {\n position: relative;\n}\n.ww-inset-0 {\n inset: 0px;\n}\n.ww-inset-4 {\n inset: 1rem;\n}\n.ww-inset-8 {\n inset: 2rem;\n}\n.ww-left-2\\.5 {\n left: 0.625rem;\n}\n.ww-top-1\\/2 {\n top: 50%;\n}\n.ww-z-50 {\n z-index: 50;\n}\n.ww-z-\\[100\\] {\n z-index: 100;\n}\n.ww-mb-1 {\n margin-bottom: 0.25rem;\n}\n.ww-mb-12 {\n margin-bottom: 3rem;\n}\n.ww-mb-2 {\n margin-bottom: 0.5rem;\n}\n.ww-ml-0\\.5 {\n margin-left: 0.125rem;\n}\n.ww-mt-0\\.5 {\n margin-top: 0.125rem;\n}\n.ww-mt-1 {\n margin-top: 0.25rem;\n}\n.ww-block {\n display: block;\n}\n.ww-inline-block {\n display: inline-block;\n}\n.ww-flex {\n display: flex;\n}\n.ww-inline-flex {\n display: inline-flex;\n}\n.ww-grid {\n display: grid;\n}\n.ww-hidden {\n display: none;\n}\n.ww-h-10 {\n height: 2.5rem;\n}\n.ww-h-16 {\n height: 4rem;\n}\n.ww-h-2 {\n height: 0.5rem;\n}\n.ww-h-2\\.5 {\n height: 0.625rem;\n}\n.ww-h-20 {\n height: 5rem;\n}\n.ww-h-3 {\n height: 0.75rem;\n}\n.ww-h-3\\.5 {\n height: 0.875rem;\n}\n.ww-h-4 {\n height: 1rem;\n}\n.ww-h-40 {\n height: 10rem;\n}\n.ww-h-48 {\n height: 12rem;\n}\n.ww-h-6 {\n height: 1.5rem;\n}\n.ww-h-7 {\n height: 1.75rem;\n}\n.ww-h-8 {\n height: 2rem;\n}\n.ww-h-full {\n height: 100%;\n}\n.ww-max-h-32 {\n max-height: 8rem;\n}\n.ww-max-h-48 {\n max-height: 12rem;\n}\n.ww-max-h-\\[168px\\] {\n max-height: 168px;\n}\n.ww-max-h-\\[180px\\] {\n max-height: 180px;\n}\n.ww-w-0\\.5 {\n width: 0.125rem;\n}\n.ww-w-10 {\n width: 2.5rem;\n}\n.ww-w-16 {\n width: 4rem;\n}\n.ww-w-2 {\n width: 0.5rem;\n}\n.ww-w-2\\.5 {\n width: 0.625rem;\n}\n.ww-w-20 {\n width: 5rem;\n}\n.ww-w-3 {\n width: 0.75rem;\n}\n.ww-w-3\\.5 {\n width: 0.875rem;\n}\n.ww-w-4 {\n width: 1rem;\n}\n.ww-w-48 {\n width: 12rem;\n}\n.ww-w-6 {\n width: 1.5rem;\n}\n.ww-w-7 {\n width: 1.75rem;\n}\n.ww-w-8 {\n width: 2rem;\n}\n.ww-w-fit {\n width: -moz-fit-content;\n width: fit-content;\n}\n.ww-w-full {\n width: 100%;\n}\n.ww-min-w-0 {\n min-width: 0px;\n}\n.ww-max-w-\\[120px\\] {\n max-width: 120px;\n}\n.ww-max-w-\\[200px\\] {\n max-width: 200px;\n}\n.ww-max-w-\\[78\\%\\] {\n max-width: 78%;\n}\n.ww-max-w-\\[82\\%\\] {\n max-width: 82%;\n}\n.ww-max-w-none {\n max-width: none;\n}\n.ww-flex-1 {\n flex: 1 1 0%;\n}\n.ww-shrink-0 {\n flex-shrink: 0;\n}\n.ww-rotate-180 {\n --tw-rotate: 180deg;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.ww-scale-100 {\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.ww-scale-105 {\n --tw-scale-x: 1.05;\n --tw-scale-y: 1.05;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.ww-scale-110 {\n --tw-scale-x: 1.1;\n --tw-scale-y: 1.1;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.ww-scale-90 {\n --tw-scale-x: .9;\n --tw-scale-y: .9;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n@keyframes ww-ping {\n 75%, 100% {\n transform: scale(2);\n opacity: 0;\n }\n}\n.ww-animate-ping {\n animation: ww-ping 1s cubic-bezier(0, 0, 0.2, 1) infinite;\n}\n@keyframes ww-pulse {\n 50% {\n opacity: .5;\n }\n}\n.ww-animate-pulse {\n animation: ww-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n}\n@keyframes ww-spin {\n to {\n transform: rotate(360deg);\n }\n}\n.ww-animate-spin {\n animation: ww-spin 1s linear infinite;\n}\n.ww-cursor-default {\n cursor: default;\n}\n.ww-cursor-pointer {\n cursor: pointer;\n}\n.ww-touch-none {\n touch-action: none;\n}\n.ww-select-none {\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n}\n.ww-resize-none {\n resize: none;\n}\n.ww-grid-cols-2 {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n}\n.ww-flex-col {\n flex-direction: column;\n}\n.ww-flex-wrap {\n flex-wrap: wrap;\n}\n.ww-items-start {\n align-items: flex-start;\n}\n.ww-items-end {\n align-items: flex-end;\n}\n.ww-items-center {\n align-items: center;\n}\n.ww-justify-end {\n justify-content: flex-end;\n}\n.ww-justify-center {\n justify-content: center;\n}\n.ww-justify-between {\n justify-content: space-between;\n}\n.ww-gap-0\\.5 {\n gap: 0.125rem;\n}\n.ww-gap-1 {\n gap: 0.25rem;\n}\n.ww-gap-1\\.5 {\n gap: 0.375rem;\n}\n.ww-gap-2 {\n gap: 0.5rem;\n}\n.ww-gap-2\\.5 {\n gap: 0.625rem;\n}\n.ww-gap-4 {\n gap: 1rem;\n}\n.ww-gap-6 {\n gap: 1.5rem;\n}\n.ww-gap-8 {\n gap: 2rem;\n}\n.ww-divide-y > :not([hidden]) ~ :not([hidden]) {\n --tw-divide-y-reverse: 0;\n border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));\n border-bottom-width: calc(1px * var(--tw-divide-y-reverse));\n}\n.ww-divide-border\\/40 > :not([hidden]) ~ :not([hidden]) {\n border-color: hsl(var(--border) / 0.4);\n}\n.ww-overflow-hidden {\n overflow: hidden;\n}\n.ww-overflow-y-auto {\n overflow-y: auto;\n}\n.ww-overscroll-contain {\n overscroll-behavior: contain;\n}\n.ww-overscroll-none {\n overscroll-behavior: none;\n}\n.ww-truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.ww-whitespace-pre-wrap {\n white-space: pre-wrap;\n}\n.ww-rounded {\n border-radius: 0.25rem;\n}\n.ww-rounded-2xl {\n border-radius: 1rem;\n}\n.ww-rounded-full {\n border-radius: 9999px;\n}\n.ww-rounded-lg {\n border-radius: var(--radius);\n}\n.ww-rounded-xl {\n border-radius: 0.75rem;\n}\n.ww-rounded-tl-none {\n border-top-left-radius: 0px;\n}\n.ww-rounded-tl-sm {\n border-top-left-radius: calc(var(--radius) - 4px);\n}\n.ww-rounded-tr-sm {\n border-top-right-radius: calc(var(--radius) - 4px);\n}\n.ww-border {\n border-width: 1px;\n}\n.ww-border-2 {\n border-width: 2px;\n}\n.ww-border-b {\n border-bottom-width: 1px;\n}\n.ww-border-l-2 {\n border-left-width: 2px;\n}\n.ww-border-t {\n border-top-width: 1px;\n}\n.ww-border-background {\n border-color: hsl(var(--background));\n}\n.ww-border-black\\/10 {\n border-color: rgb(0 0 0 / 0.1);\n}\n.ww-border-border {\n border-color: hsl(var(--border));\n}\n.ww-border-border\\/30 {\n border-color: hsl(var(--border) / 0.3);\n}\n.ww-border-border\\/40 {\n border-color: hsl(var(--border) / 0.4);\n}\n.ww-border-border\\/50 {\n border-color: hsl(var(--border) / 0.5);\n}\n.ww-border-border\\/60 {\n border-color: hsl(var(--border) / 0.6);\n}\n.ww-border-border\\/80 {\n border-color: hsl(var(--border) / 0.8);\n}\n.ww-border-muted {\n border-color: hsl(var(--muted));\n}\n.ww-border-muted-foreground\\/30 {\n border-color: hsl(var(--muted-foreground) / 0.3);\n}\n.ww-border-red-200 {\n --tw-border-opacity: 1;\n border-color: rgb(254 202 202 / var(--tw-border-opacity, 1));\n}\n.ww-border-transparent {\n border-color: transparent;\n}\n.ww-border-white\\/20 {\n border-color: rgb(255 255 255 / 0.2);\n}\n.ww-bg-background {\n background-color: hsl(var(--background));\n}\n.ww-bg-background\\/20 {\n background-color: hsl(var(--background) / 0.2);\n}\n.ww-bg-background\\/90 {\n background-color: hsl(var(--background) / 0.9);\n}\n.ww-bg-background\\/95 {\n background-color: hsl(var(--background) / 0.95);\n}\n.ww-bg-black\\/10 {\n background-color: rgb(0 0 0 / 0.1);\n}\n.ww-bg-emerald-400 {\n --tw-bg-opacity: 1;\n background-color: rgb(52 211 153 / var(--tw-bg-opacity, 1));\n}\n.ww-bg-emerald-500 {\n --tw-bg-opacity: 1;\n background-color: rgb(16 185 129 / var(--tw-bg-opacity, 1));\n}\n.ww-bg-emerald-500\\/10 {\n background-color: rgb(16 185 129 / 0.1);\n}\n.ww-bg-emerald-500\\/20 {\n background-color: rgb(16 185 129 / 0.2);\n}\n.ww-bg-foreground\\/20 {\n background-color: hsl(var(--foreground) / 0.2);\n}\n.ww-bg-foreground\\/5 {\n background-color: hsl(var(--foreground) / 0.05);\n}\n.ww-bg-foreground\\/60 {\n background-color: hsl(var(--foreground) / 0.6);\n}\n.ww-bg-muted {\n background-color: hsl(var(--muted));\n}\n.ww-bg-muted-foreground\\/10 {\n background-color: hsl(var(--muted-foreground) / 0.1);\n}\n.ww-bg-muted\\/30 {\n background-color: hsl(var(--muted) / 0.3);\n}\n.ww-bg-muted\\/40 {\n background-color: hsl(var(--muted) / 0.4);\n}\n.ww-bg-muted\\/50 {\n background-color: hsl(var(--muted) / 0.5);\n}\n.ww-bg-muted\\/60 {\n background-color: hsl(var(--muted) / 0.6);\n}\n.ww-bg-primary {\n background-color: hsl(var(--primary));\n}\n.ww-bg-primary\\/5 {\n background-color: hsl(var(--primary) / 0.05);\n}\n.ww-bg-purple-500\\/20 {\n background-color: rgb(168 85 247 / 0.2);\n}\n.ww-bg-purple-500\\/30 {\n background-color: rgb(168 85 247 / 0.3);\n}\n.ww-bg-red-50 {\n --tw-bg-opacity: 1;\n background-color: rgb(254 242 242 / var(--tw-bg-opacity, 1));\n}\n.ww-bg-transparent {\n background-color: transparent;\n}\n.ww-bg-white\\/10 {\n background-color: rgb(255 255 255 / 0.1);\n}\n.ww-bg-white\\/15 {\n background-color: rgb(255 255 255 / 0.15);\n}\n.ww-fill-current {\n fill: currentColor;\n}\n.ww-object-cover {\n -o-object-fit: cover;\n object-fit: cover;\n}\n.ww-p-0\\.5 {\n padding: 0.125rem;\n}\n.ww-p-1\\.5 {\n padding: 0.375rem;\n}\n.ww-p-3 {\n padding: 0.75rem;\n}\n.ww-px-1 {\n padding-left: 0.25rem;\n padding-right: 0.25rem;\n}\n.ww-px-2 {\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n}\n.ww-px-3 {\n padding-left: 0.75rem;\n padding-right: 0.75rem;\n}\n.ww-px-3\\.5 {\n padding-left: 0.875rem;\n padding-right: 0.875rem;\n}\n.ww-px-4 {\n padding-left: 1rem;\n padding-right: 1rem;\n}\n.ww-py-0\\.5 {\n padding-top: 0.125rem;\n padding-bottom: 0.125rem;\n}\n.ww-py-1 {\n padding-top: 0.25rem;\n padding-bottom: 0.25rem;\n}\n.ww-py-1\\.5 {\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n}\n.ww-py-2 {\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n}\n.ww-py-2\\.5 {\n padding-top: 0.625rem;\n padding-bottom: 0.625rem;\n}\n.ww-py-3 {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n}\n.ww-py-4 {\n padding-top: 1rem;\n padding-bottom: 1rem;\n}\n.ww-pb-1\\.5 {\n padding-bottom: 0.375rem;\n}\n.ww-pb-2 {\n padding-bottom: 0.5rem;\n}\n.ww-pb-4 {\n padding-bottom: 1rem;\n}\n.ww-pl-2 {\n padding-left: 0.5rem;\n}\n.ww-pl-7 {\n padding-left: 1.75rem;\n}\n.ww-pr-0\\.5 {\n padding-right: 0.125rem;\n}\n.ww-pr-3 {\n padding-right: 0.75rem;\n}\n.ww-pt-2 {\n padding-top: 0.5rem;\n}\n.ww-pt-5 {\n padding-top: 1.25rem;\n}\n.ww-text-left {\n text-align: left;\n}\n.ww-text-center {\n text-align: center;\n}\n.ww-align-middle {\n vertical-align: middle;\n}\n.ww-text-\\[10\\.5px\\] {\n font-size: 10.5px;\n}\n.ww-text-\\[10px\\] {\n font-size: 10px;\n}\n.ww-text-\\[11px\\] {\n font-size: 11px;\n}\n.ww-text-\\[12\\.5px\\] {\n font-size: 12.5px;\n}\n.ww-text-\\[13px\\] {\n font-size: 13px;\n}\n.ww-text-\\[8px\\] {\n font-size: 8px;\n}\n.ww-text-sm {\n font-size: 0.875rem;\n line-height: 1.25rem;\n}\n.ww-text-xs {\n font-size: 0.75rem;\n line-height: 1rem;\n}\n.ww-font-medium {\n font-weight: 500;\n}\n.ww-font-semibold {\n font-weight: 600;\n}\n.ww-uppercase {\n text-transform: uppercase;\n}\n.ww-leading-none {\n line-height: 1;\n}\n.ww-leading-relaxed {\n line-height: 1.625;\n}\n.ww-leading-snug {\n line-height: 1.375;\n}\n.ww-leading-tight {\n line-height: 1.25;\n}\n.ww-tracking-wide {\n letter-spacing: 0.025em;\n}\n.ww-tracking-widest {\n letter-spacing: 0.1em;\n}\n.ww-text-black\\/40 {\n color: rgb(0 0 0 / 0.4);\n}\n.ww-text-black\\/60 {\n color: rgb(0 0 0 / 0.6);\n}\n.ww-text-destructive {\n color: hsl(var(--destructive));\n}\n.ww-text-destructive\\/70 {\n color: hsl(var(--destructive) / 0.7);\n}\n.ww-text-emerald-500 {\n --tw-text-opacity: 1;\n color: rgb(16 185 129 / var(--tw-text-opacity, 1));\n}\n.ww-text-foreground {\n color: hsl(var(--foreground));\n}\n.ww-text-foreground\\/60 {\n color: hsl(var(--foreground) / 0.6);\n}\n.ww-text-foreground\\/70 {\n color: hsl(var(--foreground) / 0.7);\n}\n.ww-text-foreground\\/80 {\n color: hsl(var(--foreground) / 0.8);\n}\n.ww-text-muted-foreground {\n color: hsl(var(--muted-foreground));\n}\n.ww-text-muted-foreground\\/40 {\n color: hsl(var(--muted-foreground) / 0.4);\n}\n.ww-text-muted-foreground\\/50 {\n color: hsl(var(--muted-foreground) / 0.5);\n}\n.ww-text-muted-foreground\\/70 {\n color: hsl(var(--muted-foreground) / 0.7);\n}\n.ww-text-muted-foreground\\/80 {\n color: hsl(var(--muted-foreground) / 0.8);\n}\n.ww-text-primary {\n color: hsl(var(--primary));\n}\n.ww-text-primary-foreground {\n color: hsl(var(--primary-foreground));\n}\n.ww-text-primary\\/70 {\n color: hsl(var(--primary) / 0.7);\n}\n.ww-text-primary\\/80 {\n color: hsl(var(--primary) / 0.8);\n}\n.ww-text-red-400 {\n --tw-text-opacity: 1;\n color: rgb(248 113 113 / var(--tw-text-opacity, 1));\n}\n.ww-text-red-500 {\n --tw-text-opacity: 1;\n color: rgb(239 68 68 / var(--tw-text-opacity, 1));\n}\n.ww-text-red-600 {\n --tw-text-opacity: 1;\n color: rgb(220 38 38 / var(--tw-text-opacity, 1));\n}\n.ww-text-white {\n --tw-text-opacity: 1;\n color: rgb(255 255 255 / var(--tw-text-opacity, 1));\n}\n.ww-text-white\\/60 {\n color: rgb(255 255 255 / 0.6);\n}\n.ww-text-white\\/80 {\n color: rgb(255 255 255 / 0.8);\n}\n.ww-line-through {\n text-decoration-line: line-through;\n}\n.ww-no-underline {\n text-decoration-line: none;\n}\n.ww-decoration-foreground\\/20 {\n text-decoration-color: hsl(var(--foreground) / 0.2);\n}\n.ww-opacity-100 {\n opacity: 1;\n}\n.ww-opacity-25 {\n opacity: 0.25;\n}\n.ww-opacity-30 {\n opacity: 0.3;\n}\n.ww-opacity-40 {\n opacity: 0.4;\n}\n.ww-opacity-60 {\n opacity: 0.6;\n}\n.ww-opacity-70 {\n opacity: 0.7;\n}\n.ww-opacity-75 {\n opacity: 0.75;\n}\n.ww-opacity-80 {\n opacity: 0.8;\n}\n.ww-opacity-90 {\n opacity: 0.9;\n}\n.ww-shadow-2xl {\n --tw-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);\n --tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);\n box-shadow:\n var(--tw-ring-offset-shadow, 0 0 #0000),\n var(--tw-ring-shadow, 0 0 #0000),\n var(--tw-shadow);\n}\n.ww-shadow-lg {\n --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);\n box-shadow:\n var(--tw-ring-offset-shadow, 0 0 #0000),\n var(--tw-ring-shadow, 0 0 #0000),\n var(--tw-shadow);\n}\n.ww-shadow-md {\n --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);\n box-shadow:\n var(--tw-ring-offset-shadow, 0 0 #0000),\n var(--tw-ring-shadow, 0 0 #0000),\n var(--tw-shadow);\n}\n.ww-shadow-sm {\n --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);\n box-shadow:\n var(--tw-ring-offset-shadow, 0 0 #0000),\n var(--tw-ring-shadow, 0 0 #0000),\n var(--tw-shadow);\n}\n.ww-shadow-xl {\n --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);\n box-shadow:\n var(--tw-ring-offset-shadow, 0 0 #0000),\n var(--tw-ring-shadow, 0 0 #0000),\n var(--tw-shadow);\n}\n.ww-outline-none {\n outline: 2px solid transparent;\n outline-offset: 2px;\n}\n.ww-ring-2 {\n --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);\n box-shadow:\n var(--tw-ring-offset-shadow),\n var(--tw-ring-shadow),\n var(--tw-shadow, 0 0 #0000);\n}\n.ww-ring-inset {\n --tw-ring-inset: inset;\n}\n.ww-ring-primary\\/20 {\n --tw-ring-color: hsl(var(--primary) / 0.2);\n}\n.ww-ring-primary\\/60 {\n --tw-ring-color: hsl(var(--primary) / 0.6);\n}\n.ww-backdrop-blur-sm {\n --tw-backdrop-blur: blur(4px);\n backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);\n}\n.ww-backdrop-blur-xl {\n --tw-backdrop-blur: blur(24px);\n backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);\n}\n.ww-transition-all {\n transition-property: all;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.ww-transition-colors {\n transition-property:\n color,\n background-color,\n border-color,\n text-decoration-color,\n fill,\n stroke;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.ww-transition-opacity {\n transition-property: opacity;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.ww-transition-shadow {\n transition-property: box-shadow;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.ww-transition-transform {\n transition-property: transform;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.ww-duration-1000 {\n transition-duration: 1000ms;\n}\n.ww-duration-200 {\n transition-duration: 200ms;\n}\n.ww-duration-300 {\n transition-duration: 300ms;\n}\n.ww-duration-500 {\n transition-duration: 500ms;\n}\n.ww-duration-700 {\n transition-duration: 700ms;\n}\n@keyframes enter {\n from {\n opacity: var(--tw-enter-opacity, 1);\n transform: translate3d(var(--tw-enter-translate-x, 0), var(--tw-enter-translate-y, 0), 0) scale3d(var(--tw-enter-scale, 1), var(--tw-enter-scale, 1), var(--tw-enter-scale, 1)) rotate(var(--tw-enter-rotate, 0));\n }\n}\n@keyframes exit {\n to {\n opacity: var(--tw-exit-opacity, 1);\n transform: translate3d(var(--tw-exit-translate-x, 0), var(--tw-exit-translate-y, 0), 0) scale3d(var(--tw-exit-scale, 1), var(--tw-exit-scale, 1), var(--tw-exit-scale, 1)) rotate(var(--tw-exit-rotate, 0));\n }\n}\n.ww-duration-1000 {\n animation-duration: 1000ms;\n}\n.ww-duration-200 {\n animation-duration: 200ms;\n}\n.ww-duration-300 {\n animation-duration: 300ms;\n}\n.ww-duration-500 {\n animation-duration: 500ms;\n}\n.ww-duration-700 {\n animation-duration: 700ms;\n}\n.wallavi-widget *,\n.wallavi-widget *::before,\n.wallavi-widget *::after {\n box-sizing: border-box;\n border-width: 0;\n border-style: solid;\n}\n.wallavi-widget button {\n -moz-appearance: none;\n appearance: none;\n -webkit-appearance: none;\n background: transparent;\n border: none;\n cursor: pointer;\n}\n.wallavi-widget textarea,\n.wallavi-widget input,\n.wallavi-widget select {\n font-family: inherit;\n font-size: inherit;\n}\n.wallavi-widget img,\n.wallavi-widget video {\n max-width: 100%;\n height: auto;\n}\n.wallavi-widget .lk-control-bar {\n background: transparent !important;\n border: none !important;\n box-shadow: none !important;\n padding: 0 !important;\n gap: 1.5rem !important;\n justify-content: center !important;\n}\n.wallavi-widget .lk-button {\n background: rgba(25, 25, 28, 0.05) !important;\n border-radius: 9999px !important;\n padding: 1.25rem !important;\n color: var(--ww-fg, #19191c) !important;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1) !important;\n border: 1px solid rgba(25, 25, 28, 0.1) !important;\n}\n.wallavi-widget .lk-button:hover {\n background: rgba(25, 25, 28, 0.1) !important;\n transform: scale(1.05) !important;\n}\n.wallavi-widget .lk-disconnect-button {\n background: #ef4444 !important;\n color: white !important;\n border: none !important;\n}\n.wallavi-widget .lk-disconnect-button:hover {\n background: #dc2626 !important;\n}\n.wallavi-widget .lk-device-menu {\n bottom: 100% !important;\n top: auto !important;\n margin-bottom: 1rem !important;\n max-width: 250px !important;\n width: -moz-max-content !important;\n width: max-content !important;\n left: 50% !important;\n transform: translateX(-50%) !important;\n background: #ffffff !important;\n border-radius: 16px !important;\n box-shadow: 0 20px 40px -10px rgba(0, 0, 0, 0.15), 0 10px 20px -10px rgba(0, 0, 0, 0.1) !important;\n z-index: 1000 !important;\n overflow: hidden !important;\n border: 1px solid rgba(0, 0, 0, 0.05) !important;\n padding: 0.5rem !important;\n}\n.wallavi-widget .lk-device-menu > li {\n padding: 0.75rem 1rem !important;\n font-size: 0.875rem !important;\n color: #19191c !important;\n white-space: nowrap !important;\n overflow: hidden !important;\n text-overflow: ellipsis !important;\n border-radius: 8px !important;\n transition: background 0.15s !important;\n}\n.wallavi-widget .lk-device-menu > li:hover {\n background: rgba(0, 0, 0, 0.05) !important;\n}\n.wallavi-widget .lk-device-menu > li.lk-active {\n background: rgba(0, 0, 0, 0.08) !important;\n font-weight: 600 !important;\n}\n.placeholder\\:ww-text-muted-foreground\\/40::-moz-placeholder {\n color: hsl(var(--muted-foreground) / 0.4);\n}\n.placeholder\\:ww-text-muted-foreground\\/40::placeholder {\n color: hsl(var(--muted-foreground) / 0.4);\n}\n.placeholder\\:ww-text-muted-foreground\\/50::-moz-placeholder {\n color: hsl(var(--muted-foreground) / 0.5);\n}\n.placeholder\\:ww-text-muted-foreground\\/50::placeholder {\n color: hsl(var(--muted-foreground) / 0.5);\n}\n.focus-within\\:ww-ring-1:focus-within {\n --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);\n box-shadow:\n var(--tw-ring-offset-shadow),\n var(--tw-ring-shadow),\n var(--tw-shadow, 0 0 #0000);\n}\n.focus-within\\:ww-ring-ring\\/40:focus-within {\n --tw-ring-color: hsl(var(--ring) / 0.4);\n}\n.hover\\:-ww-translate-y-1:hover {\n --tw-translate-y: -0.25rem;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.hover\\:ww-border-primary\\/40:hover {\n border-color: hsl(var(--primary) / 0.4);\n}\n.hover\\:ww-bg-accent:hover {\n background-color: hsl(var(--accent));\n}\n.hover\\:ww-bg-foreground\\/10:hover {\n background-color: hsl(var(--foreground) / 0.1);\n}\n.hover\\:ww-bg-foreground\\/30:hover {\n background-color: hsl(var(--foreground) / 0.3);\n}\n.hover\\:ww-bg-muted:hover {\n background-color: hsl(var(--muted));\n}\n.hover\\:ww-bg-white\\/10:hover {\n background-color: rgb(255 255 255 / 0.1);\n}\n.hover\\:ww-text-accent-foreground:hover {\n color: hsl(var(--accent-foreground));\n}\n.hover\\:ww-text-foreground:hover {\n color: hsl(var(--foreground));\n}\n.hover\\:ww-text-primary:hover {\n color: hsl(var(--primary));\n}\n.hover\\:ww-opacity-80:hover {\n opacity: 0.8;\n}\n.hover\\:ww-opacity-85:hover {\n opacity: 0.85;\n}\n.hover\\:ww-shadow-sm:hover {\n --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);\n box-shadow:\n var(--tw-ring-offset-shadow, 0 0 #0000),\n var(--tw-ring-shadow, 0 0 #0000),\n var(--tw-shadow);\n}\n.hover\\:ww-shadow-xl:hover {\n --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);\n box-shadow:\n var(--tw-ring-offset-shadow, 0 0 #0000),\n var(--tw-ring-shadow, 0 0 #0000),\n var(--tw-shadow);\n}\n.focus\\:ww-ring-1:focus {\n --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);\n box-shadow:\n var(--tw-ring-offset-shadow),\n var(--tw-ring-shadow),\n var(--tw-shadow, 0 0 #0000);\n}\n.focus\\:ww-ring-ring\\/40:focus {\n --tw-ring-color: hsl(var(--ring) / 0.4);\n}\n.active\\:ww-scale-\\[0\\.98\\]:active {\n --tw-scale-x: 0.98;\n --tw-scale-y: 0.98;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.disabled\\:ww-pointer-events-none:disabled {\n pointer-events: none;\n}\n.disabled\\:ww-opacity-40:disabled {\n opacity: 0.4;\n}\n.disabled\\:ww-opacity-50:disabled {\n opacity: 0.5;\n}\n.dark\\:ww-border-red-800:is(.ww-dark *) {\n --tw-border-opacity: 1;\n border-color: rgb(153 27 27 / var(--tw-border-opacity, 1));\n}\n.dark\\:ww-bg-red-950:is(.ww-dark *) {\n --tw-bg-opacity: 1;\n background-color: rgb(69 10 10 / var(--tw-bg-opacity, 1));\n}\n.dark\\:ww-text-red-400:is(.ww-dark *) {\n --tw-text-opacity: 1;\n color: rgb(248 113 113 / var(--tw-text-opacity, 1));\n}\n");
36
36
  var twMerge = extendTailwindMerge({ prefix: "ww-" });
37
37
  var cn = (...inputs) => twMerge(clsx(inputs));
38
+ async function getFreshClerkToken() {
39
+ if (typeof window === "undefined") return null;
40
+ const clerk = window.Clerk;
41
+ if (!clerk?.session) return null;
42
+ try {
43
+ let token = await clerk.session.getToken();
44
+ if (token) {
45
+ const payloadBase64 = token.split(".")[1];
46
+ if (payloadBase64) {
47
+ const payloadJson = JSON.parse(
48
+ atob(payloadBase64.replace(/-/g, "+").replace(/_/g, "/"))
49
+ );
50
+ const exp = payloadJson.exp;
51
+ if (exp && typeof exp === "number") {
52
+ const nowSeconds = Math.floor(Date.now() / 1e3);
53
+ if (exp - nowSeconds < 30) {
54
+ token = await clerk.session.getToken({ skipCache: true });
55
+ }
56
+ }
57
+ }
58
+ }
59
+ return token;
60
+ } catch (e) {
61
+ try {
62
+ return await clerk.session.getToken();
63
+ } catch {
64
+ return null;
65
+ }
66
+ }
67
+ }
38
68
 
39
69
  // src/lib/types.ts
40
70
  function getContrastColor(hex) {
@@ -236,13 +266,11 @@ function useVoiceCall({
236
266
  try {
237
267
  const isPrivate = Boolean(workspaceId);
238
268
  const url = isPrivate ? `${API_URL}/api/threads/${threadId}/livekit-token?agentId=${encodeURIComponent(agentId)}` : `${API_URL}/api/chat/livekit-token?agentId=${encodeURIComponent(agentId)}&threadId=${encodeURIComponent(threadId)}`;
269
+ const token2 = isPrivate ? await getFreshClerkToken() : null;
239
270
  const res = await fetch(url, {
240
- headers: isPrivate && typeof window !== "undefined" ? (
241
- // @ts-ignore
242
- {
243
- Authorization: `Bearer ${await window.Clerk?.session?.getToken()}`
244
- }
245
- ) : {}
271
+ headers: {
272
+ ...token2 ? { Authorization: `Bearer ${token2}` } : {}
273
+ }
246
274
  });
247
275
  const data = await res.json();
248
276
  if (!res.ok) throw new Error(data.error || "Failed to start call");
@@ -323,6 +351,10 @@ function useChat({
323
351
  if (proto.path.startsWith("/")) onNavigateRef.current?.(proto.path);
324
352
  return;
325
353
  }
354
+ if (proto.type === "client-action") {
355
+ executeDeclarativeSteps(proto.steps, onNavigateRef.current);
356
+ return;
357
+ }
326
358
  if (proto.type === "debug-trace") {
327
359
  setDebugTraces((prev) => [
328
360
  ...prev,
@@ -338,7 +370,7 @@ function useChat({
338
370
  async (opts) => {
339
371
  const { input: userInput, msgId, extraMetadata, attachments } = opts;
340
372
  const isPrivate = Boolean(workspaceId);
341
- const token = isPrivate && typeof window !== "undefined" ? await window.Clerk?.session?.getToken() : null;
373
+ const token = isPrivate ? await getFreshClerkToken() : null;
342
374
  const url = isPrivate ? `${API_URL2}/api/threads/${threadId}/stream` : `${API_URL2}/api/chat/stream`;
343
375
  const res = await fetch(url, {
344
376
  method: "POST",
@@ -470,7 +502,7 @@ function useChat({
470
502
  void (async () => {
471
503
  try {
472
504
  const isPrivate = Boolean(workspaceId);
473
- const token = isPrivate && typeof window !== "undefined" ? await window.Clerk?.session?.getToken() : null;
505
+ const token = isPrivate ? await getFreshClerkToken() : null;
474
506
  const url = isPrivate ? `${API_URL2}/api/threads/${threadId}/messages` : `${API_URL2}/api/chat/messages?agentId=${encodeURIComponent(agentId)}&threadId=${encodeURIComponent(threadId)}`;
475
507
  const res = await fetch(url, {
476
508
  headers: {
@@ -701,6 +733,82 @@ function useChat({
701
733
  voiceCall
702
734
  };
703
735
  }
736
+ function executeDeclarativeSteps(steps, onNavigate) {
737
+ if (typeof window === "undefined" || !Array.isArray(steps)) return;
738
+ for (const step of steps) {
739
+ try {
740
+ const { action, selector, value, payload } = step;
741
+ switch (action) {
742
+ case "scroll_into_view": {
743
+ if (!selector) break;
744
+ const el = document.querySelector(selector);
745
+ el?.scrollIntoView({ behavior: "smooth", block: "center" });
746
+ break;
747
+ }
748
+ case "click": {
749
+ if (!selector) break;
750
+ const el = document.querySelector(selector);
751
+ el?.click();
752
+ break;
753
+ }
754
+ case "focus": {
755
+ if (!selector) break;
756
+ const el = document.querySelector(selector);
757
+ el?.focus();
758
+ break;
759
+ }
760
+ case "add_class": {
761
+ if (!selector || !value) break;
762
+ const el = document.querySelector(selector);
763
+ if (el) el.classList.add(...value.split(/\s+/).filter(Boolean));
764
+ break;
765
+ }
766
+ case "remove_class": {
767
+ if (!selector || !value) break;
768
+ const el = document.querySelector(selector);
769
+ if (el) el.classList.remove(...value.split(/\s+/).filter(Boolean));
770
+ break;
771
+ }
772
+ case "fill_value": {
773
+ if (!selector) break;
774
+ const el = document.querySelector(selector);
775
+ if (el) {
776
+ el.value = value ?? "";
777
+ el.dispatchEvent(new Event("input", { bubbles: true }));
778
+ el.dispatchEvent(new Event("change", { bubbles: true }));
779
+ }
780
+ break;
781
+ }
782
+ case "dispatch_event": {
783
+ if (!value) break;
784
+ const detail = payload ?? {};
785
+ window.dispatchEvent(new CustomEvent(value, { detail }));
786
+ break;
787
+ }
788
+ case "navigate": {
789
+ if (value) {
790
+ if (onNavigate) {
791
+ onNavigate(value);
792
+ } else {
793
+ window.location.href = value;
794
+ }
795
+ }
796
+ break;
797
+ }
798
+ default:
799
+ console.warn(
800
+ `[Wallavi Widget] Unknown declarative action: ${action}`
801
+ );
802
+ }
803
+ } catch (err) {
804
+ console.error(
805
+ "[Wallavi Widget] Failed to execute declarative step:",
806
+ step,
807
+ err
808
+ );
809
+ }
810
+ }
811
+ }
704
812
  function getPreferredMimeType() {
705
813
  if (typeof MediaRecorder === "undefined") return "";
706
814
  const candidates = [
@@ -2540,6 +2648,7 @@ var EMPTY = {
2540
2648
  autoOpen: false,
2541
2649
  keyboardShortcut: false,
2542
2650
  position: "bottom-right",
2651
+ widgetLayout: "bubble",
2543
2652
  bubbleSize: 52,
2544
2653
  panelWidth: 360,
2545
2654
  panelHeight: 580,
@@ -2579,6 +2688,8 @@ function useAutoConfig(agentId, enabled) {
2579
2688
  remote.showThinking = cfg.showThinking;
2580
2689
  if (cfg.regenerateMessage != null)
2581
2690
  remote.regenerateMessage = cfg.regenerateMessage;
2691
+ if (cfg.widgetLayout)
2692
+ remote.widgetLayout = cfg.widgetLayout;
2582
2693
  if (cfg.enableVoice != null)
2583
2694
  remote.enableVoice = cfg.enableVoice;
2584
2695
  setResult({
@@ -2587,6 +2698,7 @@ function useAutoConfig(agentId, enabled) {
2587
2698
  autoOpen: Boolean(cfg.autoOpen),
2588
2699
  keyboardShortcut: Boolean(cfg.keyboardShortcut),
2589
2700
  position: cfg.alignChatBubbleButton === "left" ? "bottom-left" : "bottom-right",
2701
+ widgetLayout: cfg.widgetLayout === "center" ? "center" : "bubble",
2590
2702
  bubbleSize: typeof cfg.bubbleSize === "number" ? cfg.bubbleSize : 52,
2591
2703
  panelWidth: typeof cfg.panelWidth === "number" ? cfg.panelWidth : 360,
2592
2704
  panelHeight: typeof cfg.panelHeight === "number" ? cfg.panelHeight : 580,
@@ -3045,6 +3157,7 @@ function BubbleWidget({
3045
3157
  !inboxToken && autoConfig
3046
3158
  );
3047
3159
  const resolvedPosition = remote.position ?? positionProp;
3160
+ const resolvedLayout = remote.widgetLayout ?? chatProps.widgetLayout ?? "bubble";
3048
3161
  const resolvedBubbleIcon = remote.bubbleIconUrl ?? bubbleIconUrlProp;
3049
3162
  const resolvedAutoOpen = remote.autoOpen || autoOpenProp;
3050
3163
  const resolvedKeyboardShortcut = remote.keyboardShortcut || keyboardShortcutProp;
@@ -3112,83 +3225,108 @@ function BubbleWidget({
3112
3225
  typeof window !== "undefined" ? window.innerWidth - 40 : expandedWidth
3113
3226
  ) : resolvedWidth;
3114
3227
  const panelHeight = expanded ? expandedHeight : resolvedHeight;
3115
- return /* @__PURE__ */ jsxs(
3116
- "div",
3117
- {
3118
- style: {
3119
- position: "fixed",
3120
- bottom: 20,
3121
- [isLeft ? "left" : "right"]: 20,
3122
- zIndex: 9999,
3123
- display: "flex",
3124
- flexDirection: "column",
3125
- alignItems: isLeft ? "flex-start" : "flex-end",
3126
- gap: 12
3127
- },
3128
- children: [
3129
- /* @__PURE__ */ jsx(
3130
- "div",
3131
- {
3132
- ref: panelRef,
3133
- "aria-hidden": !open,
3134
- style: {
3135
- display: open ? "block" : "none",
3136
- width: panelWidth,
3137
- height: panelHeight,
3138
- transition: "width 0.3s ease, height 0.3s ease"
3139
- },
3140
- children: /* @__PURE__ */ jsx(
3141
- ChatWidget,
3142
- {
3143
- ...mergedConfig,
3144
- agentId: inboxToken ? "support" : chatProps.agentId ?? "",
3145
- customBackend: inboxToken ? supportBackend : mergedConfig.customBackend,
3146
- onClose: handleClose,
3147
- onExpand: toggleExpanded,
3148
- expanded,
3149
- className: cn("ww-shadow-2xl ww-h-full", panelClassName)
3150
- }
3151
- )
3152
- }
3153
- ),
3154
- !hideBubble && /* @__PURE__ */ jsx(
3155
- "button",
3156
- {
3157
- onClick: () => setOpen((v) => !v),
3158
- title: open ? "Close chat" : "Open chat",
3159
- style: {
3160
- width: resolvedBubbleSize,
3161
- height: resolvedBubbleSize,
3162
- borderRadius: "50%",
3163
- border: "1px solid rgba(0,0,0,0.1)",
3164
- boxShadow: "0 4px 16px rgba(0,0,0,0.16)",
3165
- cursor: "pointer",
3166
- overflow: "hidden",
3167
- display: "flex",
3168
- alignItems: "center",
3169
- justifyContent: "center",
3170
- transition: "transform 0.2s ease, box-shadow 0.2s ease",
3171
- background: open ? "#19191c" : "#ffffff",
3172
- color: open ? "#ffffff" : "#19191c"
3173
- },
3174
- children: open ? /* @__PURE__ */ jsx(X, { style: { width: 20, height: 20 } }) : resolvedBubbleIcon ? /* @__PURE__ */ jsx(
3175
- "img",
3176
- {
3177
- src: resolvedBubbleIcon,
3178
- alt: "",
3179
- style: {
3180
- width: "100%",
3181
- height: "100%",
3182
- objectFit: "cover",
3183
- display: "block"
3228
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
3229
+ resolvedLayout === "center" && open && /* @__PURE__ */ jsx(
3230
+ "div",
3231
+ {
3232
+ onClick: handleClose,
3233
+ style: {
3234
+ position: "fixed",
3235
+ inset: 0,
3236
+ background: "rgba(0, 0, 0, 0.4)",
3237
+ backdropFilter: "blur(4px)",
3238
+ zIndex: 9998
3239
+ }
3240
+ }
3241
+ ),
3242
+ /* @__PURE__ */ jsxs(
3243
+ "div",
3244
+ {
3245
+ style: {
3246
+ position: "fixed",
3247
+ bottom: 20,
3248
+ [isLeft ? "left" : "right"]: 20,
3249
+ zIndex: 9999,
3250
+ display: "flex",
3251
+ flexDirection: "column",
3252
+ alignItems: isLeft ? "flex-start" : "flex-end",
3253
+ gap: 12
3254
+ },
3255
+ children: [
3256
+ /* @__PURE__ */ jsx(
3257
+ "div",
3258
+ {
3259
+ ref: panelRef,
3260
+ "aria-hidden": !open,
3261
+ style: resolvedLayout === "center" ? {
3262
+ display: open ? "block" : "none",
3263
+ position: "fixed",
3264
+ top: "50%",
3265
+ left: "50%",
3266
+ transform: "translate(-50%, -50%)",
3267
+ zIndex: 9999,
3268
+ width: panelWidth,
3269
+ height: panelHeight,
3270
+ transition: "width 0.3s ease, height 0.3s ease"
3271
+ } : {
3272
+ display: open ? "block" : "none",
3273
+ width: panelWidth,
3274
+ height: panelHeight,
3275
+ transition: "width 0.3s ease, height 0.3s ease"
3276
+ },
3277
+ children: /* @__PURE__ */ jsx(
3278
+ ChatWidget,
3279
+ {
3280
+ ...mergedConfig,
3281
+ agentId: inboxToken ? "support" : chatProps.agentId ?? "",
3282
+ customBackend: inboxToken ? supportBackend : mergedConfig.customBackend,
3283
+ onClose: handleClose,
3284
+ onExpand: toggleExpanded,
3285
+ expanded,
3286
+ className: cn("ww-shadow-2xl ww-h-full", panelClassName)
3184
3287
  }
3185
- }
3186
- ) : /* @__PURE__ */ jsx(DefaultIcon, {})
3187
- }
3188
- )
3189
- ]
3190
- }
3191
- );
3288
+ )
3289
+ }
3290
+ ),
3291
+ !hideBubble && /* @__PURE__ */ jsx(
3292
+ "button",
3293
+ {
3294
+ onClick: () => setOpen((v) => !v),
3295
+ title: open ? "Close chat" : "Open chat",
3296
+ style: {
3297
+ width: resolvedBubbleSize,
3298
+ height: resolvedBubbleSize,
3299
+ borderRadius: "50%",
3300
+ border: "1px solid rgba(0,0,0,0.1)",
3301
+ boxShadow: "0 4px 16px rgba(0,0,0,0.16)",
3302
+ cursor: "pointer",
3303
+ overflow: "hidden",
3304
+ display: "flex",
3305
+ alignItems: "center",
3306
+ justifyContent: "center",
3307
+ transition: "transform 0.2s ease, box-shadow 0.2s ease",
3308
+ background: open ? "#19191c" : "#ffffff",
3309
+ color: open ? "#ffffff" : "#19191c"
3310
+ },
3311
+ children: open ? /* @__PURE__ */ jsx(X, { style: { width: 20, height: 20 } }) : resolvedBubbleIcon ? /* @__PURE__ */ jsx(
3312
+ "img",
3313
+ {
3314
+ src: resolvedBubbleIcon,
3315
+ alt: "",
3316
+ style: {
3317
+ width: "100%",
3318
+ height: "100%",
3319
+ objectFit: "cover",
3320
+ display: "block"
3321
+ }
3322
+ }
3323
+ ) : /* @__PURE__ */ jsx(DefaultIcon, {})
3324
+ }
3325
+ )
3326
+ ]
3327
+ }
3328
+ )
3329
+ ] });
3192
3330
  }
3193
3331
 
3194
3332
  export { BubbleWidget, ChatWidget, PlanCard, ReasoningBlock, ToolCallBadge, formatToolName, getContrastColor, useAttachments, useChat, useSupportChat, useVoice };
package/package.json CHANGED
@@ -42,7 +42,7 @@
42
42
  },
43
43
  "private": false,
44
44
  "types": "./dist/index.d.ts",
45
- "version": "1.7.2",
45
+ "version": "1.9.0",
46
46
  "scripts": {
47
47
  "build": "tsup && pnpm build:css",
48
48
  "build:css": "tailwindcss -i ./src/styles.css -o ./dist/styles.css --config tailwind.config.cjs --minify",