@wallavi/widget 1.3.3 → 1.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.js +110 -81
  2. package/dist/index.mjs +110 -81
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var react = require('react');
4
+ var reactDom = require('react-dom');
4
5
  var clsx = require('clsx');
5
6
  var tailwindMerge = require('tailwind-merge');
6
7
  var lucideReact = require('lucide-react');
@@ -749,7 +750,10 @@ function BubbleWidget({
749
750
  ...chatProps
750
751
  }) {
751
752
  const [open, setOpen] = react.useState(false);
752
- const [expanded, setExpanded] = react.useState(false);
753
+ const [expanded, setExpanded] = react.useState(
754
+ () => typeof window !== "undefined" && localStorage.getItem("wallavi_bubble_expanded") === "true"
755
+ );
756
+ const [controlsPos, setControlsPos] = react.useState(null);
753
757
  const panelRef = react.useRef(null);
754
758
  const autoOpenedRef = react.useRef(false);
755
759
  const [remoteConfig, setRemoteConfig] = react.useState({});
@@ -839,8 +843,32 @@ function BubbleWidget({
839
843
  const expires = Date.now() + 24 * 60 * 60 * 1e3;
840
844
  localStorage.setItem("wallavi_bubble_dismissed", String(expires));
841
845
  };
842
- const toggleExpanded = () => setExpanded((v) => !v);
846
+ const toggleExpanded = () => setExpanded((v) => {
847
+ const next = !v;
848
+ localStorage.setItem("wallavi_bubble_expanded", String(next));
849
+ return next;
850
+ });
843
851
  const isLeft = resolvedPosition === "bottom-left";
852
+ react.useEffect(() => {
853
+ if (!open) {
854
+ setControlsPos(null);
855
+ return;
856
+ }
857
+ const update = () => {
858
+ const rect = panelRef.current?.getBoundingClientRect();
859
+ if (!rect) return;
860
+ setControlsPos({
861
+ top: rect.top - 12,
862
+ side: isLeft ? rect.left - 12 : window.innerWidth - rect.right - 12
863
+ });
864
+ };
865
+ const t = setTimeout(update, 16);
866
+ window.addEventListener("resize", update);
867
+ return () => {
868
+ clearTimeout(t);
869
+ window.removeEventListener("resize", update);
870
+ };
871
+ }, [open, isLeft, expanded]);
844
872
  return /* @__PURE__ */ jsxRuntime.jsxs(
845
873
  "div",
846
874
  {
@@ -855,92 +883,93 @@ function BubbleWidget({
855
883
  gap: 12
856
884
  },
857
885
  children: [
858
- /* @__PURE__ */ jsxRuntime.jsxs(
886
+ /* @__PURE__ */ jsxRuntime.jsx(
859
887
  "div",
860
888
  {
861
889
  ref: panelRef,
862
890
  "aria-hidden": !open,
863
891
  style: { display: open ? "block" : "none", position: "relative" },
864
- children: [
865
- /* @__PURE__ */ jsxRuntime.jsx(
866
- "div",
867
- {
868
- style: {
869
- width: expanded ? Math.min(expandedWidth, typeof window !== "undefined" ? window.innerWidth - 40 : expandedWidth) : width,
870
- height: expanded ? expandedHeight : height,
871
- transition: "width 0.3s ease, height 0.3s ease"
872
- },
873
- children: /* @__PURE__ */ jsxRuntime.jsx(
874
- ChatWidget,
875
- {
876
- ...mergedConfig,
877
- hideCloseButton: true,
878
- className: cn4("shadow-2xl h-full", panelClassName)
879
- }
880
- )
881
- }
882
- ),
883
- /* @__PURE__ */ jsxRuntime.jsxs(
884
- "div",
885
- {
886
- style: {
887
- position: "absolute",
888
- top: -12,
889
- [isLeft ? "left" : "right"]: -12,
890
- zIndex: 10,
891
- display: "flex",
892
- alignItems: "center",
893
- gap: 4
894
- },
895
- children: [
896
- /* @__PURE__ */ jsxRuntime.jsx(
897
- "button",
898
- {
899
- onClick: toggleExpanded,
900
- title: expanded ? "Minimize" : "Expand",
901
- style: {
902
- width: 24,
903
- height: 24,
904
- borderRadius: "50%",
905
- border: "1px solid rgba(0,0,0,0.1)",
906
- background: "var(--background, #fff)",
907
- boxShadow: "0 1px 4px rgba(0,0,0,0.12)",
908
- display: "flex",
909
- alignItems: "center",
910
- justifyContent: "center",
911
- cursor: "pointer",
912
- color: "var(--muted-foreground, #888)"
913
- },
914
- children: expanded ? /* @__PURE__ */ jsxRuntime.jsx(MinimizeIcon, {}) : /* @__PURE__ */ jsxRuntime.jsx(ExpandIcon, {})
915
- }
916
- ),
917
- /* @__PURE__ */ jsxRuntime.jsx(
918
- "button",
919
- {
920
- onClick: handleClose,
921
- title: "Close",
922
- style: {
923
- width: 24,
924
- height: 24,
925
- borderRadius: "50%",
926
- border: "1px solid rgba(0,0,0,0.1)",
927
- background: "var(--background, #fff)",
928
- boxShadow: "0 1px 4px rgba(0,0,0,0.12)",
929
- display: "flex",
930
- alignItems: "center",
931
- justifyContent: "center",
932
- cursor: "pointer",
933
- color: "var(--muted-foreground, #888)"
934
- },
935
- children: /* @__PURE__ */ jsxRuntime.jsx(CloseIcon, {})
936
- }
937
- )
938
- ]
939
- }
940
- )
941
- ]
892
+ children: /* @__PURE__ */ jsxRuntime.jsx(
893
+ "div",
894
+ {
895
+ style: {
896
+ width: expanded ? Math.min(expandedWidth, typeof window !== "undefined" ? window.innerWidth - 40 : expandedWidth) : width,
897
+ height: expanded ? expandedHeight : height,
898
+ transition: "width 0.3s ease, height 0.3s ease"
899
+ },
900
+ children: /* @__PURE__ */ jsxRuntime.jsx(
901
+ ChatWidget,
902
+ {
903
+ ...mergedConfig,
904
+ hideCloseButton: true,
905
+ className: cn4("shadow-2xl h-full", panelClassName)
906
+ }
907
+ )
908
+ }
909
+ )
942
910
  }
943
911
  ),
912
+ open && controlsPos && typeof document !== "undefined" && reactDom.createPortal(
913
+ /* @__PURE__ */ jsxRuntime.jsxs(
914
+ "div",
915
+ {
916
+ style: {
917
+ position: "fixed",
918
+ top: controlsPos.top,
919
+ [isLeft ? "left" : "right"]: controlsPos.side,
920
+ zIndex: 10001,
921
+ display: "flex",
922
+ alignItems: "center",
923
+ gap: 4
924
+ },
925
+ children: [
926
+ /* @__PURE__ */ jsxRuntime.jsx(
927
+ "button",
928
+ {
929
+ onClick: toggleExpanded,
930
+ title: expanded ? "Minimize" : "Expand",
931
+ style: {
932
+ width: 24,
933
+ height: 24,
934
+ borderRadius: "50%",
935
+ border: "1px solid rgba(0,0,0,0.1)",
936
+ background: "var(--background, #fff)",
937
+ boxShadow: "0 1px 4px rgba(0,0,0,0.12)",
938
+ display: "flex",
939
+ alignItems: "center",
940
+ justifyContent: "center",
941
+ cursor: "pointer",
942
+ color: "var(--muted-foreground, #888)"
943
+ },
944
+ children: expanded ? /* @__PURE__ */ jsxRuntime.jsx(MinimizeIcon, {}) : /* @__PURE__ */ jsxRuntime.jsx(ExpandIcon, {})
945
+ }
946
+ ),
947
+ /* @__PURE__ */ jsxRuntime.jsx(
948
+ "button",
949
+ {
950
+ onClick: handleClose,
951
+ title: "Close",
952
+ style: {
953
+ width: 24,
954
+ height: 24,
955
+ borderRadius: "50%",
956
+ border: "1px solid rgba(0,0,0,0.1)",
957
+ background: "var(--background, #fff)",
958
+ boxShadow: "0 1px 4px rgba(0,0,0,0.12)",
959
+ display: "flex",
960
+ alignItems: "center",
961
+ justifyContent: "center",
962
+ cursor: "pointer",
963
+ color: "var(--muted-foreground, #888)"
964
+ },
965
+ children: /* @__PURE__ */ jsxRuntime.jsx(CloseIcon, {})
966
+ }
967
+ )
968
+ ]
969
+ }
970
+ ),
971
+ document.body
972
+ ),
944
973
  /* @__PURE__ */ jsxRuntime.jsx(
945
974
  "button",
946
975
  {
package/dist/index.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  import { useState, useRef, useEffect, useCallback } from 'react';
2
+ import { createPortal } from 'react-dom';
2
3
  import { clsx } from 'clsx';
3
4
  import { twMerge } from 'tailwind-merge';
4
5
  import { RotateCcw, X, Loader2, ArrowUp, Zap, ChevronDown, CheckCircle2, AlertCircle } from 'lucide-react';
@@ -723,7 +724,10 @@ function BubbleWidget({
723
724
  ...chatProps
724
725
  }) {
725
726
  const [open, setOpen] = useState(false);
726
- const [expanded, setExpanded] = useState(false);
727
+ const [expanded, setExpanded] = useState(
728
+ () => typeof window !== "undefined" && localStorage.getItem("wallavi_bubble_expanded") === "true"
729
+ );
730
+ const [controlsPos, setControlsPos] = useState(null);
727
731
  const panelRef = useRef(null);
728
732
  const autoOpenedRef = useRef(false);
729
733
  const [remoteConfig, setRemoteConfig] = useState({});
@@ -813,8 +817,32 @@ function BubbleWidget({
813
817
  const expires = Date.now() + 24 * 60 * 60 * 1e3;
814
818
  localStorage.setItem("wallavi_bubble_dismissed", String(expires));
815
819
  };
816
- const toggleExpanded = () => setExpanded((v) => !v);
820
+ const toggleExpanded = () => setExpanded((v) => {
821
+ const next = !v;
822
+ localStorage.setItem("wallavi_bubble_expanded", String(next));
823
+ return next;
824
+ });
817
825
  const isLeft = resolvedPosition === "bottom-left";
826
+ useEffect(() => {
827
+ if (!open) {
828
+ setControlsPos(null);
829
+ return;
830
+ }
831
+ const update = () => {
832
+ const rect = panelRef.current?.getBoundingClientRect();
833
+ if (!rect) return;
834
+ setControlsPos({
835
+ top: rect.top - 12,
836
+ side: isLeft ? rect.left - 12 : window.innerWidth - rect.right - 12
837
+ });
838
+ };
839
+ const t = setTimeout(update, 16);
840
+ window.addEventListener("resize", update);
841
+ return () => {
842
+ clearTimeout(t);
843
+ window.removeEventListener("resize", update);
844
+ };
845
+ }, [open, isLeft, expanded]);
818
846
  return /* @__PURE__ */ jsxs(
819
847
  "div",
820
848
  {
@@ -829,92 +857,93 @@ function BubbleWidget({
829
857
  gap: 12
830
858
  },
831
859
  children: [
832
- /* @__PURE__ */ jsxs(
860
+ /* @__PURE__ */ jsx(
833
861
  "div",
834
862
  {
835
863
  ref: panelRef,
836
864
  "aria-hidden": !open,
837
865
  style: { display: open ? "block" : "none", position: "relative" },
838
- children: [
839
- /* @__PURE__ */ jsx(
840
- "div",
841
- {
842
- style: {
843
- width: expanded ? Math.min(expandedWidth, typeof window !== "undefined" ? window.innerWidth - 40 : expandedWidth) : width,
844
- height: expanded ? expandedHeight : height,
845
- transition: "width 0.3s ease, height 0.3s ease"
846
- },
847
- children: /* @__PURE__ */ jsx(
848
- ChatWidget,
849
- {
850
- ...mergedConfig,
851
- hideCloseButton: true,
852
- className: cn4("shadow-2xl h-full", panelClassName)
853
- }
854
- )
855
- }
856
- ),
857
- /* @__PURE__ */ jsxs(
858
- "div",
859
- {
860
- style: {
861
- position: "absolute",
862
- top: -12,
863
- [isLeft ? "left" : "right"]: -12,
864
- zIndex: 10,
865
- display: "flex",
866
- alignItems: "center",
867
- gap: 4
868
- },
869
- children: [
870
- /* @__PURE__ */ jsx(
871
- "button",
872
- {
873
- onClick: toggleExpanded,
874
- title: expanded ? "Minimize" : "Expand",
875
- style: {
876
- width: 24,
877
- height: 24,
878
- borderRadius: "50%",
879
- border: "1px solid rgba(0,0,0,0.1)",
880
- background: "var(--background, #fff)",
881
- boxShadow: "0 1px 4px rgba(0,0,0,0.12)",
882
- display: "flex",
883
- alignItems: "center",
884
- justifyContent: "center",
885
- cursor: "pointer",
886
- color: "var(--muted-foreground, #888)"
887
- },
888
- children: expanded ? /* @__PURE__ */ jsx(MinimizeIcon, {}) : /* @__PURE__ */ jsx(ExpandIcon, {})
889
- }
890
- ),
891
- /* @__PURE__ */ jsx(
892
- "button",
893
- {
894
- onClick: handleClose,
895
- title: "Close",
896
- style: {
897
- width: 24,
898
- height: 24,
899
- borderRadius: "50%",
900
- border: "1px solid rgba(0,0,0,0.1)",
901
- background: "var(--background, #fff)",
902
- boxShadow: "0 1px 4px rgba(0,0,0,0.12)",
903
- display: "flex",
904
- alignItems: "center",
905
- justifyContent: "center",
906
- cursor: "pointer",
907
- color: "var(--muted-foreground, #888)"
908
- },
909
- children: /* @__PURE__ */ jsx(CloseIcon, {})
910
- }
911
- )
912
- ]
913
- }
914
- )
915
- ]
866
+ children: /* @__PURE__ */ jsx(
867
+ "div",
868
+ {
869
+ style: {
870
+ width: expanded ? Math.min(expandedWidth, typeof window !== "undefined" ? window.innerWidth - 40 : expandedWidth) : width,
871
+ height: expanded ? expandedHeight : height,
872
+ transition: "width 0.3s ease, height 0.3s ease"
873
+ },
874
+ children: /* @__PURE__ */ jsx(
875
+ ChatWidget,
876
+ {
877
+ ...mergedConfig,
878
+ hideCloseButton: true,
879
+ className: cn4("shadow-2xl h-full", panelClassName)
880
+ }
881
+ )
882
+ }
883
+ )
916
884
  }
917
885
  ),
886
+ open && controlsPos && typeof document !== "undefined" && createPortal(
887
+ /* @__PURE__ */ jsxs(
888
+ "div",
889
+ {
890
+ style: {
891
+ position: "fixed",
892
+ top: controlsPos.top,
893
+ [isLeft ? "left" : "right"]: controlsPos.side,
894
+ zIndex: 10001,
895
+ display: "flex",
896
+ alignItems: "center",
897
+ gap: 4
898
+ },
899
+ children: [
900
+ /* @__PURE__ */ jsx(
901
+ "button",
902
+ {
903
+ onClick: toggleExpanded,
904
+ title: expanded ? "Minimize" : "Expand",
905
+ style: {
906
+ width: 24,
907
+ height: 24,
908
+ borderRadius: "50%",
909
+ border: "1px solid rgba(0,0,0,0.1)",
910
+ background: "var(--background, #fff)",
911
+ boxShadow: "0 1px 4px rgba(0,0,0,0.12)",
912
+ display: "flex",
913
+ alignItems: "center",
914
+ justifyContent: "center",
915
+ cursor: "pointer",
916
+ color: "var(--muted-foreground, #888)"
917
+ },
918
+ children: expanded ? /* @__PURE__ */ jsx(MinimizeIcon, {}) : /* @__PURE__ */ jsx(ExpandIcon, {})
919
+ }
920
+ ),
921
+ /* @__PURE__ */ jsx(
922
+ "button",
923
+ {
924
+ onClick: handleClose,
925
+ title: "Close",
926
+ style: {
927
+ width: 24,
928
+ height: 24,
929
+ borderRadius: "50%",
930
+ border: "1px solid rgba(0,0,0,0.1)",
931
+ background: "var(--background, #fff)",
932
+ boxShadow: "0 1px 4px rgba(0,0,0,0.12)",
933
+ display: "flex",
934
+ alignItems: "center",
935
+ justifyContent: "center",
936
+ cursor: "pointer",
937
+ color: "var(--muted-foreground, #888)"
938
+ },
939
+ children: /* @__PURE__ */ jsx(CloseIcon, {})
940
+ }
941
+ )
942
+ ]
943
+ }
944
+ ),
945
+ document.body
946
+ ),
918
947
  /* @__PURE__ */ jsx(
919
948
  "button",
920
949
  {
package/package.json CHANGED
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "private": false,
35
35
  "types": "./dist/index.d.ts",
36
- "version": "1.3.3",
36
+ "version": "1.3.5",
37
37
  "scripts": {
38
38
  "build": "tsup",
39
39
  "typecheck": "tsc --noEmit"