@basic-ui/core 0.0.28 → 0.0.32

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 (132) hide show
  1. package/build/cjs/index.js +44 -21
  2. package/build/cjs/index.js.map +1 -1
  3. package/build/esm/FocusLock/useFocusLock.js +21 -7
  4. package/build/esm/FocusLock/useFocusLock.js.map +1 -1
  5. package/build/esm/Menu/Menu.js +0 -3
  6. package/build/esm/Menu/Menu.js.map +1 -1
  7. package/build/esm/Menu/MenuButton.js +7 -5
  8. package/build/esm/Menu/MenuButton.js.map +1 -1
  9. package/build/esm/Menu/MenuList.js +8 -5
  10. package/build/esm/Menu/MenuList.js.map +1 -1
  11. package/build/esm/Menu/context.d.ts +0 -1
  12. package/build/esm/Menu/context.js.map +1 -1
  13. package/build/esm/Tooltip/Tooltip.d.ts +1 -0
  14. package/build/esm/Tooltip/Tooltip.js +10 -3
  15. package/build/esm/Tooltip/Tooltip.js.map +1 -1
  16. package/build/esm/hooks/useId.d.ts +1 -0
  17. package/build/esm/hooks/useId.js.map +1 -1
  18. package/build/tsconfig.tsbuildinfo +11 -11
  19. package/package.json +4 -3
  20. package/src/Accordion/Accordion.story.tsx +72 -0
  21. package/src/Accordion/Accordion.tsx +51 -0
  22. package/src/Accordion/AccordionBody.tsx +53 -0
  23. package/src/Accordion/AccordionHeader.tsx +165 -0
  24. package/src/Accordion/AccordionItem.tsx +43 -0
  25. package/src/Accordion/context.ts +35 -0
  26. package/src/Accordion/index.ts +4 -0
  27. package/src/Accordion/scopeQuery.ts +7 -0
  28. package/src/Accordion/styles.css +21 -0
  29. package/src/CheckBox/CheckBox.tsx +41 -0
  30. package/src/CheckBox/index.ts +1 -0
  31. package/src/ComboBox/ComboBox.story.tsx +118 -0
  32. package/src/ComboBox/Combobox.tsx +153 -0
  33. package/src/ComboBox/ComboboxButton.tsx +60 -0
  34. package/src/ComboBox/ComboboxInput.tsx +178 -0
  35. package/src/ComboBox/ComboboxLabel.tsx +32 -0
  36. package/src/ComboBox/ComboboxList.tsx +47 -0
  37. package/src/ComboBox/ComboboxOption.tsx +107 -0
  38. package/src/ComboBox/ComboboxPopover.tsx +58 -0
  39. package/src/ComboBox/cities.ts +23194 -0
  40. package/src/ComboBox/context.ts +33 -0
  41. package/src/ComboBox/hooks.tsx +428 -0
  42. package/src/ComboBox/index.ts +8 -0
  43. package/src/ComboBox/makeHash.ts +19 -0
  44. package/src/ComboBox/scopeQuery.ts +6 -0
  45. package/src/ComboBox/styles.css +30 -0
  46. package/src/FocusLock/FocusLock.tsx +59 -0
  47. package/src/FocusLock/index.ts +1 -0
  48. package/src/FocusLock/tabUtils.ts +28 -0
  49. package/src/FocusLock/useFocusLock.ts +61 -0
  50. package/src/List/List.story.tsx +17 -0
  51. package/src/List/List.tsx +17 -0
  52. package/src/List/ListItem.tsx +23 -0
  53. package/src/List/context.ts +19 -0
  54. package/src/List/index.ts +2 -0
  55. package/src/Menu/.gitkeep +0 -0
  56. package/src/Menu/Menu.story.tsx +158 -0
  57. package/src/Menu/Menu.tsx +60 -0
  58. package/src/Menu/MenuButton.tsx +83 -0
  59. package/src/Menu/MenuItem.tsx +83 -0
  60. package/src/Menu/MenuList.tsx +201 -0
  61. package/src/Menu/MenuPopover.tsx +25 -0
  62. package/src/Menu/context.ts +32 -0
  63. package/src/Menu/index.ts +5 -0
  64. package/src/Menu/scope.ts +7 -0
  65. package/src/Menu/styles.css +42 -0
  66. package/src/Modal/Modal.story.tsx +242 -0
  67. package/src/Modal/Modal.tsx +42 -0
  68. package/src/Modal/ModalBackdrop.tsx +72 -0
  69. package/src/Modal/NavDrawer.story.tsx +157 -0
  70. package/src/Modal/index.ts +2 -0
  71. package/src/Modal/styles.css +46 -0
  72. package/src/Popover/.gitkeep +0 -0
  73. package/src/Popper/Popper.story.tsx +267 -0
  74. package/src/Popper/Popper.tsx +149 -0
  75. package/src/Popper/PopperArrow.tsx +36 -0
  76. package/src/Popper/context.ts +9 -0
  77. package/src/Popper/index.ts +3 -0
  78. package/src/Popper/styles.css +60 -0
  79. package/src/Portal/Portal.tsx +20 -0
  80. package/src/Portal/index.ts +1 -0
  81. package/src/RadioButton/RadioButton.story.tsx +73 -0
  82. package/src/RadioButton/RadioButton.tsx +48 -0
  83. package/src/RadioButton/RadioGroup.tsx +56 -0
  84. package/src/RadioButton/context.ts +19 -0
  85. package/src/RadioButton/index.ts +2 -0
  86. package/src/SkipNav/SkipNav.tsx +16 -0
  87. package/src/SkipNav/index.tsx +1 -0
  88. package/src/Spinner/Spinner.story.tsx +30 -0
  89. package/src/Spinner/Spinner.tsx +112 -0
  90. package/src/Spinner/SpinnerButton.tsx +48 -0
  91. package/src/Spinner/context.ts +21 -0
  92. package/src/Spinner/index.ts +2 -0
  93. package/src/Spinner/styles.css +23 -0
  94. package/src/Tabs/Tab.story.tsx +78 -0
  95. package/src/Tabs/Tab.tsx +131 -0
  96. package/src/Tabs/TabList.tsx +63 -0
  97. package/src/Tabs/TabPanel.tsx +52 -0
  98. package/src/Tabs/TabPanels.tsx +30 -0
  99. package/src/Tabs/Tabs.tsx +47 -0
  100. package/src/Tabs/context.ts +30 -0
  101. package/src/Tabs/index.tsx +5 -0
  102. package/src/Tabs/scopeQuery.ts +6 -0
  103. package/src/Tabs/styles.css +0 -0
  104. package/src/Tooltip/.gitkeep +0 -0
  105. package/src/Tooltip/Tooltip.story.tsx +43 -0
  106. package/src/Tooltip/Tooltip.tsx +48 -0
  107. package/src/Tooltip/index.ts +1 -0
  108. package/src/Tooltip/stateMachine.ts +185 -0
  109. package/src/Tooltip/useTooltip.ts +121 -0
  110. package/src/hooks/index.ts +14 -0
  111. package/src/hooks/useAutoFocus.ts +13 -0
  112. package/src/hooks/useChildrenCounter.ts +50 -0
  113. package/src/hooks/useControlledState.ts +37 -0
  114. package/src/hooks/useFocusReturn.ts +23 -0
  115. package/src/hooks/useFocusState.ts +28 -0
  116. package/src/hooks/useGestureHandlers.ts +217 -0
  117. package/src/hooks/useId.ts +18 -0
  118. package/src/hooks/useMeasure.ts +33 -0
  119. package/src/hooks/useOnClickOutside.ts +32 -0
  120. package/src/hooks/useOnKeyDown.ts +18 -0
  121. package/src/hooks/useReducerMachine.ts +59 -0
  122. package/src/hooks/useRemoveBodyScroll.ts +37 -0
  123. package/src/hooks/useScope.ts +51 -0
  124. package/src/hooks/useThrottle.ts +19 -0
  125. package/src/index.ts +19 -0
  126. package/src/utils/assignRef.ts +27 -0
  127. package/src/utils/clamp.ts +3 -0
  128. package/src/utils/createSubscription.ts +16 -0
  129. package/src/utils/getCircularIndex.ts +7 -0
  130. package/src/utils/index.ts +4 -0
  131. package/src/utils/rubberBandClamp.ts +25 -0
  132. package/src/utils/wrapEvent.ts +20 -0
