@cloudflare/kumo 1.17.0 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (263) hide show
  1. package/CHANGELOG.md +143 -0
  2. package/ai/USAGE.md +38 -32
  3. package/ai/component-registry.json +289 -178
  4. package/ai/component-registry.md +980 -507
  5. package/ai/schemas.ts +20 -4
  6. package/dist/.build-complete +1 -1
  7. package/dist/ai/schemas.d.ts +95 -56
  8. package/dist/ai/schemas.d.ts.map +1 -1
  9. package/dist/ai/schemas.js +165 -148
  10. package/dist/ai/schemas.js.map +1 -1
  11. package/dist/chunks/{Legend-o0ntojbaplmszwk0.js → Legend-ks7se6149vsa3tze.js} +127 -118
  12. package/dist/chunks/Legend-ks7se6149vsa3tze.js.map +1 -0
  13. package/dist/chunks/badge-dan90i0rzy4pwa1j.js +102 -0
  14. package/dist/chunks/badge-dan90i0rzy4pwa1j.js.map +1 -0
  15. package/dist/chunks/{banner-nz0eryqnz3qd86ln.js → banner-eiwcnk7ts21s3bnb.js} +4 -4
  16. package/dist/chunks/{banner-nz0eryqnz3qd86ln.js.map → banner-eiwcnk7ts21s3bnb.js.map} +1 -1
  17. package/dist/chunks/{breadcrumbs-cjgn3w4drahvqnuj.js → breadcrumbs-ge20hcb3o5spswrk.js} +2 -2
  18. package/dist/chunks/{breadcrumbs-cjgn3w4drahvqnuj.js.map → breadcrumbs-ge20hcb3o5spswrk.js.map} +1 -1
  19. package/dist/chunks/{button-odxi0hp4fvi5i2w3.js → button-oaqi7ykdisyskoos.js} +8 -8
  20. package/dist/chunks/button-oaqi7ykdisyskoos.js.map +1 -0
  21. package/dist/chunks/{checkbox-dx8x0rzv582yjv7n.js → checkbox-mwgmohffm22ut13s.js} +15 -15
  22. package/dist/chunks/checkbox-mwgmohffm22ut13s.js.map +1 -0
  23. package/dist/chunks/{clipboard-text-kyk51d1ze7zvdn4q.js → clipboard-text-dxczqon3d27xp6f0.js} +10 -10
  24. package/dist/chunks/{clipboard-text-kyk51d1ze7zvdn4q.js.map → clipboard-text-dxczqon3d27xp6f0.js.map} +1 -1
  25. package/dist/chunks/{cloudflare-logo-bgts2jgsdh7sslw4.js → cloudflare-logo-pbavoe1wu8nr5c4n.js} +9 -9
  26. package/dist/chunks/{cloudflare-logo-bgts2jgsdh7sslw4.js.map → cloudflare-logo-pbavoe1wu8nr5c4n.js.map} +1 -1
  27. package/dist/chunks/{code-liq1g6f5lhee305d.js → code-cz0w1y5z4h29a9eg.js} +18 -18
  28. package/dist/chunks/code-cz0w1y5z4h29a9eg.js.map +1 -0
  29. package/dist/chunks/{combobox-9fhjzprab46csmon.js → combobox-eaowwt1xr4d23gsn.js} +113 -101
  30. package/dist/chunks/combobox-eaowwt1xr4d23gsn.js.map +1 -0
  31. package/dist/chunks/{command-palette-kenx2bbdzd4kpx36.js → command-palette-maqtbmpfev9mysqd.js} +20 -20
  32. package/dist/chunks/command-palette-maqtbmpfev9mysqd.js.map +1 -0
  33. package/dist/chunks/{dialog-e05ysa8t2fklw065.js → dialog-e3m5bhs7fds26p9y.js} +25 -25
  34. package/dist/chunks/dialog-e3m5bhs7fds26p9y.js.map +1 -0
  35. package/dist/chunks/{dropdown-g587px7zv3ssaxr4.js → dropdown-ewte287db3vyt8t5.js} +94 -92
  36. package/dist/chunks/{dropdown-g587px7zv3ssaxr4.js.map → dropdown-ewte287db3vyt8t5.js.map} +1 -1
  37. package/dist/chunks/{empty-fuz1un7r7mbz0kim.js → empty-dr1eckm2z40euns6.js} +2 -2
  38. package/dist/chunks/{empty-fuz1un7r7mbz0kim.js.map → empty-dr1eckm2z40euns6.js.map} +1 -1
  39. package/dist/chunks/{field-fq504lyu7ttsh5m9.js → field-bo5gmna16odrrb1q.js} +3 -3
  40. package/dist/chunks/{field-fq504lyu7ttsh5m9.js.map → field-bo5gmna16odrrb1q.js.map} +1 -1
  41. package/dist/chunks/{grid-m9r71jxo2b8q1972.js → grid-hj1ylz16p7g5uelh.js} +2 -2
  42. package/dist/chunks/{grid-m9r71jxo2b8q1972.js.map → grid-hj1ylz16p7g5uelh.js.map} +1 -1
  43. package/dist/chunks/input-area-jkkkjej6luumrqpa.js +78 -0
  44. package/dist/chunks/input-area-jkkkjej6luumrqpa.js.map +1 -0
  45. package/dist/chunks/input-cw05pbqdburghkus.js +113 -0
  46. package/dist/chunks/input-cw05pbqdburghkus.js.map +1 -0
  47. package/dist/chunks/{input-group-hbebbyh8fo6aqydn.js → input-group-lfugneuz71g42n0w.js} +27 -27
  48. package/dist/chunks/input-group-lfugneuz71g42n0w.js.map +1 -0
  49. package/dist/chunks/label-cvyvbqmt4mt757ff.js +68 -0
  50. package/dist/chunks/{label-j9owppbgnn35mebg.js.map → label-cvyvbqmt4mt757ff.js.map} +1 -1
  51. package/dist/chunks/layer-card-ljqth3yxgnk04v2o.js +46 -0
  52. package/dist/chunks/layer-card-ljqth3yxgnk04v2o.js.map +1 -0
  53. package/dist/chunks/{link-hmmf3k1xn6rm72rt.js → link-fjnhtxvfe5ieamjf.js} +2 -2
  54. package/dist/chunks/{link-hmmf3k1xn6rm72rt.js.map → link-fjnhtxvfe5ieamjf.js.map} +1 -1
  55. package/dist/chunks/{loader-m5wfmqwgucrr4i5v.js → loader-hr2w7cpqeev3p3vl.js} +9 -6
  56. package/dist/chunks/loader-hr2w7cpqeev3p3vl.js.map +1 -0
  57. package/dist/chunks/menubar-e5e4zwfagr0wx023.js +96 -0
  58. package/dist/chunks/menubar-e5e4zwfagr0wx023.js.map +1 -0
  59. package/dist/chunks/{meter-i84dte2f82qmvn7y.js → meter-duj3micor1lqj3y2.js} +2 -2
  60. package/dist/chunks/{meter-i84dte2f82qmvn7y.js.map → meter-duj3micor1lqj3y2.js.map} +1 -1
  61. package/dist/chunks/pagination-olaypvwr8swsmn8m.js +266 -0
  62. package/dist/chunks/pagination-olaypvwr8swsmn8m.js.map +1 -0
  63. package/dist/chunks/{popover-i951xjcgezeqr4iv.js → popover-nv9cmzbo7mf6bky0.js} +68 -72
  64. package/dist/chunks/popover-nv9cmzbo7mf6bky0.js.map +1 -0
  65. package/dist/chunks/{radio-l2vkcue40d84fmo1.js → radio-ihxbe37us2jnqtzf.js} +38 -38
  66. package/dist/chunks/radio-ihxbe37us2jnqtzf.js.map +1 -0
  67. package/dist/chunks/select-nx6ded5swra74iar.js +213 -0
  68. package/dist/chunks/select-nx6ded5swra74iar.js.map +1 -0
  69. package/dist/chunks/{sensitive-input-kznmknpp5h1grc6k.js → sensitive-input-00fujb510rrn61v9.js} +34 -34
  70. package/dist/chunks/{sensitive-input-kznmknpp5h1grc6k.js.map → sensitive-input-00fujb510rrn61v9.js.map} +1 -1
  71. package/dist/chunks/{sidebar-jepeq7gaf4issuw6.js → sidebar-ltbfius1eolkl8tb.js} +24 -28
  72. package/dist/chunks/sidebar-ltbfius1eolkl8tb.js.map +1 -0
  73. package/dist/chunks/surface-dfgurg5eu3et4vw1.js +29 -0
  74. package/dist/chunks/surface-dfgurg5eu3et4vw1.js.map +1 -0
  75. package/dist/chunks/{switch-i0zwcp3wq6vsxm1c.js → switch-fbv3iawqo3o3jgap.js} +104 -102
  76. package/dist/chunks/switch-fbv3iawqo3o3jgap.js.map +1 -0
  77. package/dist/chunks/table-of-contents-f813ivi7ta23vqdm.js +88 -0
  78. package/dist/chunks/table-of-contents-f813ivi7ta23vqdm.js.map +1 -0
  79. package/dist/chunks/table-olwwulga2l3hdwlx.js +189 -0
  80. package/dist/chunks/table-olwwulga2l3hdwlx.js.map +1 -0
  81. package/dist/chunks/{tabs-bw92jb303zxw7w4f.js → tabs-lohcglgppp6gj0hp.js} +16 -16
  82. package/dist/chunks/{tabs-bw92jb303zxw7w4f.js.map → tabs-lohcglgppp6gj0hp.js.map} +1 -1
  83. package/dist/chunks/{toast-lrnwby56drs7vtae.js → toast-dg52x89yd231mxhe.js} +30 -30
  84. package/dist/chunks/{toast-lrnwby56drs7vtae.js.map → toast-dg52x89yd231mxhe.js.map} +1 -1
  85. package/dist/chunks/{tooltip-cit9ltlxfuhwctuj.js → tooltip-hikjvdbg3xghnq1x.js} +38 -33
  86. package/dist/chunks/tooltip-hikjvdbg3xghnq1x.js.map +1 -0
  87. package/dist/chunks/{vendor-base-ui-n30qblevnpk9cc5c.js → vendor-base-ui-m5pz3e8c4grg5qmj.js} +46 -43
  88. package/dist/chunks/{vendor-base-ui-n30qblevnpk9cc5c.js.map → vendor-base-ui-m5pz3e8c4grg5qmj.js.map} +1 -1
  89. package/dist/code.js +1 -1
  90. package/dist/components/badge.js +1 -1
  91. package/dist/components/banner.js +1 -1
  92. package/dist/components/breadcrumbs.js +1 -1
  93. package/dist/components/button.js +1 -1
  94. package/dist/components/chart.js +1 -1
  95. package/dist/components/checkbox.js +1 -1
  96. package/dist/components/clipboard-text.js +1 -1
  97. package/dist/components/cloudflare-logo.js +1 -1
  98. package/dist/components/code.js +1 -1
  99. package/dist/components/combobox.js +1 -1
  100. package/dist/components/command-palette.js +1 -1
  101. package/dist/components/dialog.js +1 -1
  102. package/dist/components/dropdown.js +1 -1
  103. package/dist/components/empty.js +1 -1
  104. package/dist/components/field.js +1 -1
  105. package/dist/components/flow.js +2 -2
  106. package/dist/components/flow.js.map +1 -1
  107. package/dist/components/grid.js +1 -1
  108. package/dist/components/input.js +3 -3
  109. package/dist/components/label.js +1 -1
  110. package/dist/components/layer-card.js +1 -1
  111. package/dist/components/link.js +1 -1
  112. package/dist/components/loader.js +1 -1
  113. package/dist/components/menubar.js +1 -1
  114. package/dist/components/meter.js +1 -1
  115. package/dist/components/pagination.js +1 -1
  116. package/dist/components/popover.js +1 -1
  117. package/dist/components/radio.js +1 -1
  118. package/dist/components/select.js +1 -1
  119. package/dist/components/sensitive-input.js +1 -1
  120. package/dist/components/sidebar.js +1 -1
  121. package/dist/components/surface.js +1 -1
  122. package/dist/components/switch.js +1 -1
  123. package/dist/components/table-of-contents.js +8 -0
  124. package/dist/components/table-of-contents.js.map +1 -0
  125. package/dist/components/table.js +1 -1
  126. package/dist/components/tabs.js +1 -1
  127. package/dist/components/toast.js +2 -2
  128. package/dist/components/tooltip.js +1 -1
  129. package/dist/index.js +128 -124
  130. package/dist/index.js.map +1 -1
  131. package/dist/primitives/accordion.js +1 -1
  132. package/dist/primitives/alert-dialog.js +1 -1
  133. package/dist/primitives/autocomplete.js +1 -1
  134. package/dist/primitives/avatar.js +1 -1
  135. package/dist/primitives/button.js +1 -1
  136. package/dist/primitives/checkbox-group.js +1 -1
  137. package/dist/primitives/checkbox.js +1 -1
  138. package/dist/primitives/collapsible.js +1 -1
  139. package/dist/primitives/combobox.js +1 -1
  140. package/dist/primitives/context-menu.js +1 -1
  141. package/dist/primitives/csp-provider.js +1 -1
  142. package/dist/primitives/dialog.js +1 -1
  143. package/dist/primitives/direction-provider.js +1 -1
  144. package/dist/primitives/drawer.js +1 -1
  145. package/dist/primitives/field.js +1 -1
  146. package/dist/primitives/fieldset.js +1 -1
  147. package/dist/primitives/form.js +1 -1
  148. package/dist/primitives/input.js +1 -1
  149. package/dist/primitives/menu.js +1 -1
  150. package/dist/primitives/menubar.js +1 -1
  151. package/dist/primitives/meter.js +1 -1
  152. package/dist/primitives/navigation-menu.js +1 -1
  153. package/dist/primitives/number-field.js +1 -1
  154. package/dist/primitives/popover.js +1 -1
  155. package/dist/primitives/preview-card.js +1 -1
  156. package/dist/primitives/progress.js +1 -1
  157. package/dist/primitives/radio-group.js +1 -1
  158. package/dist/primitives/radio.js +1 -1
  159. package/dist/primitives/scroll-area.js +1 -1
  160. package/dist/primitives/select.js +1 -1
  161. package/dist/primitives/separator.js +1 -1
  162. package/dist/primitives/slider.js +1 -1
  163. package/dist/primitives/switch.js +1 -1
  164. package/dist/primitives/tabs.js +1 -1
  165. package/dist/primitives/toast.js +1 -1
  166. package/dist/primitives/toggle-group.js +1 -1
  167. package/dist/primitives/toggle.js +1 -1
  168. package/dist/primitives/toolbar.js +1 -1
  169. package/dist/primitives/tooltip.js +1 -1
  170. package/dist/primitives.js +1 -1
  171. package/dist/scripts/theme-generator/config.d.ts.map +1 -1
  172. package/dist/scripts/theme-generator/config.js +32 -113
  173. package/dist/scripts/theme-generator/config.js.map +1 -1
  174. package/dist/src/components/badge/badge.d.ts +61 -79
  175. package/dist/src/components/badge/badge.d.ts.map +1 -1
  176. package/dist/src/components/banner/banner.d.ts +3 -3
  177. package/dist/src/components/button/button.d.ts +3 -3
  178. package/dist/src/components/button/button.d.ts.map +1 -1
  179. package/dist/src/components/chart/EChart.d.ts +18 -2
  180. package/dist/src/components/chart/EChart.d.ts.map +1 -1
  181. package/dist/src/components/chart/TimeseriesChart.d.ts.map +1 -1
  182. package/dist/src/components/chart/index.d.ts +1 -1
  183. package/dist/src/components/chart/index.d.ts.map +1 -1
  184. package/dist/src/components/checkbox/checkbox.d.ts +1 -1
  185. package/dist/src/components/code/code.d.ts.map +1 -1
  186. package/dist/src/components/combobox/combobox.d.ts +16 -2
  187. package/dist/src/components/combobox/combobox.d.ts.map +1 -1
  188. package/dist/src/components/dropdown/dropdown.d.ts.map +1 -1
  189. package/dist/src/components/input/input-area.d.ts.map +1 -1
  190. package/dist/src/components/input/input.d.ts +1 -2
  191. package/dist/src/components/input/input.d.ts.map +1 -1
  192. package/dist/src/components/label/label.d.ts.map +1 -1
  193. package/dist/src/components/layer-card/layer-card.d.ts +39 -5
  194. package/dist/src/components/layer-card/layer-card.d.ts.map +1 -1
  195. package/dist/src/components/loader/loader.d.ts +7 -1
  196. package/dist/src/components/loader/loader.d.ts.map +1 -1
  197. package/dist/src/components/menubar/menubar.d.ts.map +1 -1
  198. package/dist/src/components/pagination/pagination.d.ts +62 -2
  199. package/dist/src/components/pagination/pagination.d.ts.map +1 -1
  200. package/dist/src/components/popover/popover.d.ts +35 -8
  201. package/dist/src/components/popover/popover.d.ts.map +1 -1
  202. package/dist/src/components/radio/radio.d.ts +2 -2
  203. package/dist/src/components/select/select.d.ts +115 -7
  204. package/dist/src/components/select/select.d.ts.map +1 -1
  205. package/dist/src/components/sensitive-input/sensitive-input.d.ts +1 -1
  206. package/dist/src/components/sidebar/sidebar.d.ts +2 -2
  207. package/dist/src/components/sidebar/sidebar.d.ts.map +1 -1
  208. package/dist/src/components/surface/index.d.ts +3 -0
  209. package/dist/src/components/surface/index.d.ts.map +1 -1
  210. package/dist/src/components/surface/surface.d.ts +14 -10
  211. package/dist/src/components/surface/surface.d.ts.map +1 -1
  212. package/dist/src/components/switch/switch.d.ts.map +1 -1
  213. package/dist/src/components/table/table.d.ts.map +1 -1
  214. package/dist/src/components/table-of-contents/index.d.ts +2 -0
  215. package/dist/src/components/table-of-contents/index.d.ts.map +1 -0
  216. package/dist/src/components/table-of-contents/table-of-contents.d.ts +70 -0
  217. package/dist/src/components/table-of-contents/table-of-contents.d.ts.map +1 -0
  218. package/dist/src/components/toast/toast.d.ts +1 -1
  219. package/dist/src/components/tooltip/tooltip.d.ts +25 -6
  220. package/dist/src/components/tooltip/tooltip.d.ts.map +1 -1
  221. package/dist/src/index.d.ts +6 -2
  222. package/dist/src/index.d.ts.map +1 -1
  223. package/dist/styles/kumo-binding.css +4 -0
  224. package/dist/styles/kumo-standalone.css +1 -1
  225. package/dist/styles/theme-fedramp.css +3 -3
  226. package/dist/styles/theme-kumo.css +66 -127
  227. package/package.json +5 -1
  228. package/scripts/component-registry/index.test.ts +4 -4
  229. package/scripts/component-registry/metadata.ts +3 -3
  230. package/scripts/theme-generator/config.ts +37 -116
  231. package/dist/chunks/Legend-o0ntojbaplmszwk0.js.map +0 -1
  232. package/dist/chunks/badge-n80t3z8u9ttlxi20.js +0 -120
  233. package/dist/chunks/badge-n80t3z8u9ttlxi20.js.map +0 -1
  234. package/dist/chunks/button-odxi0hp4fvi5i2w3.js.map +0 -1
  235. package/dist/chunks/checkbox-dx8x0rzv582yjv7n.js.map +0 -1
  236. package/dist/chunks/code-liq1g6f5lhee305d.js.map +0 -1
  237. package/dist/chunks/combobox-9fhjzprab46csmon.js.map +0 -1
  238. package/dist/chunks/command-palette-kenx2bbdzd4kpx36.js.map +0 -1
  239. package/dist/chunks/dialog-e05ysa8t2fklw065.js.map +0 -1
  240. package/dist/chunks/input-area-nq40szg9110on89c.js +0 -74
  241. package/dist/chunks/input-area-nq40szg9110on89c.js.map +0 -1
  242. package/dist/chunks/input-group-hbebbyh8fo6aqydn.js.map +0 -1
  243. package/dist/chunks/input-kvhyo3p4859bexvx.js +0 -109
  244. package/dist/chunks/input-kvhyo3p4859bexvx.js.map +0 -1
  245. package/dist/chunks/label-j9owppbgnn35mebg.js +0 -62
  246. package/dist/chunks/layer-card-l5yjvrxry1dhte57.js +0 -44
  247. package/dist/chunks/layer-card-l5yjvrxry1dhte57.js.map +0 -1
  248. package/dist/chunks/loader-m5wfmqwgucrr4i5v.js.map +0 -1
  249. package/dist/chunks/menubar-abojnm0uwjuni8ok.js +0 -92
  250. package/dist/chunks/menubar-abojnm0uwjuni8ok.js.map +0 -1
  251. package/dist/chunks/pagination-pbd7qqik97ac0l7m.js +0 -224
  252. package/dist/chunks/pagination-pbd7qqik97ac0l7m.js.map +0 -1
  253. package/dist/chunks/popover-i951xjcgezeqr4iv.js.map +0 -1
  254. package/dist/chunks/radio-l2vkcue40d84fmo1.js.map +0 -1
  255. package/dist/chunks/select-paedwa3nlhpq82ua.js +0 -132
  256. package/dist/chunks/select-paedwa3nlhpq82ua.js.map +0 -1
  257. package/dist/chunks/sidebar-jepeq7gaf4issuw6.js.map +0 -1
  258. package/dist/chunks/surface-blo81kgy9g0sexgm.js +0 -36
  259. package/dist/chunks/surface-blo81kgy9g0sexgm.js.map +0 -1
  260. package/dist/chunks/switch-i0zwcp3wq6vsxm1c.js.map +0 -1
  261. package/dist/chunks/table-nrcw19tlpduayukl.js +0 -183
  262. package/dist/chunks/table-nrcw19tlpduayukl.js.map +0 -1
  263. package/dist/chunks/tooltip-cit9ltlxfuhwctuj.js.map +0 -1
