@basic-ui/core 0.0.37 → 0.0.38

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 (299) hide show
  1. package/build/cjs/index.js +84 -83
  2. package/build/cjs/index.js.map +1 -1
  3. package/build/esm/Accordion/Accordion.d.ts +0 -0
  4. package/build/esm/Accordion/Accordion.js +0 -0
  5. package/build/esm/Accordion/Accordion.js.map +0 -0
  6. package/build/esm/Accordion/AccordionBody.d.ts +0 -0
  7. package/build/esm/Accordion/AccordionBody.js +0 -0
  8. package/build/esm/Accordion/AccordionBody.js.map +0 -0
  9. package/build/esm/Accordion/AccordionHeader.d.ts +0 -0
  10. package/build/esm/Accordion/AccordionHeader.js +0 -0
  11. package/build/esm/Accordion/AccordionHeader.js.map +0 -0
  12. package/build/esm/Accordion/AccordionItem.d.ts +0 -0
  13. package/build/esm/Accordion/AccordionItem.js +1 -2
  14. package/build/esm/Accordion/AccordionItem.js.map +1 -1
  15. package/build/esm/Accordion/context.d.ts +0 -0
  16. package/build/esm/Accordion/context.js +0 -0
  17. package/build/esm/Accordion/context.js.map +0 -0
  18. package/build/esm/Accordion/index.d.ts +0 -0
  19. package/build/esm/Accordion/index.js +0 -0
  20. package/build/esm/Accordion/index.js.map +0 -0
  21. package/build/esm/Accordion/scopeQuery.d.ts +0 -0
  22. package/build/esm/Accordion/scopeQuery.js +0 -0
  23. package/build/esm/Accordion/scopeQuery.js.map +0 -0
  24. package/build/esm/CheckBox/CheckBox.d.ts +0 -0
  25. package/build/esm/CheckBox/CheckBox.js +0 -0
  26. package/build/esm/CheckBox/CheckBox.js.map +0 -0
  27. package/build/esm/CheckBox/index.d.ts +0 -0
  28. package/build/esm/CheckBox/index.js +0 -0
  29. package/build/esm/CheckBox/index.js.map +0 -0
  30. package/build/esm/ComboBox/Combobox.d.ts +0 -0
  31. package/build/esm/ComboBox/Combobox.js +2 -2
  32. package/build/esm/ComboBox/Combobox.js.map +1 -1
  33. package/build/esm/ComboBox/ComboboxButton.d.ts +0 -0
  34. package/build/esm/ComboBox/ComboboxButton.js +0 -0
  35. package/build/esm/ComboBox/ComboboxButton.js.map +0 -0
  36. package/build/esm/ComboBox/ComboboxInput.d.ts +0 -0
  37. package/build/esm/ComboBox/ComboboxInput.js +0 -0
  38. package/build/esm/ComboBox/ComboboxInput.js.map +0 -0
  39. package/build/esm/ComboBox/ComboboxLabel.d.ts +0 -0
  40. package/build/esm/ComboBox/ComboboxLabel.js +0 -0
  41. package/build/esm/ComboBox/ComboboxLabel.js.map +0 -0
  42. package/build/esm/ComboBox/ComboboxList.d.ts +0 -0
  43. package/build/esm/ComboBox/ComboboxList.js +0 -0
  44. package/build/esm/ComboBox/ComboboxList.js.map +0 -0
  45. package/build/esm/ComboBox/ComboboxOption.d.ts +0 -0
  46. package/build/esm/ComboBox/ComboboxOption.js +0 -0
  47. package/build/esm/ComboBox/ComboboxOption.js.map +0 -0
  48. package/build/esm/ComboBox/ComboboxPopover.d.ts +0 -0
  49. package/build/esm/ComboBox/ComboboxPopover.js +0 -0
  50. package/build/esm/ComboBox/ComboboxPopover.js.map +0 -0
  51. package/build/esm/ComboBox/cities.d.ts +0 -0
  52. package/build/esm/ComboBox/cities.js +0 -0
  53. package/build/esm/ComboBox/cities.js.map +0 -0
  54. package/build/esm/ComboBox/context.d.ts +0 -0
  55. package/build/esm/ComboBox/context.js +0 -0
  56. package/build/esm/ComboBox/context.js.map +0 -0
  57. package/build/esm/ComboBox/hooks.d.ts +0 -0
  58. package/build/esm/ComboBox/hooks.js +0 -0
  59. package/build/esm/ComboBox/hooks.js.map +0 -0
  60. package/build/esm/ComboBox/index.d.ts +0 -0
  61. package/build/esm/ComboBox/index.js +0 -0
  62. package/build/esm/ComboBox/index.js.map +0 -0
  63. package/build/esm/ComboBox/makeHash.d.ts +0 -0
  64. package/build/esm/ComboBox/makeHash.js +0 -0
  65. package/build/esm/ComboBox/makeHash.js.map +0 -0
  66. package/build/esm/ComboBox/scopeQuery.d.ts +0 -0
  67. package/build/esm/ComboBox/scopeQuery.js +0 -0
  68. package/build/esm/ComboBox/scopeQuery.js.map +0 -0
  69. package/build/esm/FocusLock/FocusLock.d.ts +0 -0
  70. package/build/esm/FocusLock/FocusLock.js +0 -0
  71. package/build/esm/FocusLock/FocusLock.js.map +0 -0
  72. package/build/esm/FocusLock/index.d.ts +0 -0
  73. package/build/esm/FocusLock/index.js +0 -0
  74. package/build/esm/FocusLock/index.js.map +0 -0
  75. package/build/esm/FocusLock/tabUtils.d.ts +1 -0
  76. package/build/esm/FocusLock/tabUtils.js +12 -0
  77. package/build/esm/FocusLock/tabUtils.js.map +1 -1
  78. package/build/esm/FocusLock/useFocusLock.d.ts +0 -0
  79. package/build/esm/FocusLock/useFocusLock.js +4 -11
  80. package/build/esm/FocusLock/useFocusLock.js.map +1 -1
  81. package/build/esm/List/List.d.ts +0 -0
  82. package/build/esm/List/List.js +0 -0
  83. package/build/esm/List/List.js.map +0 -0
  84. package/build/esm/List/ListItem.d.ts +0 -0
  85. package/build/esm/List/ListItem.js +0 -0
  86. package/build/esm/List/ListItem.js.map +0 -0
  87. package/build/esm/List/context.d.ts +0 -0
  88. package/build/esm/List/context.js +0 -0
  89. package/build/esm/List/context.js.map +0 -0
  90. package/build/esm/List/index.d.ts +0 -0
  91. package/build/esm/List/index.js +0 -0
  92. package/build/esm/List/index.js.map +0 -0
  93. package/build/esm/Menu/Menu.d.ts +0 -0
  94. package/build/esm/Menu/Menu.js +1 -2
  95. package/build/esm/Menu/Menu.js.map +1 -1
  96. package/build/esm/Menu/MenuButton.d.ts +0 -0
  97. package/build/esm/Menu/MenuButton.js +3 -3
  98. package/build/esm/Menu/MenuButton.js.map +1 -1
  99. package/build/esm/Menu/MenuItem.d.ts +0 -0
  100. package/build/esm/Menu/MenuItem.js +3 -4
  101. package/build/esm/Menu/MenuItem.js.map +1 -1
  102. package/build/esm/Menu/MenuList.d.ts +0 -0
  103. package/build/esm/Menu/MenuList.js +0 -0
  104. package/build/esm/Menu/MenuList.js.map +0 -0
  105. package/build/esm/Menu/MenuPopover.d.ts +0 -0
  106. package/build/esm/Menu/MenuPopover.js +0 -0
  107. package/build/esm/Menu/MenuPopover.js.map +0 -0
  108. package/build/esm/Menu/context.d.ts +0 -0
  109. package/build/esm/Menu/context.js +0 -0
  110. package/build/esm/Menu/context.js.map +0 -0
  111. package/build/esm/Menu/index.d.ts +0 -0
  112. package/build/esm/Menu/index.js +0 -0
  113. package/build/esm/Menu/index.js.map +0 -0
  114. package/build/esm/Menu/scope.d.ts +0 -0
  115. package/build/esm/Menu/scope.js +0 -0
  116. package/build/esm/Menu/scope.js.map +0 -0
  117. package/build/esm/Modal/Modal.d.ts +0 -0
  118. package/build/esm/Modal/Modal.js +2 -2
  119. package/build/esm/Modal/Modal.js.map +1 -1
  120. package/build/esm/Modal/ModalBackdrop.d.ts +0 -0
  121. package/build/esm/Modal/ModalBackdrop.js +0 -0
  122. package/build/esm/Modal/ModalBackdrop.js.map +0 -0
  123. package/build/esm/Modal/index.d.ts +0 -0
  124. package/build/esm/Modal/index.js +0 -0
  125. package/build/esm/Modal/index.js.map +0 -0
  126. package/build/esm/Popper/Popper.d.ts +0 -0
  127. package/build/esm/Popper/Popper.js +5 -0
  128. package/build/esm/Popper/Popper.js.map +1 -1
  129. package/build/esm/Popper/PopperArrow.d.ts +0 -0
  130. package/build/esm/Popper/PopperArrow.js +0 -0
  131. package/build/esm/Popper/PopperArrow.js.map +0 -0
  132. package/build/esm/Popper/context.d.ts +0 -0
  133. package/build/esm/Popper/context.js +0 -0
  134. package/build/esm/Popper/context.js.map +0 -0
  135. package/build/esm/Popper/index.d.ts +0 -0
  136. package/build/esm/Popper/index.js +0 -0
  137. package/build/esm/Popper/index.js.map +0 -0
  138. package/build/esm/Portal/Portal.d.ts +0 -0
  139. package/build/esm/Portal/Portal.js +0 -0
  140. package/build/esm/Portal/Portal.js.map +0 -0
  141. package/build/esm/Portal/index.d.ts +0 -0
  142. package/build/esm/Portal/index.js +0 -0
  143. package/build/esm/Portal/index.js.map +0 -0
  144. package/build/esm/RadioButton/RadioButton.d.ts +0 -0
  145. package/build/esm/RadioButton/RadioButton.js +0 -0
  146. package/build/esm/RadioButton/RadioButton.js.map +0 -0
  147. package/build/esm/RadioButton/RadioGroup.d.ts +0 -0
  148. package/build/esm/RadioButton/RadioGroup.js +2 -2
  149. package/build/esm/RadioButton/RadioGroup.js.map +1 -1
  150. package/build/esm/RadioButton/context.d.ts +0 -0
  151. package/build/esm/RadioButton/context.js +0 -0
  152. package/build/esm/RadioButton/context.js.map +0 -0
  153. package/build/esm/RadioButton/index.d.ts +0 -0
  154. package/build/esm/RadioButton/index.js +0 -0
  155. package/build/esm/RadioButton/index.js.map +0 -0
  156. package/build/esm/SkipNav/SkipNav.d.ts +0 -0
  157. package/build/esm/SkipNav/SkipNav.js +0 -0
  158. package/build/esm/SkipNav/SkipNav.js.map +0 -0
  159. package/build/esm/SkipNav/index.d.ts +0 -0
  160. package/build/esm/SkipNav/index.js +0 -0
  161. package/build/esm/SkipNav/index.js.map +0 -0
  162. package/build/esm/Spinner/Spinner.d.ts +0 -0
  163. package/build/esm/Spinner/Spinner.js +0 -0
  164. package/build/esm/Spinner/Spinner.js.map +0 -0
  165. package/build/esm/Spinner/SpinnerButton.d.ts +0 -0
  166. package/build/esm/Spinner/SpinnerButton.js +0 -0
  167. package/build/esm/Spinner/SpinnerButton.js.map +0 -0
  168. package/build/esm/Spinner/context.d.ts +0 -0
  169. package/build/esm/Spinner/context.js +0 -0
  170. package/build/esm/Spinner/context.js.map +0 -0
  171. package/build/esm/Spinner/index.d.ts +0 -0
  172. package/build/esm/Spinner/index.js +0 -0
  173. package/build/esm/Spinner/index.js.map +0 -0
  174. package/build/esm/Tabs/Tab.d.ts +0 -0
  175. package/build/esm/Tabs/Tab.js +0 -0
  176. package/build/esm/Tabs/Tab.js.map +0 -0
  177. package/build/esm/Tabs/TabList.d.ts +0 -0
  178. package/build/esm/Tabs/TabList.js +2 -2
  179. package/build/esm/Tabs/TabList.js.map +1 -1
  180. package/build/esm/Tabs/TabPanel.d.ts +0 -0
  181. package/build/esm/Tabs/TabPanel.js +0 -0
  182. package/build/esm/Tabs/TabPanel.js.map +0 -0
  183. package/build/esm/Tabs/TabPanels.d.ts +0 -0
  184. package/build/esm/Tabs/TabPanels.js +0 -0
  185. package/build/esm/Tabs/TabPanels.js.map +0 -0
  186. package/build/esm/Tabs/Tabs.d.ts +0 -0
  187. package/build/esm/Tabs/Tabs.js +0 -0
  188. package/build/esm/Tabs/Tabs.js.map +0 -0
  189. package/build/esm/Tabs/context.d.ts +0 -0
  190. package/build/esm/Tabs/context.js +0 -0
  191. package/build/esm/Tabs/context.js.map +0 -0
  192. package/build/esm/Tabs/index.d.ts +0 -0
  193. package/build/esm/Tabs/index.js +0 -0
  194. package/build/esm/Tabs/index.js.map +0 -0
  195. package/build/esm/Tabs/scopeQuery.d.ts +0 -0
  196. package/build/esm/Tabs/scopeQuery.js +0 -0
  197. package/build/esm/Tabs/scopeQuery.js.map +0 -0
  198. package/build/esm/Tooltip/Tooltip.d.ts +0 -0
  199. package/build/esm/Tooltip/Tooltip.js +0 -0
  200. package/build/esm/Tooltip/Tooltip.js.map +0 -0
  201. package/build/esm/Tooltip/index.d.ts +0 -0
  202. package/build/esm/Tooltip/index.js +0 -0
  203. package/build/esm/Tooltip/index.js.map +0 -0
  204. package/build/esm/Tooltip/stateMachine.d.ts +0 -0
  205. package/build/esm/Tooltip/stateMachine.js +0 -0
  206. package/build/esm/Tooltip/stateMachine.js.map +0 -0
  207. package/build/esm/Tooltip/useTooltip.d.ts +0 -0
  208. package/build/esm/Tooltip/useTooltip.js +2 -3
  209. package/build/esm/Tooltip/useTooltip.js.map +1 -1
  210. package/build/esm/hooks/index.d.ts +0 -1
  211. package/build/esm/hooks/index.js +0 -1
  212. package/build/esm/hooks/index.js.map +1 -1
  213. package/build/esm/hooks/useAutoFocus.d.ts +0 -0
  214. package/build/esm/hooks/useAutoFocus.js +5 -1
  215. package/build/esm/hooks/useAutoFocus.js.map +1 -1
  216. package/build/esm/hooks/useChildrenCounter.d.ts +0 -0
  217. package/build/esm/hooks/useChildrenCounter.js +0 -0
  218. package/build/esm/hooks/useChildrenCounter.js.map +0 -0
  219. package/build/esm/hooks/useControlledState.d.ts +0 -0
  220. package/build/esm/hooks/useControlledState.js +0 -0
  221. package/build/esm/hooks/useControlledState.js.map +0 -0
  222. package/build/esm/hooks/useFocusReturn.d.ts +2 -1
  223. package/build/esm/hooks/useFocusReturn.js +24 -13
  224. package/build/esm/hooks/useFocusReturn.js.map +1 -1
  225. package/build/esm/hooks/useFocusState.d.ts +0 -0
  226. package/build/esm/hooks/useFocusState.js +0 -0
  227. package/build/esm/hooks/useFocusState.js.map +0 -0
  228. package/build/esm/hooks/useGestureHandlers.d.ts +0 -0
  229. package/build/esm/hooks/useGestureHandlers.js +0 -0
  230. package/build/esm/hooks/useGestureHandlers.js.map +0 -0
  231. package/build/esm/hooks/useId.d.ts +0 -0
  232. package/build/esm/hooks/useId.js +0 -0
  233. package/build/esm/hooks/useId.js.map +0 -0
  234. package/build/esm/hooks/useMeasure.d.ts +0 -0
  235. package/build/esm/hooks/useMeasure.js +0 -0
  236. package/build/esm/hooks/useMeasure.js.map +0 -0
  237. package/build/esm/hooks/useOnClickOutside.d.ts +0 -0
  238. package/build/esm/hooks/useOnClickOutside.js +0 -0
  239. package/build/esm/hooks/useOnClickOutside.js.map +0 -0
  240. package/build/esm/hooks/useOnKeyDown.d.ts +0 -0
  241. package/build/esm/hooks/useOnKeyDown.js +0 -0
  242. package/build/esm/hooks/useOnKeyDown.js.map +0 -0
  243. package/build/esm/hooks/useReducerMachine.d.ts +0 -0
  244. package/build/esm/hooks/useReducerMachine.js +0 -0
  245. package/build/esm/hooks/useReducerMachine.js.map +0 -0
  246. package/build/esm/hooks/useRemoveBodyScroll.d.ts +0 -0
  247. package/build/esm/hooks/useRemoveBodyScroll.js +12 -19
  248. package/build/esm/hooks/useRemoveBodyScroll.js.map +1 -1
  249. package/build/esm/hooks/useScope.d.ts +0 -0
  250. package/build/esm/hooks/useScope.js +0 -0
  251. package/build/esm/hooks/useScope.js.map +0 -0
  252. package/build/esm/hooks/useThrottle.d.ts +0 -0
  253. package/build/esm/hooks/useThrottle.js +0 -0
  254. package/build/esm/hooks/useThrottle.js.map +0 -0
  255. package/build/esm/index.d.ts +0 -0
  256. package/build/esm/index.js +0 -0
  257. package/build/esm/index.js.map +0 -0
  258. package/build/esm/utils/assignRef.d.ts +0 -0
  259. package/build/esm/utils/assignRef.js +0 -0
  260. package/build/esm/utils/assignRef.js.map +0 -0
  261. package/build/esm/utils/clamp.d.ts +0 -0
  262. package/build/esm/utils/clamp.js +0 -0
  263. package/build/esm/utils/clamp.js.map +0 -0
  264. package/build/esm/utils/createSubscription.d.ts +0 -0
  265. package/build/esm/utils/createSubscription.js +0 -0
  266. package/build/esm/utils/createSubscription.js.map +0 -0
  267. package/build/esm/utils/getCircularIndex.d.ts +0 -0
  268. package/build/esm/utils/getCircularIndex.js +0 -0
  269. package/build/esm/utils/getCircularIndex.js.map +0 -0
  270. package/build/esm/utils/index.d.ts +0 -0
  271. package/build/esm/utils/index.js +0 -0
  272. package/build/esm/utils/index.js.map +0 -0
  273. package/build/esm/utils/rubberBandClamp.d.ts +0 -0
  274. package/build/esm/utils/rubberBandClamp.js +0 -0
  275. package/build/esm/utils/rubberBandClamp.js.map +0 -0
  276. package/build/esm/utils/wrapEvent.d.ts +0 -0
  277. package/build/esm/utils/wrapEvent.js +0 -0
  278. package/build/esm/utils/wrapEvent.js.map +0 -0
  279. package/build/tsconfig.tsbuildinfo +1 -7069
  280. package/package.json +13 -13
  281. package/src/Accordion/AccordionItem.tsx +1 -2
  282. package/src/ComboBox/ComboBox.story.tsx +2 -1
  283. package/src/ComboBox/Combobox.tsx +2 -2
  284. package/src/FocusLock/tabUtils.ts +12 -0
  285. package/src/FocusLock/useFocusLock.ts +4 -11
  286. package/src/Menu/Menu.tsx +1 -2
  287. package/src/Menu/MenuButton.tsx +3 -3
  288. package/src/Menu/MenuItem.tsx +4 -6
  289. package/src/Modal/Modal.story.tsx +19 -5
  290. package/src/Modal/Modal.tsx +2 -2
  291. package/src/Popper/Popper.tsx +4 -0
  292. package/src/RadioButton/RadioGroup.tsx +2 -2
  293. package/src/Tabs/TabList.tsx +9 -2
  294. package/src/Tooltip/useTooltip.ts +2 -3
  295. package/src/hooks/index.ts +0 -1
  296. package/src/hooks/useAutoFocus.ts +8 -1
  297. package/src/hooks/useFocusReturn.ts +33 -14
  298. package/src/hooks/useRemoveBodyScroll.ts +10 -18
  299. package/src/hooks/useId.ts +0 -18
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@basic-ui/core",
3
- "version": "0.0.37",
3
+ "version": "0.0.38",
4
4
  "description": "Accessible React Components used as building blocks for UI patterns",
