@lidofinance/lido-app-ui 1.9.0 → 1.10.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 (278) hide show
  1. package/README.md +30 -1
  2. package/dist/README.md +30 -1
  3. package/dist/cjs/breadcrumbs/Breadcrumbs.cjs +92 -0
  4. package/dist/cjs/breadcrumbs/Breadcrumbs.cjs.map +1 -0
  5. package/dist/cjs/breadcrumbs/Breadcrumbs.module.css.cjs +6 -0
  6. package/dist/cjs/breadcrumbs/Breadcrumbs.module.css.cjs.map +1 -0
  7. package/dist/cjs/divider/Divider.cjs +26 -0
  8. package/dist/cjs/divider/Divider.cjs.map +1 -0
  9. package/dist/cjs/divider/Divider.module.css.cjs +6 -0
  10. package/dist/cjs/divider/Divider.module.css.cjs.map +1 -0
  11. package/dist/cjs/grid/Grid.cjs +47 -0
  12. package/dist/cjs/grid/Grid.cjs.map +1 -0
  13. package/dist/cjs/grid/Grid.module.css.cjs +6 -0
  14. package/dist/cjs/grid/Grid.module.css.cjs.map +1 -0
  15. package/dist/cjs/grid/GridItem.cjs +39 -0
  16. package/dist/cjs/grid/GridItem.cjs.map +1 -0
  17. package/dist/cjs/grid/GridItem.module.css.cjs +6 -0
  18. package/dist/cjs/grid/GridItem.module.css.cjs.map +1 -0
  19. package/dist/cjs/header/Header.cjs +31 -0
  20. package/dist/cjs/header/Header.cjs.map +1 -0
  21. package/dist/cjs/header/Header.module.css.cjs +6 -0
  22. package/dist/cjs/header/Header.module.css.cjs.map +1 -0
  23. package/dist/cjs/header/HeaderNav.cjs +69 -0
  24. package/dist/cjs/header/HeaderNav.cjs.map +1 -0
  25. package/dist/cjs/header/HeaderNav.module.css.cjs +6 -0
  26. package/dist/cjs/header/HeaderNav.module.css.cjs.map +1 -0
  27. package/dist/cjs/hidden/Hidden.cjs +25 -0
  28. package/dist/cjs/hidden/Hidden.cjs.map +1 -0
  29. package/dist/cjs/hidden/Hidden.module.css.cjs +6 -0
  30. package/dist/cjs/hidden/Hidden.module.css.cjs.map +1 -0
  31. package/dist/cjs/hooks/Portal.cjs +57 -0
  32. package/dist/cjs/hooks/Portal.cjs.map +1 -0
  33. package/dist/cjs/hooks/overlayStack.cjs +26 -0
  34. package/dist/cjs/hooks/overlayStack.cjs.map +1 -0
  35. package/dist/cjs/hooks/useBodyScrollLock.cjs +50 -0
  36. package/dist/cjs/hooks/useBodyScrollLock.cjs.map +1 -0
  37. package/dist/cjs/hooks/useEscape.cjs +25 -0
  38. package/dist/cjs/hooks/useEscape.cjs.map +1 -0
  39. package/dist/cjs/hooks/useFocusTrap.cjs +66 -0
  40. package/dist/cjs/hooks/useFocusTrap.cjs.map +1 -0
  41. package/dist/cjs/hooks/useIsomorphicLayoutEffect.cjs +10 -0
  42. package/dist/cjs/hooks/useIsomorphicLayoutEffect.cjs.map +1 -0
  43. package/dist/cjs/hooks/useOutsideClick.cjs +15 -13
  44. package/dist/cjs/hooks/useOutsideClick.cjs.map +1 -1
  45. package/dist/cjs/icon-button/IconButton.cjs +5 -2
  46. package/dist/cjs/icon-button/IconButton.cjs.map +1 -1
  47. package/dist/cjs/icon-button/IconButton.module.css.cjs +1 -1
  48. package/dist/cjs/index.cjs +26 -0
  49. package/dist/cjs/index.cjs.map +1 -1
  50. package/dist/cjs/index.css +3 -3
  51. package/dist/cjs/link-provider/Anchor.cjs +48 -0
  52. package/dist/cjs/link-provider/Anchor.cjs.map +1 -0
  53. package/dist/cjs/link-provider/LinkProvider.cjs +29 -0
  54. package/dist/cjs/link-provider/LinkProvider.cjs.map +1 -0
  55. package/dist/cjs/logo/Logo.cjs +84 -0
  56. package/dist/cjs/logo/Logo.cjs.map +1 -0
  57. package/dist/cjs/logo/Logo.module.css.cjs +6 -0
  58. package/dist/cjs/logo/Logo.module.css.cjs.map +1 -0
  59. package/dist/cjs/modal/Modal.cjs +36 -29
  60. package/dist/cjs/modal/Modal.cjs.map +1 -1
  61. package/dist/cjs/nav-link/NavLink.cjs +44 -0
  62. package/dist/cjs/nav-link/NavLink.cjs.map +1 -0
  63. package/dist/cjs/nav-link/NavLink.module.css.cjs +6 -0
  64. package/dist/cjs/nav-link/NavLink.module.css.cjs.map +1 -0
  65. package/dist/cjs/notification/Notification.cjs +20 -4
  66. package/dist/cjs/notification/Notification.cjs.map +1 -1
  67. package/dist/cjs/notification/Notification.module.css.cjs +1 -1
  68. package/dist/cjs/popover/Popover.cjs +136 -0
  69. package/dist/cjs/popover/Popover.cjs.map +1 -0
  70. package/dist/cjs/popover/Popover.module.css.cjs +6 -0
  71. package/dist/cjs/popover/Popover.module.css.cjs.map +1 -0
  72. package/dist/cjs/segmented-control/SegmentedControl.cjs +2 -1
  73. package/dist/cjs/segmented-control/SegmentedControl.cjs.map +1 -1
  74. package/dist/cjs/segmented-control/SegmentedControlCard.cjs +2 -1
  75. package/dist/cjs/segmented-control/SegmentedControlCard.cjs.map +1 -1
  76. package/dist/cjs/small-card/SmallCard.cjs +2 -1
  77. package/dist/cjs/small-card/SmallCard.cjs.map +1 -1
  78. package/dist/cjs/stack/Stack.cjs +41 -0
  79. package/dist/cjs/stack/Stack.cjs.map +1 -0
  80. package/dist/cjs/stack/Stack.module.css.cjs +6 -0
  81. package/dist/cjs/stack/Stack.module.css.cjs.map +1 -0
  82. package/dist/cjs/tabs/Tabs.cjs +2 -1
  83. package/dist/cjs/tabs/Tabs.cjs.map +1 -1
  84. package/dist/cjs/text-link/TextLink.cjs +2 -1
  85. package/dist/cjs/text-link/TextLink.cjs.map +1 -1
  86. package/dist/cjs/theme-switcher/ThemeSwitcher.cjs +39 -0
  87. package/dist/cjs/theme-switcher/ThemeSwitcher.cjs.map +1 -0
  88. package/dist/cjs/token-selector/TokenSelector.cjs +3 -3
  89. package/dist/cjs/token-selector/TokenSelector.cjs.map +1 -1
  90. package/dist/cjs/tooltip/Tooltip.cjs +2 -1
  91. package/dist/cjs/tooltip/Tooltip.cjs.map +1 -1
  92. package/dist/cjs/utils/ActionElement.cjs +41 -0
  93. package/dist/cjs/utils/ActionElement.cjs.map +1 -0
  94. package/dist/cjs/utils/responsive.cjs +67 -0
  95. package/dist/cjs/utils/responsive.cjs.map +1 -0
  96. package/dist/esm/breadcrumbs/Breadcrumbs.mjs +88 -0
  97. package/dist/esm/breadcrumbs/Breadcrumbs.mjs.map +1 -0
  98. package/dist/esm/breadcrumbs/Breadcrumbs.module.css.mjs +4 -0
  99. package/dist/esm/breadcrumbs/Breadcrumbs.module.css.mjs.map +1 -0
  100. package/dist/esm/divider/Divider.mjs +22 -0
  101. package/dist/esm/divider/Divider.mjs.map +1 -0
  102. package/dist/esm/divider/Divider.module.css.mjs +4 -0
  103. package/dist/esm/divider/Divider.module.css.mjs.map +1 -0
  104. package/dist/esm/grid/Grid.mjs +43 -0
  105. package/dist/esm/grid/Grid.mjs.map +1 -0
  106. package/dist/esm/grid/Grid.module.css.mjs +4 -0
  107. package/dist/esm/grid/Grid.module.css.mjs.map +1 -0
  108. package/dist/esm/grid/GridItem.mjs +35 -0
  109. package/dist/esm/grid/GridItem.mjs.map +1 -0
  110. package/dist/esm/grid/GridItem.module.css.mjs +4 -0
  111. package/dist/esm/grid/GridItem.module.css.mjs.map +1 -0
  112. package/dist/esm/header/Header.mjs +27 -0
  113. package/dist/esm/header/Header.mjs.map +1 -0
  114. package/dist/esm/header/Header.module.css.mjs +4 -0
  115. package/dist/esm/header/Header.module.css.mjs.map +1 -0
  116. package/dist/esm/header/HeaderNav.mjs +65 -0
  117. package/dist/esm/header/HeaderNav.mjs.map +1 -0
  118. package/dist/esm/header/HeaderNav.module.css.mjs +4 -0
  119. package/dist/esm/header/HeaderNav.module.css.mjs.map +1 -0
  120. package/dist/esm/hidden/Hidden.mjs +21 -0
  121. package/dist/esm/hidden/Hidden.mjs.map +1 -0
  122. package/dist/esm/hidden/Hidden.module.css.mjs +4 -0
  123. package/dist/esm/hidden/Hidden.module.css.mjs.map +1 -0
  124. package/dist/esm/hooks/Portal.mjs +53 -0
  125. package/dist/esm/hooks/Portal.mjs.map +1 -0
  126. package/dist/esm/hooks/overlayStack.mjs +22 -0
  127. package/dist/esm/hooks/overlayStack.mjs.map +1 -0
  128. package/dist/esm/hooks/useBodyScrollLock.mjs +46 -0
  129. package/dist/esm/hooks/useBodyScrollLock.mjs.map +1 -0
  130. package/dist/esm/hooks/useEscape.mjs +21 -0
  131. package/dist/esm/hooks/useEscape.mjs.map +1 -0
  132. package/dist/esm/hooks/useFocusTrap.mjs +62 -0
  133. package/dist/esm/hooks/useFocusTrap.mjs.map +1 -0
  134. package/dist/esm/hooks/useIsomorphicLayoutEffect.mjs +6 -0
  135. package/dist/esm/hooks/useIsomorphicLayoutEffect.mjs.map +1 -0
  136. package/dist/esm/hooks/useOutsideClick.mjs +16 -14
  137. package/dist/esm/hooks/useOutsideClick.mjs.map +1 -1
  138. package/dist/esm/icon-button/IconButton.mjs +5 -2
  139. package/dist/esm/icon-button/IconButton.mjs.map +1 -1
  140. package/dist/esm/icon-button/IconButton.module.css.mjs +1 -1
  141. package/dist/esm/index.css +3 -3
  142. package/dist/esm/index.mjs +13 -0
  143. package/dist/esm/index.mjs.map +1 -1
  144. package/dist/esm/link-provider/Anchor.mjs +44 -0
  145. package/dist/esm/link-provider/Anchor.mjs.map +1 -0
  146. package/dist/esm/link-provider/LinkProvider.mjs +24 -0
  147. package/dist/esm/link-provider/LinkProvider.mjs.map +1 -0
  148. package/dist/esm/logo/Logo.mjs +80 -0
  149. package/dist/esm/logo/Logo.mjs.map +1 -0
  150. package/dist/esm/logo/Logo.module.css.mjs +4 -0
  151. package/dist/esm/logo/Logo.module.css.mjs.map +1 -0
  152. package/dist/esm/modal/Modal.mjs +38 -31
  153. package/dist/esm/modal/Modal.mjs.map +1 -1
  154. package/dist/esm/nav-link/NavLink.mjs +40 -0
  155. package/dist/esm/nav-link/NavLink.mjs.map +1 -0
  156. package/dist/esm/nav-link/NavLink.module.css.mjs +4 -0
  157. package/dist/esm/nav-link/NavLink.module.css.mjs.map +1 -0
  158. package/dist/esm/notification/Notification.mjs +20 -4
  159. package/dist/esm/notification/Notification.mjs.map +1 -1
  160. package/dist/esm/notification/Notification.module.css.mjs +1 -1
  161. package/dist/esm/popover/Popover.mjs +132 -0
  162. package/dist/esm/popover/Popover.mjs.map +1 -0
  163. package/dist/esm/popover/Popover.module.css.mjs +4 -0
  164. package/dist/esm/popover/Popover.module.css.mjs.map +1 -0
  165. package/dist/esm/segmented-control/SegmentedControl.mjs +3 -2
  166. package/dist/esm/segmented-control/SegmentedControl.mjs.map +1 -1
  167. package/dist/esm/segmented-control/SegmentedControlCard.mjs +3 -2
  168. package/dist/esm/segmented-control/SegmentedControlCard.mjs.map +1 -1
  169. package/dist/esm/small-card/SmallCard.mjs +2 -1
  170. package/dist/esm/small-card/SmallCard.mjs.map +1 -1
  171. package/dist/esm/stack/Stack.mjs +37 -0
  172. package/dist/esm/stack/Stack.mjs.map +1 -0
  173. package/dist/esm/stack/Stack.module.css.mjs +4 -0
  174. package/dist/esm/stack/Stack.module.css.mjs.map +1 -0
  175. package/dist/esm/tabs/Tabs.mjs +3 -2
  176. package/dist/esm/tabs/Tabs.mjs.map +1 -1
  177. package/dist/esm/text-link/TextLink.mjs +2 -1
  178. package/dist/esm/text-link/TextLink.mjs.map +1 -1
  179. package/dist/esm/theme-switcher/ThemeSwitcher.mjs +35 -0
  180. package/dist/esm/theme-switcher/ThemeSwitcher.mjs.map +1 -0
  181. package/dist/esm/token-selector/TokenSelector.mjs +3 -3
  182. package/dist/esm/token-selector/TokenSelector.mjs.map +1 -1
  183. package/dist/esm/tooltip/Tooltip.mjs +3 -2
  184. package/dist/esm/tooltip/Tooltip.mjs.map +1 -1
  185. package/dist/esm/utils/ActionElement.mjs +37 -0
  186. package/dist/esm/utils/ActionElement.mjs.map +1 -0
  187. package/dist/esm/utils/responsive.mjs +58 -0
  188. package/dist/esm/utils/responsive.mjs.map +1 -0
  189. package/dist/index.css +3 -3
  190. package/dist/styles/breakpoints.css +6 -0
  191. package/dist/types/breadcrumbs/Breadcrumbs.d.ts +11 -0
  192. package/dist/types/breadcrumbs/Breadcrumbs.d.ts.map +1 -0
  193. package/dist/types/breadcrumbs/index.d.ts +3 -0
  194. package/dist/types/breadcrumbs/index.d.ts.map +1 -0
  195. package/dist/types/colors/colorTokens.d.ts.map +1 -1
  196. package/dist/types/divider/Divider.d.ts +10 -0
  197. package/dist/types/divider/Divider.d.ts.map +1 -0
  198. package/dist/types/divider/index.d.ts +3 -0
  199. package/dist/types/divider/index.d.ts.map +1 -0
  200. package/dist/types/grid/Grid.d.ts +31 -0
  201. package/dist/types/grid/Grid.d.ts.map +1 -0
  202. package/dist/types/grid/GridItem.d.ts +16 -0
  203. package/dist/types/grid/GridItem.d.ts.map +1 -0
  204. package/dist/types/grid/index.d.ts +5 -0
  205. package/dist/types/grid/index.d.ts.map +1 -0
  206. package/dist/types/header/Header.d.ts +9 -0
  207. package/dist/types/header/Header.d.ts.map +1 -0
  208. package/dist/types/header/HeaderNav.d.ts +4 -0
  209. package/dist/types/header/HeaderNav.d.ts.map +1 -0
  210. package/dist/types/header/index.d.ts +5 -0
  211. package/dist/types/header/index.d.ts.map +1 -0
  212. package/dist/types/hidden/Hidden.d.ts +11 -0
  213. package/dist/types/hidden/Hidden.d.ts.map +1 -0
  214. package/dist/types/hidden/index.d.ts +3 -0
  215. package/dist/types/hidden/index.d.ts.map +1 -0
  216. package/dist/types/hooks/Portal.d.ts +12 -0
  217. package/dist/types/hooks/Portal.d.ts.map +1 -0
  218. package/dist/types/hooks/index.d.ts +9 -0
  219. package/dist/types/hooks/index.d.ts.map +1 -0
  220. package/dist/types/hooks/overlayStack.d.ts +7 -0
  221. package/dist/types/hooks/overlayStack.d.ts.map +1 -0
  222. package/dist/types/hooks/useBodyScrollLock.d.ts +3 -0
  223. package/dist/types/hooks/useBodyScrollLock.d.ts.map +1 -0
  224. package/dist/types/hooks/useEscape.d.ts +3 -0
  225. package/dist/types/hooks/useEscape.d.ts.map +1 -0
  226. package/dist/types/hooks/useFocusTrap.d.ts +10 -0
  227. package/dist/types/hooks/useFocusTrap.d.ts.map +1 -0
  228. package/dist/types/hooks/useIsomorphicLayoutEffect.d.ts +3 -0
  229. package/dist/types/hooks/useIsomorphicLayoutEffect.d.ts.map +1 -0
  230. package/dist/types/hooks/useOutsideClick.d.ts +2 -2
  231. package/dist/types/hooks/useOutsideClick.d.ts.map +1 -1
  232. package/dist/types/icon-button/IconButton.d.ts +11 -3
  233. package/dist/types/icon-button/IconButton.d.ts.map +1 -1
  234. package/dist/types/index.d.ts +12 -0
  235. package/dist/types/index.d.ts.map +1 -1
  236. package/dist/types/link-provider/Anchor.d.ts +4 -0
  237. package/dist/types/link-provider/Anchor.d.ts.map +1 -0
  238. package/dist/types/link-provider/LinkProvider.d.ts +17 -0
  239. package/dist/types/link-provider/LinkProvider.d.ts.map +1 -0
  240. package/dist/types/link-provider/index.d.ts +3 -0
  241. package/dist/types/link-provider/index.d.ts.map +1 -0
  242. package/dist/types/logo/Logo.d.ts +13 -0
  243. package/dist/types/logo/Logo.d.ts.map +1 -0
  244. package/dist/types/logo/index.d.ts +3 -0
  245. package/dist/types/logo/index.d.ts.map +1 -0
  246. package/dist/types/modal/Modal.d.ts +23 -1
  247. package/dist/types/modal/Modal.d.ts.map +1 -1
  248. package/dist/types/nav-link/NavLink.d.ts +12 -0
  249. package/dist/types/nav-link/NavLink.d.ts.map +1 -0
  250. package/dist/types/nav-link/index.d.ts +3 -0
  251. package/dist/types/nav-link/index.d.ts.map +1 -0
  252. package/dist/types/notification/Notification.d.ts +15 -2
  253. package/dist/types/notification/Notification.d.ts.map +1 -1
  254. package/dist/types/popover/Popover.d.ts +21 -0
  255. package/dist/types/popover/Popover.d.ts.map +1 -0
  256. package/dist/types/popover/index.d.ts +3 -0
  257. package/dist/types/popover/index.d.ts.map +1 -0
  258. package/dist/types/segmented-control/SegmentedControl.d.ts.map +1 -1
  259. package/dist/types/segmented-control/SegmentedControlCard.d.ts.map +1 -1
  260. package/dist/types/small-card/SmallCard.d.ts.map +1 -1
  261. package/dist/types/stack/Stack.d.ts +25 -0
  262. package/dist/types/stack/Stack.d.ts.map +1 -0
  263. package/dist/types/stack/index.d.ts +3 -0
  264. package/dist/types/stack/index.d.ts.map +1 -0
  265. package/dist/types/tabs/Tabs.d.ts.map +1 -1
  266. package/dist/types/text-link/TextLink.d.ts.map +1 -1
  267. package/dist/types/theme-switcher/ThemeSwitcher.d.ts +5 -0
  268. package/dist/types/theme-switcher/ThemeSwitcher.d.ts.map +1 -0
  269. package/dist/types/theme-switcher/index.d.ts +3 -0
  270. package/dist/types/theme-switcher/index.d.ts.map +1 -0
  271. package/dist/types/tooltip/Tooltip.d.ts.map +1 -1
  272. package/dist/types/utils/ActionElement.d.ts +10 -0
  273. package/dist/types/utils/ActionElement.d.ts.map +1 -0
  274. package/dist/types/utils/index.d.ts +5 -0
  275. package/dist/types/utils/index.d.ts.map +1 -0
  276. package/dist/types/utils/responsive.d.ts +27 -0
  277. package/dist/types/utils/responsive.d.ts.map +1 -0
  278. package/package.json +2 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlayStack.mjs","sources":["../../../src/hooks/overlayStack.ts"],"sourcesContent":["type LayerOptions = { capture?: boolean }\n\n/** Each layer gets a document listener for `type` that only fires while it's the newest layer in its stack. */\nexport const createLayerStack = <K extends keyof DocumentEventMap>(\n type: K,\n { capture = false }: LayerOptions = {},\n) => {\n const layers: object[] = []\n return (onEvent: (event: DocumentEventMap[K]) => void) => {\n const layer = {}\n layers.push(layer)\n const listener = (event: DocumentEventMap[K]) => {\n if (layers[layers.length - 1] === layer) onEvent(event)\n }\n document.addEventListener(type, listener, capture)\n return () => {\n document.removeEventListener(type, listener, capture)\n layers.splice(layers.indexOf(layer), 1)\n }\n }\n}\n"],"names":["createLayerStack","type","capture","arguments","length","undefined","layers","onEvent","layer","push","listener","event","document","addEventListener","removeEventListener","splice","indexOf"],"mappings":"AAEA;MACaA,gBAAgB,GAAG,UAC9BC,IAAO,EAEJ;EAAA,IADH;AAAEC,IAAAA,OAAO,GAAG,KAAA;AAAoB,GAAC,GAAAC,SAAA,CAAAC,MAAA,GAAAD,CAAAA,IAAAA,SAAA,CAAAE,CAAAA,CAAAA,KAAAA,SAAA,GAAAF,SAAA,CAAG,CAAA,CAAA,GAAA,EAAE,CAAA;EAEtC,MAAMG,MAAgB,GAAG,EAAE,CAAA;AAC3B,EAAA,OAAQC,OAA6C,IAAK;IACxD,MAAMC,KAAK,GAAG,EAAE,CAAA;AAChBF,IAAAA,MAAM,CAACG,IAAI,CAACD,KAAK,CAAC,CAAA;IAClB,MAAME,QAAQ,GAAIC,KAA0B,IAAK;AAC/C,MAAA,IAAIL,MAAM,CAACA,MAAM,CAACF,MAAM,GAAG,CAAC,CAAC,KAAKI,KAAK,EAAED,OAAO,CAACI,KAAK,CAAC,CAAA;KACxD,CAAA;IACDC,QAAQ,CAACC,gBAAgB,CAACZ,IAAI,EAAES,QAAQ,EAAER,OAAO,CAAC,CAAA;AAClD,IAAA,OAAO,MAAM;MACXU,QAAQ,CAACE,mBAAmB,CAACb,IAAI,EAAES,QAAQ,EAAER,OAAO,CAAC,CAAA;MACrDI,MAAM,CAACS,MAAM,CAACT,MAAM,CAACU,OAAO,CAACR,KAAK,CAAC,EAAE,CAAC,CAAC,CAAA;KACxC,CAAA;GACF,CAAA;AACH;;;;"}