@@ -16,28 +16,24 @@ Small status label for categorizing or highlighting content.
16
16
 
17
17
  **Props:**
18
18
 
19
- - `variant`: enum [default: neutral]
19
+ - `variant`: enum [default: primary]
20
+ - `"primary"`: Primary badge
21
+ - `"secondary"`: Secondary badge
22
+ - `"error"`: Error badge
23
+ - `"warning"`: Warning badge
24
+ - `"success"`: Success badge
25
+ - `"destructive"`: Deprecated. Use red instead.
26
+ - `"info"`: Info badge
27
+ - `"beta"`: Indicates beta or experimental features
28
+ - `"outline"`: Bordered badge with transparent background
20
29
  - `"red"`: Red badge
21
- - `"red-subtle"`: Subtle red badge
22
- - `"orange"`: Orange badge
23
- - `"orange-subtle"`: Subtle orange badge
24
- - `"yellow"`: Yellow badge
25
- - `"yellow-subtle"`: Subtle yellow badge
26
30
  - `"green"`: Green badge
27
- - `"green-subtle"`: Subtle green badge
31
+ - `"neutral"`: Neutral badge
32
+ - `"orange"`: Orange badge
33
+ - `"purple"`: Purple badge
28
34
  - `"teal"`: Teal badge
29
35
  - `"teal-subtle"`: Subtle teal badge
30
36
  - `"blue"`: Blue badge
31
- - `"blue-subtle"`: Subtle blue badge
32
- - `"neutral"`: Neutral badge
33
- - `"neutral-subtle"`: Subtle neutral badge
34
- - `"inverted"`: Inverted badge
35
- - `"outline"`: Bordered badge with transparent background
36
- - `"beta"`: Indicates beta or experimental features
37
- - `"primary"`: Deprecated. Use inverted instead.
38
- - `"secondary"`: Deprecated. Use neutral instead.
39
- - `"destructive"`: Deprecated. Use red instead.
40
- - `"success"`: Deprecated. Use green instead.
41
37
  - `className`: string
42
38
  Additional CSS classes merged via `cn()`.
43
39
  - `children`: ReactNode
@@ -45,40 +41,39 @@ Small status label for categorizing or highlighting content.
45
41
 
46
42
  **Colors (kumo tokens used):**
47
43
 
48
- `bg-kumo-badge-blue`, `bg-kumo-badge-blue-subtle`, `bg-kumo-badge-green`, `bg-kumo-badge-green-subtle`, `bg-kumo-badge-inverted`, `bg-kumo-badge-neutral`, `bg-kumo-badge-orange`, `bg-kumo-badge-orange-subtle`, `bg-kumo-badge-red`, `bg-kumo-badge-red-subtle`, `bg-kumo-badge-teal`, `bg-kumo-badge-teal-subtle`, `bg-kumo-badge-yellow`, `bg-kumo-badge-yellow-subtle`, `bg-kumo-fill`, `border-kumo-brand`, `border-kumo-fill`, `text-kumo-badge-blue-subtle`, `text-kumo-badge-green-subtle`, `text-kumo-badge-inverted`, `text-kumo-badge-neutral-subtle`, `text-kumo-badge-orange-subtle`, `text-kumo-badge-red-subtle`, `text-kumo-badge-teal-subtle`, `text-kumo-badge-yellow-subtle`, `text-kumo-default`, `text-kumo-link`
44
+ `bg-kumo-badge-blue`, `bg-kumo-badge-green`, `bg-kumo-badge-inverted`, `bg-kumo-badge-neutral`, `bg-kumo-badge-orange`, `bg-kumo-badge-purple`, `bg-kumo-badge-red`, `bg-kumo-badge-teal`, `bg-kumo-badge-teal-subtle`, `bg-kumo-danger-tint`, `bg-kumo-fill`, `bg-kumo-info-tint`, `bg-kumo-success-tint`, `bg-kumo-warning-tint`, `border-kumo-brand`, `border-kumo-fill`, `text-kumo-badge-inverted`, `text-kumo-badge-neutral-subtle`, `text-kumo-badge-teal-subtle`, `text-kumo-danger`, `text-kumo-default`, `text-kumo-info`, `text-kumo-link`, `text-kumo-success`, `text-kumo-warning`
49
45
 
50
46
  **Examples:**
51
47
 
52
48
  ```tsx
53
49
  <div className="flex flex-wrap items-center gap-2">
54
- <Badge variant="red">Red</Badge>
55
- <Badge variant="orange">Orange</Badge>
56
- <Badge variant="yellow">Yellow</Badge>
57
- <Badge variant="green">Green</Badge>
58
- <Badge variant="teal">Teal</Badge>
59
- <Badge variant="blue">Blue</Badge>
60
- <Badge variant="neutral">Neutral</Badge>
61
- <Badge variant="inverted">Inverted</Badge>
50
+ <Badge variant="primary">Primary</Badge>
51
+ <Badge variant="secondary">Secondary</Badge>
52
+ <Badge variant="error">Error</Badge>
53
+ <Badge variant="success">Success</Badge>
54
+ <Badge variant="warning">Warning</Badge>
55
+ <Badge variant="info">Info</Badge>
62
56
  <Badge variant="outline">Outline</Badge>
63
57
  <Badge variant="beta">Beta</Badge>
64
- <Badge variant="red-subtle">Red subtle</Badge>
65
- <Badge variant="orange-subtle">Orange subtle</Badge>
66
- <Badge variant="yellow-subtle">Yellow subtle</Badge>
67
- <Badge variant="green-subtle">Green subtle</Badge>
68
- <Badge variant="teal-subtle">Teal subtle</Badge>
69
- <Badge variant="blue-subtle">Blue subtle</Badge>
70
- <Badge variant="neutral-subtle">Neutral subtle</Badge>
71
58
  </div>
72
59
  ```
73
60
 
74
61
  ```tsx
75
- <Badge variant="red">Red</Badge>
62
+ <div className="flex flex-wrap items-center gap-2">
63
+ <Badge variant="neutral">Neutral</Badge>
64
+ <Badge variant="red">Red</Badge>
65
+ <Badge variant="orange">Orange</Badge>
66
+ <Badge variant="green">Green</Badge>
67
+ <Badge variant="teal">Teal</Badge>
68
+ <Badge variant="blue">Blue</Badge>
69
+ <Badge variant="purple">Purple</Badge>
70
+ </div>
76
71
  ```
77
72
 
78
73
  ```tsx
79
74
  <p className="flex items-center gap-2">
80
75
  Workers
81
- <Badge variant="blue">New</Badge>
76
+ <Badge variant="secondary">New</Badge>
82
77
  </p>
83
78
  ```
84
79
 
@@ -388,7 +383,7 @@ Primary action trigger. Supports multiple variants, sizes, shapes, icons, and lo
388
383
 
389
384
  **Colors (kumo tokens used):**
390
385
 