5
5
  "author": "Lucas Terra <lucasterra7@gmail.com>",
6
6
  "license": "MIT",
@@ -15,20 +15,20 @@
15
15
  "sideEffects": false,
16
16
  "scripts": {
17
17
  "build": "run -T concurrently \"yarn:build:*\"",
18
- "build:dts": "tsc -p ./tsconfig.json --isolatedModules false --declaration --emitDeclarationOnly",
19
- "build:cjs": "rollup -c ../../rollup.config.js",
20
- "build:esm": "cross-env NODE_ENV=production BABEL_ENV=esm babel --config-file ../../babel.config.js ./src --extensions \".ts,.tsx,.js,.jsx\" --source-maps --out-dir ./build/esm --ignore \"**/*.story.tsx,**/*.story.ts,**/*.test.tsx,**/*.test.ts\"",
21
- "build-storybook": "build-storybook -c ../../scripts/storybook -o .out",
22
- "storybook": "yarn run -T start-storybook -p 9001 -c ../../scripts/storybook",
23
- "start": "yarn run storybook",
24
- "serve": "http-server .out",
25
- "lint": "eslint 'src/**/*.{js,jsx,ts,tsx}' --fix",
26
- "typecheck": "tsc --noEmit -p ./tsconfig.json",
27
- "test": "jest --config ../../jest.config.js",
18
+ "build:dts": "run -T tsc -p ./tsconfig.json --isolatedModules false --declaration --emitDeclarationOnly",
19
+ "build:cjs": "run -T rollup -c ../../rollup.config.js",
20
+ "build:esm": "run -T cross-env NODE_ENV=production BABEL_ENV=esm babel --config-file ../../babel.config.js ./src --extensions \".ts,.tsx,.js,.jsx\" --source-maps --out-dir ./build/esm --ignore \"**/*.story.tsx,**/*.story.ts,**/*.test.tsx,**/*.test.ts\"",
21
+ "build-storybook": "run -T build-storybook -c ../../scripts/storybook -o .out",
22
+ "storybook": "run -T start-storybook -p 9001 -c ../../scripts/storybook",
23
+ "start": "run storybook",
24
+ "serve": "run -T http-server .out",
25
+ "lint": "run -T eslint 'src/**/*.{js,jsx,ts,tsx}' --fix",
26
+ "typecheck": "run -T tsc --noEmit -p ./tsconfig.json",
27
+ "test": "run -T jest --config ../../jest.config.js",
28
28
  "test:watch": "yarn test --watch"
29
29
  },