@@ -0,0 +1,46 @@
1
+ import { useEffect } from 'react';
2
+
3
+ // Ref-counted so stacked overlays only restore on the last unlock.
4
+ let lockCount = 0;
5
+ let saved = {
6
+ overflow: '',
7
+ paddingRight: ''
8
+ };
9
+ const lock = () => {
10
+ if (lockCount === 0) {
11
+ const {
12
+ body,
13
+ documentElement
14
+ } = document;
15
+ saved = {
16
+ overflow: body.style.overflow,
17
+ paddingRight: body.style.paddingRight
18
+ };
19
+ const scrollbarWidth = window.innerWidth - documentElement.clientWidth;
20
+ if (scrollbarWidth > 0) {
21
+ const current = parseFloat(getComputedStyle(body).paddingRight) || 0;
22
+ body.style.paddingRight = `${current + scrollbarWidth}px`;
23
+ }
24
+ body.style.overflow = 'hidden';
25
+ }
26
+ lockCount += 1;
27
+ };
28
+ const unlock = () => {
29
+ lockCount -= 1;
30
+ if (lockCount === 0) {
31
+ document.body.style.overflow = saved.overflow;
32
+ document.body.style.paddingRight = saved.paddingRight;
33
+ }
34
+ };
35
+
36
+ /** Locks body scroll while `active`, compensating the scrollbar width. */
37
+ const useBodyScrollLock = active => {
38
+ useEffect(() => {
39
+ if (!active) return;
40
+ lock();
41
+ return unlock;
42
+ }, [active]);
43
+ };
44
+
45
+ export { useBodyScrollLock };
46
+ //# sourceMappingURL=useBodyScrollLock.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBodyScrollLock.mjs","sources":["../../../src/hooks/useBodyScrollLock.ts"],"sourcesContent":["import { useEffect } from 'react'\n\n// Ref-counted so stacked overlays only restore on the last unlock.\nlet lockCount = 0\nlet saved = { overflow: '', paddingRight: '' }\n\nconst lock = () => {\n if (lockCount === 0) {\n const { body, documentElement } = document\n saved = {\n overflow: body.style.overflow,\n paddingRight: body.style.paddingRight,\n }\n const scrollbarWidth = window.innerWidth - documentElement.clientWidth\n if (scrollbarWidth > 0) {\n const current = parseFloat(getComputedStyle(body).paddingRight) || 0\n body.style.paddingRight = `${current + scrollbarWidth}px`\n }\n body.style.overflow = 'hidden'\n }\n lockCount += 1\n}\n\nconst unlock = () => {\n lockCount -= 1\n if (lockCount === 0) {\n document.body.style.overflow = saved.overflow\n document.body.style.paddingRight = saved.paddingRight\n }\n}\n\n/** Locks body scroll while `active`, compensating the scrollbar width. */\nexport const useBodyScrollLock = (active: boolean) => {\n useEffect(() => {\n if (!active) return\n lock()\n return unlock\n }, [active])\n}\n"],"names":["lockCount","saved","overflow","paddingRight","lock","body","documentElement","document","style","scrollbarWidth","window","innerWidth","clientWidth","current","parseFloat","getComputedStyle","unlock","useBodyScrollLock","active","useEffect"],"mappings":";;AAEA;AACA,IAAIA,SAAS,GAAG,CAAC,CAAA;AACjB,IAAIC,KAAK,GAAG;AAAEC,EAAAA,QAAQ,EAAE,EAAE;AAAEC,EAAAA,YAAY,EAAE,EAAA;AAAG,CAAC,CAAA;AAE9C,MAAMC,IAAI,GAAGA,MAAM;EACjB,IAAIJ,SAAS,KAAK,CAAC,EAAE;IACnB,MAAM;MAAEK,IAAI;AAAEC,MAAAA,eAAAA;AAAgB,KAAC,GAAGC,QAAQ,CAAA;AAC1CN,IAAAA,KAAK,GAAG;AACNC,MAAAA,QAAQ,EAAEG,IAAI,CAACG,KAAK,CAACN,QAAQ;AAC7BC,MAAAA,YAAY,EAAEE,IAAI,CAACG,KAAK,CAACL,YAAAA;KAC1B,CAAA;IACD,MAAMM,cAAc,GAAGC,MAAM,CAACC,UAAU,GAAGL,eAAe,CAACM,WAAW,CAAA;IACtE,IAAIH,cAAc,GAAG,CAAC,EAAE;AACtB,MAAA,MAAMI,OAAO,GAAGC,UAAU,CAACC,gBAAgB,CAACV,IAAI,CAAC,CAACF,YAAY,CAAC,IAAI,CAAC,CAAA;MACpEE,IAAI,CAACG,KAAK,CAACL,YAAY,GAAG,CAAGU,EAAAA,OAAO,GAAGJ,cAAc,CAAI,EAAA,CAAA,CAAA;AAC3D,KAAA;AACAJ,IAAAA,IAAI,CAACG,KAAK,CAACN,QAAQ,GAAG,QAAQ,CAAA;AAChC,GAAA;AACAF,EAAAA,SAAS,IAAI,CAAC,CAAA;AAChB,CAAC,CAAA;AAED,MAAMgB,MAAM,GAAGA,MAAM;AACnBhB,EAAAA,SAAS,IAAI,CAAC,CAAA;EACd,IAAIA,SAAS,KAAK,CAAC,EAAE;IACnBO,QAAQ,CAACF,IAAI,CAACG,KAAK,CAACN,QAAQ,GAAGD,KAAK,CAACC,QAAQ,CAAA;IAC7CK,QAAQ,CAACF,IAAI,CAACG,KAAK,CAACL,YAAY,GAAGF,KAAK,CAACE,YAAY,CAAA;AACvD,GAAA;AACF,CAAC,CAAA;;AAED;AACac,MAAAA,iBAAiB,GAAIC,MAAe,IAAK;AACpDC,EAAAA,SAAS,CAAC,MAAM;IACd,IAAI,CAACD,MAAM,EAAE,OAAA;AACbd,IAAAA,IAAI,EAAE,CAAA;AACN,IAAA,OAAOY,MAAM,CAAA;AACf,GAAC,EAAE,CAACE,MAAM,CAAC,CAAC,CAAA;AACd;;;;"}
@@ -0,0 +1,21 @@
1
+ import { useRef, useEffect } from 'react';
2
+ import { createLayerStack } from './overlayStack.mjs';
3
+
4
+ const listenEscapeLayer = createLayerStack('keydown');
5
+
6
+ /** Calls `handler` on Escape while `active`; with nested overlays only the newest one handles it. */
7
+ const useEscape = (active, handler) => {
8
+ const handlerRef = useRef(handler);
9
+ handlerRef.current = handler;
10
+ useEffect(() => {
11
+ if (!active) return;
12
+ return listenEscapeLayer(event => {
13
+ if (event.key !== 'Escape' || event.defaultPrevented) return;
14
+ event.preventDefault();
15
+ handlerRef.current(event);
16
+ });
17
+ }, [active]);
18
+ };
19
+
20
+ export { useEscape };
21
+ //# sourceMappingURL=useEscape.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useEscape.mjs","sources":["../../../src/hooks/useEscape.ts"],"sourcesContent":["import { useEffect, useRef } from 'react'\n\nimport { createLayerStack } from './overlayStack'\n\nconst listenEscapeLayer = createLayerStack('keydown')\n\n/** Calls `handler` on Escape while `active`; with nested overlays only the newest one handles it. */\nexport const useEscape = (\n active: boolean,\n handler: (event: KeyboardEvent) => void,\n) => {\n const handlerRef = useRef(handler)\n handlerRef.current = handler\n\n useEffect(() => {\n if (!active) return\n\n return listenEscapeLayer((event) => {\n if (event.key !== 'Escape' || event.defaultPrevented) return\n event.preventDefault()\n handlerRef.current(event)\n })\n }, [active])\n}\n"],"names":["listenEscapeLayer","createLayerStack","useEscape","active","handler","handlerRef","useRef","current","useEffect","event","key","defaultPrevented","preventDefault"],"mappings":";;;AAIA,MAAMA,iBAAiB,GAAGC,gBAAgB,CAAC,SAAS,CAAC,CAAA;;AAErD;MACaC,SAAS,GAAGA,CACvBC,MAAe,EACfC,OAAuC,KACpC;AACH,EAAA,MAAMC,UAAU,GAAGC,MAAM,CAACF,OAAO,CAAC,CAAA;EAClCC,UAAU,CAACE,OAAO,GAAGH,OAAO,CAAA;AAE5BI,EAAAA,SAAS,CAAC,MAAM;IACd,IAAI,CAACL,MAAM,EAAE,OAAA;IAEb,OAAOH,iBAAiB,CAAES,KAAK,IAAK;MAClC,IAAIA,KAAK,CAACC,GAAG,KAAK,QAAQ,IAAID,KAAK,CAACE,gBAAgB,EAAE,OAAA;MACtDF,KAAK,CAACG,cAAc,EAAE,CAAA;AACtBP,MAAAA,UAAU,CAACE,OAAO,CAACE,KAAK,CAAC,CAAA;AAC3B,KAAC,CAAC,CAAA;AACJ,GAAC,EAAE,CAACN,MAAM,CAAC,CAAC,CAAA;AACd;;;;"}
@@ -0,0 +1,62 @@
1
+ import { useRef, useEffect } from 'react';
2
+ import { createLayerStack } from './overlayStack.mjs';
3
+
4
+ const listenTrapLayer = createLayerStack('keydown');
5
+ const TABBABLE = 'a[href],button,input:not([type="hidden"]),select,textarea,[tabindex]:not([tabindex="-1"]),[contenteditable="true"]';
6
+ const isRendered = el => {
7
+ const style = getComputedStyle(el);
8
+ return style.visibility !== 'hidden' && style.display !== 'none';
9
+ };
10
+ const getTabbable = container => Array.from(container.querySelectorAll(TABBABLE)).filter(el => !el.matches(':disabled') && el.getAttribute('aria-hidden') !== 'true' && isRendered(el));
11
+ /** Keeps Tab / Shift+Tab inside `element` while `active`; with nested traps only the newest one handles Tab. */
12
+ const useFocusTrap = function (element, active) {
13
+ let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
14
+ const optionsRef = useRef(options);
15
+ optionsRef.current = options;
16
+ useEffect(() => {
17
+ const container = element;
18
+ if (!active || !container) return;
19
+ const previous = document.activeElement;
20
+ const target = optionsRef.current.initialFocus?.current ?? getTabbable(container)[0] ?? container;
21
+ if (target === container && !container.hasAttribute('tabindex')) {
22
+ container.setAttribute('tabindex', '-1');
23
+ }
24
+ target.focus({
25
+ preventScroll: true
26
+ });
27
+ const onKeyDown = event => {
28
+ if (event.key !== 'Tab') return;
29
+ const items = getTabbable(container);
30
+ if (items.length === 0) {
31
+ event.preventDefault();
32
+ container.focus();
33
+ return;
34
+ }
35
+ const first = items[0];
36
+ const last = items[items.length - 1];
37
+ const current = document.activeElement;
38
+ if (!container.contains(current)) {
39
+ event.preventDefault();
40
+ (event.shiftKey ? last : first).focus();
41
+ } else if (event.shiftKey && (current === first || current === container)) {
42
+ event.preventDefault();
43
+ last.focus();
44
+ } else if (!event.shiftKey && current === last) {
45
+ event.preventDefault();
46
+ first.focus();
47
+ }
48
+ };
49
+ const stopListening = listenTrapLayer(onKeyDown);
50
+ return () => {
51
+ stopListening();
52
+ if ((optionsRef.current.restoreFocus ?? true) && previous && document.contains(previous)) {
53
+ previous.focus({
54
+ preventScroll: true
55
+ });
56
+ }
57
+ };
58
+ }, [element, active]);
59
+ };
60
+
61
+ export { useFocusTrap };
62
+ //# sourceMappingURL=useFocusTrap.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFocusTrap.mjs","sources":["../../../src/hooks/useFocusTrap.ts"],"sourcesContent":["import { useEffect, useRef, type RefObject } from 'react'\n\nimport { createLayerStack } from './overlayStack'\n\nconst listenTrapLayer = createLayerStack('keydown')\n\nconst TABBABLE =\n 'a[href],button,input:not([type=\"hidden\"]),select,textarea,[tabindex]:not([tabindex=\"-1\"]),[contenteditable=\"true\"]'\n\nconst isRendered = (el: HTMLElement) => {\n const style = getComputedStyle(el)\n return style.visibility !== 'hidden' && style.display !== 'none'\n}\n\nconst getTabbable = (container: HTMLElement) =>\n Array.from(container.querySelectorAll<HTMLElement>(TABBABLE)).filter(\n (el) =>\n !el.matches(':disabled') &&\n el.getAttribute('aria-hidden') !== 'true' &&\n isRendered(el),\n )\n\nexport type FocusTrapOptions = {\n /** Element to focus on activate; defaults to first tabbable, then the container. */\n initialFocus?: RefObject<HTMLElement | null>\n /** Return focus to the previously focused element on deactivate. Default true. */\n restoreFocus?: boolean\n}\n\n/** Keeps Tab / Shift+Tab inside `element` while `active`; with nested traps only the newest one handles Tab. */\nexport const useFocusTrap = (\n element: HTMLElement | null,\n active: boolean,\n options: FocusTrapOptions = {},\n) => {\n const optionsRef = useRef(options)\n optionsRef.current = options\n\n useEffect(() => {\n const container = element\n if (!active || !container) return\n\n const previous = document.activeElement as HTMLElement | null\n\n const target =\n optionsRef.current.initialFocus?.current ??\n getTabbable(container)[0] ??\n container\n if (target === container && !container.hasAttribute('tabindex')) {\n container.setAttribute('tabindex', '-1')\n }\n target.focus({ preventScroll: true })\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key !== 'Tab') return\n const items = getTabbable(container)\n if (items.length === 0) {\n event.preventDefault()\n container.focus()\n return\n }\n const first = items[0]\n const last = items[items.length - 1]\n const current = document.activeElement\n if (!container.contains(current)) {\n event.preventDefault()\n ;(event.shiftKey ? last : first).focus()\n } else if (\n event.shiftKey &&\n (current === first || current === container)\n ) {\n event.preventDefault()\n last.focus()\n } else if (!event.shiftKey && current === last) {\n event.preventDefault()\n first.focus()\n }\n }\n\n const stopListening = listenTrapLayer(onKeyDown)\n return () => {\n stopListening()\n if (\n (optionsRef.current.restoreFocus ?? true) &&\n previous &&\n document.contains(previous)\n ) {\n previous.focus({ preventScroll: true })\n }\n }\n }, [element, active])\n}\n"],"names":["listenTrapLayer","createLayerStack","TABBABLE","isRendered","el","style","getComputedStyle","visibility","display","getTabbable","container","Array","from","querySelectorAll","filter","matches","getAttribute","useFocusTrap","element","active","options","arguments","length","undefined","optionsRef","useRef","current","useEffect","previous","document","activeElement","target","initialFocus","hasAttribute","setAttribute","focus","preventScroll","onKeyDown","event","key","items","preventDefault","first","last","contains","shiftKey","stopListening","restoreFocus"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { useEffect, useLayoutEffect } from 'react';
2
+
3
+ const useIsomorphicLayoutEffect = typeof window === 'undefined' ? useEffect : useLayoutEffect;
4
+
5
+ export { useIsomorphicLayoutEffect };
6
+ //# sourceMappingURL=useIsomorphicLayoutEffect.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useIsomorphicLayoutEffect.mjs","sources":["../../../src/hooks/useIsomorphicLayoutEffect.ts"],"sourcesContent":["import { useEffect, useLayoutEffect } from 'react'\n\nexport const useIsomorphicLayoutEffect =\n typeof window === 'undefined' ? useEffect : useLayoutEffect\n"],"names":["useIsomorphicLayoutEffect","window","useEffect","useLayoutEffect"],"mappings":";;AAEO,MAAMA,yBAAyB,GACpC,OAAOC,MAAM,KAAK,WAAW,GAAGC,SAAS,GAAGC;;;;"}
@@ -1,19 +1,21 @@
1
- import { useEffect } from 'react';
1
+ import { useRef, useEffect } from 'react';
2
+ import { createLayerStack } from './overlayStack.mjs';
2
3
 
