@gnome-ui/react 1.45.1 → 1.45.2

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 (574) hide show
  1. package/dist/components/AboutDialog/AboutDialog.cjs +1 -1
  2. package/dist/components/AboutDialog/AboutDialog.cjs.map +1 -1
  3. package/dist/components/AboutDialog/AboutDialog.d.ts +1 -1
  4. package/dist/components/AboutDialog/AboutDialog.js +2 -3
  5. package/dist/components/AboutDialog/AboutDialog.js.map +1 -1
  6. package/dist/components/AboutDialog/AboutDialog.module.css.cjs +1 -1
  7. package/dist/components/AboutDialog/AboutDialog.module.css.js +28 -29
  8. package/dist/components/AboutDialog.cjs +1 -1
  9. package/dist/components/ActionRow/ActionRow.cjs +1 -1
  10. package/dist/components/ActionRow/ActionRow.cjs.map +1 -1
  11. package/dist/components/ActionRow/ActionRow.d.ts +1 -1
  12. package/dist/components/ActionRow/ActionRow.js +2 -2
  13. package/dist/components/ActionRow/ActionRow.js.map +1 -1
  14. package/dist/components/ActionRow.cjs +1 -1
  15. package/dist/components/Avatar/Avatar.cjs +1 -1
  16. package/dist/components/Avatar/Avatar.cjs.map +1 -1
  17. package/dist/components/Avatar/Avatar.d.ts +1 -1
  18. package/dist/components/Avatar/Avatar.js +2 -2
  19. package/dist/components/Avatar/Avatar.js.map +1 -1
  20. package/dist/components/Avatar.cjs +1 -1
  21. package/dist/components/AvatarRotator/AvatarRotator.cjs +1 -1
  22. package/dist/components/AvatarRotator/AvatarRotator.cjs.map +1 -1
  23. package/dist/components/AvatarRotator/AvatarRotator.d.ts +1 -1
  24. package/dist/components/AvatarRotator/AvatarRotator.js +2 -2
  25. package/dist/components/AvatarRotator/AvatarRotator.js.map +1 -1
  26. package/dist/components/AvatarRotator.cjs +1 -1
  27. package/dist/components/Badge/Badge.cjs +1 -1
  28. package/dist/components/Badge/Badge.cjs.map +1 -1
  29. package/dist/components/Badge/Badge.d.ts +1 -1
  30. package/dist/components/Badge/Badge.js +2 -2
  31. package/dist/components/Badge/Badge.js.map +1 -1
  32. package/dist/components/Badge.cjs +1 -1
  33. package/dist/components/Banner/Banner.cjs +1 -1
  34. package/dist/components/Banner/Banner.cjs.map +1 -1
  35. package/dist/components/Banner/Banner.d.ts +1 -1
  36. package/dist/components/Banner/Banner.js +34 -36
  37. package/dist/components/Banner/Banner.js.map +1 -1
  38. package/dist/components/Banner/Banner.module.css.cjs +1 -1
  39. package/dist/components/Banner/Banner.module.css.js +11 -12
  40. package/dist/components/Banner.cjs +1 -1
  41. package/dist/components/Bin/Bin.cjs +1 -1
  42. package/dist/components/Bin/Bin.cjs.map +1 -1
  43. package/dist/components/Bin/Bin.d.ts +1 -1
  44. package/dist/components/Bin/Bin.js +4 -6
  45. package/dist/components/Bin/Bin.js.map +1 -1
  46. package/dist/components/Bin.cjs +1 -1
  47. package/dist/components/Blockquote/Blockquote.cjs +1 -1
  48. package/dist/components/Blockquote/Blockquote.cjs.map +1 -1
  49. package/dist/components/Blockquote/Blockquote.d.ts +1 -1
  50. package/dist/components/Blockquote/Blockquote.js +24 -26
  51. package/dist/components/Blockquote/Blockquote.js.map +1 -1
  52. package/dist/components/Blockquote.cjs +1 -1
  53. package/dist/components/BottomSheet/BottomSheet.cjs +1 -1
  54. package/dist/components/BottomSheet/BottomSheet.cjs.map +1 -1
  55. package/dist/components/BottomSheet/BottomSheet.d.ts +1 -1
  56. package/dist/components/BottomSheet/BottomSheet.js +2 -3
  57. package/dist/components/BottomSheet/BottomSheet.js.map +1 -1
  58. package/dist/components/BottomSheet/BottomSheet.module.css.cjs +1 -1
  59. package/dist/components/BottomSheet/BottomSheet.module.css.js +8 -9
  60. package/dist/components/BottomSheet.cjs +1 -1
  61. package/dist/components/Box/Box.cjs +1 -1
  62. package/dist/components/Box/Box.cjs.map +1 -1
  63. package/dist/components/Box/Box.d.ts +1 -1
  64. package/dist/components/Box/Box.js +2 -2
  65. package/dist/components/Box/Box.js.map +1 -1
  66. package/dist/components/Box.cjs +1 -1
  67. package/dist/components/BoxedList/BoxedList.cjs +1 -1
  68. package/dist/components/BoxedList/BoxedList.cjs.map +1 -1
  69. package/dist/components/BoxedList/BoxedList.d.ts +1 -1
  70. package/dist/components/BoxedList/BoxedList.js +2 -2
  71. package/dist/components/BoxedList/BoxedList.js.map +1 -1
  72. package/dist/components/BoxedList.cjs +1 -1
  73. package/dist/components/BreakpointBin/BreakpointBin.cjs +1 -1
  74. package/dist/components/BreakpointBin/BreakpointBin.cjs.map +1 -1
  75. package/dist/components/BreakpointBin/BreakpointBin.d.ts +1 -1
  76. package/dist/components/BreakpointBin/BreakpointBin.js +2 -2
  77. package/dist/components/BreakpointBin/BreakpointBin.js.map +1 -1
  78. package/dist/components/BreakpointBin.cjs +1 -1
  79. package/dist/components/Button/Button.cjs +1 -1
  80. package/dist/components/Button/Button.cjs.map +1 -1
  81. package/dist/components/Button/Button.js.map +1 -1
  82. package/dist/components/Button.cjs +1 -1
  83. package/dist/components/ButtonContent/ButtonContent.cjs +1 -1
  84. package/dist/components/ButtonContent/ButtonContent.cjs.map +1 -1
  85. package/dist/components/ButtonContent/ButtonContent.d.ts +1 -1
  86. package/dist/components/ButtonContent/ButtonContent.js +24 -26
  87. package/dist/components/ButtonContent/ButtonContent.js.map +1 -1
  88. package/dist/components/ButtonContent.cjs +1 -1
  89. package/dist/components/ButtonRow/ButtonRow.cjs +1 -1
  90. package/dist/components/ButtonRow/ButtonRow.cjs.map +1 -1
  91. package/dist/components/ButtonRow/ButtonRow.d.ts +1 -1
  92. package/dist/components/ButtonRow/ButtonRow.js +22 -24
  93. package/dist/components/ButtonRow/ButtonRow.js.map +1 -1
  94. package/dist/components/ButtonRow.cjs +1 -1
  95. package/dist/components/Card/Card.cjs +1 -1
  96. package/dist/components/Card/Card.cjs.map +1 -1
  97. package/dist/components/Card/Card.d.ts +1 -1
  98. package/dist/components/Card/Card.js +10 -12
  99. package/dist/components/Card/Card.js.map +1 -1
  100. package/dist/components/Card/Card.module.css.cjs +1 -1
  101. package/dist/components/Card/Card.module.css.js +4 -5
  102. package/dist/components/Card.cjs +1 -1
  103. package/dist/components/Carousel/Carousel.cjs +1 -1
  104. package/dist/components/Carousel/Carousel.cjs.map +1 -1
  105. package/dist/components/Carousel/Carousel.d.ts +3 -3
  106. package/dist/components/Carousel/Carousel.js +28 -34
  107. package/dist/components/Carousel/Carousel.js.map +1 -1
  108. package/dist/components/Carousel.cjs +1 -1
  109. package/dist/components/CheckRow/CheckRow.cjs +1 -1
  110. package/dist/components/CheckRow/CheckRow.cjs.map +1 -1
  111. package/dist/components/CheckRow/CheckRow.d.ts +1 -1
  112. package/dist/components/CheckRow/CheckRow.js +7 -7
  113. package/dist/components/CheckRow/CheckRow.js.map +1 -1
  114. package/dist/components/CheckRow.cjs +1 -1
  115. package/dist/components/Checkbox/Checkbox.cjs +1 -1
  116. package/dist/components/Checkbox/Checkbox.cjs.map +1 -1
  117. package/dist/components/Checkbox/Checkbox.d.ts +1 -1
  118. package/dist/components/Checkbox/Checkbox.js +2 -2
  119. package/dist/components/Checkbox/Checkbox.js.map +1 -1
  120. package/dist/components/Checkbox.cjs +1 -1
  121. package/dist/components/Chip/Chip.cjs +1 -1
  122. package/dist/components/Chip/Chip.cjs.map +1 -1
  123. package/dist/components/Chip/Chip.d.ts +1 -1
  124. package/dist/components/Chip/Chip.js +2 -2
  125. package/dist/components/Chip/Chip.js.map +1 -1
  126. package/dist/components/Chip.cjs +1 -1
  127. package/dist/components/Clamp/Clamp.cjs +1 -1
  128. package/dist/components/Clamp/Clamp.cjs.map +1 -1
  129. package/dist/components/Clamp/Clamp.d.ts +1 -1
  130. package/dist/components/Clamp/Clamp.js +9 -11
  131. package/dist/components/Clamp/Clamp.js.map +1 -1
  132. package/dist/components/Clamp.cjs +1 -1
  133. package/dist/components/ColorPicker/ColorPicker.cjs +1 -1
  134. package/dist/components/ColorPicker/ColorPicker.cjs.map +1 -1
  135. package/dist/components/ColorPicker/ColorPicker.d.ts +2 -2
  136. package/dist/components/ColorPicker/ColorPicker.js +33 -37
  137. package/dist/components/ColorPicker/ColorPicker.js.map +1 -1
  138. package/dist/components/ColorPicker/ColorPicker.module.css.cjs +1 -1
  139. package/dist/components/ColorPicker/ColorPicker.module.css.js +9 -10
  140. package/dist/components/ColorPicker.cjs +1 -1
  141. package/dist/components/ColumnView/ColumnView.cjs +1 -1
  142. package/dist/components/ColumnView/ColumnView.cjs.map +1 -1
  143. package/dist/components/ColumnView/ColumnView.d.ts +1 -1
  144. package/dist/components/ColumnView/ColumnView.js +24 -28
  145. package/dist/components/ColumnView/ColumnView.js.map +1 -1
  146. package/dist/components/ColumnView.cjs +1 -1
  147. package/dist/components/ComboRow/ComboRow.cjs +1 -1
  148. package/dist/components/ComboRow/ComboRow.cjs.map +1 -1
  149. package/dist/components/ComboRow/ComboRow.d.ts +1 -1
  150. package/dist/components/ComboRow/ComboRow.js +2 -2
  151. package/dist/components/ComboRow/ComboRow.js.map +1 -1
  152. package/dist/components/ComboRow/ComboRow.module.css.cjs +1 -1
  153. package/dist/components/ComboRow/ComboRow.module.css.js +24 -25
  154. package/dist/components/ComboRow.cjs +1 -1
  155. package/dist/components/ContributionGraph/ContributionGraph.cjs +1 -1
  156. package/dist/components/ContributionGraph/ContributionGraph.cjs.map +1 -1
  157. package/dist/components/ContributionGraph/ContributionGraph.d.ts +1 -1
  158. package/dist/components/ContributionGraph/ContributionGraph.js +2 -2
  159. package/dist/components/ContributionGraph/ContributionGraph.js.map +1 -1
  160. package/dist/components/ContributionGraph.cjs +1 -1
  161. package/dist/components/CountDownTimer/CountDownTimer.cjs +1 -1
  162. package/dist/components/CountDownTimer/CountDownTimer.cjs.map +1 -1
  163. package/dist/components/CountDownTimer/CountDownTimer.d.ts +1 -1
  164. package/dist/components/CountDownTimer/CountDownTimer.js +2 -2
  165. package/dist/components/CountDownTimer/CountDownTimer.js.map +1 -1
  166. package/dist/components/CountDownTimer.cjs +1 -1
  167. package/dist/components/Dialog/Dialog.cjs +1 -1
  168. package/dist/components/Dialog/Dialog.cjs.map +1 -1
  169. package/dist/components/Dialog/Dialog.d.ts +1 -1
  170. package/dist/components/Dialog/Dialog.js +2 -2
  171. package/dist/components/Dialog/Dialog.js.map +1 -1
  172. package/dist/components/Dialog/Dialog.module.css.cjs +1 -1
  173. package/dist/components/Dialog/Dialog.module.css.js +8 -9
  174. package/dist/components/Dialog/dialogUtils.cjs +1 -1
  175. package/dist/components/Dialog/dialogUtils.cjs.map +1 -1
  176. package/dist/components/Dialog/dialogUtils.js.map +1 -1
  177. package/dist/components/Dialog.cjs +1 -1
  178. package/dist/components/Drawer/Drawer.cjs +1 -1
  179. package/dist/components/Drawer/Drawer.cjs.map +1 -1
  180. package/dist/components/Drawer/Drawer.d.ts +1 -1
  181. package/dist/components/Drawer/Drawer.js +2 -2
  182. package/dist/components/Drawer/Drawer.js.map +1 -1
  183. package/dist/components/Drawer/Drawer.module.css.cjs +1 -1
  184. package/dist/components/Drawer/Drawer.module.css.js +11 -12
  185. package/dist/components/Drawer.cjs +1 -1
  186. package/dist/components/Dropdown/Dropdown.cjs +1 -1
  187. package/dist/components/Dropdown/Dropdown.cjs.map +1 -1
  188. package/dist/components/Dropdown/Dropdown.d.ts +1 -1
  189. package/dist/components/Dropdown/Dropdown.js +2 -2
  190. package/dist/components/Dropdown/Dropdown.js.map +1 -1
  191. package/dist/components/Dropdown/Dropdown.module.css.cjs +1 -1
  192. package/dist/components/Dropdown/Dropdown.module.css.js +20 -21
  193. package/dist/components/Dropdown.cjs +1 -1
  194. package/dist/components/EntryRow/EntryRow.cjs +1 -1
  195. package/dist/components/EntryRow/EntryRow.cjs.map +1 -1
  196. package/dist/components/EntryRow/EntryRow.d.ts +1 -1
  197. package/dist/components/EntryRow/EntryRow.js +2 -2
  198. package/dist/components/EntryRow/EntryRow.js.map +1 -1
  199. package/dist/components/EntryRow.cjs +1 -1
  200. package/dist/components/ExpanderRow/ExpanderRow.cjs +1 -1
  201. package/dist/components/ExpanderRow/ExpanderRow.cjs.map +1 -1
  202. package/dist/components/ExpanderRow/ExpanderRow.d.ts +1 -1
  203. package/dist/components/ExpanderRow/ExpanderRow.js +2 -2
  204. package/dist/components/ExpanderRow/ExpanderRow.js.map +1 -1
  205. package/dist/components/ExpanderRow.cjs +1 -1
  206. package/dist/components/Footer/Footer.cjs +1 -1
  207. package/dist/components/Footer/Footer.cjs.map +1 -1
  208. package/dist/components/Footer/Footer.d.ts +1 -1
  209. package/dist/components/Footer/Footer.js +22 -24
  210. package/dist/components/Footer/Footer.js.map +1 -1
  211. package/dist/components/Footer.cjs +1 -1
  212. package/dist/components/Frame/Frame.cjs +1 -1
  213. package/dist/components/Frame/Frame.cjs.map +1 -1
  214. package/dist/components/Frame/Frame.d.ts +1 -1
  215. package/dist/components/Frame/Frame.js +5 -7
  216. package/dist/components/Frame/Frame.js.map +1 -1
  217. package/dist/components/Frame.cjs +1 -1
  218. package/dist/components/GnomeProvider/GnomeContext.cjs +1 -1
  219. package/dist/components/GnomeProvider/GnomeContext.cjs.map +1 -1
  220. package/dist/components/GnomeProvider/GnomeContext.js.map +1 -1
  221. package/dist/components/GnomeProvider/GnomeProvider.cjs +1 -1
  222. package/dist/components/GnomeProvider/GnomeProvider.cjs.map +1 -1
  223. package/dist/components/GnomeProvider/GnomeProvider.d.ts +1 -1
  224. package/dist/components/GnomeProvider/GnomeProvider.js +2 -2
  225. package/dist/components/GnomeProvider/GnomeProvider.js.map +1 -1
  226. package/dist/components/HeaderBar/HeaderBar.cjs +1 -1
  227. package/dist/components/HeaderBar/HeaderBar.cjs.map +1 -1
  228. package/dist/components/HeaderBar/HeaderBar.d.ts +1 -1
  229. package/dist/components/HeaderBar/HeaderBar.js +26 -28
  230. package/dist/components/HeaderBar/HeaderBar.js.map +1 -1
  231. package/dist/components/HeaderBar.cjs +1 -1
  232. package/dist/components/Icon/Icon.cjs +1 -1
  233. package/dist/components/Icon/Icon.cjs.map +1 -1
  234. package/dist/components/Icon/Icon.d.ts +1 -1
  235. package/dist/components/Icon/Icon.js +2 -2
  236. package/dist/components/Icon/Icon.js.map +1 -1
  237. package/dist/components/Icon.cjs +1 -1
  238. package/dist/components/IconButton/IconButton.cjs +1 -1
  239. package/dist/components/IconButton/IconButton.cjs.map +1 -1
  240. package/dist/components/IconButton/IconButton.js +4 -4
  241. package/dist/components/IconButton/IconButton.js.map +1 -1
  242. package/dist/components/IconButton.cjs +1 -1
  243. package/dist/components/InlineViewSwitcher/InlineViewSwitcher.cjs +1 -1
  244. package/dist/components/InlineViewSwitcher/InlineViewSwitcher.cjs.map +1 -1
  245. package/dist/components/InlineViewSwitcher/InlineViewSwitcher.d.ts +1 -1
  246. package/dist/components/InlineViewSwitcher/InlineViewSwitcher.js +2 -2
  247. package/dist/components/InlineViewSwitcher/InlineViewSwitcher.js.map +1 -1
  248. package/dist/components/InlineViewSwitcher/InlineViewSwitcherItem.cjs +1 -1
  249. package/dist/components/InlineViewSwitcher/InlineViewSwitcherItem.cjs.map +1 -1
  250. package/dist/components/InlineViewSwitcher/InlineViewSwitcherItem.d.ts +1 -1
  251. package/dist/components/InlineViewSwitcher/InlineViewSwitcherItem.js +2 -2
  252. package/dist/components/InlineViewSwitcher/InlineViewSwitcherItem.js.map +1 -1
  253. package/dist/components/InlineViewSwitcher.cjs +1 -1
  254. package/dist/components/Link/Link.cjs +1 -1
  255. package/dist/components/Link/Link.cjs.map +1 -1
  256. package/dist/components/Link/Link.d.ts +1 -1
  257. package/dist/components/Link/Link.js +2 -2
  258. package/dist/components/Link/Link.js.map +1 -1
  259. package/dist/components/Link.cjs +1 -1
  260. package/dist/components/LinkedGroup/LinkedGroup.cjs +1 -1
  261. package/dist/components/LinkedGroup/LinkedGroup.cjs.map +1 -1
  262. package/dist/components/LinkedGroup/LinkedGroup.d.ts +1 -1
  263. package/dist/components/LinkedGroup/LinkedGroup.js +9 -11
  264. package/dist/components/LinkedGroup/LinkedGroup.js.map +1 -1
  265. package/dist/components/LinkedGroup.cjs +1 -1
  266. package/dist/components/NavigationSplitView/NavigationSplitView.cjs +1 -1
  267. package/dist/components/NavigationSplitView/NavigationSplitView.cjs.map +1 -1
  268. package/dist/components/NavigationSplitView/NavigationSplitView.d.ts +1 -1
  269. package/dist/components/NavigationSplitView/NavigationSplitView.js +2 -2
  270. package/dist/components/NavigationSplitView/NavigationSplitView.js.map +1 -1
  271. package/dist/components/NavigationSplitView.cjs +1 -1
  272. package/dist/components/NavigationView/NavigationView.cjs +1 -1
  273. package/dist/components/NavigationView/NavigationView.cjs.map +1 -1
  274. package/dist/components/NavigationView/NavigationView.d.ts +2 -2
  275. package/dist/components/NavigationView/NavigationView.js +3 -4
  276. package/dist/components/NavigationView/NavigationView.js.map +1 -1
  277. package/dist/components/NavigationView/NavigationView.module.css.cjs +1 -1
  278. package/dist/components/NavigationView/NavigationView.module.css.js +9 -10
  279. package/dist/components/NavigationView.cjs +1 -1
  280. package/dist/components/OverlaySplitView/OverlaySplitView.cjs +1 -1
  281. package/dist/components/OverlaySplitView/OverlaySplitView.cjs.map +1 -1
  282. package/dist/components/OverlaySplitView/OverlaySplitView.d.ts +1 -1
  283. package/dist/components/OverlaySplitView/OverlaySplitView.js +2 -2
  284. package/dist/components/OverlaySplitView/OverlaySplitView.js.map +1 -1
  285. package/dist/components/OverlaySplitView.cjs +1 -1
  286. package/dist/components/PasswordEntryRow/PasswordEntryRow.cjs +1 -1
  287. package/dist/components/PasswordEntryRow/PasswordEntryRow.cjs.map +1 -1
  288. package/dist/components/PasswordEntryRow/PasswordEntryRow.d.ts +1 -1
  289. package/dist/components/PasswordEntryRow/PasswordEntryRow.js +2 -2
  290. package/dist/components/PasswordEntryRow/PasswordEntryRow.js.map +1 -1
  291. package/dist/components/PasswordEntryRow.cjs +1 -1
  292. package/dist/components/PathBar/PathBar.cjs +1 -1
  293. package/dist/components/PathBar/PathBar.cjs.map +1 -1
  294. package/dist/components/PathBar/PathBar.d.ts +1 -1
  295. package/dist/components/PathBar/PathBar.js +48 -50
  296. package/dist/components/PathBar/PathBar.js.map +1 -1
  297. package/dist/components/PathBar.cjs +1 -1
  298. package/dist/components/Popover/Popover.cjs +1 -1
  299. package/dist/components/Popover/Popover.cjs.map +1 -1
  300. package/dist/components/Popover/Popover.d.ts +1 -1
  301. package/dist/components/Popover/Popover.js +5 -5
  302. package/dist/components/Popover/Popover.js.map +1 -1
  303. package/dist/components/Popover.cjs +1 -1
  304. package/dist/components/PreferencesDialog/PreferencesDialog.cjs +1 -1
  305. package/dist/components/PreferencesDialog/PreferencesDialog.cjs.map +1 -1
  306. package/dist/components/PreferencesDialog/PreferencesDialog.d.ts +1 -1
  307. package/dist/components/PreferencesDialog/PreferencesDialog.js +2 -2
  308. package/dist/components/PreferencesDialog/PreferencesDialog.js.map +1 -1
  309. package/dist/components/PreferencesDialog/PreferencesDialog.module.css.cjs +1 -1
  310. package/dist/components/PreferencesDialog/PreferencesDialog.module.css.js +18 -19
  311. package/dist/components/PreferencesDialog.cjs +1 -1
  312. package/dist/components/PreferencesGroup/PreferencesGroup.cjs +1 -1
  313. package/dist/components/PreferencesGroup/PreferencesGroup.cjs.map +1 -1
  314. package/dist/components/PreferencesGroup/PreferencesGroup.d.ts +1 -1
  315. package/dist/components/PreferencesGroup/PreferencesGroup.js +2 -2
  316. package/dist/components/PreferencesGroup/PreferencesGroup.js.map +1 -1
  317. package/dist/components/PreferencesGroup.cjs +1 -1
  318. package/dist/components/PreferencesPage/PreferencesPage.cjs +1 -1
  319. package/dist/components/PreferencesPage/PreferencesPage.cjs.map +1 -1
  320. package/dist/components/PreferencesPage/PreferencesPage.d.ts +1 -1
  321. package/dist/components/PreferencesPage/PreferencesPage.js +9 -11
  322. package/dist/components/PreferencesPage/PreferencesPage.js.map +1 -1
  323. package/dist/components/PreferencesPage.cjs +1 -1
  324. package/dist/components/ProgressBar/ProgressBar.cjs +1 -1
  325. package/dist/components/ProgressBar/ProgressBar.cjs.map +1 -1
  326. package/dist/components/ProgressBar/ProgressBar.d.ts +1 -1
  327. package/dist/components/ProgressBar/ProgressBar.js +2 -2
  328. package/dist/components/ProgressBar/ProgressBar.js.map +1 -1
  329. package/dist/components/ProgressBar.cjs +1 -1
  330. package/dist/components/RadioButton/RadioButton.cjs +1 -1
  331. package/dist/components/RadioButton/RadioButton.cjs.map +1 -1
  332. package/dist/components/RadioButton/RadioButton.d.ts +1 -1
  333. package/dist/components/RadioButton/RadioButton.js +5 -7
  334. package/dist/components/RadioButton/RadioButton.js.map +1 -1
  335. package/dist/components/RadioButton.cjs +1 -1
  336. package/dist/components/SearchBar/SearchBar.cjs +1 -1
  337. package/dist/components/SearchBar/SearchBar.cjs.map +1 -1
  338. package/dist/components/SearchBar/SearchBar.d.ts +1 -1
  339. package/dist/components/SearchBar/SearchBar.js +2 -2
  340. package/dist/components/SearchBar/SearchBar.js.map +1 -1
  341. package/dist/components/SearchBar.cjs +1 -1
  342. package/dist/components/SegmentedBar/SegmentedBar.cjs +1 -1
  343. package/dist/components/SegmentedBar/SegmentedBar.cjs.map +1 -1
  344. package/dist/components/SegmentedBar/SegmentedBar.js.map +1 -1
  345. package/dist/components/SegmentedBar.cjs +1 -1
  346. package/dist/components/Separator/Separator.cjs +1 -1
  347. package/dist/components/Separator/Separator.cjs.map +1 -1
  348. package/dist/components/Separator/Separator.d.ts +1 -1
  349. package/dist/components/Separator/Separator.js +2 -2
  350. package/dist/components/Separator/Separator.js.map +1 -1
  351. package/dist/components/Separator.cjs +1 -1
  352. package/dist/components/ShortcutLabel/ShortcutLabel.cjs +1 -1
  353. package/dist/components/ShortcutLabel/ShortcutLabel.cjs.map +1 -1
  354. package/dist/components/ShortcutLabel/ShortcutLabel.d.ts +1 -1
  355. package/dist/components/ShortcutLabel/ShortcutLabel.js +2 -3
  356. package/dist/components/ShortcutLabel/ShortcutLabel.js.map +1 -1
  357. package/dist/components/ShortcutLabel.cjs +1 -1
  358. package/dist/components/ShortcutsDialog/ShortcutsDialog.cjs +1 -1
  359. package/dist/components/ShortcutsDialog/ShortcutsDialog.cjs.map +1 -1
  360. package/dist/components/ShortcutsDialog/ShortcutsDialog.d.ts +1 -1
  361. package/dist/components/ShortcutsDialog/ShortcutsDialog.js +2 -3
  362. package/dist/components/ShortcutsDialog/ShortcutsDialog.js.map +1 -1
  363. package/dist/components/ShortcutsDialog/ShortcutsDialog.module.css.cjs +1 -1
  364. package/dist/components/ShortcutsDialog/ShortcutsDialog.module.css.js +21 -22
  365. package/dist/components/ShortcutsDialog.cjs +1 -1
  366. package/dist/components/Sidebar/Sidebar.cjs +1 -1
  367. package/dist/components/Sidebar/Sidebar.cjs.map +1 -1
  368. package/dist/components/Sidebar/Sidebar.d.ts +1 -1
  369. package/dist/components/Sidebar/Sidebar.js +2 -3
  370. package/dist/components/Sidebar/Sidebar.js.map +1 -1
  371. package/dist/components/Sidebar/Sidebar.module.css.cjs +1 -1
  372. package/dist/components/Sidebar/Sidebar.module.css.js +33 -34
  373. package/dist/components/Sidebar/SidebarItem.cjs +1 -1
  374. package/dist/components/Sidebar/SidebarItem.cjs.map +1 -1
  375. package/dist/components/Sidebar/SidebarItem.d.ts +1 -1
  376. package/dist/components/Sidebar/SidebarItem.js +16 -16
  377. package/dist/components/Sidebar/SidebarItem.js.map +1 -1
  378. package/dist/components/Sidebar/SidebarSection.cjs +1 -1
  379. package/dist/components/Sidebar/SidebarSection.cjs.map +1 -1
  380. package/dist/components/Sidebar/SidebarSection.js.map +1 -1
  381. package/dist/components/Sidebar.cjs +1 -1
  382. package/dist/components/Skeleton/Skeleton.cjs +1 -1
  383. package/dist/components/Skeleton/Skeleton.cjs.map +1 -1
  384. package/dist/components/Skeleton/Skeleton.d.ts +1 -1
  385. package/dist/components/Skeleton/Skeleton.js +9 -10
  386. package/dist/components/Skeleton/Skeleton.js.map +1 -1
  387. package/dist/components/Skeleton.cjs +1 -1
  388. package/dist/components/Slider/Slider.cjs +1 -1
  389. package/dist/components/Slider/Slider.cjs.map +1 -1
  390. package/dist/components/Slider/Slider.d.ts +1 -1
  391. package/dist/components/Slider/Slider.js +2 -2
  392. package/dist/components/Slider/Slider.js.map +1 -1
  393. package/dist/components/Slider.cjs +1 -1
  394. package/dist/components/SpinButton/SpinButton.cjs +1 -1
  395. package/dist/components/SpinButton/SpinButton.cjs.map +1 -1
  396. package/dist/components/SpinButton/SpinButton.d.ts +1 -1
  397. package/dist/components/SpinButton/SpinButton.js +2 -2
  398. package/dist/components/SpinButton/SpinButton.js.map +1 -1
  399. package/dist/components/SpinButton.cjs +1 -1
  400. package/dist/components/SpinRow/SpinRow.cjs +1 -1
  401. package/dist/components/SpinRow/SpinRow.cjs.map +1 -1
  402. package/dist/components/SpinRow/SpinRow.d.ts +1 -1
  403. package/dist/components/SpinRow/SpinRow.js +2 -2
  404. package/dist/components/SpinRow/SpinRow.js.map +1 -1
  405. package/dist/components/SpinRow.cjs +1 -1
  406. package/dist/components/Spinner/Spinner.cjs +1 -1
  407. package/dist/components/Spinner/Spinner.cjs.map +1 -1
  408. package/dist/components/Spinner/Spinner.d.ts +1 -1
  409. package/dist/components/Spinner/Spinner.js +2 -2
  410. package/dist/components/Spinner/Spinner.js.map +1 -1
  411. package/dist/components/Spinner.cjs +1 -1
  412. package/dist/components/SplitButton/SplitButton.cjs +1 -1
  413. package/dist/components/SplitButton/SplitButton.cjs.map +1 -1
  414. package/dist/components/SplitButton/SplitButton.d.ts +1 -1
  415. package/dist/components/SplitButton/SplitButton.js +2 -2
  416. package/dist/components/SplitButton/SplitButton.js.map +1 -1
  417. package/dist/components/SplitButton.cjs +1 -1
  418. package/dist/components/StatusBadge/StatusBadge.cjs +1 -1
  419. package/dist/components/StatusBadge/StatusBadge.cjs.map +1 -1
  420. package/dist/components/StatusBadge/StatusBadge.d.ts +1 -1
  421. package/dist/components/StatusBadge/StatusBadge.js +9 -11
  422. package/dist/components/StatusBadge/StatusBadge.js.map +1 -1
  423. package/dist/components/StatusBadge.cjs +1 -1
  424. package/dist/components/StatusPage/StatusPage.cjs +1 -1
  425. package/dist/components/StatusPage/StatusPage.cjs.map +1 -1
  426. package/dist/components/StatusPage/StatusPage.d.ts +1 -1
  427. package/dist/components/StatusPage/StatusPage.js +2 -2
  428. package/dist/components/StatusPage/StatusPage.js.map +1 -1
  429. package/dist/components/StatusPage.cjs +1 -1
  430. package/dist/components/Switch/Switch.cjs +1 -1
  431. package/dist/components/Switch/Switch.cjs.map +1 -1
  432. package/dist/components/Switch/Switch.d.ts +1 -1
  433. package/dist/components/Switch/Switch.js +6 -8
  434. package/dist/components/Switch/Switch.js.map +1 -1
  435. package/dist/components/Switch.cjs +1 -1
  436. package/dist/components/SwitchRow/SwitchRow.cjs +1 -1
  437. package/dist/components/SwitchRow/SwitchRow.cjs.map +1 -1
  438. package/dist/components/SwitchRow/SwitchRow.d.ts +1 -1
  439. package/dist/components/SwitchRow/SwitchRow.js +7 -7
  440. package/dist/components/SwitchRow/SwitchRow.js.map +1 -1
  441. package/dist/components/SwitchRow.cjs +1 -1
  442. package/dist/components/Tabs/TabBar.cjs +1 -1
  443. package/dist/components/Tabs/TabBar.cjs.map +1 -1
  444. package/dist/components/Tabs/TabBar.d.ts +1 -1
  445. package/dist/components/Tabs/TabBar.js +2 -2
  446. package/dist/components/Tabs/TabBar.js.map +1 -1
  447. package/dist/components/Tabs/TabItem.cjs +1 -1
  448. package/dist/components/Tabs/TabItem.cjs.map +1 -1
  449. package/dist/components/Tabs/TabItem.js.map +1 -1
  450. package/dist/components/Tabs/TabPanel.cjs +1 -1
  451. package/dist/components/Tabs/TabPanel.cjs.map +1 -1
  452. package/dist/components/Tabs/TabPanel.d.ts +1 -1
  453. package/dist/components/Tabs/TabPanel.js +8 -10
  454. package/dist/components/Tabs/TabPanel.js.map +1 -1
  455. package/dist/components/Tabs.cjs +1 -1
  456. package/dist/components/TerminalView/TerminalView.cjs +1 -1
  457. package/dist/components/TerminalView/TerminalView.cjs.map +1 -1
  458. package/dist/components/TerminalView/TerminalView.d.ts +1 -1
  459. package/dist/components/TerminalView/TerminalView.js +2 -2
  460. package/dist/components/TerminalView/TerminalView.js.map +1 -1
  461. package/dist/components/TerminalView.cjs +1 -1
  462. package/dist/components/Text/Text.cjs +1 -1
  463. package/dist/components/Text/Text.cjs.map +1 -1
  464. package/dist/components/Text/Text.d.ts +1 -1
  465. package/dist/components/Text/Text.js +10 -13
  466. package/dist/components/Text/Text.js.map +1 -1
  467. package/dist/components/Text/Text.module.css.cjs +1 -1
  468. package/dist/components/Text/Text.module.css.js +9 -10
  469. package/dist/components/Text.cjs +1 -1
  470. package/dist/components/TextField/TextField.cjs +1 -1
  471. package/dist/components/TextField/TextField.cjs.map +1 -1
  472. package/dist/components/TextField/TextField.d.ts +1 -1
  473. package/dist/components/TextField/TextField.js +2 -2
  474. package/dist/components/TextField/TextField.js.map +1 -1
  475. package/dist/components/TextField.cjs +1 -1
  476. package/dist/components/Timeline/Timeline.cjs +1 -1
  477. package/dist/components/Timeline/Timeline.cjs.map +1 -1
  478. package/dist/components/Timeline/Timeline.d.ts +1 -1
  479. package/dist/components/Timeline/Timeline.js +2 -2
  480. package/dist/components/Timeline/Timeline.js.map +1 -1
  481. package/dist/components/Timeline.cjs +1 -1
  482. package/dist/components/Toast/Toast.cjs +1 -1
  483. package/dist/components/Toast/Toast.cjs.map +1 -1
  484. package/dist/components/Toast/Toast.d.ts +1 -1
  485. package/dist/components/Toast/Toast.js +2 -2
  486. package/dist/components/Toast/Toast.js.map +1 -1
  487. package/dist/components/Toast/Toast.module.css.cjs +1 -1
  488. package/dist/components/Toast/Toast.module.css.js +10 -11
  489. package/dist/components/Toast/Toaster.cjs +1 -1
  490. package/dist/components/Toast/Toaster.cjs.map +1 -1
  491. package/dist/components/Toast/Toaster.d.ts +1 -1
  492. package/dist/components/Toast/Toaster.js +2 -2
  493. package/dist/components/Toast/Toaster.js.map +1 -1
  494. package/dist/components/Toast.cjs +1 -1
  495. package/dist/components/ToggleGroup/ToggleGroup.cjs +1 -1
  496. package/dist/components/ToggleGroup/ToggleGroup.cjs.map +1 -1
  497. package/dist/components/ToggleGroup/ToggleGroup.d.ts +1 -1
  498. package/dist/components/ToggleGroup/ToggleGroup.js +2 -2
  499. package/dist/components/ToggleGroup/ToggleGroup.js.map +1 -1
  500. package/dist/components/ToggleGroup/ToggleGroupItem.cjs +1 -1
  501. package/dist/components/ToggleGroup/ToggleGroupItem.cjs.map +1 -1
  502. package/dist/components/ToggleGroup/ToggleGroupItem.d.ts +1 -1
  503. package/dist/components/ToggleGroup/ToggleGroupItem.js +2 -2
  504. package/dist/components/ToggleGroup/ToggleGroupItem.js.map +1 -1
  505. package/dist/components/ToggleGroup.cjs +1 -1
  506. package/dist/components/Toolbar/Spacer.cjs +1 -1
  507. package/dist/components/Toolbar/Spacer.cjs.map +1 -1
  508. package/dist/components/Toolbar/Spacer.d.ts +1 -1
  509. package/dist/components/Toolbar/Spacer.js +5 -7
  510. package/dist/components/Toolbar/Spacer.js.map +1 -1
  511. package/dist/components/Toolbar/Toolbar.cjs +1 -1
  512. package/dist/components/Toolbar/Toolbar.cjs.map +1 -1
  513. package/dist/components/Toolbar/Toolbar.d.ts +1 -1
  514. package/dist/components/Toolbar/Toolbar.js +5 -7
  515. package/dist/components/Toolbar/Toolbar.js.map +1 -1
  516. package/dist/components/Toolbar.cjs +1 -1
  517. package/dist/components/ToolbarView/ToolbarView.cjs +1 -1
  518. package/dist/components/ToolbarView/ToolbarView.cjs.map +1 -1
  519. package/dist/components/ToolbarView/ToolbarView.d.ts +1 -1
  520. package/dist/components/ToolbarView/ToolbarView.js +18 -20
  521. package/dist/components/ToolbarView/ToolbarView.js.map +1 -1
  522. package/dist/components/ToolbarView.cjs +1 -1
  523. package/dist/components/Tooltip/Tooltip.cjs +1 -1
  524. package/dist/components/Tooltip/Tooltip.cjs.map +1 -1
  525. package/dist/components/Tooltip/Tooltip.d.ts +1 -1
  526. package/dist/components/Tooltip/Tooltip.js +2 -2
  527. package/dist/components/Tooltip/Tooltip.js.map +1 -1
  528. package/dist/components/Tooltip.cjs +1 -1
  529. package/dist/components/ViewSwitcher/ViewSwitcher.cjs +1 -1
  530. package/dist/components/ViewSwitcher/ViewSwitcher.cjs.map +1 -1
  531. package/dist/components/ViewSwitcher/ViewSwitcher.d.ts +1 -1
  532. package/dist/components/ViewSwitcher/ViewSwitcher.js +2 -2
  533. package/dist/components/ViewSwitcher/ViewSwitcher.js.map +1 -1
  534. package/dist/components/ViewSwitcher/ViewSwitcherItem.cjs +1 -1
  535. package/dist/components/ViewSwitcher/ViewSwitcherItem.cjs.map +1 -1
  536. package/dist/components/ViewSwitcher/ViewSwitcherItem.d.ts +1 -1
  537. package/dist/components/ViewSwitcher/ViewSwitcherItem.js +24 -26
  538. package/dist/components/ViewSwitcher/ViewSwitcherItem.js.map +1 -1
  539. package/dist/components/ViewSwitcher.cjs +1 -1
  540. package/dist/components/ViewSwitcherBar/ViewSwitcherBar.cjs +1 -1
  541. package/dist/components/ViewSwitcherBar/ViewSwitcherBar.cjs.map +1 -1
  542. package/dist/components/ViewSwitcherBar/ViewSwitcherBar.d.ts +1 -1
  543. package/dist/components/ViewSwitcherBar/ViewSwitcherBar.js +7 -9
  544. package/dist/components/ViewSwitcherBar/ViewSwitcherBar.js.map +1 -1
  545. package/dist/components/ViewSwitcherBar.cjs +1 -1
  546. package/dist/components/ViewSwitcherSidebar/ViewSwitcherSidebar.cjs +1 -1
  547. package/dist/components/ViewSwitcherSidebar/ViewSwitcherSidebar.cjs.map +1 -1
  548. package/dist/components/ViewSwitcherSidebar/ViewSwitcherSidebar.d.ts +1 -1
  549. package/dist/components/ViewSwitcherSidebar/ViewSwitcherSidebar.js +2 -2
  550. package/dist/components/ViewSwitcherSidebar/ViewSwitcherSidebar.js.map +1 -1
  551. package/dist/components/ViewSwitcherSidebar/ViewSwitcherSidebarItem.cjs +1 -1
  552. package/dist/components/ViewSwitcherSidebar/ViewSwitcherSidebarItem.cjs.map +1 -1
  553. package/dist/components/ViewSwitcherSidebar/ViewSwitcherSidebarItem.d.ts +1 -1
  554. package/dist/components/ViewSwitcherSidebar/ViewSwitcherSidebarItem.js +2 -2
  555. package/dist/components/ViewSwitcherSidebar/ViewSwitcherSidebarItem.js.map +1 -1
  556. package/dist/components/ViewSwitcherSidebar.cjs +1 -1
  557. package/dist/components/WindowTitle/WindowTitle.cjs +1 -1
  558. package/dist/components/WindowTitle/WindowTitle.cjs.map +1 -1
  559. package/dist/components/WindowTitle/WindowTitle.d.ts +1 -1
  560. package/dist/components/WindowTitle/WindowTitle.js +11 -13
  561. package/dist/components/WindowTitle/WindowTitle.js.map +1 -1
  562. package/dist/components/WindowTitle.cjs +1 -1
  563. package/dist/components/WrapBox/WrapBox.cjs +1 -1
  564. package/dist/components/WrapBox/WrapBox.cjs.map +1 -1
  565. package/dist/components/WrapBox/WrapBox.d.ts +1 -1
  566. package/dist/components/WrapBox/WrapBox.js +5 -5
  567. package/dist/components/WrapBox/WrapBox.js.map +1 -1
  568. package/dist/components/WrapBox.cjs +1 -1
  569. package/dist/hooks/useBreakpoint.cjs +1 -1
  570. package/dist/hooks/useBreakpoint.cjs.map +1 -1
  571. package/dist/hooks/useBreakpoint.js.map +1 -1
  572. package/dist/hooks.cjs +1 -1
  573. package/dist/index.cjs +1 -1
  574. package/package.json +2 -2