30
30
  "dependencies": {
31
- "@popperjs/core": "^2.9.2",
31
+ "@popperjs/core": "^2.11.5",
32
32
  "resize-observer-polyfill": "^1.5.1"
33
33
  },
34
34
  "peerDependencies": {
@@ -36,5 +36,5 @@
36
36
  "react": "^16.14.0 || ^17.0.0 || ^18.0.0",
37
37
  "react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0"
38
38
  },
39
- "gitHead": "78b668ff80ce86a4672b3f34ca2c1aaaf79c56eb"
39
+ "gitHead": "f3a2affbe87fb4f5e59f5528f9e3af53fc311120"
40
40
  }
@@ -1,7 +1,6 @@
1
- import { Fragment, forwardRef } from 'react';
1
+ import { Fragment, forwardRef, useId } from 'react';
2
2
  import type * as React from 'react';
3
3
  import { AccordionItemContextProps, AccordionItemProvider } from './context';
4
- import { useId } from '../hooks';
5
4
 
6
5
  export interface AccordionItemProps
7
6
  extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {
@@ -1,4 +1,4 @@
1
- import { useMemo, useState } from 'react';
1
+ import { useMemo, useState, useRef } from 'react';
2
2
  import type * as React from 'react';
3
3
  import { ComboboxOption } from './ComboboxOption';
4
4
  import { ComboboxList } from './ComboboxList';
@@ -6,6 +6,7 @@ import { ComboboxPopover } from './ComboboxPopover';
6
6
  import { ComboboxInput } from './ComboboxInput';
7
7
  import { ComboboxLabel } from './ComboboxLabel';
8
8
  import { Combobox } from './Combobox';
9
+ import { Popper } from '../Popper';
9
10
  import cities from './cities';
10
11
  import './styles.css';
11
12
 
@@ -1,4 +1,4 @@
1
- import { forwardRef, useRef, useMemo } from 'react';
1
+ import { forwardRef, useRef, useMemo, useId } from 'react';
2
2
  import type * as React from 'react';
3
3
  import {
4
4
  stateChart,
@@ -9,7 +9,7 @@ import {
9
9
  } from './hooks';
10
10
  import { ComboBoxProvider, ComboBoxContextProps } from './context';
11
11
  import { useReducerMachine } from '../hooks/useReducerMachine';
12
- import { useId, Scope, getScope } from '../hooks';
12
+ import { Scope, getScope } from '../hooks';
13
13
 
14
14
  export type SelectEventHandler = (
15
15
  text: string,
@@ -26,3 +26,15 @@ export const getTabblableNodes = (
26
26
 
27
27
  return Array.from(parentNode.querySelectorAll(tabblable));
28
28
  };
29
+
30
+ export function focusOnChildNode(parentNode: HTMLElement, itemIndex: 0 | -1) {
31
+ const elements = getTabblableNodes(parentNode);
32
+ if (elements.length > 0) {
33
+ elements[itemIndex === -1 ? elements.length - 1 : 0].focus();
34
+ } else {
35
+ const currentTabIndex = parentNode.tabIndex;
36
+ parentNode.tabIndex = 0;
37
+ parentNode.focus();
38
+ parentNode.tabIndex = currentTabIndex;
39
+ }
40
+ }
@@ -1,5 +1,5 @@
1
1
  import { useEffect } from 'react';
2
- import { getTabblableNodes } from './tabUtils';
2
+ import { focusOnChildNode } from './tabUtils';
3
3
 
4
4
  export interface FocusLockOptions {
5
5
  enabled: boolean;
@@ -28,23 +28,16 @@ export function useFocusLock(
28
28
  }
29
29
 
30
30
  if (event.target === lockEndRef.current) {
31
- rootEl.focus();
31
+ focusOnChildNode(rootEl, 0);
32
32
  } else if (event.target === lockStartRef.current) {
33
- const nodes = getTabblableNodes(rootEl);
34
-
35
- if (nodes.length > 0) {
36
- const nodeToFocus = nodes.length - 1;
37
- nodes[nodeToFocus].focus();
38
- } else {
39
- rootEl.focus();
40
- }
33
+ focusOnChildNode(rootEl, -1);
41
34
  } else if (
42
35
  document !== event.target &&
43
36
  rootEl !== event.target &&
44
37
  !rootEl.contains(event.target as any)
45
38
  ) {
46
39
  event.preventDefault();
47
- rootEl.focus();
40
+ focusOnChildNode(rootEl, 0);
48
41
  }
49
42
  };
50
43
 
package/src/Menu/Menu.tsx CHANGED
@@ -1,7 +1,6 @@
1
- import { forwardRef, useRef, Fragment } from 'react';
1
+ import { forwardRef, useRef, Fragment, useId } from 'react';
2
2
  import type * as React from 'react';
3
3
  import { MenuProvider, MenuContextProps } from './context';
4
- import { useId } from '../hooks/useId';
5
4
  import { useControlledState } from '../hooks';
6
5
 
7
6
  export interface MenuProps {
@@ -1,8 +1,7 @@
1
- import { forwardRef } from 'react';
1
+ import { forwardRef, useId } from 'react';
2
2
  import type * as React from 'react';
3
3
  import { useMenuContext } from './context';
4
4
  import { wrapEvent } from '../utils/wrapEvent';
5
- import { useId } from '../hooks';
6
5
 
7
6
  export type MenuButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {
8
7
  as?: React.ElementType<any>;
@@ -32,7 +31,8 @@ export const MenuButton = forwardRef<HTMLButtonElement, MenuButtonProps>(
32
31
  onChange,
33
32
  } = useMenuContext();
34
33
 
35
- const buttonId = useId(preferredId);
34
+ const buttonIdGenerated = useId();
35
+ const buttonId = preferredId || buttonIdGenerated;
36
36
 
37
37
  const handleKeyDown = (e: React.KeyboardEvent<HTMLButtonElement>) => {
38
38
  if (disabled) {
@@ -1,4 +1,4 @@
1
- import { forwardRef, useRef } from 'react';
1
+ import { forwardRef, useRef, useId } from 'react';
2
2
  import type * as React from 'react';
3
3
  import { useMenuContext, useMenuListContext } from './context';
4
4
  import { assignMultipleRefs } from '../utils/assignRef';
@@ -25,10 +25,10 @@ export const MenuItem = forwardRef<any, MenuItemProps>(function MenuItem(
25
25
  onKeyDown,
26
26
  ...otherProps
27
27
  } = props;
28
- const { menuListIdRef, onChange, buttonRef } = useMenuContext();
28
+ const { onChange, buttonRef } = useMenuContext();
29
29
  const { navigationItem, onNavigate } = useMenuListContext();
30
30
  const ref = useRef<HTMLLIElement>();
31
- const itemIndex = useRef(-1);
31
+ const itemId = useId();
32
32
 
33
33
  const isActive = ref.current && ref.current === navigationItem;
34
34
 
@@ -65,9 +65,7 @@ export const MenuItem = forwardRef<any, MenuItemProps>(function MenuItem(
65
65
  return (
66
66
  <Comp
67
67
  ref={assignMultipleRefs(ref, forwardedRef)}
68
- id={
69
- disabled ? undefined : `${menuListIdRef.current}_${itemIndex.current}`
70
- }
68
+ id={disabled ? undefined : itemId}
71
69
  data-menu-item=""
72
70
  data-highlighted={isActive ? '' : undefined}
73
71
  role="menuitem"
@@ -91,7 +91,9 @@ const SimpleModalControlledExample = () => {
91
91
 
92
92
  return (
93
93
  <>
94
- <button onClick={() => setOpen(!open)}>Open modal</button>
94
+ <button id="open-modal" onClick={() => setOpen(!open)}>
95
+ Open modal
96
+ </button>
95
97
  {open && (
96
98
  <Portal>
97
99
  <ModalBackdrop onClose={handleClose}>
@@ -113,12 +115,16 @@ const NestedModalControlledExample = () => {
113
115
 
114
116
  return (
115
117
  <>
116
- <button onClick={() => setOpen(!open)}>Open modal</button>
118
+ <button id="open-modal" onClick={() => setOpen(!open)}>
119
+ Open modal
120
+ </button>
117
121
  {open && (
118
122
  <Portal>
119
123
  <ModalBackdrop onClose={() => setOpen(false)}>
120
124
  <Modal trapFocus={true}>
121
- <button onClick={() => setOpen2(true)}>Open another modal</button>
125
+ <button id="open-another-modal" onClick={() => setOpen2(true)}>
126
+ Open another modal
127
+ </button>
122
128
  {open2 && (
123
129
  <Portal>
124
130
  <ModalBackdrop onClose={() => setOpen2(false)}>
@@ -130,7 +136,13 @@ const NestedModalControlledExample = () => {
130
136
  </Portal>
131
137
  )}
132
138
  <LoremIpsum numOfParagraphs={1} />
133
- <button onClick={() => setOpen(false)}>Close</button>
139
+ <button
140
+ autoFocus
141
+ id="close-button"
142
+ onClick={() => setOpen(false)}
143
+ >
144
+ Close
145
+ </button>
134
146
  </Modal>
135
147
  </ModalBackdrop>
136
148
  </Portal>
@@ -187,7 +199,9 @@ const SimpleModalControlledAnimatedExample = () => {
187
199
 
188
200
  return (
189
201
  <>
190
- <button onClick={handleOpen}>Open modal</button>
202
+ <button id="open-modal" onClick={handleOpen}>
203
+ Open modal
204
+ </button>
191
205
  {open && (
192
206
  <Portal>
193
207
  <animated.div
@@ -19,7 +19,7 @@ export const Modal = forwardRef<HTMLDivElement, ModalProps>(
19
19
  ) => {
20
20
  const modalRef = useRef<HTMLDivElement>(null);
21
21
 
22
- useFocusReturn(trapFocus);
22
+ useFocusReturn(trapFocus, modalRef);
23
23
  useRemoveBodyScroll(trapFocus);
24
24
  useAutoFocus(trapFocus, modalRef);
25
25
 
@@ -31,7 +31,7 @@ export const Modal = forwardRef<HTMLDivElement, ModalProps>(
31
31
  role="dialog"
32
32
  aria-modal="true"
33
33
  style={style}
34
- tabIndex={0}
34
+ tabIndex={-1}
35
35
  {...otherProps}
36
36
  >
37
37
  {children}
@@ -123,6 +123,10 @@ export const Popper = memo(
123
123
  };
124
124
  }, [anchorEl, modifiers, placement, strategy, defaultModifiers]);
125
125
 
126
+ useEnhancedEffect(() => {
127
+ popperEngineInstance.current?.forceUpdate();
128
+ }, [props.hidden || props['aria-hidden']]);
129
+
126
130
  const contextValue: PopperContextProps = {
127
131
  arrowRef,
128
132
  };
@@ -1,7 +1,7 @@
1
- import { forwardRef } from 'react';
1
+ import { forwardRef, useId } from 'react';
2
2
  import type * as React from 'react';
3
3
  import { RadioGroupProvider, RadioValue } from './context';
4
- import { useControlledState, useId } from '../hooks';
4
+ import { useControlledState } from '../hooks';
5
5
 
6
6
  export interface RadioGroupProps
7
7
  extends Omit<
@@ -1,7 +1,14 @@
1
- import { forwardRef, useRef, useEffect, Children, cloneElement } from 'react';
1
+ import {
2
+ forwardRef,
3
+ useRef,
4
+ useEffect,
5
+ Children,
6
+ cloneElement,
7
+ useId,
8
+ } from 'react';
2
9
  import type * as React from 'react';
3
10
  import { TabListProvider, useTabsContext } from './context';
4
- import { useScope, useId } from '../hooks';
11
+ import { useScope } from '../hooks';
5
12
  import { assignMultipleRefs } from '../utils';
6
13
 
7
14
  export interface TabListProps extends React.HTMLAttributes<HTMLDivElement> {
@@ -1,7 +1,6 @@
1
- import { useRef, RefAttributes, useEffect, useState } from 'react';
1
+ import { useRef, RefAttributes, useEffect, useState, useId } from 'react';
2
2
  import { assignMultipleRefs } from '../utils/assignRef';
3
3
  import { wrapEvent } from '../utils/wrapEvent';
4
- import { useId } from '../hooks/useId';
5
4
  import {
6
5
  send,
7
6
  state,
@@ -43,7 +42,7 @@ export function useTooltip(
43
42
  } = childProps;
44
43
  const anchorEl = useRef<HTMLElement>(null);
45
44
  const [visible, setVisible] = useState(false);
46
- const id = useId('');
45
+ const id = useId();
47
46
 
48
47
  useEffect(() => {
49
48
  subscription.subscribe(() => {
@@ -3,7 +3,6 @@ export * from './useControlledState';
3
3
  export * from './useChildrenCounter';
4
4
  export * from './useFocusReturn';
5
5
  export * from './useFocusState';
6
- export * from './useId';
7
6
  export * from './useOnClickOutside';
8
7
  export * from './useOnKeyDown';
9
8
  export * from './useReducerMachine';
@@ -1,4 +1,5 @@
1
1
  import { useEffect } from 'react';
2
+ import { focusOnChildNode } from '../FocusLock/tabUtils';
2
3
 
3
4
  export function useAutoFocus(
4
5
  open: boolean,
@@ -6,7 +7,13 @@ export function useAutoFocus(
6
7
  ) {
7
8
  useEffect(() => {
8
9
  if (open) {
9
- elementRef.current && elementRef.current.focus();
10
+ // We will only autoFocus on the first child if the currently active element isn't already trapped inside the modal
11
+ if (
12
+ elementRef.current &&
13
+ !elementRef.current.contains(document.activeElement)
14
+ ) {
15
+ focusOnChildNode(elementRef.current, 0);
16
+ }
10
17
  }
11
18
  // eslint-disable-next-line react-hooks/exhaustive-deps
12
19
  }, [open]);
@@ -1,23 +1,42 @@
1
- import { useEffect, useRef } from 'react';
1
+ import { MutableRefObject, useEffect, useRef } from 'react';
2
2
 
3
- export function useFocusReturn(open: boolean) {
4
- const previousFocusRef = useRef<Element | null>(null);
3
+ export function useFocusReturn(
4
+ open: boolean,
5
+ rootEl: MutableRefObject<HTMLElement | null>
6
+ ) {
7
+ const previousFocusRef = useRef<HTMLElement | null>(
8
+ (() => {
9
+ if (
10
+ open &&
11
+ typeof document !== 'undefined' &&
12
+ document.activeElement instanceof HTMLElement
13
+ ) {
14
+ return document.activeElement;
15
+ }
16
+ return null;
17
+ })()
18
+ );
5
19
 
6
20
  useEffect(() => {
7
21
  if (open) {
8
22
  // once opened, keep track of the element that triggered
9
23
  // the Modal opening
10
- previousFocusRef.current = document.activeElement;
11
- }
24
+ if (
25
+ !previousFocusRef.current &&
26
+ document.activeElement instanceof HTMLElement &&
27
+ !rootEl.current?.contains(document.activeElement)
28
+ ) {
29
+ previousFocusRef.current = document.activeElement;
30
+ }
12
31
 
13
- return () => {
14
- // on unmount, return focus to that element
15
- const previousFocus = previousFocusRef.current;
16
- requestAnimationFrame(() => {
17
- if (previousFocus) {
18
- (previousFocus as HTMLElement).focus();
32
+ const rootElement = rootEl.current;
33
+ const previousElement = previousFocusRef.current;
34
+ return () => {
35
+ // on unmount, return focus to that element
36
+ if (previousElement && !rootElement?.contains(document.activeElement)) {
37
+ previousElement.focus({ preventScroll: true });
19
38
  }
20
- });
21
- };
22
- }, [open]);
39
+ };
40
+ }
41
+ }, [open, rootEl]);
23
42
  }
@@ -1,37 +1,29 @@
1
1
  import { useEffect } from 'react';
2
2
 
3
+ let scrollBodyCount = 0;
3
4
  export function useRemoveBodyScroll(open: boolean) {
4
5
  useEffect(() => {
5
6
  if (open) {
6
- const locksCount = ((window as any).__SCROLL_BODY_COUNT__ || 0) + 1;
7
+ scrollBodyCount += 1;
7
8
 
8
9
  // calculate scrollbar width if mounting the first scroll lock
9
10
  let scrollBarWidth = 0;
10
- if (locksCount === 1) {
11
+ if (scrollBodyCount === 1) {
11
12
  scrollBarWidth = window.innerWidth - document.body.clientWidth;
12
13
  }
13
14
 
14
15
  document.body.style.overflow = 'hidden';
15
16
  if (scrollBarWidth > 0) {
16
- document.body.style.paddingRight = `${scrollBarWidth}px`;
17
+ document.body.style.marginRight = `${scrollBarWidth}px`;
17
18
  }
18
19
 
19
- // save current lock count in global object
20
- (window as any).__SCROLL_BODY_COUNT__ = locksCount;
21
- }
22
-
23
- return () => {
24
- if (open) {
25
- const locksCount = (window as any).__SCROLL_BODY_COUNT__ - 1;
26
-
27
- if (locksCount === 0) {
20
+ return () => {
21
+ scrollBodyCount -= 1;
22
+ if (scrollBodyCount === 0) {
28
23
  document.body.style.overflow = '';
29
- document.body.style.paddingRight = '';
24
+ document.body.style.marginRight = '';
30
25
  }
31
-
32
- // save current lock count in global object
33
- (window as any).__SCROLL_BODY_COUNT__ = locksCount;
34
- }
35
- };
26
+ };
27
+ }
36
28
  }, [open]);
37
29
  }
@@ -1,18 +0,0 @@
1
- import { useEffect, useState } from 'react';
2
-
3
- // Could use UUID but if we hit 9,007,199,254,740,991 unique components over
4
- // the lifetime of the app before it gets reloaded, I mean ... come on.
5
- // I don't even know what xillion that is.
6
- // /me googles
7
- // Oh duh, quadrillion. Nine quadrillion components. I think we're okay.
8
- let id = 0;
9
- const genId = () => `${++id}`;
10
-
11
- export function useId(): string | undefined;
12
- export function useId(preferredId: string): string;
13
- export function useId(preferredId: string | undefined): string | undefined;
14
- export function useId(preferredId?: string): string | undefined {
15
- const [id, setId] = useState<string | undefined>(preferredId);
16
- useEffect(() => setId(genId()), []);
17
- return id;
18
- }