391
- `bg-kumo-base`, `bg-kumo-brand`, `bg-kumo-brand-hover`, `bg-kumo-danger`, `bg-kumo-tint`, `ring-kumo-line`, `ring-kumo-ring`, `text-kumo-danger`, `text-kumo-default`, `text-kumo-subtle`
386
+ `bg-kumo-base`, `bg-kumo-brand`, `bg-kumo-brand-hover`, `bg-kumo-danger`, `bg-kumo-tint`, `ring-kumo-hairline`, `text-kumo-danger`, `text-kumo-default`, `text-kumo-subtle`
392
387
 
393
388
  **Examples:**
394
389
 
@@ -484,8 +479,8 @@ Checkbox component
484
479
 
485
480
  **State Classes:**
486
481
  - `"default"`:
487
- - `focus`: `[&:focus-within>span]:ring-kumo-ring`
488
- - `hover`: `[&:hover>span]:ring-kumo-ring`
482
+ - `focus`: `[&:focus-within>span]:ring-kumo-hairline`
483
+ - `hover`: `[&:hover>span]:ring-kumo-hairline`
489
484
  - `label`: ReactNode
490
485
  Label content for the checkbox (enables built-in Field wrapper) - can be a string or any React node
491
486
  - `labelTooltip`: ReactNode
@@ -509,7 +504,7 @@ Checkbox component
509
504
 
510
505
  **Colors (kumo tokens used):**
511
506
 
512
- `bg-kumo-base`, `bg-kumo-contrast`, `ring-kumo-contrast`, `ring-kumo-danger`, `ring-kumo-line`, `ring-kumo-ring`, `text-kumo-danger`, `text-kumo-default`, `text-kumo-inverse`, `text-kumo-subtle`
507
+ `bg-kumo-base`, `bg-kumo-contrast`, `ring-kumo-contrast`, `ring-kumo-danger`, `ring-kumo-hairline`, `text-kumo-danger`, `text-kumo-default`, `text-kumo-inverse`, `text-kumo-subtle`
513
508
 
514
509
  **Styling:**
515
510
 
@@ -520,8 +515,8 @@ Checkbox component
520
515
  - `checked`: `bg-kumo-contrast`, `text-kumo-inverse`
521
516
  - `indeterminate`: `bg-kumo-contrast`, `text-kumo-inverse`
522
517
  - `error`: `ring-kumo-danger`
523
- - `hover`: `ring-kumo-ring`
524
- - `focus`: `ring-kumo-ring`
518
+ - `hover`: `ring-kumo-hairline`
519
+ - `focus`: `ring-kumo-hairline`
525
520
  - `disabled`: `opacity-50`, `cursor-not-allowed`
526
521
  - **Icons:**
527
522
  - `ph-check` (checked) size 12
@@ -643,7 +638,7 @@ Read-only text field with a one-click copy-to-clipboard button.
643
638
 
644
639
  **Colors (kumo tokens used):**
645
640
 
646
- `bg-kumo-base`, `border-kumo-line`, `outline-kumo-fill`, `text-kumo-default`
641
+ `bg-kumo-base`, `border-kumo-hairline`, `outline-kumo-fill`, `text-kumo-default`
647
642
 
648
643
  **Styling:**
649
644
 
@@ -985,7 +980,7 @@ Cloudflare logo component.
985
980
 
986
981
  **Colors (kumo tokens used):**
987
982
 
988
- `bg-kumo-base`, `ring-kumo-line`, `text-kumo-default`
983
+ `bg-kumo-base`, `ring-kumo-hairline`, `text-kumo-default`
989
984
 
990
985
  **Examples:**
991
986
 
@@ -1113,7 +1108,7 @@ Cloudflare logo component.
1113
1108
  ```
1114
1109
 
1115
1110
  ```tsx
1116
- <footer className="flex w-full items-center justify-between rounded-lg border border-kumo-line bg-kumo-elevated px-6 py-4">
1111
+ <footer className="flex w-full items-center justify-between rounded-lg border border-kumo-hairline bg-kumo-elevated px-6 py-4">
1117
1112
  <span className="text-sm text-kumo-subtle">
1118
1113
  &copy; 2026 Your Company. All rights reserved.
1119
1114
  </span>
@@ -1282,7 +1277,7 @@ Combobox — autocomplete input with filterable dropdown list. Compound compone
1282
1277
 
1283
1278
  **Colors (kumo tokens used):**
1284
1279
 
1285
- `bg-kumo-base`, `bg-kumo-fill-hover`, `bg-kumo-overlay`, `bg-kumo-tint`, `border-kumo-line`, `ring-kumo-line`, `text-kumo-default`, `text-kumo-strong`, `text-kumo-subtle`
1280
+ `bg-kumo-base`, `bg-kumo-fill-hover`, `bg-kumo-overlay`, `bg-kumo-tint`, `border-kumo-hairline`, `ring-kumo-hairline`, `ring-kumo-line`, `text-kumo-default`, `text-kumo-strong`, `text-kumo-subtle`
1286
1281
 
1287
1282
  **Sub-Components:**
1288
1283
 
@@ -1661,7 +1656,7 @@ CommandPalette — accessible command palette / spotlight search overlay. Compo
1661
1656
 
1662
1657
  **Colors (kumo tokens used):**
1663
1658
 
1664
- `bg-kumo-base`, `bg-kumo-elevated`, `bg-kumo-overlay`, `bg-kumo-warning`, `ring-kumo-line`, `text-kumo-default`, `text-kumo-strong`, `text-kumo-subtle`
1659
+ `bg-kumo-base`, `bg-kumo-elevated`, `bg-kumo-overlay`, `bg-kumo-warning`, `ring-kumo-hairline`, `text-kumo-default`, `text-kumo-strong`, `text-kumo-subtle`
1665
1660
 
1666
1661
  **Examples:**
1667
1662
 
@@ -1719,13 +1714,13 @@ CommandPalette — accessible command palette / spotlight search overlay. Compo
1719
1714
  </CommandPalette.List>
1720
1715
  <CommandPalette.Footer>
1721
1716
  <span className="flex items-center gap-2">
1722
- <kbd className="rounded border border-kumo-line bg-kumo-base px-1.5 py-0.5 text-[10px]">
1717
+ <kbd className="rounded border border-kumo-hairline bg-kumo-base px-1.5 py-0.5 text-[10px]">
1723
1718
  ↑↓
1724
1719
  </kbd>
1725
1720
  <span>Navigate</span>
1726
1721
  </span>
1727
1722
  <span className="flex items-center gap-2">
1728
- <kbd className="rounded border border-kumo-line bg-kumo-base px-1.5 py-0.5 text-[10px]">
1723
+ <kbd className="rounded border border-kumo-hairline bg-kumo-base px-1.5 py-0.5 text-[10px]">
1729
1724
 
1730
1725
  </kbd>
1731
1726
  <span>Select</span>
@@ -1862,13 +1857,13 @@ CommandPalette — accessible command palette / spotlight search overlay. Compo
1862
1857
  </CommandPalette.List>
1863
1858
  <CommandPalette.Footer>
1864
1859
  <span className="flex items-center gap-2">
1865
- <kbd className="rounded border border-kumo-line bg-kumo-base px-1.5 py-0.5 text-[10px]">
1860
+ <kbd className="rounded border border-kumo-hairline bg-kumo-base px-1.5 py-0.5 text-[10px]">
1866
1861
  ↑↓
1867
1862
  </kbd>
1868
1863
  <span>Navigate</span>
1869
1864
  </span>
1870
1865
  <span className="flex items-center gap-2">
1871
- <kbd className="rounded border border-kumo-line bg-kumo-base px-1.5 py-0.5 text-[10px]">
1866
+ <kbd className="rounded border border-kumo-hairline bg-kumo-base px-1.5 py-0.5 text-[10px]">
1872
1867
  ⌘↵
1873
1868
  </kbd>
1874
1869
  <span>Open in new tab</span>
