@stack-spot/citric-react 0.1.0

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 (345) hide show
  1. package/dist/citric.css +2580 -0
  2. package/dist/components/Accordion.d.ts +33 -0
  3. package/dist/components/Accordion.d.ts.map +1 -0
  4. package/dist/components/Accordion.js +19 -0
  5. package/dist/components/Accordion.js.map +1 -0
  6. package/dist/components/Alert.d.ts +11 -0
  7. package/dist/components/Alert.d.ts.map +1 -0
  8. package/dist/components/Alert.js +5 -0
  9. package/dist/components/Alert.js.map +1 -0
  10. package/dist/components/AsyncContent.d.ts +30 -0
  11. package/dist/components/AsyncContent.d.ts.map +1 -0
  12. package/dist/components/AsyncContent.js +33 -0
  13. package/dist/components/AsyncContent.js.map +1 -0
  14. package/dist/components/Avatar.d.ts +22 -0
  15. package/dist/components/Avatar.d.ts.map +1 -0
  16. package/dist/components/Avatar.js +9 -0
  17. package/dist/components/Avatar.js.map +1 -0
  18. package/dist/components/AvatarGroup.d.ts +25 -0
  19. package/dist/components/AvatarGroup.d.ts.map +1 -0
  20. package/dist/components/AvatarGroup.js +9 -0
  21. package/dist/components/AvatarGroup.js.map +1 -0
  22. package/dist/components/Badge.d.ts +18 -0
  23. package/dist/components/Badge.d.ts.map +1 -0
  24. package/dist/components/Badge.js +7 -0
  25. package/dist/components/Badge.js.map +1 -0
  26. package/dist/components/Blockquote.d.ts +5 -0
  27. package/dist/components/Blockquote.d.ts.map +1 -0
  28. package/dist/components/Blockquote.js +4 -0
  29. package/dist/components/Blockquote.js.map +1 -0
  30. package/dist/components/Breadcrumb.d.ts +12 -0
  31. package/dist/components/Breadcrumb.d.ts.map +1 -0
  32. package/dist/components/Breadcrumb.js +8 -0
  33. package/dist/components/Breadcrumb.js.map +1 -0
  34. package/dist/components/Button.d.ts +42 -0
  35. package/dist/components/Button.d.ts.map +1 -0
  36. package/dist/components/Button.js +25 -0
  37. package/dist/components/Button.js.map +1 -0
  38. package/dist/components/Card.d.ts +19 -0
  39. package/dist/components/Card.d.ts.map +1 -0
  40. package/dist/components/Card.js +5 -0
  41. package/dist/components/Card.js.map +1 -0
  42. package/dist/components/Checkbox.d.ts +14 -0
  43. package/dist/components/Checkbox.d.ts.map +1 -0
  44. package/dist/components/Checkbox.js +7 -0
  45. package/dist/components/Checkbox.js.map +1 -0
  46. package/dist/components/CheckboxGroup.d.ts +53 -0
  47. package/dist/components/CheckboxGroup.d.ts.map +1 -0
  48. package/dist/components/CheckboxGroup.js +17 -0
  49. package/dist/components/CheckboxGroup.js.map +1 -0
  50. package/dist/components/Circle.d.ts +18 -0
  51. package/dist/components/Circle.d.ts.map +1 -0
  52. package/dist/components/Circle.js +5 -0
  53. package/dist/components/Circle.js.map +1 -0
  54. package/dist/components/CitricComponent.d.ts +14 -0
  55. package/dist/components/CitricComponent.d.ts.map +1 -0
  56. package/dist/components/CitricComponent.js +15 -0
  57. package/dist/components/CitricComponent.js.map +1 -0
  58. package/dist/components/Divider.d.ts +14 -0
  59. package/dist/components/Divider.d.ts.map +1 -0
  60. package/dist/components/Divider.js +5 -0
  61. package/dist/components/Divider.js.map +1 -0
  62. package/dist/components/ErrorBoundary.d.ts +32 -0
  63. package/dist/components/ErrorBoundary.d.ts.map +1 -0
  64. package/dist/components/ErrorBoundary.js +46 -0
  65. package/dist/components/ErrorBoundary.js.map +1 -0
  66. package/dist/components/ErrorMessage.d.ts +4 -0
  67. package/dist/components/ErrorMessage.d.ts.map +1 -0
  68. package/dist/components/ErrorMessage.js +7 -0
  69. package/dist/components/ErrorMessage.js.map +1 -0
  70. package/dist/components/FallbackBoundary.d.ts +13 -0
  71. package/dist/components/FallbackBoundary.d.ts.map +1 -0
  72. package/dist/components/FallbackBoundary.js +11 -0
  73. package/dist/components/FallbackBoundary.js.map +1 -0
  74. package/dist/components/Favorite.d.ts +23 -0
  75. package/dist/components/Favorite.d.ts.map +1 -0
  76. package/dist/components/Favorite.js +5 -0
  77. package/dist/components/Favorite.js.map +1 -0
  78. package/dist/components/FieldGroup.d.ts +14 -0
  79. package/dist/components/FieldGroup.d.ts.map +1 -0
  80. package/dist/components/FieldGroup.js +5 -0
  81. package/dist/components/FieldGroup.js.map +1 -0
  82. package/dist/components/Form.d.ts +5 -0
  83. package/dist/components/Form.d.ts.map +1 -0
  84. package/dist/components/Form.js +6 -0
  85. package/dist/components/Form.js.map +1 -0
  86. package/dist/components/FormGroup.d.ts +22 -0
  87. package/dist/components/FormGroup.d.ts.map +1 -0
  88. package/dist/components/FormGroup.js +8 -0
  89. package/dist/components/FormGroup.js.map +1 -0
  90. package/dist/components/IconBox.d.ts +46 -0
  91. package/dist/components/IconBox.d.ts.map +1 -0
  92. package/dist/components/IconBox.js +29 -0
  93. package/dist/components/IconBox.js.map +1 -0
  94. package/dist/components/Input.d.ts +15 -0
  95. package/dist/components/Input.d.ts.map +1 -0
  96. package/dist/components/Input.js +18 -0
  97. package/dist/components/Input.js.map +1 -0
  98. package/dist/components/Link.d.ts +20 -0
  99. package/dist/components/Link.d.ts.map +1 -0
  100. package/dist/components/Link.js +21 -0
  101. package/dist/components/Link.js.map +1 -0
  102. package/dist/components/LoadingPanel.d.ts +2 -0
  103. package/dist/components/LoadingPanel.d.ts.map +1 -0
  104. package/dist/components/LoadingPanel.js +5 -0
  105. package/dist/components/LoadingPanel.js.map +1 -0
  106. package/dist/components/MenuOverlay/Menu.d.ts +6 -0
  107. package/dist/components/MenuOverlay/Menu.d.ts.map +1 -0
  108. package/dist/components/MenuOverlay/Menu.js +100 -0
  109. package/dist/components/MenuOverlay/Menu.js.map +1 -0
  110. package/dist/components/MenuOverlay/context.d.ts +6 -0
  111. package/dist/components/MenuOverlay/context.d.ts.map +1 -0
  112. package/dist/components/MenuOverlay/context.js +16 -0
  113. package/dist/components/MenuOverlay/context.js.map +1 -0
  114. package/dist/components/MenuOverlay/index.d.ts +3 -0
  115. package/dist/components/MenuOverlay/index.d.ts.map +1 -0
  116. package/dist/components/MenuOverlay/index.js +23 -0
  117. package/dist/components/MenuOverlay/index.js.map +1 -0
  118. package/dist/components/MenuOverlay/keyboard.d.ts +2 -0
  119. package/dist/components/MenuOverlay/keyboard.d.ts.map +1 -0
  120. package/dist/components/MenuOverlay/keyboard.js +66 -0
  121. package/dist/components/MenuOverlay/keyboard.js.map +1 -0
  122. package/dist/components/MenuOverlay/types.d.ts +166 -0
  123. package/dist/components/MenuOverlay/types.d.ts.map +1 -0
  124. package/dist/components/MenuOverlay/types.js +2 -0
  125. package/dist/components/MenuOverlay/types.js.map +1 -0
  126. package/dist/components/Overlay/context.d.ts +4 -0
  127. package/dist/components/Overlay/context.d.ts.map +1 -0
  128. package/dist/components/Overlay/context.js +7 -0
  129. package/dist/components/Overlay/context.js.map +1 -0
  130. package/dist/components/Overlay/index.d.ts +14 -0
  131. package/dist/components/Overlay/index.d.ts.map +1 -0
  132. package/dist/components/Overlay/index.js +120 -0
  133. package/dist/components/Overlay/index.js.map +1 -0
  134. package/dist/components/Overlay/types.d.ts +67 -0
  135. package/dist/components/Overlay/types.d.ts.map +1 -0
  136. package/dist/components/Overlay/types.js +2 -0
  137. package/dist/components/Overlay/types.js.map +1 -0
  138. package/dist/components/Pagination.d.ts +28 -0
  139. package/dist/components/Pagination.d.ts.map +1 -0
  140. package/dist/components/Pagination.js +30 -0
  141. package/dist/components/Pagination.js.map +1 -0
  142. package/dist/components/ProgressBar.d.ts +12 -0
  143. package/dist/components/ProgressBar.d.ts.map +1 -0
  144. package/dist/components/ProgressBar.js +7 -0
  145. package/dist/components/ProgressBar.js.map +1 -0
  146. package/dist/components/ProgressCircular.d.ts +16 -0
  147. package/dist/components/ProgressCircular.d.ts.map +1 -0
  148. package/dist/components/ProgressCircular.js +7 -0
  149. package/dist/components/ProgressCircular.js.map +1 -0
  150. package/dist/components/RadioGroup.d.ts +48 -0
  151. package/dist/components/RadioGroup.d.ts.map +1 -0
  152. package/dist/components/RadioGroup.js +17 -0
  153. package/dist/components/RadioGroup.js.map +1 -0
  154. package/dist/components/Rating.d.ts +13 -0
  155. package/dist/components/Rating.d.ts.map +1 -0
  156. package/dist/components/Rating.js +4 -0
  157. package/dist/components/Rating.js.map +1 -0
  158. package/dist/components/Select/RichSelect.d.ts +5 -0
  159. package/dist/components/Select/RichSelect.d.ts.map +1 -0
  160. package/dist/components/Select/RichSelect.js +152 -0
  161. package/dist/components/Select/RichSelect.js.map +1 -0
  162. package/dist/components/Select/SimpleSelect.d.ts +5 -0
  163. package/dist/components/Select/SimpleSelect.d.ts.map +1 -0
  164. package/dist/components/Select/SimpleSelect.js +24 -0
  165. package/dist/components/Select/SimpleSelect.js.map +1 -0
  166. package/dist/components/Select/index.d.ts +4 -0
  167. package/dist/components/Select/index.d.ts.map +1 -0
  168. package/dist/components/Select/index.js +7 -0
  169. package/dist/components/Select/index.js.map +1 -0
  170. package/dist/components/Select/types.d.ts +118 -0
  171. package/dist/components/Select/types.d.ts.map +1 -0
  172. package/dist/components/Select/types.js +2 -0
  173. package/dist/components/Select/types.js.map +1 -0
  174. package/dist/components/SelectBox.d.ts +65 -0
  175. package/dist/components/SelectBox.d.ts.map +1 -0
  176. package/dist/components/SelectBox.js +26 -0
  177. package/dist/components/SelectBox.js.map +1 -0
  178. package/dist/components/Skeleton.d.ts +30 -0
  179. package/dist/components/Skeleton.d.ts.map +1 -0
  180. package/dist/components/Skeleton.js +5 -0
  181. package/dist/components/Skeleton.js.map +1 -0
  182. package/dist/components/Slider.d.ts +32 -0
  183. package/dist/components/Slider.d.ts.map +1 -0
  184. package/dist/components/Slider.js +19 -0
  185. package/dist/components/Slider.js.map +1 -0
  186. package/dist/components/SmartTable.d.ts +87 -0
  187. package/dist/components/SmartTable.d.ts.map +1 -0
  188. package/dist/components/SmartTable.js +16 -0
  189. package/dist/components/SmartTable.js.map +1 -0
  190. package/dist/components/Stepper.d.ts +52 -0
  191. package/dist/components/Stepper.d.ts.map +1 -0
  192. package/dist/components/Stepper.js +53 -0
  193. package/dist/components/Stepper.js.map +1 -0
  194. package/dist/components/Switch.d.ts +10 -0
  195. package/dist/components/Switch.d.ts.map +1 -0
  196. package/dist/components/Switch.js +7 -0
  197. package/dist/components/Switch.js.map +1 -0
  198. package/dist/components/Table.d.ts +106 -0
  199. package/dist/components/Table.d.ts.map +1 -0
  200. package/dist/components/Table.js +86 -0
  201. package/dist/components/Table.js.map +1 -0
  202. package/dist/components/Tabs/TabController.d.ts +11 -0
  203. package/dist/components/Tabs/TabController.d.ts.map +1 -0
  204. package/dist/components/Tabs/TabController.js +39 -0
  205. package/dist/components/Tabs/TabController.js.map +1 -0
  206. package/dist/components/Tabs/index.d.ts +5 -0
  207. package/dist/components/Tabs/index.d.ts.map +1 -0
  208. package/dist/components/Tabs/index.js +37 -0
  209. package/dist/components/Tabs/index.js.map +1 -0
  210. package/dist/components/Tabs/types.d.ts +46 -0
  211. package/dist/components/Tabs/types.d.ts.map +1 -0
  212. package/dist/components/Tabs/types.js +2 -0
  213. package/dist/components/Tabs/types.js.map +1 -0
  214. package/dist/components/Tabs/utils.d.ts +3 -0
  215. package/dist/components/Tabs/utils.d.ts.map +1 -0
  216. package/dist/components/Tabs/utils.js +5 -0
  217. package/dist/components/Tabs/utils.js.map +1 -0
  218. package/dist/components/Text.d.ts +27 -0
  219. package/dist/components/Text.d.ts.map +1 -0
  220. package/dist/components/Text.js +45 -0
  221. package/dist/components/Text.js.map +1 -0
  222. package/dist/components/Textarea.d.ts +8 -0
  223. package/dist/components/Textarea.d.ts.map +1 -0
  224. package/dist/components/Textarea.js +4 -0
  225. package/dist/components/Textarea.js.map +1 -0
  226. package/dist/components/Tooltip.d.ts +25 -0
  227. package/dist/components/Tooltip.d.ts.map +1 -0
  228. package/dist/components/Tooltip.js +18 -0
  229. package/dist/components/Tooltip.js.map +1 -0
  230. package/dist/components/layout.d.ts +46 -0
  231. package/dist/components/layout.d.ts.map +1 -0
  232. package/dist/components/layout.js +18 -0
  233. package/dist/components/layout.js.map +1 -0
  234. package/dist/context/CitricContext.d.ts +3 -0
  235. package/dist/context/CitricContext.d.ts.map +1 -0
  236. package/dist/context/CitricContext.js +3 -0
  237. package/dist/context/CitricContext.js.map +1 -0
  238. package/dist/context/CitricProvider.d.ts +9 -0
  239. package/dist/context/CitricProvider.d.ts.map +1 -0
  240. package/dist/context/CitricProvider.js +8 -0
  241. package/dist/context/CitricProvider.js.map +1 -0
  242. package/dist/context/hooks.d.ts +2 -0
  243. package/dist/context/hooks.d.ts.map +1 -0
  244. package/dist/context/hooks.js +6 -0
  245. package/dist/context/hooks.js.map +1 -0
  246. package/dist/index.d.ts +48 -0
  247. package/dist/index.d.ts.map +1 -0
  248. package/dist/index.js +48 -0
  249. package/dist/index.js.map +1 -0
  250. package/dist/overlay.d.ts +83 -0
  251. package/dist/overlay.d.ts.map +1 -0
  252. package/dist/overlay.js +199 -0
  253. package/dist/overlay.js.map +1 -0
  254. package/dist/theme.css +419 -0
  255. package/dist/types.d.ts +175 -0
  256. package/dist/types.d.ts.map +1 -0
  257. package/dist/types.js +2 -0
  258. package/dist/types.js.map +1 -0
  259. package/dist/utils/ValueController.d.ts +10 -0
  260. package/dist/utils/ValueController.d.ts.map +1 -0
  261. package/dist/utils/ValueController.js +32 -0
  262. package/dist/utils/ValueController.js.map +1 -0
  263. package/dist/utils/acessibility.d.ts +52 -0
  264. package/dist/utils/acessibility.d.ts.map +1 -0
  265. package/dist/utils/acessibility.js +80 -0
  266. package/dist/utils/acessibility.js.map +1 -0
  267. package/dist/utils/css.d.ts +12 -0
  268. package/dist/utils/css.d.ts.map +1 -0
  269. package/dist/utils/css.js +72 -0
  270. package/dist/utils/css.js.map +1 -0
  271. package/dist/utils/options.d.ts +3 -0
  272. package/dist/utils/options.d.ts.map +1 -0
  273. package/dist/utils/options.js +7 -0
  274. package/dist/utils/options.js.map +1 -0
  275. package/package.json +51 -0
  276. package/scripts/build-css.ts +49 -0
  277. package/src/components/Accordion.tsx +74 -0
  278. package/src/components/Alert.tsx +16 -0
  279. package/src/components/AsyncContent.tsx +54 -0
  280. package/src/components/Avatar.tsx +34 -0
  281. package/src/components/AvatarGroup.tsx +40 -0
  282. package/src/components/Badge.tsx +28 -0
  283. package/src/components/Blockquote.tsx +9 -0
  284. package/src/components/Breadcrumb.tsx +24 -0
  285. package/src/components/Button.tsx +88 -0
  286. package/src/components/Card.tsx +32 -0
  287. package/src/components/Checkbox.tsx +36 -0
  288. package/src/components/CheckboxGroup.tsx +93 -0
  289. package/src/components/Circle.tsx +26 -0
  290. package/src/components/CitricComponent.ts +34 -0
  291. package/src/components/Divider.tsx +22 -0
  292. package/src/components/ErrorBoundary.tsx +62 -0
  293. package/src/components/ErrorMessage.tsx +11 -0
  294. package/src/components/FallbackBoundary.tsx +29 -0
  295. package/src/components/Favorite.tsx +37 -0
  296. package/src/components/FieldGroup.tsx +22 -0
  297. package/src/components/Form.tsx +17 -0
  298. package/src/components/FormGroup.tsx +45 -0
  299. package/src/components/IconBox.tsx +78 -0
  300. package/src/components/Input.tsx +32 -0
  301. package/src/components/Link.tsx +40 -0
  302. package/src/components/LoadingPanel.tsx +8 -0
  303. package/src/components/MenuOverlay/Menu.tsx +157 -0
  304. package/src/components/MenuOverlay/context.ts +20 -0
  305. package/src/components/MenuOverlay/index.tsx +35 -0
  306. package/src/components/MenuOverlay/keyboard.ts +60 -0
  307. package/src/components/MenuOverlay/types.ts +178 -0
  308. package/src/components/Overlay/context.ts +10 -0
  309. package/src/components/Overlay/index.tsx +137 -0
  310. package/src/components/Overlay/types.ts +71 -0
  311. package/src/components/Pagination.tsx +90 -0
  312. package/src/components/ProgressBar.tsx +25 -0
  313. package/src/components/ProgressCircular.tsx +29 -0
  314. package/src/components/RadioGroup.tsx +87 -0
  315. package/src/components/Rating.tsx +25 -0
  316. package/src/components/Select/RichSelect.tsx +214 -0
  317. package/src/components/Select/SimpleSelect.tsx +66 -0
  318. package/src/components/Select/index.tsx +8 -0
  319. package/src/components/Select/types.ts +121 -0
  320. package/src/components/SelectBox.tsx +134 -0
  321. package/src/components/Skeleton.tsx +41 -0
  322. package/src/components/Slider.tsx +77 -0
  323. package/src/components/SmartTable.tsx +148 -0
  324. package/src/components/Stepper.tsx +142 -0
  325. package/src/components/Switch.tsx +29 -0
  326. package/src/components/Table.tsx +219 -0
  327. package/src/components/Tabs/TabController.ts +40 -0
  328. package/src/components/Tabs/index.tsx +64 -0
  329. package/src/components/Tabs/types.ts +48 -0
  330. package/src/components/Tabs/utils.ts +6 -0
  331. package/src/components/Text.ts +75 -0
  332. package/src/components/Textarea.tsx +12 -0
  333. package/src/components/Tooltip.tsx +53 -0
  334. package/src/components/layout.tsx +53 -0
  335. package/src/context/CitricContext.tsx +4 -0
  336. package/src/context/CitricProvider.tsx +14 -0
  337. package/src/context/hooks.ts +6 -0
  338. package/src/index.ts +47 -0
  339. package/src/overlay.ts +276 -0
  340. package/src/types.ts +226 -0
  341. package/src/utils/ValueController.ts +28 -0
  342. package/src/utils/acessibility.ts +92 -0
  343. package/src/utils/css.ts +106 -0
  344. package/src/utils/options.ts +7 -0
  345. package/tsconfig.json +10 -0
