@eshal-bot/chat-widget 0.1.6 → 0.1.7

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.
@@ -57713,8 +57713,16 @@
57713
57713
  onboardingCompleted = false
57714
57714
  } = _ref;
57715
57715
  const [showTooltip, setShowTooltip] = reactExports.useState(false);
57716
+ const [tooltipPosition, setTooltipPosition] = reactExports.useState({
57717
+ top: 0,
57718
+ left: 0,
57719
+ placement: 'top',
57720
+ arrowOffset: 0
57721
+ });
57716
57722
  const tooltipTimeoutRef = reactExports.useRef(null);
57717
57723
  const textareaRef = reactExports.useRef(null);
57724
+ const voiceButtonRef = reactExports.useRef(null);
57725
+ const tooltipRef = reactExports.useRef(null);
57718
57726
  useGoogleFont(fontFamily);
57719
57727
  reactExports.useEffect(() => {
57720
57728
  if (isOpen && !isMinimized) {
@@ -57773,6 +57781,71 @@
57773
57781
  };
57774
57782
  const tooltipMessage = getTooltipMessage();
57775
57783
 
57784
+ // Calculate tooltip position dynamically
57785
+ const calculateTooltipPosition = () => {
57786
+ if (!voiceButtonRef.current) return;
57787
+ const buttonRect = voiceButtonRef.current.getBoundingClientRect();
57788
+ const tooltipWidth = 220; // maxWidth from style
57789
+ const tooltipHeight = 60; // approximate height
57790
+ const spacing = 8; // spacing between button and tooltip
57791
+
57792
+ // Try to position above first (preferred)
57793
+ const spaceAbove = buttonRect.top;
57794
+ const spaceBelow = window.innerHeight - buttonRect.bottom;
57795
+ let placement = 'top';
57796
+ let top = 0;
57797
+ let left = 0;
57798
+ if (spaceAbove >= tooltipHeight + spacing) {
57799
+ // Position above
57800
+ placement = 'top';
57801
+ top = buttonRect.top - tooltipHeight - spacing;
57802
+ left = buttonRect.right - tooltipWidth; // Right-align with button
57803
+
57804
+ // Ensure tooltip doesn't go off-screen to the left
57805
+ if (left < 10) {
57806
+ left = 10;
57807
+ }
57808
+ // Ensure tooltip doesn't go off-screen to the right
57809
+ if (left + tooltipWidth > window.innerWidth - 10) {
57810
+ left = window.innerWidth - tooltipWidth - 10;
57811
+ }
57812
+ } else if (spaceBelow >= tooltipHeight + spacing) {
57813
+ // Position below as fallback
57814
+ placement = 'bottom';
57815
+ top = buttonRect.bottom + spacing;
57816
+ left = buttonRect.right - tooltipWidth;
57817
+
57818
+ // Ensure tooltip doesn't go off-screen
57819
+ if (left < 10) {
57820
+ left = 10;
57821
+ }
57822
+ if (left + tooltipWidth > window.innerWidth - 10) {
57823
+ left = window.innerWidth - tooltipWidth - 10;
57824
+ }
57825
+ } else {
57826
+ // Not enough space above or below, position above anyway (may be partially visible)
57827
+ placement = 'top';
57828
+ top = Math.max(10, buttonRect.top - tooltipHeight - spacing);
57829
+ left = buttonRect.right - tooltipWidth;
57830
+ if (left < 10) {
57831
+ left = 10;
57832
+ }
57833
+ if (left + tooltipWidth > window.innerWidth - 10) {
57834
+ left = window.innerWidth - tooltipWidth - 10;
57835
+ }
57836
+ }
57837
+
57838
+ // Calculate arrow offset (center of button relative to tooltip left edge)
57839
+ const buttonCenterX = buttonRect.left + buttonRect.width / 2;
57840
+ const arrowOffset = buttonCenterX - left;
57841
+ return {
57842
+ top,
57843
+ left,
57844
+ placement,
57845
+ arrowOffset
57846
+ };
57847
+ };
57848
+
57776
57849
  // Handle tooltip show/hide
57777
57850
  const handleMouseEnter = () => {
57778
57851
  if (isVoiceButtonDisabled && tooltipMessage) {
@@ -57780,6 +57853,9 @@
57780
57853
  clearTimeout(tooltipTimeoutRef.current);
57781
57854
  tooltipTimeoutRef.current = null;
57782
57855
  }
57856
+ // Calculate position and show tooltip
57857
+ const position = calculateTooltipPosition();
57858
+ setTooltipPosition(position);
57783
57859
  setShowTooltip(true);
57784
57860
  }
57785
57861
  };
@@ -57790,6 +57866,22 @@
57790
57866
  }