@@ -1,2 +1,2 @@
1
- const e=require(`./ComboRow.module.css.cjs`);let t=require(`react`),n=require(`react/jsx-runtime`);function r({title:r,subtitle:i,leading:a,options:o,value:s,defaultValue:c,onValueChange:l,disabled:u=!1,className:d,...f}){let p=s!==void 0,[m,h]=(0,t.useState)(c),g=p?s:m,[_,v]=(0,t.useState)(!1),[y,b]=(0,t.useState)(-1),[x,S]=(0,t.useState)(!1),C=(0,t.useId)(),w=(0,t.useId)(),T=(0,t.useRef)(null),E=(0,t.useRef)(null),D=o.find(e=>e.value===g),O=(0,t.useCallback)(()=>{if(!T.current)return;let e=T.current.getBoundingClientRect(),t=window.innerHeight-e.bottom,n=Math.min(o.length*44+8,260);S(t<n&&e.top>n)},[o.length]),k=(0,t.useCallback)(()=>{if(u)return;O(),v(!0);let e=o.findIndex(e=>e.value===g&&!e.disabled);b(e>=0?e:o.findIndex(e=>!e.disabled))},[u,O,o,g]),A=(0,t.useCallback)(()=>{v(!1),b(-1),T.current?.focus()},[]),j=(0,t.useCallback)(e=>{e.disabled||(p||h(e.value),l?.(e.value),A())},[p,l,A]);(0,t.useEffect)(()=>{!_||y<0||!E.current||E.current.children[y]?.scrollIntoView({block:`nearest`})},[y,_]),(0,t.useEffect)(()=>{if(!_)return;let e=e=>{!T.current?.contains(e.target)&&!E.current?.contains(e.target)&&A()};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[_,A]);let M=(0,t.useCallback)(e=>{switch(e.key){case`Enter`:case` `:case`ArrowDown`:e.preventDefault(),k();break;case`ArrowUp`:e.preventDefault(),O(),v(!0),b(o.reduce((e,t,n)=>t.disabled?e:n,-1));break}},[k,O,o]),N=(0,t.useCallback)(e=>{let t=o.map((e,t)=>({o:e,i:t})).filter(({o:e})=>!e.disabled).map(({i:e})=>e),n=t.indexOf(y);switch(e.key){case`ArrowDown`:{e.preventDefault();let r=t[Math.min(n+1,t.length-1)];b(r??y);break}case`ArrowUp`:{e.preventDefault();let r=t[Math.max(n-1,0)];b(r??y);break}case`Home`:e.preventDefault(),b(t[0]??-1);break;case`End`:e.preventDefault(),b(t[t.length-1]??-1);break;case`Enter`:case` `:e.preventDefault(),y>=0&&j(o[y]);break;case`Escape`:case`Tab`:A();break}},[o,y,j,A]);return(0,n.jsxs)(`div`,{className:[e.default.row,u?e.default.disabled:null,d].filter(Boolean).join(` `),...f,children:[a&&(0,n.jsx)(`span`,{className:e.default.leading,children:a}),(0,n.jsxs)(`span`,{className:e.default.content,children:[(0,n.jsx)(`span`,{className:e.default.title,children:r}),i&&(0,n.jsx)(`span`,{className:e.default.subtitle,children:i})]}),(0,n.jsxs)(`div`,{className:e.default.comboWrap,children:[(0,n.jsxs)(`button`,{ref:T,id:C,type:`button`,role:`combobox`,"aria-haspopup":`listbox`,"aria-expanded":_,"aria-controls":w,"aria-activedescendant":_&&y>=0?`${w}-opt-${y}`:void 0,disabled:u,className:[e.default.trigger,_?e.default.triggerOpen:null].filter(Boolean).join(` `),onClick:()=>_?A():k(),onKeyDown:M,children:[(0,n.jsx)(`span`,{className:[e.default.triggerLabel,D?null:e.default.placeholder].filter(Boolean).join(` `),children:D?.label??`—`}),(0,n.jsx)(`svg`,{className:[e.default.chevron,_?e.default.chevronOpen:null].filter(Boolean).join(` `),width:`16`,height:`16`,viewBox:`0 0 16 16`,"aria-hidden":`true`,focusable:`false`,children:(0,n.jsx)(`path`,{d:`M4 6l4 4 4-4`,fill:`none`,stroke:`currentColor`,strokeWidth:`1.5`,strokeLinecap:`round`,strokeLinejoin:`round`})})]}),_&&(0,n.jsx)(`ul`,{ref:E,id:w,"aria-labelledby":C,tabIndex:-1,className:[e.default.list,x?e.default.listUp:e.default.listDown].filter(Boolean).join(` `),onKeyDown:N,children:o.map((t,r)=>(0,n.jsxs)(`li`,{id:`${w}-opt-${r}`,"aria-selected":t.value===g,"aria-disabled":t.disabled,className:[e.default.option,t.value===g?e.default.optionSelected:null,r===y?e.default.optionActive:null,t.disabled?e.default.optionDisabled:null].filter(Boolean).join(` `),onMouseEnter:()=>!t.disabled&&b(r),onClick:()=>j(t),children:[(0,n.jsx)(`span`,{className:e.default.optionLabel,children:t.label}),t.value===g&&(0,n.jsx)(`svg`,{width:`16`,height:`16`,viewBox:`0 0 16 16`,"aria-hidden":`true`,focusable:`false`,className:e.default.checkIcon,children:(0,n.jsx)(`path`,{d:`M3 8l4 4 6-6`,fill:`none`,stroke:`currentColor`,strokeWidth:`1.75`,strokeLinecap:`round`,strokeLinejoin:`round`})})]},t.value))})]})]})}exports.ComboRow=r;
1
+ const e=require("./ComboRow.module.css.cjs");let t=require("react"),n=require("react/jsx-runtime");var r=({title:r,subtitle:i,leading:a,options:o,value:s,defaultValue:c,onValueChange:l,disabled:u=!1,className:d,...f})=>{let p=s!==void 0,[m,h]=(0,t.useState)(c),g=p?s:m,[_,v]=(0,t.useState)(!1),[y,b]=(0,t.useState)(-1),[x,S]=(0,t.useState)(!1),C=(0,t.useId)(),w=(0,t.useId)(),T=(0,t.useRef)(null),E=(0,t.useRef)(null),D=o.find(e=>e.value===g),O=(0,t.useCallback)(()=>{if(!T.current)return;let e=T.current.getBoundingClientRect(),t=window.innerHeight-e.bottom,n=Math.min(o.length*44+8,260);S(t<n&&e.top>n)},[o.length]),k=(0,t.useCallback)(()=>{if(u)return;O(),v(!0);let e=o.findIndex(e=>e.value===g&&!e.disabled);b(e>=0?e:o.findIndex(e=>!e.disabled))},[u,O,o,g]),A=(0,t.useCallback)(()=>{v(!1),b(-1),T.current?.focus()},[]),j=(0,t.useCallback)(e=>{e.disabled||(p||h(e.value),l?.(e.value),A())},[p,l,A]);(0,t.useEffect)(()=>{!_||y<0||!E.current||E.current.children[y]?.scrollIntoView({block:`nearest`})},[y,_]),(0,t.useEffect)(()=>{if(!_)return;let e=e=>{!T.current?.contains(e.target)&&!E.current?.contains(e.target)&&A()};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[_,A]);let M=(0,t.useCallback)(e=>{switch(e.key){case`Enter`:case` `:case`ArrowDown`:e.preventDefault(),k();break;case`ArrowUp`:e.preventDefault(),O(),v(!0),b(o.reduce((e,t,n)=>t.disabled?e:n,-1));break}},[k,O,o]),N=(0,t.useCallback)(e=>{let t=o.map((e,t)=>({o:e,i:t})).filter(({o:e})=>!e.disabled).map(({i:e})=>e),n=t.indexOf(y);switch(e.key){case`ArrowDown`:{e.preventDefault();let r=t[Math.min(n+1,t.length-1)];b(r??y);break}case`ArrowUp`:{e.preventDefault();let r=t[Math.max(n-1,0)];b(r??y);break}case`Home`:e.preventDefault(),b(t[0]??-1);break;case`End`:e.preventDefault(),b(t[t.length-1]??-1);break;case`Enter`:case` `:e.preventDefault(),y>=0&&j(o[y]);break;case`Escape`:case`Tab`:A();break}},[o,y,j,A]);return(0,n.jsxs)(`div`,{className:[e.default.row,u?e.default.disabled:null,d].filter(Boolean).join(` `),...f,children:[a&&(0,n.jsx)(`span`,{className:e.default.leading,children:a}),(0,n.jsxs)(`span`,{className:e.default.content,children:[(0,n.jsx)(`span`,{className:e.default.title,children:r}),i&&(0,n.jsx)(`span`,{className:e.default.subtitle,children:i})]}),(0,n.jsxs)(`div`,{className:e.default.comboWrap,children:[(0,n.jsxs)(`button`,{ref:T,id:C,type:`button`,role:`combobox`,"aria-haspopup":`listbox`,"aria-expanded":_,"aria-controls":w,"aria-activedescendant":_&&y>=0?`${w}-opt-${y}`:void 0,disabled:u,className:[e.default.trigger,_?e.default.triggerOpen:null].filter(Boolean).join(` `),onClick:()=>_?A():k(),onKeyDown:M,children:[(0,n.jsx)(`span`,{className:[e.default.triggerLabel,D?null:e.default.placeholder].filter(Boolean).join(` `),children:D?.label??`—`}),(0,n.jsx)(`svg`,{className:[e.default.chevron,_?e.default.chevronOpen:null].filter(Boolean).join(` `),width:`16`,height:`16`,viewBox:`0 0 16 16`,"aria-hidden":`true`,focusable:`false`,children:(0,n.jsx)(`path`,{d:`M4 6l4 4 4-4`,fill:`none`,stroke:`currentColor`,strokeWidth:`1.5`,strokeLinecap:`round`,strokeLinejoin:`round`})})]}),_&&(0,n.jsx)(`ul`,{ref:E,id:w,"aria-labelledby":C,tabIndex:-1,className:[e.default.list,x?e.default.listUp:e.default.listDown].filter(Boolean).join(` `),onKeyDown:N,children:o.map((t,r)=>(0,n.jsxs)(`li`,{id:`${w}-opt-${r}`,"aria-selected":t.value===g,"aria-disabled":t.disabled,className:[e.default.option,t.value===g?e.default.optionSelected:null,r===y?e.default.optionActive:null,t.disabled?e.default.optionDisabled:null].filter(Boolean).join(` `),onMouseEnter:()=>!t.disabled&&b(r),onClick:()=>j(t),children:[(0,n.jsx)(`span`,{className:e.default.optionLabel,children:t.label}),t.value===g&&(0,n.jsx)(`svg`,{width:`16`,height:`16`,viewBox:`0 0 16 16`,"aria-hidden":`true`,focusable:`false`,className:e.default.checkIcon,children:(0,n.jsx)(`path`,{d:`M3 8l4 4 6-6`,fill:`none`,stroke:`currentColor`,strokeWidth:`1.75`,strokeLinecap:`round`,strokeLinejoin:`round`})})]},t.value))})]})]})};exports.ComboRow=r;
2
2
  //# sourceMappingURL=ComboRow.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ComboRow.cjs","names":[],"sources":["../../../src/components/ComboRow/ComboRow.tsx"],"sourcesContent":["import {\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n} from 'react';\n\nimport styles from './ComboRow.module.css';\n\nexport interface ComboRowOption<V extends string = string> {\n value: V;\n label: string;\n disabled?: boolean;\n}\n\nexport interface ComboRowProps<V extends string = string>\n extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {\n /** Primary label. */\n title: string;\n /** Secondary line below the title. */\n subtitle?: string;\n /** Icon or image placed at the leading edge. */\n leading?: ReactNode;\n /** The list of selectable options. */\n options: ComboRowOption<V>[];\n /** The currently selected value (controlled). */\n value?: V;\n /** Initial value when uncontrolled. */\n defaultValue?: V;\n /** Called when the user selects an option. */\n onValueChange?: (value: V) => void;\n /** Disables the row. */\n disabled?: boolean;\n}\n\n/**\n * Settings row with an inline combo selector at the trailing edge.\n *\n * Mirrors `AdwComboRow` — a standard `ActionRow` layout with a dropdown\n * for choosing among a set of options. The dropdown opens inline in the row\n * and follows the same keyboard patterns as the standalone `Dropdown`.\n *\n * @see https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.ComboRow.html\n */\nexport function ComboRow<V extends string = string>({\n title,\n subtitle,\n leading,\n options,\n value: controlledValue,\n defaultValue,\n onValueChange,\n disabled = false,\n className,\n ...props\n}: ComboRowProps<V>) {\n const isControlled = controlledValue !== undefined;\n const [uncontrolledValue, setUncontrolledValue] = useState<V | undefined>(defaultValue);\n const value = isControlled ? controlledValue : uncontrolledValue;\n\n const [open, setOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState(-1);\n const [flipUp, setFlipUp] = useState(false);\n\n const triggerId = useId();\n const listboxId = useId();\n const triggerRef = useRef<HTMLButtonElement>(null);\n const listRef = useRef<HTMLUListElement>(null);\n\n const selected = options.find((o) => o.value === value);\n\n const computeFlip = useCallback(() => {\n if (!triggerRef.current) {\n return;\n }\n\n const rect = triggerRef.current.getBoundingClientRect();\n const spaceBelow = window.innerHeight - rect.bottom;\n const listH = Math.min(options.length * 44 + 8, 260);\n\n setFlipUp(spaceBelow < listH && rect.top > listH);\n }, [options.length]);\n\n const openList = useCallback(() => {\n if (disabled) {\n return;\n }\n\n computeFlip();\n setOpen(true);\n const idx = options.findIndex((o) => o.value === value && !o.disabled);\n\n setActiveIndex(idx >= 0 ? idx : options.findIndex((o) => !o.disabled));\n }, [disabled, computeFlip, options, value]);\n\n const closeList = useCallback(() => {\n setOpen(false);\n setActiveIndex(-1);\n triggerRef.current?.focus();\n }, []);\n\n const selectOption = useCallback(\n (opt: ComboRowOption<V>) => {\n if (opt.disabled) {\n return;\n }\n\n if (!isControlled) {\n setUncontrolledValue(opt.value);\n }\n\n onValueChange?.(opt.value);\n closeList();\n },\n [isControlled, onValueChange, closeList],\n );\n\n useEffect(() => {\n if (!open || activeIndex < 0 || !listRef.current) {\n return;\n }\n\n const item = listRef.current.children[activeIndex] as HTMLElement | undefined;\n\n item?.scrollIntoView({ block: 'nearest' });\n }, [activeIndex, open]);\n\n useEffect(() => {\n if (!open) {\n return;\n }\n\n const handler = (e: MouseEvent) => {\n if (\n !triggerRef.current?.contains(e.target as Node) &&\n !listRef.current?.contains(e.target as Node)\n ) {\n closeList();\n }\n };\n\n document.addEventListener('mousedown', handler);\n\n return () => document.removeEventListener('mousedown', handler);\n }, [open, closeList]);\n\n const handleTriggerKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n switch (e.key) {\n case 'Enter':\n case ' ':\n case 'ArrowDown':\n e.preventDefault();\n openList();\n break;\n case 'ArrowUp':\n e.preventDefault();\n computeFlip();\n setOpen(true);\n setActiveIndex(options.reduce((last, o, i) => (!o.disabled ? i : last), -1));\n break;\n }\n },\n [openList, computeFlip, options],\n );\n\n const handleListKeyDown = useCallback(\n (e: KeyboardEvent<HTMLUListElement>) => {\n const enabledIndexes = options\n .map((o, i) => ({ o, i }))\n .filter(({ o }) => !o.disabled)\n .map(({ i }) => i);\n const currentPos = enabledIndexes.indexOf(activeIndex);\n\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault();\n const next = enabledIndexes[Math.min(currentPos + 1, enabledIndexes.length - 1)];\n\n setActiveIndex(next ?? activeIndex);\n break;\n }\n case 'ArrowUp': {\n e.preventDefault();\n const prev = enabledIndexes[Math.max(currentPos - 1, 0)];\n\n setActiveIndex(prev ?? activeIndex);\n break;\n }\n case 'Home':\n e.preventDefault();\n setActiveIndex(enabledIndexes[0] ?? -1);\n break;\n case 'End':\n e.preventDefault();\n setActiveIndex(enabledIndexes[enabledIndexes.length - 1] ?? -1);\n break;\n case 'Enter':\n case ' ': {\n e.preventDefault();\n if (activeIndex >= 0) {\n selectOption(options[activeIndex]);\n }\n\n break;\n }\n case 'Escape':\n case 'Tab':\n closeList();\n break;\n }\n },\n [options, activeIndex, selectOption, closeList],\n );\n\n return (\n <div\n className={[styles.row, disabled ? styles.disabled : null, className]\n .filter(Boolean)\n .join(' ')}\n {...props}\n >\n {leading && <span className={styles.leading}>{leading}</span>}\n\n <span className={styles.content}>\n <span className={styles.title}>{title}</span>\n {subtitle && <span className={styles.subtitle}>{subtitle}</span>}\n </span>\n\n {/* Combo trigger button */}\n <div className={styles.comboWrap}>\n <button\n ref={triggerRef}\n id={triggerId}\n type=\"button\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-controls={listboxId}\n aria-activedescendant={\n open && activeIndex >= 0 ? `${listboxId}-opt-${activeIndex}` : undefined\n }\n disabled={disabled}\n className={[styles.trigger, open ? styles.triggerOpen : null].filter(Boolean).join(' ')}\n onClick={() => (open ? closeList() : openList())}\n onKeyDown={handleTriggerKeyDown}\n >\n <span\n className={[styles.triggerLabel, !selected ? styles.placeholder : null]\n .filter(Boolean)\n .join(' ')}\n >\n {selected?.label ?? '—'}\n </span>\n <svg\n className={[styles.chevron, open ? styles.chevronOpen : null].filter(Boolean).join(' ')}\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path\n d=\"M4 6l4 4 4-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </button>\n\n {open && (\n <ul\n ref={listRef}\n id={listboxId}\n aria-labelledby={triggerId}\n tabIndex={-1}\n className={[styles.list, flipUp ? styles.listUp : styles.listDown]\n .filter(Boolean)\n .join(' ')}\n onKeyDown={handleListKeyDown}\n >\n {options.map((opt, i) => (\n <li\n key={opt.value}\n id={`${listboxId}-opt-${i}`}\n aria-selected={opt.value === value}\n aria-disabled={opt.disabled}\n className={[\n styles.option,\n opt.value === value ? styles.optionSelected : null,\n i === activeIndex ? styles.optionActive : null,\n opt.disabled ? styles.optionDisabled : null,\n ]\n .filter(Boolean)\n .join(' ')}\n onMouseEnter={() => !opt.disabled && setActiveIndex(i)}\n onClick={() => selectOption(opt)}\n >\n <span className={styles.optionLabel}>{opt.label}</span>\n {opt.value === value && (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n aria-hidden=\"true\"\n focusable=\"false\"\n className={styles.checkIcon}\n >\n <path\n d=\"M3 8l4 4 6-6\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.75\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )}\n </li>\n ))}\n </ul>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ComboRow.cjs","names":[],"sources":["../../../src/components/ComboRow/ComboRow.tsx"],"sourcesContent":["import {\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n} from 'react';\n\nimport styles from './ComboRow.module.css';\n\nexport interface ComboRowOption<V extends string = string> {\n value: V;\n label: string;\n disabled?: boolean;\n}\n\nexport interface ComboRowProps<V extends string = string>\n extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {\n /** Primary label. */\n title: string;\n /** Secondary line below the title. */\n subtitle?: string;\n /** Icon or image placed at the leading edge. */\n leading?: ReactNode;\n /** The list of selectable options. */\n options: ComboRowOption<V>[];\n /** The currently selected value (controlled). */\n value?: V;\n /** Initial value when uncontrolled. */\n defaultValue?: V;\n /** Called when the user selects an option. */\n onValueChange?: (value: V) => void;\n /** Disables the row. */\n disabled?: boolean;\n}\n\n/**\n * Settings row with an inline combo selector at the trailing edge.\n *\n * Mirrors `AdwComboRow` — a standard `ActionRow` layout with a dropdown\n * for choosing among a set of options. The dropdown opens inline in the row\n * and follows the same keyboard patterns as the standalone `Dropdown`.\n *\n * @see https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.ComboRow.html\n */\nexport const ComboRow = <V extends string = string>({\n title,\n subtitle,\n leading,\n options,\n value: controlledValue,\n defaultValue,\n onValueChange,\n disabled = false,\n className,\n ...props\n}: ComboRowProps<V>) => {\n const isControlled = controlledValue !== undefined;\n const [uncontrolledValue, setUncontrolledValue] = useState<V | undefined>(defaultValue);\n const value = isControlled ? controlledValue : uncontrolledValue;\n\n const [open, setOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState(-1);\n const [flipUp, setFlipUp] = useState(false);\n\n const triggerId = useId();\n const listboxId = useId();\n const triggerRef = useRef<HTMLButtonElement>(null);\n const listRef = useRef<HTMLUListElement>(null);\n\n const selected = options.find((o) => o.value === value);\n\n const computeFlip = useCallback(() => {\n if (!triggerRef.current) {\n return;\n }\n\n const rect = triggerRef.current.getBoundingClientRect();\n const spaceBelow = window.innerHeight - rect.bottom;\n const listH = Math.min(options.length * 44 + 8, 260);\n\n setFlipUp(spaceBelow < listH && rect.top > listH);\n }, [options.length]);\n\n const openList = useCallback(() => {\n if (disabled) {\n return;\n }\n\n computeFlip();\n setOpen(true);\n const idx = options.findIndex((o) => o.value === value && !o.disabled);\n\n setActiveIndex(idx >= 0 ? idx : options.findIndex((o) => !o.disabled));\n }, [disabled, computeFlip, options, value]);\n\n const closeList = useCallback(() => {\n setOpen(false);\n setActiveIndex(-1);\n triggerRef.current?.focus();\n }, []);\n\n const selectOption = useCallback(\n (opt: ComboRowOption<V>) => {\n if (opt.disabled) {\n return;\n }\n\n if (!isControlled) {\n setUncontrolledValue(opt.value);\n }\n\n onValueChange?.(opt.value);\n closeList();\n },\n [isControlled, onValueChange, closeList],\n );\n\n useEffect(() => {\n if (!open || activeIndex < 0 || !listRef.current) {\n return;\n }\n\n const item = listRef.current.children[activeIndex] as HTMLElement | undefined;\n\n item?.scrollIntoView({ block: 'nearest' });\n }, [activeIndex, open]);\n\n useEffect(() => {\n if (!open) {\n return;\n }\n\n const handler = (e: MouseEvent) => {\n if (\n !triggerRef.current?.contains(e.target as Node) &&\n !listRef.current?.contains(e.target as Node)\n ) {\n closeList();\n }\n };\n\n document.addEventListener('mousedown', handler);\n\n return () => document.removeEventListener('mousedown', handler);\n }, [open, closeList]);\n\n const handleTriggerKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n switch (e.key) {\n case 'Enter':\n case ' ':\n case 'ArrowDown':\n e.preventDefault();\n openList();\n break;\n case 'ArrowUp':\n e.preventDefault();\n computeFlip();\n setOpen(true);\n setActiveIndex(options.reduce((last, o, i) => (!o.disabled ? i : last), -1));\n break;\n }\n },\n [openList, computeFlip, options],\n );\n\n const handleListKeyDown = useCallback(\n (e: KeyboardEvent<HTMLUListElement>) => {\n const enabledIndexes = options\n .map((o, i) => ({ o, i }))\n .filter(({ o }) => !o.disabled)\n .map(({ i }) => i);\n const currentPos = enabledIndexes.indexOf(activeIndex);\n\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault();\n const next = enabledIndexes[Math.min(currentPos + 1, enabledIndexes.length - 1)];\n\n setActiveIndex(next ?? activeIndex);\n break;\n }\n case 'ArrowUp': {\n e.preventDefault();\n const prev = enabledIndexes[Math.max(currentPos - 1, 0)];\n\n setActiveIndex(prev ?? activeIndex);\n break;\n }\n case 'Home':\n e.preventDefault();\n setActiveIndex(enabledIndexes[0] ?? -1);\n break;\n case 'End':\n e.preventDefault();\n setActiveIndex(enabledIndexes[enabledIndexes.length - 1] ?? -1);\n break;\n case 'Enter':\n case ' ': {\n e.preventDefault();\n if (activeIndex >= 0) {\n selectOption(options[activeIndex]);\n }\n\n break;\n }\n case 'Escape':\n case 'Tab':\n closeList();\n break;\n }\n },\n [options, activeIndex, selectOption, closeList],\n );\n\n return (\n <div\n className={[styles.row, disabled ? styles.disabled : null, className]\n .filter(Boolean)\n .join(' ')}\n {...props}\n >\n {leading && <span className={styles.leading}>{leading}</span>}\n\n <span className={styles.content}>\n <span className={styles.title}>{title}</span>\n {subtitle && <span className={styles.subtitle}>{subtitle}</span>}\n </span>\n\n {/* Combo trigger button */}\n <div className={styles.comboWrap}>\n <button\n ref={triggerRef}\n id={triggerId}\n type=\"button\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-controls={listboxId}\n aria-activedescendant={\n open && activeIndex >= 0 ? `${listboxId}-opt-${activeIndex}` : undefined\n }\n disabled={disabled}\n className={[styles.trigger, open ? styles.triggerOpen : null].filter(Boolean).join(' ')}\n onClick={() => (open ? closeList() : openList())}\n onKeyDown={handleTriggerKeyDown}\n >\n <span\n className={[styles.triggerLabel, !selected ? styles.placeholder : null]\n .filter(Boolean)\n .join(' ')}\n >\n {selected?.label ?? '—'}\n </span>\n <svg\n className={[styles.chevron, open ? styles.chevronOpen : null].filter(Boolean).join(' ')}\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path\n d=\"M4 6l4 4 4-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </button>\n\n {open && (\n <ul\n ref={listRef}\n id={listboxId}\n aria-labelledby={triggerId}\n tabIndex={-1}\n className={[styles.list, flipUp ? styles.listUp : styles.listDown]\n .filter(Boolean)\n .join(' ')}\n onKeyDown={handleListKeyDown}\n >\n {options.map((opt, i) => (\n <li\n key={opt.value}\n id={`${listboxId}-opt-${i}`}\n aria-selected={opt.value === value}\n aria-disabled={opt.disabled}\n className={[\n styles.option,\n opt.value === value ? styles.optionSelected : null,\n i === activeIndex ? styles.optionActive : null,\n opt.disabled ? styles.optionDisabled : null,\n ]\n .filter(Boolean)\n .join(' ')}\n onMouseEnter={() => !opt.disabled && setActiveIndex(i)}\n onClick={() => selectOption(opt)}\n >\n <span className={styles.optionLabel}>{opt.label}</span>\n {opt.value === value && (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n aria-hidden=\"true\"\n focusable=\"false\"\n className={styles.checkIcon}\n >\n <path\n d=\"M3 8l4 4 6-6\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.75\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )}\n </li>\n ))}\n </ul>\n )}\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -31,4 +31,4 @@ export interface ComboRowProps<V extends string = string> extends Omit<HTMLAttri
31
31
  *
32
32
  * @see https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.ComboRow.html
33
33
  */
34
- export declare function ComboRow<V extends string = string>({ title, subtitle, leading, options, value: controlledValue, defaultValue, onValueChange, disabled, className, ...props }: ComboRowProps<V>): import("react/jsx-runtime").JSX.Element;
34
+ export declare const ComboRow: <V extends string = string>({ title, subtitle, leading, options, value: controlledValue, defaultValue, onValueChange, disabled, className, ...props }: ComboRowProps<V>) => import("react/jsx-runtime").JSX.Element;
@@ -2,7 +2,7 @@ import e from "./ComboRow.module.css.js";
2
2
  import { useCallback as t, useEffect as n, useId as r, useRef as i, useState as a } from "react";
3
3
  import { jsx as o, jsxs as s } from "react/jsx-runtime";
4
4
  //#region src/components/ComboRow/ComboRow.tsx
5
- function c({ title: c, subtitle: l, leading: u, options: d, value: f, defaultValue: p, onValueChange: m, disabled: h = !1, className: g, ..._ }) {
5
+ var c = ({ title: c, subtitle: l, leading: u, options: d, value: f, defaultValue: p, onValueChange: m, disabled: h = !1, className: g, ..._ }) => {
6
6
  let v = f !== void 0, [y, b] = a(p), x = v ? f : y, [S, C] = a(!1), [w, T] = a(-1), [E, D] = a(!1), O = r(), k = r(), A = i(null), j = i(null), M = d.find((e) => e.value === x), N = t(() => {
7
7
  if (!A.current) return;
8
8
  let e = A.current.getBoundingClientRect(), t = window.innerHeight - e.bottom, n = Math.min(d.length * 44 + 8, 260);
@@ -188,7 +188,7 @@ function c({ title: c, subtitle: l, leading: u, options: d, value: f, defaultVal
188
188
  })
189
189
  ]
190
190
  });
191
- }
191
+ };
192
192
  //#endregion
193
193
  export { c as ComboRow };
194
194
 
@@ -1 +1 @@
1
- {"version":3,"file":"ComboRow.js","names":[],"sources":["../../../src/components/ComboRow/ComboRow.tsx"],"sourcesContent":["import {\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n} from 'react';\n\nimport styles from './ComboRow.module.css';\n\nexport interface ComboRowOption<V extends string = string> {\n value: V;\n label: string;\n disabled?: boolean;\n}\n\nexport interface ComboRowProps<V extends string = string>\n extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {\n /** Primary label. */\n title: string;\n /** Secondary line below the title. */\n subtitle?: string;\n /** Icon or image placed at the leading edge. */\n leading?: ReactNode;\n /** The list of selectable options. */\n options: ComboRowOption<V>[];\n /** The currently selected value (controlled). */\n value?: V;\n /** Initial value when uncontrolled. */\n defaultValue?: V;\n /** Called when the user selects an option. */\n onValueChange?: (value: V) => void;\n /** Disables the row. */\n disabled?: boolean;\n}\n\n/**\n * Settings row with an inline combo selector at the trailing edge.\n *\n * Mirrors `AdwComboRow` — a standard `ActionRow` layout with a dropdown\n * for choosing among a set of options. The dropdown opens inline in the row\n * and follows the same keyboard patterns as the standalone `Dropdown`.\n *\n * @see https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.ComboRow.html\n */\nexport function ComboRow<V extends string = string>({\n title,\n subtitle,\n leading,\n options,\n value: controlledValue,\n defaultValue,\n onValueChange,\n disabled = false,\n className,\n ...props\n}: ComboRowProps<V>) {\n const isControlled = controlledValue !== undefined;\n const [uncontrolledValue, setUncontrolledValue] = useState<V | undefined>(defaultValue);\n const value = isControlled ? controlledValue : uncontrolledValue;\n\n const [open, setOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState(-1);\n const [flipUp, setFlipUp] = useState(false);\n\n const triggerId = useId();\n const listboxId = useId();\n const triggerRef = useRef<HTMLButtonElement>(null);\n const listRef = useRef<HTMLUListElement>(null);\n\n const selected = options.find((o) => o.value === value);\n\n const computeFlip = useCallback(() => {\n if (!triggerRef.current) {\n return;\n }\n\n const rect = triggerRef.current.getBoundingClientRect();\n const spaceBelow = window.innerHeight - rect.bottom;\n const listH = Math.min(options.length * 44 + 8, 260);\n\n setFlipUp(spaceBelow < listH && rect.top > listH);\n }, [options.length]);\n\n const openList = useCallback(() => {\n if (disabled) {\n return;\n }\n\n computeFlip();\n setOpen(true);\n const idx = options.findIndex((o) => o.value === value && !o.disabled);\n\n setActiveIndex(idx >= 0 ? idx : options.findIndex((o) => !o.disabled));\n }, [disabled, computeFlip, options, value]);\n\n const closeList = useCallback(() => {\n setOpen(false);\n setActiveIndex(-1);\n triggerRef.current?.focus();\n }, []);\n\n const selectOption = useCallback(\n (opt: ComboRowOption<V>) => {\n if (opt.disabled) {\n return;\n }\n\n if (!isControlled) {\n setUncontrolledValue(opt.value);\n }\n\n onValueChange?.(opt.value);\n closeList();\n },\n [isControlled, onValueChange, closeList],\n );\n\n useEffect(() => {\n if (!open || activeIndex < 0 || !listRef.current) {\n return;\n }\n\n const item = listRef.current.children[activeIndex] as HTMLElement | undefined;\n\n item?.scrollIntoView({ block: 'nearest' });\n }, [activeIndex, open]);\n\n useEffect(() => {\n if (!open) {\n return;\n }\n\n const handler = (e: MouseEvent) => {\n if (\n !triggerRef.current?.contains(e.target as Node) &&\n !listRef.current?.contains(e.target as Node)\n ) {\n closeList();\n }\n };\n\n document.addEventListener('mousedown', handler);\n\n return () => document.removeEventListener('mousedown', handler);\n }, [open, closeList]);\n\n const handleTriggerKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n switch (e.key) {\n case 'Enter':\n case ' ':\n case 'ArrowDown':\n e.preventDefault();\n openList();\n break;\n case 'ArrowUp':\n e.preventDefault();\n computeFlip();\n setOpen(true);\n setActiveIndex(options.reduce((last, o, i) => (!o.disabled ? i : last), -1));\n break;\n }\n },\n [openList, computeFlip, options],\n );\n\n const handleListKeyDown = useCallback(\n (e: KeyboardEvent<HTMLUListElement>) => {\n const enabledIndexes = options\n .map((o, i) => ({ o, i }))\n .filter(({ o }) => !o.disabled)\n .map(({ i }) => i);\n const currentPos = enabledIndexes.indexOf(activeIndex);\n\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault();\n const next = enabledIndexes[Math.min(currentPos + 1, enabledIndexes.length - 1)];\n\n setActiveIndex(next ?? activeIndex);\n break;\n }\n case 'ArrowUp': {\n e.preventDefault();\n const prev = enabledIndexes[Math.max(currentPos - 1, 0)];\n\n setActiveIndex(prev ?? activeIndex);\n break;\n }\n case 'Home':\n e.preventDefault();\n setActiveIndex(enabledIndexes[0] ?? -1);\n break;\n case 'End':\n e.preventDefault();\n setActiveIndex(enabledIndexes[enabledIndexes.length - 1] ?? -1);\n break;\n case 'Enter':\n case ' ': {\n e.preventDefault();\n if (activeIndex >= 0) {\n selectOption(options[activeIndex]);\n }\n\n break;\n }\n case 'Escape':\n case 'Tab':\n closeList();\n break;\n }\n },\n [options, activeIndex, selectOption, closeList],\n );\n\n return (\n <div\n className={[styles.row, disabled ? styles.disabled : null, className]\n .filter(Boolean)\n .join(' ')}\n {...props}\n >\n {leading && <span className={styles.leading}>{leading}</span>}\n\n <span className={styles.content}>\n <span className={styles.title}>{title}</span>\n {subtitle && <span className={styles.subtitle}>{subtitle}</span>}\n </span>\n\n {/* Combo trigger button */}\n <div className={styles.comboWrap}>\n <button\n ref={triggerRef}\n id={triggerId}\n type=\"button\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-controls={listboxId}\n aria-activedescendant={\n open && activeIndex >= 0 ? `${listboxId}-opt-${activeIndex}` : undefined\n }\n disabled={disabled}\n className={[styles.trigger, open ? styles.triggerOpen : null].filter(Boolean).join(' ')}\n onClick={() => (open ? closeList() : openList())}\n onKeyDown={handleTriggerKeyDown}\n >\n <span\n className={[styles.triggerLabel, !selected ? styles.placeholder : null]\n .filter(Boolean)\n .join(' ')}\n >\n {selected?.label ?? '—'}\n </span>\n <svg\n className={[styles.chevron, open ? styles.chevronOpen : null].filter(Boolean).join(' ')}\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path\n d=\"M4 6l4 4 4-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </button>\n\n {open && (\n <ul\n ref={listRef}\n id={listboxId}\n aria-labelledby={triggerId}\n tabIndex={-1}\n className={[styles.list, flipUp ? styles.listUp : styles.listDown]\n .filter(Boolean)\n .join(' ')}\n onKeyDown={handleListKeyDown}\n >\n {options.map((opt, i) => (\n <li\n key={opt.value}\n id={`${listboxId}-opt-${i}`}\n aria-selected={opt.value === value}\n aria-disabled={opt.disabled}\n className={[\n styles.option,\n opt.value === value ? styles.optionSelected : null,\n i === activeIndex ? styles.optionActive : null,\n opt.disabled ? styles.optionDisabled : null,\n ]\n .filter(Boolean)\n .join(' ')}\n onMouseEnter={() => !opt.disabled && setActiveIndex(i)}\n onClick={() => selectOption(opt)}\n >\n <span className={styles.optionLabel}>{opt.label}</span>\n {opt.value === value && (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n aria-hidden=\"true\"\n focusable=\"false\"\n className={styles.checkIcon}\n >\n <path\n d=\"M3 8l4 4 6-6\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.75\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )}\n </li>\n ))}\n </ul>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ComboRow.js","names":[],"sources":["../../../src/components/ComboRow/ComboRow.tsx"],"sourcesContent":["import {\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n} from 'react';\n\nimport styles from './ComboRow.module.css';\n\nexport interface ComboRowOption<V extends string = string> {\n value: V;\n label: string;\n disabled?: boolean;\n}\n\nexport interface ComboRowProps<V extends string = string>\n extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {\n /** Primary label. */\n title: string;\n /** Secondary line below the title. */\n subtitle?: string;\n /** Icon or image placed at the leading edge. */\n leading?: ReactNode;\n /** The list of selectable options. */\n options: ComboRowOption<V>[];\n /** The currently selected value (controlled). */\n value?: V;\n /** Initial value when uncontrolled. */\n defaultValue?: V;\n /** Called when the user selects an option. */\n onValueChange?: (value: V) => void;\n /** Disables the row. */\n disabled?: boolean;\n}\n\n/**\n * Settings row with an inline combo selector at the trailing edge.\n *\n * Mirrors `AdwComboRow` — a standard `ActionRow` layout with a dropdown\n * for choosing among a set of options. The dropdown opens inline in the row\n * and follows the same keyboard patterns as the standalone `Dropdown`.\n *\n * @see https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.ComboRow.html\n */\nexport const ComboRow = <V extends string = string>({\n title,\n subtitle,\n leading,\n options,\n value: controlledValue,\n defaultValue,\n onValueChange,\n disabled = false,\n className,\n ...props\n}: ComboRowProps<V>) => {\n const isControlled = controlledValue !== undefined;\n const [uncontrolledValue, setUncontrolledValue] = useState<V | undefined>(defaultValue);\n const value = isControlled ? controlledValue : uncontrolledValue;\n\n const [open, setOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState(-1);\n const [flipUp, setFlipUp] = useState(false);\n\n const triggerId = useId();\n const listboxId = useId();\n const triggerRef = useRef<HTMLButtonElement>(null);\n const listRef = useRef<HTMLUListElement>(null);\n\n const selected = options.find((o) => o.value === value);\n\n const computeFlip = useCallback(() => {\n if (!triggerRef.current) {\n return;\n }\n\n const rect = triggerRef.current.getBoundingClientRect();\n const spaceBelow = window.innerHeight - rect.bottom;\n const listH = Math.min(options.length * 44 + 8, 260);\n\n setFlipUp(spaceBelow < listH && rect.top > listH);\n }, [options.length]);\n\n const openList = useCallback(() => {\n if (disabled) {\n return;\n }\n\n computeFlip();\n setOpen(true);\n const idx = options.findIndex((o) => o.value === value && !o.disabled);\n\n setActiveIndex(idx >= 0 ? idx : options.findIndex((o) => !o.disabled));\n }, [disabled, computeFlip, options, value]);\n\n const closeList = useCallback(() => {\n setOpen(false);\n setActiveIndex(-1);\n triggerRef.current?.focus();\n }, []);\n\n const selectOption = useCallback(\n (opt: ComboRowOption<V>) => {\n if (opt.disabled) {\n return;\n }\n\n if (!isControlled) {\n setUncontrolledValue(opt.value);\n }\n\n onValueChange?.(opt.value);\n closeList();\n },\n [isControlled, onValueChange, closeList],\n );\n\n useEffect(() => {\n if (!open || activeIndex < 0 || !listRef.current) {\n return;\n }\n\n const item = listRef.current.children[activeIndex] as HTMLElement | undefined;\n\n item?.scrollIntoView({ block: 'nearest' });\n }, [activeIndex, open]);\n\n useEffect(() => {\n if (!open) {\n return;\n }\n\n const handler = (e: MouseEvent) => {\n if (\n !triggerRef.current?.contains(e.target as Node) &&\n !listRef.current?.contains(e.target as Node)\n ) {\n closeList();\n }\n };\n\n document.addEventListener('mousedown', handler);\n\n return () => document.removeEventListener('mousedown', handler);\n }, [open, closeList]);\n\n const handleTriggerKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n switch (e.key) {\n case 'Enter':\n case ' ':\n case 'ArrowDown':\n e.preventDefault();\n openList();\n break;\n case 'ArrowUp':\n e.preventDefault();\n computeFlip();\n setOpen(true);\n setActiveIndex(options.reduce((last, o, i) => (!o.disabled ? i : last), -1));\n break;\n }\n },\n [openList, computeFlip, options],\n );\n\n const handleListKeyDown = useCallback(\n (e: KeyboardEvent<HTMLUListElement>) => {\n const enabledIndexes = options\n .map((o, i) => ({ o, i }))\n .filter(({ o }) => !o.disabled)\n .map(({ i }) => i);\n const currentPos = enabledIndexes.indexOf(activeIndex);\n\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault();\n const next = enabledIndexes[Math.min(currentPos + 1, enabledIndexes.length - 1)];\n\n setActiveIndex(next ?? activeIndex);\n break;\n }\n case 'ArrowUp': {\n e.preventDefault();\n const prev = enabledIndexes[Math.max(currentPos - 1, 0)];\n\n setActiveIndex(prev ?? activeIndex);\n break;\n }\n case 'Home':\n e.preventDefault();\n setActiveIndex(enabledIndexes[0] ?? -1);\n break;\n case 'End':\n e.preventDefault();\n setActiveIndex(enabledIndexes[enabledIndexes.length - 1] ?? -1);\n break;\n case 'Enter':\n case ' ': {\n e.preventDefault();\n if (activeIndex >= 0) {\n selectOption(options[activeIndex]);\n }\n\n break;\n }\n case 'Escape':\n case 'Tab':\n closeList();\n break;\n }\n },\n [options, activeIndex, selectOption, closeList],\n );\n\n return (\n <div\n className={[styles.row, disabled ? styles.disabled : null, className]\n .filter(Boolean)\n .join(' ')}\n {...props}\n >\n {leading && <span className={styles.leading}>{leading}</span>}\n\n <span className={styles.content}>\n <span className={styles.title}>{title}</span>\n {subtitle && <span className={styles.subtitle}>{subtitle}</span>}\n </span>\n\n {/* Combo trigger button */}\n <div className={styles.comboWrap}>\n <button\n ref={triggerRef}\n id={triggerId}\n type=\"button\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-controls={listboxId}\n aria-activedescendant={\n open && activeIndex >= 0 ? `${listboxId}-opt-${activeIndex}` : undefined\n }\n disabled={disabled}\n className={[styles.trigger, open ? styles.triggerOpen : null].filter(Boolean).join(' ')}\n onClick={() => (open ? closeList() : openList())}\n onKeyDown={handleTriggerKeyDown}\n >\n <span\n className={[styles.triggerLabel, !selected ? styles.placeholder : null]\n .filter(Boolean)\n .join(' ')}\n >\n {selected?.label ?? '—'}\n </span>\n <svg\n className={[styles.chevron, open ? styles.chevronOpen : null].filter(Boolean).join(' ')}\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path\n d=\"M4 6l4 4 4-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </button>\n\n {open && (\n <ul\n ref={listRef}\n id={listboxId}\n aria-labelledby={triggerId}\n tabIndex={-1}\n className={[styles.list, flipUp ? styles.listUp : styles.listDown]\n .filter(Boolean)\n .join(' ')}\n onKeyDown={handleListKeyDown}\n >\n {options.map((opt, i) => (\n <li\n key={opt.value}\n id={`${listboxId}-opt-${i}`}\n aria-selected={opt.value === value}\n aria-disabled={opt.disabled}\n className={[\n styles.option,\n opt.value === value ? styles.optionSelected : null,\n i === activeIndex ? styles.optionActive : null,\n opt.disabled ? styles.optionDisabled : null,\n ]\n .filter(Boolean)\n .join(' ')}\n onMouseEnter={() => !opt.disabled && setActiveIndex(i)}\n onClick={() => selectOption(opt)}\n >\n <span className={styles.optionLabel}>{opt.label}</span>\n {opt.value === value && (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n aria-hidden=\"true\"\n focusable=\"false\"\n className={styles.checkIcon}\n >\n <path\n d=\"M3 8l4 4 6-6\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.75\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )}\n </li>\n ))}\n </ul>\n )}\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- var e=`_row_1rib3_3`,t=`_disabled_1rib3_16`,n=`_leading_1rib3_23`,r=`_content_1rib3_32`,i=`_title_1rib3_40`,a=`_subtitle_1rib3_51`,o=`_comboWrap_1rib3_65`,s=`_trigger_1rib3_73`,c=`_triggerOpen_1rib3_126`,l=`_triggerLabel_1rib3_136`,u=`_placeholder_1rib3_144`,d=`_chevron_1rib3_150`,f=`_chevronOpen_1rib3_157`,p=`_list_1rib3_163`,m=`_listDown_1rib3_200`,h=`_listUp_1rib3_204`,g=`_option_1rib3_224`,_=`_optionActive_1rib3_241`,v=`_optionSelected_1rib3_245`,y=`_optionDisabled_1rib3_249`,b=`_optionLabel_1rib3_255`,x=`_checkIcon_1rib3_263`,S={row:e,disabled:t,leading:n,content:r,title:i,subtitle:a,comboWrap:o,trigger:s,triggerOpen:c,triggerLabel:l,placeholder:u,chevron:d,chevronOpen:f,list:p,"list-in":`_list-in_1rib3_1`,listDown:m,listUp:h,"list-in-up":`_list-in-up_1rib3_1`,option:g,optionActive:_,optionSelected:v,optionDisabled:y,optionLabel:b,checkIcon:x};exports.default=S;
1
+ var e={row:`_row_1rib3_3`,disabled:`_disabled_1rib3_16`,leading:`_leading_1rib3_23`,content:`_content_1rib3_32`,title:`_title_1rib3_40`,subtitle:`_subtitle_1rib3_51`,comboWrap:`_comboWrap_1rib3_65`,trigger:`_trigger_1rib3_73`,triggerOpen:`_triggerOpen_1rib3_126`,triggerLabel:`_triggerLabel_1rib3_136`,placeholder:`_placeholder_1rib3_144`,chevron:`_chevron_1rib3_150`,chevronOpen:`_chevronOpen_1rib3_157`,list:`_list_1rib3_163`,"list-in":`_list-in_1rib3_1`,listDown:`_listDown_1rib3_200`,listUp:`_listUp_1rib3_204`,"list-in-up":`_list-in-up_1rib3_1`,option:`_option_1rib3_224`,optionActive:`_optionActive_1rib3_241`,optionSelected:`_optionSelected_1rib3_245`,optionDisabled:`_optionDisabled_1rib3_249`,optionLabel:`_optionLabel_1rib3_255`,checkIcon:`_checkIcon_1rib3_263`};exports.default=e;
2
2
  //# sourceMappingURL=ComboRow.module.css.cjs.map
@@ -1,31 +1,30 @@
1
- //#region src/components/ComboRow/ComboRow.module.css
2
- var e = "_row_1rib3_3", t = "_disabled_1rib3_16", n = "_leading_1rib3_23", r = "_content_1rib3_32", i = "_title_1rib3_40", a = "_subtitle_1rib3_51", o = "_comboWrap_1rib3_65", s = "_trigger_1rib3_73", c = "_triggerOpen_1rib3_126", l = "_triggerLabel_1rib3_136", u = "_placeholder_1rib3_144", d = "_chevron_1rib3_150", f = "_chevronOpen_1rib3_157", p = "_list_1rib3_163", m = "_listDown_1rib3_200", h = "_listUp_1rib3_204", g = "_option_1rib3_224", _ = "_optionActive_1rib3_241", v = "_optionSelected_1rib3_245", y = "_optionDisabled_1rib3_249", b = "_optionLabel_1rib3_255", x = "_checkIcon_1rib3_263", S = {
3
- row: e,
4
- disabled: t,
5
- leading: n,
6
- content: r,
7
- title: i,
8
- subtitle: a,
9
- comboWrap: o,
10
- trigger: s,
11
- triggerOpen: c,
12
- triggerLabel: l,
13
- placeholder: u,
14
- chevron: d,
15
- chevronOpen: f,
16
- list: p,
1
+ var e = {
2
+ row: "_row_1rib3_3",
3
+ disabled: "_disabled_1rib3_16",
4
+ leading: "_leading_1rib3_23",
5
+ content: "_content_1rib3_32",
6
+ title: "_title_1rib3_40",
7
+ subtitle: "_subtitle_1rib3_51",
8
+ comboWrap: "_comboWrap_1rib3_65",
9
+ trigger: "_trigger_1rib3_73",
10
+ triggerOpen: "_triggerOpen_1rib3_126",
11
+ triggerLabel: "_triggerLabel_1rib3_136",
12
+ placeholder: "_placeholder_1rib3_144",
13
+ chevron: "_chevron_1rib3_150",
14
+ chevronOpen: "_chevronOpen_1rib3_157",
15
+ list: "_list_1rib3_163",
17
16
  "list-in": "_list-in_1rib3_1",
18
- listDown: m,
19
- listUp: h,
17
+ listDown: "_listDown_1rib3_200",
18
+ listUp: "_listUp_1rib3_204",
20
19
  "list-in-up": "_list-in-up_1rib3_1",
21
- option: g,
22
- optionActive: _,
23
- optionSelected: v,
24
- optionDisabled: y,
25
- optionLabel: b,
26
- checkIcon: x
20
+ option: "_option_1rib3_224",
21
+ optionActive: "_optionActive_1rib3_241",
22
+ optionSelected: "_optionSelected_1rib3_245",
23
+ optionDisabled: "_optionDisabled_1rib3_249",
24
+ optionLabel: "_optionLabel_1rib3_255",
25
+ checkIcon: "_checkIcon_1rib3_263"
27
26
  };
28
27
  //#endregion
29
- export { S as default };
28
+ export { e as default };
30
29
 
31
30
  //# sourceMappingURL=ComboRow.module.css.js.map
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./ComboRow/ComboRow.cjs`);exports.ComboRow=e.ComboRow;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./ComboRow/ComboRow.cjs");exports.ComboRow=e.ComboRow;
@@ -1,2 +1,2 @@
1
- const e=require(`../GnomeProvider/GnomeContext.cjs`),t=require(`./ContributionGraph.module.css.cjs`);let n=require(`react`),r=require(`react-dom`),i=require(`react/jsx-runtime`);var a=new Date(2e3,0,2);function o(e,t){return t.format(new Date(2e3,e))}function s(e,t){let n=new Date(a);return n.setDate(a.getDate()+e),t.format(n)}var c=28,l=20,u=new Set([`blue`,`green`,`yellow`,`orange`,`red`,`purple`,`brown`]);function ee(e){return[`var(--gnome-card-shade-color)`,`var(--gnome-${e}-1)`,`var(--gnome-${e}-2)`,`var(--gnome-${e}-4)`,`var(--gnome-${e}-5)`]}function d(e){return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,`0`)}-${String(e.getDate()).padStart(2,`0`)}`}function f(e){let[t,n,r]=e.split(`-`).map(Number);return new Date(t,n-1,r)}function p(e,t){return t.format(f(e))}function m({data:a,maxLevel:f=4,cellSize:m=12,cellGap:h=3,responsive:g=!0,minCellSize:te=8,maxCellSize:ne=24,weekStartDay:_=1,showMonthLabels:v=!0,showDayLabels:y=!0,showLegend:re=!0,weeks:b=52,ariaLabel:x=`Contribution graph`,onDayClick:S,tooltipContent:ie,className:ae}){let C=e.useDateTimeFormatter({month:`short`}),w=e.useDateTimeFormatter({weekday:`short`}),T=e.useDateTimeFormatter({weekday:`long`,year:`numeric`,month:`long`,day:`numeric`}),{accentColor:E}=(0,n.useContext)(e.GnomeContext),D=u.has(E)?E:`green`,O=(0,n.useRef)(null),k=(0,n.useRef)(null),A=(0,n.useRef)(null),j=(0,n.useMemo)(()=>ee(D),[D]),[M,N]=(0,n.useState)(null),[P,F]=(0,n.useState)({col:0,row:0}),[I,L]=(0,n.useState)(null),[R,z]=(0,n.useState)(null);(0,n.useEffect)(()=>{if(!g)return;let e=k.current;if(!e)return;let t=()=>{let t=e.clientWidth||e.getBoundingClientRect().width;t>0&&N(t)};if(t(),typeof ResizeObserver>`u`)return window.addEventListener(`resize`,t),()=>window.removeEventListener(`resize`,t);let n=new ResizeObserver(t);return n.observe(e),()=>n.disconnect()},[g]),(0,n.useEffect)(()=>{if(!I)return;let e=()=>{let e=A.current;if(!e)return;let t=I.target.getBoundingClientRect(),n=e.getBoundingClientRect(),r=document.documentElement.clientWidth||window.innerWidth,i=document.documentElement.clientHeight||window.innerHeight,a=Math.max(8,r-n.width-8),o=Math.max(8,i-n.height-8),s=t.left+t.width/2-n.width/2,c=t.top-n.height-6,l=c>=8?c:t.bottom+6;z({left:Math.max(8,Math.min(s,a)),top:Math.max(8,Math.min(l,o))})};return e(),window.addEventListener(`resize`,e),window.addEventListener(`scroll`,e,{passive:!0,capture:!0}),()=>{window.removeEventListener(`resize`,e),window.removeEventListener(`scroll`,e,{capture:!0})}},[I]);let B=(0,n.useMemo)(()=>{let e=new Map;for(let t of a)e.set(t.date,t.count);return e},[a]),V=(0,n.useMemo)(()=>Math.max(1,...a.map(e=>e.count)),[a]),H=y?c:0,U=v?l:0,W=Math.max(1,Math.floor(b)),G=Math.max(1,te),K=Math.max(G,ne),q=(0,n.useMemo)(()=>{if(!g||M===null)return{cellSize:m,weeks:W};let e=Math.max(0,M-H),t=(e+h)/W-h;if(t>=G)return{cellSize:Math.min(K,t),weeks:W};let n=Math.floor((e+h)/(G+h));return{cellSize:G,weeks:Math.max(1,Math.min(W,n))}},[M,h,m,W,H,K,G,g]),J=q.weeks,Y=q.cellSize,X=Y+h,{grid:Z,monthLabels:oe}=(0,n.useMemo)(()=>{let e=new Date;e.setHours(0,0,0,0);let t=(e.getDay()-_+7)%7,n=new Date(e);n.setDate(e.getDate()-t);let r=new Date(n);r.setDate(n.getDate()-(J-1)*7);let i=[],a=[],s=-1;for(let t=0;t<J;t++){let n=new Date(r);n.setDate(r.getDate()+t*7),n.getMonth()!==s&&(a.push({col:t,month:o(n.getMonth(),C)}),s=n.getMonth());let c=[];for(let n=0;n<7;n++){let i=new Date(r);i.setDate(r.getDate()+t*7+n);let a=i>e,o=d(i),s=a?0:B.get(o)??0,l=s===0?0:Math.min(f,Math.ceil(s/V*f));c.push({iso:o,count:s,level:l,future:a})}i.push(c)}return{grid:i,monthLabels:a}},[B,V,f,J,_,C]),se=(0,n.useMemo)(()=>[1,3,5].map(e=>({row:(e-_+7)%7,label:s(e,w)})),[_,w]),ce=H+J*X-h,le=U+7*X-h,Q=Math.min(4,Math.floor(Y/3));(0,n.useEffect)(()=>{F(e=>({col:Math.min(J-1,e.col),row:e.row}))},[J]);function ue(e,t){let n=Math.max(0,Math.min(J-1,e)),r=Math.max(0,Math.min(6,t));F({col:n,row:r}),O.current?.querySelector(`[data-col="${n}"][data-row="${r}"]`)?.focus()}function $(e,t,n){let r={ArrowRight:[t+1,n],ArrowLeft:[t-1,n],ArrowDown:[t,n+1],ArrowUp:[t,n-1]};if(r[e.key])e.preventDefault(),ue(...r[e.key]);else if(e.key===`Enter`||e.key===` `){e.preventDefault();let r=Z[t]?.[n];r&&!r.future&&S?.({date:r.iso,count:r.count})}}function de(e,t){z(null),L({target:e.currentTarget,text:t})}function fe(){L(null),z(null)}function pe(e){return e.future?j[0]:j[Math.min(e.level,j.length-1)]??j[j.length-1]}function me(e){if(e.future)return p(e.iso,T);let t=p(e.iso,T);return ie?.({date:e.iso,count:e.count})??`${e.count} contribution${e.count===1?``:`s`} on ${t}`}return(0,i.jsxs)(`div`,{className:[t.default.wrapper,ae].filter(Boolean).join(` `),children:[(0,i.jsx)(`div`,{ref:k,className:t.default.graphViewport,children:(0,i.jsxs)(`svg`,{ref:O,width:ce,height:le,className:t.default.svg,"aria-label":x,role:`img`,"data-cell-size":Y,"data-visible-weeks":J,children:[v&&oe.map(({col:e,month:n})=>(0,i.jsx)(`text`,{x:H+e*X,y:12,className:t.default.label,children:n},`m-${e}`)),y&&se.map(({row:e,label:n})=>(0,i.jsx)(`text`,{x:0,y:U+e*X+Y-1,className:t.default.label,children:n},`d-${e}`)),(0,i.jsx)(`g`,{role:`grid`,"aria-label":x,children:Z.map((e,n)=>(0,i.jsx)(`g`,{role:`row`,children:e.map((e,r)=>{let a=me(e),o=P.col===n&&P.row===r;return(0,i.jsx)(`rect`,{"data-col":n,"data-row":r,x:H+n*X,y:U+r*X,width:Y,height:Y,rx:Q,fill:pe(e),opacity:e.future?.35:1,className:t.default.cell,role:`gridcell`,"aria-label":a,"aria-disabled":e.future||void 0,tabIndex:o?0:-1,onClick:()=>!e.future&&S?.({date:e.iso,count:e.count}),onKeyDown:e=>$(e,n,r),onFocus:()=>F({col:n,row:r}),onMouseEnter:e=>de(e,a),onMouseLeave:fe},`${n}-${r}`)})},n))})]})}),I&&typeof document<`u`&&(0,r.createPortal)((0,i.jsx)(`div`,{ref:A,className:t.default.tooltip,style:R?{left:R.left,top:R.top}:{visibility:`hidden`,left:0,top:0},role:`tooltip`,children:I.text}),document.body),re&&(0,i.jsxs)(`div`,{className:t.default.legend,children:[(0,i.jsx)(`span`,{className:t.default.legendLabel,children:`Less`}),Array.from({length:f+1},(e,n)=>(0,i.jsx)(`svg`,{width:Y,height:Y,"aria-hidden":`true`,className:t.default.legendCell,children:(0,i.jsx)(`rect`,{width:Y,height:Y,rx:Q,fill:j[Math.min(n,j.length-1)]})},n)),(0,i.jsx)(`span`,{className:t.default.legendLabel,children:`More`})]})]})}exports.ContributionGraph=m;
1
+ const e=require("../GnomeProvider/GnomeContext.cjs"),t=require("./ContributionGraph.module.css.cjs");let n=require("react"),r=require("react-dom"),i=require("react/jsx-runtime");var a=new Date(2e3,0,2);function o(e,t){return t.format(new Date(2e3,e))}function s(e,t){let n=new Date(a);return n.setDate(a.getDate()+e),t.format(n)}var c=28,l=20,u=new Set([`blue`,`green`,`yellow`,`orange`,`red`,`purple`,`brown`]);function ee(e){return[`var(--gnome-card-shade-color)`,`var(--gnome-${e}-1)`,`var(--gnome-${e}-2)`,`var(--gnome-${e}-4)`,`var(--gnome-${e}-5)`]}function d(e){return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,`0`)}-${String(e.getDate()).padStart(2,`0`)}`}function f(e){let[t,n,r]=e.split(`-`).map(Number);return new Date(t,n-1,r)}function p(e,t){return t.format(f(e))}var m=({data:a,maxLevel:f=4,cellSize:m=12,cellGap:h=3,responsive:g=!0,minCellSize:te=8,maxCellSize:ne=24,weekStartDay:_=1,showMonthLabels:v=!0,showDayLabels:y=!0,showLegend:re=!0,weeks:b=52,ariaLabel:x=`Contribution graph`,onDayClick:S,tooltipContent:ie,className:ae})=>{let C=e.useDateTimeFormatter({month:`short`}),w=e.useDateTimeFormatter({weekday:`short`}),T=e.useDateTimeFormatter({weekday:`long`,year:`numeric`,month:`long`,day:`numeric`}),{accentColor:E}=(0,n.useContext)(e.GnomeContext),D=u.has(E)?E:`green`,O=(0,n.useRef)(null),k=(0,n.useRef)(null),A=(0,n.useRef)(null),j=(0,n.useMemo)(()=>ee(D),[D]),[M,N]=(0,n.useState)(null),[P,F]=(0,n.useState)({col:0,row:0}),[I,L]=(0,n.useState)(null),[R,z]=(0,n.useState)(null);(0,n.useEffect)(()=>{if(!g)return;let e=k.current;if(!e)return;let t=()=>{let t=e.clientWidth||e.getBoundingClientRect().width;t>0&&N(t)};if(t(),typeof ResizeObserver>`u`)return window.addEventListener(`resize`,t),()=>window.removeEventListener(`resize`,t);let n=new ResizeObserver(t);return n.observe(e),()=>n.disconnect()},[g]),(0,n.useEffect)(()=>{if(!I)return;let e=()=>{let e=A.current;if(!e)return;let t=I.target.getBoundingClientRect(),n=e.getBoundingClientRect(),r=document.documentElement.clientWidth||window.innerWidth,i=document.documentElement.clientHeight||window.innerHeight,a=Math.max(8,r-n.width-8),o=Math.max(8,i-n.height-8),s=t.left+t.width/2-n.width/2,c=t.top-n.height-6,l=c>=8?c:t.bottom+6;z({left:Math.max(8,Math.min(s,a)),top:Math.max(8,Math.min(l,o))})};return e(),window.addEventListener(`resize`,e),window.addEventListener(`scroll`,e,{passive:!0,capture:!0}),()=>{window.removeEventListener(`resize`,e),window.removeEventListener(`scroll`,e,{capture:!0})}},[I]);let B=(0,n.useMemo)(()=>{let e=new Map;for(let t of a)e.set(t.date,t.count);return e},[a]),V=(0,n.useMemo)(()=>Math.max(1,...a.map(e=>e.count)),[a]),H=y?c:0,U=v?l:0,W=Math.max(1,Math.floor(b)),G=Math.max(1,te),K=Math.max(G,ne),q=(0,n.useMemo)(()=>{if(!g||M===null)return{cellSize:m,weeks:W};let e=Math.max(0,M-H),t=(e+h)/W-h;if(t>=G)return{cellSize:Math.min(K,t),weeks:W};let n=Math.floor((e+h)/(G+h));return{cellSize:G,weeks:Math.max(1,Math.min(W,n))}},[M,h,m,W,H,K,G,g]),J=q.weeks,Y=q.cellSize,X=Y+h,{grid:Z,monthLabels:oe}=(0,n.useMemo)(()=>{let e=new Date;e.setHours(0,0,0,0);let t=(e.getDay()-_+7)%7,n=new Date(e);n.setDate(e.getDate()-t);let r=new Date(n);r.setDate(n.getDate()-(J-1)*7);let i=[],a=[],s=-1;for(let t=0;t<J;t++){let n=new Date(r);n.setDate(r.getDate()+t*7),n.getMonth()!==s&&(a.push({col:t,month:o(n.getMonth(),C)}),s=n.getMonth());let c=[];for(let n=0;n<7;n++){let i=new Date(r);i.setDate(r.getDate()+t*7+n);let a=i>e,o=d(i),s=a?0:B.get(o)??0,l=s===0?0:Math.min(f,Math.ceil(s/V*f));c.push({iso:o,count:s,level:l,future:a})}i.push(c)}return{grid:i,monthLabels:a}},[B,V,f,J,_,C]),se=(0,n.useMemo)(()=>[1,3,5].map(e=>({row:(e-_+7)%7,label:s(e,w)})),[_,w]),ce=H+J*X-h,le=U+7*X-h,Q=Math.min(4,Math.floor(Y/3));(0,n.useEffect)(()=>{F(e=>({col:Math.min(J-1,e.col),row:e.row}))},[J]);function ue(e,t){let n=Math.max(0,Math.min(J-1,e)),r=Math.max(0,Math.min(6,t));F({col:n,row:r}),O.current?.querySelector(`[data-col="${n}"][data-row="${r}"]`)?.focus()}function $(e,t,n){let r={ArrowRight:[t+1,n],ArrowLeft:[t-1,n],ArrowDown:[t,n+1],ArrowUp:[t,n-1]};if(r[e.key])e.preventDefault(),ue(...r[e.key]);else if(e.key===`Enter`||e.key===` `){e.preventDefault();let r=Z[t]?.[n];r&&!r.future&&S?.({date:r.iso,count:r.count})}}function de(e,t){z(null),L({target:e.currentTarget,text:t})}function fe(){L(null),z(null)}function pe(e){return e.future?j[0]:j[Math.min(e.level,j.length-1)]??j[j.length-1]}function me(e){if(e.future)return p(e.iso,T);let t=p(e.iso,T);return ie?.({date:e.iso,count:e.count})??`${e.count} contribution${e.count===1?``:`s`} on ${t}`}return(0,i.jsxs)(`div`,{className:[t.default.wrapper,ae].filter(Boolean).join(` `),children:[(0,i.jsx)(`div`,{ref:k,className:t.default.graphViewport,children:(0,i.jsxs)(`svg`,{ref:O,width:ce,height:le,className:t.default.svg,"aria-label":x,role:`img`,"data-cell-size":Y,"data-visible-weeks":J,children:[v&&oe.map(({col:e,month:n})=>(0,i.jsx)(`text`,{x:H+e*X,y:12,className:t.default.label,children:n},`m-${e}`)),y&&se.map(({row:e,label:n})=>(0,i.jsx)(`text`,{x:0,y:U+e*X+Y-1,className:t.default.label,children:n},`d-${e}`)),(0,i.jsx)(`g`,{role:`grid`,"aria-label":x,children:Z.map((e,n)=>(0,i.jsx)(`g`,{role:`row`,children:e.map((e,r)=>{let a=me(e),o=P.col===n&&P.row===r;return(0,i.jsx)(`rect`,{"data-col":n,"data-row":r,x:H+n*X,y:U+r*X,width:Y,height:Y,rx:Q,fill:pe(e),opacity:e.future?.35:1,className:t.default.cell,role:`gridcell`,"aria-label":a,"aria-disabled":e.future||void 0,tabIndex:o?0:-1,onClick:()=>!e.future&&S?.({date:e.iso,count:e.count}),onKeyDown:e=>$(e,n,r),onFocus:()=>F({col:n,row:r}),onMouseEnter:e=>de(e,a),onMouseLeave:fe},`${n}-${r}`)})},n))})]})}),I&&typeof document<`u`&&(0,r.createPortal)((0,i.jsx)(`div`,{ref:A,className:t.default.tooltip,style:R?{left:R.left,top:R.top}:{visibility:`hidden`,left:0,top:0},role:`tooltip`,children:I.text}),document.body),re&&(0,i.jsxs)(`div`,{className:t.default.legend,children:[(0,i.jsx)(`span`,{className:t.default.legendLabel,children:`Less`}),Array.from({length:f+1},(e,n)=>(0,i.jsx)(`svg`,{width:Y,height:Y,"aria-hidden":`true`,className:t.default.legendCell,children:(0,i.jsx)(`rect`,{width:Y,height:Y,rx:Q,fill:j[Math.min(n,j.length-1)]})},n)),(0,i.jsx)(`span`,{className:t.default.legendLabel,children:`More`})]})]})};exports.ContributionGraph=m;
2
2
  //# sourceMappingURL=ContributionGraph.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ContributionGraph.cjs","names":[],"sources":["../../../src/components/ContributionGraph/ContributionGraph.tsx"],"sourcesContent":["import type { KeyboardEvent, MouseEvent } from 'react';\nimport { useContext, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { createPortal } from 'react-dom';\n\nimport {\n GnomeContext,\n type GnomeNamedAccentColor,\n useDateTimeFormatter,\n} from '../GnomeProvider/GnomeContext';\n\nimport styles from './ContributionGraph.module.css';\n\nexport interface ContributionDay {\n /** ISO 8601 date — \"YYYY-MM-DD\". */\n date: string;\n /** Non-negative activity count. */\n count: number;\n}\n\nexport interface ContributionGraphProps {\n /** Activity data. Days absent from the array are treated as count = 0. */\n data: ContributionDay[];\n /**\n * Number of intensity levels (excluding 0).\n * @default 4\n */\n maxLevel?: number;\n /** Cell side length in pixels. @default 12 */\n cellSize?: number;\n /** Gap between cells in pixels. @default 3 */\n cellGap?: number;\n /**\n * Fit the graph to its container by resizing cells and reducing visible\n * weeks when the configured range cannot stay legible.\n * @default true\n */\n responsive?: boolean;\n /** Smallest responsive cell side length in pixels. @default 8 */\n minCellSize?: number;\n /** Largest responsive cell side length in pixels. @default 24 */\n maxCellSize?: number;\n /** 0 = Sunday · 1 = Monday (GNOME locale default). @default 1 */\n weekStartDay?: 0 | 1;\n /** @default true */\n showMonthLabels?: boolean;\n /** @default true */\n showDayLabels?: boolean;\n /** @default true */\n showLegend?: boolean;\n /** Number of week columns to display. @default 52 */\n weeks?: number;\n /** @default \"Contribution graph\" */\n ariaLabel?: string;\n onDayClick?: (day: ContributionDay) => void;\n /** Returns a plain-text tooltip string for a day. */\n tooltipContent?: (day: ContributionDay) => string;\n className?: string;\n}\n\n// Reference Sunday: 2000-01-02 is a Sunday (day index 0)\nconst REF_SUNDAY = new Date(2000, 0, 2);\n\nfunction getShortMonth(monthIndex: number, formatter: Intl.DateTimeFormat): string {\n return formatter.format(new Date(2000, monthIndex));\n}\n\nfunction getShortDay(dayIndex: number, formatter: Intl.DateTimeFormat): string {\n const date = new Date(REF_SUNDAY);\n\n date.setDate(REF_SUNDAY.getDate() + dayIndex);\n\n return formatter.format(date);\n}\n\nconst DAY_LABEL_WIDTH = 28;\nconst MONTH_LABEL_HEIGHT = 20;\n\nconst NAMED_ACCENTS = new Set<GnomeNamedAccentColor>([\n 'blue',\n 'green',\n 'yellow',\n 'orange',\n 'red',\n 'purple',\n 'brown',\n]);\n\nfunction accentScale(accentColor: GnomeNamedAccentColor): string[] {\n return [\n 'var(--gnome-card-shade-color)',\n `var(--gnome-${accentColor}-1)`,\n `var(--gnome-${accentColor}-2)`,\n `var(--gnome-${accentColor}-4)`,\n `var(--gnome-${accentColor}-5)`,\n ];\n}\n\nfunction dateToIso(date: Date): string {\n const y = date.getFullYear();\n const m = String(date.getMonth() + 1).padStart(2, '0');\n const d = String(date.getDate()).padStart(2, '0');\n\n return `${y}-${m}-${d}`;\n}\n\nfunction isoToLocal(iso: string): Date {\n const [y, m, d] = iso.split('-').map(Number);\n\n return new Date(y, m - 1, d);\n}\n\nfunction fullDateLabel(iso: string, formatter: Intl.DateTimeFormat): string {\n return formatter.format(isoToLocal(iso));\n}\n\ninterface GridCell {\n iso: string;\n count: number;\n level: number;\n future: boolean;\n}\n\nexport function ContributionGraph({\n data,\n maxLevel = 4,\n cellSize = 12,\n cellGap = 3,\n responsive = true,\n minCellSize = 8,\n maxCellSize = 24,\n weekStartDay = 1,\n showMonthLabels = true,\n showDayLabels = true,\n showLegend = true,\n weeks = 52,\n ariaLabel = 'Contribution graph',\n onDayClick,\n tooltipContent,\n className,\n}: ContributionGraphProps) {\n const monthFormatter = useDateTimeFormatter({ month: 'short' });\n const weekdayFormatter = useDateTimeFormatter({ weekday: 'short' });\n const fullDateFormatter = useDateTimeFormatter({\n weekday: 'long',\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n });\n const { accentColor } = useContext(GnomeContext);\n const graphAccent = NAMED_ACCENTS.has(accentColor as GnomeNamedAccentColor)\n ? (accentColor as GnomeNamedAccentColor)\n : 'green';\n const svgRef = useRef<SVGSVGElement>(null);\n const graphViewportRef = useRef<HTMLDivElement>(null);\n const tooltipRef = useRef<HTMLDivElement>(null);\n const colors = useMemo(() => accentScale(graphAccent), [graphAccent]);\n\n const [availableWidth, setAvailableWidth] = useState<number | null>(null);\n const [focusedCell, setFocusedCell] = useState({ col: 0, row: 0 });\n const [tooltip, setTooltip] = useState<{\n target: SVGRectElement;\n text: string;\n } | null>(null);\n const [tooltipPosition, setTooltipPosition] = useState<{\n left: number;\n top: number;\n } | null>(null);\n\n useEffect(() => {\n if (!responsive) {\n return;\n }\n\n const viewport = graphViewportRef.current;\n\n if (!viewport) {\n return;\n }\n\n const updateWidth = () => {\n const width = viewport.clientWidth || viewport.getBoundingClientRect().width;\n\n if (width > 0) {\n setAvailableWidth(width);\n }\n };\n\n updateWidth();\n\n if (typeof ResizeObserver === 'undefined') {\n window.addEventListener('resize', updateWidth);\n\n return () => window.removeEventListener('resize', updateWidth);\n }\n\n const observer = new ResizeObserver(updateWidth);\n\n observer.observe(viewport);\n\n return () => observer.disconnect();\n }, [responsive]);\n\n useEffect(() => {\n if (!tooltip) {\n return;\n }\n\n const placeTooltip = () => {\n const tooltipNode = tooltipRef.current;\n\n if (!tooltipNode) {\n return;\n }\n\n const cellRect = tooltip.target.getBoundingClientRect();\n const tipRect = tooltipNode.getBoundingClientRect();\n const margin = 8;\n const gap = 6;\n const viewportWidth = document.documentElement.clientWidth || window.innerWidth;\n const viewportHeight = document.documentElement.clientHeight || window.innerHeight;\n const maxLeft = Math.max(margin, viewportWidth - tipRect.width - margin);\n const maxTop = Math.max(margin, viewportHeight - tipRect.height - margin);\n const centeredLeft = cellRect.left + cellRect.width / 2 - tipRect.width / 2;\n const aboveTop = cellRect.top - tipRect.height - gap;\n const preferredTop = aboveTop >= margin ? aboveTop : cellRect.bottom + gap;\n\n setTooltipPosition({\n left: Math.max(margin, Math.min(centeredLeft, maxLeft)),\n top: Math.max(margin, Math.min(preferredTop, maxTop)),\n });\n };\n\n placeTooltip();\n window.addEventListener('resize', placeTooltip);\n window.addEventListener('scroll', placeTooltip, { passive: true, capture: true });\n\n return () => {\n window.removeEventListener('resize', placeTooltip);\n window.removeEventListener('scroll', placeTooltip, { capture: true });\n };\n }, [tooltip]);\n\n const countMap = useMemo(() => {\n const map = new Map<string, number>();\n\n for (const d of data) {\n map.set(d.date, d.count);\n }\n\n return map;\n }, [data]);\n\n const maxCount = useMemo(() => Math.max(1, ...data.map((d) => d.count)), [data]);\n\n const dayLabelW = showDayLabels ? DAY_LABEL_WIDTH : 0;\n const monthLabelH = showMonthLabels ? MONTH_LABEL_HEIGHT : 0;\n const configuredWeeks = Math.max(1, Math.floor(weeks));\n const normalizedMinCellSize = Math.max(1, minCellSize);\n const normalizedMaxCellSize = Math.max(normalizedMinCellSize, maxCellSize);\n const fit = useMemo(() => {\n if (!responsive || availableWidth === null) {\n return { cellSize, weeks: configuredWeeks };\n }\n\n const gridWidth = Math.max(0, availableWidth - dayLabelW);\n const fittedCellSize = (gridWidth + cellGap) / configuredWeeks - cellGap;\n\n if (fittedCellSize >= normalizedMinCellSize) {\n return {\n cellSize: Math.min(normalizedMaxCellSize, fittedCellSize),\n weeks: configuredWeeks,\n };\n }\n\n const fittedWeeks = Math.floor((gridWidth + cellGap) / (normalizedMinCellSize + cellGap));\n\n return {\n cellSize: normalizedMinCellSize,\n weeks: Math.max(1, Math.min(configuredWeeks, fittedWeeks)),\n };\n }, [\n availableWidth,\n cellGap,\n cellSize,\n configuredWeeks,\n dayLabelW,\n normalizedMaxCellSize,\n normalizedMinCellSize,\n responsive,\n ]);\n const visibleWeeks = fit.weeks;\n const resolvedCellSize = fit.cellSize;\n const stride = resolvedCellSize + cellGap;\n\n const { grid, monthLabels } = useMemo(() => {\n const today = new Date();\n\n today.setHours(0, 0, 0, 0);\n\n // Align to start of current week\n const daysFromWeekStart = (today.getDay() - weekStartDay + 7) % 7;\n const lastWeekStart = new Date(today);\n\n lastWeekStart.setDate(today.getDate() - daysFromWeekStart);\n\n const firstDay = new Date(lastWeekStart);\n\n firstDay.setDate(lastWeekStart.getDate() - (visibleWeeks - 1) * 7);\n\n const gridResult: GridCell[][] = [];\n const labels: { col: number; month: string }[] = [];\n\n let lastMonth = -1;\n\n for (let col = 0; col < visibleWeeks; col++) {\n const colStart = new Date(firstDay);\n\n colStart.setDate(firstDay.getDate() + col * 7);\n\n // Month label when the column starts a new month\n if (colStart.getMonth() !== lastMonth) {\n labels.push({\n col,\n month: getShortMonth(colStart.getMonth(), monthFormatter),\n });\n lastMonth = colStart.getMonth();\n }\n\n const column: GridCell[] = [];\n\n for (let row = 0; row < 7; row++) {\n const date = new Date(firstDay);\n\n date.setDate(firstDay.getDate() + col * 7 + row);\n const future = date > today;\n const iso = dateToIso(date);\n const count = future ? 0 : (countMap.get(iso) ?? 0);\n const level =\n count === 0 ? 0 : Math.min(maxLevel, Math.ceil((count / maxCount) * maxLevel));\n\n column.push({ iso, count, level, future });\n }\n\n gridResult.push(column);\n }\n\n return { grid: gridResult, monthLabels: labels };\n }, [countMap, maxCount, maxLevel, visibleWeeks, weekStartDay, monthFormatter]);\n\n // Always label Mon(1), Wed(3), Fri(5) — rows shift with weekStartDay\n const labelRows = useMemo(\n () =>\n [1, 3, 5].map((dayIndex) => ({\n row: (dayIndex - weekStartDay + 7) % 7,\n label: getShortDay(dayIndex, weekdayFormatter),\n })),\n [weekStartDay, weekdayFormatter],\n );\n\n const svgWidth = dayLabelW + visibleWeeks * stride - cellGap;\n const svgHeight = monthLabelH + 7 * stride - cellGap;\n const cellRx = Math.min(4, Math.floor(resolvedCellSize / 3));\n\n useEffect(() => {\n setFocusedCell((current) => ({\n col: Math.min(visibleWeeks - 1, current.col),\n row: current.row,\n }));\n }, [visibleWeeks]);\n\n function focusCell(col: number, row: number) {\n const c = Math.max(0, Math.min(visibleWeeks - 1, col));\n const r = Math.max(0, Math.min(6, row));\n\n setFocusedCell({ col: c, row: r });\n svgRef.current?.querySelector<SVGRectElement>(`[data-col=\"${c}\"][data-row=\"${r}\"]`)?.focus();\n }\n\n function handleCellKey(e: KeyboardEvent, col: number, row: number) {\n const moves: Record<string, [number, number]> = {\n ArrowRight: [col + 1, row],\n ArrowLeft: [col - 1, row],\n ArrowDown: [col, row + 1],\n ArrowUp: [col, row - 1],\n };\n\n if (moves[e.key]) {\n e.preventDefault();\n focusCell(...moves[e.key]);\n } else if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n const cell = grid[col]?.[row];\n\n if (cell && !cell.future) {\n onDayClick?.({ date: cell.iso, count: cell.count });\n }\n }\n }\n\n function handleMouseEnter(e: MouseEvent<SVGRectElement>, text: string) {\n setTooltipPosition(null);\n setTooltip({\n target: e.currentTarget,\n text,\n });\n }\n\n function hideTooltip() {\n setTooltip(null);\n setTooltipPosition(null);\n }\n\n function cellColor(cell: GridCell): string {\n if (cell.future) {\n return colors[0];\n }\n\n return colors[Math.min(cell.level, colors.length - 1)] ?? colors[colors.length - 1];\n }\n\n function cellTooltip(cell: GridCell): string {\n if (cell.future) {\n return fullDateLabel(cell.iso, fullDateFormatter);\n }\n\n const formattedDate = fullDateLabel(cell.iso, fullDateFormatter);\n\n return (\n tooltipContent?.({ date: cell.iso, count: cell.count }) ??\n `${cell.count} contribution${cell.count !== 1 ? 's' : ''} on ${formattedDate}`\n );\n }\n\n return (\n <div className={[styles.wrapper, className].filter(Boolean).join(' ')}>\n <div ref={graphViewportRef} className={styles.graphViewport}>\n <svg\n ref={svgRef}\n width={svgWidth}\n height={svgHeight}\n className={styles.svg}\n aria-label={ariaLabel}\n role=\"img\"\n data-cell-size={resolvedCellSize}\n data-visible-weeks={visibleWeeks}\n >\n {/* Month labels */}\n {showMonthLabels &&\n monthLabels.map(({ col, month }) => (\n <text key={`m-${col}`} x={dayLabelW + col * stride} y={12} className={styles.label}>\n {month}\n </text>\n ))}\n\n {/* Day-of-week labels: Mon, Wed, Fri */}\n {showDayLabels &&\n labelRows.map(({ row, label }) => (\n <text\n key={`d-${row}`}\n x={0}\n y={monthLabelH + row * stride + resolvedCellSize - 1}\n className={styles.label}\n >\n {label}\n </text>\n ))}\n\n {/* Activity grid */}\n <g role=\"grid\" aria-label={ariaLabel}>\n {grid.map((column, col) => (\n <g key={col} role=\"row\">\n {column.map((cell, row) => {\n const tipText = cellTooltip(cell);\n const isFocused = focusedCell.col === col && focusedCell.row === row;\n\n return (\n <rect\n key={`${col}-${row}`}\n data-col={col}\n data-row={row}\n x={dayLabelW + col * stride}\n y={monthLabelH + row * stride}\n width={resolvedCellSize}\n height={resolvedCellSize}\n rx={cellRx}\n fill={cellColor(cell)}\n opacity={cell.future ? 0.35 : 1}\n className={styles.cell}\n role=\"gridcell\"\n aria-label={tipText}\n aria-disabled={cell.future || undefined}\n tabIndex={isFocused ? 0 : -1}\n onClick={() =>\n !cell.future && onDayClick?.({ date: cell.iso, count: cell.count })\n }\n onKeyDown={(e) => handleCellKey(e, col, row)}\n onFocus={() => setFocusedCell({ col, row })}\n onMouseEnter={(e) => handleMouseEnter(e, tipText)}\n onMouseLeave={hideTooltip}\n />\n );\n })}\n </g>\n ))}\n </g>\n </svg>\n </div>\n\n {tooltip &&\n typeof document !== 'undefined' &&\n createPortal(\n <div\n ref={tooltipRef}\n className={styles.tooltip}\n style={\n tooltipPosition\n ? { left: tooltipPosition.left, top: tooltipPosition.top }\n : { visibility: 'hidden', left: 0, top: 0 }\n }\n role=\"tooltip\"\n >\n {tooltip.text}\n </div>,\n document.body,\n )}\n\n {showLegend && (\n <div className={styles.legend}>\n <span className={styles.legendLabel}>Less</span>\n {Array.from({ length: maxLevel + 1 }, (_, i) => (\n <svg\n key={i}\n width={resolvedCellSize}\n height={resolvedCellSize}\n aria-hidden=\"true\"\n className={styles.legendCell}\n >\n <rect\n width={resolvedCellSize}\n height={resolvedCellSize}\n rx={cellRx}\n fill={colors[Math.min(i, colors.length - 1)]}\n />\n </svg>\n ))}\n <span className={styles.legendLabel}>More</span>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ContributionGraph.cjs","names":[],"sources":["../../../src/components/ContributionGraph/ContributionGraph.tsx"],"sourcesContent":["import type { KeyboardEvent, MouseEvent } from 'react';\nimport { useContext, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { createPortal } from 'react-dom';\n\nimport {\n GnomeContext,\n type GnomeNamedAccentColor,\n useDateTimeFormatter,\n} from '../GnomeProvider/GnomeContext';\n\nimport styles from './ContributionGraph.module.css';\n\nexport interface ContributionDay {\n /** ISO 8601 date — \"YYYY-MM-DD\". */\n date: string;\n /** Non-negative activity count. */\n count: number;\n}\n\nexport interface ContributionGraphProps {\n /** Activity data. Days absent from the array are treated as count = 0. */\n data: ContributionDay[];\n /**\n * Number of intensity levels (excluding 0).\n * @default 4\n */\n maxLevel?: number;\n /** Cell side length in pixels. @default 12 */\n cellSize?: number;\n /** Gap between cells in pixels. @default 3 */\n cellGap?: number;\n /**\n * Fit the graph to its container by resizing cells and reducing visible\n * weeks when the configured range cannot stay legible.\n * @default true\n */\n responsive?: boolean;\n /** Smallest responsive cell side length in pixels. @default 8 */\n minCellSize?: number;\n /** Largest responsive cell side length in pixels. @default 24 */\n maxCellSize?: number;\n /** 0 = Sunday · 1 = Monday (GNOME locale default). @default 1 */\n weekStartDay?: 0 | 1;\n /** @default true */\n showMonthLabels?: boolean;\n /** @default true */\n showDayLabels?: boolean;\n /** @default true */\n showLegend?: boolean;\n /** Number of week columns to display. @default 52 */\n weeks?: number;\n /** @default \"Contribution graph\" */\n ariaLabel?: string;\n onDayClick?: (day: ContributionDay) => void;\n /** Returns a plain-text tooltip string for a day. */\n tooltipContent?: (day: ContributionDay) => string;\n className?: string;\n}\n\n// Reference Sunday: 2000-01-02 is a Sunday (day index 0)\nconst REF_SUNDAY = new Date(2000, 0, 2);\n\nfunction getShortMonth(monthIndex: number, formatter: Intl.DateTimeFormat): string {\n return formatter.format(new Date(2000, monthIndex));\n}\n\nfunction getShortDay(dayIndex: number, formatter: Intl.DateTimeFormat): string {\n const date = new Date(REF_SUNDAY);\n\n date.setDate(REF_SUNDAY.getDate() + dayIndex);\n\n return formatter.format(date);\n}\n\nconst DAY_LABEL_WIDTH = 28;\nconst MONTH_LABEL_HEIGHT = 20;\n\nconst NAMED_ACCENTS = new Set<GnomeNamedAccentColor>([\n 'blue',\n 'green',\n 'yellow',\n 'orange',\n 'red',\n 'purple',\n 'brown',\n]);\n\nfunction accentScale(accentColor: GnomeNamedAccentColor): string[] {\n return [\n 'var(--gnome-card-shade-color)',\n `var(--gnome-${accentColor}-1)`,\n `var(--gnome-${accentColor}-2)`,\n `var(--gnome-${accentColor}-4)`,\n `var(--gnome-${accentColor}-5)`,\n ];\n}\n\nfunction dateToIso(date: Date): string {\n const y = date.getFullYear();\n const m = String(date.getMonth() + 1).padStart(2, '0');\n const d = String(date.getDate()).padStart(2, '0');\n\n return `${y}-${m}-${d}`;\n}\n\nfunction isoToLocal(iso: string): Date {\n const [y, m, d] = iso.split('-').map(Number);\n\n return new Date(y, m - 1, d);\n}\n\nfunction fullDateLabel(iso: string, formatter: Intl.DateTimeFormat): string {\n return formatter.format(isoToLocal(iso));\n}\n\ninterface GridCell {\n iso: string;\n count: number;\n level: number;\n future: boolean;\n}\n\nexport const ContributionGraph = ({\n data,\n maxLevel = 4,\n cellSize = 12,\n cellGap = 3,\n responsive = true,\n minCellSize = 8,\n maxCellSize = 24,\n weekStartDay = 1,\n showMonthLabels = true,\n showDayLabels = true,\n showLegend = true,\n weeks = 52,\n ariaLabel = 'Contribution graph',\n onDayClick,\n tooltipContent,\n className,\n}: ContributionGraphProps) => {\n const monthFormatter = useDateTimeFormatter({ month: 'short' });\n const weekdayFormatter = useDateTimeFormatter({ weekday: 'short' });\n const fullDateFormatter = useDateTimeFormatter({\n weekday: 'long',\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n });\n const { accentColor } = useContext(GnomeContext);\n const graphAccent = NAMED_ACCENTS.has(accentColor as GnomeNamedAccentColor)\n ? (accentColor as GnomeNamedAccentColor)\n : 'green';\n const svgRef = useRef<SVGSVGElement>(null);\n const graphViewportRef = useRef<HTMLDivElement>(null);\n const tooltipRef = useRef<HTMLDivElement>(null);\n const colors = useMemo(() => accentScale(graphAccent), [graphAccent]);\n\n const [availableWidth, setAvailableWidth] = useState<number | null>(null);\n const [focusedCell, setFocusedCell] = useState({ col: 0, row: 0 });\n const [tooltip, setTooltip] = useState<{\n target: SVGRectElement;\n text: string;\n } | null>(null);\n const [tooltipPosition, setTooltipPosition] = useState<{\n left: number;\n top: number;\n } | null>(null);\n\n useEffect(() => {\n if (!responsive) {\n return;\n }\n\n const viewport = graphViewportRef.current;\n\n if (!viewport) {\n return;\n }\n\n const updateWidth = () => {\n const width = viewport.clientWidth || viewport.getBoundingClientRect().width;\n\n if (width > 0) {\n setAvailableWidth(width);\n }\n };\n\n updateWidth();\n\n if (typeof ResizeObserver === 'undefined') {\n window.addEventListener('resize', updateWidth);\n\n return () => window.removeEventListener('resize', updateWidth);\n }\n\n const observer = new ResizeObserver(updateWidth);\n\n observer.observe(viewport);\n\n return () => observer.disconnect();\n }, [responsive]);\n\n useEffect(() => {\n if (!tooltip) {\n return;\n }\n\n const placeTooltip = () => {\n const tooltipNode = tooltipRef.current;\n\n if (!tooltipNode) {\n return;\n }\n\n const cellRect = tooltip.target.getBoundingClientRect();\n const tipRect = tooltipNode.getBoundingClientRect();\n const margin = 8;\n const gap = 6;\n const viewportWidth = document.documentElement.clientWidth || window.innerWidth;\n const viewportHeight = document.documentElement.clientHeight || window.innerHeight;\n const maxLeft = Math.max(margin, viewportWidth - tipRect.width - margin);\n const maxTop = Math.max(margin, viewportHeight - tipRect.height - margin);\n const centeredLeft = cellRect.left + cellRect.width / 2 - tipRect.width / 2;\n const aboveTop = cellRect.top - tipRect.height - gap;\n const preferredTop = aboveTop >= margin ? aboveTop : cellRect.bottom + gap;\n\n setTooltipPosition({\n left: Math.max(margin, Math.min(centeredLeft, maxLeft)),\n top: Math.max(margin, Math.min(preferredTop, maxTop)),\n });\n };\n\n placeTooltip();\n window.addEventListener('resize', placeTooltip);\n window.addEventListener('scroll', placeTooltip, { passive: true, capture: true });\n\n return () => {\n window.removeEventListener('resize', placeTooltip);\n window.removeEventListener('scroll', placeTooltip, { capture: true });\n };\n }, [tooltip]);\n\n const countMap = useMemo(() => {\n const map = new Map<string, number>();\n\n for (const d of data) {\n map.set(d.date, d.count);\n }\n\n return map;\n }, [data]);\n\n const maxCount = useMemo(() => Math.max(1, ...data.map((d) => d.count)), [data]);\n\n const dayLabelW = showDayLabels ? DAY_LABEL_WIDTH : 0;\n const monthLabelH = showMonthLabels ? MONTH_LABEL_HEIGHT : 0;\n const configuredWeeks = Math.max(1, Math.floor(weeks));\n const normalizedMinCellSize = Math.max(1, minCellSize);\n const normalizedMaxCellSize = Math.max(normalizedMinCellSize, maxCellSize);\n const fit = useMemo(() => {\n if (!responsive || availableWidth === null) {\n return { cellSize, weeks: configuredWeeks };\n }\n\n const gridWidth = Math.max(0, availableWidth - dayLabelW);\n const fittedCellSize = (gridWidth + cellGap) / configuredWeeks - cellGap;\n\n if (fittedCellSize >= normalizedMinCellSize) {\n return {\n cellSize: Math.min(normalizedMaxCellSize, fittedCellSize),\n weeks: configuredWeeks,\n };\n }\n\n const fittedWeeks = Math.floor((gridWidth + cellGap) / (normalizedMinCellSize + cellGap));\n\n return {\n cellSize: normalizedMinCellSize,\n weeks: Math.max(1, Math.min(configuredWeeks, fittedWeeks)),\n };\n }, [\n availableWidth,\n cellGap,\n cellSize,\n configuredWeeks,\n dayLabelW,\n normalizedMaxCellSize,\n normalizedMinCellSize,\n responsive,\n ]);\n const visibleWeeks = fit.weeks;\n const resolvedCellSize = fit.cellSize;\n const stride = resolvedCellSize + cellGap;\n\n const { grid, monthLabels } = useMemo(() => {\n const today = new Date();\n\n today.setHours(0, 0, 0, 0);\n\n // Align to start of current week\n const daysFromWeekStart = (today.getDay() - weekStartDay + 7) % 7;\n const lastWeekStart = new Date(today);\n\n lastWeekStart.setDate(today.getDate() - daysFromWeekStart);\n\n const firstDay = new Date(lastWeekStart);\n\n firstDay.setDate(lastWeekStart.getDate() - (visibleWeeks - 1) * 7);\n\n const gridResult: GridCell[][] = [];\n const labels: { col: number; month: string }[] = [];\n\n let lastMonth = -1;\n\n for (let col = 0; col < visibleWeeks; col++) {\n const colStart = new Date(firstDay);\n\n colStart.setDate(firstDay.getDate() + col * 7);\n\n // Month label when the column starts a new month\n if (colStart.getMonth() !== lastMonth) {\n labels.push({\n col,\n month: getShortMonth(colStart.getMonth(), monthFormatter),\n });\n lastMonth = colStart.getMonth();\n }\n\n const column: GridCell[] = [];\n\n for (let row = 0; row < 7; row++) {\n const date = new Date(firstDay);\n\n date.setDate(firstDay.getDate() + col * 7 + row);\n const future = date > today;\n const iso = dateToIso(date);\n const count = future ? 0 : (countMap.get(iso) ?? 0);\n const level =\n count === 0 ? 0 : Math.min(maxLevel, Math.ceil((count / maxCount) * maxLevel));\n\n column.push({ iso, count, level, future });\n }\n\n gridResult.push(column);\n }\n\n return { grid: gridResult, monthLabels: labels };\n }, [countMap, maxCount, maxLevel, visibleWeeks, weekStartDay, monthFormatter]);\n\n // Always label Mon(1), Wed(3), Fri(5) — rows shift with weekStartDay\n const labelRows = useMemo(\n () =>\n [1, 3, 5].map((dayIndex) => ({\n row: (dayIndex - weekStartDay + 7) % 7,\n label: getShortDay(dayIndex, weekdayFormatter),\n })),\n [weekStartDay, weekdayFormatter],\n );\n\n const svgWidth = dayLabelW + visibleWeeks * stride - cellGap;\n const svgHeight = monthLabelH + 7 * stride - cellGap;\n const cellRx = Math.min(4, Math.floor(resolvedCellSize / 3));\n\n useEffect(() => {\n setFocusedCell((current) => ({\n col: Math.min(visibleWeeks - 1, current.col),\n row: current.row,\n }));\n }, [visibleWeeks]);\n\n function focusCell(col: number, row: number) {\n const c = Math.max(0, Math.min(visibleWeeks - 1, col));\n const r = Math.max(0, Math.min(6, row));\n\n setFocusedCell({ col: c, row: r });\n svgRef.current?.querySelector<SVGRectElement>(`[data-col=\"${c}\"][data-row=\"${r}\"]`)?.focus();\n }\n\n function handleCellKey(e: KeyboardEvent, col: number, row: number) {\n const moves: Record<string, [number, number]> = {\n ArrowRight: [col + 1, row],\n ArrowLeft: [col - 1, row],\n ArrowDown: [col, row + 1],\n ArrowUp: [col, row - 1],\n };\n\n if (moves[e.key]) {\n e.preventDefault();\n focusCell(...moves[e.key]);\n } else if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n const cell = grid[col]?.[row];\n\n if (cell && !cell.future) {\n onDayClick?.({ date: cell.iso, count: cell.count });\n }\n }\n }\n\n function handleMouseEnter(e: MouseEvent<SVGRectElement>, text: string) {\n setTooltipPosition(null);\n setTooltip({\n target: e.currentTarget,\n text,\n });\n }\n\n function hideTooltip() {\n setTooltip(null);\n setTooltipPosition(null);\n }\n\n function cellColor(cell: GridCell): string {\n if (cell.future) {\n return colors[0];\n }\n\n return colors[Math.min(cell.level, colors.length - 1)] ?? colors[colors.length - 1];\n }\n\n function cellTooltip(cell: GridCell): string {\n if (cell.future) {\n return fullDateLabel(cell.iso, fullDateFormatter);\n }\n\n const formattedDate = fullDateLabel(cell.iso, fullDateFormatter);\n\n return (\n tooltipContent?.({ date: cell.iso, count: cell.count }) ??\n `${cell.count} contribution${cell.count !== 1 ? 's' : ''} on ${formattedDate}`\n );\n }\n\n return (\n <div className={[styles.wrapper, className].filter(Boolean).join(' ')}>\n <div ref={graphViewportRef} className={styles.graphViewport}>\n <svg\n ref={svgRef}\n width={svgWidth}\n height={svgHeight}\n className={styles.svg}\n aria-label={ariaLabel}\n role=\"img\"\n data-cell-size={resolvedCellSize}\n data-visible-weeks={visibleWeeks}\n >\n {/* Month labels */}\n {showMonthLabels &&\n monthLabels.map(({ col, month }) => (\n <text key={`m-${col}`} x={dayLabelW + col * stride} y={12} className={styles.label}>\n {month}\n </text>\n ))}\n\n {/* Day-of-week labels: Mon, Wed, Fri */}\n {showDayLabels &&\n labelRows.map(({ row, label }) => (\n <text\n key={`d-${row}`}\n x={0}\n y={monthLabelH + row * stride + resolvedCellSize - 1}\n className={styles.label}\n >\n {label}\n </text>\n ))}\n\n {/* Activity grid */}\n <g role=\"grid\" aria-label={ariaLabel}>\n {grid.map((column, col) => (\n <g key={col} role=\"row\">\n {column.map((cell, row) => {\n const tipText = cellTooltip(cell);\n const isFocused = focusedCell.col === col && focusedCell.row === row;\n\n return (\n <rect\n key={`${col}-${row}`}\n data-col={col}\n data-row={row}\n x={dayLabelW + col * stride}\n y={monthLabelH + row * stride}\n width={resolvedCellSize}\n height={resolvedCellSize}\n rx={cellRx}\n fill={cellColor(cell)}\n opacity={cell.future ? 0.35 : 1}\n className={styles.cell}\n role=\"gridcell\"\n aria-label={tipText}\n aria-disabled={cell.future || undefined}\n tabIndex={isFocused ? 0 : -1}\n onClick={() =>\n !cell.future && onDayClick?.({ date: cell.iso, count: cell.count })\n }\n onKeyDown={(e) => handleCellKey(e, col, row)}\n onFocus={() => setFocusedCell({ col, row })}\n onMouseEnter={(e) => handleMouseEnter(e, tipText)}\n onMouseLeave={hideTooltip}\n />\n );\n })}\n </g>\n ))}\n </g>\n </svg>\n </div>\n\n {tooltip &&\n typeof document !== 'undefined' &&\n createPortal(\n <div\n ref={tooltipRef}\n className={styles.tooltip}\n style={\n tooltipPosition\n ? { left: tooltipPosition.left, top: tooltipPosition.top }\n : { visibility: 'hidden', left: 0, top: 0 }\n }\n role=\"tooltip\"\n >\n {tooltip.text}\n </div>,\n document.body,\n )}\n\n {showLegend && (\n <div className={styles.legend}>\n <span className={styles.legendLabel}>Less</span>\n {Array.from({ length: maxLevel + 1 }, (_, i) => (\n <svg\n key={i}\n width={resolvedCellSize}\n height={resolvedCellSize}\n aria-hidden=\"true\"\n className={styles.legendCell}\n >\n <rect\n width={resolvedCellSize}\n height={resolvedCellSize}\n rx={cellRx}\n fill={colors[Math.min(i, colors.length - 1)]}\n />\n </svg>\n ))}\n <span className={styles.legendLabel}>More</span>\n </div>\n )}\n </div>\n );\n};\n"],"mappings":"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"}
@@ -43,4 +43,4 @@ export interface ContributionGraphProps {
43
43
  tooltipContent?: (day: ContributionDay) => string;
44
44
  className?: string;
45
45
  }
46
- export declare function ContributionGraph({ data, maxLevel, cellSize, cellGap, responsive, minCellSize, maxCellSize, weekStartDay, showMonthLabels, showDayLabels, showLegend, weeks, ariaLabel, onDayClick, tooltipContent, className, }: ContributionGraphProps): import("react/jsx-runtime").JSX.Element;
46
+ export declare const ContributionGraph: ({ data, maxLevel, cellSize, cellGap, responsive, minCellSize, maxCellSize, weekStartDay, showMonthLabels, showDayLabels, showLegend, weeks, ariaLabel, onDayClick, tooltipContent, className, }: ContributionGraphProps) => import("react/jsx-runtime").JSX.Element;
@@ -40,7 +40,7 @@ function m(e) {
40
40
  function h(e, t) {
41
41
  return t.format(m(e));
42
42
  }
43
- function g({ data: d, maxLevel: m = 4, cellSize: g = 12, cellGap: _ = 3, responsive: v = !0, minCellSize: ae = 8, maxCellSize: oe = 24, weekStartDay: y = 1, showMonthLabels: b = !0, showDayLabels: x = !0, showLegend: se = !0, weeks: ce = 52, ariaLabel: S = "Contribution graph", onDayClick: C, tooltipContent: le, className: ue }) {
43
+ var g = ({ data: d, maxLevel: m = 4, cellSize: g = 12, cellGap: _ = 3, responsive: v = !0, minCellSize: ae = 8, maxCellSize: oe = 24, weekStartDay: y = 1, showMonthLabels: b = !0, showDayLabels: x = !0, showLegend: se = !0, weeks: ce = 52, ariaLabel: S = "Contribution graph", onDayClick: C, tooltipContent: le, className: ue }) => {
44
44
  let w = t({ month: "short" }), T = t({ weekday: "short" }), E = t({
45
45
  weekday: "long",
46
46
  year: "numeric",
@@ -313,7 +313,7 @@ function g({ data: d, maxLevel: m = 4, cellSize: g = 12, cellGap: _ = 3, respons
313
313
  })
314
314
  ]
315
315
  });
316
- }
316
+ };
317
317
  //#endregion
318
318
  export { g as ContributionGraph };
319
319
 
@@ -1 +1 @@
1
- {"version":3,"file":"ContributionGraph.js","names":[],"sources":["../../../src/components/ContributionGraph/ContributionGraph.tsx"],"sourcesContent":["import type { KeyboardEvent, MouseEvent } from 'react';\nimport { useContext, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { createPortal } from 'react-dom';\n\nimport {\n GnomeContext,\n type GnomeNamedAccentColor,\n useDateTimeFormatter,\n} from '../GnomeProvider/GnomeContext';\n\nimport styles from './ContributionGraph.module.css';\n\nexport interface ContributionDay {\n /** ISO 8601 date — \"YYYY-MM-DD\". */\n date: string;\n /** Non-negative activity count. */\n count: number;\n}\n\nexport interface ContributionGraphProps {\n /** Activity data. Days absent from the array are treated as count = 0. */\n data: ContributionDay[];\n /**\n * Number of intensity levels (excluding 0).\n * @default 4\n */\n maxLevel?: number;\n /** Cell side length in pixels. @default 12 */\n cellSize?: number;\n /** Gap between cells in pixels. @default 3 */\n cellGap?: number;\n /**\n * Fit the graph to its container by resizing cells and reducing visible\n * weeks when the configured range cannot stay legible.\n * @default true\n */\n responsive?: boolean;\n /** Smallest responsive cell side length in pixels. @default 8 */\n minCellSize?: number;\n /** Largest responsive cell side length in pixels. @default 24 */\n maxCellSize?: number;\n /** 0 = Sunday · 1 = Monday (GNOME locale default). @default 1 */\n weekStartDay?: 0 | 1;\n /** @default true */\n showMonthLabels?: boolean;\n /** @default true */\n showDayLabels?: boolean;\n /** @default true */\n showLegend?: boolean;\n /** Number of week columns to display. @default 52 */\n weeks?: number;\n /** @default \"Contribution graph\" */\n ariaLabel?: string;\n onDayClick?: (day: ContributionDay) => void;\n /** Returns a plain-text tooltip string for a day. */\n tooltipContent?: (day: ContributionDay) => string;\n className?: string;\n}\n\n// Reference Sunday: 2000-01-02 is a Sunday (day index 0)\nconst REF_SUNDAY = new Date(2000, 0, 2);\n\nfunction getShortMonth(monthIndex: number, formatter: Intl.DateTimeFormat): string {\n return formatter.format(new Date(2000, monthIndex));\n}\n\nfunction getShortDay(dayIndex: number, formatter: Intl.DateTimeFormat): string {\n const date = new Date(REF_SUNDAY);\n\n date.setDate(REF_SUNDAY.getDate() + dayIndex);\n\n return formatter.format(date);\n}\n\nconst DAY_LABEL_WIDTH = 28;\nconst MONTH_LABEL_HEIGHT = 20;\n\nconst NAMED_ACCENTS = new Set<GnomeNamedAccentColor>([\n 'blue',\n 'green',\n 'yellow',\n 'orange',\n 'red',\n 'purple',\n 'brown',\n]);\n\nfunction accentScale(accentColor: GnomeNamedAccentColor): string[] {\n return [\n 'var(--gnome-card-shade-color)',\n `var(--gnome-${accentColor}-1)`,\n `var(--gnome-${accentColor}-2)`,\n `var(--gnome-${accentColor}-4)`,\n `var(--gnome-${accentColor}-5)`,\n ];\n}\n\nfunction dateToIso(date: Date): string {\n const y = date.getFullYear();\n const m = String(date.getMonth() + 1).padStart(2, '0');\n const d = String(date.getDate()).padStart(2, '0');\n\n return `${y}-${m}-${d}`;\n}\n\nfunction isoToLocal(iso: string): Date {\n const [y, m, d] = iso.split('-').map(Number);\n\n return new Date(y, m - 1, d);\n}\n\nfunction fullDateLabel(iso: string, formatter: Intl.DateTimeFormat): string {\n return formatter.format(isoToLocal(iso));\n}\n\ninterface GridCell {\n iso: string;\n count: number;\n level: number;\n future: boolean;\n}\n\nexport function ContributionGraph({\n data,\n maxLevel = 4,\n cellSize = 12,\n cellGap = 3,\n responsive = true,\n minCellSize = 8,\n maxCellSize = 24,\n weekStartDay = 1,\n showMonthLabels = true,\n showDayLabels = true,\n showLegend = true,\n weeks = 52,\n ariaLabel = 'Contribution graph',\n onDayClick,\n tooltipContent,\n className,\n}: ContributionGraphProps) {\n const monthFormatter = useDateTimeFormatter({ month: 'short' });\n const weekdayFormatter = useDateTimeFormatter({ weekday: 'short' });\n const fullDateFormatter = useDateTimeFormatter({\n weekday: 'long',\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n });\n const { accentColor } = useContext(GnomeContext);\n const graphAccent = NAMED_ACCENTS.has(accentColor as GnomeNamedAccentColor)\n ? (accentColor as GnomeNamedAccentColor)\n : 'green';\n const svgRef = useRef<SVGSVGElement>(null);\n const graphViewportRef = useRef<HTMLDivElement>(null);\n const tooltipRef = useRef<HTMLDivElement>(null);\n const colors = useMemo(() => accentScale(graphAccent), [graphAccent]);\n\n const [availableWidth, setAvailableWidth] = useState<number | null>(null);\n const [focusedCell, setFocusedCell] = useState({ col: 0, row: 0 });\n const [tooltip, setTooltip] = useState<{\n target: SVGRectElement;\n text: string;\n } | null>(null);\n const [tooltipPosition, setTooltipPosition] = useState<{\n left: number;\n top: number;\n } | null>(null);\n\n useEffect(() => {\n if (!responsive) {\n return;\n }\n\n const viewport = graphViewportRef.current;\n\n if (!viewport) {\n return;\n }\n\n const updateWidth = () => {\n const width = viewport.clientWidth || viewport.getBoundingClientRect().width;\n\n if (width > 0) {\n setAvailableWidth(width);\n }\n };\n\n updateWidth();\n\n if (typeof ResizeObserver === 'undefined') {\n window.addEventListener('resize', updateWidth);\n\n return () => window.removeEventListener('resize', updateWidth);\n }\n\n const observer = new ResizeObserver(updateWidth);\n\n observer.observe(viewport);\n\n return () => observer.disconnect();\n }, [responsive]);\n\n useEffect(() => {\n if (!tooltip) {\n return;\n }\n\n const placeTooltip = () => {\n const tooltipNode = tooltipRef.current;\n\n if (!tooltipNode) {\n return;\n }\n\n const cellRect = tooltip.target.getBoundingClientRect();\n const tipRect = tooltipNode.getBoundingClientRect();\n const margin = 8;\n const gap = 6;\n const viewportWidth = document.documentElement.clientWidth || window.innerWidth;\n const viewportHeight = document.documentElement.clientHeight || window.innerHeight;\n const maxLeft = Math.max(margin, viewportWidth - tipRect.width - margin);\n const maxTop = Math.max(margin, viewportHeight - tipRect.height - margin);\n const centeredLeft = cellRect.left + cellRect.width / 2 - tipRect.width / 2;\n const aboveTop = cellRect.top - tipRect.height - gap;\n const preferredTop = aboveTop >= margin ? aboveTop : cellRect.bottom + gap;\n\n setTooltipPosition({\n left: Math.max(margin, Math.min(centeredLeft, maxLeft)),\n top: Math.max(margin, Math.min(preferredTop, maxTop)),\n });\n };\n\n placeTooltip();\n window.addEventListener('resize', placeTooltip);\n window.addEventListener('scroll', placeTooltip, { passive: true, capture: true });\n\n return () => {\n window.removeEventListener('resize', placeTooltip);\n window.removeEventListener('scroll', placeTooltip, { capture: true });\n };\n }, [tooltip]);\n\n const countMap = useMemo(() => {\n const map = new Map<string, number>();\n\n for (const d of data) {\n map.set(d.date, d.count);\n }\n\n return map;\n }, [data]);\n\n const maxCount = useMemo(() => Math.max(1, ...data.map((d) => d.count)), [data]);\n\n const dayLabelW = showDayLabels ? DAY_LABEL_WIDTH : 0;\n const monthLabelH = showMonthLabels ? MONTH_LABEL_HEIGHT : 0;\n const configuredWeeks = Math.max(1, Math.floor(weeks));\n const normalizedMinCellSize = Math.max(1, minCellSize);\n const normalizedMaxCellSize = Math.max(normalizedMinCellSize, maxCellSize);\n const fit = useMemo(() => {\n if (!responsive || availableWidth === null) {\n return { cellSize, weeks: configuredWeeks };\n }\n\n const gridWidth = Math.max(0, availableWidth - dayLabelW);\n const fittedCellSize = (gridWidth + cellGap) / configuredWeeks - cellGap;\n\n if (fittedCellSize >= normalizedMinCellSize) {\n return {\n cellSize: Math.min(normalizedMaxCellSize, fittedCellSize),\n weeks: configuredWeeks,\n };\n }\n\n const fittedWeeks = Math.floor((gridWidth + cellGap) / (normalizedMinCellSize + cellGap));\n\n return {\n cellSize: normalizedMinCellSize,\n weeks: Math.max(1, Math.min(configuredWeeks, fittedWeeks)),\n };\n }, [\n availableWidth,\n cellGap,\n cellSize,\n configuredWeeks,\n dayLabelW,\n normalizedMaxCellSize,\n normalizedMinCellSize,\n responsive,\n ]);\n const visibleWeeks = fit.weeks;\n const resolvedCellSize = fit.cellSize;\n const stride = resolvedCellSize + cellGap;\n\n const { grid, monthLabels } = useMemo(() => {\n const today = new Date();\n\n today.setHours(0, 0, 0, 0);\n\n // Align to start of current week\n const daysFromWeekStart = (today.getDay() - weekStartDay + 7) % 7;\n const lastWeekStart = new Date(today);\n\n lastWeekStart.setDate(today.getDate() - daysFromWeekStart);\n\n const firstDay = new Date(lastWeekStart);\n\n firstDay.setDate(lastWeekStart.getDate() - (visibleWeeks - 1) * 7);\n\n const gridResult: GridCell[][] = [];\n const labels: { col: number; month: string }[] = [];\n\n let lastMonth = -1;\n\n for (let col = 0; col < visibleWeeks; col++) {\n const colStart = new Date(firstDay);\n\n colStart.setDate(firstDay.getDate() + col * 7);\n\n // Month label when the column starts a new month\n if (colStart.getMonth() !== lastMonth) {\n labels.push({\n col,\n month: getShortMonth(colStart.getMonth(), monthFormatter),\n });\n lastMonth = colStart.getMonth();\n }\n\n const column: GridCell[] = [];\n\n for (let row = 0; row < 7; row++) {\n const date = new Date(firstDay);\n\n date.setDate(firstDay.getDate() + col * 7 + row);\n const future = date > today;\n const iso = dateToIso(date);\n const count = future ? 0 : (countMap.get(iso) ?? 0);\n const level =\n count === 0 ? 0 : Math.min(maxLevel, Math.ceil((count / maxCount) * maxLevel));\n\n column.push({ iso, count, level, future });\n }\n\n gridResult.push(column);\n }\n\n return { grid: gridResult, monthLabels: labels };\n }, [countMap, maxCount, maxLevel, visibleWeeks, weekStartDay, monthFormatter]);\n\n // Always label Mon(1), Wed(3), Fri(5) — rows shift with weekStartDay\n const labelRows = useMemo(\n () =>\n [1, 3, 5].map((dayIndex) => ({\n row: (dayIndex - weekStartDay + 7) % 7,\n label: getShortDay(dayIndex, weekdayFormatter),\n })),\n [weekStartDay, weekdayFormatter],\n );\n\n const svgWidth = dayLabelW + visibleWeeks * stride - cellGap;\n const svgHeight = monthLabelH + 7 * stride - cellGap;\n const cellRx = Math.min(4, Math.floor(resolvedCellSize / 3));\n\n useEffect(() => {\n setFocusedCell((current) => ({\n col: Math.min(visibleWeeks - 1, current.col),\n row: current.row,\n }));\n }, [visibleWeeks]);\n\n function focusCell(col: number, row: number) {\n const c = Math.max(0, Math.min(visibleWeeks - 1, col));\n const r = Math.max(0, Math.min(6, row));\n\n setFocusedCell({ col: c, row: r });\n svgRef.current?.querySelector<SVGRectElement>(`[data-col=\"${c}\"][data-row=\"${r}\"]`)?.focus();\n }\n\n function handleCellKey(e: KeyboardEvent, col: number, row: number) {\n const moves: Record<string, [number, number]> = {\n ArrowRight: [col + 1, row],\n ArrowLeft: [col - 1, row],\n ArrowDown: [col, row + 1],\n ArrowUp: [col, row - 1],\n };\n\n if (moves[e.key]) {\n e.preventDefault();\n focusCell(...moves[e.key]);\n } else if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n const cell = grid[col]?.[row];\n\n if (cell && !cell.future) {\n onDayClick?.({ date: cell.iso, count: cell.count });\n }\n }\n }\n\n function handleMouseEnter(e: MouseEvent<SVGRectElement>, text: string) {\n setTooltipPosition(null);\n setTooltip({\n target: e.currentTarget,\n text,\n });\n }\n\n function hideTooltip() {\n setTooltip(null);\n setTooltipPosition(null);\n }\n\n function cellColor(cell: GridCell): string {\n if (cell.future) {\n return colors[0];\n }\n\n return colors[Math.min(cell.level, colors.length - 1)] ?? colors[colors.length - 1];\n }\n\n function cellTooltip(cell: GridCell): string {\n if (cell.future) {\n return fullDateLabel(cell.iso, fullDateFormatter);\n }\n\n const formattedDate = fullDateLabel(cell.iso, fullDateFormatter);\n\n return (\n tooltipContent?.({ date: cell.iso, count: cell.count }) ??\n `${cell.count} contribution${cell.count !== 1 ? 's' : ''} on ${formattedDate}`\n );\n }\n\n return (\n <div className={[styles.wrapper, className].filter(Boolean).join(' ')}>\n <div ref={graphViewportRef} className={styles.graphViewport}>\n <svg\n ref={svgRef}\n width={svgWidth}\n height={svgHeight}\n className={styles.svg}\n aria-label={ariaLabel}\n role=\"img\"\n data-cell-size={resolvedCellSize}\n data-visible-weeks={visibleWeeks}\n >\n {/* Month labels */}\n {showMonthLabels &&\n monthLabels.map(({ col, month }) => (\n <text key={`m-${col}`} x={dayLabelW + col * stride} y={12} className={styles.label}>\n {month}\n </text>\n ))}\n\n {/* Day-of-week labels: Mon, Wed, Fri */}\n {showDayLabels &&\n labelRows.map(({ row, label }) => (\n <text\n key={`d-${row}`}\n x={0}\n y={monthLabelH + row * stride + resolvedCellSize - 1}\n className={styles.label}\n >\n {label}\n </text>\n ))}\n\n {/* Activity grid */}\n <g role=\"grid\" aria-label={ariaLabel}>\n {grid.map((column, col) => (\n <g key={col} role=\"row\">\n {column.map((cell, row) => {\n const tipText = cellTooltip(cell);\n const isFocused = focusedCell.col === col && focusedCell.row === row;\n\n return (\n <rect\n key={`${col}-${row}`}\n data-col={col}\n data-row={row}\n x={dayLabelW + col * stride}\n y={monthLabelH + row * stride}\n width={resolvedCellSize}\n height={resolvedCellSize}\n rx={cellRx}\n fill={cellColor(cell)}\n opacity={cell.future ? 0.35 : 1}\n className={styles.cell}\n role=\"gridcell\"\n aria-label={tipText}\n aria-disabled={cell.future || undefined}\n tabIndex={isFocused ? 0 : -1}\n onClick={() =>\n !cell.future && onDayClick?.({ date: cell.iso, count: cell.count })\n }\n onKeyDown={(e) => handleCellKey(e, col, row)}\n onFocus={() => setFocusedCell({ col, row })}\n onMouseEnter={(e) => handleMouseEnter(e, tipText)}\n onMouseLeave={hideTooltip}\n />\n );\n })}\n </g>\n ))}\n </g>\n </svg>\n </div>\n\n {tooltip &&\n typeof document !== 'undefined' &&\n createPortal(\n <div\n ref={tooltipRef}\n className={styles.tooltip}\n style={\n tooltipPosition\n ? { left: tooltipPosition.left, top: tooltipPosition.top }\n : { visibility: 'hidden', left: 0, top: 0 }\n }\n role=\"tooltip\"\n >\n {tooltip.text}\n </div>,\n document.body,\n )}\n\n {showLegend && (\n <div className={styles.legend}>\n <span className={styles.legendLabel}>Less</span>\n {Array.from({ length: maxLevel + 1 }, (_, i) => (\n <svg\n key={i}\n width={resolvedCellSize}\n height={resolvedCellSize}\n aria-hidden=\"true\"\n className={styles.legendCell}\n >\n <rect\n width={resolvedCellSize}\n height={resolvedCellSize}\n rx={cellRx}\n fill={colors[Math.min(i, colors.length - 1)]}\n />\n </svg>\n ))}\n <span className={styles.legendLabel}>More</span>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;AA6DA,IAAM,IAAa,IAAI,KAAK,KAAM,GAAG,EAAE;AAEvC,SAAS,EAAc,GAAoB,GAAwC;AACjF,QAAO,EAAU,OAAO,IAAI,KAAK,KAAM,EAAW,CAAC;;AAGrD,SAAS,GAAY,GAAkB,GAAwC;CAC7E,IAAM,IAAO,IAAI,KAAK,EAAW;AAIjC,QAFA,EAAK,QAAQ,EAAW,SAAS,GAAG,EAAS,EAEtC,EAAU,OAAO,EAAK;;AAG/B,IAAM,KAAkB,IAClB,KAAqB,IAErB,KAAgB,IAAI,IAA2B;CACnD;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,SAAS,GAAY,GAA8C;AACjE,QAAO;EACL;EACA,eAAe,EAAY;EAC3B,eAAe,EAAY;EAC3B,eAAe,EAAY;EAC3B,eAAe,EAAY;EAC5B;;AAGH,SAAS,EAAU,GAAoB;AAKrC,QAAO,GAJG,EAAK,aAAa,CAIhB,GAHF,OAAO,EAAK,UAAU,GAAG,EAAE,CAAC,SAAS,GAAG,IAAI,CAGrC,GAFP,OAAO,EAAK,SAAS,CAAC,CAAC,SAAS,GAAG,IAAI;;AAKnD,SAAS,EAAW,GAAmB;CACrC,IAAM,CAAC,GAAG,GAAG,KAAK,EAAI,MAAM,IAAI,CAAC,IAAI,OAAO;AAE5C,QAAO,IAAI,KAAK,GAAG,IAAI,GAAG,EAAE;;AAG9B,SAAS,EAAc,GAAa,GAAwC;AAC1E,QAAO,EAAU,OAAO,EAAW,EAAI,CAAC;;AAU1C,SAAgB,EAAkB,EAChC,SACA,cAAW,GACX,cAAW,IACX,aAAU,GACV,gBAAa,IACb,kBAAc,GACd,kBAAc,IACd,kBAAe,GACf,qBAAkB,IAClB,mBAAgB,IAChB,iBAAa,IACb,YAAQ,IACR,eAAY,sBACZ,eACA,oBACA,iBACyB;CACzB,IAAM,IAAiB,EAAqB,EAAE,OAAO,SAAS,CAAC,EACzD,IAAmB,EAAqB,EAAE,SAAS,SAAS,CAAC,EAC7D,IAAoB,EAAqB;EAC7C,SAAS;EACT,MAAM;EACN,OAAO;EACP,KAAK;EACN,CAAC,EACI,EAAE,mBAAgB,EAAW,EAAa,EAC1C,IAAc,GAAc,IAAI,EAAqC,GACtE,IACD,SACE,IAAS,EAAsB,KAAK,EACpC,IAAmB,EAAuB,KAAK,EAC/C,IAAa,EAAuB,KAAK,EACzC,IAAS,QAAc,GAAY,EAAY,EAAE,CAAC,EAAY,CAAC,EAE/D,CAAC,GAAgB,MAAqB,EAAwB,KAAK,EACnE,CAAC,GAAa,KAAkB,EAAS;EAAE,KAAK;EAAG,KAAK;EAAG,CAAC,EAC5D,CAAC,GAAS,KAAc,EAGpB,KAAK,EACT,CAAC,GAAiB,KAAsB,EAGpC,KAAK;AAoCf,CAlCA,QAAgB;AACd,MAAI,CAAC,EACH;EAGF,IAAM,IAAW,EAAiB;AAElC,MAAI,CAAC,EACH;EAGF,IAAM,UAAoB;GACxB,IAAM,IAAQ,EAAS,eAAe,EAAS,uBAAuB,CAAC;AAEvE,GAAI,IAAQ,KACV,GAAkB,EAAM;;AAM5B,MAFA,GAAa,EAET,OAAO,iBAAmB,IAG5B,QAFA,OAAO,iBAAiB,UAAU,EAAY,QAEjC,OAAO,oBAAoB,UAAU,EAAY;EAGhE,IAAM,IAAW,IAAI,eAAe,EAAY;AAIhD,SAFA,EAAS,QAAQ,EAAS,QAEb,EAAS,YAAY;IACjC,CAAC,EAAW,CAAC,EAEhB,QAAgB;AACd,MAAI,CAAC,EACH;EAGF,IAAM,UAAqB;GACzB,IAAM,IAAc,EAAW;AAE/B,OAAI,CAAC,EACH;GAGF,IAAM,IAAW,EAAQ,OAAO,uBAAuB,EACjD,IAAU,EAAY,uBAAuB,EAG7C,IAAgB,SAAS,gBAAgB,eAAe,OAAO,YAC/D,IAAiB,SAAS,gBAAgB,gBAAgB,OAAO,aACjE,IAAU,KAAK,IAAI,GAAQ,IAAgB,EAAQ,QAAQ,EAAO,EAClE,IAAS,KAAK,IAAI,GAAQ,IAAiB,EAAQ,SAAS,EAAO,EACnE,IAAe,EAAS,OAAO,EAAS,QAAQ,IAAI,EAAQ,QAAQ,GACpE,IAAW,EAAS,MAAM,EAAQ,SAAS,GAC3C,IAAe,KAAY,IAAS,IAAW,EAAS,SAAS;AAEvE,KAAmB;IACjB,MAAM,KAAK,IAAI,GAAQ,KAAK,IAAI,GAAc,EAAQ,CAAC;IACvD,KAAK,KAAK,IAAI,GAAQ,KAAK,IAAI,GAAc,EAAO,CAAC;IACtD,CAAC;;AAOJ,SAJA,GAAc,EACd,OAAO,iBAAiB,UAAU,EAAa,EAC/C,OAAO,iBAAiB,UAAU,GAAc;GAAE,SAAS;GAAM,SAAS;GAAM,CAAC,QAEpE;AAEX,GADA,OAAO,oBAAoB,UAAU,EAAa,EAClD,OAAO,oBAAoB,UAAU,GAAc,EAAE,SAAS,IAAM,CAAC;;IAEtE,CAAC,EAAQ,CAAC;CAEb,IAAM,IAAW,QAAc;EAC7B,IAAM,oBAAM,IAAI,KAAqB;AAErC,OAAK,IAAM,KAAK,EACd,GAAI,IAAI,EAAE,MAAM,EAAE,MAAM;AAG1B,SAAO;IACN,CAAC,EAAK,CAAC,EAEJ,IAAW,QAAc,KAAK,IAAI,GAAG,GAAG,EAAK,KAAK,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,EAAK,CAAC,EAE1E,IAAY,IAAgB,KAAkB,GAC9C,IAAc,IAAkB,KAAqB,GACrD,IAAkB,KAAK,IAAI,GAAG,KAAK,MAAM,GAAM,CAAC,EAChD,IAAwB,KAAK,IAAI,GAAG,GAAY,EAChD,IAAwB,KAAK,IAAI,GAAuB,GAAY,EACpE,IAAM,QAAc;AACxB,MAAI,CAAC,KAAc,MAAmB,KACpC,QAAO;GAAE;GAAU,OAAO;GAAiB;EAG7C,IAAM,IAAY,KAAK,IAAI,GAAG,IAAiB,EAAU,EACnD,KAAkB,IAAY,KAAW,IAAkB;AAEjE,MAAI,KAAkB,EACpB,QAAO;GACL,UAAU,KAAK,IAAI,GAAuB,EAAe;GACzD,OAAO;GACR;EAGH,IAAM,IAAc,KAAK,OAAO,IAAY,MAAY,IAAwB,GAAS;AAEzF,SAAO;GACL,UAAU;GACV,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAiB,EAAY,CAAC;GAC3D;IACA;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,EACI,IAAe,EAAI,OACnB,IAAmB,EAAI,UACvB,IAAS,IAAmB,GAE5B,EAAE,SAAM,oBAAgB,QAAc;EAC1C,IAAM,oBAAQ,IAAI,MAAM;AAExB,IAAM,SAAS,GAAG,GAAG,GAAG,EAAE;EAG1B,IAAM,KAAqB,EAAM,QAAQ,GAAG,IAAe,KAAK,GAC1D,IAAgB,IAAI,KAAK,EAAM;AAErC,IAAc,QAAQ,EAAM,SAAS,GAAG,EAAkB;EAE1D,IAAM,IAAW,IAAI,KAAK,EAAc;AAExC,IAAS,QAAQ,EAAc,SAAS,IAAI,IAAe,KAAK,EAAE;EAElE,IAAM,IAA2B,EAAE,EAC7B,IAA2C,EAAE,EAE/C,IAAY;AAEhB,OAAK,IAAI,IAAM,GAAG,IAAM,GAAc,KAAO;GAC3C,IAAM,IAAW,IAAI,KAAK,EAAS;AAKnC,GAHA,EAAS,QAAQ,EAAS,SAAS,GAAG,IAAM,EAAE,EAG1C,EAAS,UAAU,KAAK,MAC1B,EAAO,KAAK;IACV;IACA,OAAO,EAAc,EAAS,UAAU,EAAE,EAAe;IAC1D,CAAC,EACF,IAAY,EAAS,UAAU;GAGjC,IAAM,IAAqB,EAAE;AAE7B,QAAK,IAAI,IAAM,GAAG,IAAM,GAAG,KAAO;IAChC,IAAM,IAAO,IAAI,KAAK,EAAS;AAE/B,MAAK,QAAQ,EAAS,SAAS,GAAG,IAAM,IAAI,EAAI;IAChD,IAAM,IAAS,IAAO,GAChB,IAAM,EAAU,EAAK,EACrB,IAAQ,IAAS,IAAK,EAAS,IAAI,EAAI,IAAI,GAC3C,IACJ,MAAU,IAAI,IAAI,KAAK,IAAI,GAAU,KAAK,KAAM,IAAQ,IAAY,EAAS,CAAC;AAEhF,MAAO,KAAK;KAAE;KAAK;KAAO;KAAO;KAAQ,CAAC;;AAG5C,KAAW,KAAK,EAAO;;AAGzB,SAAO;GAAE,MAAM;GAAY,aAAa;GAAQ;IAC/C;EAAC;EAAU;EAAU;EAAU;EAAc;EAAc;EAAe,CAAC,EAGxE,KAAY,QAEd;EAAC;EAAG;EAAG;EAAE,CAAC,KAAK,OAAc;EAC3B,MAAM,IAAW,IAAe,KAAK;EACrC,OAAO,GAAY,GAAU,EAAiB;EAC/C,EAAE,EACL,CAAC,GAAc,EAAiB,CACjC,EAEK,IAAW,IAAY,IAAe,IAAS,GAC/C,KAAY,IAAc,IAAI,IAAS,GACvC,IAAS,KAAK,IAAI,GAAG,KAAK,MAAM,IAAmB,EAAE,CAAC;AAE5D,SAAgB;AACd,KAAgB,OAAa;GAC3B,KAAK,KAAK,IAAI,IAAe,GAAG,EAAQ,IAAI;GAC5C,KAAK,EAAQ;GACd,EAAE;IACF,CAAC,EAAa,CAAC;CAElB,SAAS,GAAU,GAAa,GAAa;EAC3C,IAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,IAAe,GAAG,EAAI,CAAC,EAChD,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,EAAI,CAAC;AAGvC,EADA,EAAe;GAAE,KAAK;GAAG,KAAK;GAAG,CAAC,EAClC,EAAO,SAAS,cAA8B,cAAc,EAAE,eAAe,EAAE,IAAI,EAAE,OAAO;;CAG9F,SAAS,GAAc,GAAkB,GAAa,GAAa;EACjE,IAAM,IAA0C;GAC9C,YAAY,CAAC,IAAM,GAAG,EAAI;GAC1B,WAAW,CAAC,IAAM,GAAG,EAAI;GACzB,WAAW,CAAC,GAAK,IAAM,EAAE;GACzB,SAAS,CAAC,GAAK,IAAM,EAAE;GACxB;AAED,MAAI,EAAM,EAAE,KAEV,CADA,EAAE,gBAAgB,EAClB,GAAU,GAAG,EAAM,EAAE,KAAK;WACjB,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AAC7C,KAAE,gBAAgB;GAClB,IAAM,IAAO,EAAK,KAAO;AAEzB,GAAI,KAAQ,CAAC,EAAK,UAChB,IAAa;IAAE,MAAM,EAAK;IAAK,OAAO,EAAK;IAAO,CAAC;;;CAKzD,SAAS,GAAiB,GAA+B,GAAc;AAErE,EADA,EAAmB,KAAK,EACxB,EAAW;GACT,QAAQ,EAAE;GACV;GACD,CAAC;;CAGJ,SAAS,KAAc;AAErB,EADA,EAAW,KAAK,EAChB,EAAmB,KAAK;;CAG1B,SAAS,GAAU,GAAwB;AAKzC,SAJI,EAAK,SACA,EAAO,KAGT,EAAO,KAAK,IAAI,EAAK,OAAO,EAAO,SAAS,EAAE,KAAK,EAAO,EAAO,SAAS;;CAGnF,SAAS,GAAY,GAAwB;AAC3C,MAAI,EAAK,OACP,QAAO,EAAc,EAAK,KAAK,EAAkB;EAGnD,IAAM,IAAgB,EAAc,EAAK,KAAK,EAAkB;AAEhE,SACE,KAAiB;GAAE,MAAM,EAAK;GAAK,OAAO,EAAK;GAAO,CAAC,IACvD,GAAG,EAAK,MAAM,eAAe,EAAK,UAAU,IAAU,KAAN,IAAS,MAAM;;AAInE,QACE,kBAAC,OAAD;EAAK,WAAW,CAAC,EAAO,SAAS,GAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;YAArE;GACE,kBAAC,OAAD;IAAK,KAAK;IAAkB,WAAW,EAAO;cAC5C,kBAAC,OAAD;KACE,KAAK;KACL,OAAO;KACP,QAAQ;KACR,WAAW,EAAO;KAClB,cAAY;KACZ,MAAK;KACL,kBAAgB;KAChB,sBAAoB;eARtB;MAWG,KACC,GAAY,KAAK,EAAE,QAAK,eACtB,kBAAC,QAAD;OAAuB,GAAG,IAAY,IAAM;OAAQ,GAAG;OAAI,WAAW,EAAO;iBAC1E;OACI,EAFI,KAAK,IAET,CACP;MAGH,KACC,GAAU,KAAK,EAAE,QAAK,eACpB,kBAAC,QAAD;OAEE,GAAG;OACH,GAAG,IAAc,IAAM,IAAS,IAAmB;OACnD,WAAW,EAAO;iBAEjB;OACI,EANA,KAAK,IAML,CACP;MAGJ,kBAAC,KAAD;OAAG,MAAK;OAAO,cAAY;iBACxB,EAAK,KAAK,GAAQ,MACjB,kBAAC,KAAD;QAAa,MAAK;kBACf,EAAO,KAAK,GAAM,MAAQ;SACzB,IAAM,IAAU,GAAY,EAAK,EAC3B,IAAY,EAAY,QAAQ,KAAO,EAAY,QAAQ;AAEjE,gBACE,kBAAC,QAAD;UAEE,YAAU;UACV,YAAU;UACV,GAAG,IAAY,IAAM;UACrB,GAAG,IAAc,IAAM;UACvB,OAAO;UACP,QAAQ;UACR,IAAI;UACJ,MAAM,GAAU,EAAK;UACrB,SAAS,EAAK,SAAS,MAAO;UAC9B,WAAW,EAAO;UAClB,MAAK;UACL,cAAY;UACZ,iBAAe,EAAK,UAAU,KAAA;UAC9B,UAAU,IAAY,IAAI;UAC1B,eACE,CAAC,EAAK,UAAU,IAAa;WAAE,MAAM,EAAK;WAAK,OAAO,EAAK;WAAO,CAAC;UAErE,YAAY,MAAM,GAAc,GAAG,GAAK,EAAI;UAC5C,eAAe,EAAe;WAAE;WAAK;WAAK,CAAC;UAC3C,eAAe,MAAM,GAAiB,GAAG,EAAQ;UACjD,cAAc;UACd,EAtBK,GAAG,EAAI,GAAG,IAsBf;UAEJ;QACA,EAhCI,EAgCJ,CACJ;OACA,CAAA;MACA;;IACF,CAAA;GAEL,KACC,OAAO,WAAa,OACpB,EACE,kBAAC,OAAD;IACE,KAAK;IACL,WAAW,EAAO;IAClB,OACE,IACI;KAAE,MAAM,EAAgB;KAAM,KAAK,EAAgB;KAAK,GACxD;KAAE,YAAY;KAAU,MAAM;KAAG,KAAK;KAAG;IAE/C,MAAK;cAEJ,EAAQ;IACL,CAAA,EACN,SAAS,KACV;GAEF,MACC,kBAAC,OAAD;IAAK,WAAW,EAAO;cAAvB;KACE,kBAAC,QAAD;MAAM,WAAW,EAAO;gBAAa;MAAW,CAAA;KAC/C,MAAM,KAAK,EAAE,QAAQ,IAAW,GAAG,GAAG,GAAG,MACxC,kBAAC,OAAD;MAEE,OAAO;MACP,QAAQ;MACR,eAAY;MACZ,WAAW,EAAO;gBAElB,kBAAC,QAAD;OACE,OAAO;OACP,QAAQ;OACR,IAAI;OACJ,MAAM,EAAO,KAAK,IAAI,GAAG,EAAO,SAAS,EAAE;OAC3C,CAAA;MACE,EAZC,EAYD,CACN;KACF,kBAAC,QAAD;MAAM,WAAW,EAAO;gBAAa;MAAW,CAAA;KAC5C;;GAEJ"}
1
+ {"version":3,"file":"ContributionGraph.js","names":[],"sources":["../../../src/components/ContributionGraph/ContributionGraph.tsx"],"sourcesContent":["import type { KeyboardEvent, MouseEvent } from 'react';\nimport { useContext, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { createPortal } from 'react-dom';\n\nimport {\n GnomeContext,\n type GnomeNamedAccentColor,\n useDateTimeFormatter,\n} from '../GnomeProvider/GnomeContext';\n\nimport styles from './ContributionGraph.module.css';\n\nexport interface ContributionDay {\n /** ISO 8601 date — \"YYYY-MM-DD\". */\n date: string;\n /** Non-negative activity count. */\n count: number;\n}\n\nexport interface ContributionGraphProps {\n /** Activity data. Days absent from the array are treated as count = 0. */\n data: ContributionDay[];\n /**\n * Number of intensity levels (excluding 0).\n * @default 4\n */\n maxLevel?: number;\n /** Cell side length in pixels. @default 12 */\n cellSize?: number;\n /** Gap between cells in pixels. @default 3 */\n cellGap?: number;\n /**\n * Fit the graph to its container by resizing cells and reducing visible\n * weeks when the configured range cannot stay legible.\n * @default true\n */\n responsive?: boolean;\n /** Smallest responsive cell side length in pixels. @default 8 */\n minCellSize?: number;\n /** Largest responsive cell side length in pixels. @default 24 */\n maxCellSize?: number;\n /** 0 = Sunday · 1 = Monday (GNOME locale default). @default 1 */\n weekStartDay?: 0 | 1;\n /** @default true */\n showMonthLabels?: boolean;\n /** @default true */\n showDayLabels?: boolean;\n /** @default true */\n showLegend?: boolean;\n /** Number of week columns to display. @default 52 */\n weeks?: number;\n /** @default \"Contribution graph\" */\n ariaLabel?: string;\n onDayClick?: (day: ContributionDay) => void;\n /** Returns a plain-text tooltip string for a day. */\n tooltipContent?: (day: ContributionDay) => string;\n className?: string;\n}\n\n// Reference Sunday: 2000-01-02 is a Sunday (day index 0)\nconst REF_SUNDAY = new Date(2000, 0, 2);\n\nfunction getShortMonth(monthIndex: number, formatter: Intl.DateTimeFormat): string {\n return formatter.format(new Date(2000, monthIndex));\n}\n\nfunction getShortDay(dayIndex: number, formatter: Intl.DateTimeFormat): string {\n const date = new Date(REF_SUNDAY);\n\n date.setDate(REF_SUNDAY.getDate() + dayIndex);\n\n return formatter.format(date);\n}\n\nconst DAY_LABEL_WIDTH = 28;\nconst MONTH_LABEL_HEIGHT = 20;\n\nconst NAMED_ACCENTS = new Set<GnomeNamedAccentColor>([\n 'blue',\n 'green',\n 'yellow',\n 'orange',\n 'red',\n 'purple',\n 'brown',\n]);\n\nfunction accentScale(accentColor: GnomeNamedAccentColor): string[] {\n return [\n 'var(--gnome-card-shade-color)',\n `var(--gnome-${accentColor}-1)`,\n `var(--gnome-${accentColor}-2)`,\n `var(--gnome-${accentColor}-4)`,\n `var(--gnome-${accentColor}-5)`,\n ];\n}\n\nfunction dateToIso(date: Date): string {\n const y = date.getFullYear();\n const m = String(date.getMonth() + 1).padStart(2, '0');\n const d = String(date.getDate()).padStart(2, '0');\n\n return `${y}-${m}-${d}`;\n}\n\nfunction isoToLocal(iso: string): Date {\n const [y, m, d] = iso.split('-').map(Number);\n\n return new Date(y, m - 1, d);\n}\n\nfunction fullDateLabel(iso: string, formatter: Intl.DateTimeFormat): string {\n return formatter.format(isoToLocal(iso));\n}\n\ninterface GridCell {\n iso: string;\n count: number;\n level: number;\n future: boolean;\n}\n\nexport const ContributionGraph = ({\n data,\n maxLevel = 4,\n cellSize = 12,\n cellGap = 3,\n responsive = true,\n minCellSize = 8,\n maxCellSize = 24,\n weekStartDay = 1,\n showMonthLabels = true,\n showDayLabels = true,\n showLegend = true,\n weeks = 52,\n ariaLabel = 'Contribution graph',\n onDayClick,\n tooltipContent,\n className,\n}: ContributionGraphProps) => {\n const monthFormatter = useDateTimeFormatter({ month: 'short' });\n const weekdayFormatter = useDateTimeFormatter({ weekday: 'short' });\n const fullDateFormatter = useDateTimeFormatter({\n weekday: 'long',\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n });\n const { accentColor } = useContext(GnomeContext);\n const graphAccent = NAMED_ACCENTS.has(accentColor as GnomeNamedAccentColor)\n ? (accentColor as GnomeNamedAccentColor)\n : 'green';\n const svgRef = useRef<SVGSVGElement>(null);\n const graphViewportRef = useRef<HTMLDivElement>(null);\n const tooltipRef = useRef<HTMLDivElement>(null);\n const colors = useMemo(() => accentScale(graphAccent), [graphAccent]);\n\n const [availableWidth, setAvailableWidth] = useState<number | null>(null);\n const [focusedCell, setFocusedCell] = useState({ col: 0, row: 0 });\n const [tooltip, setTooltip] = useState<{\n target: SVGRectElement;\n text: string;\n } | null>(null);\n const [tooltipPosition, setTooltipPosition] = useState<{\n left: number;\n top: number;\n } | null>(null);\n\n useEffect(() => {\n if (!responsive) {\n return;\n }\n\n const viewport = graphViewportRef.current;\n\n if (!viewport) {\n return;\n }\n\n const updateWidth = () => {\n const width = viewport.clientWidth || viewport.getBoundingClientRect().width;\n\n if (width > 0) {\n setAvailableWidth(width);\n }\n };\n\n updateWidth();\n\n if (typeof ResizeObserver === 'undefined') {\n window.addEventListener('resize', updateWidth);\n\n return () => window.removeEventListener('resize', updateWidth);\n }\n\n const observer = new ResizeObserver(updateWidth);\n\n observer.observe(viewport);\n\n return () => observer.disconnect();\n }, [responsive]);\n\n useEffect(() => {\n if (!tooltip) {\n return;\n }\n\n const placeTooltip = () => {\n const tooltipNode = tooltipRef.current;\n\n if (!tooltipNode) {\n return;\n }\n\n const cellRect = tooltip.target.getBoundingClientRect();\n const tipRect = tooltipNode.getBoundingClientRect();\n const margin = 8;\n const gap = 6;\n const viewportWidth = document.documentElement.clientWidth || window.innerWidth;\n const viewportHeight = document.documentElement.clientHeight || window.innerHeight;\n const maxLeft = Math.max(margin, viewportWidth - tipRect.width - margin);\n const maxTop = Math.max(margin, viewportHeight - tipRect.height - margin);\n const centeredLeft = cellRect.left + cellRect.width / 2 - tipRect.width / 2;\n const aboveTop = cellRect.top - tipRect.height - gap;\n const preferredTop = aboveTop >= margin ? aboveTop : cellRect.bottom + gap;\n\n setTooltipPosition({\n left: Math.max(margin, Math.min(centeredLeft, maxLeft)),\n top: Math.max(margin, Math.min(preferredTop, maxTop)),\n });\n };\n\n placeTooltip();\n window.addEventListener('resize', placeTooltip);\n window.addEventListener('scroll', placeTooltip, { passive: true, capture: true });\n\n return () => {\n window.removeEventListener('resize', placeTooltip);\n window.removeEventListener('scroll', placeTooltip, { capture: true });\n };\n }, [tooltip]);\n\n const countMap = useMemo(() => {\n const map = new Map<string, number>();\n\n for (const d of data) {\n map.set(d.date, d.count);\n }\n\n return map;\n }, [data]);\n\n const maxCount = useMemo(() => Math.max(1, ...data.map((d) => d.count)), [data]);\n\n const dayLabelW = showDayLabels ? DAY_LABEL_WIDTH : 0;\n const monthLabelH = showMonthLabels ? MONTH_LABEL_HEIGHT : 0;\n const configuredWeeks = Math.max(1, Math.floor(weeks));\n const normalizedMinCellSize = Math.max(1, minCellSize);\n const normalizedMaxCellSize = Math.max(normalizedMinCellSize, maxCellSize);\n const fit = useMemo(() => {\n if (!responsive || availableWidth === null) {\n return { cellSize, weeks: configuredWeeks };\n }\n\n const gridWidth = Math.max(0, availableWidth - dayLabelW);\n const fittedCellSize = (gridWidth + cellGap) / configuredWeeks - cellGap;\n\n if (fittedCellSize >= normalizedMinCellSize) {\n return {\n cellSize: Math.min(normalizedMaxCellSize, fittedCellSize),\n weeks: configuredWeeks,\n };\n }\n\n const fittedWeeks = Math.floor((gridWidth + cellGap) / (normalizedMinCellSize + cellGap));\n\n return {\n cellSize: normalizedMinCellSize,\n weeks: Math.max(1, Math.min(configuredWeeks, fittedWeeks)),\n };\n }, [\n availableWidth,\n cellGap,\n cellSize,\n configuredWeeks,\n dayLabelW,\n normalizedMaxCellSize,\n normalizedMinCellSize,\n responsive,\n ]);\n const visibleWeeks = fit.weeks;\n const resolvedCellSize = fit.cellSize;\n const stride = resolvedCellSize + cellGap;\n\n const { grid, monthLabels } = useMemo(() => {\n const today = new Date();\n\n today.setHours(0, 0, 0, 0);\n\n // Align to start of current week\n const daysFromWeekStart = (today.getDay() - weekStartDay + 7) % 7;\n const lastWeekStart = new Date(today);\n\n lastWeekStart.setDate(today.getDate() - daysFromWeekStart);\n\n const firstDay = new Date(lastWeekStart);\n\n firstDay.setDate(lastWeekStart.getDate() - (visibleWeeks - 1) * 7);\n\n const gridResult: GridCell[][] = [];\n const labels: { col: number; month: string }[] = [];\n\n let lastMonth = -1;\n\n for (let col = 0; col < visibleWeeks; col++) {\n const colStart = new Date(firstDay);\n\n colStart.setDate(firstDay.getDate() + col * 7);\n\n // Month label when the column starts a new month\n if (colStart.getMonth() !== lastMonth) {\n labels.push({\n col,\n month: getShortMonth(colStart.getMonth(), monthFormatter),\n });\n lastMonth = colStart.getMonth();\n }\n\n const column: GridCell[] = [];\n\n for (let row = 0; row < 7; row++) {\n const date = new Date(firstDay);\n\n date.setDate(firstDay.getDate() + col * 7 + row);\n const future = date > today;\n const iso = dateToIso(date);\n const count = future ? 0 : (countMap.get(iso) ?? 0);\n const level =\n count === 0 ? 0 : Math.min(maxLevel, Math.ceil((count / maxCount) * maxLevel));\n\n column.push({ iso, count, level, future });\n }\n\n gridResult.push(column);\n }\n\n return { grid: gridResult, monthLabels: labels };\n }, [countMap, maxCount, maxLevel, visibleWeeks, weekStartDay, monthFormatter]);\n\n // Always label Mon(1), Wed(3), Fri(5) — rows shift with weekStartDay\n const labelRows = useMemo(\n () =>\n [1, 3, 5].map((dayIndex) => ({\n row: (dayIndex - weekStartDay + 7) % 7,\n label: getShortDay(dayIndex, weekdayFormatter),\n })),\n [weekStartDay, weekdayFormatter],\n );\n\n const svgWidth = dayLabelW + visibleWeeks * stride - cellGap;\n const svgHeight = monthLabelH + 7 * stride - cellGap;\n const cellRx = Math.min(4, Math.floor(resolvedCellSize / 3));\n\n useEffect(() => {\n setFocusedCell((current) => ({\n col: Math.min(visibleWeeks - 1, current.col),\n row: current.row,\n }));\n }, [visibleWeeks]);\n\n function focusCell(col: number, row: number) {\n const c = Math.max(0, Math.min(visibleWeeks - 1, col));\n const r = Math.max(0, Math.min(6, row));\n\n setFocusedCell({ col: c, row: r });\n svgRef.current?.querySelector<SVGRectElement>(`[data-col=\"${c}\"][data-row=\"${r}\"]`)?.focus();\n }\n\n function handleCellKey(e: KeyboardEvent, col: number, row: number) {\n const moves: Record<string, [number, number]> = {\n ArrowRight: [col + 1, row],\n ArrowLeft: [col - 1, row],\n ArrowDown: [col, row + 1],\n ArrowUp: [col, row - 1],\n };\n\n if (moves[e.key]) {\n e.preventDefault();\n focusCell(...moves[e.key]);\n } else if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n const cell = grid[col]?.[row];\n\n if (cell && !cell.future) {\n onDayClick?.({ date: cell.iso, count: cell.count });\n }\n }\n }\n\n function handleMouseEnter(e: MouseEvent<SVGRectElement>, text: string) {\n setTooltipPosition(null);\n setTooltip({\n target: e.currentTarget,\n text,\n });\n }\n\n function hideTooltip() {\n setTooltip(null);\n setTooltipPosition(null);\n }\n\n function cellColor(cell: GridCell): string {\n if (cell.future) {\n return colors[0];\n }\n\n return colors[Math.min(cell.level, colors.length - 1)] ?? colors[colors.length - 1];\n }\n\n function cellTooltip(cell: GridCell): string {\n if (cell.future) {\n return fullDateLabel(cell.iso, fullDateFormatter);\n }\n\n const formattedDate = fullDateLabel(cell.iso, fullDateFormatter);\n\n return (\n tooltipContent?.({ date: cell.iso, count: cell.count }) ??\n `${cell.count} contribution${cell.count !== 1 ? 's' : ''} on ${formattedDate}`\n );\n }\n\n return (\n <div className={[styles.wrapper, className].filter(Boolean).join(' ')}>\n <div ref={graphViewportRef} className={styles.graphViewport}>\n <svg\n ref={svgRef}\n width={svgWidth}\n height={svgHeight}\n className={styles.svg}\n aria-label={ariaLabel}\n role=\"img\"\n data-cell-size={resolvedCellSize}\n data-visible-weeks={visibleWeeks}\n >\n {/* Month labels */}\n {showMonthLabels &&\n monthLabels.map(({ col, month }) => (\n <text key={`m-${col}`} x={dayLabelW + col * stride} y={12} className={styles.label}>\n {month}\n </text>\n ))}\n\n {/* Day-of-week labels: Mon, Wed, Fri */}\n {showDayLabels &&\n labelRows.map(({ row, label }) => (\n <text\n key={`d-${row}`}\n x={0}\n y={monthLabelH + row * stride + resolvedCellSize - 1}\n className={styles.label}\n >\n {label}\n </text>\n ))}\n\n {/* Activity grid */}\n <g role=\"grid\" aria-label={ariaLabel}>\n {grid.map((column, col) => (\n <g key={col} role=\"row\">\n {column.map((cell, row) => {\n const tipText = cellTooltip(cell);\n const isFocused = focusedCell.col === col && focusedCell.row === row;\n\n return (\n <rect\n key={`${col}-${row}`}\n data-col={col}\n data-row={row}\n x={dayLabelW + col * stride}\n y={monthLabelH + row * stride}\n width={resolvedCellSize}\n height={resolvedCellSize}\n rx={cellRx}\n fill={cellColor(cell)}\n opacity={cell.future ? 0.35 : 1}\n className={styles.cell}\n role=\"gridcell\"\n aria-label={tipText}\n aria-disabled={cell.future || undefined}\n tabIndex={isFocused ? 0 : -1}\n onClick={() =>\n !cell.future && onDayClick?.({ date: cell.iso, count: cell.count })\n }\n onKeyDown={(e) => handleCellKey(e, col, row)}\n onFocus={() => setFocusedCell({ col, row })}\n onMouseEnter={(e) => handleMouseEnter(e, tipText)}\n onMouseLeave={hideTooltip}\n />\n );\n })}\n </g>\n ))}\n </g>\n </svg>\n </div>\n\n {tooltip &&\n typeof document !== 'undefined' &&\n createPortal(\n <div\n ref={tooltipRef}\n className={styles.tooltip}\n style={\n tooltipPosition\n ? { left: tooltipPosition.left, top: tooltipPosition.top }\n : { visibility: 'hidden', left: 0, top: 0 }\n }\n role=\"tooltip\"\n >\n {tooltip.text}\n </div>,\n document.body,\n )}\n\n {showLegend && (\n <div className={styles.legend}>\n <span className={styles.legendLabel}>Less</span>\n {Array.from({ length: maxLevel + 1 }, (_, i) => (\n <svg\n key={i}\n width={resolvedCellSize}\n height={resolvedCellSize}\n aria-hidden=\"true\"\n className={styles.legendCell}\n >\n <rect\n width={resolvedCellSize}\n height={resolvedCellSize}\n rx={cellRx}\n fill={colors[Math.min(i, colors.length - 1)]}\n />\n </svg>\n ))}\n <span className={styles.legendLabel}>More</span>\n </div>\n )}\n </div>\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./ContributionGraph/ContributionGraph.cjs`);exports.ContributionGraph=e.ContributionGraph;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./ContributionGraph/ContributionGraph.cjs");exports.ContributionGraph=e.ContributionGraph;