@@ -1906,11 +1901,15 @@ DatePicker — a date selection calendar. Built on [react-day-picker](https://d
1906
1901
 
1907
1902
  ```tsx
1908
1903
  <div className="flex flex-col gap-4">
1909
- <DatePicker mode="single" selected={date} onChange={d => {
1910
- if (d) {
1911
- setDate(d);
1912
- }
1913
- }} />
1904
+ <DatePicker
1905
+ mode="single"
1906
+ selected={date}
1907
+ onChange={(d) => {
1908
+ if (d) {
1909
+ setDate(d);
1910
+ }
1911
+ }}
1912
+ />
1914
1913
  <p className="text-sm text-kumo-subtle">
1915
1914
  Selected: {date ? date.toLocaleDateString() : "None"}
1916
1915
  </p>
@@ -1965,10 +1964,10 @@ DatePicker — a date selection calendar. Built on [react-day-picker](https://d
1965
1964
 
1966
1965
  ```tsx
1967
1966
  <Popover>
1968
- <Popover.Trigger asChild>
1969
- <Button variant="outline" icon={CalendarDotsIcon}>
1970
- {date ? date.toLocaleDateString() : "Pick a date"}
1971
- </Button>
1967
+ <Popover.Trigger
1968
+ render={<Button variant="outline" icon={CalendarDotsIcon} />}
1969
+ >
1970
+ {date ? date.toLocaleDateString() : "Pick a date"}
1972
1971
  </Popover.Trigger>
1973
1972
  <Popover.Content className="p-3">
1974
1973
  <DatePicker mode="single" selected={date} onChange={setDate} />
@@ -1978,10 +1977,10 @@ DatePicker — a date selection calendar. Built on [react-day-picker](https://d
1978
1977
 
1979
1978
  ```tsx
1980
1979
  <Popover>
1981
- <Popover.Trigger asChild>
1982
- <Button variant="outline" icon={CalendarDotsIcon}>
1983
- {formatRange()}
1984
- </Button>
1980
+ <Popover.Trigger
1981
+ render={<Button variant="outline" icon={CalendarDotsIcon} />}
1982
+ >
1983
+ {formatRange()}
1985
1984
  </Popover.Trigger>
1986
1985
  <Popover.Content className="p-3">
1987
1986
  <DatePicker
@@ -1996,14 +1995,14 @@ DatePicker — a date selection calendar. Built on [react-day-picker](https://d
1996
1995
 
1997
1996
  ```tsx
1998
1997
  <Popover>
1999
- <Popover.Trigger asChild>
2000
- <Button variant="outline" icon={CalendarDotsIcon}>
2001
- {formatRange()}
2002
- </Button>
1998
+ <Popover.Trigger
1999
+ render={<Button variant="outline" icon={CalendarDotsIcon} />}
2000
+ >
2001
+ {formatRange()}
2003
2002
  </Popover.Trigger>
2004
2003
  <Popover.Content className="p-0">
2005
2004
  <div className="flex">
2006
- <div className="flex flex-col gap-1 border-r border-kumo-line p-2 text-sm">
2005
+ <div className="flex flex-col gap-1 border-r border-kumo-hairline p-2 text-sm">
2007
2006
  {presets.map((preset) => {
2008
2007
  const isActive = isPresetActive(preset);
2009
2008
  return (
@@ -2011,10 +2010,11 @@ DatePicker — a date selection calendar. Built on [react-day-picker](https://d
2011
2010
  key={preset.label}
2012
2011
  type="button"
2013
2012
  onClick={() => handlePresetClick(preset)}
2014
- className={`rounded-md px-3 py-1.5 text-left whitespace-nowrap ${isActive
2015
- ? "bg-kumo-bg-inverse text-kumo-text-inverse"
2016
- : "text-kumo-strong hover:bg-kumo-control"
2017
- }`}
2013
+ className={`rounded-md px-3 py-1.5 text-left whitespace-nowrap ${
2014
+ isActive
2015
+ ? "bg-kumo-bg-inverse text-kumo-text-inverse"
2016
+ : "text-kumo-strong hover:bg-kumo-control"
2017
+ }`}
2018
2018
  >
2019
2019
  {preset.label}
2020
2020
  </button>
@@ -2149,7 +2149,7 @@ Dialog component
2149
2149
 
2150
2150
  **Colors (kumo tokens used):**
2151
2151
 
2152
- `bg-kumo-base`, `bg-kumo-recessed`, `text-kumo-default`
2152
+ `bg-kumo-base`, `bg-kumo-recessed`, `ring-kumo-line`, `text-kumo-default`
2153
2153
 
2154
2154
  **Styling:**
2155
2155
 
@@ -2465,7 +2465,7 @@ DropdownMenu — accessible dropdown menu anchored to a trigger. Compound compo
2465
2465
 
2466
2466
  **Colors (kumo tokens used):**
2467
2467
 
2468
- `bg-kumo-control`, `bg-kumo-danger`, `bg-kumo-line`, `bg-kumo-overlay`, `bg-kumo-tint`, `ring-kumo-line`, `text-kumo-danger`, `text-kumo-default`
2468
+ `bg-kumo-control`, `bg-kumo-danger`, `bg-kumo-hairline`, `bg-kumo-overlay`, `bg-kumo-tint`, `ring-kumo-line`, `text-kumo-danger`, `text-kumo-default`
2469
2469
 
2470
2470
  **Sub-Components:**
2471
2471
 
@@ -2731,7 +2731,7 @@ Responsive CSS grid layout container with preset column configurations.
2731
2731
 
2732
2732
  **Colors (kumo tokens used):**
2733
2733
 
2734
- `border-kumo-line`
2734
+ `border-kumo-hairline`
2735
2735
 
2736
2736
  **Examples:**
2737
2737
 
@@ -3012,13 +3012,13 @@ Input component
3012
3012
 
3013
3013
  **State Classes:**
3014
3014
  - `"default"`:
3015
- - `focus`: `focus:ring-kumo-ring`
3015
+ - `focus`: `focus:ring-kumo-hairline`
3016
3016
  - `"error"`:
3017
3017
  - `focus`: `focus:ring-kumo-danger`
3018
3018
 
3019
3019
  **Colors (kumo tokens used):**
3020
3020
 
3021
- `bg-kumo-control`, `ring-kumo-danger`, `ring-kumo-line`, `ring-kumo-ring`, `text-kumo-default`, `text-kumo-subtle`
3021
+ `bg-kumo-control`, `ring-kumo-danger`, `ring-kumo-hairline`, `text-kumo-default`, `text-kumo-subtle`
3022
3022
 
3023
3023
  **Styling:**
3024
3024
 
@@ -3039,7 +3039,6 @@ Input component
3039
3039
  label="Email"
3040
3040
  placeholder="you@example.com"
3041
3041
  value="invalid-email"
3042
- variant="error"
3043
3042
  error="Please enter a valid email address"
3044
3043
  />
3045
3044
  ```
@@ -3049,7 +3048,6 @@ Input component
3049
3048
  label="Password"
3050
3049
  type="password"
3051
3050
  value="short"
3052
- variant="error"
3053
3051
  error={{
3054
3052
  message: "Password must be at least 8 characters",
3055
3053
  match: "tooShort",
@@ -3109,6 +3107,26 @@ Input component
3109
3107
  />
3110
3108
  ```
3111
3109
 
3110
+ ```tsx
3111
+ <Input
3112
+ label="With onChange"
3113
+ placeholder="Type something..."
3114
+ description={value ? `Value: ${value}` : "Uses e.target.value"}
3115
+ value={value}
3116
+ onChange={(e) => setValue(e.target.value)}
3117
+ />
3118
+ ```
3119
+
3120
+ ```tsx
3121
+ <Input
3122
+ label="With onValueChange"
3123
+ placeholder="Type something..."
3124
+ description={value ? `Value: ${value}` : "Receives the value directly"}
3125
+ value={value}
3126
+ onValueChange={(v) => setValue(v)}
3127
+ />
3128
+ ```
3129
+
3112
3130
 
3113
3131
  ---
3114
3132
 
@@ -3208,13 +3226,19 @@ LayerCard component
3208
3226
 
3209
3227
  **Props:**
3210
3228
 
3229
+ - `render`: ReactNode
3230
+ Allows you to replace the component’s HTML element with a different tag, or compose it with another component.
3231
+
3232
+ Accepts a `ReactElement` or a function that returns the element to render.
3211
3233
  - `children`: ReactNode
3212
3234
  - `className`: string
3213
- Additional CSS classes merged via `cn()`.
3235
+ - `id`: string
3236
+ - `lang`: string
3237
+ - `title`: string
3214
3238
 
3215
3239
  **Colors (kumo tokens used):**
3216
3240
 
3217
- `bg-kumo-base`, `bg-kumo-elevated`, `ring-kumo-fill`, `ring-kumo-line`, `text-kumo-strong`
3241
+ `bg-kumo-base`, `bg-kumo-elevated`, `ring-kumo-fill`, `ring-kumo-hairline`, `ring-kumo-line`, `text-kumo-strong`
3218
3242
 
3219
3243
  **Styling:**
3220
3244
 
@@ -3460,7 +3484,7 @@ MenuBar — horizontal icon-button toolbar with keyboard arrow-key navigation.
3460
3484
 
3461
3485
  **Colors (kumo tokens used):**
3462
3486
 
3463
- `bg-kumo-base`, `bg-kumo-recessed`, `border-kumo-fill`, `border-kumo-recessed`
3487
+ `bg-kumo-base`, `bg-kumo-elevated`, `bg-kumo-recessed`, `border-kumo-recessed`, `ring-kumo-line`
3464
3488
 
3465
3489
  **Styling:**
3466
3490
 
@@ -3571,6 +3595,12 @@ Pagination component
3571
3595
  Total number of items across all pages.
3572
3596
  - `className`: string
3573
3597
  Additional CSS classes for the container
3598
+ - `labels`: PaginationLabels
3599
+ Labels for internationalization of aria-labels. All labels have English defaults.
3600
+
3601
+ For visible text like "Showing X of Y", use render props on sub-components:
3602
+ - `Pagination.Info` children for the info text
3603
+ - `Pagination.PageSize` label prop for the "Per page:" text
3574
3604
  - `children`: ReactNode
3575
3605
  Compound component children for custom layouts. Use Pagination.Info, Pagination.PageSize, Pagination.Controls, and Pagination.Separator.
3576
3606
  - `controls`: enum [default: full]
@@ -3580,7 +3610,7 @@ Pagination component
3580
3610
 
3581
3611
  **Colors (kumo tokens used):**
3582
3612
 
3583
- `border-kumo-line`, `text-kumo-strong`
3613
+ `border-kumo-hairline`, `ring-kumo-hairline`, `text-kumo-strong`
3584
3614
 
3585
3615
  **Styling:**
3586
3616
 
@@ -3607,6 +3637,7 @@ PageSize sub-component
3607
3637
  Props:
3608
3638
  - `value`: number (required)
3609
3639
  - `options`: number[]
3640
+ - `page`: " (required)
3610
3641
  - `label`: ReactNode
3611
3642
  - `className`: string
3612
3643
 
@@ -3615,6 +3646,8 @@ Props:
3615
3646
  Controls sub-component
3616
3647
 
3617
3648
  Props:
3649
+ - `Note`: ** `"dropdown"` renders an option for every page (required)
3650
+ - `pageSelector`: "input" | "dropdown"
3618
3651
  - `className`: string
3619
3652
 
3620
3653
  #### Pagination.Separator
@@ -3694,6 +3727,26 @@ Props:
3694
3727
  </Pagination>
3695
3728
  ```
3696
3729
 
3730
+ ```tsx
3731
+ <Pagination
3732
+ page={page}
3733
+ setPage={setPage}
3734
+ perPage={perPage}
3735
+ totalCount={500}
3736
+ >
3737
+ <Pagination.Info />
3738
+ <Pagination.Separator />
3739
+ <Pagination.PageSize
3740
+ value={perPage}
3741
+ onChange={(size) => {
3742
+ setPerPage(size);
3743
+ setPage(1);
3744
+ }}
3745
+ />
3746
+ <Pagination.Controls pageSelector="dropdown" />
3747
+ </Pagination>
3748
+ ```
3749
+
3697
3750
  ```tsx
3698
3751
  <Pagination
3699
3752
  page={page}
@@ -3716,6 +3769,34 @@ Props:
3716
3769
  </Pagination>
3717
3770
  ```
3718
3771
 
3772
+ ```tsx
3773
+ <Pagination
3774
+ page={page}
3775
+ setPage={setPage}
3776
+ perPage={10}
3777
+ totalCount={100}
3778
+ labels={{
3779
+ firstPage: "Première page",
3780
+ previousPage: "Page précédente",
3781
+ nextPage: "Page suivante",
3782
+ lastPage: "Dernière page",
3783
+ pageNumber: "Numéro de page",
3784
+ pageSize: "Taille de page",
3785
+ }}
3786
+ >
3787
+ <Pagination.Info>
3788
+ {({ pageShowingRange, totalCount }) => (
3789
+ <>
3790
+ Affichage de{" "}
3791
+ <span className="tabular-nums">{pageShowingRange}</span> sur{" "}
3792
+ <span className="tabular-nums">{totalCount}</span>
3793
+ </>
3794
+ )}
3795
+ </Pagination.Info>
3796
+ <Pagination.Controls />
3797
+ </Pagination>
3798
+ ```
3799
+
3719
3800
 
3720
3801
  ---
3721
3802
 
@@ -3770,9 +3851,11 @@ Close sub-component
3770
3851
 
3771
3852
  ```tsx
3772
3853
  <Popover>
3773
- <Popover.Trigger asChild>
3774
- <Button shape="square" icon={BellIcon} aria-label="Notifications" />
3775
- </Popover.Trigger>
3854
+ <Popover.Trigger
3855
+ render={
3856
+ <Button shape="square" icon={BellIcon} aria-label="Notifications" />
3857
+ }
3858
+ />
3776
3859
  <Popover.Content>
3777
3860
  <Popover.Title>Notifications</Popover.Title>
3778
3861
  <Popover.Description>
@@ -3784,9 +3867,7 @@ Close sub-component
3784
3867
 
3785
3868
  ```tsx
3786
3869
  <Popover>
3787
- <Popover.Trigger asChild>
3788
- <Button>Open Popover</Button>
3789
- </Popover.Trigger>
3870
+ <Popover.Trigger render={<Button />}>Open Popover</Popover.Trigger>
3790
3871
  <Popover.Content>
3791
3872
  <Popover.Title>Popover Title</Popover.Title>
3792
3873
  <Popover.Description>
@@ -3798,19 +3879,15 @@ Close sub-component
3798
3879
 
3799
3880
  ```tsx
3800
3881
  <Popover>
3801
- <Popover.Trigger asChild>
3802
- <Button>Open Settings</Button>
3803
- </Popover.Trigger>
3882
+ <Popover.Trigger render={<Button />}>Open Settings</Popover.Trigger>
3804
3883
  <Popover.Content>
3805
3884
  <Popover.Title>Settings</Popover.Title>
3806
3885
  <Popover.Description>
3807
3886
  Configure your preferences below.
3808
3887
  </Popover.Description>
3809
3888
  <div className="mt-3">
3810
- <Popover.Close asChild>
3811
- <Button variant="secondary" size="sm">
3812
- Close
3813
- </Button>
3889
+ <Popover.Close render={<Button variant="secondary" size="sm" />}>
3890
+ Close
3814
3891
  </Popover.Close>
3815
3892
  </div>
3816
3893
  </Popover.Content>
@@ -3820,8 +3897,8 @@ Close sub-component
3820
3897
  ```tsx
3821
3898
  <div className="flex flex-wrap gap-4">
3822
3899
  <Popover>
3823
- <Popover.Trigger asChild>
3824
- <Button variant="secondary">Bottom</Button>
3900
+ <Popover.Trigger render={<Button variant="secondary" />}>
3901
+ Bottom
3825
3902
  </Popover.Trigger>
3826
3903
  <Popover.Content side="bottom">
3827
3904
  <Popover.Title>Bottom</Popover.Title>
@@ -3832,8 +3909,8 @@ Close sub-component
3832
3909
  </Popover>
3833
3910
 
3834
3911
  <Popover>
3835
- <Popover.Trigger asChild>
3836
- <Button variant="secondary">Top</Button>
3912
+ <Popover.Trigger render={<Button variant="secondary" />}>
3913
+ Top
3837
3914
  </Popover.Trigger>
3838
3915
  <Popover.Content side="top">
3839
3916
  <Popover.Title>Top</Popover.Title>
@@ -3842,8 +3919,8 @@ Close sub-component
3842
3919
  </Popover>
3843
3920
 
3844
3921
  <Popover>
3845
- <Popover.Trigger asChild>
3846
- <Button variant="secondary">Left</Button>
3922
+ <Popover.Trigger render={<Button variant="secondary" />}>
3923
+ Left
3847
3924
  </Popover.Trigger>
3848
3925
  <Popover.Content side="left">
3849
3926
  <Popover.Title>Left</Popover.Title>
@@ -3852,8 +3929,8 @@ Close sub-component
3852
3929
  </Popover>
3853
3930
 
3854
3931
  <Popover>
3855
- <Popover.Trigger asChild>
3856
- <Button variant="secondary">Right</Button>
3932
+ <Popover.Trigger render={<Button variant="secondary" />}>
3933
+ Right
3857
3934
  </Popover.Trigger>
3858
3935
  <Popover.Content side="right">
3859
3936
  <Popover.Title>Right</Popover.Title>
@@ -3865,9 +3942,7 @@ Close sub-component
3865
3942
 
3866
3943
  ```tsx
3867
3944
  <Popover>
3868
- <Popover.Trigger asChild>
3869
- <Button>User Profile</Button>
3870
- </Popover.Trigger>
3945
+ <Popover.Trigger render={<Button />}>User Profile</Popover.Trigger>
3871
3946
  <Popover.Content className="w-64">
3872
3947
  <div className="flex items-center gap-3">
3873
3948
  <div className="size-10 rounded-full bg-kumo-recessed" />
@@ -3876,14 +3951,14 @@ Close sub-component
3876
3951
  <p className="text-sm text-kumo-subtle">jane@example.com</p>
3877
3952
  </div>
3878
3953
  </div>
3879
- <div className="mt-3 flex gap-2 border-t border-kumo-line pt-3">
3954
+ <div className="mt-3 flex gap-2 border-t border-kumo-hairline pt-3">
3880
3955
  <Button variant="secondary" size="sm" className="flex-1">
3881
3956
  Profile
3882
3957
  </Button>
3883
- <Popover.Close asChild>
3884
- <Button variant="ghost" size="sm" className="flex-1">
3885
- Sign Out
3886
- </Button>
3958
+ <Popover.Close
3959
+ render={<Button variant="ghost" size="sm" className="flex-1" />}
3960
+ >
3961
+ Sign Out
3887
3962
  </Popover.Close>
3888
3963
  </div>
3889
3964
  </Popover.Content>
@@ -3892,8 +3967,12 @@ Close sub-component
3892
3967
 
3893
3968
  ```tsx
3894
3969
  <Popover>
3895
- <Popover.Trigger openOnHover delay={200} asChild>
3896
- <Button variant="secondary">Hover Me</Button>
3970
+ <Popover.Trigger
3971
+ openOnHover
3972
+ delay={200}
3973
+ render={<Button variant="secondary" />}
3974
+ >
3975
+ Hover Me
3897
3976
  </Popover.Trigger>
3898
3977
  <Popover.Content>
3899
3978
  <Popover.Title>Hover Triggered</Popover.Title>
@@ -3902,16 +3981,79 @@ Close sub-component
3902
3981
  interactive content like buttons and links.
3903
3982
  </Popover.Description>
3904
3983
  <div className="mt-3">
3905
- <Popover.Close asChild>
3906
- <Button variant="secondary" size="sm">
3907
- Got it
3908
- </Button>
3984
+ <Popover.Close render={<Button variant="secondary" size="sm" />}>
3985
+ Got it
3909
3986
  </Popover.Close>
3910
3987
  </div>
3911
3988
  </Popover.Content>
3912
3989
  </Popover>
3913
3990
  ```
3914
3991
 
3992
+ ```tsx
3993
+ <div className="w-full">
3994
+ <div className="overflow-hidden rounded-lg border border-kumo-hairline">
3995
+ <table className="w-full text-sm">
3996
+ <thead className="bg-kumo-elevated">
3997
+ <tr>
3998
+ <th className="px-4 py-2 text-left font-medium">Name</th>
3999
+ <th className="px-4 py-2 text-left font-medium">Status</th>
4000
+ <th className="w-12 px-4 py-2"></th>
4001
+ </tr>
4002
+ </thead>
4003
+ <tbody className="divide-y divide-kumo-hairline">
4004
+ {rows.map((row) => (
4005
+ <tr
4006
+ key={row.id}
4007
+ ref={(el) => {
4008
+ if (el) rowRefs.current.set(row.id, el);
4009
+ }}
4010
+ className={
4011
+ selectedRow === row.id ? "bg-kumo-recessed" : "bg-kumo-base"
4012
+ }
4013
+ >
4014
+ <td className="px-4 py-2 font-mono">{row.name}</td>
4015
+ <td className="px-4 py-2 text-kumo-subtle">{row.status}</td>
4016
+ <td className="px-4 py-2">
4017
+ <Button
4018
+ size="xs"
4019
+ variant="ghost"
4020
+ shape="square"
4021
+ icon={DotsThree}
4022
+ aria-label={`Actions for ${row.name}`}
4023
+ onClick={() => handleEdit(row.id)}
4024
+ />
4025
+ </td>
4026
+ </tr>
4027
+ ))}
4028
+ </tbody>
4029
+ </table>
4030
+ </div>
4031
+ <Popover
4032
+ open={!!selectedRow}
4033
+ onOpenChange={(open) => !open && setSelectedRow(null)}
4034
+ >
4035
+ <Popover.Content
4036
+ side="left"
4037
+ anchor={
4038
+ anchorRect ? { getBoundingClientRect: () => anchorRect } : undefined
4039
+ }
4040
+ >
4041
+ <Popover.Title>
4042
+ Edit {rows.find((r) => r.id === selectedRow)?.name}
4043
+ </Popover.Title>
4044
+ <Popover.Description>
4045
+ The popover anchors to the selected row, not the icon button.
4046
+ </Popover.Description>
4047
+ <div className="mt-3">
4048
+ <Popover.Close render={<Button size="sm" variant="secondary" />}>
4049
+ Close
4050
+ </Popover.Close>
4051
+ </div>
4052
+ </Popover.Content>
4053
+ </Popover>
4054
+ </div>
4055
+ ```
4056
+
3915
4057
 
3916
4058
  ---
3917
4059
 
@@ -3957,7 +4099,7 @@ Radio — radio button group for single-select choices. Compound component: `Ra
3957
4099
 
3958
4100
  **Colors (kumo tokens used):**
3959
4101
 
3960
- `bg-kumo-base`, `bg-kumo-contrast`, `bg-kumo-tint`, `border-kumo-danger`, `border-kumo-interact`, `border-kumo-ring`, `ring-kumo-danger`, `ring-kumo-line`, `ring-kumo-ring`, `text-kumo-danger`, `text-kumo-default`, `text-kumo-subtle`
4102
+ `bg-kumo-base`, `bg-kumo-contrast`, `bg-kumo-tint`, `border-kumo-danger`, `border-kumo-hairline`, `border-kumo-interact`, `ring-kumo-danger`, `ring-kumo-hairline`, `text-kumo-danger`, `text-kumo-default`, `text-kumo-subtle`
3961
4103
 
3962
4104
  **Sub-Components:**
3963
4105
 
@@ -4189,6 +4331,8 @@ Select component
4189
4331
 
4190
4332
  - `className`: string
4191
4333
  Additional CSS classes merged via `cn()`.
4334
+ - `size`: enum [default: base]
4335
+ Size of the select trigger. Matches Input component sizes.
4192
4336
  - `label`: ReactNode
4193
4337
  Label content for the select. When provided, enables the Field wrapper with a visible label above the select. For accessibility without a visible label, use `aria-label` instead.
4194
4338
  - `hideLabel`: boolean
@@ -4217,7 +4361,7 @@ Select component
4217
4361
 
4218
4362
  **Colors (kumo tokens used):**
4219
4363
 
4220
- `bg-kumo-base`, `bg-kumo-tint`, `ring-kumo-ring`, `text-kumo-danger`, `text-kumo-default`, `text-kumo-subtle`
4364
+ `bg-kumo-base`, `bg-kumo-hairline`, `bg-kumo-tint`, `ring-kumo-hairline`, `ring-kumo-line`, `text-kumo-danger`, `text-kumo-default`, `text-kumo-placeholder`, `text-kumo-subtle`
4221
4365
 
4222
4366
  **Styling:**
4223
4367
 
@@ -4230,6 +4374,18 @@ This is a compound component. Use these sub-components:
4230
4374
 
4231
4375
  Option sub-component
4232
4376
 
4377
+ #### Select.Group
4378
+
4379
+ Group sub-component
4380
+
4381
+ #### Select.GroupLabel
4382
+
4383
+ GroupLabel sub-component
4384
+
4385
+ #### Select.Separator
4386
+
4387
+ Separator sub-component
4388
+
4233
4389
 
4234
4390
  **Examples:**
4235
4391
 
@@ -4243,6 +4399,51 @@ Option sub-component
4243
4399
  />
4244
4400
  ```
4245
4401
 
4402
+ ```tsx
4403
+ <div className="grid gap-4">
4404
+ <div className="flex items-center gap-3">
4405
+ <span className="w-10 text-sm text-kumo-subtle">xs</span>
4406
+ <Select
4407
+ aria-label="Select size xs"
4408
+ size="xs"
4409
+ className="w-[200px]"
4410
+ placeholder="Choose..."
4411
+ items={{ a: "Option A", b: "Option B" }}
4412
+ />
4413
+ </div>
4414
+ <div className="flex items-center gap-3">
4415
+ <span className="w-10 text-sm text-kumo-subtle">sm</span>
4416
+ <Select
4417
+ aria-label="Select size sm"
4418
+ size="sm"
4419
+ className="w-[200px]"
4420
+ placeholder="Choose..."
4421
+ items={{ a: "Option A", b: "Option B" }}
4422
+ />
4423
+ </div>
4424
+ <div className="flex items-center gap-3">
4425
+ <span className="w-10 text-sm text-kumo-subtle">base</span>
4426
+ <Select
4427
+ aria-label="Select size base"
4428
+ size="base"
4429
+ className="w-[200px]"
4430
+ placeholder="Choose..."
4431
+ items={{ a: "Option A", b: "Option B" }}
4432
+ />
4433
+ </div>
4434
+ <div className="flex items-center gap-3">
4435
+ <span className="w-10 text-sm text-kumo-subtle">lg</span>
4436
+ <Select
4437
+ aria-label="Select size lg"
4438
+ size="lg"
4439
+ className="w-[200px]"
4440
+ placeholder="Choose..."
4441
+ items={{ a: "Option A", b: "Option B" }}
4442
+ />
4443
+ </div>
4444
+ </div>
4445
+ ```
4446
+
4246
4447
  ```tsx
4247
4448
  <Select
4248
4449
  label="Issue Type"
@@ -4405,13 +4606,12 @@ Option sub-component
4405
4606
  <Select
4406
4607
  label="Author"
4407
4608
  description="Select the primary author for this document"
4609
+ placeholder="Select an author"
4408
4610
  className="w-[200px]"
4409
4611
  onValueChange={(v) => setValue(v as (typeof authors)[0] | null)}
4410
4612
  value={value}
4411
4613
  isItemEqualToValue={(item, value) => item?.id === value?.id}
4412
- renderValue={(author) => {
4413
- return author?.name ?? "Select an author";
4414
- }}
4614
+ renderValue={(author) => author.name}
4415
4615
  >
4416
4616
  {authors.map((author) => (
4417
4617
  <Select.Option key={author.id} value={author}>
@@ -4424,6 +4624,74 @@ Option sub-component
4424
4624
  </Select>
4425
4625
  ```
4426
4626
 
4627
+ ```tsx
4628
+ <Select
4629
+ label="Deployment Region"
4630
+ placeholder="Choose a region..."
4631
+ className="w-[250px]"
4632
+ value={value}
4633
+ onValueChange={(v) => setValue(v as Region | null)}
4634
+ isItemEqualToValue={(item, val) => item.value === val.value}
4635
+ >
4636
+ {regions.map((region) => (
4637
+ <Select.Option
4638
+ key={region.value}
4639
+ value={region}
4640
+ disabled={region.disabled}
4641
+ >
4642
+ {region.label}
4643
+ </Select.Option>
4644
+ ))}
4645
+ </Select>
4646
+ ```
4647
+
4648
+ ```tsx
4649
+ <Select
4650
+ label="Food"
4651
+ placeholder="Pick a food..."
4652
+ className="w-[220px]"
4653
+ value={value}
4654
+ onValueChange={(v) => setValue(v as Food | null)}
4655
+ isItemEqualToValue={(item, val) => item.value === val.value}
4656
+ >
4657
+ <Select.Group>
4658
+ <Select.GroupLabel>Fruits</Select.GroupLabel>
4659
+ {foods.fruits.map((food) => (
4660
+ <Select.Option key={food.value} value={food}>
4661
+ {food.label}
4662
+ </Select.Option>
4663
+ ))}
4664
+ </Select.Group>
4665
+ <Select.Separator />
4666
+ <Select.Group>
4667
+ <Select.GroupLabel>Vegetables</Select.GroupLabel>
4668
+ {foods.vegetables.map((food) => (
4669
+ <Select.Option key={food.value} value={food}>
4670
+ {food.label}
4671
+ </Select.Option>
4672
+ ))}
4673
+ </Select.Group>
4674
+ </Select>
4675
+ ```
4676
+
4677
+ ```tsx
4678
+ <Select
4679
+ label="Long List Select"
4680
+ description="Tests scrolling behavior with many options"
4681
+ placeholder="Choose an option..."
4682
+ className="w-[220px]"
4683
+ value={value}
4684
+ onValueChange={(v) => setValue(v as LongListItem | null)}
4685
+ isItemEqualToValue={(item, val) => item.value === val.value}
4686
+ >
4687
+ {longListItems.map((item) => (
4688
+ <Select.Option key={item.value} value={item}>
4689
+ {item.label}
4690
+ </Select.Option>
4691
+ ))}
4692
+ </Select>
4693
+ ```
4694
+
4427
4695
 
4428
4696
  ---
4429
4697
 
@@ -4478,7 +4746,7 @@ Password/secret input that masks its value by default and reveals on click. Incl
4478
4746
 
4479
4747
  **Colors (kumo tokens used):**
4480
4748
 
4481
- `bg-kumo-brand`, `bg-kumo-control`, `outline-kumo-ring`, `ring-kumo-ring`, `text-kumo-default`, `text-kumo-subtle`
4749
+ `bg-kumo-brand`, `bg-kumo-control`, `outline-kumo-hairline`, `ring-kumo-hairline`, `text-kumo-default`, `text-kumo-subtle`
4482
4750
 
4483
4751
  **Examples:**
4484
4752
 
@@ -4595,7 +4863,7 @@ Sidebar — responsive navigation panel with expand/collapse support. Compound
4595
4863
 
4596
4864
  **Colors (kumo tokens used):**
4597
4865
 
4598
- `bg-kumo-base`, `bg-kumo-brand`, `bg-kumo-line`, `bg-kumo-overlay`, `bg-kumo-recessed`, `bg-kumo-tint`, `border-kumo-line`, `ring-kumo-line`, `ring-kumo-ring`, `text-kumo-default`, `text-kumo-strong`, `text-kumo-subtle`
4866
+ `bg-kumo-base`, `bg-kumo-brand`, `bg-kumo-hairline`, `bg-kumo-overlay`, `bg-kumo-recessed`, `bg-kumo-tint`, `border-kumo-hairline`, `ring-kumo-hairline`, `text-kumo-default`, `text-kumo-strong`, `text-kumo-subtle`
4599
4867
 
4600
4868
  **Styling:**
4601
4869
 
@@ -5030,7 +5298,7 @@ CollapsibleContent sub-component
5030
5298
 
5031
5299
  ### Surface
5032
5300
 
5033
- Polymorphic container with consistent background, shadow, and border styling. Use the `render` prop to change the underlying element: ```tsx <Surface render={<section />} className="rounded-lg p-4">Card content</Surface> ```
5301
+ Surface component
5034
5302
 
5035
5303
  **Type:** component
5036
5304
 
@@ -5051,49 +5319,6 @@ Accepts a `ReactElement` or a function that returns the element to render.
5051
5319
  - `lang`: string
5052
5320
  - `title`: string
5053
5321
 
5054
- **Colors (kumo tokens used):**
5055
-
5056
- `bg-kumo-base`, `ring-kumo-line`
5057
-
5058
- **Examples:**
5059
-
5060
- ```tsx
5061
- <Surface className="rounded-lg p-6">
5062
- <Text size="lg" bold>
5063
- Surface Component
5064
- </Text>
5065
- <div className="mt-2">
5066
- <Text variant="secondary">
5067
- A container with consistent elevation and border styling.
5068
- </Text>
5069
- </div>
5070
- </Surface>
5071
- ```
5072
-
5073
- ```tsx
5074
- <div className="flex flex-col gap-4">
5075
- <Surface render={<section />} className="rounded-lg p-4">
5076
- <Text bold>As section element</Text>
5077
- </Surface>
5078
- <Surface render={<article />} className="rounded-lg p-4">
5079
- <Text bold>As article element</Text>
5080
- </Surface>
5081
- <Surface render={<aside />} className="rounded-lg p-4">
5082
- <Text bold>As aside element</Text>
5083
- </Surface>
5084
- </div>
5085
- ```
5086
-
5087
- ```tsx
5088
- <Surface className="rounded-lg p-6">
5089
- <Text bold>Outer Surface</Text>
5090
- <Surface className="mt-4 rounded-md bg-kumo-elevated p-4">
5091
- <Text variant="secondary">Nested Surface</Text>
5092
- </Surface>
5093
- </Surface>
5094
- ```
5095
-
5096
-
5097
5322
  ---
5098
5323
 
5099
5324
  ### Switch
@@ -5138,7 +5363,7 @@ Switch component
5138
5363
 
5139
5364
  **Colors (kumo tokens used):**
5140
5365
 
5141
- `bg-kumo-base`, `border-kumo-line`, `ring-kumo-line`, `text-kumo-danger`, `text-kumo-default`, `text-kumo-subtle`
5366
+ `bg-kumo-base`, `border-kumo-hairline`, `ring-kumo-hairline`, `text-kumo-danger`, `text-kumo-default`, `text-kumo-subtle`
5142
5367
 
5143
5368
  **Sub-Components:**
5144
5369
 
@@ -5206,16 +5431,8 @@ Props:
5206
5431
 
5207
5432
  ```tsx
5208
5433
  <div className="grid grid-cols-2 gap-x-8 gap-y-4">
5209
- <Switch
5210
- label="Default off"
5211
- checked={false}
5212
- onCheckedChange={() => {}}
5213
- />
5214
- <Switch
5215
- label="Default on"
5216
- checked={true}
5217
- onCheckedChange={() => {}}
5218
- />
5434
+ <Switch label="Default off" checked={false} onCheckedChange={() => {}} />
5435
+ <Switch label="Default on" checked={true} onCheckedChange={() => {}} />
5219
5436
  <Switch
5220
5437
  label="Neutral off"
5221
5438
  variant="neutral"
@@ -5231,6 +5448,15 @@ Props:
5231
5448
  </div>
5232
5449
  ```
5233
5450
 
5451
+ ```tsx
5452
+ <Switch
5453
+ id="my-custom-switch"
5454
+ label="Custom ID"
5455
+ checked={checked}
5456
+ onCheckedChange={setChecked}
5457
+ />
5458
+ ```
5459
+
5234
5460
  ```tsx
5235
5461
  <div className="flex flex-col gap-4">
5236
5462
  <Switch
@@ -5285,7 +5511,7 @@ Table — semantic HTML table with styled rows, cells, and selection support. C
5285
5511
 
5286
5512
  **Colors (kumo tokens used):**
5287
5513
 
5288
- `bg-kumo-base`, `bg-kumo-elevated`, `bg-kumo-ring`, `bg-kumo-tint`, `border-kumo-fill`, `text-kumo-default`, `text-kumo-strong`
5514
+ `bg-kumo-base`, `bg-kumo-elevated`, `bg-kumo-hairline`, `bg-kumo-tint`, `border-kumo-fill`, `text-kumo-default`, `text-kumo-strong`
5289
5515
 
5290
5516
  **Sub-Components:**
5291
5517
 
@@ -5331,326 +5557,537 @@ ResizeHandle sub-component
5331
5557
  **Examples:**
5332
5558
 
5333
5559
  ```tsx
5334
- <LayerCard>
5335
- <LayerCard.Primary className="p-0">
5336
- <Table>
5337
- <Table.Header>
5338
- <Table.Row>
5339
- <Table.Head>Subject</Table.Head>
5340
- <Table.Head>From</Table.Head>
5341
- <Table.Head>Date</Table.Head>
5560
+ <LayerCard className="p-0">
5561
+ <Table>
5562
+ <Table.Header>
5563
+ <Table.Row>
5564
+ <Table.Head>Subject</Table.Head>
5565
+ <Table.Head>From</Table.Head>
5566
+ <Table.Head>Date</Table.Head>
5567
+ </Table.Row>
5568
+ </Table.Header>
5569
+ <Table.Body>
5570
+ {emailData.slice(0, 3).map((row) => (
5571
+ <Table.Row key={row.id}>
5572
+ <Table.Cell>{row.subject}</Table.Cell>
5573
+ <Table.Cell>{row.from}</Table.Cell>
5574
+ <Table.Cell>{row.date}</Table.Cell>
5342
5575
  </Table.Row>
5343
- </Table.Header>
5344
- <Table.Body>
5345
- {emailData.slice(0, 3).map((row) => (
5346
- <Table.Row key={row.id}>
5347
- <Table.Cell>{row.subject}</Table.Cell>
5348
- <Table.Cell>{row.from}</Table.Cell>
5349
- <Table.Cell>{row.date}</Table.Cell>
5350
- </Table.Row>
5351
- ))}
5352
- </Table.Body>
5353
- </Table>
5354
- </LayerCard.Primary>
5576
+ ))}
5577
+ </Table.Body>
5578
+ </Table>
5355
5579
  </LayerCard>
5356
5580
  ```
5357
5581
 
5358
5582
  ```tsx
5359
- <LayerCard>
5360
- <LayerCard.Primary className="p-0">
5361
- <Table>
5362
- <Table.Header>
5363
- <Table.Row>
5364
- <Table.CheckHead
5365
- checked={selectedIds.size === rows.length}
5366
- indeterminate={
5367
- selectedIds.size > 0 && selectedIds.size < rows.length
5368
- }
5369
- onValueChange={toggleAll}
5370
- aria-label="Select all rows"
5583
+ <LayerCard className="p-0">
5584
+ <Table>
5585
+ <Table.Header>
5586
+ <Table.Row>
5587
+ <Table.CheckHead
5588
+ checked={selectedIds.size === rows.length}
5589
+ indeterminate={
5590
+ selectedIds.size > 0 && selectedIds.size < rows.length
5591
+ }
5592
+ onValueChange={toggleAll}
5593
+ aria-label="Select all rows"
5594
+ />
5595
+ <Table.Head>Subject</Table.Head>
5596
+ <Table.Head>From</Table.Head>
5597
+ <Table.Head>Date</Table.Head>
5598
+ </Table.Row>
5599
+ </Table.Header>
5600
+ <Table.Body>
5601
+ {rows.map((row) => (
5602
+ <Table.Row key={row.id}>
5603
+ <Table.CheckCell
5604
+ checked={selectedIds.has(row.id)}
5605
+ onValueChange={() => toggleRow(row.id)}
5606
+ aria-label={`Select ${row.subject}`}
5371
5607
  />
5372
- <Table.Head>Subject</Table.Head>
5373
- <Table.Head>From</Table.Head>
5374
- <Table.Head>Date</Table.Head>
5608
+ <Table.Cell>{row.subject}</Table.Cell>
5609
+ <Table.Cell>{row.from}</Table.Cell>
5610
+ <Table.Cell>{row.date}</Table.Cell>
5375
5611
  </Table.Row>
5376
- </Table.Header>
5377
- <Table.Body>
5378
- {rows.map((row) => (
5379
- <Table.Row key={row.id}>
5380
- <Table.CheckCell
5381
- checked={selectedIds.has(row.id)}
5382
- onValueChange={() => toggleRow(row.id)}
5383
- aria-label={`Select ${row.subject}`}
5384
- />
5385
- <Table.Cell>{row.subject}</Table.Cell>
5386
- <Table.Cell>{row.from}</Table.Cell>
5387
- <Table.Cell>{row.date}</Table.Cell>
5388
- </Table.Row>
5389
- ))}
5390
- </Table.Body>
5391
- </Table>
5392
- </LayerCard.Primary>
5612
+ ))}
5613
+ </Table.Body>
5614
+ </Table>
5393
5615
  </LayerCard>
5394
5616
  ```
5395
5617
 
5396
5618
  ```tsx
5397
- <LayerCard>
5398
- <LayerCard.Primary className="p-0">
5399
- <Table>
5400
- <Table.Header variant="compact">
5401
- <Table.Row>
5402
- <Table.Head>Subject</Table.Head>
5403
- <Table.Head>From</Table.Head>
5404
- <Table.Head>Date</Table.Head>
5619
+ <LayerCard className="p-0">
5620
+ <Table>
5621
+ <Table.Header variant="compact">
5622
+ <Table.Row>
5623
+ <Table.Head>Subject</Table.Head>
5624
+ <Table.Head>From</Table.Head>
5625
+ <Table.Head>Date</Table.Head>
5626
+ </Table.Row>
5627
+ </Table.Header>
5628
+ <Table.Body>
5629
+ {emailData.slice(0, 3).map((row) => (
5630
+ <Table.Row key={row.id}>
5631
+ <Table.Cell>{row.subject}</Table.Cell>
5632
+ <Table.Cell>{row.from}</Table.Cell>
5633
+ <Table.Cell>{row.date}</Table.Cell>
5405
5634
  </Table.Row>
5406
- </Table.Header>
5407
- <Table.Body>
5408
- {emailData.slice(0, 3).map((row) => (
5409
- <Table.Row key={row.id}>
5410
- <Table.Cell>{row.subject}</Table.Cell>
5411
- <Table.Cell>{row.from}</Table.Cell>
5412
- <Table.Cell>{row.date}</Table.Cell>
5413
- </Table.Row>
5414
- ))}
5415
- </Table.Body>
5416
- </Table>
5417
- </LayerCard.Primary>
5635
+ ))}
5636
+ </Table.Body>
5637
+ </Table>
5418
5638
  </LayerCard>
5419
5639
  ```
5420
5640
 
5421
5641
  ```tsx
5422
- <LayerCard>
5423
- <LayerCard.Primary className="p-0">
5424
- <Table>
5425
- <Table.Header>
5426
- <Table.Row>
5427
- <Table.CheckHead
5428
- checked={selectedIds.size === rows.length}
5429
- indeterminate={
5430
- selectedIds.size > 0 && selectedIds.size < rows.length
5431
- }
5432
- onValueChange={toggleAll}
5433
- aria-label="Select all rows"
5642
+ <LayerCard className="p-0">
5643
+ <Table>
5644
+ <Table.Header>
5645
+ <Table.Row>
5646
+ <Table.CheckHead
5647
+ checked={selectedIds.size === rows.length}
5648
+ indeterminate={
5649
+ selectedIds.size > 0 && selectedIds.size < rows.length
5650
+ }
5651
+ onValueChange={toggleAll}
5652
+ aria-label="Select all rows"
5653
+ />
5654
+ <Table.Head>Subject</Table.Head>
5655
+ <Table.Head>From</Table.Head>
5656
+ <Table.Head>Date</Table.Head>
5657
+ </Table.Row>
5658
+ </Table.Header>
5659
+ <Table.Body>
5660
+ {rows.map((row) => (
5661
+ <Table.Row
5662
+ key={row.id}
5663
+ variant={selectedIds.has(row.id) ? "selected" : "default"}
5664
+ >
5665
+ <Table.CheckCell
5666
+ checked={selectedIds.has(row.id)}
5667
+ onValueChange={() => toggleRow(row.id)}
5668
+ aria-label={`Select ${row.subject}`}
5434
5669
  />
5435
- <Table.Head>Subject</Table.Head>
5436
- <Table.Head>From</Table.Head>
5437
- <Table.Head>Date</Table.Head>
5670
+ <Table.Cell>{row.subject}</Table.Cell>
5671
+ <Table.Cell>{row.from}</Table.Cell>
5672
+ <Table.Cell>{row.date}</Table.Cell>
5438
5673
  </Table.Row>
5439
- </Table.Header>
5440
- <Table.Body>
5441
- {rows.map((row) => (
5442
- <Table.Row
5443
- key={row.id}
5444
- variant={selectedIds.has(row.id) ? "selected" : "default"}
5445
- >
5446
- <Table.CheckCell
5447
- checked={selectedIds.has(row.id)}
5448
- onValueChange={() => toggleRow(row.id)}
5449
- aria-label={`Select ${row.subject}`}
5450
- />
5451
- <Table.Cell>{row.subject}</Table.Cell>
5452
- <Table.Cell>{row.from}</Table.Cell>
5453
- <Table.Cell>{row.date}</Table.Cell>
5454
- </Table.Row>
5455
- ))}
5456
- </Table.Body>
5457
- </Table>
5458
- </LayerCard.Primary>
5674
+ ))}
5675
+ </Table.Body>
5676
+ </Table>
5459
5677
  </LayerCard>
5460
5678
  ```
5461
5679
 
5462
5680
  ```tsx
5463
- <LayerCard>
5464
- <LayerCard.Primary className="p-0">
5465
- <Table layout="fixed">
5466
- <colgroup>
5467
- <col />
5468
- <col className="w-[150px]" />
5469
- <col className="w-[150px]" />
5470
- </colgroup>
5471
- <Table.Header>
5472
- <Table.Row>
5473
- <Table.Head>Subject</Table.Head>
5474
- <Table.Head>From</Table.Head>
5475
- <Table.Head>Date</Table.Head>
5681
+ <LayerCard className="p-0">
5682
+ <Table layout="fixed">
5683
+ <colgroup>
5684
+ <col />
5685
+ <col className="w-[150px]" />
5686
+ <col className="w-[150px]" />
5687
+ </colgroup>
5688
+ <Table.Header>
5689
+ <Table.Row>
5690
+ <Table.Head>Subject</Table.Head>
5691
+ <Table.Head>From</Table.Head>
5692
+ <Table.Head>Date</Table.Head>
5693
+ </Table.Row>
5694
+ </Table.Header>
5695
+ <Table.Body>
5696
+ {emailData.map((row) => (
5697
+ <Table.Row key={row.id}>
5698
+ <Table.Cell>{row.subject}</Table.Cell>
5699
+ <Table.Cell>{row.from}</Table.Cell>
5700
+ <Table.Cell>{row.date}</Table.Cell>
5476
5701
  </Table.Row>
5477
- </Table.Header>
5478
- <Table.Body>
5479
- {emailData.map((row) => (
5480
- <Table.Row key={row.id}>
5481
- <Table.Cell>{row.subject}</Table.Cell>
5482
- <Table.Cell>{row.from}</Table.Cell>
5483
- <Table.Cell>{row.date}</Table.Cell>
5484
- </Table.Row>
5485
- ))}
5486
- </Table.Body>
5487
- </Table>
5488
- </LayerCard.Primary>
5702
+ ))}
5703
+ </Table.Body>
5704
+ </Table>
5489
5705
  </LayerCard>
5490
5706
  ```
5491
5707
 
5492
5708
  ```tsx
5493
- <LayerCard>
5494
- <LayerCard.Primary className="w-full max-w-md overflow-x-auto p-0">
5495
- <Table>
5496
- <Table.Header>
5497
- <Table.Row>
5498
- <Table.Head>Subject</Table.Head>
5499
- <Table.Head>From</Table.Head>
5500
- <Table.Head>Date</Table.Head>
5501
- <Table.Head>Tags</Table.Head>
5502
- <Table.Head sticky="right">
5503
- <span className="sr-only">Actions</span>
5504
- </Table.Head>
5709
+ <LayerCard className="w-full max-w-md overflow-x-auto p-0">
5710
+ <Table>
5711
+ <Table.Header variant="compact">
5712
+ <Table.Row>
5713
+ <Table.Head>Subject</Table.Head>
5714
+ <Table.Head>From</Table.Head>
5715
+ <Table.Head>Date</Table.Head>
5716
+ <Table.Head>Tags</Table.Head>
5717
+ <Table.Head sticky="right">
5718
+ <span className="sr-only">Actions</span>
5719
+ </Table.Head>
5720
+ </Table.Row>
5721
+ </Table.Header>
5722
+ <Table.Body>
5723
+ {emailData.map((row) => (
5724
+ <Table.Row key={row.id}>
5725
+ <Table.Cell className="whitespace-nowrap">
5726
+ {row.subject}
5727
+ </Table.Cell>
5728
+ <Table.Cell className="whitespace-nowrap">
5729
+ {row.from}
5730
+ </Table.Cell>
5731
+ <Table.Cell className="whitespace-nowrap">
5732
+ {row.date}
5733
+ </Table.Cell>
5734
+ <Table.Cell className="whitespace-nowrap">
5735
+ {row.tags ? (
5736
+ <div className="inline-flex gap-1">
5737
+ {row.tags.map((tag) => (
5738
+ <Badge key={tag}>{tag}</Badge>
5739
+ ))}
5740
+ </div>
5741
+ ) : (
5742
+ "—"
5743
+ )}
5744
+ </Table.Cell>
5745
+ <Table.Cell sticky="right" className="text-right">
5746
+ <DropdownMenu>
5747
+ <DropdownMenu.Trigger
5748
+ render={
5749
+ <Button
5750
+ variant="ghost"
5751
+ size="sm"
5752
+ shape="square"
5753
+ aria-label="More options"
5754
+ >
5755
+ <DotsThree weight="bold" size={16} />
5756
+ </Button>
5757
+ }
5758
+ />
5759
+ <DropdownMenu.Content>
5760
+ <DropdownMenu.Item icon={Eye}>View</DropdownMenu.Item>
5761
+ <DropdownMenu.Item icon={PencilSimple}>
5762
+ Edit
5763
+ </DropdownMenu.Item>
5764
+ <DropdownMenu.Separator />
5765
+ <DropdownMenu.Item icon={Trash} variant="danger">
5766
+ Delete
5767
+ </DropdownMenu.Item>
5768
+ </DropdownMenu.Content>
5769
+ </DropdownMenu>
5770
+ </Table.Cell>
5505
5771
  </Table.Row>
5506
- </Table.Header>
5507
- <Table.Body>
5508
- {emailData.map((row) => (
5509
- <Table.Row key={row.id}>
5510
- <Table.Cell className="whitespace-nowrap">
5511
- {row.subject}
5512
- </Table.Cell>
5513
- <Table.Cell className="whitespace-nowrap">
5514
- {row.from}
5515
- </Table.Cell>
5516
- <Table.Cell className="whitespace-nowrap">
5517
- {row.date}
5518
- </Table.Cell>
5519
- <Table.Cell className="whitespace-nowrap">
5520
- {row.tags ? (
5521
- <div className="inline-flex gap-1">
5772
+ ))}
5773
+ </Table.Body>
5774
+ </Table>
5775
+ </LayerCard>
5776
+ ```
5777
+
5778
+ ```tsx
5779
+ <LayerCard className="w-full max-w-md overflow-x-auto p-0">
5780
+ <Table>
5781
+ <Table.Header>
5782
+ <Table.Row>
5783
+ <Table.Head>Subject</Table.Head>
5784
+ <Table.Head>From</Table.Head>
5785
+ <Table.Head>Date</Table.Head>
5786
+ <Table.Head>Tags</Table.Head>
5787
+ <Table.Head sticky="right">
5788
+ <span className="sr-only">Actions</span>
5789
+ </Table.Head>
5790
+ </Table.Row>
5791
+ </Table.Header>
5792
+ <Table.Body>
5793
+ {emailData.map((row) => (
5794
+ <Table.Row key={row.id}>
5795
+ <Table.Cell className="whitespace-nowrap">
5796
+ {row.subject}
5797
+ </Table.Cell>
5798
+ <Table.Cell className="whitespace-nowrap">
5799
+ {row.from}
5800
+ </Table.Cell>
5801
+ <Table.Cell className="whitespace-nowrap">
5802
+ {row.date}
5803
+ </Table.Cell>
5804
+ <Table.Cell className="whitespace-nowrap">
5805
+ {row.tags ? (
5806
+ <div className="inline-flex gap-1">
5807
+ {row.tags.map((tag) => (
5808
+ <Badge key={tag}>{tag}</Badge>
5809
+ ))}
5810
+ </div>
5811
+ ) : (
5812
+ "—"
5813
+ )}
5814
+ </Table.Cell>
5815
+ <Table.Cell sticky="right" className="text-right">
5816
+ <DropdownMenu>
5817
+ <DropdownMenu.Trigger
5818
+ render={
5819
+ <Button
5820
+ variant="ghost"
5821
+ size="sm"
5822
+ shape="square"
5823
+ aria-label="More options"
5824
+ >
5825
+ <DotsThree weight="bold" size={16} />
5826
+ </Button>
5827
+ }
5828
+ />
5829
+ <DropdownMenu.Content>
5830
+ <DropdownMenu.Item icon={Eye}>View</DropdownMenu.Item>
5831
+ <DropdownMenu.Item icon={PencilSimple}>
5832
+ Edit
5833
+ </DropdownMenu.Item>
5834
+ <DropdownMenu.Separator />
5835
+ <DropdownMenu.Item icon={Trash} variant="danger">
5836
+ Delete
5837
+ </DropdownMenu.Item>
5838
+ </DropdownMenu.Content>
5839
+ </DropdownMenu>
5840
+ </Table.Cell>
5841
+ </Table.Row>
5842
+ ))}
5843
+ </Table.Body>
5844
+ </Table>
5845
+ </LayerCard>
5846
+ ```
5847
+
5848
+ ```tsx
5849
+ <LayerCard className="w-full overflow-x-auto p-0">
5850
+ <Table layout="fixed">
5851
+ <colgroup>
5852
+ <col />{" "}
5853
+ {/* Checkbox column - width handled by Table.CheckHead/CheckCell */}
5854
+ <col />
5855
+ <col style={{ width: "150px" }} />
5856
+ <col style={{ width: "120px" }} />
5857
+ <col style={{ width: "50px" }} />
5858
+ </colgroup>
5859
+ <Table.Header>
5860
+ <Table.Row>
5861
+ <Table.CheckHead
5862
+ checked={selectedIds.size === emailData.length}
5863
+ indeterminate={
5864
+ selectedIds.size > 0 && selectedIds.size < emailData.length
5865
+ }
5866
+ onValueChange={toggleAll}
5867
+ aria-label="Select all rows"
5868
+ />
5869
+ <Table.Head>Subject</Table.Head>
5870
+ <Table.Head>From</Table.Head>
5871
+ <Table.Head>Date</Table.Head>
5872
+ <Table.Head></Table.Head>
5873
+ </Table.Row>
5874
+ </Table.Header>
5875
+ <Table.Body>
5876
+ {emailData.map((row) => (
5877
+ <Table.Row
5878
+ key={row.id}
5879
+ variant={selectedIds.has(row.id) ? "selected" : "default"}
5880
+ >
5881
+ <Table.CheckCell
5882
+ checked={selectedIds.has(row.id)}
5883
+ onValueChange={() => toggleRow(row.id)}
5884
+ aria-label={`Select ${row.subject}`}
5885
+ />
5886
+ <Table.Cell>
5887
+ <div className="flex items-center gap-2">
5888
+ <EnvelopeSimple size={16} />
5889
+ <span className="truncate">{row.subject}</span>
5890
+ {row.tags && (
5891
+ <div className="ml-2 inline-flex gap-1">
5522
5892
  {row.tags.map((tag) => (
5523
5893
  <Badge key={tag}>{tag}</Badge>
5524
5894
  ))}
5525
5895
  </div>
5526
- ) : (
5527
- "—"
5528
5896
  )}
5529
- </Table.Cell>
5530
- <Table.Cell sticky="right" className="text-right">
5531
- <DropdownMenu>
5532
- <DropdownMenu.Trigger
5533
- render={
5534
- <Button
5535
- variant="ghost"
5536
- size="sm"
5537
- shape="square"
5538
- aria-label="More options"
5539
- >
5540
- <DotsThree weight="bold" size={16} />
5541
- </Button>
5542
- }
5543
- />
5544
- <DropdownMenu.Content>
5545
- <DropdownMenu.Item icon={Eye}>View</DropdownMenu.Item>
5546
- <DropdownMenu.Item icon={PencilSimple}>
5547
- Edit
5548
- </DropdownMenu.Item>
5549
- <DropdownMenu.Separator />
5550
- <DropdownMenu.Item icon={Trash} variant="danger">
5551
- Delete
5552
- </DropdownMenu.Item>
5553
- </DropdownMenu.Content>
5554
- </DropdownMenu>
5555
- </Table.Cell>
5556
- </Table.Row>
5557
- ))}
5558
- </Table.Body>
5559
- </Table>
5560
- </LayerCard.Primary>
5897
+ </div>
5898
+ </Table.Cell>
5899
+ <Table.Cell>
5900
+ <span className="truncate">{row.from}</span>
5901
+ </Table.Cell>
5902
+ <Table.Cell>
5903
+ <span className="truncate">{row.date}</span>
5904
+ </Table.Cell>
5905
+ <Table.Cell className="text-right">
5906
+ <DropdownMenu>
5907
+ <DropdownMenu.Trigger
5908
+ render={
5909
+ <Button
5910
+ variant="ghost"
5911
+ size="sm"
5912
+ shape="square"
5913
+ aria-label="More options"
5914
+ >
5915
+ <DotsThree weight="bold" size={16} />
5916
+ </Button>
5917
+ }
5918
+ />
5919
+ <DropdownMenu.Content>
5920
+ <DropdownMenu.Item icon={Eye}>View</DropdownMenu.Item>
5921
+ <DropdownMenu.Item icon={PencilSimple}>
5922
+ Edit
5923
+ </DropdownMenu.Item>
5924
+ <DropdownMenu.Separator />
5925
+ <DropdownMenu.Item icon={Trash} variant="danger">
5926
+ Delete
5927
+ </DropdownMenu.Item>
5928
+ </DropdownMenu.Content>
5929
+ </DropdownMenu>
5930
+ </Table.Cell>
5931
+ </Table.Row>
5932
+ ))}
5933
+ </Table.Body>
5934
+ </Table>
5561
5935
  </LayerCard>
5562
5936
  ```
5563
5937
 
5938
+
5939
+ ---
5940
+
5941
+ ### TableOfContents
5942
+
5943
+ TableOfContents — presentational compound component for section navigation. Purely visual; all interaction logic (scroll tracking, active state management) is left to the consumer.
5944
+
5945
+ **Type:** component
5946
+
5947
+ **Import:** `import { TableOfContents } from "@cloudflare/kumo";`
5948
+
5949
+ **Category:** Other
5950
+
5951
+ **Props:**
5952
+
5953
+ - `children`: ReactNode
5954
+ - `className`: string
5955
+ - `id`: string
5956
+ - `lang`: string
5957
+ - `title`: string
5958
+
5959
+ **Colors (kumo tokens used):**
5960
+
5961
+ `bg-kumo-brand`, `bg-kumo-line`, `bg-kumo-tint`, `text-kumo-default`, `text-kumo-subtle`
5962
+
5963
+ **Sub-Components:**
5964
+
5965
+ This is a compound component. Use these sub-components:
5966
+
5967
+ #### TableOfContents.Title
5968
+
5969
+ Title sub-component
5970
+
5971
+ #### TableOfContents.List
5972
+
5973
+ List sub-component
5974
+
5975
+ #### TableOfContents.Item
5976
+
5977
+ Item sub-component
5978
+
5979
+ #### TableOfContents.Group
5980
+
5981
+ Group sub-component
5982
+
5983
+
5984
+ **Examples:**
5985
+
5564
5986
  ```tsx
5565
- <LayerCard>
5566
- <LayerCard.Primary className="w-full overflow-x-auto p-0">
5567
- <Table layout="fixed">
5568
- <colgroup>
5569
- <col />{" "}
5570
- {/* Checkbox column - width handled by Table.CheckHead/CheckCell */}
5571
- <col />
5572
- <col style={{ width: "150px" }} />
5573
- <col style={{ width: "120px" }} />
5574
- <col style={{ width: "50px" }} />
5575
- </colgroup>
5576
- <Table.Header>
5577
- <Table.Row>
5578
- <Table.CheckHead
5579
- checked={selectedIds.size === emailData.length}
5580
- indeterminate={
5581
- selectedIds.size > 0 && selectedIds.size < emailData.length
5582
- }
5583
- onValueChange={toggleAll}
5584
- aria-label="Select all rows"
5585
- />
5586
- <Table.Head>Subject</Table.Head>
5587
- <Table.Head>From</Table.Head>
5588
- <Table.Head>Date</Table.Head>
5589
- <Table.Head></Table.Head>
5590
- </Table.Row>
5591
- </Table.Header>
5592
- <Table.Body>
5593
- {emailData.map((row) => (
5594
- <Table.Row
5595
- key={row.id}
5596
- variant={selectedIds.has(row.id) ? "selected" : "default"}
5987
+ <DemoWrapper>
5988
+ <TableOfContents>
5989
+ <TableOfContents.Title>On this page</TableOfContents.Title>
5990
+ <TableOfContents.List>
5991
+ {headings.map((heading) => (
5992
+ <TableOfContents.Item
5993
+ key={heading.text}
5994
+ active={heading.text === "Usage"}
5995
+ className="cursor-pointer"
5996
+ >
5997
+ {heading.text}
5998
+ </TableOfContents.Item>
5999
+ ))}
6000
+ </TableOfContents.List>
6001
+ </TableOfContents>
6002
+ </DemoWrapper>
6003
+ ```
6004
+
6005
+ ```tsx
6006
+ <DemoWrapper>
6007
+ <TableOfContents>
6008
+ <TableOfContents.Title>On this page</TableOfContents.Title>
6009
+ <TableOfContents.List>
6010
+ {headings.map((heading) => (
6011
+ <TableOfContents.Item
6012
+ key={heading.text}
6013
+ active={heading.text === active}
6014
+ onClick={() => setActive(heading.text)}
6015
+ className="cursor-pointer"
6016
+ >
6017
+ {heading.text}
6018
+ </TableOfContents.Item>
6019
+ ))}
6020
+ </TableOfContents.List>
6021
+ </TableOfContents>
6022
+ </DemoWrapper>
6023
+ ```
6024
+
6025
+ ```tsx
6026
+ <DemoWrapper>
6027
+ <TableOfContents>
6028
+ <TableOfContents.Title>On this page</TableOfContents.Title>
6029
+ <TableOfContents.List>
6030
+ {headings.map((heading) => (
6031
+ <TableOfContents.Item key={heading.text} className="cursor-pointer">
6032
+ {heading.text}
6033
+ </TableOfContents.Item>
6034
+ ))}
6035
+ </TableOfContents.List>
6036
+ </TableOfContents>
6037
+ </DemoWrapper>
6038
+ ```
6039
+
6040
+ ```tsx
6041
+ <DemoWrapper>
6042
+ <TableOfContents>
6043
+ <TableOfContents.Title>On this page</TableOfContents.Title>
6044
+ <TableOfContents.List>
6045
+ <TableOfContents.Item active className="cursor-pointer">
6046
+ Overview
6047
+ </TableOfContents.Item>
6048
+ <TableOfContents.Group label="Getting Started">
6049
+ <TableOfContents.Item className="cursor-pointer">
6050
+ Installation
6051
+ </TableOfContents.Item>
6052
+ <TableOfContents.Item className="cursor-pointer">
6053
+ Configuration
6054
+ </TableOfContents.Item>
6055
+ </TableOfContents.Group>
6056
+ <TableOfContents.Group label="API">
6057
+ <TableOfContents.Item className="cursor-pointer">
6058
+ Props
6059
+ </TableOfContents.Item>
6060
+ <TableOfContents.Item className="cursor-pointer">
6061
+ Events
6062
+ </TableOfContents.Item>
6063
+ </TableOfContents.Group>
6064
+ </TableOfContents.List>
6065
+ </TableOfContents>
6066
+ </DemoWrapper>
6067
+ ```
6068
+
6069
+ ```tsx
6070
+ <DemoWrapper>
6071
+ <div className="space-y-3">
6072
+ <TableOfContents>
6073
+ <TableOfContents.List>
6074
+ {["Introduction", "Installation", "Usage"].map((text) => (
6075
+ <TableOfContents.Item
6076
+ key={text}
6077
+ render={<button type="button" />}
6078
+ onClick={() => setClicked(text)}
6079
+ active={text === "Introduction"}
5597
6080
  >
5598
- <Table.CheckCell
5599
- checked={selectedIds.has(row.id)}
5600
- onValueChange={() => toggleRow(row.id)}
5601
- aria-label={`Select ${row.subject}`}
5602
- />
5603
- <Table.Cell>
5604
- <div className="flex items-center gap-2">
5605
- <EnvelopeSimple size={16} />
5606
- <span className="truncate">{row.subject}</span>
5607
- {row.tags && (
5608
- <div className="ml-2 inline-flex gap-1">
5609
- {row.tags.map((tag) => (
5610
- <Badge key={tag}>{tag}</Badge>
5611
- ))}
5612
- </div>
5613
- )}
5614
- </div>
5615
- </Table.Cell>
5616
- <Table.Cell>
5617
- <span className="truncate">{row.from}</span>
5618
- </Table.Cell>
5619
- <Table.Cell>
5620
- <span className="truncate">{row.date}</span>
5621
- </Table.Cell>
5622
- <Table.Cell className="text-right">
5623
- <DropdownMenu>
5624
- <DropdownMenu.Trigger
5625
- render={
5626
- <Button
5627
- variant="ghost"
5628
- size="sm"
5629
- shape="square"
5630
- aria-label="More options"
5631
- >
5632
- <DotsThree weight="bold" size={16} />
5633
- </Button>
5634
- }
5635
- />
5636
- <DropdownMenu.Content>
5637
- <DropdownMenu.Item icon={Eye}>View</DropdownMenu.Item>
5638
- <DropdownMenu.Item icon={PencilSimple}>
5639
- Edit
5640
- </DropdownMenu.Item>
5641
- <DropdownMenu.Separator />
5642
- <DropdownMenu.Item icon={Trash} variant="danger">
5643
- Delete
5644
- </DropdownMenu.Item>
5645
- </DropdownMenu.Content>
5646
- </DropdownMenu>
5647
- </Table.Cell>
5648
- </Table.Row>
6081
+ {text}
6082
+ </TableOfContents.Item>
5649
6083
  ))}
5650
- </Table.Body>
5651
- </Table>
5652
- </LayerCard.Primary>
5653
- </LayerCard>
6084
+ </TableOfContents.List>
6085
+ </TableOfContents>
6086
+ {clicked && (
6087
+ <p className="text-xs text-kumo-subtle">Clicked: {clicked}</p>
6088
+ )}
6089
+ </div>
6090
+ </DemoWrapper>
5654
6091
  ```
5655
6092
 
5656
6093
 
@@ -5691,7 +6128,7 @@ Tab navigation component with segmented or underline style. Built on Base UI Tab
5691
6128
 
5692
6129
  **Colors (kumo tokens used):**
5693
6130
 
5694
- `bg-kumo-base`, `bg-kumo-brand`, `bg-kumo-recessed`, `bg-kumo-tint`, `border-kumo-ring`, `ring-kumo-line`, `ring-kumo-ring`, `text-kumo-default`, `text-kumo-strong`, `text-kumo-subtle`
6131
+ `bg-kumo-base`, `bg-kumo-brand`, `bg-kumo-recessed`, `bg-kumo-tint`, `border-kumo-hairline`, `ring-kumo-hairline`, `ring-kumo-line`, `text-kumo-default`, `text-kumo-strong`, `text-kumo-subtle`
5695
6132
 
5696
6133
  **Styling:**
5697
6134
 
@@ -5844,69 +6281,69 @@ Text component
5844
6281
 
5845
6282
  ```tsx
5846
6283
  <div className="grid w-full grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
5847
- <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
6284
+ <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
5848
6285
  <Text variant="heading1">Heading 1</Text>
5849
- <p className="font-mono text-xs text-kumo-subtle">text-3xl (30px)</p>
6286
+ <Text variant="mono-secondary">text-3xl (30px)</Text>
5850
6287
  </div>
5851
- <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
6288
+ <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
5852
6289
  <Text variant="heading2">Heading 2</Text>
5853
- <p className="font-mono text-xs text-kumo-subtle">text-2xl (24px)</p>
6290
+ <Text variant="mono-secondary">text-2xl (24px)</Text>
5854
6291
  </div>
5855
- <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
6292
+ <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
5856
6293
  <Text variant="heading3">Heading 3</Text>
5857
- <p className="font-mono text-xs text-kumo-subtle">text-lg (16px)</p>
6294
+ <Text variant="mono-secondary">text-lg (16px)</Text>
5858
6295
  </div>
5859
- <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
6296
+ <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
5860
6297
  <Text>Body</Text>
5861
- <p className="font-mono text-xs text-kumo-subtle">text-base (14px)</p>
6298
+ <Text variant="mono-secondary">text-base (14px)</Text>
5862
6299
  </div>
5863
- <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
6300
+ <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
5864
6301
  <Text bold>Body bold</Text>
5865
- <p className="font-mono text-xs text-kumo-subtle">text-base (14px)</p>
6302
+ <Text variant="mono-secondary">text-base (14px)</Text>
5866
6303
  </div>
5867
- <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
6304
+ <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
5868
6305
  <Text size="lg">Body lg</Text>
5869
- <p className="font-mono text-xs text-kumo-subtle">text-lg (16px)</p>
6306
+ <Text variant="mono-secondary">text-lg (16px)</Text>
5870
6307
  </div>
5871
- <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
6308
+ <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
5872
6309
  <Text size="sm">Body sm</Text>
5873
- <p className="font-mono text-xs text-kumo-subtle">text-sm (13px)</p>
6310
+ <Text variant="mono-secondary">text-sm (13px)</Text>
5874
6311
  </div>
5875
- <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
6312
+ <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
5876
6313
  <Text size="xs">Body xs</Text>
5877
- <p className="font-mono text-xs text-kumo-subtle">text-xs (12px)</p>
6314
+ <Text variant="mono-secondary">text-xs (12px)</Text>
5878
6315
  </div>
5879
- <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
6316
+ <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
5880
6317
  <Text variant="secondary">Body secondary</Text>
5881
- <p className="font-mono text-xs text-kumo-subtle">text-base (14px)</p>
6318
+ <Text variant="mono-secondary">text-base (14px)</Text>
5882
6319
  </div>
5883
- <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
6320
+ <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
5884
6321
  <Text variant="mono">Monospace</Text>
5885
- <p className="font-mono text-xs text-kumo-subtle">text-sm (13px)</p>
6322
+ <Text variant="mono-secondary">text-sm (13px)</Text>
5886
6323
  </div>
5887
- <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
6324
+ <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
5888
6325
  <Text variant="mono" size="lg">
5889
6326
  Monospace lg
5890
6327
  </Text>
5891
- <p className="font-mono text-xs text-kumo-subtle">text-base (14px)</p>
6328
+ <Text variant="mono-secondary">text-base (14px)</Text>
5892
6329
  </div>
5893
- <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
6330
+ <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
5894
6331
  <Text variant="mono-secondary">Monospace secondary</Text>
5895
- <p className="font-mono text-xs text-kumo-subtle">text-sm (13px)</p>
6332
+ <Text variant="mono-secondary">text-sm (13px)</Text>
5896
6333
  </div>
5897
- <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
6334
+ <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
5898
6335
  <Text variant="success">Success</Text>
5899
- <p className="font-mono text-xs text-kumo-subtle">text-base (14px)</p>
6336
+ <Text variant="mono-secondary">text-base (14px)</Text>
5900
6337
  </div>
5901
- <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
6338
+ <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
5902
6339
  <Text variant="error">Error</Text>
5903
- <p className="font-mono text-xs text-kumo-subtle">text-base (14px)</p>
6340
+ <Text variant="mono-secondary">text-base (14px)</Text>
5904
6341
  </div>
5905
6342
  </div>
5906
6343
  ```
5907
6344
 
5908
6345
  ```tsx
5909
- <div className="w-64 rounded-lg border border-kumo-line bg-kumo-base p-4">
6346
+ <div className="w-64 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
5910
6347
  <Text truncate>
5911
6348
  This is a long piece of text that will be truncated with an ellipsis
5912
6349
  when it overflows its container.
@@ -5942,7 +6379,7 @@ Toasty — toast notification provider and viewport. Renders a `Toast.Provider`
5942
6379
 
5943
6380
  **Colors (kumo tokens used):**
5944
6381
 
5945
- `bg-kumo-base`, `bg-kumo-contrast`, `bg-kumo-control`, `bg-kumo-danger-tint`, `bg-kumo-fill-hover`, `bg-kumo-info-tint`, `bg-kumo-success-tint`, `bg-kumo-warning-tint`, `border-kumo-fill`, `ring-kumo-danger`, `ring-kumo-info`, `ring-kumo-ring`, `ring-kumo-success`, `ring-kumo-warning`, `text-kumo-danger`, `text-kumo-default`, `text-kumo-info`, `text-kumo-strong`, `text-kumo-subtle`, `text-kumo-success`, `text-kumo-warning`
6382
+ `bg-kumo-base`, `bg-kumo-contrast`, `bg-kumo-control`, `bg-kumo-danger`, `bg-kumo-fill-hover`, `bg-kumo-info`, `bg-kumo-success`, `bg-kumo-warning`, `border-kumo-fill`, `ring-kumo-danger`, `ring-kumo-hairline`, `ring-kumo-info`, `ring-kumo-line`, `ring-kumo-success`, `ring-kumo-warning`, `text-kumo-danger`, `text-kumo-default`, `text-kumo-info`, `text-kumo-strong`, `text-kumo-subtle`, `text-kumo-success`, `text-kumo-warning`
5946
6383
 
5947
6384
  **Styling:**
5948
6385
 
@@ -5981,25 +6418,32 @@ Accessible popup that shows additional information on hover/focus. Wrap your app
5981
6418
 
5982
6419
  ```tsx
5983
6420
  <TooltipProvider>
5984
- <Tooltip content="Add new item" asChild>
5985
- <Button shape="square" icon={PlusIcon} aria-label="Add new item" />
5986
- </Tooltip>
6421
+ <Tooltip
6422
+ content="Add new item"
6423
+ render={
6424
+ <Button shape="square" icon={PlusIcon} aria-label="Add new item" />
6425
+ }
6426
+ />
5987
6427
  </TooltipProvider>
5988
6428
  ```
5989
6429
 
5990
6430
  ```tsx
5991
6431
  <TooltipProvider>
5992
6432
  <div className="flex gap-2">
5993
- <Tooltip content="Add" asChild>
5994
- <Button shape="square" icon={PlusIcon} aria-label="Add" />
5995
- </Tooltip>
5996
- <Tooltip content="Change language" asChild>
5997
- <Button
5998
- shape="square"
5999
- icon={TranslateIcon}
6000
- aria-label="Change language"
6001
- />
6002
- </Tooltip>
6433
+ <Tooltip
6434
+ content="Add"
6435
+ render={<Button shape="square" icon={PlusIcon} aria-label="Add" />}
6436
+ />
6437
+ <Tooltip
6438
+ content="Change language"
6439
+ render={
6440
+ <Button
6441
+ shape="square"
6442
+ icon={TranslateIcon}
6443
+ aria-label="Change language"
6444
+ />
6445
+ }
6446
+ />
6003
6447
  </div>
6004
6448
  </TooltipProvider>
6005
6449
  ```
@@ -6016,6 +6460,35 @@ Accessible popup that shows additional information on hover/focus. Wrap your app
6016
6460
  </TooltipProvider>
6017
6461
  ```
6018
6462
 
6463
+ ```tsx
6464
+ <TooltipProvider>
6465
+ <div className="flex gap-4">
6466
+ <Tooltip
6467
+ content="Opens after 1 second"
6468
+ delay={1000}
6469
+ render={<Button variant="secondary" />}
6470
+ >
6471
+ 1s open delay
6472
+ </Tooltip>
6473
+ <Tooltip
6474
+ content="Stays open 500ms after leaving"
6475
+ closeDelay={500}
6476
+ render={<Button variant="secondary" />}
6477
+ >
6478
+ 500ms close delay
6479
+ </Tooltip>
6480
+ <Tooltip
6481
+ content="Instant open, stays 1s"
6482
+ delay={0}
6483
+ closeDelay={1000}
6484
+ render={<Button variant="secondary" />}
6485
+ >
6486
+ Instant + 1s close
6487
+ </Tooltip>
6488
+ </div>
6489
+ </TooltipProvider>
6490
+ ```
6491
+
6019
6492
 
6020
6493
  ---
6021
6494
 
@@ -6047,7 +6520,7 @@ Multi-line textarea input with Input variants and InputArea-specific dimensions
6047
6520
  - **Feedback:** Banner, Loader, Toasty
6048
6521
  - **Action:** Button, ClipboardText
6049
6522
  - **Input:** Checkbox, Combobox, DateRangePicker, Field, Input, Radio, Select, Switch
6050
- - **Other:** CloudflareLogo, DatePicker, Label, Link, SensitiveInput, Sidebar, Table, DeleteResource
6523
+ - **Other:** CloudflareLogo, DatePicker, Label, Link, SensitiveInput, Sidebar, Table, TableOfContents, DeleteResource
6051
6524
  - **Navigation:** CommandPalette, MenuBar, Pagination, Tabs
6052
6525
  - **Overlay:** Dialog, DropdownMenu, Popover, Tooltip
6053
6526
  - **Layout:** Grid, Surface, PageHeader, ResourceListPage