57791
57867
  setShowTooltip(false);
57792
57868
  };
57869
+
57870
+ // Update tooltip position on scroll/resize
57871
+ reactExports.useEffect(() => {
57872
+ if (showTooltip && tooltipMessage) {
57873
+ const updatePosition = () => {
57874
+ const position = calculateTooltipPosition();
57875
+ setTooltipPosition(position);
57876
+ };
57877
+ window.addEventListener('scroll', updatePosition, true);
57878
+ window.addEventListener('resize', updatePosition);
57879
+ return () => {
57880
+ window.removeEventListener('scroll', updatePosition, true);
57881
+ window.removeEventListener('resize', updatePosition);
57882
+ };
57883
+ }
57884
+ }, [showTooltip, tooltipMessage]);
57793
57885
  reactExports.useEffect(() => {
57794
57886
  return () => {
57795
57887
  if (tooltipTimeoutRef.current) {
@@ -57845,6 +57937,7 @@
57845
57937
  onMouseEnter: handleMouseEnter,
57846
57938
  onMouseLeave: handleMouseLeave,
57847
57939
  children: [/*#__PURE__*/jsxRuntimeExports.jsx("button", {
57940
+ ref: voiceButtonRef,
57848
57941
  type: "button",
57849
57942
  onClick: onVoiceToggle,
57850
57943
  className: "h-10 w-10 rounded-xl flex items-center justify-center transition-all duration-200 shadow-md ".concat(isVoiceSessionActive ? "bg-red-500 text-white hover:bg-red-600" : isDark ? "bg-gray-800 text-gray-200 hover:bg-gray-700" : "bg-white text-gray-600 hover:bg-gray-100", " ").concat(isVoiceButtonDisabled ? "opacity-60 cursor-not-allowed shadow-none" : ""),
@@ -57854,15 +57947,18 @@
57854
57947
  }) : /*#__PURE__*/jsxRuntimeExports.jsx(AudioLines, {
57855
57948
  className: "w-4 h-4"
57856
57949
  })
57857
- }), showTooltip && tooltipMessage && /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
57858
- className: "absolute bottom-full mb-1.5 right-0 px-3 py-1.5 text-xs rounded-md shadow-md pointer-events-none",
57950
+ }), showTooltip && tooltipMessage && typeof document !== 'undefined' && /*#__PURE__*/reactDomExports.createPortal(/*#__PURE__*/jsxRuntimeExports.jsxs("div", {
57951
+ ref: tooltipRef,
57952
+ className: "px-3 py-1.5 text-xs rounded-md shadow-md pointer-events-none",
57859
57953
  style: {
57954
+ position: "fixed",
57955
+ top: "".concat(tooltipPosition.top, "px"),
57956
+ left: "".concat(tooltipPosition.left, "px"),
57860
57957
  maxWidth: "220px",
57861
57958
  whiteSpace: "normal",
57862
57959
  wordWrap: "break-word",
57863
57960
  minWidth: "180px",
57864
- zIndex: 99999,
57865
- position: "absolute",
57961
+ zIndex: 999999,
57866
57962
  backgroundColor: isDark ? "#1f2937" : "#ffffff",
57867
57963
  color: isDark ? "#f3f4f6" : "#111827",
57868
57964
  border: isDark ? "1px solid #374151" : "1px solid #e5e7eb",
@@ -57871,26 +57967,56 @@
57871
57967
  children: [/*#__PURE__*/jsxRuntimeExports.jsx("div", {
57872
57968
  className: "text-left leading-relaxed",
57873
57969
  children: tooltipMessage
57874
- }), /*#__PURE__*/jsxRuntimeExports.jsx("div", {
57875
- className: "absolute top-full right-4",
57876
- style: {
57877
- width: 0,
57878
- height: 0,
57879
- borderLeft: "5px solid transparent",
57880
- borderRight: "5px solid transparent",
57881
- borderTop: isDark ? "5px solid #374151" : "5px solid #e5e7eb"
57882
- }
57883
- }), /*#__PURE__*/jsxRuntimeExports.jsx("div", {
57884
- className: "absolute top-full right-4 -mt-px",
57885
- style: {
57886
- width: 0,
57887
- height: 0,
57888
- borderLeft: "4px solid transparent",
57889
- borderRight: "4px solid transparent",
57890
- borderTop: isDark ? "4px solid #1f2937" : "4px solid #ffffff"
57891
- }
57970
+ }), tooltipPosition.placement === 'top' && /*#__PURE__*/jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
57971
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx("div", {
57972
+ className: "absolute top-full",
57973
+ style: {
57974
+ left: "".concat(tooltipPosition.arrowOffset, "px"),
57975
+ transform: "translateX(-50%)",
57976
+ width: 0,
57977
+ height: 0,
57978
+ borderLeft: "5px solid transparent",
57979
+ borderRight: "5px solid transparent",
57980
+ borderTop: isDark ? "5px solid #374151" : "5px solid #e5e7eb"
57981
+ }
57982
+ }), /*#__PURE__*/jsxRuntimeExports.jsx("div", {
57983
+ className: "absolute top-full -mt-px",
57984
+ style: {
57985
+ left: "".concat(tooltipPosition.arrowOffset, "px"),
57986
+ transform: "translateX(-50%)",
57987
+ width: 0,
57988
+ height: 0,
57989
+ borderLeft: "4px solid transparent",
57990
+ borderRight: "4px solid transparent",
57991
+ borderTop: isDark ? "4px solid #1f2937" : "4px solid #ffffff"
57992
+ }
57993
+ })]
57994
+ }), tooltipPosition.placement === 'bottom' && /*#__PURE__*/jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
57995
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx("div", {
57996
+ className: "absolute bottom-full",
57997
+ style: {
57998
+ left: "".concat(tooltipPosition.arrowOffset, "px"),
57999
+ transform: "translateX(-50%)",
58000
+ width: 0,
58001
+ height: 0,
58002
+ borderLeft: "5px solid transparent",
58003
+ borderRight: "5px solid transparent",
58004
+ borderBottom: isDark ? "5px solid #374151" : "5px solid #e5e7eb"
58005
+ }
58006
+ }), /*#__PURE__*/jsxRuntimeExports.jsx("div", {
58007
+ className: "absolute bottom-full -mb-px",
58008
+ style: {
58009
+ left: "".concat(tooltipPosition.arrowOffset, "px"),
58010
+ transform: "translateX(-50%)",
58011
+ width: 0,
58012
+ height: 0,
58013
+ borderLeft: "4px solid transparent",
58014
+ borderRight: "4px solid transparent",
58015
+ borderBottom: isDark ? "4px solid #1f2937" : "4px solid #ffffff"
58016
+ }
58017
+ })]
57892
58018
  })]
57893
- })]
58019
+ }), document.body)]
57894
58020
  }), /*#__PURE__*/jsxRuntimeExports.jsx("button", {
57895
58021
  onClick: isVoiceSessionActive && onBidiSubmit ? onBidiSubmit : onSend,
57896
58022
  disabled: isDisabled || isVoiceSessionActive && voiceStatus !== "connected",