@liedekef/ftable 1.1.50 → 1.1.51

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 (38) hide show
  1. package/ftable.esm.js +122 -12
  2. package/ftable.js +122 -12
  3. package/ftable.min.js +2 -2
  4. package/ftable.umd.js +122 -12
  5. package/package.json +1 -1
  6. package/themes/basic/ftable_basic.css +4 -0
  7. package/themes/basic/ftable_basic.min.css +1 -1
  8. package/themes/ftable_theme_base.less +5 -0
  9. package/themes/lightcolor/blue/ftable.css +4 -0
  10. package/themes/lightcolor/blue/ftable.min.css +1 -1
  11. package/themes/lightcolor/gray/ftable.css +4 -0
  12. package/themes/lightcolor/gray/ftable.min.css +1 -1
  13. package/themes/lightcolor/green/ftable.css +4 -0
  14. package/themes/lightcolor/green/ftable.min.css +1 -1
  15. package/themes/lightcolor/orange/ftable.css +4 -0
  16. package/themes/lightcolor/orange/ftable.min.css +1 -1
  17. package/themes/lightcolor/red/ftable.css +4 -0
  18. package/themes/lightcolor/red/ftable.min.css +1 -1
  19. package/themes/metro/blue/ftable.css +4 -0
  20. package/themes/metro/blue/ftable.min.css +1 -1
  21. package/themes/metro/brown/ftable.css +4 -0
  22. package/themes/metro/brown/ftable.min.css +1 -1
  23. package/themes/metro/crimson/ftable.css +4 -0
  24. package/themes/metro/crimson/ftable.min.css +1 -1
  25. package/themes/metro/darkgray/ftable.css +4 -0
  26. package/themes/metro/darkgray/ftable.min.css +1 -1
  27. package/themes/metro/darkorange/ftable.css +4 -0
  28. package/themes/metro/darkorange/ftable.min.css +1 -1
  29. package/themes/metro/green/ftable.css +4 -0
  30. package/themes/metro/green/ftable.min.css +1 -1
  31. package/themes/metro/lightgray/ftable.css +4 -0
  32. package/themes/metro/lightgray/ftable.min.css +1 -1
  33. package/themes/metro/pink/ftable.css +4 -0
  34. package/themes/metro/pink/ftable.min.css +1 -1
  35. package/themes/metro/purple/ftable.css +4 -0
  36. package/themes/metro/purple/ftable.min.css +1 -1
  37. package/themes/metro/red/ftable.css +4 -0
  38. package/themes/metro/red/ftable.min.css +1 -1