@@ -0,0 +1,100 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { listToClass } from '@stack-spot/portal-theme';
3
+ import { useTranslate } from '@stack-spot/portal-translate';
4
+ import { createElement, useEffect, useMemo } from 'react';
5
+ import { ValueController } from '../../utils/ValueController.js';
6
+ import { CitricComponent } from '../CitricComponent.js';
7
+ import { IconButton } from '../IconBox.js';
8
+ import { useOverlayController } from '../Overlay/context.js';
9
+ import { MenuProvider, useMenuController, useMenuState } from './context.js';
10
+ import { keyboardNavigation } from './keyboard.js';
11
+ // Arbitrary time (ms) to wait before running a function that needs the view to be updated with the next state value.
12
+ const RENDER_DELAY = 20;
13
+ function Submenu({ children, label, className, icon, iconRight }) {
14
+ const controller = useMenuController();
15
+ return (_jsxs("button", { className: listToClass([className, 'submenu']), onClick: (e) => {
16
+ e.stopPropagation();
17
+ const menu = e.target instanceof HTMLElement ? e.target.closest('[data-citric="menu"]') : undefined;
18
+ controller?.setValue({ items: children, label, parent: controller?.getValue() });
19
+ const isOpenedWithMouse = e.detail > 0;
20
+ if (!isOpenedWithMouse) {
21
+ setTimeout(() => {
22
+ const firstFocusable = menu?.querySelector('a, button');
23
+ if (firstFocusable instanceof HTMLElement)
24
+ firstFocusable.focus();
25
+ }, RENDER_DELAY);
26
+ }
27
+ }, children: [icon, _jsx("span", { children: label }), iconRight] }));
28
+ }
29
+ function MenuSection({ children, label, className }) {
30
+ return (_jsxs("section", { className: className, children: [label && _jsx("h6", { children: label }), _jsx("nav", { children: _jsx(MenuItems, { items: children }) }), !label && _jsx("hr", {})] }));
31
+ }
32
+ function MenuAction({ label, active, href, icon, iconRight, className, onClick, ...props }) {
33
+ const overlayController = useOverlayController();
34
+ const children = _jsxs(_Fragment, { children: [icon, typeof label === 'string' ? _jsx("span", { children: label }) : label.element, iconRight] });
35
+ return createElement(href ? 'a' : 'button', {
36
+ href,
37
+ 'aria-label': typeof label === 'string' ? label : label.id,
38
+ className: listToClass([className, active && 'active']),
39
+ onClick: (e) => {
40
+ overlayController?.close();
41
+ onClick?.(e);
42
+ },
43
+ ...props,
44
+ }, children);
45
+ }
46
+ function hasSections(items) {
47
+ return items.some(i => 'children' in i && i.children.length && i.type === 'section');
48
+ }
49
+ function hasSubmenus(items) {
50
+ return items.some(i => 'children' in i && i.children.length && i.type === 'collapsible');
51
+ }
52
+ function MenuItems({ items }) {
53
+ return useMemo(() => items.map((item, index) => {
54
+ if ('children' in item && item.type === 'section')
55
+ return _jsx(MenuSection, { ...item }, item.label || index);
56
+ if ('children' in item && item.type === 'collapsible')
57
+ return _jsx(Submenu, { ...item }, item.label || index);
58
+ return _jsx(MenuAction, { ...item }, (typeof item.label === 'string' ? item.label : item.label?.id) || index);
59
+ }), [items]);
60
+ }
61
+ /**
62
+ * TODO: make the height changes animated.
63
+ */
64
+ export function Menu({ items, appearance, bgLevel, header, roundedItems, showBorders, showShadows, spaced, className, onKeyDown, ...props }) {
65
+ const controller = useMemo(() => new ValueController({ items }), []);
66
+ const current = useMenuState(controller);
67
+ const { sectioned, collapsible } = useMemo(() => ({ sectioned: hasSections(current.items), collapsible: hasSubmenus(current.items) }), [current.items]);
68
+ const tag = header || sectioned || collapsible ? 'div' : 'nav';
69
+ const t = useTranslate(dictionary);
70
+ useEffect(() => {
71
+ if (items !== controller.getValue().items)
72
+ controller.setValue({ items });
73
+ }, [items]);
74
+ return (_jsx(MenuProvider, { value: controller, children: _jsxs(CitricComponent, { tag: tag, component: "menu", className: listToClass([
75
+ className, appearance, roundedItems && 'rounded-items', showBorders && 'bordered', showShadows === false && 'no-shadow',
76
+ spaced && 'spaced', bgLevel && `bg-${bgLevel}`,
77
+ ]), onKeyDown: (e) => {
78
+ keyboardNavigation(e);
79
+ onKeyDown?.(e);
80
+ }, ...props, children: [header && _jsx("header", { children: header }), current.parent && (_jsxs("div", { className: "back-button", children: [_jsx(IconButton, { icon: "ArrowLeft", "aria-label": t.goBack, onClick: (e) => {
81
+ e.stopPropagation();
82
+ const menu = e.target instanceof HTMLElement ? e.target.closest('[data-citric="menu"]') : undefined;
83
+ if (current.parent)
84
+ controller.setValue(current.parent);
85
+ setTimeout(() => {
86
+ const lastItem = Array.from(menu?.querySelectorAll('a, button') ?? []).find(el => el.textContent === current.label);
87
+ if (lastItem instanceof HTMLElement)
88
+ lastItem.focus();
89
+ }, RENDER_DELAY);
90
+ } }), _jsx("span", { children: current.label || t.goBack })] })), sectioned ? _jsx(MenuItems, { items: current.items }) : _jsx("nav", { children: _jsx(MenuItems, { items: current.items }) })] }) }));
91
+ }
92
+ const dictionary = {
93
+ en: {
94
+ goBack: 'Go back',
95
+ },
96
+ pt: {
97
+ goBack: 'Voltar',
98
+ },
99
+ };
100
+ //# sourceMappingURL=Menu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Menu.js","sourceRoot":"","sources":["../../../src/components/MenuOverlay/Menu.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { ValueController } from '../../utils/ValueController.js';
2
+ import { MenuState } from './types.js';
3
+ export declare const MenuProvider: import("react").Provider<ValueController<MenuState> | undefined>;
4
+ export declare function useMenuController(): ValueController<MenuState> | undefined;
5
+ export declare function useMenuState(controller?: ValueController<MenuState>): MenuState;
6
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/components/MenuOverlay/context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAInC,eAAO,MAAM,YAAY,kEAAmB,CAAA;AAE5C,wBAAgB,iBAAiB,2CAEhC;AAED,wBAAgB,YAAY,CAAC,UAAU,CAAC,EAAE,eAAe,CAAC,SAAS,CAAC,aAOnE"}
@@ -0,0 +1,16 @@
1
+ import { createContext, useContext, useEffect, useState } from 'react';
2
+ const context = createContext(undefined);
3
+ export const MenuProvider = context.Provider;
4
+ export function useMenuController() {
5
+ return useContext(context);
6
+ }
7
+ export function useMenuState(controller) {
8
+ const controllerFromContext = useMenuController();
9
+ controller ??= controllerFromContext;
10
+ if (!controller)
11
+ throw new Error('useMenuState used outside the context of a Menu');
12
+ const [state, setState] = useState(controller.getValue());
13
+ useEffect(() => controller.onChange(setState));
14
+ return state;
15
+ }
16
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/components/MenuOverlay/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAItE,MAAM,OAAO,GAAG,aAAa,CAAyC,SAAS,CAAC,CAAA;AAEhF,MAAM,CAAC,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAA;AAE5C,MAAM,UAAU,iBAAiB;IAC/B,OAAO,UAAU,CAAC,OAAO,CAAC,CAAA;AAC5B,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,UAAuC;IAClE,MAAM,qBAAqB,GAAG,iBAAiB,EAAE,CAAA;IACjD,UAAU,KAAK,qBAAqB,CAAA;IACpC,IAAI,CAAC,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAA;IACnF,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAA;IACzD,SAAS,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC9C,OAAO,KAAK,CAAA;AACd,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { MenuOverlayProps } from './types.js';
2
+ export declare const MenuOverlay: ({ id, items, appearance, bgLevel, header, roundedItems, showBorders, showShadows, spaced, menuClass, menuStyle, children, ...props }: MenuOverlayProps) => import("react/jsx-runtime").JSX.Element;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/MenuOverlay/index.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE1C,eAAO,MAAM,WAAW,GAAI,sIAEzB,gBAAgB,4CAgBlB,CAAA"}
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useTranslate } from '@stack-spot/portal-translate';
3
+ import { useMemo } from 'react';
4
+ import { IconButton } from '../IconBox.js';
5
+ import { Overlay } from '../Overlay/index.js';
6
+ import { Menu } from './Menu.js';
7
+ export const MenuOverlay = ({ id, items, appearance, bgLevel, header, roundedItems, showBorders, showShadows, spaced, menuClass, menuStyle, children, ...props }) => {
8
+ const t = useTranslate(dictionary);
9
+ const randomId = useMemo(() => `${Math.random()}`, []);
10
+ const menuProps = {
11
+ items, appearance, bgLevel, roundedItems, showBorders, showShadows, spaced, header, className: menuClass, style: menuStyle,
12
+ };
13
+ return (_jsx(Overlay, { content: _jsx(Menu, { ...menuProps }), attributes: { id: id || randomId, style: { margin: '8px' } }, triggerOn: "click", ...props, children: children ?? _jsx(IconButton, { icon: "EllipsisVertical", "aria-label": t.open }) }));
14
+ };
15
+ const dictionary = {
16
+ en: {
17
+ open: 'Open menu',
18
+ },
19
+ pt: {
20
+ open: 'Abrir menu',
21
+ },
22
+ };
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/MenuOverlay/index.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAc,YAAY,EAAE,MAAM,8BAA8B,CAAA;AACvE,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAG7B,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,EAC1B,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAC/G,EAAE,EAAE;IACrB,MAAM,CAAC,GAAG,YAAY,CAAC,UAAU,CAAC,CAAA;IAClC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;IACtD,MAAM,SAAS,GAAG;QAChB,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS;KAC3H,CAAA;IACD,OAAO,CACL,KAAC,OAAO,IACN,OAAO,EAAE,KAAC,IAAI,OAAK,SAAS,GAAI,EAChC,UAAU,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,QAAQ,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAC5D,SAAS,EAAC,OAAO,KACb,KAAK,YAER,QAAQ,IAAI,KAAC,UAAU,IAAC,IAAI,EAAC,kBAAkB,gBAAa,CAAC,CAAC,IAAI,GAAI,GAC/D,CACX,CAAA;AACH,CAAC,CAAA;AAED,MAAM,UAAU,GAAG;IACjB,EAAE,EAAE;QACF,IAAI,EAAE,WAAW;KAClB;IACD,EAAE,EAAE;QACF,IAAI,EAAE,YAAY;KACnB;CACmB,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare function keyboardNavigation(event: React.KeyboardEvent): void;
2
+ //# sourceMappingURL=keyboard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyboard.d.ts","sourceRoot":"","sources":["../../../src/components/MenuOverlay/keyboard.ts"],"names":[],"mappings":"AA8CA,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,aAAa,QAa5D"}
@@ -0,0 +1,66 @@
1
+ // TODO: scroll the element into view when it's focused. Very important for accessibility in scrollable menus.
2
+ function getCurrent(element) {
3
+ return element instanceof HTMLElement
4
+ ? element.querySelector('button:focus, a:focus')
5
+ : null;
6
+ }
7
+ function getMenuItems(element) {
8
+ return element instanceof HTMLElement ? element.querySelectorAll('button, a') : undefined;
9
+ }
10
+ function focusFirst(element) {
11
+ const first = getMenuItems(element)?.[0];
12
+ if (first instanceof HTMLElement)
13
+ first.focus();
14
+ }
15
+ function focusLast(element) {
16
+ const all = getMenuItems(element);
17
+ const last = all?.[all.length];
18
+ if (last instanceof HTMLElement)
19
+ last.focus();
20
+ }
21
+ function indexOf(elements, element) {
22
+ for (let i = 0; i < elements.length; i++) {
23
+ if (elements[i] === element)
24
+ return i;
25
+ }
26
+ return -1;
27
+ }
28
+ function focusPrevious(element, current) {
29
+ const all = getMenuItems(element);
30
+ const index = all ? indexOf(all, current) : -1;
31
+ if (!all || index === -1)
32
+ return;
33
+ const prev = index === 0 ? all[all.length - 1] : all[index - 1];
34
+ if (prev instanceof HTMLElement)
35
+ prev.focus();
36
+ }
37
+ function focusNext(element, current) {
38
+ const all = getMenuItems(element);
39
+ const index = all ? indexOf(all, current) : -1;
40
+ if (!all || index === -1)
41
+ return;
42
+ const next = index >= all.length - 1 ? all[0] : all[index + 1];
43
+ if (next instanceof HTMLElement)
44
+ next.focus();
45
+ }
46
+ export function keyboardNavigation(event) {
47
+ if (!['ArrowUp', 'ArrowDown'].includes(event.key))
48
+ return;
49
+ event.stopPropagation();
50
+ event.preventDefault();
51
+ const menu = event.target instanceof HTMLElement ? event.target.closest('[data-citric="menu"]') : undefined;
52
+ const current = getCurrent(menu);
53
+ if (event.key === 'ArrowUp') {
54
+ if (current)
55
+ focusPrevious(menu, current);
56
+ else
57
+ focusLast(menu);
58
+ }
59
+ else {
60
+ if (current)
61
+ focusNext(menu, current);
62
+ else
63
+ focusFirst(menu);
64
+ }
65
+ }
66
+ //# sourceMappingURL=keyboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyboard.js","sourceRoot":"","sources":["../../../src/components/MenuOverlay/keyboard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,166 @@
1
+ import { HTMLExtension } from '../../types.js';
2
+ import { BaseOverlayProps } from '../Overlay/types.js';
3
+ interface CustomLabel {
4
+ /**
5
+ * A unique identifier for this label. This is also used to read this label to screen readers.
6
+ */
7
+ id: string;
8
+ /**
9
+ * A custom label that can be made up of any React component.
10
+ */
11
+ element: React.ReactNode;
12
+ }
13
+ interface Action {
14
+ /**
15
+ * The label of the action.
16
+ */
17
+ label: string | CustomLabel;
18
+ /**
19
+ * Function to run on a click.
20
+ */
21
+ onClick?: (event?: React.MouseEvent) => void;
22
+ /**
23
+ * URL to open on a click.
24
+ */
25
+ href?: string;
26
+ /**
27
+ * Target of the URL to open.
28
+ */
29
+ target?: React.AnchorHTMLAttributes<HTMLAnchorElement>['target'];
30
+ /**
31
+ * Language of the linked document.
32
+ */
33
+ lang?: React.AnchorHTMLAttributes<HTMLAnchorElement>['lang'];
34
+ /**
35
+ * Language of the destination URL.
36
+ */
37
+ hrefLang?: React.AnchorHTMLAttributes<HTMLAnchorElement>['hrefLang'];
38
+ /**
39
+ * The title of the action.
40
+ */
41
+ title?: string;
42
+ /**
43
+ * Whether or not this link/button is disabled.
44
+ *
45
+ * @default false
46
+ */
47
+ disabled?: boolean;
48
+ }
49
+ interface ItemWithIcon {
50
+ /**
51
+ * An Icon to appear at the left of the item.
52
+ */
53
+ icon?: React.ReactElement;
54
+ /**
55
+ * An Icon to appear at the right of the item.
56
+ */
57
+ iconRight?: React.ReactElement;
58
+ }
59
+ export interface ListAction extends ItemWithIcon, Action {
60
+ /**
61
+ * Whether or not this option is currently active.
62
+ */
63
+ active?: boolean;
64
+ /**
65
+ * A class to be added to this item.
66
+ */
67
+ className?: string;
68
+ }
69
+ interface ListGroup {
70
+ /**
71
+ * If this group is rendered as a section with its items right below it or a collapsible, which requires a click to open a submenu.
72
+ */
73
+ type?: 'section' | 'collapsible';
74
+ /**
75
+ * The items of this group.
76
+ */
77
+ children: ListItem[];
78
+ /**
79
+ * A class to be added to this item.
80
+ */
81
+ className?: string;
82
+ }
83
+ export interface ListSection extends ListGroup {
84
+ type: 'section';
85
+ /**
86
+ * The section's title.
87
+ */
88
+ label?: string;
89
+ }
90
+ export interface ListCollapsible extends ListGroup, ItemWithIcon {
91
+ type?: 'collapsible';
92
+ /**
93
+ * The title of the collapsible menu.
94
+ */
95
+ label: string;
96
+ }
97
+ export type ListItem = ListSection | ListCollapsible | ListAction;
98
+ export interface MenuState {
99
+ items: ListItem[];
100
+ parent?: MenuState;
101
+ label?: string;
102
+ }
103
+ export interface BaseMenuProps {
104
+ /**
105
+ * The options in the selection list.
106
+ */
107
+ items: ListItem[];
108
+ /**
109
+ * A header for the menu.
110
+ */
111
+ header?: React.ReactNode;
112
+ /**
113
+ * Whether or not to render spaces between the items and the sides of the menu.
114
+ *
115
+ * @default false
116
+ */
117
+ spaced?: boolean;
118
+ /**
119
+ * Wheter or not to render borders.
120
+ *
121
+ * @default false
122
+ */
123
+ showBorders?: boolean;
124
+ /**
125
+ * Whether or not to use rounded corners for each menu item.
126
+ *
127
+ * @default false
128
+ */
129
+ roundedItems?: boolean;
130
+ /**
131
+ * Use 'square' for sharp corners and 'circle' for rounded corners.
132
+ *
133
+ * @default 'circle'
134
+ */
135
+ appearance?: 'square' | 'circle';
136
+ /**
137
+ * The level of the background color. Use this to lighten or darken the background.
138
+ *
139
+ * @default 300
140
+ */
141
+ bgLevel?: 300 | 400 | 500 | 600;
142
+ /**
143
+ * Whether or not to render shadows behind the menu.
144
+ *
145
+ * @default true
146
+ */
147
+ showShadows?: boolean;
148
+ /**
149
+ * A class for the menu element.
150
+ */
151
+ menuClass?: string;
152
+ /**
153
+ * Styles for the menu element.
154
+ */
155
+ menuStyle?: React.CSSProperties;
156
+ }
157
+ export type MenuProps = HTMLExtension<'div', BaseMenuProps, 'children'>;
158
+ export interface BaseMenuOverlayProps extends BaseMenuProps, Omit<BaseOverlayProps<'div'>, 'tag' | 'onRenderChild' | 'content' | 'triggerOn' | 'reference'> {
159
+ /**
160
+ * A unique id for this menu. If not provided, a random number will be used.
161
+ */
162
+ id?: string;
163
+ }
164
+ export type MenuOverlayProps = HTMLExtension<'div', BaseMenuOverlayProps>;
165
+ export {};
166
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/MenuOverlay/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/components/MenuOverlay/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import { OverlayController } from './types.js';
2
+ export declare const OverlayProvider: import("react").Provider<OverlayController | undefined>;
3
+ export declare function useOverlayController(): OverlayController | undefined;
4
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/components/Overlay/context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAI3C,eAAO,MAAM,eAAe,yDAAmB,CAAA;AAE/C,wBAAgB,oBAAoB,kCAEnC"}
@@ -0,0 +1,7 @@
1
+ import { createContext, useContext } from 'react';
2
+ const context = createContext(undefined);
3
+ export const OverlayProvider = context.Provider;
4
+ export function useOverlayController() {
5
+ return useContext(context);
6
+ }
7
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/components/Overlay/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAGjD,MAAM,OAAO,GAAG,aAAa,CAAgC,SAAS,CAAC,CAAA;AAEvE,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAA;AAE/C,MAAM,UAAU,oBAAoB;IAClC,OAAO,UAAU,CAAC,OAAO,CAAC,CAAA;AAC5B,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { OverlayProps } from './types.js';
2
+ /**
3
+ * These todos are in order of priority.
4
+ *
5
+ * TODO: update position when the size changes. Currently, the top position seems out of place whenever the height changes. The same is
6
+ * probably true for the left position if the width changes.
7
+ * TODO: hoverDelayMS
8
+ * TODO: reposition the overlay when it's under a scrollable element other then the body and this element is scrolled.
9
+ * TODO: close the overlay when it's under a scrollable element other then the body and the element that triggered the tooltip becomes
10
+ * hidden by the scroll.
11
+ * TODO: use React Portal to implement overlays. The current implementation will lose every React context in the tree.
12
+ */
13
+ export declare function Overlay<T extends keyof React.JSX.IntrinsicElements>({ tag, children, content, position, triggerOn, attributes, onRenderChild, autoFocusBehavior, ...props }: OverlayProps<T>): import("react/jsx-runtime").JSX.Element;
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Overlay/index.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAqB,YAAY,EAAE,MAAM,SAAS,CAAA;AAEzD;;;;;;;;;;GAUG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,MAAM,KAAK,CAAC,GAAG,CAAC,iBAAiB,EAAE,EACnE,GAAG,EACH,QAAQ,EACR,OAAO,EACP,QAAgB,EAChB,SAAmB,EACnB,UAAU,EACV,aAAa,EACb,iBAA8B,EAC9B,GAAG,KAAK,EACT,EAAE,YAAY,CAAC,CAAC,CAAC,2CA6GjB"}
@@ -0,0 +1,120 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useRef } from 'react';
3
+ import { showOverlay } from '../../overlay.js';
4
+ import { focusFirstChild } from '../../utils/acessibility.js';
5
+ import { OverlayProvider } from './context.js';
6
+ /**
7
+ * These todos are in order of priority.
8
+ *
9
+ * TODO: update position when the size changes. Currently, the top position seems out of place whenever the height changes. The same is
10
+ * probably true for the left position if the width changes.
11
+ * TODO: hoverDelayMS
12
+ * TODO: reposition the overlay when it's under a scrollable element other then the body and this element is scrolled.
13
+ * TODO: close the overlay when it's under a scrollable element other then the body and the element that triggered the tooltip becomes
14
+ * hidden by the scroll.
15
+ * TODO: use React Portal to implement overlays. The current implementation will lose every React context in the tree.
16
+ */
17
+ export function Overlay({ tag, children, content, position = 'top', triggerOn = 'hover', attributes, onRenderChild, autoFocusBehavior = 'keyboard', ...props }) {
18
+ const controller = useRef({ close: () => Promise.resolve() });
19
+ const wrapper = useRef(null);
20
+ // props that don't require removing and reattaching the event listeners
21
+ const dynamic = useRef({ tag, content, position, attributes });
22
+ useEffect(() => {
23
+ dynamic.current = { tag, content, position, attributes };
24
+ }, [tag, content, position, attributes]);
25
+ useEffect(() => {
26
+ let visible = false;
27
+ let hideOnClickOutside;
28
+ let hideOnEsc;
29
+ let hideOverlay;
30
+ let removeRefocusTargetListener;
31
+ function getTarget() {
32
+ const target = wrapper.current?.firstChild;
33
+ return target instanceof HTMLElement ? target : undefined;
34
+ }
35
+ if (onRenderChild) {
36
+ const target = getTarget();
37
+ if (target)
38
+ onRenderChild(target);
39
+ }
40
+ async function show(event) {
41
+ if (visible)
42
+ return;
43
+ visible = true;
44
+ const target = getTarget();
45
+ if (!target)
46
+ return;
47
+ const { overlay, hide: hideFn } = showOverlay({
48
+ tag: dynamic.current.tag,
49
+ content: ['string', 'number', 'boolean'].includes(typeof dynamic.current.content)
50
+ ? dynamic.current.content
51
+ : _jsx(OverlayProvider, { value: controller.current, children: dynamic.current.content }),
52
+ target,
53
+ position: dynamic.current.position,
54
+ attributes: dynamic.current.attributes,
55
+ });
56
+ hideOverlay = hideFn;
57
+ function onHide(condition) {
58
+ return (event) => {
59
+ if (condition(event))
60
+ controller.current.close();
61
+ };
62
+ }
63
+ if (event.type === 'click') {
64
+ event.stopPropagation();
65
+ hideOnClickOutside = onHide(e => e instanceof MouseEvent && e.button === 0 && !overlay.contains(e.target));
66
+ hideOnEsc = onHide(e => e instanceof KeyboardEvent && e.key === 'Escape');
67
+ document.addEventListener('click', hideOnClickOutside);
68
+ document.addEventListener('keydown', hideOnEsc);
69
+ }
70
+ //focus target when the last overlay element loses focus
71
+ function refocusTarget(e) {
72
+ if (e.key === 'Tab' && e.target instanceof HTMLElement) {
73
+ const allItems = Array.from(e.target.closest('[data-citric="menu"]')?.querySelectorAll('a, button') ?? []);
74
+ if (e.target === allItems[allItems.length - 1]) {
75
+ getTarget()?.focus();
76
+ e.preventDefault();
77
+ }
78
+ }
79
+ }
80
+ overlay.addEventListener('keydown', refocusTarget);
81
+ removeRefocusTargetListener = () => overlay.removeEventListener('keydown', refocusTarget);
82
+ // auto-focus
83
+ const openedWithMouse = event instanceof MouseEvent && event.detail > 0;
84
+ if (autoFocusBehavior === 'always' || (autoFocusBehavior === 'keyboard' && !openedWithMouse)) {
85
+ setTimeout(() => focusFirstChild(overlay), 20);
86
+ }
87
+ }
88
+ controller.current.close = async () => {
89
+ visible = false;
90
+ if (hideOnClickOutside)
91
+ document.removeEventListener('click', hideOnClickOutside);
92
+ if (hideOnEsc)
93
+ document.removeEventListener('keydown', hideOnEsc);
94
+ removeRefocusTargetListener?.();
95
+ await hideOverlay?.();
96
+ };
97
+ if (triggerOn === 'hover') {
98
+ getTarget()?.addEventListener('mouseenter', show);
99
+ getTarget()?.addEventListener('mouseleave', controller.current.close);
100
+ getTarget()?.addEventListener('focus', show);
101
+ getTarget()?.addEventListener('blur', controller.current.close);
102
+ return () => {
103
+ getTarget()?.removeEventListener('mouseenter', show);
104
+ getTarget()?.removeEventListener('mouseleave', controller.current.close);
105
+ getTarget()?.removeEventListener('focus', show);
106
+ getTarget()?.removeEventListener('blur', controller.current.close);
107
+ };
108
+ }
109
+ if (triggerOn === 'click') {
110
+ getTarget()?.addEventListener('click', show);
111
+ return () => {
112
+ getTarget()?.removeEventListener('click', show);
113
+ if (hideOnClickOutside)
114
+ document.removeEventListener('click', hideOnClickOutside);
115
+ };
116
+ }
117
+ }, [wrapper.current, triggerOn]);
118
+ return _jsx("div", { ref: wrapper, ...props, children: children });
119
+ }
120
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/Overlay/index.tsx"],"names":[],"mappings":"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"}