@graphprotocol/gds-react 0.1.2 → 0.2.1

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 (433) hide show
  1. package/dist/GDSContext.d.ts +13 -0
  2. package/dist/GDSContext.d.ts.map +1 -0
  3. package/dist/GDSContext.js +4 -0
  4. package/dist/GDSContext.js.map +1 -0
  5. package/dist/GDSProvider.d.ts +13 -19
  6. package/dist/GDSProvider.d.ts.map +1 -1
  7. package/dist/GDSProvider.js +14 -11
  8. package/dist/GDSProvider.js.map +1 -1
  9. package/dist/components/Address.js +2 -2
  10. package/dist/components/Address.meta.d.ts +1 -13
  11. package/dist/components/Address.meta.d.ts.map +1 -1
  12. package/dist/components/Avatar.d.ts.map +1 -1
  13. package/dist/components/Avatar.js +3 -11
  14. package/dist/components/Avatar.js.map +1 -1
  15. package/dist/components/Avatar.meta.d.ts +0 -2
  16. package/dist/components/Avatar.meta.d.ts.map +1 -1
  17. package/dist/components/AvatarGroup.meta.d.ts +8 -2
  18. package/dist/components/AvatarGroup.meta.d.ts.map +1 -1
  19. package/dist/components/Breadcrumbs.meta.d.ts +2 -3
  20. package/dist/components/Breadcrumbs.meta.d.ts.map +1 -1
  21. package/dist/components/Breadcrumbs.meta.js +3 -1
  22. package/dist/components/Breadcrumbs.meta.js.map +1 -1
  23. package/dist/components/Breadcrumbs.parts.d.ts.map +1 -1
  24. package/dist/components/Breadcrumbs.parts.js +13 -21
  25. package/dist/components/Breadcrumbs.parts.js.map +1 -1
  26. package/dist/components/Button.d.ts.map +1 -1
  27. package/dist/components/Button.js +70 -69
  28. package/dist/components/Button.js.map +1 -1
  29. package/dist/components/Button.meta.d.ts +1 -4
  30. package/dist/components/Button.meta.d.ts.map +1 -1
  31. package/dist/components/ButtonGroup.d.ts.map +1 -1
  32. package/dist/components/ButtonGroup.js +1 -5
  33. package/dist/components/ButtonGroup.js.map +1 -1
  34. package/dist/components/ButtonGroup.meta.d.ts +1 -5
  35. package/dist/components/ButtonGroup.meta.d.ts.map +1 -1
  36. package/dist/components/ButtonGroup.meta.js +8 -0
  37. package/dist/components/ButtonGroup.meta.js.map +1 -1
  38. package/dist/components/Card.js +2 -2
  39. package/dist/components/Card.js.map +1 -1
  40. package/dist/components/Card.meta.d.ts +1 -2
  41. package/dist/components/Card.meta.d.ts.map +1 -1
  42. package/dist/components/Card.meta.js +1 -0
  43. package/dist/components/Card.meta.js.map +1 -1
  44. package/dist/components/Checkbox.meta.d.ts +1 -6
  45. package/dist/components/Checkbox.meta.d.ts.map +1 -1
  46. package/dist/components/Checkbox.meta.js +1 -5
  47. package/dist/components/Checkbox.meta.js.map +1 -1
  48. package/dist/components/Chip.meta.d.ts +2 -4
  49. package/dist/components/Chip.meta.d.ts.map +1 -1
  50. package/dist/components/Chip.parts.d.ts.map +1 -1
  51. package/dist/components/Chip.parts.js +1 -9
  52. package/dist/components/Chip.parts.js.map +1 -1
  53. package/dist/components/Cluster.meta.d.ts +8 -2
  54. package/dist/components/Cluster.meta.d.ts.map +1 -1
  55. package/dist/components/CodeBlock.d.ts +1 -1
  56. package/dist/components/CodeBlock.meta.d.ts +2 -4
  57. package/dist/components/CodeBlock.meta.d.ts.map +1 -1
  58. package/dist/components/CodeBlock.parts.d.ts +6 -7
  59. package/dist/components/CodeBlock.parts.d.ts.map +1 -1
  60. package/dist/components/CodeBlock.parts.js +28 -10
  61. package/dist/components/CodeBlock.parts.js.map +1 -1
  62. package/dist/components/CodeInline.js +3 -3
  63. package/dist/components/CodeInline.meta.d.ts +1 -1
  64. package/dist/components/CodeInline.meta.d.ts.map +1 -1
  65. package/dist/components/CopyButton.d.ts +1 -1
  66. package/dist/components/CopyButton.d.ts.map +1 -1
  67. package/dist/components/CopyButton.js +46 -21
  68. package/dist/components/CopyButton.js.map +1 -1
  69. package/dist/components/CopyButton.meta.d.ts +1 -12
  70. package/dist/components/CopyButton.meta.d.ts.map +1 -1
  71. package/dist/components/CopyButton.meta.js +1 -6
  72. package/dist/components/CopyButton.meta.js.map +1 -1
  73. package/dist/components/CurrencyInput.meta.d.ts +1 -6
  74. package/dist/components/CurrencyInput.meta.d.ts.map +1 -1
  75. package/dist/components/CurrencyInput.meta.js +1 -5
  76. package/dist/components/CurrencyInput.meta.js.map +1 -1
  77. package/dist/components/DescriptionList.meta.d.ts +2 -5
  78. package/dist/components/DescriptionList.meta.d.ts.map +1 -1
  79. package/dist/components/DescriptionList.parts.d.ts +3 -0
  80. package/dist/components/DescriptionList.parts.d.ts.map +1 -1
  81. package/dist/components/DescriptionList.parts.js +1 -0
  82. package/dist/components/DescriptionList.parts.js.map +1 -1
  83. package/dist/components/Divider.meta.d.ts +1 -3
  84. package/dist/components/Divider.meta.d.ts.map +1 -1
  85. package/dist/components/Icon.js +4 -4
  86. package/dist/components/Icon.js.map +1 -1
  87. package/dist/components/Icon.meta.d.ts +0 -2
  88. package/dist/components/Icon.meta.d.ts.map +1 -1
  89. package/dist/components/Icon.meta.js +1 -0
  90. package/dist/components/Icon.meta.js.map +1 -1
  91. package/dist/components/Input.d.ts +5 -4
  92. package/dist/components/Input.d.ts.map +1 -1
  93. package/dist/components/Input.js +3 -2
  94. package/dist/components/Input.js.map +1 -1
  95. package/dist/components/Input.meta.d.ts +1 -6
  96. package/dist/components/Input.meta.d.ts.map +1 -1
  97. package/dist/components/Input.meta.js +1 -5
  98. package/dist/components/Input.meta.js.map +1 -1
  99. package/dist/components/Keyboard.js +1 -1
  100. package/dist/components/Keyboard.meta.d.ts +0 -1
  101. package/dist/components/Keyboard.meta.d.ts.map +1 -1
  102. package/dist/components/Label.meta.d.ts +1 -3
  103. package/dist/components/Label.meta.d.ts.map +1 -1
  104. package/dist/components/Link.d.ts +1 -1
  105. package/dist/components/Link.d.ts.map +1 -1
  106. package/dist/components/Link.js +3 -4
  107. package/dist/components/Link.js.map +1 -1
  108. package/dist/components/Link.meta.d.ts +1 -2
  109. package/dist/components/Link.meta.d.ts.map +1 -1
  110. package/dist/components/Link.meta.js +1 -0
  111. package/dist/components/Link.meta.js.map +1 -1
  112. package/dist/components/Menu.meta.d.ts +31 -2
  113. package/dist/components/Menu.meta.d.ts.map +1 -1
  114. package/dist/components/Menu.meta.js +39 -1
  115. package/dist/components/Menu.meta.js.map +1 -1
  116. package/dist/components/Menu.parts.d.ts +22 -32
  117. package/dist/components/Menu.parts.d.ts.map +1 -1
  118. package/dist/components/Menu.parts.js +286 -300
  119. package/dist/components/Menu.parts.js.map +1 -1
  120. package/dist/components/Modal.d.ts +1 -1
  121. package/dist/components/Modal.meta.d.ts +1 -3
  122. package/dist/components/Modal.meta.d.ts.map +1 -1
  123. package/dist/components/Modal.meta.js +1 -1
  124. package/dist/components/Modal.meta.js.map +1 -1
  125. package/dist/components/Modal.parts.d.ts +14 -15
  126. package/dist/components/Modal.parts.d.ts.map +1 -1
  127. package/dist/components/Modal.parts.js +20 -20
  128. package/dist/components/Modal.parts.js.map +1 -1
  129. package/dist/components/OTCInput.js +1 -1
  130. package/dist/components/OTCInput.meta.d.ts +1 -6
  131. package/dist/components/OTCInput.meta.d.ts.map +1 -1
  132. package/dist/components/OTCInput.meta.js +1 -5
  133. package/dist/components/OTCInput.meta.js.map +1 -1
  134. package/dist/components/Pane.d.ts +9 -0
  135. package/dist/components/Pane.d.ts.map +1 -0
  136. package/dist/components/Pane.js +8 -0
  137. package/dist/components/Pane.js.map +1 -0
  138. package/dist/components/Pane.meta.d.ts +20 -0
  139. package/dist/components/Pane.meta.d.ts.map +1 -0
  140. package/dist/components/Pane.meta.js +30 -0
  141. package/dist/components/Pane.meta.js.map +1 -0
  142. package/dist/components/Pane.parts.d.ts +77 -0
  143. package/dist/components/Pane.parts.d.ts.map +1 -0
  144. package/dist/components/Pane.parts.js +412 -0
  145. package/dist/components/Pane.parts.js.map +1 -0
  146. package/dist/components/Radio.meta.d.ts +1 -6
  147. package/dist/components/Radio.meta.d.ts.map +1 -1
  148. package/dist/components/Radio.meta.js +1 -5
  149. package/dist/components/Radio.meta.js.map +1 -1
  150. package/dist/components/Search.js +1 -1
  151. package/dist/components/Search.meta.d.ts +1 -3
  152. package/dist/components/Search.meta.d.ts.map +1 -1
  153. package/dist/components/SegmentedControl.meta.d.ts +2 -3
  154. package/dist/components/SegmentedControl.meta.d.ts.map +1 -1
  155. package/dist/components/SegmentedControl.meta.js +3 -1
  156. package/dist/components/SegmentedControl.meta.js.map +1 -1
  157. package/dist/components/SegmentedControl.parts.d.ts.map +1 -1
  158. package/dist/components/SegmentedControl.parts.js +4 -9
  159. package/dist/components/SegmentedControl.parts.js.map +1 -1
  160. package/dist/components/Status.meta.d.ts +0 -2
  161. package/dist/components/Status.meta.d.ts.map +1 -1
  162. package/dist/components/Stepper.meta.d.ts +1 -2
  163. package/dist/components/Stepper.meta.d.ts.map +1 -1
  164. package/dist/components/Stepper.meta.js +1 -0
  165. package/dist/components/Stepper.meta.js.map +1 -1
  166. package/dist/components/Stepper.parts.d.ts.map +1 -1
  167. package/dist/components/Stepper.parts.js +1 -1
  168. package/dist/components/Stepper.parts.js.map +1 -1
  169. package/dist/components/Switch.meta.d.ts +1 -6
  170. package/dist/components/Switch.meta.d.ts.map +1 -1
  171. package/dist/components/Switch.meta.js +1 -5
  172. package/dist/components/Switch.meta.js.map +1 -1
  173. package/dist/components/TabSet.meta.d.ts +2 -5
  174. package/dist/components/TabSet.meta.d.ts.map +1 -1
  175. package/dist/components/TabSet.meta.js +3 -1
  176. package/dist/components/TabSet.meta.js.map +1 -1
  177. package/dist/components/Tag.meta.d.ts +0 -2
  178. package/dist/components/Tag.meta.d.ts.map +1 -1
  179. package/dist/components/TextArea.meta.d.ts +1 -6
  180. package/dist/components/TextArea.meta.d.ts.map +1 -1
  181. package/dist/components/TextArea.meta.js +1 -5
  182. package/dist/components/TextArea.meta.js.map +1 -1
  183. package/dist/components/ToggleButton.js +2 -2
  184. package/dist/components/ToggleButton.js.map +1 -1
  185. package/dist/components/ToggleButton.meta.d.ts +1 -12
  186. package/dist/components/ToggleButton.meta.d.ts.map +1 -1
  187. package/dist/components/ToggleButton.meta.js +1 -6
  188. package/dist/components/ToggleButton.meta.js.map +1 -1
  189. package/dist/components/Tooltip.d.ts +2 -2
  190. package/dist/components/Tooltip.d.ts.map +1 -1
  191. package/dist/components/Tooltip.js +2 -2
  192. package/dist/components/Tooltip.js.map +1 -1
  193. package/dist/components/Tooltip.meta.d.ts +12 -7
  194. package/dist/components/Tooltip.meta.d.ts.map +1 -1
  195. package/dist/components/Tooltip.meta.js +13 -2
  196. package/dist/components/Tooltip.meta.js.map +1 -1
  197. package/dist/components/Tooltip.parts.d.ts +31 -22
  198. package/dist/components/Tooltip.parts.d.ts.map +1 -1
  199. package/dist/components/Tooltip.parts.js +127 -98
  200. package/dist/components/Tooltip.parts.js.map +1 -1
  201. package/dist/components/base/Addon.meta.d.ts +1 -1
  202. package/dist/components/base/Addon.meta.d.ts.map +1 -1
  203. package/dist/components/base/Addon.meta.js +3 -1
  204. package/dist/components/base/Addon.meta.js.map +1 -1
  205. package/dist/components/base/ButtonOrLink.d.ts +2 -2
  206. package/dist/components/base/ButtonOrLink.d.ts.map +1 -1
  207. package/dist/components/base/ButtonOrLink.parts.d.ts +14 -6
  208. package/dist/components/base/ButtonOrLink.parts.d.ts.map +1 -1
  209. package/dist/components/base/ButtonOrLink.parts.js +54 -65
  210. package/dist/components/base/ButtonOrLink.parts.js.map +1 -1
  211. package/dist/components/base/Checkable.meta.d.ts +1 -2
  212. package/dist/components/base/Checkable.meta.d.ts.map +1 -1
  213. package/dist/components/base/Checkable.parts.d.ts +6 -6
  214. package/dist/components/base/Checkable.parts.d.ts.map +1 -1
  215. package/dist/components/base/Checkable.parts.js +2 -2
  216. package/dist/components/base/Checkable.parts.js.map +1 -1
  217. package/dist/components/base/Field.meta.d.ts +1 -2
  218. package/dist/components/base/Field.meta.d.ts.map +1 -1
  219. package/dist/components/base/Field.parts.d.ts +5 -4
  220. package/dist/components/base/Field.parts.d.ts.map +1 -1
  221. package/dist/components/base/Field.parts.js +1 -1
  222. package/dist/components/base/Field.parts.js.map +1 -1
  223. package/dist/components/base/MaybeButtonOrLink.d.ts +20 -3
  224. package/dist/components/base/MaybeButtonOrLink.d.ts.map +1 -1
  225. package/dist/components/base/MaybeButtonOrLink.js +5 -3
  226. package/dist/components/base/MaybeButtonOrLink.js.map +1 -1
  227. package/dist/components/base/Portal.d.ts +1 -1
  228. package/dist/components/base/Portal.d.ts.map +1 -1
  229. package/dist/components/base/Portal.js +3 -6
  230. package/dist/components/base/Portal.js.map +1 -1
  231. package/dist/components/base/Presence.d.ts +157 -0
  232. package/dist/components/base/Presence.d.ts.map +1 -0
  233. package/dist/components/base/Presence.js +808 -0
  234. package/dist/components/base/Presence.js.map +1 -0
  235. package/dist/components/base/Render.d.ts +21 -6
  236. package/dist/components/base/Render.d.ts.map +1 -1
  237. package/dist/components/base/Render.js +3 -2
  238. package/dist/components/base/Render.js.map +1 -1
  239. package/dist/components/base/Transition.js +2 -2
  240. package/dist/components/base/Transition.meta.d.ts +1 -1
  241. package/dist/components/base/Transition.meta.d.ts.map +1 -1
  242. package/dist/components/base/Transition.meta.js +1 -0
  243. package/dist/components/base/Transition.meta.js.map +1 -1
  244. package/dist/components/base/index.d.ts +2 -2
  245. package/dist/components/base/index.d.ts.map +1 -1
  246. package/dist/components/base/index.js +2 -2
  247. package/dist/components/base/index.js.map +1 -1
  248. package/dist/components/index.d.ts +3 -1
  249. package/dist/components/index.d.ts.map +1 -1
  250. package/dist/components/index.js +3 -1
  251. package/dist/components/index.js.map +1 -1
  252. package/dist/hooks/index.d.ts +1 -0
  253. package/dist/hooks/index.d.ts.map +1 -1
  254. package/dist/hooks/index.js +1 -0
  255. package/dist/hooks/index.js.map +1 -1
  256. package/dist/hooks/useCSSProp.d.ts.map +1 -1
  257. package/dist/hooks/useCSSProp.js +7 -7
  258. package/dist/hooks/useCSSProp.js.map +1 -1
  259. package/dist/hooks/useCSSProps.d.ts +11 -13
  260. package/dist/hooks/useCSSProps.d.ts.map +1 -1
  261. package/dist/hooks/useCSSProps.js +11 -19
  262. package/dist/hooks/useCSSProps.js.map +1 -1
  263. package/dist/hooks/useCSSPropsPolyfill.d.ts +1 -1
  264. package/dist/hooks/useCSSPropsPolyfill.d.ts.map +1 -1
  265. package/dist/hooks/useCSSPropsPolyfill.js +12 -20
  266. package/dist/hooks/useCSSPropsPolyfill.js.map +1 -1
  267. package/dist/hooks/useCSSState.d.ts.map +1 -1
  268. package/dist/hooks/useCSSState.js +7 -3
  269. package/dist/hooks/useCSSState.js.map +1 -1
  270. package/dist/hooks/useControlled.d.ts.map +1 -1
  271. package/dist/hooks/useControlled.js +6 -4
  272. package/dist/hooks/useControlled.js.map +1 -1
  273. package/dist/hooks/useEffectWithRefDeps.d.ts +2 -2
  274. package/dist/hooks/useEffectWithRefDeps.d.ts.map +1 -1
  275. package/dist/hooks/useEffectWithRefDeps.js +1 -1
  276. package/dist/hooks/useEffectWithRefDeps.js.map +1 -1
  277. package/dist/hooks/useFirstRender.d.ts +14 -0
  278. package/dist/hooks/useFirstRender.d.ts.map +1 -0
  279. package/dist/hooks/useFirstRender.js +20 -0
  280. package/dist/hooks/useFirstRender.js.map +1 -0
  281. package/dist/hooks/useGDS.d.ts +1 -1
  282. package/dist/hooks/useGDS.js +1 -1
  283. package/dist/hooks/useGDS.js.map +1 -1
  284. package/dist/hooks/usePrevious.d.ts +6 -4
  285. package/dist/hooks/usePrevious.d.ts.map +1 -1
  286. package/dist/hooks/usePrevious.js +6 -4
  287. package/dist/hooks/usePrevious.js.map +1 -1
  288. package/dist/hooks/useRefWithInit.d.ts +2 -2
  289. package/dist/hooks/useRefWithInit.d.ts.map +1 -1
  290. package/dist/hooks/useRefWithInit.js.map +1 -1
  291. package/dist/hooks/useStyleObserver.d.ts +2 -2
  292. package/dist/hooks/useStyleObserver.d.ts.map +1 -1
  293. package/dist/hooks/useStyleObserver.js +1 -1
  294. package/dist/hooks/useStyleObserver.js.map +1 -1
  295. package/dist/icons/CalendarDynamicIcon.d.ts +8 -5
  296. package/dist/icons/CalendarDynamicIcon.d.ts.map +1 -1
  297. package/dist/icons/CalendarDynamicIcon.js +5 -2
  298. package/dist/icons/CalendarDynamicIcon.js.map +1 -1
  299. package/dist/icons/CopyInteractiveIcon.d.ts +5 -4
  300. package/dist/icons/CopyInteractiveIcon.d.ts.map +1 -1
  301. package/dist/icons/CopyInteractiveIcon.js +2 -2
  302. package/dist/icons/CopyInteractiveIcon.js.map +1 -1
  303. package/dist/icons/SidebarLeftInteractiveIcon.d.ts +4 -3
  304. package/dist/icons/SidebarLeftInteractiveIcon.d.ts.map +1 -1
  305. package/dist/icons/SidebarLeftInteractiveIcon.js +2 -2
  306. package/dist/icons/SidebarLeftInteractiveIcon.js.map +1 -1
  307. package/dist/icons/SidebarRightInteractiveIcon.d.ts +4 -3
  308. package/dist/icons/SidebarRightInteractiveIcon.d.ts.map +1 -1
  309. package/dist/icons/SidebarRightInteractiveIcon.js +2 -2
  310. package/dist/icons/SidebarRightInteractiveIcon.js.map +1 -1
  311. package/dist/tailwind-plugin.d.ts.map +1 -1
  312. package/dist/tailwind-plugin.js +8 -5
  313. package/dist/tailwind-plugin.js.map +1 -1
  314. package/dist/utils/InlineCounter.d.ts +3 -0
  315. package/dist/utils/InlineCounter.d.ts.map +1 -0
  316. package/dist/utils/InlineCounter.js +7 -0
  317. package/dist/utils/InlineCounter.js.map +1 -0
  318. package/dist/utils/RenderCount.d.ts +3 -0
  319. package/dist/utils/RenderCount.d.ts.map +1 -0
  320. package/dist/utils/RenderCount.js +7 -0
  321. package/dist/utils/RenderCount.js.map +1 -0
  322. package/dist/utils/cn.d.ts +3 -1
  323. package/dist/utils/cn.d.ts.map +1 -1
  324. package/dist/utils/cn.js +3 -1
  325. package/dist/utils/cn.js.map +1 -1
  326. package/dist/utils/getCSSPropsAttributes.d.ts +10 -3
  327. package/dist/utils/getCSSPropsAttributes.d.ts.map +1 -1
  328. package/dist/utils/getCSSPropsAttributes.js +4 -5
  329. package/dist/utils/getCSSPropsAttributes.js.map +1 -1
  330. package/dist/utils/index.d.ts +2 -0
  331. package/dist/utils/index.d.ts.map +1 -1
  332. package/dist/utils/index.js +2 -0
  333. package/dist/utils/index.js.map +1 -1
  334. package/dist/utils/splitProps.d.ts +1 -4
  335. package/dist/utils/splitProps.d.ts.map +1 -1
  336. package/dist/utils/splitProps.js +2 -7
  337. package/dist/utils/splitProps.js.map +1 -1
  338. package/dist/utils/trimReactNode.d.ts +10 -8
  339. package/dist/utils/trimReactNode.d.ts.map +1 -1
  340. package/dist/utils/trimReactNode.js +10 -8
  341. package/dist/utils/trimReactNode.js.map +1 -1
  342. package/package.json +21 -21
  343. package/src/GDSContext.ts +16 -0
  344. package/src/GDSProvider.tsx +31 -40
  345. package/src/components/Address.tsx +2 -2
  346. package/src/components/Avatar.tsx +8 -12
  347. package/src/components/Breadcrumbs.meta.ts +3 -1
  348. package/src/components/Breadcrumbs.parts.tsx +16 -28
  349. package/src/components/Button.tsx +114 -104
  350. package/src/components/ButtonGroup.meta.ts +8 -0
  351. package/src/components/ButtonGroup.tsx +1 -5
  352. package/src/components/Card.meta.ts +1 -0
  353. package/src/components/Card.tsx +2 -2
  354. package/src/components/Checkbox.meta.ts +1 -5
  355. package/src/components/Chip.parts.tsx +1 -11
  356. package/src/components/CodeBlock.parts.tsx +75 -50
  357. package/src/components/CodeInline.tsx +3 -3
  358. package/src/components/CopyButton.meta.ts +1 -6
  359. package/src/components/CopyButton.tsx +50 -27
  360. package/src/components/CurrencyInput.meta.ts +1 -5
  361. package/src/components/DescriptionList.parts.tsx +1 -0
  362. package/src/components/Icon.meta.ts +1 -0
  363. package/src/components/Icon.tsx +4 -4
  364. package/src/components/Input.meta.ts +1 -5
  365. package/src/components/Input.tsx +6 -7
  366. package/src/components/Keyboard.tsx +1 -1
  367. package/src/components/Link.meta.ts +1 -0
  368. package/src/components/Link.tsx +4 -5
  369. package/src/components/Menu.meta.ts +39 -1
  370. package/src/components/Menu.parts.tsx +554 -547
  371. package/src/components/Modal.meta.ts +1 -1
  372. package/src/components/Modal.parts.tsx +40 -46
  373. package/src/components/OTCInput.meta.ts +1 -5
  374. package/src/components/OTCInput.tsx +1 -1
  375. package/src/components/Pane.meta.ts +31 -0
  376. package/src/components/Pane.parts.tsx +713 -0
  377. package/src/components/Pane.tsx +17 -0
  378. package/src/components/Radio.meta.ts +1 -5
  379. package/src/components/Search.tsx +1 -1
  380. package/src/components/SegmentedControl.meta.ts +3 -1
  381. package/src/components/SegmentedControl.parts.tsx +7 -10
  382. package/src/components/Stepper.meta.ts +1 -0
  383. package/src/components/Stepper.parts.tsx +3 -1
  384. package/src/components/Switch.meta.ts +1 -5
  385. package/src/components/TabSet.meta.ts +3 -1
  386. package/src/components/TextArea.meta.ts +1 -5
  387. package/src/components/ToggleButton.meta.ts +1 -6
  388. package/src/components/ToggleButton.tsx +1 -1
  389. package/src/components/Tooltip.meta.ts +13 -2
  390. package/src/components/Tooltip.parts.tsx +241 -169
  391. package/src/components/Tooltip.tsx +2 -2
  392. package/src/components/base/Addon.meta.ts +3 -1
  393. package/src/components/base/ButtonOrLink.parts.tsx +118 -97
  394. package/src/components/base/ButtonOrLink.tsx +1 -0
  395. package/src/components/base/Checkable.parts.tsx +6 -13
  396. package/src/components/base/Field.parts.tsx +5 -5
  397. package/src/components/base/MaybeButtonOrLink.tsx +26 -5
  398. package/src/components/base/Portal.tsx +5 -7
  399. package/src/components/base/Presence.tsx +1375 -0
  400. package/src/components/base/Render.tsx +37 -15
  401. package/src/components/base/Transition.meta.ts +1 -0
  402. package/src/components/base/Transition.tsx +2 -2
  403. package/src/components/base/index.ts +9 -2
  404. package/src/components/index.ts +11 -2
  405. package/src/hooks/index.ts +1 -0
  406. package/src/hooks/useCSSProp.ts +7 -9
  407. package/src/hooks/useCSSProps.ts +13 -22
  408. package/src/hooks/useCSSPropsPolyfill.ts +15 -23
  409. package/src/hooks/useCSSState.ts +11 -6
  410. package/src/hooks/useControlled.ts +16 -8
  411. package/src/hooks/useEffectWithRefDeps.ts +2 -2
  412. package/src/hooks/useFirstRender.ts +36 -0
  413. package/src/hooks/useGDS.ts +1 -1
  414. package/src/hooks/usePrevious.ts +6 -4
  415. package/src/hooks/useRefWithInit.ts +2 -2
  416. package/src/hooks/useStyleObserver.ts +6 -2
  417. package/src/icons/CalendarDynamicIcon.tsx +16 -6
  418. package/src/icons/CopyInteractiveIcon.tsx +10 -5
  419. package/src/icons/SidebarLeftInteractiveIcon.tsx +9 -5
  420. package/src/icons/SidebarRightInteractiveIcon.tsx +9 -5
  421. package/src/tailwind-plugin.ts +8 -5
  422. package/src/utils/InlineCounter.tsx +17 -0
  423. package/src/utils/RenderCount.tsx +7 -0
  424. package/src/utils/cn.ts +3 -1
  425. package/src/utils/getCSSPropsAttributes.ts +13 -8
  426. package/src/utils/index.ts +2 -0
  427. package/src/utils/splitProps.ts +9 -9
  428. package/src/utils/trimReactNode.tsx +10 -8
  429. package/dist/components/base/ButtonOrLink.meta.d.ts +0 -2
  430. package/dist/components/base/ButtonOrLink.meta.d.ts.map +0 -1
  431. package/dist/components/base/ButtonOrLink.meta.js +0 -6
  432. package/dist/components/base/ButtonOrLink.meta.js.map +0 -1
  433. package/src/components/base/ButtonOrLink.meta.ts +0 -6