package/ftable.esm.js CHANGED
@@ -1429,7 +1429,10 @@ class FTableFormBuilder {
1429
1429
  // Create display area
1430
1430
  const display = FTableDOMHelper.create('div', {
1431
1431
  className: 'ftable-multiselect-display',
1432
- parent: container
1432
+ parent: container,
1433
+ attributes: {
1434
+ tabindex: '0' // Makes it focusable and in tab order
1435
+ }
1433
1436
  });
1434
1437
 
1435
1438
  const selectedDisplay = FTableDOMHelper.create('div', {
@@ -1449,7 +1452,10 @@ class FTableFormBuilder {
1449
1452
  type: 'button',
1450
1453
  className: 'ftable-multiselect-toggle',
1451
1454
  innerHTML: '▼',
1452
- parent: display
1455
+ parent: display,
1456
+ attributes: {
1457
+ tabindex: '-1' // this skips regular focus when tabbing
1458
+ }
1453
1459
  });
1454
1460
 
1455
1461
  // Dropdown and overlay will be created on demand and appended to body
@@ -1524,6 +1530,7 @@ class FTableFormBuilder {
1524
1530
 
1525
1531
  // Function to close dropdown
1526
1532
  const closeDropdown = () => {
1533
+ display.focus(); // Return focus to the trigger
1527
1534
  if (dropdown) {
1528
1535
  dropdown.remove();
1529
1536
  dropdown = null;
@@ -1558,7 +1565,7 @@ class FTableFormBuilder {
1558
1565
  dropdown.style.zIndex = '10000';
1559
1566
 
1560
1567
  // Adjust horizontal position if needed
1561
- const dropdownRect = dropdown.getBoundingClientRect();
1568
+ const dropdownRect = dropdown.getBoundingClientRect();
1562
1569
  const viewportWidth = window.innerWidth;
1563
1570
  if (dropdownRect.right > viewportWidth) {
1564
1571
  left = Math.max(10, viewportWidth - dropdownRect.width - 10);
@@ -1643,7 +1650,12 @@ class FTableFormBuilder {
1643
1650
  // Create dropdown
1644
1651
  dropdown = FTableDOMHelper.create('div', {
1645
1652
  className: 'ftable-multiselect-dropdown',
1646
- parent: document.body
1653
+ parent: document.body,
1654
+ attributes: {
1655
+ tabindex: '-1',
1656
+ role: 'listbox',
1657
+ 'aria-multiselectable': 'true'
1658
+ }
1647
1659
  });
1648
1660
 
1649
1661
  // Populate options
@@ -1652,6 +1664,37 @@ class FTableFormBuilder {
1652
1664
  // Position dropdown
1653
1665
  positionDropdown();
1654
1666
 
1667
+ // dropdown focus
1668
+ dropdown.focus();
1669
+
1670
+ // Add keyboard navigation
1671
+ dropdown.addEventListener('keydown', (e) => {
1672
+ if (e.key === 'Escape') {
1673
+ closeDropdown();
1674
+ } else if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
1675
+ e.preventDefault();
1676
+ // Navigate between options
1677
+ const checkboxes = Array.from(dropdown.querySelectorAll('.ftable-multiselect-checkbox'));
1678
+ const current = document.activeElement;
1679
+ const currentIndex = checkboxes.indexOf(current);
1680
+
1681
+ let nextIndex;
1682
+ if (e.key === 'ArrowDown') {
1683
+ nextIndex = currentIndex < checkboxes.length - 1 ? currentIndex + 1 : 0;
1684
+ } else {
1685
+ nextIndex = currentIndex > 0 ? currentIndex - 1 : checkboxes.length - 1;
1686
+ }
1687
+
1688
+ checkboxes[nextIndex].focus();
1689
+ } else if (e.key === ' ' || e.key === 'Enter') {
1690
+ e.preventDefault();
1691
+ // Toggle the focused checkbox
1692
+ if (document.activeElement.classList.contains('ftable-multiselect-checkbox')) {
1693
+ document.activeElement.click();
1694
+ }
1695
+ }
1696
+ });
1697
+
1655
1698
  // Handle clicks outside
1656
1699
  dropdownOverlay.addEventListener('click', (event) => {
1657
1700
  if (event.target === dropdownOverlay) {
@@ -1660,13 +1703,19 @@ class FTableFormBuilder {
1660
1703
  });
1661
1704
 
1662
1705
  // Reposition on scroll/resize
1706
+ const scrollHandler = (e) => {
1707
+ if (dropdown && dropdown.contains(e.target)) {
1708
+ return; // Allow scrolling inside dropdown
1709
+ }
1710
+ positionDropdown();
1711
+ };
1663
1712
  const repositionHandler = () => positionDropdown();
1664
- window.addEventListener('scroll', repositionHandler, true);
1713
+ window.addEventListener('scroll', scrollHandler, true);
1665
1714
  window.addEventListener('resize', repositionHandler);
1666
1715
 
1667
1716
  // Store cleanup function
1668
1717
  container._cleanupHandlers = () => {
1669
- window.removeEventListener('scroll', repositionHandler, true);
1718
+ window.removeEventListener('scroll', scrollHandler, true);
1670
1719
  window.removeEventListener('resize', repositionHandler);
1671
1720
  };
1672
1721
  }
@@ -1674,6 +1723,12 @@ class FTableFormBuilder {
1674
1723
 
1675
1724
  display.addEventListener('click', toggleDropdown);
1676
1725
  toggleBtn.addEventListener('click', toggleDropdown);
1726
+ display.addEventListener('keydown', (e) => {
1727
+ if (e.key === 'ArrowDown' || e.key === 'Enter') {
1728
+ e.preventDefault();
1729
+ toggleDropdown();
1730
+ }
1731
+ });
1677
1732
 
1678
1733
  // Clean up when container is removed from DOM
1679
1734
  const observer = new MutationObserver((mutations) => {
@@ -2732,7 +2787,10 @@ class FTable extends FTableEventEmitter {
2732
2787
  // Create display area
2733
2788
  const display = FTableDOMHelper.create('div', {
2734
2789
  className: 'ftable-multiselect-display',
2735
- parent: container
2790
+ parent: container,
2791
+ attributes: {
2792
+ tabindex: '0' // Makes it focusable and in tab order
2793
+ }
2736
2794
  });
2737
2795
 
2738
2796
  const selectedDisplay = FTableDOMHelper.create('div', {
@@ -2752,7 +2810,10 @@ class FTable extends FTableEventEmitter {
2752
2810
  type: 'button',
2753
2811
  className: 'ftable-multiselect-toggle',
2754
2812
  innerHTML: '▼',
2755
- parent: display
2813
+ parent: display,
2814
+ attributes: {
2815
+ tabindex: '-1' // this skips regular focus when tabbing
2816
+ }
2756
2817
  });
2757
2818
 
2758
2819
  // Dropdown and overlay will be created on demand and appended to body
@@ -2826,6 +2887,7 @@ class FTable extends FTableEventEmitter {
2826
2887
 
2827
2888
  // Function to close dropdown
2828
2889
  const closeDropdown = () => {
2890
+ display.focus(); // Return focus to the trigger
2829
2891
  if (dropdown) {
2830
2892
  dropdown.remove();
2831
2893
  dropdown = null;
@@ -2860,7 +2922,7 @@ class FTable extends FTableEventEmitter {
2860
2922
  dropdown.style.zIndex = '10000';
2861
2923
 
2862
2924
  // Adjust horizontal position if needed
2863
- const dropdownRect = dropdown.getBoundingClientRect();
2925
+ const dropdownRect = dropdown.getBoundingClientRect();
2864
2926
  const viewportWidth = window.innerWidth;
2865
2927
  if (dropdownRect.right > viewportWidth) {
2866
2928
  left = Math.max(10, viewportWidth - dropdownRect.width - 10);
@@ -2957,7 +3019,12 @@ class FTable extends FTableEventEmitter {
2957
3019
  // Create dropdown
2958
3020
  dropdown = FTableDOMHelper.create('div', {
2959
3021
  className: 'ftable-multiselect-dropdown',
2960
- parent: document.body
3022
+ parent: document.body,
3023
+ attributes: {
3024
+ tabindex: '-1',
3025
+ role: 'listbox',
3026
+ 'aria-multiselectable': 'true'
3027
+ }
2961
3028
  });
2962
3029
 
2963
3030
  // Populate options
@@ -2966,6 +3033,37 @@ class FTable extends FTableEventEmitter {
2966
3033
  // Position dropdown
2967
3034
  positionDropdown();
2968
3035
 
3036
+ // dropdown focus
3037
+ dropdown.focus();
3038
+
3039
+ // Add keyboard navigation
3040
+ dropdown.addEventListener('keydown', (e) => {
3041
+ if (e.key === 'Escape') {
3042
+ closeDropdown();
3043
+ } else if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
3044
+ e.preventDefault();
3045
+ // Navigate between options
3046
+ const checkboxes = Array.from(dropdown.querySelectorAll('.ftable-multiselect-checkbox'));
3047
+ const current = document.activeElement;
3048
+ const currentIndex = checkboxes.indexOf(current);
3049
+
3050
+ let nextIndex;
3051
+ if (e.key === 'ArrowDown') {
3052
+ nextIndex = currentIndex < checkboxes.length - 1 ? currentIndex + 1 : 0;
3053
+ } else {
3054
+ nextIndex = currentIndex > 0 ? currentIndex - 1 : checkboxes.length - 1;
3055
+ }
3056
+
3057
+ checkboxes[nextIndex].focus();
3058
+ } else if (e.key === ' ' || e.key === 'Enter') {
3059
+ e.preventDefault();
3060
+ // Toggle the focused checkbox
3061
+ if (document.activeElement.classList.contains('ftable-multiselect-checkbox')) {
3062
+ document.activeElement.click();
3063
+ }
3064
+ }
3065
+ });
3066
+
2969
3067
  // Handle clicks outside
2970
3068
  dropdownOverlay.addEventListener('click', (event) => {
2971
3069
  if (event.target === dropdownOverlay) {
@@ -2974,13 +3072,19 @@ class FTable extends FTableEventEmitter {
2974
3072
  });
2975
3073
 
2976
3074
  // Reposition on scroll/resize
3075
+ const scrollHandler = (e) => {
3076
+ if (dropdown && dropdown.contains(e.target)) {
3077
+ return; // Allow scrolling inside dropdown
3078
+ }
3079
+ positionDropdown();
3080
+ };
2977
3081
  const repositionHandler = () => positionDropdown();
2978
- window.addEventListener('scroll', repositionHandler, true);
3082
+ window.addEventListener('scroll', scrollHandler, true);
2979
3083
  window.addEventListener('resize', repositionHandler);
2980
3084
 
2981
3085
  // Store cleanup function
2982
3086
  container._cleanupHandlers = () => {
2983
- window.removeEventListener('scroll', repositionHandler, true);
3087
+ window.removeEventListener('scroll', scrollHandler, true);
2984
3088
  window.removeEventListener('resize', repositionHandler);
2985
3089
  };
2986
3090
  }
@@ -2988,6 +3092,12 @@ class FTable extends FTableEventEmitter {
2988
3092
 
2989
3093
  display.addEventListener('click', toggleDropdown);
2990
3094
  toggleBtn.addEventListener('click', toggleDropdown);
3095
+ display.addEventListener('keydown', (e) => {
3096
+ if (e.key === 'ArrowDown' || e.key === 'Enter') {
3097
+ e.preventDefault();
3098
+ toggleDropdown();
3099
+ }
3100
+ });
2991
3101
 
2992
3102
  // Add reset method to container
2993
3103
  container.resetMultiSelect = () => {
package/ftable.js CHANGED
@@ -1430,7 +1430,10 @@ class FTableFormBuilder {
1430
1430
  // Create display area
1431
1431
  const display = FTableDOMHelper.create('div', {
1432
1432
  className: 'ftable-multiselect-display',
1433
- parent: container
1433
+ parent: container,
1434
+ attributes: {
1435
+ tabindex: '0' // Makes it focusable and in tab order
1436
+ }
1434
1437
  });
1435
1438
 
1436
1439
  const selectedDisplay = FTableDOMHelper.create('div', {
@@ -1450,7 +1453,10 @@ class FTableFormBuilder {
1450
1453
  type: 'button',
1451
1454
  className: 'ftable-multiselect-toggle',
1452
1455
  innerHTML: '▼',
1453
- parent: display
1456
+ parent: display,
1457
+ attributes: {
1458
+ tabindex: '-1' // this skips regular focus when tabbing
1459
+ }
1454
1460
  });
1455
1461
 
1456
1462
  // Dropdown and overlay will be created on demand and appended to body
@@ -1525,6 +1531,7 @@ class FTableFormBuilder {
1525
1531
 
1526
1532
  // Function to close dropdown
1527
1533
  const closeDropdown = () => {
1534
+ display.focus(); // Return focus to the trigger
1528
1535
  if (dropdown) {
1529
1536
  dropdown.remove();
1530
1537
  dropdown = null;
@@ -1559,7 +1566,7 @@ class FTableFormBuilder {
1559
1566
  dropdown.style.zIndex = '10000';
1560
1567
 
1561
1568
  // Adjust horizontal position if needed
1562
- const dropdownRect = dropdown.getBoundingClientRect();
1569
+ const dropdownRect = dropdown.getBoundingClientRect();
1563
1570
  const viewportWidth = window.innerWidth;
1564
1571
  if (dropdownRect.right > viewportWidth) {
1565
1572
  left = Math.max(10, viewportWidth - dropdownRect.width - 10);
@@ -1644,7 +1651,12 @@ class FTableFormBuilder {
1644
1651
  // Create dropdown
1645
1652
  dropdown = FTableDOMHelper.create('div', {
1646
1653
  className: 'ftable-multiselect-dropdown',
1647
- parent: document.body
1654
+ parent: document.body,
1655
+ attributes: {
1656
+ tabindex: '-1',
1657
+ role: 'listbox',
1658
+ 'aria-multiselectable': 'true'
1659
+ }
1648
1660
  });
1649
1661
 
1650
1662
  // Populate options
@@ -1653,6 +1665,37 @@ class FTableFormBuilder {
1653
1665
  // Position dropdown
1654
1666
  positionDropdown();
1655
1667
 
1668
+ // dropdown focus
1669
+ dropdown.focus();
1670
+
1671
+ // Add keyboard navigation
1672
+ dropdown.addEventListener('keydown', (e) => {
1673
+ if (e.key === 'Escape') {
1674
+ closeDropdown();
1675
+ } else if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
1676
+ e.preventDefault();
1677
+ // Navigate between options
1678
+ const checkboxes = Array.from(dropdown.querySelectorAll('.ftable-multiselect-checkbox'));
1679
+ const current = document.activeElement;
1680
+ const currentIndex = checkboxes.indexOf(current);
1681
+
1682
+ let nextIndex;
1683
+ if (e.key === 'ArrowDown') {
1684
+ nextIndex = currentIndex < checkboxes.length - 1 ? currentIndex + 1 : 0;
1685
+ } else {
1686
+ nextIndex = currentIndex > 0 ? currentIndex - 1 : checkboxes.length - 1;
1687
+ }
1688
+
1689
+ checkboxes[nextIndex].focus();
1690
+ } else if (e.key === ' ' || e.key === 'Enter') {
1691
+ e.preventDefault();
1692
+ // Toggle the focused checkbox
1693
+ if (document.activeElement.classList.contains('ftable-multiselect-checkbox')) {
1694
+ document.activeElement.click();
1695
+ }
1696
+ }
1697
+ });
1698
+
1656
1699
  // Handle clicks outside
1657
1700
  dropdownOverlay.addEventListener('click', (event) => {
1658
1701
  if (event.target === dropdownOverlay) {
@@ -1661,13 +1704,19 @@ class FTableFormBuilder {
1661
1704
  });
1662
1705
 
1663
1706
  // Reposition on scroll/resize
1707
+ const scrollHandler = (e) => {
1708
+ if (dropdown && dropdown.contains(e.target)) {
1709
+ return; // Allow scrolling inside dropdown
1710
+ }
1711
+ positionDropdown();
1712
+ };
1664
1713
  const repositionHandler = () => positionDropdown();
1665
- window.addEventListener('scroll', repositionHandler, true);
1714
+ window.addEventListener('scroll', scrollHandler, true);
1666
1715
  window.addEventListener('resize', repositionHandler);
1667
1716
 
1668
1717
  // Store cleanup function
1669
1718
  container._cleanupHandlers = () => {
1670
- window.removeEventListener('scroll', repositionHandler, true);
1719
+ window.removeEventListener('scroll', scrollHandler, true);
1671
1720
  window.removeEventListener('resize', repositionHandler);
1672
1721
  };
1673
1722
  }
@@ -1675,6 +1724,12 @@ class FTableFormBuilder {
1675
1724
 
1676
1725
  display.addEventListener('click', toggleDropdown);
1677
1726
  toggleBtn.addEventListener('click', toggleDropdown);
1727
+ display.addEventListener('keydown', (e) => {
1728
+ if (e.key === 'ArrowDown' || e.key === 'Enter') {
1729
+ e.preventDefault();
1730
+ toggleDropdown();
1731
+ }
1732
+ });
1678
1733
 
1679
1734
  // Clean up when container is removed from DOM
1680
1735
  const observer = new MutationObserver((mutations) => {
@@ -2733,7 +2788,10 @@ class FTable extends FTableEventEmitter {
2733
2788
  // Create display area
2734
2789
  const display = FTableDOMHelper.create('div', {
2735
2790
  className: 'ftable-multiselect-display',
2736
- parent: container
2791
+ parent: container,
2792
+ attributes: {
2793
+ tabindex: '0' // Makes it focusable and in tab order
2794
+ }
2737
2795
  });
2738
2796
 
2739
2797
  const selectedDisplay = FTableDOMHelper.create('div', {
@@ -2753,7 +2811,10 @@ class FTable extends FTableEventEmitter {
2753
2811
  type: 'button',
2754
2812
  className: 'ftable-multiselect-toggle',
2755
2813
  innerHTML: '▼',
2756
- parent: display
2814
+ parent: display,
2815
+ attributes: {
2816
+ tabindex: '-1' // this skips regular focus when tabbing
2817
+ }
2757
2818
  });
2758
2819
 
2759
2820
  // Dropdown and overlay will be created on demand and appended to body
@@ -2827,6 +2888,7 @@ class FTable extends FTableEventEmitter {
2827
2888
 
2828
2889
  // Function to close dropdown
2829
2890
  const closeDropdown = () => {
2891
+ display.focus(); // Return focus to the trigger
2830
2892
  if (dropdown) {
2831
2893
  dropdown.remove();
2832
2894
  dropdown = null;
@@ -2861,7 +2923,7 @@ class FTable extends FTableEventEmitter {
2861
2923
  dropdown.style.zIndex = '10000';
2862
2924
 
2863
2925
  // Adjust horizontal position if needed
2864
- const dropdownRect = dropdown.getBoundingClientRect();
2926
+ const dropdownRect = dropdown.getBoundingClientRect();
2865
2927
  const viewportWidth = window.innerWidth;
2866
2928
  if (dropdownRect.right > viewportWidth) {
2867
2929
  left = Math.max(10, viewportWidth - dropdownRect.width - 10);
@@ -2958,7 +3020,12 @@ class FTable extends FTableEventEmitter {
2958
3020
  // Create dropdown
2959
3021
  dropdown = FTableDOMHelper.create('div', {
2960
3022
  className: 'ftable-multiselect-dropdown',
2961
- parent: document.body
3023
+ parent: document.body,
3024
+ attributes: {
3025
+ tabindex: '-1',
3026
+ role: 'listbox',
3027
+ 'aria-multiselectable': 'true'
3028
+ }
2962
3029
  });
2963
3030
 
2964
3031
  // Populate options
@@ -2967,6 +3034,37 @@ class FTable extends FTableEventEmitter {
2967
3034
  // Position dropdown
2968
3035
  positionDropdown();
2969
3036
 
3037
+ // dropdown focus
3038
+ dropdown.focus();
3039
+
3040
+ // Add keyboard navigation
3041
+ dropdown.addEventListener('keydown', (e) => {
3042
+ if (e.key === 'Escape') {
3043
+ closeDropdown();
3044
+ } else if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
3045
+ e.preventDefault();
3046
+ // Navigate between options
3047
+ const checkboxes = Array.from(dropdown.querySelectorAll('.ftable-multiselect-checkbox'));
3048
+ const current = document.activeElement;
3049
+ const currentIndex = checkboxes.indexOf(current);
3050
+
3051
+ let nextIndex;
3052
+ if (e.key === 'ArrowDown') {
3053
+ nextIndex = currentIndex < checkboxes.length - 1 ? currentIndex + 1 : 0;
3054
+ } else {
3055
+ nextIndex = currentIndex > 0 ? currentIndex - 1 : checkboxes.length - 1;
3056
+ }
3057
+
3058
+ checkboxes[nextIndex].focus();
3059
+ } else if (e.key === ' ' || e.key === 'Enter') {
3060
+ e.preventDefault();
3061
+ // Toggle the focused checkbox
3062
+ if (document.activeElement.classList.contains('ftable-multiselect-checkbox')) {
3063
+ document.activeElement.click();
3064
+ }
3065
+ }
3066
+ });
3067
+
2970
3068
  // Handle clicks outside
2971
3069
  dropdownOverlay.addEventListener('click', (event) => {
2972
3070
  if (event.target === dropdownOverlay) {
@@ -2975,13 +3073,19 @@ class FTable extends FTableEventEmitter {
2975
3073
  });
2976
3074
 
2977
3075
  // Reposition on scroll/resize
3076
+ const scrollHandler = (e) => {
3077
+ if (dropdown && dropdown.contains(e.target)) {
3078
+ return; // Allow scrolling inside dropdown
3079
+ }
3080
+ positionDropdown();
3081
+ };
2978
3082
  const repositionHandler = () => positionDropdown();
2979
- window.addEventListener('scroll', repositionHandler, true);
3083
+ window.addEventListener('scroll', scrollHandler, true);
2980
3084
  window.addEventListener('resize', repositionHandler);
2981
3085
 
2982
3086
  // Store cleanup function
2983
3087
  container._cleanupHandlers = () => {
2984
- window.removeEventListener('scroll', repositionHandler, true);
3088
+ window.removeEventListener('scroll', scrollHandler, true);
2985
3089
  window.removeEventListener('resize', repositionHandler);
2986
3090
  };
2987
3091
  }
@@ -2989,6 +3093,12 @@ class FTable extends FTableEventEmitter {
2989
3093
 
2990
3094
  display.addEventListener('click', toggleDropdown);
2991
3095
  toggleBtn.addEventListener('click', toggleDropdown);
3096
+ display.addEventListener('keydown', (e) => {
3097
+ if (e.key === 'ArrowDown' || e.key === 'Enter') {
3098
+ e.preventDefault();
3099
+ toggleDropdown();
3100
+ }
3101
+ });
2992
3102
 
2993
3103
  // Add reset method to container
2994
3104
  container.resetMultiSelect = () => {