3
- const useOutsideClick = (ref, onOutside, enabled) => {
4
+ const listenOutsideLayer = createLayerStack('pointerdown', {
5
+ capture: true
6
+ });
7
+
8
+ /** Calls `onOutside` on pointerdown outside `element` while `enabled`; with nested overlays only the newest one handles outside clicks. */
9
+ const useOutsideClick = (element, onOutside, enabled) => {
10
+ const handlerRef = useRef(onOutside);
11
+ handlerRef.current = onOutside;
4
12
  useEffect(() => {
5
- if (!enabled) return;
6
- const handlePointerDown = event => {
7
- const element = ref.current;
8
- if (!element) return;
9
- if (event.target instanceof Node && element.contains(event.target)) {
10
- return;
11
- }
12
- onOutside();
13
- };
14
- document.addEventListener('pointerdown', handlePointerDown, true);
15
- return () => document.removeEventListener('pointerdown', handlePointerDown, true);
16
- }, [ref, onOutside, enabled]);
13
+ if (!enabled || !element) return;
14
+ return listenOutsideLayer(event => {
15
+ if (event.target instanceof Node && element.contains(event.target)) return;
16
+ handlerRef.current(event);
17
+ });
18
+ }, [element, enabled]);
17
19
  };
18
20
 
19
21
  export { useOutsideClick };