@@ -1,13 +1,7 @@
1
1
  'use client'
2
2
 
3
- import {
4
- useCallback,
5
- useEffect,
6
- useRef,
7
- useState,
8
- type ComponentProps,
9
- type CSSProperties,
10
- } from 'react'
3
+ import { useCallback, useRef, useState, type ComponentProps, type CSSProperties } from 'react'
4
+ import { useRenderCount, useThrottledEffect } from '@react-hookz/web'
11
5
  import { isEqual } from '@ver0/deep-equal'
12
6
 
13
7
  import type { GDSComponentProps } from '@graphprotocol/gds-css'
@@ -84,24 +78,16 @@ export function BreadcrumbsRoot({
84
78
  )
85
79
  }, [])
86
80
 
87
- // Call `updateWrappedCount` after every render and on resize
88
- const firstRender = useRef(true)
89
- useEffect(() => {
90
- /**
91
- * The timeout prevents a "Maximum update depth exceeded" error in the unlikely event of an
92
- * infinite loop due to `hiddenItems` causing a layout change that makes items wrap differently.
93
- * But we don't want it on the first render because it can cause a flash of incorrect state.
94
- */
95
- if (firstRender.current) {
96
- firstRender.current = false
97
- updateWrappedCount()
98
- return
99
- }
100
- const timeout = window.setTimeout(() => {
101
- updateWrappedCount()
102
- }, 0)
103
- return () => window.clearTimeout(timeout)
104
- })
81
+ /**
82
+ * Call `updateWrappedCount` after every render, with `useThrottledEffect` to prevent a "Maximum
83
+ * update depth exceeded" error in the unlikely event of an infinite loop due to `hiddenItems`
84
+ * causing a layout change that makes items wrap differently (change `-ms-10` below to `-ms-20` to
85
+ * see how that can happen).
86
+ */
87
+ const renderCount = useRenderCount()
88
+ useThrottledEffect(updateWrappedCount, [renderCount], 1)
89
+
90
+ // Call `updateWrappedCount` on resize
105
91
  const resizeObserverRef = useRef<ResizeObserver | null>(null)