@@ -1634,6 +1634,7 @@ const getTabblableNodes = parentNode => {
1634
1634
  return Array.from(parentNode.querySelectorAll(tabblable));
1635
1635
  };
1636
1636
 
1637
+ const focusLockStack = [];
1637
1638
  function useFocusLock(ref, opts) {
1638
1639
  const {
1639
1640
  enabled = true,
@@ -1641,28 +1642,41 @@ function useFocusLock(ref, opts) {
1641
1642
  lockEndRef
1642
1643
  } = opts;
1643
1644
  react.useEffect(() => {
1644
- if (enabled) {
1645
+ const rootEl = ref.current;
1646
+
1647
+ if (enabled && rootEl) {
1648
+ focusLockStack.push(rootEl);
1649
+
1645
1650
  const listener = event => {
1651
+ const isActiveFocusLock = focusLockStack[focusLockStack.length - 1] === rootEl;
1652
+
1653
+ if (!isActiveFocusLock) {
1654
+ // Not the currently focused lock. Forget about it.
1655
+ return;
1656
+ }
1657
+
1646
1658
  if (event.target === lockEndRef.current) {
1647
- ref.current && ref.current.focus();
1659
+ rootEl.focus();
1648
1660
  } else if (event.target === lockStartRef.current) {
1649
- const nodes = getTabblableNodes(ref.current);
1661
+ const nodes = getTabblableNodes(rootEl);
1650
1662
 
1651
1663
  if (nodes.length > 0) {
1652
1664
  const nodeToFocus = nodes.length - 1;
1653
1665
  nodes[nodeToFocus].focus();
1654
1666
  } else {
1655
- ref.current && ref.current.focus();
1667
+ rootEl.focus();
1656
1668
  }
1657
- } else if (document !== event.target && ref.current && ref.current !== event.target && !ref.current.contains(event.target)) {
1669
+ } else if (document !== event.target && rootEl !== event.target && !rootEl.contains(event.target)) {
1658
1670
  event.preventDefault();
1659
- ref.current.focus();
1671
+ rootEl.focus();
1660
1672
  }
1661
1673
  };
1662
1674
 
1663
1675
  document.addEventListener('focusin', listener);
1664
1676
  return () => {
1665
- document.removeEventListener('focusin', listener);
1677
+ document.removeEventListener('focusin', listener); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1678
+
1679
+ focusLockStack.pop();
1666
1680
  };
1667
1681
  } // eslint-disable-next-line react-hooks/exhaustive-deps
1668
1682
 
@@ -1733,7 +1747,6 @@ const Menu = /*#__PURE__*/react.forwardRef(function Menu(props, forwardedRef) {
1733
1747
  } = props,
1734
1748
  otherProps = _objectWithoutPropertiesLoose__default['default'](props, ["as", "open", "defaultOpen", "onChange"]);
1735
1749
 
1736
- const buttonIdRef = react.useRef();
1737
1750
  const menuListIdRef = react.useRef();
1738
1751
  const openWithArrowKeyRef = react.useRef(null);
1739
1752
  const buttonRef = react.useRef(null);
@@ -1741,9 +1754,7 @@ const Menu = /*#__PURE__*/react.forwardRef(function Menu(props, forwardedRef) {
1741
1754
  setState(isOpen);
1742
1755
  });
1743
1756
  menuListIdRef.current = useId();
1744
- buttonIdRef.current = useId();
1745
1757
  const value = {
1746
- buttonIdRef,
1747
1758
  menuListIdRef,
1748
1759
  openWithArrowKeyRef,
1749
1760
  open,
@@ -1770,19 +1781,20 @@ const MenuButton = /*#__PURE__*/react.forwardRef(function MenuButton(props, forw
1770
1781
 
1771
1782
  const {
1772
1783
  menuListIdRef,
1773
- buttonIdRef,
1774
1784
  openWithArrowKeyRef,
1775
1785
  open,
1776
1786
  buttonRef,
1777
1787
  onChange
1778
1788
  } = useMenuContext();
1779
- buttonIdRef.current = preferredId || buttonIdRef.current;
1789
+ const buttonId = useId(preferredId);
1780
1790
 
1781
1791
  const handleKeyDown = e => {
1782
1792
  if (disabled) {
1783
1793
  return;
1784
1794
  }
1785
1795
 
1796
+ buttonRef.current = e.currentTarget;
1797
+
1786
1798
  const isArrowKey = () => ['ArrowUp', 'ArrowDown'].includes(e.key);
1787
1799
 
1788
1800
  const isEnterKey = () => [' ', 'Enter'].includes(e.key);
@@ -1805,12 +1817,13 @@ const MenuButton = /*#__PURE__*/react.forwardRef(function MenuButton(props, forw
1805
1817
  return;
1806
1818
  }
1807
1819
 
1820
+ buttonRef.current = e.currentTarget;
1808
1821
  onChange && onChange(e, !open);
1809
1822
  };
1810
1823
 
1811
1824
  return /*#__PURE__*/jsxRuntime.jsx(Comp, _extends__default['default']({
1812
- ref: assignMultipleRefs(forwardedRef, buttonRef),
1813
- id: buttonIdRef.current,
1825
+ ref: forwardedRef,
1826
+ id: buttonId,
1814
1827
  role: "button",
1815
1828
  type: "button",
1816
1829
  "aria-haspopup": true,
@@ -1894,6 +1907,8 @@ function queryScope(type, props) {
1894
1907
 
1895
1908
  const useEnhancedEffect$1 = typeof window !== 'undefined' ? react.useLayoutEffect : react.useEffect;
1896
1909
  const MenuList = /*#__PURE__*/react.forwardRef(function MenuList(props, forwardedRef) {
1910
+ var _buttonRef$current3;
1911
+
1897
1912
  const {
1898
1913
  as: Comp = 'ul',
1899
1914
  onKeyDown,
@@ -1904,7 +1919,6 @@ const MenuList = /*#__PURE__*/react.forwardRef(function MenuList(props, forwarde
1904
1919
 
1905
1920
  const {
1906
1921
  menuListIdRef,
1907
- buttonIdRef,
1908
1922
  buttonRef,
1909
1923
  onChange,
1910
1924
  openWithArrowKeyRef,
@@ -1944,7 +1958,9 @@ const MenuList = /*#__PURE__*/react.forwardRef(function MenuList(props, forwarde
1944
1958
  setMounted(true);
1945
1959
  }, [mounted, navigationItem, onNavigate, openWithArrowKeyRef, scope, defaultActiveItemValue]);
1946
1960
  useOnClickOutside(menuListRef, e => {
1947
- if (e.target !== buttonRef.current) {
1961
+ var _buttonRef$current;
1962
+
1963
+ if (e.target instanceof HTMLElement && e.target !== buttonRef.current && !((_buttonRef$current = buttonRef.current) != null && _buttonRef$current.contains(e.target))) {
1948
1964
  onChange && onChange(e, false);
1949
1965
  }
1950
1966
 
@@ -1956,12 +1972,12 @@ const MenuList = /*#__PURE__*/react.forwardRef(function MenuList(props, forwarde
1956
1972
  case 'Escape':
1957
1973
  case 'Tab':
1958
1974
  {
1959
- var _buttonRef$current;
1975
+ var _buttonRef$current2;
1960
1976
 
1961
1977
  onChange && onChange(e, false);
1962
1978
  e.preventDefault(); // prevents focusing on next element, because we will be handling it
1963
1979
 
1964
- (_buttonRef$current = buttonRef.current) == null ? void 0 : _buttonRef$current.focus();
1980
+ (_buttonRef$current2 = buttonRef.current) == null ? void 0 : _buttonRef$current2.focus();
1965
1981
  break;
1966
1982
  }
1967
1983
 
@@ -2046,7 +2062,7 @@ const MenuList = /*#__PURE__*/react.forwardRef(function MenuList(props, forwarde
2046
2062
  ref: assignMultipleRefs(forwardedRef, menuListRef),
2047
2063
  id: menuListIdRef.current,
2048
2064
  role: "menu",
2049
- "aria-labelledby": buttonIdRef.current,
2065
+ "aria-labelledby": (_buttonRef$current3 = buttonRef.current) == null ? void 0 : _buttonRef$current3.id,
2050
2066
  "data-menu-list": "",
2051
2067
  tabIndex: "-1",
2052
2068
  onKeyDown: wrapEvent(onKeyDown, handleKeyDown)
@@ -2998,9 +3014,10 @@ const Tooltip = /*#__PURE__*/react.forwardRef(function Tooltip(props, forwardedR
2998
3014
  const {
2999
3015
  as: Comp = 'div',
3000
3016
  innerAs,
3001
- children
3017
+ children,
3018
+ disabled = false
3002
3019
  } = props,
3003
- otherProps = _objectWithoutPropertiesLoose__default['default'](props, ["as", "innerAs", "children"]);
3020
+ otherProps = _objectWithoutPropertiesLoose__default['default'](props, ["as", "innerAs", "children", "disabled"]);
3004
3021
 
3005
3022
  const child = react.Children.only(children);
3006
3023
  const [childProps, _ref] = useTooltip(child.props, child.ref, otherProps);
@@ -3010,6 +3027,12 @@ const Tooltip = /*#__PURE__*/react.forwardRef(function Tooltip(props, forwardedR
3010
3027
  } = _ref,
3011
3028
  tooltipProps = _objectWithoutPropertiesLoose__default['default'](_ref, ["visible"]);
3012
3029
 
3030
+ if (disabled) {
3031
+ return /*#__PURE__*/jsxRuntime.jsx(jsxRuntime.Fragment, {
3032
+ children: child
3033
+ });
3034
+ }
3035
+
3013
3036
  return /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
3014
3037
  children: [/*#__PURE__*/react.cloneElement(child, childProps), visible && /*#__PURE__*/jsxRuntime.jsx(Comp, _extends__default['default']({
3015
3038
  as: innerAs,