andy-widget-react 2.2.0 → 2.2.1

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.esm.js CHANGED
@@ -1493,9 +1493,6 @@ const generateDesignTokenVariablesString = () => {
1493
1493
  --andy-chat-avatar-size: 32px;
1494
1494
  --andy-chat-avatar-size-small: 24px;
1495
1495
 
1496
- /* Keyboard handling */
1497
- --andy-keyboard-height: 0px;
1498
-
1499
1496
  /* === THEMABLE VARIABLES (Default Light Theme) === */
1500
1497
  --andy-themable-background: var(--andy-color-background);
1501
1498
  --andy-themable-background-secondary: var(--andy-color-white);
@@ -2879,11 +2876,6 @@ const getCoreStructuralCssString = () => {
2879
2876
  }
2880
2877
  }
2881
2878
 
2882
- /* No special handling for keyboard - let browser handle it naturally */
2883
- .andy-chat-window--keyboard-open {
2884
- /* Browser handles positioning automatically with our margin-based approach */
2885
- }
2886
-
2887
2879
  /* Ensure the window content is properly laid out */
2888
2880
  .andy-chat-window__messages {
2889
2881
  flex: 1 1 auto;
@@ -3001,17 +2993,12 @@ const getCoreStructuralCssString = () => {
3001
2993
  }
3002
2994
  }
3003
2995
 
3004
- /* Desktop keyboard handling (for testing) */
2996
+ /* Desktop */
3005
2997
  @media (min-width: 521px) {
3006
2998
  /* Desktop retains original positioning behavior */
3007
2999
  .andy-chat-window {
3008
3000
  transition: transform 0.3s ease-out;
3009
3001
  }
3010
-
3011
- /* Optional: Add keyboard handling for desktop if needed */
3012
- .andy-chat-window--keyboard-open {
3013
- /* No transform on desktop - keyboard doesn't affect viewport */
3014
- }
3015
3002
  }
3016
3003
 
3017
3004
  /* Orientation */
