@espressif/dashboard-ui-components 1.11.1 → 1.12.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 (532) hide show
  1. package/.claude/rules/dashboard-ui-consumption.md +176 -5
  2. package/.cursor/rules/dashboard-ui-consumption.mdc +163 -4
  3. package/CHANGELOG.md +1020 -0
  4. package/README.md +240 -7
  5. package/THIRD-PARTY-NOTICES.md +2 -1
  6. package/dist/alert.props-CcKo49Rb.d.ts +44 -0
  7. package/dist/animation/index.d.ts +3 -0
  8. package/dist/animation/index.js +3 -0
  9. package/dist/avatar.props-2q5BsX-R.d.ts +29 -0
  10. package/dist/button-BK-DIR_L.d.ts +21 -0
  11. package/dist/button-BxJ7s6sR.d.ts +76 -0
  12. package/dist/calendar.props-BtCzuWH1.d.ts +12 -0
  13. package/dist/carousel/index.d.ts +2 -0
  14. package/dist/carousel/index.js +2 -0
  15. package/dist/charts/index.d.ts +5 -0
  16. package/dist/charts/index.js +9 -0
  17. package/dist/common/app-logo/app-logo.js +1 -1
  18. package/dist/common/index.d.ts +9 -20
  19. package/dist/common/my-account-menu/my-account-menu.js +45 -13
  20. package/dist/common/profile-card/profile-card.js +3 -2
  21. package/dist/components/accordion/accordion.js +14 -5
  22. package/dist/components/accordion/index.d.ts +36 -0
  23. package/dist/components/accordion/index.js +2 -0
  24. package/dist/components/advanced-search-box/advanced-search-box.js +8 -2
  25. package/dist/components/advanced-search-box/index.d.ts +29 -0
  26. package/dist/components/advanced-search-box/index.js +2 -0
  27. package/dist/components/alert/alert.js +2 -1
  28. package/dist/components/alert/index.d.ts +12 -0
  29. package/dist/components/alert/index.js +2 -0
  30. package/dist/components/anchored-panel/anchored-panel.js +83 -0
  31. package/dist/components/anchored-panel/index.d.ts +31 -0
  32. package/dist/components/anchored-panel/index.js +2 -0
  33. package/dist/components/animated-containers/index.d.ts +13 -0
  34. package/dist/components/animated-containers/index.js +2 -0
  35. package/dist/components/async-multi-select/async-multi-select.js +48 -7
  36. package/dist/components/async-multi-select/index.d.ts +63 -0
  37. package/dist/components/async-multi-select/index.js +2 -0
  38. package/dist/components/avatar/avatar.js +11 -4
  39. package/dist/components/avatar/index.d.ts +8 -0
  40. package/dist/components/avatar/index.js +2 -0
  41. package/dist/components/avatar-group/avatar-group.js +35 -0
  42. package/dist/components/avatar-group/index.d.ts +31 -0
  43. package/dist/components/avatar-group/index.js +2 -0
  44. package/dist/components/badge/index.d.ts +14 -0
  45. package/dist/components/badge/index.js +2 -0
  46. package/dist/components/breadcrumb/index.d.ts +21 -0
  47. package/dist/components/breadcrumb/index.js +2 -0
  48. package/dist/components/bubble/bubble.js +18 -0
  49. package/dist/components/bubble/index.d.ts +19 -0
  50. package/dist/components/bubble/index.js +2 -0
  51. package/dist/components/button/button.js +87 -25
  52. package/dist/components/button/flash-button.js +9 -3
  53. package/dist/components/button/index.d.ts +56 -0
  54. package/dist/components/button/index.js +6 -0
  55. package/dist/components/button-group/index.d.ts +16 -0
  56. package/dist/components/button-group/index.js +2 -0
  57. package/dist/components/calendar/calendar.js +5 -5
  58. package/dist/components/calendar/index.d.ts +11 -0
  59. package/dist/components/calendar/index.js +2 -0
  60. package/dist/components/card/index.d.ts +11 -0
  61. package/dist/components/card/index.js +2 -0
  62. package/dist/components/card-rail/card-rail.js +50 -0
  63. package/dist/components/card-rail/index.d.ts +30 -0
  64. package/dist/components/card-rail/index.js +2 -0
  65. package/dist/components/cards/collapsible-card.js +5 -2
  66. package/dist/components/cards/index.d.ts +16200 -0
  67. package/dist/components/cards/index.js +8 -0
  68. package/dist/components/cards/section-card.js +133 -8
  69. package/dist/components/cards/simple-card.js +5 -2
  70. package/dist/components/carousel/carousel.js +137 -49
  71. package/dist/components/carousel/index.d.ts +130 -0
  72. package/dist/components/carousel/index.js +2 -0
  73. package/dist/components/category-card/category-card.js +111 -0
  74. package/dist/components/category-card/index.d.ts +55 -0
  75. package/dist/components/category-card/index.js +2 -0
  76. package/dist/components/chart/area-chart.js +95 -85
  77. package/dist/components/chart/bar-chart.js +123 -60
  78. package/dist/components/chart/chart.js +127 -3
  79. package/dist/components/chart/composed-chart.js +109 -98
  80. package/dist/components/chart/donut-chart.js +23 -5
  81. package/dist/components/chart/index.d.ts +732 -0
  82. package/dist/components/chart/index.js +9 -0
  83. package/dist/components/chart/line-chart.js +93 -83
  84. package/dist/components/chart/treemap-chart.js +71 -58
  85. package/dist/components/check-badge/check-badge.js +25 -0
  86. package/dist/components/check-badge/index.d.ts +13 -0
  87. package/dist/components/check-badge/index.js +2 -0
  88. package/dist/components/checkbox/index.d.ts +8 -0
  89. package/dist/components/checkbox/index.js +2 -0
  90. package/dist/components/choice-card/choice-card.js +99 -0
  91. package/dist/components/choice-card/index.d.ts +41 -0
  92. package/dist/components/choice-card/index.js +2 -0
  93. package/dist/components/circular-progress/circular-progress.js +5 -2
  94. package/dist/components/circular-progress/index.d.ts +23 -0
  95. package/dist/components/circular-progress/index.js +2 -0
  96. package/dist/components/code/index.d.ts +40 -0
  97. package/dist/components/code/index.js +2 -0
  98. package/dist/components/code-editor/code-editor.js +9 -3
  99. package/dist/components/code-editor/index.d.ts +82 -0
  100. package/dist/components/code-editor/index.js +2 -0
  101. package/dist/components/collapsible/index.d.ts +42 -0
  102. package/dist/components/collapsible/index.js +2 -0
  103. package/dist/components/column-panel/column-panel.js +38 -0
  104. package/dist/components/column-panel/index.d.ts +37 -0
  105. package/dist/components/column-panel/index.js +3 -0
  106. package/dist/components/column-panel/use-panel-flag.js +27 -0
  107. package/dist/components/combobox/index.d.ts +28 -0
  108. package/dist/components/combobox/index.js +2 -0
  109. package/dist/components/confirmation-dialog/confirmation-dialog.js +1 -1
  110. package/dist/components/confirmation-dialog/index.d.ts +40 -0
  111. package/dist/components/confirmation-dialog/index.js +3 -0
  112. package/dist/components/content-container/index.d.ts +16 -0
  113. package/dist/components/content-container/index.js +2 -0
  114. package/dist/components/copiable-text/index.d.ts +33 -0
  115. package/dist/components/copiable-text/index.js +2 -0
  116. package/dist/components/coverflow/_constants/coverflow-poses.js +23 -0
  117. package/dist/components/coverflow/_constants/coverflow-shapes.js +23 -0
  118. package/dist/components/coverflow/_hooks/use-coverflow.js +90 -0
  119. package/dist/components/coverflow/_utils/ring.js +24 -0
  120. package/dist/components/coverflow/coverflow.js +198 -0
  121. package/dist/components/coverflow/index.d.ts +105 -0
  122. package/dist/components/coverflow/index.js +2 -0
  123. package/dist/components/data-table/data-table.js +9 -2
  124. package/dist/components/data-table/index.d.ts +120 -0
  125. package/dist/components/data-table/index.js +3 -0
  126. package/dist/components/date-picker/date-picker.js +5 -2
  127. package/dist/components/date-picker/index.d.ts +50 -0
  128. package/dist/components/date-picker/index.js +2 -0
  129. package/dist/components/date-range-picker/date-range-picker.js +11 -2
  130. package/dist/components/date-range-picker/index.d.ts +100 -0
  131. package/dist/components/date-range-picker/index.js +3 -0
  132. package/dist/components/date-time-picker/date-time-picker.js +5 -2
  133. package/dist/components/date-time-picker/index.d.ts +79 -0
  134. package/dist/components/date-time-picker/index.js +2 -0
  135. package/dist/components/device-icon/index.d.ts +17 -0
  136. package/dist/components/device-icon/index.js +2 -0
  137. package/dist/components/dialog/index.d.ts +38 -0
  138. package/dist/components/dialog/index.js +2 -0
  139. package/dist/components/dropdown-menu/index.d.ts +57 -0
  140. package/dist/components/dropdown-menu/index.js +2 -0
  141. package/dist/components/dynamic-list/dynamic-list.js +4 -4
  142. package/dist/components/dynamic-list/index.d.ts +74 -0
  143. package/dist/components/dynamic-list/index.js +2 -0
  144. package/dist/components/error-display/index.d.ts +17 -0
  145. package/dist/components/error-display/index.js +3 -0
  146. package/dist/components/expandable-text/expandable-text-overlay.js +78 -0
  147. package/dist/components/expandable-text/expandable-text.js +73 -0
  148. package/dist/components/expandable-text/index.d.ts +39 -0
  149. package/dist/components/expandable-text/index.js +2 -0
  150. package/dist/components/expandable-text/use-clamped.js +23 -0
  151. package/dist/components/facet-filters/_hooks/use-filter-group.js +51 -0
  152. package/dist/components/facet-filters/active-filters.js +31 -0
  153. package/dist/components/facet-filters/filter-group.js +110 -0
  154. package/dist/components/facet-filters/filters-panel.js +59 -0
  155. package/dist/components/facet-filters/filters-pill.js +40 -0
  156. package/dist/components/facet-filters/index.d.ts +104 -0
  157. package/dist/components/facet-filters/index.js +6 -0
  158. package/dist/components/facet-filters/use-filters-collapsed.js +21 -0
  159. package/dist/components/feature-grid/feature-grid.js +115 -0
  160. package/dist/components/feature-grid/index.d.ts +53 -0
  161. package/dist/components/feature-grid/index.js +2 -0
  162. package/dist/components/file-input/file-input.js +9 -3
  163. package/dist/components/file-input/index.d.ts +78 -0
  164. package/dist/components/file-input/index.js +2 -0
  165. package/dist/components/file-upload/file-upload.js +10 -5
  166. package/dist/components/file-upload/index.d.ts +38 -0
  167. package/dist/components/file-upload/index.js +2 -0
  168. package/dist/components/filters-bar/filters-bar.js +5 -1
  169. package/dist/components/filters-bar/index.d.ts +26 -0
  170. package/dist/components/filters-bar/index.js +2 -0
  171. package/dist/components/flip-card/flip-card.js +147 -0
  172. package/dist/components/flip-card/index.d.ts +43 -0
  173. package/dist/components/flip-card/index.js +2 -0
  174. package/dist/components/floating-window/_hooks/use-drag-move.js +76 -0
  175. package/dist/components/floating-window/floating-window.js +97 -0
  176. package/dist/components/floating-window/index.d.ts +45 -0
  177. package/dist/components/floating-window/index.js +2 -0
  178. package/dist/components/form/index.d.ts +28 -0
  179. package/dist/components/form/index.js +2 -0
  180. package/dist/components/fullscreen-dialog/fullscreen-dialog.js +6 -2
  181. package/dist/components/fullscreen-dialog/index.d.ts +38 -0
  182. package/dist/components/fullscreen-dialog/index.js +2 -0
  183. package/dist/components/horizontal-stepper/horizontal-stepper.js +122 -0
  184. package/dist/components/horizontal-stepper/index.d.ts +70 -0
  185. package/dist/components/horizontal-stepper/index.js +2 -0
  186. package/dist/components/icon-avatar/index.d.ts +9 -0
  187. package/dist/components/icon-avatar/index.js +2 -0
  188. package/dist/components/icon-text-action-card/icon-text-action-card.js +9 -5
  189. package/dist/components/icon-text-action-card/index.d.ts +11 -0
  190. package/dist/components/icon-text-action-card/index.js +2 -0
  191. package/dist/components/identicon/identicon.js +33 -0
  192. package/dist/components/identicon/index.d.ts +26 -0
  193. package/dist/components/identicon/index.js +2 -0
  194. package/dist/components/illustration/index.d.ts +37 -0
  195. package/dist/components/illustration/index.js +3 -0
  196. package/dist/components/index.d.ts +177 -19529
  197. package/dist/components/index.js +61 -10
  198. package/dist/components/input/index.d.ts +15 -0
  199. package/dist/components/input/index.js +3 -0
  200. package/dist/components/input-group/index.d.ts +35 -0
  201. package/dist/components/input-group/index.js +2 -0
  202. package/dist/components/input-group/input-group.js +41 -0
  203. package/dist/components/input-otp/index.d.ts +63 -0
  204. package/dist/components/input-otp/index.js +2 -0
  205. package/dist/components/key-value-manager/index.d.ts +63 -0
  206. package/dist/components/key-value-manager/index.js +2 -0
  207. package/dist/components/key-value-manager/key-value-manager-table.js +7 -5
  208. package/dist/components/label/index.d.ts +8 -0
  209. package/dist/components/label/index.js +2 -0
  210. package/dist/components/link/index.d.ts +33 -0
  211. package/dist/components/link/index.js +2 -0
  212. package/dist/components/list/index.d.ts +9 -0
  213. package/dist/components/list/index.js +3 -0
  214. package/dist/components/list/list-item.utils.js +1 -1
  215. package/dist/components/list/list.js +3 -1
  216. package/dist/components/list-details/index.d.ts +51 -0
  217. package/dist/components/list-details/index.js +2 -0
  218. package/dist/components/list-details/list-details.js +5 -2
  219. package/dist/components/lottie-animation-container/index.d.ts +10 -0
  220. package/dist/components/lottie-animation-container/index.js +2 -0
  221. package/dist/components/lottie-animation-container/lottie-animation-container.js +22 -3
  222. package/dist/components/lottie-animations/index.d.ts +8 -0
  223. package/dist/components/lottie-animations/index.js +2 -0
  224. package/dist/components/markdown-content/index.d.ts +32 -0
  225. package/dist/components/markdown-content/index.js +2 -0
  226. package/dist/components/media-card/index.d.ts +125 -0
  227. package/dist/components/media-card/index.js +4 -0
  228. package/dist/components/media-card/media-card-image.js +59 -0
  229. package/dist/components/media-card/media-card-reveal.js +76 -0
  230. package/dist/components/media-card/media-card.classes.js +37 -0
  231. package/dist/components/media-card/media-card.js +91 -0
  232. package/dist/components/media-stage/index.d.ts +41 -0
  233. package/dist/components/media-stage/index.js +2 -0
  234. package/dist/components/media-stage/media-stage.js +48 -0
  235. package/dist/components/menu/index.d.ts +14 -0
  236. package/dist/components/menu/index.js +2 -0
  237. package/dist/components/message-scroller/_hooks/use-follow-bottom.js +85 -0
  238. package/dist/components/message-scroller/index.d.ts +29 -0
  239. package/dist/components/message-scroller/index.js +2 -0
  240. package/dist/components/message-scroller/message-scroller.js +65 -0
  241. package/dist/components/mini-bar-chart/index.d.ts +40 -0
  242. package/dist/components/mini-bar-chart/index.js +2 -0
  243. package/dist/components/mini-bar-chart/mini-bar-chart.js +93 -0
  244. package/dist/components/monospace-content/index.d.ts +43 -0
  245. package/dist/components/monospace-content/index.js +2 -0
  246. package/dist/components/monospace-content/monospace-content.js +1 -1
  247. package/dist/components/nav-bar/index.d.ts +148 -0
  248. package/dist/components/nav-bar/index.js +2 -0
  249. package/dist/components/nav-bar/nav-bar-details-panel.js +158 -44
  250. package/dist/components/nav-bar/nav-bar-mobile-menu.js +93 -27
  251. package/dist/components/nav-bar/nav-bar.js +256 -138
  252. package/dist/components/nav-bar/use-nav-bar-hover-details.js +80 -0
  253. package/dist/components/nav-bar/use-nav-bar-overflow.js +5 -5
  254. package/dist/components/notice-strip/index.d.ts +32 -0
  255. package/dist/components/notice-strip/index.js +2 -0
  256. package/dist/components/notice-strip/notice-strip.js +57 -0
  257. package/dist/components/option-card-group/index.d.ts +50 -0
  258. package/dist/components/option-card-group/index.js +2 -0
  259. package/dist/components/option-card-group/option-card-group.js +76 -0
  260. package/dist/components/overflow-badge-list/index.d.ts +63 -0
  261. package/dist/components/overflow-badge-list/index.js +2 -0
  262. package/dist/components/overflow-badge-list/overflow-badge-list.js +78 -19
  263. package/dist/components/page-banner/index.d.ts +33 -0
  264. package/dist/components/page-banner/index.js +2 -0
  265. package/dist/components/page-banner/page-banner.js +56 -0
  266. package/dist/components/page-container/index.d.ts +20 -0
  267. package/dist/components/page-container/index.js +3 -0
  268. package/dist/components/page-container/page-container.js +5 -5
  269. package/dist/components/pagination/index.d.ts +31 -0
  270. package/dist/components/pagination/index.js +3 -0
  271. package/dist/components/popover/index.d.ts +60 -0
  272. package/dist/components/popover/index.js +3 -0
  273. package/dist/components/preview-card/index.d.ts +24 -0
  274. package/dist/components/preview-card/index.js +2 -0
  275. package/dist/components/progress-bar/index.d.ts +32 -0
  276. package/dist/components/progress-bar/index.js +2 -0
  277. package/dist/components/progress-bar/progress-bar.js +22 -6
  278. package/dist/components/radio-group/index.d.ts +24 -0
  279. package/dist/components/radio-group/index.js +2 -0
  280. package/dist/components/rank-numeral/index.d.ts +30 -0
  281. package/dist/components/rank-numeral/index.js +2 -0
  282. package/dist/components/rank-numeral/rank-numeral.js +26 -0
  283. package/dist/components/reaction-button/index.d.ts +32 -0
  284. package/dist/components/reaction-button/index.js +2 -0
  285. package/dist/components/reaction-button/reaction-button.js +50 -0
  286. package/dist/components/readout/index.d.ts +31 -0
  287. package/dist/components/readout/index.js +2 -0
  288. package/dist/components/readout/readout.js +63 -0
  289. package/dist/components/requirement-list/index.d.ts +52 -0
  290. package/dist/components/requirement-list/index.js +2 -0
  291. package/dist/components/requirement-list/requirement-list.js +29 -8
  292. package/dist/components/resizable/index.d.ts +31 -0
  293. package/dist/components/resizable/index.js +4 -0
  294. package/dist/components/resizable/resizable-group.js +23 -0
  295. package/dist/components/resizable/resizable-panel.js +28 -0
  296. package/dist/components/resizable/resizable-separator.js +24 -0
  297. package/dist/components/reveal/index.d.ts +23 -0
  298. package/dist/components/reveal/index.js +2 -0
  299. package/dist/components/reveal/reveal.js +24 -0
  300. package/dist/components/scroll-area/index.d.ts +27 -0
  301. package/dist/components/scroll-area/index.js +2 -0
  302. package/dist/components/scrollable-sections/index.d.ts +58 -0
  303. package/dist/components/scrollable-sections/index.js +2 -0
  304. package/dist/components/scrollable-sections/scrollable-sections.js +11 -3
  305. package/dist/components/search-box/index.d.ts +32 -0
  306. package/dist/components/search-box/index.js +2 -0
  307. package/dist/components/search-box/search-box.js +18 -3
  308. package/dist/components/search-field-shell.js +1 -1
  309. package/dist/components/select/index.d.ts +44 -0
  310. package/dist/components/select/index.js +2 -0
  311. package/dist/components/selectable-card-list/checkbox-card-list.js +5 -3
  312. package/dist/components/selectable-card-list/index.d.ts +76 -0
  313. package/dist/components/selectable-card-list/index.js +2 -0
  314. package/dist/components/selectable-card-list/radio-card-list.js +12 -6
  315. package/dist/components/selectable-card-list/selectable-card-list-shared.js +24 -12
  316. package/dist/components/selectable-card-list/selectable-card-list.js +12 -3
  317. package/dist/components/separator/index.d.ts +24 -0
  318. package/dist/components/separator/index.js +2 -0
  319. package/dist/components/share-menu/index.d.ts +55 -0
  320. package/dist/components/share-menu/index.js +2 -0
  321. package/dist/components/share-menu/share-marks.js +31 -0
  322. package/dist/components/share-menu/share-menu.js +140 -0
  323. package/dist/components/share-menu/share-urls.js +15 -0
  324. package/dist/components/sheet/index.d.ts +41 -0
  325. package/dist/components/sheet/index.js +2 -0
  326. package/dist/components/showcase-card/index.d.ts +53 -0
  327. package/dist/components/showcase-card/index.js +2 -0
  328. package/dist/components/showcase-card/showcase-card.js +75 -0
  329. package/dist/components/sidebar/index.d.ts +109 -0
  330. package/dist/components/sidebar/index.js +4 -0
  331. package/dist/components/sidebar/sidebar.js +56 -40
  332. package/dist/components/simple-clickable-card/index.d.ts +11 -0
  333. package/dist/components/simple-clickable-card/index.js +2 -0
  334. package/dist/components/simple-clickable-card/simple-clickable-card-shared.js +2 -2
  335. package/dist/components/simple-clickable-card/simple-clickable-card.js +5 -2
  336. package/dist/components/simple-info-card/index.d.ts +25 -0
  337. package/dist/components/simple-info-card/index.js +2 -0
  338. package/dist/components/simple-info-card/simple-info-card.js +6 -3
  339. package/dist/components/simple-list/index.d.ts +63 -0
  340. package/dist/components/simple-list/index.js +2 -0
  341. package/dist/components/simple-list/simple-list.js +3 -1
  342. package/dist/components/simple-paginated-list/index.d.ts +20 -0
  343. package/dist/components/simple-paginated-list/index.js +2 -0
  344. package/dist/components/simplified-date/index.d.ts +18 -0
  345. package/dist/components/simplified-date/index.js +2 -0
  346. package/dist/components/skeleton/index.d.ts +5 -0
  347. package/dist/components/skeleton/index.js +2 -0
  348. package/dist/components/skeletons/index.d.ts +11 -0
  349. package/dist/components/skeletons/index.js +2 -0
  350. package/dist/components/sort-menu/index.d.ts +34 -0
  351. package/dist/components/sort-menu/index.js +2 -0
  352. package/dist/components/sort-menu/sort-menu.js +39 -0
  353. package/dist/components/spinner/index.d.ts +15 -0
  354. package/dist/components/spinner/index.js +2 -0
  355. package/dist/components/stat-card/index.d.ts +43 -0
  356. package/dist/components/stat-card/index.js +2 -0
  357. package/dist/components/stat-card/stat-card.js +31 -12
  358. package/dist/components/status-badge/index.d.ts +24 -0
  359. package/dist/components/status-badge/index.js +2 -0
  360. package/dist/components/status-badge/status-badge.js +3 -2
  361. package/dist/components/status-card-list/index.d.ts +24 -0
  362. package/dist/components/status-card-list/index.js +2 -0
  363. package/dist/components/status-card-list/status-card-list.js +8 -4
  364. package/dist/components/step-tabs/index.d.ts +94 -0
  365. package/dist/components/step-tabs/index.js +2 -0
  366. package/dist/components/step-tabs/step-tabs.js +202 -0
  367. package/dist/components/style-scope/index.d.ts +32 -0
  368. package/dist/components/style-scope/index.js +2 -0
  369. package/dist/components/style-scope/style-scope.js +49 -0
  370. package/dist/components/switch/index.d.ts +15 -0
  371. package/dist/components/switch/index.js +2 -0
  372. package/dist/components/table/index.d.ts +18 -0
  373. package/dist/components/table/index.js +2 -0
  374. package/dist/components/tabs/index.d.ts +103 -0
  375. package/dist/components/tabs/index.js +2 -0
  376. package/dist/components/tag/index.d.ts +31 -0
  377. package/dist/components/tag/index.js +2 -0
  378. package/dist/components/tag/tag.js +79 -28
  379. package/dist/components/tag-input/index.d.ts +36 -0
  380. package/dist/components/tag-input/index.js +2 -0
  381. package/dist/components/tag-input/tag-input.js +10 -4
  382. package/dist/components/text-effects/index.d.ts +53 -0
  383. package/dist/components/text-effects/index.js +6 -0
  384. package/dist/components/textarea/index.d.ts +16 -0
  385. package/dist/components/textarea/index.js +2 -0
  386. package/dist/components/thumbnail-strip/index.d.ts +42 -0
  387. package/dist/components/thumbnail-strip/index.js +2 -0
  388. package/dist/components/thumbnail-strip/thumbnail-strip.js +124 -0
  389. package/dist/components/thumbnail-strip/use-scroll-edges.js +41 -0
  390. package/dist/components/time-picker/index.d.ts +13 -0
  391. package/dist/components/time-picker/index.js +2 -0
  392. package/dist/components/timeline/index.d.ts +39 -0
  393. package/dist/components/timeline/index.js +2 -0
  394. package/dist/components/timeline/timeline.js +85 -0
  395. package/dist/components/toast/index.d.ts +56 -0
  396. package/dist/components/toast/index.js +2 -0
  397. package/dist/components/toast/toast.js +42 -32
  398. package/dist/components/togglable-items-list/index.d.ts +28 -0
  399. package/dist/components/togglable-items-list/index.js +2 -0
  400. package/dist/components/toggle-group/index.d.ts +35 -0
  401. package/dist/components/toggle-group/index.js +2 -0
  402. package/dist/components/toolbar/index.d.ts +58 -0
  403. package/dist/components/toolbar/index.js +3 -0
  404. package/dist/components/toolbar/toolbar-button.js +40 -0
  405. package/dist/components/toolbar/toolbar.js +56 -0
  406. package/dist/components/tooltip/index.d.ts +29 -0
  407. package/dist/components/tooltip/index.js +3 -0
  408. package/dist/components/tooltip/tooltip.js +12 -2
  409. package/dist/components/transfer-list/index.d.ts +36 -0
  410. package/dist/components/transfer-list/index.js +2 -0
  411. package/dist/components/transfer-list/transfer-list.js +1 -1
  412. package/dist/components/truncated-line-with-tooltip/index.d.ts +22 -0
  413. package/dist/components/truncated-line-with-tooltip/index.js +2 -0
  414. package/dist/components/truncated-line-with-tooltip/truncated-line-with-tooltip.js +26 -8
  415. package/dist/components/typography/index.d.ts +19 -0
  416. package/dist/components/typography/index.js +3 -0
  417. package/dist/components/use-mobile/index.d.ts +3 -0
  418. package/dist/components/use-mobile/index.js +2 -0
  419. package/dist/components/user-type-badge/index.d.ts +39 -0
  420. package/dist/components/user-type-badge/index.js +3 -0
  421. package/dist/components/user-type-badge/user-type-badge.js +2 -1
  422. package/dist/components/vertical-stepper/index.d.ts +7 -0
  423. package/dist/components/vertical-stepper/index.js +2 -0
  424. package/dist/components/vertical-stepper/vertical-stepper.js +33 -6
  425. package/dist/components/view-toggle/index.d.ts +38 -0
  426. package/dist/components/view-toggle/index.js +2 -0
  427. package/dist/components/view-toggle/view-toggle.js +56 -0
  428. package/dist/core/animate-ui/components/animate/code.js +83 -9
  429. package/dist/core/animate-ui/components/animate/tabs.js +234 -19
  430. package/dist/core/animate-ui/components/animate/tooltip.js +10 -2
  431. package/dist/core/animate-ui/components/base/preview-card.js +20 -3
  432. package/dist/core/animate-ui/components/buttons/copy.js +12 -6
  433. package/dist/core/animate-ui/components/radix/dialog.js +17 -3
  434. package/dist/core/animate-ui/components/radix/dropdown-menu.js +26 -9
  435. package/dist/core/animate-ui/components/radix/sheet.js +20 -4
  436. package/dist/core/animate-ui/components/radix/sidebar.js +9 -9
  437. package/dist/core/animate-ui/components/radix/toggle-group.js +103 -13
  438. package/dist/core/animate-ui/components/radix/toggle.js +5 -5
  439. package/dist/core/animate-ui/primitives/animate/code-block.js +31 -4
  440. package/dist/core/animate-ui/primitives/animate/shiki-highlighter.js +5 -2
  441. package/dist/core/animate-ui/primitives/animate/tabs.js +7 -4
  442. package/dist/core/animate-ui/primitives/animate/tooltip.js +10 -3
  443. package/dist/core/animate-ui/primitives/base/preview-card.js +2 -2
  444. package/dist/core/animate-ui/primitives/base/progress.js +1 -1
  445. package/dist/core/animate-ui/primitives/base/radio.js +3 -3
  446. package/dist/core/animate-ui/primitives/effects/highlight.js +1 -0
  447. package/dist/core/animate-ui/primitives/radix/accordion.js +1 -1
  448. package/dist/core/animate-ui/primitives/radix/dialog.js +6 -3
  449. package/dist/core/animate-ui/primitives/radix/dropdown-menu.js +2 -2
  450. package/dist/core/animate-ui/primitives/radix/sheet.js +7 -3
  451. package/dist/core/animate-ui/primitives/radix/switch.js +2 -2
  452. package/dist/core/animate-ui/primitives/radix/toggle-group.js +2 -2
  453. package/dist/core/badge.js +5 -2
  454. package/dist/core/breadcrumb.js +1 -1
  455. package/dist/core/button/button.js +8 -8
  456. package/dist/core/button/craft-button.js +8 -2
  457. package/dist/core/button.js +17 -7
  458. package/dist/core/card.js +23 -5
  459. package/dist/core/combobox/combobox.js +8 -2
  460. package/dist/core/command.js +3 -3
  461. package/dist/core/form.js +1 -1
  462. package/dist/core/hooks/use-nested-layer-press-guard.js +46 -0
  463. package/dist/core/hooks/use-on-screen.js +33 -0
  464. package/dist/core/hooks/use-prefers-reduced-motion.js +19 -0
  465. package/dist/core/hooks/use-scroll-overflow.js +20 -0
  466. package/dist/core/index.d.ts +30 -5
  467. package/dist/core/index.js +5 -2
  468. package/dist/core/input/input-password.js +13 -9
  469. package/dist/core/input/input.js +38 -12
  470. package/dist/core/input-otp/input-otp.js +9 -5
  471. package/dist/core/popover-group.js +48 -0
  472. package/dist/core/popover-hover.js +127 -0
  473. package/dist/core/popover.js +75 -6
  474. package/dist/core/select.js +50 -19
  475. package/dist/core/table.js +5 -3
  476. package/dist/core/textarea/textarea.js +11 -3
  477. package/dist/data-table/index.d.ts +4 -0
  478. package/dist/data-table/index.js +3 -0
  479. package/dist/date/index.d.ts +11 -0
  480. package/dist/date/index.js +7 -0
  481. package/dist/forms/index.d.ts +4 -0
  482. package/dist/forms/index.js +2 -0
  483. package/dist/icon-avatar.props-RYtw2eSW.d.ts +31 -0
  484. package/dist/icon-text-action-card.props-B2ggncUK.d.ts +53 -0
  485. package/dist/index.d.ts +169 -15
  486. package/dist/index.js +63 -10
  487. package/dist/input-CYI1hhGc.d.ts +38 -0
  488. package/dist/layouts/index.d.ts +132 -8
  489. package/dist/layouts/index.js +3 -1
  490. package/dist/layouts/minimal-workspace-layout/minimal-workspace-layout-context.js +5 -0
  491. package/dist/layouts/minimal-workspace-layout/minimal-workspace-layout.js +404 -0
  492. package/dist/layouts/minimal-workspace-layout/rail-logo.js +90 -0
  493. package/dist/layouts/minimal-workspace-layout/sidebar-trigger.js +42 -0
  494. package/dist/layouts/shared/account-menu-props.js +21 -0
  495. package/dist/layouts/shared/footer-branding.js +34 -0
  496. package/dist/layouts/shared/sidebar-logo.js +59 -0
  497. package/dist/layouts/workspace-layout/account-menu/account-menu.js +9 -3
  498. package/dist/layouts/workspace-layout/footer/footer.js +1 -1
  499. package/dist/layouts/workspace-layout/header/header.js +1 -1
  500. package/dist/layouts/workspace-layout/workspace-layout.js +28 -80
  501. package/dist/{list.props-x1j3CbcF.d.ts → list.props-DP_xPTqU.d.ts} +2 -1
  502. package/dist/markdown/index.d.ts +11 -0
  503. package/dist/markdown/index.js +5 -0
  504. package/dist/my-account-menu.props-C7DK71WC.d.ts +67 -0
  505. package/dist/page-container.props-JutTvKFq.d.ts +48 -0
  506. package/dist/resizable.props-RxFY5tm_.d.ts +44 -0
  507. package/dist/section-card-B7c5uc08.d.ts +84 -0
  508. package/dist/simple-clickable-card.props-BrPCw7CR.d.ts +51 -0
  509. package/dist/slot-DGErA9zi.d.ts +10 -0
  510. package/dist/status-badge.props-lKlEOfRt.d.ts +32 -0
  511. package/dist/style-axes-DSQ2DGc5.d.ts +133 -0
  512. package/dist/toast/index.d.ts +6 -0
  513. package/dist/toast/index.js +2 -0
  514. package/dist/tooltip-C0bYa8a3.d.ts +37 -0
  515. package/dist/{types-DtUxK-Am.d.ts → types-CkXflqg7.d.ts} +31 -1
  516. package/dist/utils/cn.js +6 -1
  517. package/dist/utils/color.js +35 -10
  518. package/dist/utils/index.d.ts +18 -2
  519. package/dist/utils/index.js +4 -1
  520. package/dist/utils/silver-shine.js +16 -1
  521. package/dist/utils/style-axes.js +227 -0
  522. package/dist/utils/variant.js +104 -8
  523. package/dist/utils/view-transition.js +21 -0
  524. package/dist/variant-D81RhpbR.d.ts +104 -0
  525. package/dist/vertical-stepper.props-BXYcbW70.d.ts +29 -0
  526. package/package.json +52 -6
  527. package/src/styles/colors.css +100 -4
  528. package/src/styles/globals.css +8 -131
  529. package/src/styles/style-axes.css +21 -0
  530. package/src/styles/theme.css +696 -0
  531. package/dist/app-logo.props-Ct7QBdTd.d.ts +0 -40
  532. package/dist/popover-ByLD3-Qv.d.ts +0 -204