@@ -1 +1 @@
1
- {"version":3,"file":"useOutsideClick.mjs","sources":["../../../src/hooks/useOutsideClick.ts"],"sourcesContent":["import { useEffect, type RefObject } from 'react'\n\nexport const useOutsideClick = (\n ref: RefObject<HTMLElement | null>,\n onOutside: () => void,\n enabled: boolean,\n) => {\n useEffect(() => {\n if (!enabled) return\n\n const handlePointerDown = (event: PointerEvent) => {\n const element = ref.current\n if (!element) return\n if (event.target instanceof Node && element.contains(event.target)) {\n return\n }\n onOutside()\n }\n\n document.addEventListener('pointerdown', handlePointerDown, true)\n return () =>\n document.removeEventListener('pointerdown', handlePointerDown, true)\n }, [ref, onOutside, enabled])\n}\n"],"names":["useOutsideClick","ref","onOutside","enabled","useEffect","handlePointerDown","event","element","current","target","Node","contains","document","addEventListener","removeEventListener"],"mappings":";;AAEO,MAAMA,eAAe,GAAGA,CAC7BC,GAAkC,EAClCC,SAAqB,EACrBC,OAAgB,KACb;AACHC,EAAAA,SAAS,CAAC,MAAM;IACd,IAAI,CAACD,OAAO,EAAE,OAAA;IAEd,MAAME,iBAAiB,GAAIC,KAAmB,IAAK;AACjD,MAAA,MAAMC,OAAO,GAAGN,GAAG,CAACO,OAAO,CAAA;MAC3B,IAAI,CAACD,OAAO,EAAE,OAAA;AACd,MAAA,IAAID,KAAK,CAACG,MAAM,YAAYC,IAAI,IAAIH,OAAO,CAACI,QAAQ,CAACL,KAAK,CAACG,MAAM,CAAC,EAAE;AAClE,QAAA,OAAA;AACF,OAAA;AACAP,MAAAA,SAAS,EAAE,CAAA;KACZ,CAAA;IAEDU,QAAQ,CAACC,gBAAgB,CAAC,aAAa,EAAER,iBAAiB,EAAE,IAAI,CAAC,CAAA;IACjE,OAAO,MACLO,QAAQ,CAACE,mBAAmB,CAAC,aAAa,EAAET,iBAAiB,EAAE,IAAI,CAAC,CAAA;GACvE,EAAE,CAACJ,GAAG,EAAEC,SAAS,EAAEC,OAAO,CAAC,CAAC,CAAA;AAC/B;;;;"}
1
+ {"version":3,"file":"useOutsideClick.mjs","sources":["../../../src/hooks/useOutsideClick.ts"],"sourcesContent":["import { useEffect, useRef } from 'react'\n\nimport { createLayerStack } from './overlayStack'\n\nconst listenOutsideLayer = createLayerStack('pointerdown', { capture: true })\n\n/** Calls `onOutside` on pointerdown outside `element` while `enabled`; with nested overlays only the newest one handles outside clicks. */\nexport const useOutsideClick = (\n element: HTMLElement | null,\n onOutside: (event: PointerEvent) => void,\n enabled: boolean,\n) => {\n const handlerRef = useRef(onOutside)\n handlerRef.current = onOutside\n\n useEffect(() => {\n if (!enabled || !element) return\n\n return listenOutsideLayer((event) => {\n if (event.target instanceof Node && element.contains(event.target)) return\n handlerRef.current(event)\n })\n }, [element, enabled])\n}\n"],"names":["listenOutsideLayer","createLayerStack","capture","useOutsideClick","element","onOutside","enabled","handlerRef","useRef","current","useEffect","event","target","Node","contains"],"mappings":";;;AAIA,MAAMA,kBAAkB,GAAGC,gBAAgB,CAAC,aAAa,EAAE;AAAEC,EAAAA,OAAO,EAAE,IAAA;AAAK,CAAC,CAAC,CAAA;;AAE7E;AACO,MAAMC,eAAe,GAAGA,CAC7BC,OAA2B,EAC3BC,SAAwC,EACxCC,OAAgB,KACb;AACH,EAAA,MAAMC,UAAU,GAAGC,MAAM,CAACH,SAAS,CAAC,CAAA;EACpCE,UAAU,CAACE,OAAO,GAAGJ,SAAS,CAAA;AAE9BK,EAAAA,SAAS,CAAC,MAAM;AACd,IAAA,IAAI,CAACJ,OAAO,IAAI,CAACF,OAAO,EAAE,OAAA;IAE1B,OAAOJ,kBAAkB,CAAEW,KAAK,IAAK;AACnC,MAAA,IAAIA,KAAK,CAACC,MAAM,YAAYC,IAAI,IAAIT,OAAO,CAACU,QAAQ,CAACH,KAAK,CAACC,MAAM,CAAC,EAAE,OAAA;AACpEL,MAAAA,UAAU,CAACE,OAAO,CAACE,KAAK,CAAC,CAAA;AAC3B,KAAC,CAAC,CAAA;AACJ,GAAC,EAAE,CAACP,OAAO,EAAEE,OAAO,CAAC,CAAC,CAAA;AACxB;;;;"}
@@ -1,10 +1,11 @@
1
+ import { forwardRef } from 'react';
1
2
  import cn from 'classnames';