@@ -3503,244 +3490,6 @@ const UI_STRINGS = {
3503
3490
  */
3504
3491
  const getUiStrings = lang => UI_STRINGS[lang] || UI_STRINGS.en;
3505
3492
 
3506
- /**
3507
- * Keyboard detection utility for handling mobile virtual keyboards
3508
- * Provides cross-browser support for detecting keyboard open/close events
3509
- */
3510
-
3511
- class KeyboardDetector {
3512
- constructor() {
3513
- this.isKeyboardOpen = false;
3514
- this.keyboardHeight = 0;
3515
- this.listeners = new Set();
3516
- this.inputElement = null;
3517
- this.viewportHeight = window.innerHeight;
3518
- this.visualViewport = window.visualViewport;
3519
-
3520
- this.initializeDetection();
3521
- }
3522
-
3523
- /**
3524
- * Initialize keyboard detection
3525
- */
3526
- initializeDetection() {
3527
- // Use Visual Viewport API if available (most modern browsers)
3528
- if (this.visualViewport) {
3529
- this.visualViewport.addEventListener('resize', this.handleViewportResize.bind(this));
3530
- this.visualViewport.addEventListener('scroll', this.handleViewportScroll.bind(this));
3531
- } else {
3532
- // Fallback for older browsers
3533
- window.addEventListener('resize', this.handleWindowResize.bind(this));
3534
- }
3535
-
3536
- // Additional detection via focus/blur events
3537
- document.addEventListener('focusin', this.handleFocusIn.bind(this), true);
3538
- document.addEventListener('focusout', this.handleFocusOut.bind(this), true);
3539
-
3540
- // Orientation change handler
3541
- window.addEventListener('orientationchange', this.handleOrientationChange.bind(this));
3542
- }
3543
-
3544
- /**
3545
- * Handle visual viewport resize (modern browsers)
3546
- */
3547
- handleViewportResize() {
3548
- const currentHeight = this.visualViewport.height;
3549
- const heightDifference = window.innerHeight - currentHeight;
3550
-
3551
- // If viewport shrunk by more than 100px, keyboard is likely open
3552
- if (heightDifference > 100) {
3553
- this.setKeyboardOpen(true, heightDifference);
3554
- } else if (heightDifference < 50) {
3555
- this.setKeyboardOpen(false, 0);
3556
- }
3557
- }
3558
-
3559
- /**
3560
- * Handle visual viewport scroll
3561
- */
3562
- handleViewportScroll() {
3563
- // On iOS, viewport scrolls when keyboard opens
3564
- if (this.visualViewport.offsetTop > 0) {
3565
- this.setKeyboardOpen(true, this.visualViewport.offsetTop);
3566
- }
3567
- }
3568
-
3569
- /**
3570
- * Handle window resize (fallback for older browsers)
3571
- */
3572
- handleWindowResize() {
3573
- const currentHeight = window.innerHeight;
3574
- const heightDifference = this.viewportHeight - currentHeight;
3575
-
3576
- // Significant height reduction likely means keyboard opened
3577
- if (heightDifference > 100) {
3578
- this.setKeyboardOpen(true, heightDifference);
3579
- } else if (Math.abs(heightDifference) < 50) {
3580
- this.setKeyboardOpen(false, 0);
3581
- this.viewportHeight = currentHeight;
3582
- }
3583
- }
3584
-
3585
- /**
3586
- * Handle input focus
3587
- */
3588
- handleFocusIn(e) {
3589
- const isInput = ['input', 'textarea'].includes(e.target.tagName.toLowerCase());
3590
- if (isInput) {
3591
- this.inputElement = e.target;
3592
- // Delay to allow keyboard animation
3593
- setTimeout(() => {
3594
- if (this.inputElement === e.target) {
3595
- this.checkKeyboardStatus();
3596
- }
3597
- }, 300);
3598
- }
3599
- }
3600
-
3601
- /**
3602
- * Handle input blur
3603
- */
3604
- handleFocusOut(e) {
3605
- const isInput = ['input', 'textarea'].includes(e.target.tagName.toLowerCase());
3606
- if (isInput && this.inputElement === e.target) {
3607
- this.inputElement = null;
3608
- // Delay to allow keyboard animation
3609
- setTimeout(() => {
3610
- if (!this.inputElement) {
3611
- this.setKeyboardOpen(false, 0);
3612
- }
3613
- }, 300);
3614
- }
3615
- }
3616
-
3617
- /**
3618
- * Handle orientation change
3619
- */
3620
- handleOrientationChange() {
3621
- // Reset viewport height after orientation change
3622
- setTimeout(() => {
3623
- this.viewportHeight = window.innerHeight;
3624
- this.checkKeyboardStatus();
3625
- }, 500);
3626
- }
3627
-
3628
- /**
3629
- * Check keyboard status (for browsers without Visual Viewport API)
3630
- */
3631
- checkKeyboardStatus() {
3632
- if (!this.visualViewport) {
3633
- const currentHeight = window.innerHeight;
3634
- const heightDifference = this.viewportHeight - currentHeight;
3635
-
3636
- if (this.inputElement && heightDifference > 100) {
3637
- this.setKeyboardOpen(true, heightDifference);
3638
- }
3639
- }
3640
- }
3641
-
3642
- /**
3643
- * Set keyboard state and notify listeners
3644
- */
3645
- setKeyboardOpen(isOpen, height) {
3646
- const changed = this.isKeyboardOpen !== isOpen || this.keyboardHeight !== height;
3647
-
3648
- this.isKeyboardOpen = isOpen;
3649
- this.keyboardHeight = height;
3650
-
3651
- if (changed) {
3652
- this.notifyListeners();
3653
- }
3654
- }
3655
-
3656
- /**
3657
- * Add listener for keyboard state changes
3658
- */
3659
- addListener(callback) {
3660
- this.listeners.add(callback);
3661
- // Immediately notify with current state
3662
- callback({
3663
- isOpen: this.isKeyboardOpen,
3664
- height: this.keyboardHeight
3665
- });
3666
- }
3667
-
3668
- /**
3669
- * Remove listener
3670
- */
3671
- removeListener(callback) {
3672
- this.listeners.delete(callback);
3673
- }
3674
-
3675
- /**
3676
- * Notify all listeners of state change
3677
- */
3678
- notifyListeners() {
3679
- const state = {
3680
- isOpen: this.isKeyboardOpen,
3681
- height: this.keyboardHeight
3682
- };
3683
-
3684
- this.listeners.forEach(callback => {
3685
- try {
3686
- callback(state);
3687
- } catch (error) {
3688
- console.error('Error in keyboard detector listener:', error);
3689
- }
3690
- });
3691
- }
3692
-
3693
- /**
3694
- * Get current keyboard state
3695
- */
3696
- getState() {
3697
- return {
3698
- isOpen: this.isKeyboardOpen,
3699
- height: this.keyboardHeight
3700
- }
3701
- }
3702
-
3703
- /**
3704
- * Cleanup
3705
- */
3706
- destroy() {
3707
- if (this.visualViewport) {
3708
- this.visualViewport.removeEventListener('resize', this.handleViewportResize.bind(this));
3709
- this.visualViewport.removeEventListener('scroll', this.handleViewportScroll.bind(this));
3710
- } else {
3711
- window.removeEventListener('resize', this.handleWindowResize.bind(this));
3712
- }
3713
-
3714
- document.removeEventListener('focusin', this.handleFocusIn.bind(this), true);
3715
- document.removeEventListener('focusout', this.handleFocusOut.bind(this), true);
3716
- window.removeEventListener('orientationchange', this.handleOrientationChange.bind(this));
3717
-
3718
- this.listeners.clear();
3719
- }
3720
- }
3721
-
3722
- // Create singleton instance
3723
- let keyboardDetectorInstance = null;
3724
-
3725
- /**
3726
- * Get or create keyboard detector instance
3727
- */
3728
- function getKeyboardDetector() {
3729
- if (!keyboardDetectorInstance) {
3730
- keyboardDetectorInstance = new KeyboardDetector();
3731
- }
3732
- return keyboardDetectorInstance
3733
- }
3734
-
3735
- /**
3736
- * Update CSS custom property on host element
3737
- */
3738
- function updateKeyboardHeight(hostElement, height) {
3739
- if (hostElement) {
3740
- hostElement.style.setProperty('--andy-keyboard-height', `${height}px`);
3741
- }
3742
- }
3743
-
3744
3493
  /**
3745
3494
  * Mobile detection utility for AndyChat
3746
3495
  * Provides reliable mobile device detection with multiple methods
@@ -4030,22 +3779,7 @@ const AndyChat = ({ embedId, tooltip, name, headline, description, welcomeMessag
4030
3779
  portalRef.current = portalTarget;
4031
3780
  }
4032
3781
  setShadowReady(true);
4033
- const keyboardDetector = getKeyboardDetector();
4034
- const keyboardListener = ({ isOpen: kbOpen, height }) => {
4035
- updateKeyboardHeight(containerRef.current, height);
4036
- const chatWindow = shadowRef.current?.querySelector('.andy-chat-window');
4037
- if (chatWindow) {
4038
- if (kbOpen && height > 0) {
4039
- chatWindow.classList.add('andy-chat-window--keyboard-open');
4040
- }
4041
- else {
4042
- chatWindow.classList.remove('andy-chat-window--keyboard-open');
4043
- }
4044
- }
4045
- };
4046
- keyboardDetector.addListener(keyboardListener);
4047
3782
  return () => {
4048
- keyboardDetector.removeListener(keyboardListener);
4049
3783
  shadowRef.current = null;
4050
3784
  portalRef.current = null;
4051
3785
  setShadowReady(false);