package/CHANGELOG.md CHANGED
@@ -4,6 +4,1026 @@ All notable changes to this project are documented here. The format is based on
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres
5
5
  to [Semantic Versioning](https://semver.org/).
6
6
 
7
+ ## [1.12.0] - 2026-11-13
8
+
9
+ Everything in this release is additive except the visual changes under
10
+ **Changed** (outline and glow buttons are see-through; `ExpandableText`'s link
11
+ takes its text's size; a selected tab's label is held readable): an app that changes nothing gets the same exports and
12
+ the same compiled stylesheet (apart from inert additions listed below).
13
+
14
+ ### Fixed
15
+ - **A link can be an `openOnHover` popover's trigger.** A click on a trigger
16
+ whose popover a hover had opened was cancelled (`preventDefault`) to keep the
17
+ popover open, so a link trigger (`PopoverTrigger asChild` around an `<a>` or
18
+ a router link) did not navigate. The click now goes through, and the close
19
+ it would cause is ignored instead; the popover still stays open.
20
+ - **A `Carousel`'s side arrows take the `labels` they are given.** With
21
+ `navigation="arrows"` and the default placement, `labels.previous` and
22
+ `labels.next` were ignored and the arrows always said "Previous slide" and
23
+ "Next slide"; only the overlay arrows read them. Without labels they still
24
+ say the English default.
25
+ - **On mobile, the `Sidebar` closes after any tap on a nav row** or its
26
+ `endAction` (+) button. It used to close only when the tap landed on the
27
+ row's icon or label text; elsewhere in the row the link navigated but the
28
+ sidebar stayed open over the new page. Keyboard Enter on a focused link now
29
+ closes it too. Toggling a group header still leaves it open.
30
+ - **A toast sits on an opaque surface, whatever its variant.** The soft
31
+ (default), outline, glow and gradient variants paint little or no background
32
+ of their own, so the page showed through a toast and its text was hard to
33
+ read. The toast is now the popover surface with the variant's tint, border
34
+ and text on it; solid toasts look as before.
35
+ - **A tooltip whose words change says the new ones.** A toggle's tooltip
36
+ (`Button` `tooltip` "Maximize panel" → "Restore panel") kept saying its first
37
+ words: the tooltip passes its props on only when they differ, and leaves its
38
+ content out of that comparison because the content is a new element on every
39
+ render. Text content now rides as a compared prop of its own, so changed words
40
+ reach the tooltip; element content behaves as before.
41
+ - **`KeyValueManager` no longer nests a `<tr>` inside a `<tr>`.** Its desktop
42
+ table wrapped each page of rows in an animated row, which made React log
43
+ "In HTML, `<tr>` cannot be a child of `<tr>`" and risked hydration errors.
44
+ The page slide now animates the table body, so each row is a single `<tr>`.
45
+ The slide, which had no visible effect on the table before, now plays when
46
+ paging; it does not play on first render. No API changes.
47
+ - **A hover popover no longer opens after the pointer has left.** With
48
+ `openOnHover`, leaving the trigger before `openDelay` ran out still opened
49
+ it; the pending open is now cancelled.
50
+ - **A hover hand-over in a `PopoverGroup` keeps the new popover open.** The
51
+ popover being replaced returned focus to its own trigger as it closed; that
52
+ focus landed outside the new panel and closed it as well, leaving nothing
53
+ open. A close caused by a hover never moves focus now. Likewise a click
54
+ from one popover's trigger to another's opens the second: the first one's
55
+ own close no longer closes whichever popover is open, and a popover the
56
+ group closes because another took its place never sends focus back to its
57
+ trigger (that focus closed the new one).
58
+
59
+ ### Changed
60
+ - **A selected tab's label is held readable.** In the pill variants it sat
61
+ on a 10% tint of its own colour, which took the default blue to 4:1 on a
62
+ light page, under the 4.5:1 small text needs. The label keeps its hue and
63
+ chroma but its lightness is capped at L 40 on a light page and floored at
64
+ L 62 on a dark one (relative colour syntax; older browsers keep the colour
65
+ as given). The default blue becomes a slightly deeper blue (5:1), and so
66
+ does `line`'s; colours already in range, and `solid`, are unchanged.
67
+ - **`ExpandableText`'s "Show more" link takes its text's size.** It had a fixed
68
+ `text-sm`, so under smaller text (`className="text-xs"`) the link outweighed
69
+ what it expands. It now sets no size of its own: under `text-sm` text, the
70
+ common case, it looks exactly as before. Weight and colour are unchanged.
71
+ - **Outline and glow buttons are see-through.** The base `outline` and `glow`
72
+ variants (`/core`'s `buttonVariants`, so the styled `Button`, `CopyButton`,
73
+ `Pagination`, `DateRangePicker`… too) fill with `bg-transparent` instead of
74
+ `bg-background`. On the page background nothing changes; on a card, a band
75
+ or a tinted panel the button now shows that surface instead of a
76
+ page-coloured patch. A button drawn over a picture gives itself a surface,
77
+ as `Carousel`'s overlay arrows (`bg-card`) and `Coverflow`'s (`bg-background`)
78
+ already do — pass the same class to keep the old look anywhere it matters.
79
+
80
+ ### Added
81
+ - **`Toolbar` and `ToolbarButton`** — a 44px bar of small controls across
82
+ the top of a work area, with `start`, `center` and `end` slots: the two
83
+ sides share the width, so the centre stays centred on the bar whatever the
84
+ sides hold. Left/Right arrows move between its controls and Home/End jump
85
+ to the ends, as the `toolbar` role promises; `tone="dark"` keeps it dark in
86
+ either theme. `ToolbarButton` is its 28px icon-only button: the `label` is
87
+ the accessible name and the tooltip, `pressed` makes it a toggle, and a
88
+ `count` or an `attention` dot can sit over the icon. Quiet (ghost) unless
89
+ `color="primary"`.
90
+ - **`AnchoredPanel`** — a small non-modal panel attached to a point by a
91
+ short leader line (`anchorRef`, opening on `side` left or right), for
92
+ editing the thing it sits beside rather than in a far corner. A plain
93
+ `title`, an optional monospace `subtitle` and `badge` in its header, ✕ to
94
+ close. Focus moves into it on opening; Escape, ✕ or a press outside closes
95
+ it, except a press `keepOpenFor` accepts (the control that toggles it).
96
+ - **`FloatingWindow`** — a small window floating over the page, moved by its
97
+ bar: a non-modal dialog, so the page behind it stays live. The bar carries
98
+ Minimize (folds it to a pill in the bottom-left corner; `attention` puts a
99
+ dot on the pill and says why), Dock (also Escape) and Close. The page keeps
100
+ the `position`; the window hands back the new spot, kept inside the
101
+ viewport, once a drag ends. Wrap `onMinimize` / `onRestore` in
102
+ `startViewTransition` and the window morphs into its pill and back.
103
+ - **`NoticeStrip`** — one line of news across the top of a canvas, the full
104
+ width of its container, in the glow of its `tone` (`info`, `warning`,
105
+ `error`) on an opaque base, with its words and `actions` centred and an
106
+ optional ✕ at the far end (`onDismiss`, `dismissLabel`). An error is an
107
+ `alert`, anything else a `status`. Built on `Alert`.
108
+ - **`Readout`** — an instrument's display: values in monospace on a dark
109
+ plate, each with its unit in a dimmer ink (`segments`), the same in both
110
+ themes. `state` marks it `selected`, `error` (the values turn red) or
111
+ `stale`; `labelled` draws each value's label before it. With `onClick` it
112
+ is a toggle button, pressed while `selected`.
113
+ - **`ChoiceCard`** — a card you click to choose something (a board, a
114
+ framework), where a media card is one you click to open. The whole card is
115
+ one toggle button: its picture edge to edge on a mist that clears into the
116
+ card, the title and meta lines under it, a ring and a tick when `selected`,
117
+ greyed with its reason as the `note` when `disabled`. `layout="row"` puts
118
+ a small picture on the left, for a list of several chosen at once.
119
+ - **`ShowcaseCard`** — a catalogue card on `MediaCard`: a picture with an
120
+ actions strip that slides up over it (`reveal`), the name, a meta row and
121
+ a footer row. The title opens what `open` says: a page (`href`), a page of
122
+ the app through the router's own link (`link`), or an action (`onOpen` with
123
+ a `label`); without it the title is plain text. Cards glide to their new
124
+ places in a view transition.
125
+ - **`SortMenu`** — a one-of picker: the current choice as an outline button's
126
+ label (named "Sort makers: Newest"), the choices as radio items in a menu.
127
+ A sort by default; with another `icon`, any filter of the same shape.
128
+ `iconOnlyBelow` shrinks it to its icons on a narrow row; `align` picks the
129
+ edge the menu lines up with.
130
+ - **Facet filters: `FiltersPanel`, `FilterGroup`, `FiltersPill` and
131
+ `ActiveFilters`**, a filters side panel for a catalogue page, props only:
132
+ the page hands in its groups already counted and labelled
133
+ (`FacetFilterGroup`), what is ticked (`FacetSelection`) and every string
134
+ (`FacetFiltersLabels`). Each group shows three options, five more per
135
+ "Show more", every ticked option always, and has a search of its own. The
136
+ panel folds into a floating `FiltersPill` and back — one view-transition
137
+ name, so the panel morphs into the pill — with `useFiltersCollapsed`
138
+ holding the state and `supportsViewTransitions` telling the page when to
139
+ play the CSS entrance instead. `ActiveFilters` lists what narrows the
140
+ results, each removable, and "Clear all".
141
+ - **`InputGroup`, `InputGroupTextarea` and `InputGroupAddon`** — a field and
142
+ the controls that belong to it in one bordered box that takes the focus
143
+ ring when anything inside has focus (shadcn's Input Group on the library's
144
+ tokens). `elevation` is `raised` (default), `float` (a halo on every side,
145
+ for a box floating at the bottom of a window) or `flat`. The text area is
146
+ borderless and grows with its content (`field-sizing: content`) between
147
+ its min and max height; the addon is a row of controls under it.
148
+ - **`Bubble`** — one turn's text in a conversation: `variant="filled"` puts
149
+ the person's own words in a soft tinted box, `plain` (default) leaves the
150
+ other side as text on the page. `size="sm"` for a conversation in a column
151
+ beside other things.
152
+ - **`Reveal`** — one part of a section's entrance: it rises into place and
153
+ fades in when `revealed` turns true, a beat later per `order` (0–3), with
154
+ `grow` settling from slightly small. Under reduced motion it is simply
155
+ there.
156
+ - **`CheckBadge`** — a small filled success circle with a tick, drawn inside
157
+ an `<svg>` at `cx`, `cy` with radius `r` in scene units.
158
+ - **`MessageScroller`** — a conversation's scrolling area: it follows new
159
+ messages while the reader is at the end, stops when they scroll up to
160
+ read, and offers a round "jump to latest" button (`jumpLabel`) until they
161
+ are back. A `log` for assistive technology, so new messages are announced
162
+ politely; `paused` holds it still; the jump is instant under reduced
163
+ motion. Scrolls in `ScrollArea`, its thumb shown only while the pointer is
164
+ over the thread.
165
+ - **Resizable panels: `ResizableGroup`, `ResizablePanel` and
166
+ `ResizableSeparator`**, a row or column of panels the person resizes by
167
+ dragging, or with the keyboard, the separators between them. The group
168
+ takes a remembered `defaultLayout` and reports `onLayoutChanged` once a
169
+ change settles; a panel can be `collapsible` and is driven from outside
170
+ through `panelRef` (`ResizablePanelHandle`); the separator is a hairline
171
+ lit in the primary colour while pointed at, held or focused. **New
172
+ dependency:** `react-resizable-panels` (^4.14.1, MIT), reached only by
173
+ these components and `ColumnPanel`.
174
+ - **`ColumnPanel` and `usePanelFlag`** — a `ResizablePanel` that is shown and
175
+ hidden by an `open` flag (a chat, a details column), collapsing to nothing
176
+ and reopening at `openSize`; `size` moves it from a button (a maximize).
177
+ Hidden, it stays mounted but leaves the accessibility tree and the tab
178
+ order. `usePanelFlag` is the hook behind it, for any collapsible panel; it
179
+ waits instead of throwing when asked before the group has measured the
180
+ panel.
181
+ - **`Coverflow` says what opening the front card does.** `openCursor`:
182
+ `zoom-in` (the default, as before) for a picture opened larger, `pointer`
183
+ for a card that leads somewhere, such as a project's own page — the zoom
184
+ cursor there promised a bigger picture and got a page.
185
+ - **`Accordion` can be controlled.** `value` (the open item's id, `''` for
186
+ none; the open ids with `allowMultiple`) with `onValueChange` lets the page
187
+ keep the state — for an accordion that is also opened and closed from
188
+ elsewhere, such as a parts list whose row opens when the part is clicked on a
189
+ drawing. Without `value` it keeps its own state from `defaultValue`, as
190
+ before. `itemClassName` goes on every item, so `data-[state=open]:…` can
191
+ style the open row.
192
+ - **`FeatureGrid`** — what something does, as a numbered grid: a short title
193
+ per item and an optional sentence under it, two columns where there is room
194
+ (`columns` 1–3, by the grid's own width), each item drawing its own
195
+ dividers so an odd count leaves an empty cell rather than a grey block. A
196
+ long list shows its first `pageSize` items (default 6); the button under it
197
+ shows the rest at once (`reveal="all"`, "Show all 15") or the next page at a
198
+ time (`reveal="page"`, "Show 6 more"), moves focus to the first item it adds,
199
+ and folds back ("Show fewer") once everything shows. `numbered={false}` drops
200
+ the numbers; `titleAs` picks the title element; labels are props.
201
+ - **`navigationPlacement="beside"` on `Carousel`**: the side arrows sit in
202
+ gutters of their own to the left and right of the slides, and the slides are
203
+ kept clear of them — for a row of cards or chips, where the default arrows
204
+ (drawn over the slides' edges) cover the first and last card. Dots and custom
205
+ controls still go below. `'below'` and `'overlay'` are unchanged.
206
+ - **`scrollable` on `FullscreenDialog`** (default `true`, as before). With
207
+ `false` the body is exactly the height left under the heading and does not
208
+ scroll, so its content can fill it (`h-full`): a picture shown whole, a
209
+ canvas, a player. Inside the scroll area a picture had no height to fit to
210
+ and ran past the screen.
211
+ - **`ToggleGroup variant="solid"`**: the selected item is a pill filled with
212
+ the group's `color`, its text in that colour's `-foreground` (black or white
213
+ by lightness for any other CSS colour), on a quiet hairline frame — the same
214
+ recipe as `TabsList variant="solid"`, so the two sit together. A pressed
215
+ item of a `multiple` group is filled itself. Mist's fill is nearly the
216
+ surface it sits on, so a solid mist pill keeps its `mist-border` hairline.
217
+ The other variants are unchanged. (`contrastingForeground`, the text-on-any-
218
+ fill rule `TabsList` already used, moved into the shared colour utility so
219
+ both read one copy.)
220
+ - **`MediaStage`** — a fixed-proportion frame (4:3 by default, 16:9 or 1:1)
221
+ for one picture: a product photo, a video poster, a wiring diagram. Its
222
+ height comes from its width alone, so a gallery never jumps between pictures
223
+ of different shapes and a column beside it never stretches it. A photo is
224
+ shown whole over a blurred, darkened copy of itself (the copy is hidden from
225
+ assistive technology); `variant="diagram"` puts the picture on the dotted
226
+ canvas surface instead. Arrows, captions or a video player go in as
227
+ `children`, drawn on top.
228
+ - **`ThumbnailStrip`** — the row of thumbnails under a gallery: one button per
229
+ picture, the one on show pressed and scrolled into view within the row
230
+ (never the page). When the row runs past an edge, that side shows an arrow
231
+ over a fade into the strip's surface; a hidden arrow is out of the tab order.
232
+ `size="sm"` for a phone; labels are props, English by default.
233
+ - **`HorizontalStepper` steps can carry a `description`**, and the stepper takes
234
+ `align="start"` (nodes and text on the left of each column, the line running
235
+ out to the right) and `semantics="list"` (read as an ordered list with the
236
+ `in_progress` step marked `aria-current="step"`, for when the steps are the
237
+ instructions rather than a status picture). Defaults draw and read exactly
238
+ as before.
239
+ - **`lines` on `TruncatedLineWithTooltip`** (1–6, default 1): past one line
240
+ the text is clamped to that many lines (a card's description) and measured
241
+ by its height, so the whole text is offered on hover only when the lines
242
+ cut it. One line behaves as before.
243
+ - **`ViewToggle`** switches a collection between cards in a grid and rows
244
+ in a list: two icon toggles on a `ToggleGroup`, the current one pressed, and
245
+ one always on (pressing it again does nothing). Labels are props, English by
246
+ default (`Layout`, `Grid view`, `List view`).
247
+ - **`gapped` on a segmented `ProgressBar`.** Each segment is drawn as its own
248
+ rounded piece with a small gap between them, on no track, instead of one bar
249
+ cut into colours (default `false`, so nothing changes unless it is set).
250
+ - **`avatarColor` on the account menus.** `MyAccountMenu`, the `ProfileCard`
251
+ it shows, and the layouts' `headerConfig` take the avatar's fill behind the
252
+ initial (default `primary`, so nothing changes unless it is set).
253
+ - **`OptionCardGroup`: a choice between a few compact cards.** For a choice
254
+ that needs an icon and a sentence per option (how much to share, which plan,
255
+ which way to start): cards side by side, wrapping one under the other on a
256
+ narrow screen, each with an optional `media` icon on a small tile beside its
257
+ `title` (also the radio's name), a `description` and `tags` drawn as small
258
+ `StatusBadge`s. A native radio group, so the arrow keys move the choice; the
259
+ chosen card carries a primary ring, and a tag marked `emphasis` ("+ Source",
260
+ what this choice adds) turns primary only while its card is chosen.
261
+ - **`FileUpload` `layout="row"`.** The icon, the lines and the browse control
262
+ on one compact line, for a drop zone inside a form or a card where the tall,
263
+ centred `stacked` default (unchanged) would dominate.
264
+ - **`Code` numbers, marks and links lines.** `lineNumbers` puts a gutter
265
+ beside the code (a CSS counter, so the numbers are never selected or
266
+ copied); `highlightLines` tints whole lines (a search hit, a linked line);
267
+ `lineIdPrefix` gives each line an `id` (`L` → `#L42`) a page can scroll to
268
+ or link. `maxHighlightLength` (default `200000` characters) shows a very
269
+ large file as plain text, keeping its numbers, marks and ids. Lines are now
270
+ full-width blocks, so a mark spans the row. Additive: without the new props
271
+ nothing changes but the line boxes' width.
272
+ - **`Code` shows something beside a line.** `lineMarks` (`{ [line]: node }`)
273
+ draws a small node at a line's left edge, in the padding before the numbers,
274
+ scrolling with the line: a pin a line drives, a breakpoint, a finding. It may
275
+ be interactive (an icon button with a tooltip) and comes after the code in
276
+ the reading order, never in the code's text. The code now scrolls in a
277
+ wrapper (`data-slot="code-scroll"`) that holds the code and its marks; it
278
+ looks the same.
279
+ - **`cmake` and `ini` in the curated Shiki bundle** (`properties` is an alias
280
+ of `ini`), for `CMakeLists.txt` and `KEY=value` files such as ESP-IDF's
281
+ `sdkconfig.defaults`.
282
+ - **`bg-recessed` and `shadow-recessed`,** the floor and walls of something
283
+ sunk into the surface around it (StepTabs' tray): `--color-recessed` (a
284
+ translucent darkening, deeper in dark mode, where a lighter veil reads as
285
+ raised) and `--shadow-recessed` (an inner shadow under the top edge, a
286
+ softer one inside it, a faint rim, and a light lip along the bottom edge),
287
+ whose per-theme value is `--espd-shadow-recessed`.
288
+ - **`bg-canvas`, `canvas-dot` and `canvas-rim`,** a work surface things are
289
+ placed on and dragged around (a wiring diagram, a whiteboard): `--color-canvas`
290
+ a step off the page (lifted in dark mode, never near-black, because much
291
+ hardware artwork is dark grey), `--color-canvas-dot` for its grid, and
292
+ `--color-canvas-rim` to outline artwork drawn in its own colours (light in
293
+ dark mode, dark in light mode).
294
+ - **Wire colours: `wire-power`, `wire-ground` and `wire-1` … `wire-8`,** for
295
+ connections drawn on the canvas (a wiring diagram). Each is at least 3:1
296
+ against the canvas in its own theme (darker in light mode, lighter in dark),
297
+ which the chart palette is not: it does not change with the theme, and two
298
+ of its colours fall to 2.5:1 on a dark canvas.
299
+ - **`TabsList` `size`, `color` and a `solid` variant.** `size="sm"` is a 28px
300
+ strip (24px triggers, small text) for a toolbar; `size="lg"` has 36px
301
+ triggers, base text and 20px icons. `color` (default `primary`, any preset
302
+ or CSS colour) tints every variant from one `--espd-tabs-color` variable:
303
+ the pill's wash, the list's border, the glow's halo, the underline and the
304
+ selected label. `variant="solid"` fills the selected tab in that colour,
305
+ its text in the preset's `-foreground` token or, for any other colour,
306
+ black or white by the fill's lightness. A list that sets none of them looks
307
+ as before.
308
+ - **`StepTabs`**: a one-row strip of a product's steps that is both navigation
309
+ and progress. Each step is a tab the person can go to, and carries its
310
+ `status` (the steppers' four, `stale` included) as a mark before its word:
311
+ a check when done, a dot in progress that throbs with a soft halo
312
+ (`animate-throb` and `animate-throb-ring`, new tokens; still under reduced
313
+ motion), a warning triangle when out of date,
314
+ nothing when not started (the word alone, centred). The status is read after
315
+ the word ("Firmware, Done"; `statusLabels` translates it) and is never
316
+ filled in from the order. Controlled (`value` / `onValueChange`, called for
317
+ the step on show too) and without panels, so the caller routes. One tab
318
+ stop; ←/→ (wrapping), Home and End move focus, Enter or Space chooses; a
319
+ `disabled` step is reached but not chosen. A step's `description` (text or
320
+ non-interactive React content: why it is out of date, when it was built,
321
+ why it cannot be chosen yet) shows in a tooltip on hover and keyboard
322
+ focus and is read as the tab's description; nothing focusable goes in it. `variant` `rounded` (a tinted
323
+ pill edged with a hairline a shade stronger than its wash, no outline round
324
+ the group; `tray` sits the steps in a capsule recessed into the bar — a
325
+ translucent floor with inner shadows for walls and a light lip below, no
326
+ line of its own — so they read as one control and the pill keeps its hue
327
+ on it) or `line` (an underline; `rule` draws the
328
+ strip's own bottom border), `size` `sm` (a 28px toolbar), `default` or
329
+ `lg` (40px steps, base text), and `color`
330
+ tints the pill, the word on show and the marks; the marks, the out-of-date
331
+ triangle included, are held at 3:1 against the page the same way the label
332
+ is. Built on `Tabs`, whose API is unchanged.
333
+ - **A `failed` step status** (`VerticalStepperStepStatus`, so `VerticalStepper`,
334
+ `HorizontalStepper` and `StepTabs` alike): a step that ran and did not
335
+ succeed — a check that found a problem, a build that broke. It counts as
336
+ reached, like `stale`, and is drawn in `error` the way `stale` is drawn in
337
+ `warning`: `VerticalStepper` tints its node and ends the row with a cross,
338
+ `HorizontalStepper` fills its node, `StepTabs` marks it with a cross; each
339
+ reads it as "failed" (`StepTabs`' word is overridable through
340
+ `statusLabels`). Code that switches over the status exhaustively must handle
341
+ the new value.
342
+ - **A `stale` step status** (`VerticalStepperStepStatus`, so `VerticalStepper`
343
+ and `HorizontalStepper` alike): a step that was done but whose input has
344
+ changed since, so it needs doing again. It counts as reached (the line into
345
+ it is filled). `HorizontalStepper` fills its node in `warning` whatever the
346
+ `color`; `VerticalStepper` tints its node in `warning`, ends the row with a
347
+ warning triangle instead of the check, and reads it as "out of date".
348
+ Code that switches over the status exhaustively must handle the new value.
349
+ - **`RequirementListItem.description`**: an optional second line under a
350
+ row's label, one size smaller and muted in both states (only the label
351
+ takes the met colour), for a checklist whose labels need an example to act
352
+ on. A row with one aligns to the top with its icon on the label's line;
353
+ rows without one are unchanged.
354
+ - **`PopoverGroup`**: popovers that share one place on screen. At most one is
355
+ open; with `openOnHover` the first opens after its `openDelay`, another takes
356
+ over only after the pointer rests on it for `switchDelay` (default 350 ms),
357
+ and reaching the open content cancels a pending switch, so crossing other
358
+ triggers on the way to the panel does not switch it. `value` /
359
+ `defaultValue` / `onValueChange` name the open one; `Popover` gains `value`,
360
+ its key in the group. A popover outside a group is unchanged.
361
+ - **`FlipCard`**: two faces, controlled by `flipped`. `effect="turn"` (the
362
+ default) turns it over about `x` (a split-flap) or `y` (a page);
363
+ `effect="slide"` slides the showing face out past the far edge while the next
364
+ follows it in from the near one (down for `x`, sideways for `y`). Every
365
+ change moves the same way, so loading the hidden face and flipping shows a
366
+ stream of items in one slot; the hidden face is `aria-hidden` and `inert`;
367
+ `onFlipEnd` reports the end of a change (at once under reduced motion, where
368
+ the faces swap in place).
369
+ - **`AsyncMultiSelect` `action`**: a row pinned under the scrolling options,
370
+ after a separator (`{ label, description?, icon?, onSelect }`), for a way out
371
+ of the search such as "Browse all". It stays in sight while the options
372
+ scroll, is reachable with the arrow keys, and shows also when nothing
373
+ matches (the empty text above it). Choosing it closes the dropdown and calls
374
+ `onSelect`; it selects nothing. New type `AsyncMultiSelectAction`.
375
+ - **`shadow-float`** (`--shadow-float`): a wide, soft halo with no offset, for
376
+ something that floats over the page on every side, such as a composer docked
377
+ at the bottom of a window, where the `shadow-*` sizes (cast downward) would be
378
+ hidden. Coloured like `shadow-glow`, by the shadow-colour utility beside it
379
+ (`shadow-float shadow-foreground/10`); `cn` treats it as a shadow size.
380
+ - **`SelectableCardList` `cardSelectionStyle`** (`border` | `tint` | `none`):
381
+ how a selected row shows it. `border`, the default, is the primary border as
382
+ before. `tint` is a very subtle primary background with the border in that
383
+ same tint, for lists where a heavy border is too much. `none` changes nothing
384
+ (the indicator still shows the selection).
385
+ - **`SelectableCardList` item `note`, and `icon` is optional.** A `note` is a
386
+ line under the secondary text that is never truncated, for why a row is
387
+ suggested or why it is disabled (primary colour; muted on a disabled row).
388
+ An item without an `icon` draws no avatar and starts with its text.
389
+ Existing lists are unchanged.
390
+ - **`Input` `startAddOnAction` / `endAddOnAction`**: a control (a button) that
391
+ is the add-on itself. It fills the segment edge to edge at the field's
392
+ height, takes the field's outer corners and none where it meets the text,
393
+ and its focus ring sits exactly on the segment's edges. It never shrinks:
394
+ the text part gives up the room. Takes precedence over
395
+ `…AddOnContent` and `…AddOn` on its side; text add-ons keep their padded box.
396
+ - **`Tooltip` `maxWidth`** (`xs` | `sm` | `md`): caps the bubble's width so a
397
+ long tooltip (a sentence or two) wraps instead of running off the screen.
398
+ Unset, the bubble fits its content as before.
399
+ - **`scrollbar-hover`** utility: a thin scrollbar that shows only while the
400
+ pointer is over the scroller or focus is inside it, for a row that runs past
401
+ the edge (filter chips). The thumb fades in and out (Chromium, Firefox;
402
+ Safari shows it at once). The track keeps its space, so nothing shifts on
403
+ hover. Beside `scrollbar-none`; the stylesheet only grows by its rules.
404
+ - **`--espd-navbar-backdrop-blur`**: blurs the page under an open `NavBar`
405
+ details panel, behind its dim. Unset (`initial`) by default; it then
406
+ follows `--espd-overlay-blur`, and with neither set the page stays sharp,
407
+ as before. An app that already sets `--espd-overlay-blur` therefore gets
408
+ the same blur under the nav panel; set this token to `0px` to opt out. The
409
+ stylesheet only grows: the token declaration and its reader.
410
+ - **`--espd-elevation-navbar`**: the shadow of `NavBar`'s floating pill
411
+ (`morphOnScroll`, scrolled) and of the details panel hanging from any
412
+ `NavBar`. Unset (`initial`) by default, so both fall back to
413
+ `--espd-elevation-overlay` and then to the bar's own `shadow-lg`, as
414
+ before. A dark theme, where a black shadow vanishes into a near-black
415
+ page, can give the bar a glow of its own without changing every overlay,
416
+ e.g. `.dark { --espd-elevation-navbar: 0 0 0 1px rgb(255 255 255 / 0.08),
417
+ 0 0 32px -6px var(--color-primary); }`. The pill now keeps its shadow
418
+ while its panel is open, clipped at its bottom edge, so pill and panel
419
+ cast one shadow as one card. The stylesheet only grows: the token
420
+ declaration, the shadow reader, a box-shadow transition and the pill's
421
+ clip; `shadow-lg` stays generated.
422
+ - **`CategoryCard`**: one category of a collection as a card that opens or
423
+ filters it, for a "browse by kind" row. Its icon on a tile in `color` (a
424
+ preset or any CSS colour, through the same `soft` resolution as `Badge`;
425
+ `iconClassName` for a token tint such as `bg-swatch-2-light text-swatch-2`
426
+ in its place),
427
+ the count in the corner (`value`), the name, a line (`description`) and a few
428
+ examples (`tags`, folding past `maxTags` into "+N"). The whole card is a
429
+ button, or a link with `href`; `selected` gives an accent border and
430
+ `aria-pressed` (or `aria-current` on a link) for cards used as a filter. It
431
+ is a size container: below 12rem wide it tightens and drops the tags, so a
432
+ two-up phone grid needs nothing from the app. The title truncates with a
433
+ tooltip (`truncateTitle`), the description clamps to two lines
434
+ (`truncateDescription`). Prop names follow `SimpleClickableCard`.
435
+ - **`TruncatedLineWithTooltip` is public** (`/components`): one line that
436
+ truncates and shows the whole text in a tooltip only when it is cut. It
437
+ brings its own `TooltipProvider` when the app has none (it used to throw),
438
+ as `SectionCard`'s copy already did; `className` is optional.
439
+ - **`MiniBarChart`.** A row of bars with no axes and no tooltip, sized to
440
+ sit inside a card: `values`, an sr-only `label` (required — the bars are
441
+ hidden from assistive technology), `highlightIndex` (the others fade),
442
+ `color` (any `Color`, or `currentColor` to follow the text on a filled
443
+ tile), `density` (`default` | `thin` for dozens of bars) and `height`
444
+ (default 32). The tallest value fills the height; a zero draws as a faint
445
+ stub rather than nothing. `barTooltip(value, index)` gives each bar a tooltip on
446
+ hover (return `null` for none): every bar then takes the chart's full
447
+ height as its hover target and brightens while hovered, and one provider
448
+ per chart swaps the tooltip at once from bar to bar. A visual extra —
449
+ `label` stays what assistive technology reads.
450
+ - **`ShareMenu`.** Share a link from a `DropdownMenu`: copy it (the item
451
+ says "Link copied" for 1.4s, then the menu closes), the device's share
452
+ sheet (`native`, offered only where `navigator.share` exists), or a site's
453
+ own share page in a new tab — X, Reddit, LinkedIn, Telegram — or an email.
454
+ `url`, `title`, `text?`, `targets?` (order and subset), `labels?` and
455
+ `icons?` per target (English and the library's monochrome marks by
456
+ default), `trigger` (your button), `align`, `onShare(target)` for
457
+ analytics and `onCopyError`.
458
+ - **`Timeline`.** A short feed, newest first: a dot per item on a
459
+ connecting line, the title, and when under it in the mono face. Pages by
460
+ `pageSize` (default 5); "Show N more" reveals the next page, which rises
461
+ in, and moves focus to its first item. `items` (`id`, `title`, `time?`,
462
+ `color?`), `labels.showMore(count)`.
463
+ - **`StatCard`: `caption`, `visual` and `surface`.** `visual` is a
464
+ fixed-height row between the value and the caption for a small picture (a
465
+ `MiniBarChart`, a `ProgressBar`), so a row of cards stays level with or
466
+ without one. `caption` is one trimmed line under it; a string caption is
467
+ also its `title`. `surface="plain"` draws the card surface with a border
468
+ instead of the colour's gradient (`tinted`, the default), so a row of
469
+ differently coloured tiles reads as one set.
470
+ - **`ProgressBar` segments take a `tooltip`.** Shown on hover over that
471
+ segment; one provider per bar swaps it at once from segment to segment. A
472
+ bar with no segment tooltip renders exactly as before.
473
+ - **`CircularProgress`: `children`.** Content centred inside the ring — an
474
+ icon or an `IconAvatar` for a badge medal — drawn in place of the
475
+ percentage.
476
+ - **Scrim tokens for modal overlays**: `--espd-overlay-scrim` (the colour
477
+ behind a modal `Sheet` or `Dialog`, `/core`'s `Dialog` and `CommandDialog`
478
+ included) and `--espd-overlay-blur` (how much it blurs the page under it).
479
+ Unset (`initial`) by default, so every scrim keeps its own: black at 50%
480
+ (Sheet, Dialog) or 80% (`/core`'s Dialog), no blur. A dark theme, whose
481
+ page is already near-black, can deepen or blur it on `:root` or `.dark`:
482
+ `--espd-overlay-scrim: rgb(0 0 0 / 0.6); --espd-overlay-blur: 6px;`.
483
+ The stylesheet only grows: the two token reads, the declarations, and
484
+ `bg-black/50` / `bg-black/80` kept for apps that use them.
485
+ - **`Button` `color="silver"`**: the brand's metallic finish, which `Badge`
486
+ and `Tag` already take. `default` gets the brushed-metal sheen of a solid
487
+ silver badge over the `gray` fill, `outline` and `glow` the metallic 1px
488
+ ring in place of a border, `ghost` and `link` plain `gray`.
489
+ - **`SearchBox` names its input**: `id`, `name`, `aria-label`,
490
+ `aria-labelledby` and `aria-describedby` go to the `<input>`, not the
491
+ wrapper. A search box usually has no visible label and a placeholder is not
492
+ an accessible name everywhere, so pass `aria-label` (or point
493
+ `aria-labelledby` at a heading, or `id` at a `<label htmlFor>`).
494
+ - **`Coverflow`**: a 3D carousel seen from inside a ring of image cards. The
495
+ front card faces the viewer, the cards on either side turn toward it, and
496
+ every card stands on a glass reflection that fades into the floor; the
497
+ front item's `caption` node shows beneath, in a polite live region. It never
498
+ runs out: a short list is repeated round the ring. Arrows, ← / →, a swipe,
499
+ a dot or a click on a side card turns it; `onOpen` makes the front card a
500
+ button. `aspect` (`landscape` | `square`), `variant` (`card` | `cutout`),
501
+ `reflection`, controlled `index` / `onIndexChange`, `autoplay` / `delay`
502
+ (as in `Carousel`; never under reduced motion, off screen, in a hidden tab
503
+ or while in use), `renderFace` for pictures that are not a plain URL, and
504
+ translated `labels`. It draws no background: put it on a dark floor.
505
+ - **`HorizontalStepper`**: a few stops in a row joined by a line (requested,
506
+ building, shipped), the horizontal sibling of `VerticalStepper` with the same
507
+ step `status` values. `color` fills the steps reached and the line up to the
508
+ current one; `size="sm"` for a card; `tone="inverse"` for a dark overlay;
509
+ `animateIn="media-card-reveal"` pops the nodes in and fills the line each time
510
+ the surrounding `MediaCard` reveals. One image to assistive technology
511
+ (`ariaLabel`).
512
+ - **`ExpandableText`**: text clamped to `lines` with a "Show more" link that
513
+ appears only when the text is really cut off (measured with a
514
+ ResizeObserver). `mode="inline"` grows in place; `mode="overlay"` opens the
515
+ full text, with an optional `header` and `footer`, over the nearest
516
+ positioned ancestor as a circle growing from the link, so a card never
517
+ changes height. Escape closes it and focus returns to the link.
518
+ - **`ReactionButton`**: a reaction with its count (a like, an upvote, a want),
519
+ `aria-pressed`; switching it on pops the mark, spreads a ring, bursts the
520
+ sparkle and ticks the count (`animate-heart-pop`, `animate-espd-ripple`,
521
+ `animate-sparkle`, `animate-rise-in`); switching off plays nothing.
522
+ - **`PageBanner`**: an outlined banner at the top of a page or tab — `kicker`,
523
+ `title`, `description`, `meta`, `action` and aria-hidden `decoration` —
524
+ stacking into one column on a narrow screen.
525
+ - **`OverflowBadgeList` `singleLine`, `overflowAs` and `badgeClassName`**
526
+ (all optional, defaults unchanged). `singleLine` never wraps: the last
527
+ visible badge shrinks with an ellipsis so the overflow label stays whole.
528
+ `overflowAs="text" | "badge"` makes the overflow label a button whose
529
+ popover lists the HIDDEN items on hover, focus or tap; unset keeps the
530
+ original hover tooltip of every item. `badgeColor` (and an item's `color`)
531
+ now take any `Color` a badge does, `"silver"` included; the five presets
532
+ keep working as before. Compiled CSS gains the utilities these
533
+ five use (`line-clamp-2`…`6`, `scale-x-0`, `origin-left`, `max-w-140`,
534
+ `font-extrabold` and a few sizes), all inert unless used.
535
+ - **Celebration animations for a toggle switched on**: `animate-heart-pop`
536
+ (a like), `animate-bookmark-drop` (a save) and `animate-sparkle` (six dots
537
+ in the brand colours bursting from one element; pair with
538
+ `animate-espd-ripple` for a ring). Switching off plays nothing; wrap them in
539
+ `motion-safe:`.
540
+ - **`ToggleGroup` `variant`**: `default` (the control frame, as before),
541
+ `rounded` (a pill) and `glow` (a pill with a halo) — the same frames as
542
+ `TabsList`, so a segment control can sit beside a glowing tab list. The
543
+ rounded border and the glow take the group's `color`.
544
+ - **`glow` on `Button` and `TabsList`.** `Button variant="glow"` is the
545
+ `outline` button with the soft halo in its `color` that Badge, Alert and
546
+ Tag use for their `glow` variant (`shadow-glow`, the colour at 45%); the
547
+ halo replaces the elevation shadow, so `elevation` does not apply to it,
548
+ while `radius` and `border` do. `TabsList variant="glow"` is the `rounded`
549
+ list with the same halo in `primary`; its scroller keeps a 12px gutter
550
+ around the list so the halo is not clipped. Compiled CSS gains `.-m-3`.
551
+ - **`MediaCardImage`**, the picture in a `MediaCardMedia` with its loading
552
+ handled: a pulsing placeholder until it arrives, then a fade-in (none under
553
+ reduced motion), and its `fallback` in its place if it fails. `fit`
554
+ (`cover` / `contain`), lazy by default, `eager` for the first screenful.
555
+ - **`MediaCard`**: a card led by a picture that opens as one link. The title's
556
+ `MediaCardLink` (an `<a>`, or your router's link with `asChild`) is
557
+ stretched over the whole card; `MediaCardAction` lifts a button above it,
558
+ so a button is never nested in the link. Parts: `MediaCardMedia` (16:9,
559
+ `layout="bleed"` for a photo or `"inset"` for a tile on a tint),
560
+ `MediaCardBody`, `MediaCardTitle`, `MediaCardMeta`, `MediaCardFooter`. It
561
+ lifts on hover and keyboard focus (`lift`), and rings when its link has
562
+ focus. `MediaCardReveal` adds a layer over the media on hover and focus:
563
+ `variant="circle"` opens a scrim from the centre with a ring bursting out
564
+ and springs its parts in, in order (`MediaCardRevealItem`,
565
+ `MediaCardRevealChips`, `MediaCardRevealFooter` with an `action` that
566
+ swings in last), hidden on touch screens; `variant="strip"` fades a strip
567
+ of actions in along the bottom, always shown on touch screens. Nothing
568
+ moves under reduced motion. The circle has no backdrop blur on purpose:
569
+ Chrome paints a backdrop-filter across the whole layer while its clip-path
570
+ animates, and the circle never shows.
571
+ - **`Avatar` `color`.** The initial's circle was always `primary`; it now takes
572
+ any preset (filled with that colour, the initial in its `-foreground`) or
573
+ any CSS colour. Defaults to `primary`, so existing avatars are unchanged.
574
+ Behind it, `resolveColor` gains an `fg` target: the text that reads on a
575
+ fill of the colour (the preset's foreground token, or
576
+ `--espd-on-solid-foreground` for an arbitrary colour, as `solid` uses).
577
+ - **`AvatarGroup`.** A row of overlapping avatars on rings of the page
578
+ background, with a "+N" chip past `max` or up to `total` (the five most
579
+ active of 31 people). `label` names the group; without it the row is
580
+ decorative.
581
+ - **`Identicon`.** A generated avatar drawn from a grid of cells (`cells`,
582
+ row by row, `columns` default 5) in `currentColor`. It takes the cells rather
583
+ than a name, so the app that owns an identity also owns how it becomes a
584
+ picture.
585
+ - **`Avatar` `size="xl"` and `fallback`.** A 76px tile for a profile card, and
586
+ any node (an `Identicon`) in place of the initial when there is no image.
587
+ `AvatarSize` names the sizes.
588
+ - **Swatch colours** `--color-swatch-1…5` (an ink) and `--color-swatch-1…5-light`
589
+ (its tint), light and dark: five categorical colours for telling things apart
590
+ by colour alone (one person's tile from the next), picked by a stable hash,
591
+ never by meaning.
592
+ - **Scrim colours** `--color-scrim` / `--color-scrim-foreground`: a dark
593
+ see-through layer over content and the text that reads on it, the same in
594
+ both themes (`bg-scrim/85 text-scrim-foreground`).
595
+ - **`ease-overshoot`** (a bigger overshoot than `ease-spring`, for chips and
596
+ buttons popping into place) and **`animate-burst`** (one ring bursting out
597
+ of a mark to 3.4x and fading, 0.6 s).
598
+ - **`animate-spin-slow`** (90 s, linear, endless) for background decoration,
599
+ and the **circular reveal** utilities `clip-circle-closed`,
600
+ `clip-circle-open` and `transition-clip` (clip and visibility together), for
601
+ a panel that opens from its centre over a card.
602
+ - **Tabs collapsible to icons.** `TabsTrigger` takes an `icon` (placed inside
603
+ an `asChild` child too, so a router link keeps working), and `TabsList`
604
+ takes `collapsible` (with `collapsed` / `defaultCollapsed` /
605
+ `onCollapsedChange`): clicking the selected tab folds every trigger that has
606
+ an icon to just its icon, and clicking it again restores the labels. The
607
+ state belongs to the list, so it holds as the selection moves; a trigger
608
+ without an icon keeps its label and does not toggle. Folding is animated:
609
+ each label squeezes shut on a spring (width, fade, a touch of blur) while its
610
+ icon gives a small wiggle, and the highlight follows the shrinking tab;
611
+ nothing moves under reduced motion. Labels stay in the DOM, so they remain
612
+ the tabs' accessible names while folded.
613
+ - **`SearchBox` `value` / `defaultValue`.** Pass `value` with `onValueChange`
614
+ to drive the box from outside (a "Clear all" button, the URL's `?q=`);
615
+ omit it and the box keeps its own text, now seeded from `defaultValue`.
616
+ - **`Popover` `openOnHover`** (with `openDelay`, 120 ms, and `closeDelay`,
617
+ 150 ms). Opens when a mouse rests on the trigger or keyboard focus reaches
618
+ it, and stays open while the pointer is over the content. A click still
619
+ toggles it, so touch screens work as before; a click on a hover-opened
620
+ popover pins it open. The focus a close returns to the trigger does not
621
+ reopen it, and a hover that ends does not pull focus back.
622
+ - **View transitions.** `startViewTransition(update)` in `/utils` runs a
623
+ React state change inside the browser's view transition (directly where it
624
+ is unsupported or reduced motion is asked for). Two utilities name what
625
+ moves: `view-transition-morph` (the one element that becomes another, drawn
626
+ above the page, 0.6 s spring) and `view-transition-glide` (every member of a
627
+ set moving on its own via `match-element`, 0.5 s spring).
628
+ - **`below-navbar` spacing** (`top-below-navbar`, `scroll-mt-below-navbar`, …):
629
+ the clearance under a sticky `NavBar` — its height, the gap it floats at once
630
+ morphed into a pill, and a little air — so a sticky side panel or an anchor
631
+ target is never covered by the bar.
632
+ - **Entrance animations** `animate-pop-in`, `animate-slide-in-start` and
633
+ `animate-rise-in`, with their keyframes; also the fallbacks where view
634
+ transitions are unsupported.
635
+ - **Per-component and grouped entry points.**
636
+ `@espressif/dashboard-ui-components/components/<folder>` exposes one
637
+ component folder (`/components/button`, `/components/dialog`, … 98 of them,
638
+ plus `/components/combobox`), and `/charts`, `/data-table`, `/markdown`,
639
+ `/date`, `/carousel`, `/forms`, `/animation` and `/toast` each expose one
640
+ heavy family. They export exactly the names `/components` exports for that
641
+ folder, bound to the same modules, so mixing paths never duplicates a
642
+ component or its context. Production bundles were already tree-shaken; the
643
+ gain is for test runners, dev servers and CommonJS tooling, which evaluate
644
+ everything an entry reaches: a Vitest + jsdom suite can now import
645
+ `/components/button` with no stubs. `./package.json` is exported too.
646
+
647
+ **Upgrading:** optional. Import from the narrowest path you can. The
648
+ `/components` barrel and the root still export everything, unchanged.
649
+ - **`theme.css`, a tokens-only stylesheet**
650
+ (`@espressif/dashboard-ui-components/theme.css`): every token, the `dark`
651
+ variant, keyframes, the library's `@source` and the border colour the
652
+ components rely on, without `@import "tailwindcss"`, Preflight or page
653
+ styles, for apps that bring their own Tailwind. `./styles` is now built from
654
+ it and compiles to the same CSS (rules reordered where they do not overlap).
655
+ - **Dark mode through `data-theme="dark"`** as well as the `.dark` class: the
656
+ `dark:` variant and every dark token block also match
657
+ `[data-theme="dark"]` and its descendants. Apps that only use `.dark` see
658
+ no change.
659
+ - **Semantic tokens beyond colour**, each defaulting to the value it replaces:
660
+ `--espd-control-height-sm|md|lg` (buttons, inputs, selects, toggles),
661
+ `--espd-button-padding-x-sm|md|lg`, `--espd-duration-fast|normal|slow`,
662
+ `--espd-ring-width`, `--espd-ring-offset` and `--espd-on-solid-foreground`
663
+ (text on a `solid` surface of an arbitrary colour). Every reader also
664
+ carries the default as a `var()` fallback. The compiled stylesheet only
665
+ gains rules: the three white-text utilities components no longer use stay
666
+ generated. What is already overridable and what is still hard-coded is in
667
+ `docs/token-audit.md`.
668
+ - **Variants an app can add.** `Variant` is now `keyof VariantRegistry`, an
669
+ interface an app augments (`declare module "…/components" { interface
670
+ VariantRegistry { glow: true } }`); `registerVariant(name, recipe)` supplies
671
+ the styles at runtime and `listVariants()` lists built-ins plus registered
672
+ ones. Every variant-driven component accepts a registered variant. The four
673
+ built-ins cannot be replaced, `VARIANTS` still lists only them, and an
674
+ unknown, unregistered variant behaves as before. Also exported from
675
+ `/utils`, with `VARIANTS` and `resolveVariantStyles`.
676
+ - **Style-axis registries** (radius, elevation, border, density), the
677
+ groundwork for per-role tokens and per-instance props: `Radius`,
678
+ `Elevation`, `Border` and `Density` are `keyof` interfaces an app augments
679
+ like `VariantRegistry`; `registerStyleValue(axis, name, css)` and
680
+ `registerDensity(name, tokens)` add values (built-ins cannot be replaced),
681
+ `listStyleValues` and `resolveStyleValue` / `resolveDensity` read them, and
682
+ `useStyleAxes` builds a component root's style from the props. A value is
683
+ CSS, not a class, so a registered value needs no generated Tailwind class.
684
+ No component takes these props yet. Exported from `/components` and
685
+ `/utils`. The compiled stylesheet gains the inert `--shadow-xs` …
686
+ `--shadow-xl` declarations on `:root`, which the elevation values read.
687
+ - **Role tokens for controls.** `--espd-radius-control`,
688
+ `--espd-border-width-control` and `--espd-elevation-control` give every
689
+ control one corner radius, border width or shadow: Button (both bases),
690
+ FlashButton, InvertButton, CopyButton, Input (and its add-ons), Textarea,
691
+ Select, SearchBox, AdvancedSearchBox, FileInput, InputOTP, TagInput,
692
+ Toggle, ToggleGroup, Combobox, AsyncMultiSelect and the date-picker
693
+ triggers. Elevation applies to the buttons that draw a shadow (default and
694
+ outline). All ten role tokens (control, surface, overlay, pill, item) are
695
+ declared on `:root` as `initial`, which means unset: each component keeps
696
+ its own value until an app sets the token, so nothing changes by default.
697
+ An app's `className` still wins over a token: `cn` now treats a labelled
698
+ `shadow-[shadow:…]` class as a shadow, so `shadow-none` replaces it.
699
+ `rounded-s-lg` and `rounded-e-lg` stay generated although Input no longer
700
+ uses them.
701
+ - **Role tokens for surfaces.** `--espd-radius-surface`,
702
+ `--espd-border-width-surface` and `--espd-elevation-surface` reach Card
703
+ (and SimpleCard), CollapsibleCard, StatCard (every size), Alert,
704
+ IconTextActionCard, SimpleInfoCard, SimpleClickableCard, the
705
+ SelectableCardList items, FileUpload, CodeEditor, Code, DataTable (with
706
+ `showBorder`), ListDetails, ScrollableSections and StatusCardList. Radius
707
+ reaches all of them; border width the ones with their own border; elevation
708
+ Card, CollapsibleCard and PageContainer's elevated header (unset, the
709
+ header keeps its accent-tinted shadow; set, the token's shadow and colour
710
+ replace it; `shadow-md` stays generated). Explicit opt-outs keep their
711
+ literals (SimpleCard
712
+ `noShadow` / `noBorder`, NoDataCard). SectionCard takes radius and
713
+ elevation; its border comes from its variant styles.
714
+ `rounded-xl` and `rounded-3xl` stay generated.
715
+ - **Role tokens for overlays.** `--espd-radius-overlay` and
716
+ `--espd-elevation-overlay` reach Dialog, CommandDialog, Sheet, Popover, the
717
+ date-picker popovers, DropdownMenu (and its submenus), Select content,
718
+ Combobox's list, Tooltip, Toast, PreviewCard, the NavBar details panel, the
719
+ collapsed Sidebar flyout and the chart tooltip, each falling back to its own
720
+ radius and shadow. Overlays render in portals, so set these on `:root` (or
721
+ `<html>`), not on a wrapper. FullscreenDialog keeps its square corners.
722
+ `rounded-2xl`, `rounded-l-2xl`, `rounded-r-2xl` and `shadow-xl` stay
723
+ generated.
724
+ - **Role token for pills.** `--espd-radius-pill` reaches Badge (and so
725
+ UserTypeBadge and OverflowBadgeList), Tag and its name chip (and so
726
+ TagInput's chips), StatusBadge and StatCard's trend badge, each falling
727
+ back to its own radius (`md` for Badge, `full` for StatusBadge). Tag's
728
+ `rounded` prop still makes it fully round.
729
+ - **Role token for items.** `--espd-radius-item` reaches the rows of
730
+ Select, DropdownMenu (items, checkbox and radio items, sub-triggers and the
731
+ hover highlight), Command / Combobox, Sidebar (menu buttons, sub-buttons and
732
+ the active highlight), NavBar, Tabs (triggers and highlight), List (and so
733
+ Menu), TransferList and Calendar day cells (today, a selected day, range
734
+ start and end, and the row ends inside a range; the range middle stays
735
+ square), each falling back to its own radius. Calendar days used to follow
736
+ Button's control radius; they now follow the item token. NavBar's
737
+ `isPill` and the Tabs `rounded` variant keep their full rounding.
738
+ `rounded-[10px]` and Calendar's old `rounded-*-md` utilities stay generated.
739
+ - **`radius`, `elevation` and `border` props on one component**, through
740
+ `useStyleAxes`. A value affects that component only: the private variables
741
+ (`--espd-own-radius`, `--espd-own-elevation`, `--espd-own-border-width`)
742
+ are registered non-inheriting in the new `src/styles/style-axes.css`
743
+ (imported by `theme.css`), so components nested inside keep their own look.
744
+ With no prop the DOM is unchanged. Precedence: `className` > prop > role
745
+ token > the component's own default.
746
+ - Controls: Button (all three; `border` on `outline`), FlashButton,
747
+ InvertButton, CopyButton (`radius`), Input, Textarea, SelectTrigger,
748
+ SearchBox, AdvancedSearchBox, FileInput, TagInput, AsyncCombobox,
749
+ AsyncMultiSelect (`radius`, `border`), InputOTP, DatePicker,
750
+ DateTimePicker, DateRangePicker (trigger), ToggleGroup (`radius`).
751
+ - Surfaces: Card, SimpleCard, CollapsibleCard (all three), SectionCard
752
+ (`radius`, `elevation`), StatCard, Alert, IconTextActionCard,
753
+ SimpleInfoCard, SimpleClickableCard, FileUpload, ListDetails,
754
+ StatusCardList (`radius`), SelectableCardList, CodeEditor, Code,
755
+ DataTable, `ScrollableSections.Tabs` (`radius`, `border`).
756
+ - Overlays: DialogContent, SheetContent, PopoverContent,
757
+ DropdownMenuContent, DropdownMenuSubContent, SelectContent,
758
+ PreviewCardPanel (`radius`, `elevation`). The date pickers' calendar
759
+ popovers (and DateRangePicker's side calendar panel) take
760
+ `popoverRadius` and `popoverElevation` on DatePicker, DateTimePicker
761
+ and DateRangePicker; their `radius` stays the trigger's.
762
+ TooltipContent and the `Tooltip` wrapper take `radius` and
763
+ `elevation`; a tooltip draws no shadow by default, so its elevation
764
+ reads the prop only (the overlay elevation token does not reach it).
765
+ Toast (also through `toast({ title, radius, elevation })`) and
766
+ ChartTooltipContent take `radius` and `elevation`; AreaChart, BarChart,
767
+ ComposedChart, DonutChart, LineChart and TreemapChart forward
768
+ `tooltipRadius` / `tooltipElevation` to their hover tooltip; Sidebar
769
+ takes `flyoutRadius` / `flyoutElevation` for the menu a group opens
770
+ while the sidebar is collapsed to icons.
771
+ - Pills: Badge, Tag, StatusBadge, UserTypeBadge, OverflowBadgeList
772
+ (`radius`).
773
+
774
+ The older props keep working and lose to the new one when both are set:
775
+ `rounded` (Input, InputOTP, FileInput, Tag, TagInput, the date pickers)
776
+ is `radius="full"`; SimpleCard's `noShadow` / `noBorder` are
777
+ `elevation="none"` / `border="none"`. The animate-ui highlight primitive
778
+ keeps an item's own `style` when it clones it (it used to replace it).
779
+ - **Density.** `density="compact" | "default" | "comfortable"` on Table,
780
+ DataTable, Card, List, SimpleList, FiltersBar, Sidebar (desktop),
781
+ DialogContent and SheetContent scales controls, table head and cells, list
782
+ rows, sidebar rows and two gaps together; `default` is today's look. New
783
+ tokens, defaulting to today: `--espd-table-head-height`,
784
+ `--espd-table-cell-padding`, `--espd-sidebar-row-height` (+ `-sm`),
785
+ `--espd-item-height` for List rows (falls back to `--menu-item-height`),
786
+ `--espd-gap-field` (FormItem's spacing between label, control and
787
+ message) and `--espd-gap-stack` (DialogContent's gap between header, body
788
+ and footer). A `space-y-*` / `gap-*` class an app passes still wins.
789
+ `registerDensity(name, tokens)` adds a density; `densityStyle` and
790
+ `DensityProps` are exported.
791
+ - **`StyleScope`** (`/components/style-scope`): role tokens per role
792
+ (`radius={{ control: "full" }}`, `elevation`, `border`) and a `density` for
793
+ a subtree, on a `display: contents` wrapper or, with `asChild`, on its
794
+ child. Overlays render in portals outside it; set their tokens on `:root`.
795
+ `min-h-[var(--menu-item-height)]` stays generated.
796
+ - **`SectionCard` `expandOnHover`** (default `false`): the card starts
797
+ collapsed, expands while the pointer is over it or keyboard focus is inside
798
+ it, and collapses once it leaves. No chevron is shown; `allowCollapse`,
799
+ `hideCollapseIcon`, `defaultOpen`, `open` and `fillHeight` are ignored, and
800
+ `onOpenChange` still fires. The height transition reverses smoothly when
801
+ the pointer leaves mid-way and respects `prefers-reduced-motion`. On touch
802
+ screens a tap on the header toggles the body.
803
+ - **Sonner's toast styles in `./styles`.** The Toast component still imports
804
+ them from JavaScript (kept for compatibility); duplicate rules are harmless.
805
+ - **`--font-mono` token** beside `--font-sans`. The library's own components
806
+ already use `font-mono` (`CodeEditor`, `MonospaceContent`, code in
807
+ `MarkdownContent`, chart tooltips) but never declared the token, so they
808
+ inherited Tailwind's default and an app had no library token to override.
809
+ The default value is that same Tailwind stack, so nothing changes until an
810
+ app sets its own in `@theme`.
811
+ - **Segmented stacked bars.** `BarChart` takes `segmented` (with `stacked`):
812
+ each segment is its own pill with a `segmentGap` (default `4`px) between
813
+ segments, and the stack's outer ends stay flush with the plot. With
814
+ `layout="vertical"` and hidden axes it draws a single distribution bar.
815
+ - **List legends on every chart.** `legendLayout="rows"` lists one entry per
816
+ line (swatch, label, then the value aligned right) below the chart;
817
+ `"columns"` splits those rows over `legendColumns` columns (default `2`)
818
+ and falls back to one column when the legend is narrower than 28rem.
819
+ `legendValue` picks `value` (default), `percent`, `both` or `none`;
820
+ cartesian charts show each series' total across `data`. Also
821
+ `legendValueFormatter` and `legendClassName`, and `ChartLegendList` for
822
+ custom charts. The default `legendLayout="inline"` is unchanged.
823
+ - **`MinimalWorkspaceLayout`** (`/layouts`): a header-less app shell with
824
+ its own look. The sidebar runs the full height of the window on the page
825
+ background, separated from the content only by a hairline border, so the
826
+ content seems to own the screen; expanded, it lifts with a soft, wide
827
+ shadow. Border, shadow and selected-row colours are mixed from the sidebar's surface, so
828
+ they follow any surface an app sets, light or dark. It starts as a 56px icon
829
+ rail and expands into the labelled sidebar: from an expand button that
830
+ replaces the logo on hover, from a click on any empty part of the rail
831
+ (double-arrow cursor), or with ⌘/Ctrl+B; a collapse button sits beside the
832
+ expanded logo. Top to bottom the sidebar holds the logo, an optional
833
+ `sidebarConfig.header` (a node, or a function of `{ collapsed }`), the menu,
834
+ the footer and the account menu (avatar in the rail, avatar + name + email
835
+ when expanded). `topRightContent` floats over the content's top-right
836
+ corner. It takes WorkspaceLayout's props, so switching is a rename:
837
+ `footerConfig`, `hideBreadcrumbs`, `sidebarConfig.allowCollapsible` and
838
+ `sidebarConfig.variant` are dropped, `headerConfig.rightContent` becomes the
839
+ top-right content, and `defaultSidebarOpen` defaults to `false`. Sizes,
840
+ surfaces (separately for the rail and the expanded sidebar), row accent, border, shadow,
841
+ height and timing are `--espd-minimal-workspace-layout-*` tokens; the logos
842
+ crossfade, and right after expanding the menu rows pop in one by one (a group's rows cascading after it, icons popping a beat later), all off under
843
+ `prefers-reduced-motion`. With `sidebarConfig.hideWhenCollapsed` the
844
+ collapsed sidebar is gone entirely instead of a rail, and the content takes
845
+ the full width: hovering the content's left edge shows a strip in the
846
+ primary colour, and a click there slides the full sidebar in over the
847
+ content (a peek, under a wider shadow) until the pointer leaves it;
848
+ `MinimalWorkspaceSidebarTrigger`, an exported button for
849
+ `topRightContent`, or ⌘/Ctrl+B opens it inline beside the content and
850
+ closes it again. A peek is never reported through `onSidebarOpenChange`;
851
+ `labels.showSidebar` / `hideSidebar` name the trigger.
852
+ - **Sidebar** takes `beforeContent` (a region between the header and the
853
+ menu), `headerClassName`, `className`, `id` and `onClick` for the desktop
854
+ container, and `mobileClassName` for the mobile sheet's panel.
855
+ - **`AccountMenu` / `MyAccountMenu`** take `triggerVariant="card"` (avatar,
856
+ name and email in a full-width row, for sidebars), `side` and `align`. The
857
+ default trigger is unchanged.
858
+ - **Stylesheet additions (inert unless used):** the
859
+ `--espd-minimal-workspace-layout-*` tokens on `:root` (among them
860
+ `-edge-color`, `-edge-width` and `-sidebar-overlay-elevation` for a hidden
861
+ sidebar) and the `espd-pop-in` / `espd-icon-pop` / `espd-fade-in`
862
+ keyframes.
863
+ - **`glow`, a fifth built-in variant** (`variant="glow"` on Badge, Alert,
864
+ Tag, StatusBadge, the cards, Toast and every other variant-driven
865
+ component): a faint tint, a hairline border and a soft, tight halo, each a
866
+ fraction of the colour, for every preset colour, `silver` and any CSS
867
+ colour. It is the recipe the demo used to register for itself, now built
868
+ in, with a `--shadow-glow` token for its halo (`cn` files `shadow-glow` as
869
+ a shadow size, so merging it beside a shadow colour keeps both). `VARIANTS`
870
+ and `listVariants()` now start with five names.
871
+
872
+ **Upgrading:** an app that registered its own `glow` with
873
+ `registerVariant` now gets a warning and the built-in; rename its variant to
874
+ keep it. `Record<Variant, …>` maps an app keeps need a `glow` entry.
875
+ - **`Carousel` takes `align`** (`'start' | 'center' | 'end'`, default
876
+ `'center'` as before; type `CarouselAlign`). Use `'start'` for slides of
877
+ different widths, such as chips: centred and then held inside the row's
878
+ bounds, the first step barely moved and the next one jumped.
879
+ - **Marketing and motion tokens (inert unless used):** `text-display` and
880
+ `text-lead` (fluid headline and lead-paragraph sizes, with their line
881
+ height, tracking and weight), `ease-spring` and `ease-emphasized`,
882
+ `animate-espd-ripple` with its `espd-ripple` keyframes, a `scrollbar-none`
883
+ utility for a swipeable row with its own arrows, and `transition-draw`
884
+ (an SVG line drawing in: dash offset and opacity only).
885
+
886
+ ### Changed
887
+ - **The `tailwindcss` peer range is now `^4.1.0`** (was `^4.0.0`).
888
+ `Coverflow`'s reflection fades with the `mask-*` utilities, which arrived
889
+ in Tailwind 4.1; on 4.0 the reflection would show with a hard edge. Nothing
890
+ else depends on 4.1.
891
+ - **`LottieAnimationContainer` loads the Lottie player on first mount**
892
+ instead of at import, keeping its size while it loads. Importing the
893
+ library no longer evaluates `lottie-web`, which touched `<canvas>` at import
894
+ (breaking jsdom test suites) and uses `eval` (rejected by a strict CSP).
895
+ Apps that never render an animation never load it.
896
+ - **`@base-ui-components/react` 1.0.0-rc.0 → `@base-ui/react` ^1.8.0** (the
897
+ package was renamed; the old one is deprecated). `PreviewCard`,
898
+ `ProgressBar` and `RadioGroup` render and behave as before on 1.8 and 1.9;
899
+ their prop types only gained optional props or widened. The range starts
900
+ at 1.8 so apps with a package-age cooldown (pnpm `minimumReleaseAge`) can
901
+ still resolve a version.
902
+ - **`Tag`: `value` is required and `name` is optional** (breaking for
903
+ types). Without `name` the tinted name chip is not rendered and the tag
904
+ shows only `value`. Both segments use the font's own line height
905
+ (`line-height: normal`); the name gets a
906
+ faint contour and a tight text shadow. Each truncates with an ellipsis at a capped width;
907
+ the new `showFullName` and `showFullValue` props (default `false`) let it
908
+ wrap instead, and drop the default tooltip for that segment. With
909
+ `onDelete`, the end padding shrinks to match the vertical padding, and the
910
+ delete button is round only with `rounded`; otherwise its corners follow
911
+ the tag's (pill radius minus its inset). The `success` name chip on the
912
+ `outline` and `gradient` variants is `bg-success/20` (was `/15`).
913
+ TagInput's single-label chips now pass the tag as `value`.
914
+
915
+ **Upgrading:** a `Tag` with only `name` becomes `<Tag value="…" />`
916
+ (`nameTooltip` → `valueTooltip`). It then renders without the name chip.
917
+
918
+ ### Deprecated
919
+ - **Layout height tokens renamed by owner.** With more layouts coming, the
920
+ generic names are replaced by names that say whose height they are:
921
+
922
+ | Deprecated (1.x) | New |
923
+ |---|---|
924
+ | `--espd-header-height` | `--espd-shell-header-height` (any layout's top bar; AppLogo and the workspace header read it) |
925
+ | `--espd-footer-height` | `--espd-workspace-layout-footer-height` |
926
+ | `--espd-hidden-footer-height` | `--espd-workspace-layout-hidden-footer-height` |
927
+
928
+ The new names are not declared: every read falls back to the deprecated
929
+ name, which keeps its default. An app that overrides an old name, at any
930
+ selector including `.dark`, sees no change; one that sets a new name wins
931
+ over the old. The compiled classes that read the old names stay generated.
932
+
933
+ **Upgrading:** optional in 1.x. Rename your overrides, and any of your own
934
+ CSS that reads these tokens (e.g. `calc(var(--espd-header-height) + 8rem)`),
935
+ together: a stylesheet that sets the new name but reads the old one gets
936
+ the default. The deprecated names are removed in 2.0.
937
+
938
+ ### Fixed
939
+ - **`AsyncMultiSelect`'s `label` names its combobox.** The `<label>` was not
940
+ linked to the trigger, and a combobox does not take its name from its
941
+ content, so screen readers announced an unnamed combobox.
942
+ - **An `Input` with an add-on rings as one control.** Keyboard focus in the
943
+ field used to ring the text part only, stopping short of the add-on beside
944
+ it, so a button add-on (`endAddOnContent`) read as a separate box. The ring
945
+ now goes around the field and its add-ons together, in the error colour when
946
+ the field is in error. A control inside an add-on keeps its own ring when it
947
+ has the focus itself. Fields without add-ons are unchanged.
948
+ - **A sidebar row for the root (`/`) is selected only on the root.** Rows
949
+ match the current path as a prefix (so `/nodes/42` selects `/nodes`), and
950
+ every path starts with `/`: a Home row lit up beside whichever row was
951
+ really current. The breadcrumbs still treat the root as every page's
952
+ ancestor.
953
+ - **A `MediaCard`'s circle reveal no longer swallows clicks.** The panel
954
+ lies over the card's stretched link, and caught the pointer itself, so a
955
+ click on an open panel did nothing, although the card read as one link.
956
+ Like the strip, it is now `pointer-events-none` with only its footer's
957
+ `action` taking the pointer: a click anywhere else opens the card. Content
958
+ that must be interactive belongs in the footer's `action`.
959
+ - **`OverflowBadgeList`'s "+N" badge sits level with the others.** With
960
+ `overflowAs="badge"` its popover button was a block whose badge sat on a
961
+ text line, adding the descender below it (a 25px button around a 22px
962
+ badge); the button is `inline-flex` now.
963
+ - **`Accordion` titles can fill the row and truncate.** A node `title` sat in
964
+ a wrapper that neither grew nor shrank, and the trigger kept its content's
965
+ width, so a title could not push a badge to the right edge and a long one
966
+ widened the row past its container instead of truncating. The wrapper is
967
+ `min-w-0 flex-1`, the trigger `min-w-0`, with a gap before the chevron.
968
+ String titles look as before.
969
+ - **A scrolling tab list (and anything on `useScrollOverflow`) no longer keeps
970
+ a stale "more this way" edge** after content animates to a smaller size. The
971
+ tab highlight springing narrower overflowed the list for a moment and then
972
+ settled without another resize, so the fade and chevron stayed. It now keeps
973
+ measuring for a short while after each resize.
974
+ - **`TabsTrigger`'s `onClick` no longer replaces selecting the tab.** It used
975
+ to override the trigger's own click handler, so a tab with an `onClick`
976
+ could not be selected by clicking it. The consumer's handler now runs first,
977
+ and `preventDefault()` in it keeps the selection where it is.
978
+ - **`Button` with `asChild`** no longer throws ("Slot failed to slot onto its
979
+ children"). `<Button asChild startIcon={…}><a href="…">Label</a></Button>`
980
+ (or a router `Link`) renders one element with the button's classes, the
981
+ icons and the label. With `disabled` or `loading` the link gets
982
+ `aria-disabled`, `data-disabled`, `tabIndex={-1}` and the disabled look,
983
+ and its clicks are cancelled before the link's own `onClick`. Without
984
+ `asChild` the markup is unchanged.
985
+ - **Sidebar's collapsed-group flyout scrolls.** A long group no longer runs
986
+ off the bottom of a short window: the flyout dropped an `overflow-visible`
987
+ that overrode its menu's own height cap and scrolling.
988
+ - **`SectionCard`** no longer throws ("useContext must be used within
989
+ GlobalTooltipProvider") when its `secondaryText` overflows in an app that
990
+ has no `TooltipProvider`. The truncation tooltip now uses the app's
991
+ provider when there is one and brings its own otherwise.
992
+
993
+ ### Documentation
994
+ - The styled `Button`, the uncoloured base `Button` in `/core` and the
995
+ styled Button's `fullWidth` default (`true`) are documented in JSDoc and the
996
+ README.
997
+
998
+ ### Internal
999
+ - `usePrefersReducedMotion` moved out of `carousel.tsx` into
1000
+ `src/core/hooks/`, shared with `Coverflow` (as is the new `useOnScreen`:
1001
+ on screen and the tab visible). `Carousel` behaves as before.
1002
+ - **Backward-compatibility gate**, `npm run verify`: a public-API snapshot
1003
+ (`api-snapshot.json`, removals fail), a compiled-stylesheet snapshot
1004
+ (`snapshots/`), bundle budgets that also fail if a narrow entry reaches a
1005
+ heavy dependency, and an unpublished `playground/` that installs the packed
1006
+ library like a real app: a visual catalogue compared pixel for pixel
1007
+ against the 1.11.0 baseline (light, dark, `theme.css`-only and
1008
+ `data-theme`), Button hover/focus states, a minimal-consumer size
1009
+ measurement and a no-stubs Vitest import suite. CI runs the API and CSS
1010
+ checks and that the generated entries are current.
1011
+
1012
+ ## [1.11.2] - 2026-10-21
1013
+
1014
+ ### Fixed
1015
+ - **`SelectContent`** — a long list now stays on screen and scrolls. Its
1016
+ height cap used the Tailwind v3 form `max-h-[--var]`, which Tailwind v4
1017
+ compiles to invalid CSS, so the list had no max height: it opened past the
1018
+ top of the viewport and could not scroll. It now uses `max-h-(--var)`.
1019
+ - **`SelectContent`** — scrolling no longer snaps back to the top when it
1020
+ starts without the mouse over an item (touch, scrollbar drag). When a scroll
1021
+ arrow appears, Radix scrolls the focused item back into view; focus now
1022
+ moves to the listbox once that item leaves the viewport. After a scroll,
1023
+ arrow keys start again from the first item.
1024
+ - **`SelectContent`, `PopoverContent`** — the open animation's transform
1025
+ origin uses Tailwind v4 syntax (`origin-(--var)`), so it is applied again.
1026
+
7
1027
  ## [1.11.1] - 2026-10-21
8
1028
 
9
1029
  ### Fixed