2
3
  import { CounterSlot } from '../counter/CounterSlot.mjs';
3
4
  import styles from './IconButton.module.css.mjs';
4
5
  import { jsxs, jsx } from 'react/jsx-runtime';
5
6
  import { IconLoaderCircle } from '../icons/components/base/IconLoaderCircle.mjs';
6
7
 
7
- const IconButton = _ref => {
8
+ const IconButton = /*#__PURE__*/forwardRef((_ref, ref) => {
8
9
  let {
9
10
  className,
10
11
  type = 'button',
@@ -17,6 +18,7 @@ const IconButton = _ref => {
17
18
  ...rest
18
19
  } = _ref;
19
20
  return /*#__PURE__*/jsxs("button", {
21
+ ref: ref,
20
22
  type: type,
21
23
  disabled: disabled || loading,
22
24
  "aria-busy": loading || undefined,
@@ -36,7 +38,8 @@ const IconButton = _ref => {
36
38
  children: counter
37
39
  })]
38
40
  });
39
- };
41
+ });
42
+ IconButton.displayName = 'IconButton';
40
43
 
41
44
  export { IconButton };
42
45
  //# sourceMappingURL=IconButton.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"IconButton.mjs","sources":["../../../src/icon-button/IconButton.tsx"],"sourcesContent":["import type { ButtonHTMLAttributes, ReactNode } from 'react'\n\nimport cn from 'classnames'\n\nimport { CounterSlot } from '../counter/CounterSlot'\nimport { IconLoaderCircle } from '../icons'\nimport styles from './IconButton.module.css'\n\nexport type IconButtonVariant = 'outline' | 'ghost'\n\nexport type IconButtonDataTestId = {\n root?: string\n icon?: string\n counter?: string\n}\n\nexport type IconButtonProps = Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n 'aria-label'\n> & {\n 'aria-label': string\n icon: ReactNode\n variant?: IconButtonVariant\n loading?: boolean\n /** Corner slot, aria-hidden: put the count into `aria-label`. */\n counter?: ReactNode\n dataTestId?: IconButtonDataTestId\n}\n\nexport const IconButton = ({\n className,\n type = 'button',\n variant = 'outline',\n loading = false,\n disabled = false,\n icon,\n counter,\n dataTestId,\n ...rest\n}: IconButtonProps) => (\n <button\n type={type}\n disabled={disabled || loading}\n aria-busy={loading || undefined}\n className={cn(\n styles.button,\n styles[variant],\n loading && styles.loading,\n className,\n )}\n data-testid={dataTestId?.root}\n {...rest}\n >\n {loading ? (\n <IconLoaderCircle className={styles.spinner} aria-hidden='true' />\n ) : (\n <span\n className={styles.icon}\n aria-hidden='true'\n data-testid={dataTestId?.icon}\n >\n {icon}\n </span>\n )}\n <CounterSlot dataTestId={dataTestId?.counter}>{counter}</CounterSlot>\n </button>\n)\n"],"names":["IconButton","_ref","className","type","variant","loading","disabled","icon","counter","dataTestId","rest","_jsxs","undefined","cn","styles","button","root","children","_jsx","IconLoaderCircle","spinner","CounterSlot"],"mappings":";;;;;;AA6BO,MAAMA,UAAU,GAAGC,IAAA,IAAA;EAAA,IAAC;IACzBC,SAAS;AACTC,IAAAA,IAAI,GAAG,QAAQ;AACfC,IAAAA,OAAO,GAAG,SAAS;AACnBC,IAAAA,OAAO,GAAG,KAAK;AACfC,IAAAA,QAAQ,GAAG,KAAK;IAChBC,IAAI;IACJC,OAAO;IACPC,UAAU;IACV,GAAGC,IAAAA;AACY,GAAC,GAAAT,IAAA,CAAA;AAAA,EAAA,oBAChBU,IAAA,CAAA,QAAA,EAAA;AACER,IAAAA,IAAI,EAAEA,IAAK;IACXG,QAAQ,EAAEA,QAAQ,IAAID,OAAQ;IAC9B,WAAWA,EAAAA,OAAO,IAAIO,SAAU;AAChCV,IAAAA,SAAS,EAAEW,EAAE,CACXC,MAAM,CAACC,MAAM,EACbD,MAAM,CAACV,OAAO,CAAC,EACfC,OAAO,IAAIS,MAAM,CAACT,OAAO,EACzBH,SACF,CAAE;IACF,aAAaO,EAAAA,UAAU,EAAEO,IAAK;AAAA,IAAA,GAC1BN,IAAI;AAAAO,IAAAA,QAAA,EAEPZ,CAAAA,OAAO,gBACNa,GAAA,CAACC,gBAAgB,EAAA;MAACjB,SAAS,EAAEY,MAAM,CAACM,OAAQ;MAAC,aAAY,EAAA,MAAA;KAAQ,CAAC,gBAElEF,GAAA,CAAA,MAAA,EAAA;MACEhB,SAAS,EAAEY,MAAM,CAACP,IAAK;AACvB,MAAA,aAAA,EAAY,MAAM;MAClB,aAAaE,EAAAA,UAAU,EAAEF,IAAK;AAAAU,MAAAA,QAAA,EAE7BV,IAAAA;AAAI,KACD,CACP,eACDW,GAAA,CAACG,WAAW,EAAA;MAACZ,UAAU,EAAEA,UAAU,EAAED,OAAQ;AAAAS,MAAAA,QAAA,EAAET,OAAAA;AAAO,KAAc,CAAC,CAAA;AAAA,GAC/D,CAAC,CAAA;AAAA;;;;"}