106
92
  const hiddenContainerRefCallback = useCallback(
107
93
  (element: HTMLDivElement | null) => {
@@ -123,7 +109,7 @@ export function BreadcrumbsRoot({
123
109
  ref={cssPropsPolyfillPassedRef}
124
110
  aria-label={ariaLabel}
125
111
  className={cn(
126
- 'gds-breadcrumbs isolate root-grid *:col-span-full *:row-span-full u:max-w-full u:text-14',
112
+ 'gds-breadcrumbs root-grid *:col-span-full *:row-span-full u:max-w-full u:text-14 i:h-max',
127
113
  className,
128
114
  )}
129
115
  {...getCSSPropsAttributes(BreadcrumbsMeta, { align }, style)}
@@ -184,7 +170,8 @@ export function BreadcrumbsRoot({
184
170
  <DotsThreeIcon alt="Show hidden items" className="top-1.25" />
185
171
  </Button>
186
172
  }
187
- position={{ align: 'center', gap: 4 }}
173
+ align="center"
174
+ gap={4}
188
175
  >
189
176
  {hiddenItems.map((item, index) => (
190
177
  <Menu.Item
@@ -234,6 +221,7 @@ BreadcrumbsRoot.displayName = 'Breadcrumbs'
234
221
  export declare namespace BreadcrumbsItemProps {
235
222
  interface BaseProps extends GDSComponentProps<typeof BreadcrumbsItemMeta> {
236
223
  addonBefore?: AddonValue | undefined
224
+ // TODO: Add `addonAfter` prop, e.g. for `CaretDownInteractiveIcon` when `Breadcrumbs.Item` is a menu trigger?
237
225
  /**
238
226
  * Whether this breadcrumb item represents the current page. Defaults to `true` if no `href` is
239
227
  * passed, or `false` otherwise.
@@ -10,7 +10,7 @@ import { cn, getCSSPropsAttributes, isReactNode } from '../utils/index.ts'
10
10
  import { renderAddon, type AddonValue } from './base/Addon.tsx'
11
11
  import { ButtonOrLink, type ButtonOrLinkProps } from './base/ButtonOrLink.tsx'
12
12
  import { ButtonMeta } from './Button.meta.ts'
13
- import { Tooltip, useCollectedTooltip, type TooltipProps } from './Tooltip.tsx'
13
+ import { Tooltip, type TooltipProps } from './Tooltip.tsx'
14
14
 
15
15
  export declare namespace ButtonProps {
16
16
  interface BaseProps extends GDSComponentProps<typeof ButtonMeta> {
@@ -86,114 +86,124 @@ export function Button({
86
86
  const addonAfter = getAddon(passedAddonAfter, loading)
87
87
  const replaceChildrenWithLoading = loading && !addonBefore && !addonAfter
88
88
 
89
- const { onCollect, collectedContent } = useCollectedTooltip()
90
- let tooltipProps: Omit<TooltipProps, 'children'> = { content: collectedContent }
91
- if (tooltip !== undefined) {
92
- tooltipProps = isReactNode(tooltip) ? { content: tooltip } : { ...tooltipProps, ...tooltip }
93
- }
94
-
95
89
  return (
96
- <Tooltip {...tooltipProps}>
97
- <ButtonOrLink
98
- ref={cssPropsPolyfillStatePassedRef}
99
- disabled={disabled || (loading ? 'focusable' : false)}
100
- aria-busy={loading || undefined}
101
- data-variant={cssProps.variant}
102
- data-hide-label={cssProps.hideLabel || undefined}
103
- className={cn(
104
- `gds-button root-flex flex-col u:size-max u:max-w-full u:font-regular u:outline-0
105
- u:checked:state-checked
106
- u:hover:state-hover
107
- u:focus-visible:state-focus
108
- u:active:state-active
109
- u:disabled:state-disabled
110
- u:disabled:state-idle
111
- ${/* Determine whether the button is "addon-only" (`0` means no and `auto` means yes; we can improve this when `if()` is supported, e.g. `min-w-[if(style(--gds-state-addon-only):auto;else:0)]`) */ ''}
112
- state-[addon-only=0]
113
- data-hide-label:state-[addon-only=auto]
114
- not-has-nested/button-children:state-[addon-only=auto]
115
- has-nested-has-addon-compatible-only/button-children:state-[addon-only=auto]
116
- ${/* Ensure an addon-only button does not get squished in a flex container (like a button group) */ ''}
117
- u:min-w-(--gds-state-addon-only)
118
- ${/* Ensure a button in a horizontal button group grows by default, except if it is addon-only */ ''}
119
- u:@prop-orientation-horizontal/button-group:has-nested-not-has-addon-compatible-only/button-children:grow
120
- ${/* But if the button group is `fullWidth`, then all the buttons it contains should be equal width, regardless of their content */ ''}
121
- u:@prop-orientation-horizontal/button-group:@prop-full-width-true/button-group:grow
122
- u:@prop-orientation-horizontal/button-group:@prop-full-width-true/button-group:basis-0
123
- ${/* Extend the tap area of a naked button */ ''}
124
- data-[variant=naked]:before:absolute
125
- data-[variant=naked]:before:-inset-2`,
126
- className,
127
- )}
128
- {...state.polyfillAttributes}
129
- {...getCSSPropsAttributes(ButtonMeta, { variant, size, hideLabel }, style)}
130
- {...cssPropsPolyfillAttributes}
131
- {...props}
132
- >
133
- <span
134
- className={`
135
- nested/button-paint pointer-events-none flex h-(--height) max-w-full min-w-full grow items-center justify-center
136
- rounded-(--gds-button-radius) border-(length:--border-width) border-(--gds-button-border)
137
- bg-(--gds-button-bg) text-(--gds-button-fg) transition [--border-width:1px]
138
- @state-[addon-only=auto]/button:w-(--height)
139
- @prop-variant-naked/button:transition-[color]
140
- @prop-variant-naked/button:[--border-width:0px]
141
- @prop-size-xsmall/button:px-1.25
142
- @prop-size-xsmall/button:text-12
143
- @prop-size-xsmall/button:[--height:--spacing(7)]
144
- @prop-size-small/button:px-1.75
145
- @prop-size-small/button:text-12
146
- @prop-size-small/button:[--height:--spacing(8)]
147
- @prop-size-medium/button:px-1.75
148
- @prop-size-medium/button:text-14
149
- @prop-size-medium/button:[--height:--spacing(10)]
150
- @prop-size-large/button:px-2.75
151
- @prop-size-large/button:text-16
152
- @prop-size-large/button:[--height:--spacing(12)]
153
- u:*:transition-opacity
154
- u:*:@state-disabled/button:opacity-disabled
155
- u:*:@state-disabled/button:grayscale
156
- u:@prop-size-xsmall/button:addon-small
157
- u:@prop-size-small/button:addon-small
158
- u:@prop-size-medium/button:addon-medium
159
- u:@prop-size-large/button:addon-large
160
- i:@state-active/button:transition-none
161
- i:@prop-variant-naked/button:px-0
162
- i:@prop-variant-naked/button:[--height:1lh]
163
- `}
90
+ <ButtonOrLink
91
+ ref={cssPropsPolyfillStatePassedRef}
92
+ disabled={disabled || (loading ? 'focusable' : false)}
93
+ aria-busy={loading || undefined}
94
+ data-variant={cssProps.variant}
95
+ data-hide-label={cssProps.hideLabel || undefined}
96
+ className={cn(
97
+ `gds-button root-flex flex-col u:size-max u:max-w-full u:outline-0
98
+ u:checked:state-checked
99
+ u:hover:state-hover
100
+ u:focus-visible:state-focus
101
+ u:active:state-active
102
+ u:disabled:state-disabled
103
+ u:disabled:state-idle
104
+ ${/* Determine whether the button is "addon-only" (`0` means no and `auto` means yes; we can improve this when `if()` is supported, e.g. `min-w-[if(style(--gds-state-addon-only):auto;else:0)]`) */ ''}
105
+ state-[addon-only=0]
106
+ data-hide-label:state-[addon-only=auto]
107
+ not-has-nested/button-children:state-[addon-only=auto]
108
+ has-nested-has-addon-compatible-only/button-children:state-[addon-only=auto]
109
+ ${/* Ensure an addon-only button does not get squished in a flex container (like a button group) */ ''}
110
+ u:min-w-(--gds-state-addon-only)
111
+ ${/* Ensure a button in a horizontal button group grows by default, except if it is addon-only */ ''}
112
+ u:@prop-orientation-horizontal/button-group:has-nested-not-has-addon-compatible-only/button-children:grow
113
+ ${/* But if the button group is `fullWidth`, then all the buttons it contains should be equal width, regardless of their content */ ''}
114
+ u:@prop-orientation-horizontal/button-group:@prop-full-width-true/button-group:grow
115
+ u:@prop-orientation-horizontal/button-group:@prop-full-width-true/button-group:basis-0
116
+ ${/* In a button group, the group itself should be the stacking context */ ''}
117
+ u:in-button-group:isolation-auto
118
+ ${/* Extend the tap area of a naked button */ ''}
119
+ data-[variant=naked]:before:absolute
120
+ data-[variant=naked]:before:-inset-2`,
121
+ className,
122
+ )}
123
+ {...state.polyfillAttributes}
124
+ {...getCSSPropsAttributes(ButtonMeta, { variant, size, hideLabel }, style)}
125
+ {...cssPropsPolyfillAttributes}
126
+ {...props}
127
+ render={(renderProps, { Element, elementProps }) => (
128
+ <Tooltip
129
+ {...(isReactNode(tooltip) ? { content: tooltip } : tooltip)}
130
+ triggerProps={renderProps}
164
131
  >
165
- {/* Focus ring (rendered separately for better spacing in naked buttons) */}
166
- <span
167
- className={`
168
- absolute -inset-px rounded-inherit opacity-100 filter-none
169
- @state-focus/button:outline
170
- @prop-variant-naked/button:-inset-0.5
171
- `}
172
- />
173
- {addonBefore ? <ButtonAddon side="before">{addonBefore}</ButtonAddon> : null}
174
- {children ? (
132
+ <Element {...elementProps}>
133
+ {/* Prevent the extended tap area of a naked button from overlapping the tap area of another naked button in the same group */}
175
134
  <span
176
- data-loading={replaceChildrenWithLoading || undefined}
177
- className={cn(
178
- `nested/button-children
179
- truncate
180
- data-loading:invisible
181
- @prop-hide-label-true/button:not-has-addon-compatible:sr-only
182
- u:@prop-size-xsmall/button:px-0.5
183
- u:@prop-size-small/button:px-0.5
184
- u:@prop-size-medium/button:px-1
185
- u:@prop-size-large/button:px-1
186
- u:i:@state-[addon-only=auto]/button:px-0`,
187
- )}
135
+ className={`
136
+ absolute inset-[calc(-1*var(--gds-button-group-gap)/2)] z-10
137
+ not-in-button-group:hidden
138
+ @prop-not-variant-naked/button:hidden
139
+ `}
140
+ />
141
+ <span
142
+ className={`
143
+ nested/button-paint pointer-events-none flex h-(--height) max-w-full min-w-full grow items-center justify-center
144
+ rounded-(--gds-button-radius) border-(length:--border-width) border-(--gds-button-border)
145
+ bg-(--gds-button-bg) text-(--gds-button-fg) transition [--border-width:1px]
146
+ @state-[addon-only=auto]/button:w-(--height)
147
+ @prop-variant-naked/button:transition-[color]
148
+ @prop-variant-naked/button:[--border-width:0px]
149
+ @prop-size-xsmall/button:px-1.25
150
+ @prop-size-xsmall/button:text-12
151
+ @prop-size-xsmall/button:[--height:--spacing(7)]
152
+ @prop-size-small/button:px-1.75
153
+ @prop-size-small/button:text-12
154
+ @prop-size-small/button:[--height:--spacing(8)]
155
+ @prop-size-medium/button:px-1.75
156
+ @prop-size-medium/button:text-14
157
+ @prop-size-medium/button:[--height:--spacing(10)]
158
+ @prop-size-large/button:px-2.75
159
+ @prop-size-large/button:text-16
160
+ @prop-size-large/button:[--height:--spacing(12)]
161
+ u:*:transition-opacity
162
+ u:*:@state-disabled/button:opacity-disabled
163
+ u:*:@state-disabled/button:grayscale
164
+ u:@prop-size-xsmall/button:addon-small
165
+ u:@prop-size-small/button:addon-small
166
+ u:@prop-size-medium/button:addon-medium
167
+ u:@prop-size-large/button:addon-large
168
+ i:@state-active/button:transition-none
169
+ i:@prop-variant-naked/button:px-0
170
+ i:@prop-variant-naked/button:[--height:1lh]
171
+ `}
188
172
  >
189
- <Tooltip.Collector onCollect={onCollect}>{children}</Tooltip.Collector>
173
+ {/* Focus ring (rendered separately for better spacing in naked buttons) */}
174
+ <span
175
+ className={`
176
+ absolute -inset-px rounded-inherit opacity-100 filter-none
177
+ @state-focus/button:outline
178
+ @prop-variant-naked/button:-inset-0.5
179
+ `}
180
+ />
181
+ {addonBefore ? <ButtonAddon side="before">{addonBefore}</ButtonAddon> : null}
182
+ {children ? (
183
+ <span
184
+ data-loading={replaceChildrenWithLoading || undefined}
185
+ className={cn(
186
+ `nested/button-children
187
+ truncate
188
+ data-loading:invisible
189
+ @prop-hide-label-true/button:not-has-addon-compatible:sr-only
190
+ u:@prop-size-xsmall/button:px-0.5
191
+ u:@prop-size-small/button:px-0.5
192
+ u:@prop-size-medium/button:px-1
193
+ u:@prop-size-large/button:px-1
194
+ u:i:@state-[addon-only=auto]/button:px-0`,
195
+ )}
196
+ >
197
+ <Tooltip.Collector>{children}</Tooltip.Collector>
198
+ </span>
199
+ ) : null}
200
+ {replaceChildrenWithLoading ? loadingIcon : null}
201
+ {addonAfter ? <ButtonAddon side="after">{addonAfter}</ButtonAddon> : null}
190
202
  </span>
191
- ) : null}
192
- {replaceChildrenWithLoading ? loadingIcon : null}
193
- {addonAfter ? <ButtonAddon side="after">{addonAfter}</ButtonAddon> : null}
194
- </span>
195
- </ButtonOrLink>
196
- </Tooltip>
203
+ </Element>
204
+ </Tooltip>
205
+ )}
206
+ />
197
207
  )
198
208
  }
199
209
 
@@ -29,4 +29,12 @@ export const ButtonGroupMeta = createComponent('ButtonGroup', {
29
29
  defaultValue: false,
30
30
  },
31
31
  },
32
+ vars: {
33
+ gap: {
34
+ '@variant @prop-size-xsmall/button-group': '--spacing(1)',
35
+ '@variant @prop-size-small/button-group': '--spacing(1.5)',
36
+ '@variant @prop-size-medium/button-group': '--spacing(2)',
37
+ '@variant @prop-size-large/button-group': '--spacing(2)',
38
+ },
39
+ },
32
40
  })
@@ -77,11 +77,7 @@ export function ButtonGroup({
77
77
  * mentioned, vertical in horizontal doesn't make sense.
78
78
  */
79
79
  className={`
80
- flex items-center
81
- @prop-size-xsmall/button-group:gap-1
82
- @prop-size-small/button-group:gap-1.5
83
- @prop-size-medium/button-group:gap-2
84
- @prop-size-large/button-group:gap-2
80
+ flex items-center gap-(--gds-button-group-gap)
85
81
  @prop-orientation-vertical/button-group:not-in-button-group-[[data-gds-prop-polyfill-orientation=gds-horizontal]]:flex-col
86
82
  i:*:@prop-orientation-vertical/button-group:not-in-button-group-[[data-gds-prop-polyfill-orientation=gds-horizontal]]:w-full
87
83
  `}
@@ -1,6 +1,7 @@
1
1
  import { createComponent } from '@graphprotocol/gds-css'
2
2
 
3
3
  export const CardMeta = createComponent('Card', {
4
+ isolate: 'allow-inheritance',
4
5
  cssProps: {
5
6
  /** @default 'secondary' */
6
7
  variant: {
@@ -122,7 +122,7 @@ export function Card({
122
122
  {...state.polyfillAttributes}
123
123
  {...nestedProps}
124
124
  {...(as !== undefined && ({ as: 'span' } as Record<string, unknown>))}
125
- render={(renderProps, { Element, category, target }) => {
125
+ render={(renderProps, { Element, elementProps, category, target }) => {
126
126
  const renderChildrenOutside = interactiveContent === true && category !== 'other'
127
127
  const contentId =
128
128
  renderChildrenOutside && !('aria-label' in props || 'aria-labelledby' in props)
@@ -130,7 +130,7 @@ export function Card({
130
130
  : undefined
131
131
  return (
132
132
  <>
133
- <Element aria-labelledby={contentId} {...renderProps}>
133
+ <Element aria-labelledby={contentId} {...renderProps} {...elementProps}>
134
134
  {/**
135
135
  * This `span` ensures that the rounded corners are always hoverable/clickable, instead of only when
136
136
  * `children` includes an absolutely-positioned element that fills the card, and not even
@@ -3,9 +3,5 @@ import { createComponent } from '@graphprotocol/gds-css'
3
3
  import { CheckableMeta } from './base/Checkable.meta.ts'
4
4
 
5
5
  export const CheckboxMeta = createComponent('Checkbox', {
6
- containerName: 'gds-checkable',
7
- cssProps: {
8
- /** @default 'medium' */
9
- size: CheckableMeta.cssProps.size,
10
- },
6
+ extends: CheckableMeta,
11
7
  })
@@ -170,17 +170,7 @@ export function ChipRoot({
170
170
  {/* Ensure rounded corners are clickable */}
171
171
  <span className="absolute inset-0 not-in-clickable:hidden" />
172
172
  {addonBefore ? <ChipAddon side="before">{renderAddon(addonBefore)}</ChipAddon> : null}
173
- <span
174
- className={`
175
- flex items-baseline
176
- @prop-size-small/chip:gap-0.5
177
- @prop-size-small/chip:px-0.5
178
- @prop-size-medium/chip:gap-1
179
- @prop-size-medium/chip:px-1
180
- @prop-size-large/chip:gap-1
181
- @prop-size-large/chip:px-1
182
- `}
183
- >
173
+ <span className="flex items-baseline gap-1 px-1">
184
174
  <span className="truncate">{children}</span>
185
175
  {count ? (
186
176
  <span
@@ -39,7 +39,9 @@ import {
39
39
 
40
40
  import { useControlled, useCSSPropsPolyfill, useGDS } from '../hooks/index.ts'
41
41
  import { cn, getCSSPropsAttributes, type Stringifiable } from '../utils/index.ts'
42
+ import { renderAddon, type AddonValue } from './base/Addon.tsx'
42
43
  import { Button } from './Button.tsx'
44
+ import { ButtonGroup } from './ButtonGroup.tsx'
43
45
  import { CodeBlockMeta } from './CodeBlock.meta.ts'
44
46
  import { CopyButton } from './CopyButton.tsx'
45
47
  import { TabSet, TabSetContext, type TabSetTabProps } from './TabSet.tsx'
@@ -150,8 +152,21 @@ function CodeBlockHeader({ buttons, className, children, ...props }: CodeBlockHe
150
152
  )}
151
153
  {...props}
152
154
  >
153
- <div className="grow">{children}</div>
154
- {buttons ? <div className="flex shrink-0 items-center gap-3 pe-2.5">{buttons}</div> : null}
155
+ <div className="min-w-em grow">{children}</div>
156
+ {buttons ? (
157
+ <ButtonGroup
158
+ variant="naked"
159
+ size="medium"
160
+ /**
161
+ * The `not-has-button:hidden` class prevents an empty `ButtonGroup` from taking space
162
+ * in the layout, which can happen when the stuff that `CodeBlockTabs` passes as
163
+ * `buttons` ends up rendering nothing (which we can't know in advance).
164
+ */
165
+ className="me-2 shrink-0 self-center not-has-button:hidden"
166
+ >
167
+ {buttons}
168
+ </ButtonGroup>
169
+ ) : null}
155
170
  <div className="absolute inset-x-0 bottom-0 border-b border-subtle" />
156
171
  </figcaption>
157
172
  </CodeBlockHeaderContext.Provider>
@@ -162,8 +177,8 @@ export interface CodeBlockProps extends Omit<ComponentProps<'div'>, 'onCopy'>, S
162
177
  /** @default 'text' */
163
178
  language?: Language | undefined
164
179
  /** Defaults to an icon that matches the `language`. */
165
- icon?: ReactNode | undefined
166
- label?: string | undefined
180
+ icon?: AddonValue | undefined
181
+ label?: ReactNode | undefined
167
182
  children: Stringifiable
168
183
  }
169
184
 
@@ -314,64 +329,74 @@ export function CodeBlockRoot({
314
329
  })
315
330
  }, [highlighter, childrenString, activeTheme, language, highlights, secrets, diff])
316
331
 
317
- const buttons = (
318
- <>
319
- {secrets.length > 0 ? (
320
- <Button variant="naked" size="medium" onClick={() => setMasked(!masked)}>
321
- {masked ? (
322
- <EyeIcon alt={`Reveal secret${secrets.length > 1 ? 's' : ''}`} />
323
- ) : (
324
- <EyeClosedIcon alt={`Hide secret${secrets.length > 1 ? 's' : ''}`} />
325
- )}
326
- </Button>
327
- ) : null}
328
- {copy ? (
329
- <CopyButton
330
- variant="naked"
331
- size="medium"
332
- value={typeof copy === 'string' ? copy : codeToCopy}
333
- onCopy={onCopy}
334
- />
335
- ) : null}
336
- </>
337
- )
332
+ const buttonElements = [
333
+ secrets.length > 0 && (
334
+ <Button key="reveal" onClick={() => setMasked(!masked)}>
335
+ {masked ? (
336
+ <EyeIcon alt={`Reveal secret${secrets.length > 1 ? 's' : ''}`} />
337
+ ) : (
338
+ <EyeClosedIcon alt={`Hide secret${secrets.length > 1 ? 's' : ''}`} />
339
+ )}
340
+ </Button>
341
+ ),
342
+ copy && (
343
+ <CopyButton key="copy" value={typeof copy === 'string' ? copy : codeToCopy} onCopy={onCopy} />
344
+ ),
345
+ ].filter(Boolean)
346
+
347
+ const buttons = buttonElements.length > 0 ? <>{buttonElements}</> : null
338
348
 
339
349
  if (hasAncestorHeader) {
340
350
  return buttons
341
351
  }
342
352
 
343
353
  const Wrapper = hasAncestorTabs ? 'div' : CodeBlockWrapper
344
- const headerContent = (
345
- <div className="flex h-full items-center gap-2 ps-2">
346
- {icon ? (
347
- <span className="flex size-4 shrink-0 items-center justify-center **:icon:default-size-3.5">
348
- {icon}
349
- </span>
350
- ) : null}
351
- {label ? <span className="truncate text-14 text-muted">{label}</span> : null}
352
- </div>
353
- )
354
+ const headerContent =
355
+ label || passedIcon ? (
356
+ <div className="flex h-full items-center gap-2 ps-2">
357
+ {icon ? (
358
+ <span className="flex size-4 shrink-0 items-center justify-center **:icon:default-size-3.5">
359
+ {renderAddon(icon)}
360
+ </span>
361
+ ) : null}
362
+ {label ? <span className="truncate text-14 text-muted">{label}</span> : null}
363
+ </div>
364
+ ) : null
354
365
 
355
366
  return (
356
367
  <Wrapper
357
368
  ref={cssPropsPolyfillPassedRef}
369
+ data-has-header={Boolean(headerContent) || undefined}
358
370
  className={cn(
359
- `gds-code-block isolate root-flex flex-col
360
- u:not-in-code-block-tabs:min-h-24
361
- u:not-in-code-block-tabs:rounded-8`,
371
+ `gds-code-block group/code-block root-flex flex-col
372
+ u:not-in-code-block-tabs:rounded-8
373
+ u:not-in-code-block-tabs:not-data-has-header:min-h-13
374
+ u:not-in-code-block-tabs:data-has-header:min-h-24`,
362
375
  className,
363
376
  )}
364
377
  {...getCSSPropsAttributes(CodeBlockMeta, { wrap, lineNumbers, rows }, style)}
365
378
  {...cssPropsPolyfillAttributes}
366
379
  {...props}
367
380
  >
368
- {!hasAncestorTabs ? (
369
- <CodeBlockHeader buttons={buttons}>{headerContent}</CodeBlockHeader>
370
- ) : null}
371
- {hasAncestorTabs && label ? (
372
- <div className="flex h-10 shrink-0 px-2">
373
- <div className="absolute inset-0 border-b border-subtle" />
374
- {headerContent}
381
+ {headerContent ? (
382
+ hasAncestorTabs ? (
383
+ <div className="flex h-10 shrink-0 px-2">
384
+ <div className="absolute inset-0 border-b border-subtle" />
385
+ {headerContent}
386
+ </div>
387
+ ) : (
388
+ <CodeBlockHeader buttons={buttons}>{headerContent}</CodeBlockHeader>
389
+ )
390
+ ) : !hasAncestorTabs && buttons ? (
391
+ <div
392
+ className={`
393
+ absolute end-3 top-3 z-10 opacity-0 transition
394
+ group-not-hover/code-block:pointer-events-none
395
+ group-hover/code-block:opacity-100
396
+ has-focus-visible:opacity-100
397
+ `}
398
+ >
399
+ <ButtonGroup size="xsmall">{buttons}</ButtonGroup>
375
400
  </div>
376
401
  ) : null}
377
402
  <pre
@@ -384,7 +409,7 @@ export function CodeBlockRoot({
384
409
  * that case, so it should be fine.
385
410
  */
386
411
  className={`
387
- h-(--max-height) max-h-max grow overflow-auto font-mono text-14
412
+ isolate scrollbar-thin h-(--max-height) max-h-max grow overflow-auto font-mono text-14
388
413
  [--max-height:calc(9999px-min(9999px,var(--gds-code-block-rows)*9999px)+var(--gds-code-block-rows)*1lh+2*var(--padding))]
389
414
  [--padding:--spacing(4)]
390
415
  firefox:h-auto
@@ -427,8 +452,8 @@ export function CodeBlockRoot({
427
452
  <span
428
453
  aria-hidden
429
454
  className={`
430
- hidden min-w-4 text-center text-12 text-subtle select-none
431
- @prop-line-numbers-true/code-block:block
455
+ min-w-4 text-center text-12 text-subtle select-none
456
+ @prop-line-numbers-false/code-block:hidden
432
457
  `}
433
458
  >
434
459
  {lineIndex + 1}
@@ -544,7 +569,7 @@ export function CodeBlockTabs<const Tabs extends readonly Tab[], T extends TabVa
544
569
  className,
545
570
  children,
546
571
  ...props
547
- }: CodeBlockTabsProps<Tabs, T> & { ref?: React.Ref<HTMLDivElement> }) {
572
+ }: CodeBlockTabsProps<Tabs, T>) {
548
573
  if (passedTabs.length === 0) {
549
574
  throw new Error('[CodeBlock.Tabs] At least 1 tab is required')
550
575
  }
@@ -583,7 +608,7 @@ export function CodeBlockTabs<const Tabs extends readonly Tab[], T extends TabVa
583
608
  defaultValue={defaultValue ?? (tabs[0]!.value as T)}
584
609
  onChange={onChange}
585
610
  className={cn(
586
- `gds-code-block-tabs isolate root-flex flex-col u:min-h-24 u:rounded-8
611
+ `gds-code-block-tabs root-flex flex-col u:min-h-24 u:rounded-8
587
612
  u:[--saved-default-line-numbers:var(--gds-default-line-numbers)]
588
613
  u:[--saved-default-rows:var(--gds-default-rows)]
589
614
  u:[--saved-default-wrap:var(--gds-default-wrap)]
@@ -15,8 +15,8 @@ export function CodeInline({ className, children, ...props }: CodeInlineProps) {
15
15
  return (
16
16
  <span
17
17
  className={cn(
18
- `gds-code-inline root-inline
19
- u:font-mono u:font-regular u:wrap-anywhere u:whitespace-pre-wrap u:text-code u:in-link:text-link-idle
18
+ `gds-code-inline root-inline u:font-mono u:text-size-inherit u:wrap-anywhere u:whitespace-pre-wrap u:text-code
19
+ u:in-link:text-link-idle
20
20
  ${/* If inside a link, ensure the underline of the link appears over the background and border by default */ ''}
21
21
  u:in-link:-z-10
22
22
  ${/* Prevent messing with the line height (this needs to be set on the root _and_ on the inner element) */ ''}
@@ -44,7 +44,7 @@ export function CodeInline({ className, children, ...props }: CodeInlineProps) {
44
44
  in-link:transition-[border-radius]
45
45
  in-link-hover:rounded-b-none
46
46
  ${/* Prevent incorrect alignment when empty */ ''}
47
- empty:after:content-(--content-nbsp)
47
+ empty:after:content-nbsp
48
48
  `}
49
49
  {...props}
50
50
  >
@@ -5,17 +5,12 @@ import { ButtonMeta } from './Button.meta.ts'
5
5
  type ButtonVariant = (typeof ButtonMeta.cssProps.variant.values)[number]
6
6
 
7
7
  export const CopyButtonMeta = createComponent('CopyButton', {
8
- containerName: 'gds-button',
8
+ extends: ButtonMeta,
9
9
  cssProps: {
10
- /** @default 'secondary' */
11
10
  variant: {
12
11
  type: 'values',
13
12
  values: ['secondary', 'tertiary', 'inverse', 'naked'] as const satisfies ButtonVariant[],
14
13
  defaultValue: 'secondary',
15
14
  },
16
- /** @default 'medium' */
17
- size: ButtonMeta.cssProps.size,
18
- /** @default false */
19
- hideLabel: ButtonMeta.cssProps.hideLabel,
20
15
  },
21
16
  })