1
+ {"version":3,"file":"IconButton.mjs","sources":["../../../src/icon-button/IconButton.tsx"],"sourcesContent":["import { forwardRef, type ButtonHTMLAttributes, type ReactNode } from 'react'\n\nimport cn from 'classnames'\n\nimport { CounterSlot } from '../counter/CounterSlot'\nimport { IconLoaderCircle } from '../icons'\nimport styles from './IconButton.module.css'\n\nexport type IconButtonVariant = 'outline' | 'ghost' | 'surface'\n\nexport type IconButtonDataTestId = {\n root?: string\n icon?: string\n counter?: string\n}\n\nexport type IconButtonProps = Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n 'aria-label'\n> & {\n 'aria-label': string\n icon: ReactNode\n variant?: IconButtonVariant\n loading?: boolean\n /** Corner slot, aria-hidden: put the count into `aria-label`. */\n counter?: ReactNode\n dataTestId?: IconButtonDataTestId\n}\n\nexport const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(\n (\n {\n className,\n type = 'button',\n variant = 'outline',\n loading = false,\n disabled = false,\n icon,\n counter,\n dataTestId,\n ...rest\n },\n ref,\n ) => (\n <button\n ref={ref}\n type={type}\n disabled={disabled || loading}\n aria-busy={loading || undefined}\n className={cn(\n styles.button,\n styles[variant],\n loading && styles.loading,\n className,\n )}\n data-testid={dataTestId?.root}\n {...rest}\n >\n {loading ? (\n <IconLoaderCircle className={styles.spinner} aria-hidden='true' />\n ) : (\n <span\n className={styles.icon}\n aria-hidden='true'\n data-testid={dataTestId?.icon}\n >\n {icon}\n </span>\n )}\n <CounterSlot dataTestId={dataTestId?.counter}>{counter}</CounterSlot>\n </button>\n ),\n)\n\nIconButton.displayName = 'IconButton'\n"],"names":["IconButton","forwardRef","_ref","ref","className","type","variant","loading","disabled","icon","counter","dataTestId","rest","_jsxs","undefined","cn","styles","button","root","children","_jsx","IconLoaderCircle","spinner","CounterSlot","displayName"],"mappings":";;;;;;;AA6BO,MAAMA,UAAU,gBAAGC,UAAU,CAClC,CAAAC,IAAA,EAYEC,GAAG,KAAA;EAAA,IAXH;IACEC,SAAS;AACTC,IAAAA,IAAI,GAAG,QAAQ;AACfC,IAAAA,OAAO,GAAG,SAAS;AACnBC,IAAAA,OAAO,GAAG,KAAK;AACfC,IAAAA,QAAQ,GAAG,KAAK;IAChBC,IAAI;IACJC,OAAO;IACPC,UAAU;IACV,GAAGC,IAAAA;AACL,GAAC,GAAAV,IAAA,CAAA;AAAA,EAAA,oBAGDW,IAAA,CAAA,QAAA,EAAA;AACEV,IAAAA,GAAG,EAAEA,GAAI;AACTE,IAAAA,IAAI,EAAEA,IAAK;IACXG,QAAQ,EAAEA,QAAQ,IAAID,OAAQ;IAC9B,WAAWA,EAAAA,OAAO,IAAIO,SAAU;AAChCV,IAAAA,SAAS,EAAEW,EAAE,CACXC,MAAM,CAACC,MAAM,EACbD,MAAM,CAACV,OAAO,CAAC,EACfC,OAAO,IAAIS,MAAM,CAACT,OAAO,EACzBH,SACF,CAAE;IACF,aAAaO,EAAAA,UAAU,EAAEO,IAAK;AAAA,IAAA,GAC1BN,IAAI;AAAAO,IAAAA,QAAA,EAEPZ,CAAAA,OAAO,gBACNa,GAAA,CAACC,gBAAgB,EAAA;MAACjB,SAAS,EAAEY,MAAM,CAACM,OAAQ;MAAC,aAAY,EAAA,MAAA;KAAQ,CAAC,gBAElEF,GAAA,CAAA,MAAA,EAAA;MACEhB,SAAS,EAAEY,MAAM,CAACP,IAAK;AACvB,MAAA,aAAA,EAAY,MAAM;MAClB,aAAaE,EAAAA,UAAU,EAAEF,IAAK;AAAAU,MAAAA,QAAA,EAE7BV,IAAAA;AAAI,KACD,CACP,eACDW,GAAA,CAACG,WAAW,EAAA;MAACZ,UAAU,EAAEA,UAAU,EAAED,OAAQ;AAAAS,MAAAA,QAAA,EAAET,OAAAA;AAAO,KAAc,CAAC,CAAA;AAAA,GAC/D,CAAC,CAAA;AAAA,CAEb,EAAC;AAEDV,UAAU,CAACwB,WAAW,GAAG,YAAY;;;;"}
@@ -1,4 +1,4 @@
1
- const styles = {"button":"IconButton-module_button__5QpG9","icon":"IconButton-module_icon__1WMNC","spinner":"IconButton-module_spinner__-fwrf","spin":"IconButton-module_spin__eNilo","outline":"IconButton-module_outline__91r6g","ghost":"IconButton-module_ghost__WYnGy","loading":"IconButton-module_loading__v67XX"};
1
+ const styles = {"button":"IconButton-module_button__5QpG9","icon":"IconButton-module_icon__1WMNC","spinner":"IconButton-module_spinner__-fwrf","spin":"IconButton-module_spin__eNilo","outline":"IconButton-module_outline__91r6g","surface":"IconButton-module_surface__GQ6lQ","ghost":"IconButton-module_ghost__WYnGy","loading":"IconButton-module_loading__v67XX"};
2
2
 
3
3
  export { styles as default };
4
4
  //# sourceMappingURL=IconButton.module.css.mjs.map