@d4gger/design-system 3.0.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (403) hide show
  1. package/dist/{components/controlGroup/ControlGroup.cjs → _internal/floatingLayer.cjs} +11 -26
  2. package/dist/_internal/floatingLayer.cjs.map +7 -0
  3. package/dist/_internal/floatingLayer.d.cts +28 -0
  4. package/dist/_internal/floatingLayer.d.cts.map +1 -0
  5. package/dist/_internal/floatingLayer.d.mts +28 -0
  6. package/dist/_internal/floatingLayer.d.mts.map +1 -0
  7. package/dist/_internal/floatingLayer.d.ts +28 -0
  8. package/dist/_internal/floatingLayer.d.ts.map +1 -0
  9. package/dist/_internal/floatingLayer.js +11 -0
  10. package/dist/_internal/floatingLayer.js.map +7 -0
  11. package/dist/components/banner/Banner.cjs +105 -0
  12. package/dist/components/banner/Banner.cjs.map +7 -0
  13. package/dist/components/banner/Banner.d.cts +27 -0
  14. package/dist/components/banner/Banner.d.cts.map +1 -0
  15. package/dist/components/banner/Banner.d.mts +27 -0
  16. package/dist/components/banner/Banner.d.mts.map +1 -0
  17. package/dist/components/banner/Banner.d.ts +27 -0
  18. package/dist/components/banner/Banner.d.ts.map +1 -0
  19. package/dist/components/banner/Banner.js +80 -0
  20. package/dist/components/banner/Banner.js.map +7 -0
  21. package/dist/components/{controlGroup/controlGroup.props.cjs → banner/banner.props.cjs} +23 -16
  22. package/dist/components/banner/banner.props.cjs.map +7 -0
  23. package/dist/components/banner/banner.props.d.cts +32 -0
  24. package/dist/components/banner/banner.props.d.cts.map +1 -0
  25. package/dist/components/banner/banner.props.d.mts +32 -0
  26. package/dist/components/banner/banner.props.d.mts.map +1 -0
  27. package/dist/components/banner/banner.props.d.ts +32 -0
  28. package/dist/components/banner/banner.props.d.ts.map +1 -0
  29. package/dist/components/banner/banner.props.js +27 -0
  30. package/dist/components/banner/banner.props.js.map +7 -0
  31. package/dist/components/banner.css +60 -0
  32. package/dist/components/button-group.css +25 -0
  33. package/dist/components/button.css +9 -0
  34. package/dist/components/card.css +3 -0
  35. package/dist/components/carousel/Carousel.cjs +109 -39
  36. package/dist/components/carousel/Carousel.cjs.map +3 -3
  37. package/dist/components/carousel/Carousel.d.cts.map +1 -1
  38. package/dist/components/carousel/Carousel.d.mts.map +1 -1
  39. package/dist/components/carousel/Carousel.d.ts.map +1 -1
  40. package/dist/components/carousel/Carousel.js +111 -41
  41. package/dist/components/carousel/Carousel.js.map +3 -3
  42. package/dist/components/carousel.css +93 -26
  43. package/dist/components/chart/Chart.cjs +61 -11
  44. package/dist/components/chart/Chart.cjs.map +2 -2
  45. package/dist/components/chart/Chart.d.cts.map +1 -1
  46. package/dist/components/chart/Chart.d.mts.map +1 -1
  47. package/dist/components/chart/Chart.d.ts.map +1 -1
  48. package/dist/components/chart/Chart.js +62 -11
  49. package/dist/components/chart/Chart.js.map +2 -2
  50. package/dist/components/chart.css +10 -1
  51. package/dist/components/checkbox.css +14 -0
  52. package/dist/components/combobox/Combobox.cjs +3 -1
  53. package/dist/components/combobox/Combobox.cjs.map +2 -2
  54. package/dist/components/combobox/Combobox.d.cts.map +1 -1
  55. package/dist/components/combobox/Combobox.d.mts.map +1 -1
  56. package/dist/components/combobox/Combobox.d.ts.map +1 -1
  57. package/dist/components/combobox/Combobox.js +3 -1
  58. package/dist/components/combobox/Combobox.js.map +2 -2
  59. package/dist/components/combobox.css +5 -1
  60. package/dist/components/command/Command.cjs +1 -1
  61. package/dist/components/command/Command.cjs.map +2 -2
  62. package/dist/components/command/Command.js +1 -1
  63. package/dist/components/command/Command.js.map +2 -2
  64. package/dist/components/context-menu.css +1 -1
  65. package/dist/components/copy-field.css +18 -0
  66. package/dist/components/copyField/CopyField.cjs +3 -3
  67. package/dist/components/copyField/CopyField.cjs.map +2 -2
  68. package/dist/components/copyField/CopyField.d.cts.map +1 -1
  69. package/dist/components/copyField/CopyField.d.mts.map +1 -1
  70. package/dist/components/copyField/CopyField.d.ts.map +1 -1
  71. package/dist/components/copyField/CopyField.js +3 -3
  72. package/dist/components/copyField/CopyField.js.map +2 -2
  73. package/dist/components/data-list.css +19 -4
  74. package/dist/components/data-table.css +190 -0
  75. package/dist/components/dataTable/DataTable.cjs +193 -68
  76. package/dist/components/dataTable/DataTable.cjs.map +3 -3
  77. package/dist/components/dataTable/DataTable.d.cts +29 -1
  78. package/dist/components/dataTable/DataTable.d.cts.map +1 -1
  79. package/dist/components/dataTable/DataTable.d.mts +29 -1
  80. package/dist/components/dataTable/DataTable.d.mts.map +1 -1
  81. package/dist/components/dataTable/DataTable.d.ts +29 -1
  82. package/dist/components/dataTable/DataTable.d.ts.map +1 -1
  83. package/dist/components/dataTable/DataTable.js +193 -68
  84. package/dist/components/dataTable/DataTable.js.map +2 -2
  85. package/dist/components/dataTable/DataTableContext.cjs +41 -0
  86. package/dist/components/dataTable/DataTableContext.cjs.map +7 -0
  87. package/dist/components/dataTable/DataTableContext.d.cts +23 -0
  88. package/dist/components/dataTable/DataTableContext.d.cts.map +1 -0
  89. package/dist/components/dataTable/DataTableContext.d.mts +23 -0
  90. package/dist/components/dataTable/DataTableContext.d.mts.map +1 -0
  91. package/dist/components/dataTable/DataTableContext.d.ts +23 -0
  92. package/dist/components/dataTable/DataTableContext.d.ts.map +1 -0
  93. package/dist/components/dataTable/DataTableContext.js +11 -0
  94. package/dist/components/dataTable/DataTableContext.js.map +7 -0
  95. package/dist/components/dataTable/DataTablePagination.cjs +72 -47
  96. package/dist/components/dataTable/DataTablePagination.cjs.map +2 -2
  97. package/dist/components/dataTable/DataTablePagination.d.cts +5 -1
  98. package/dist/components/dataTable/DataTablePagination.d.cts.map +1 -1
  99. package/dist/components/dataTable/DataTablePagination.d.mts +5 -1
  100. package/dist/components/dataTable/DataTablePagination.d.mts.map +1 -1
  101. package/dist/components/dataTable/DataTablePagination.d.ts +5 -1
  102. package/dist/components/dataTable/DataTablePagination.d.ts.map +1 -1
  103. package/dist/components/dataTable/DataTablePagination.js +75 -47
  104. package/dist/components/dataTable/DataTablePagination.js.map +2 -2
  105. package/dist/components/dataTable/DataTableToolbar.cjs +122 -93
  106. package/dist/components/dataTable/DataTableToolbar.cjs.map +2 -2
  107. package/dist/components/dataTable/DataTableToolbar.d.cts +6 -5
  108. package/dist/components/dataTable/DataTableToolbar.d.cts.map +1 -1
  109. package/dist/components/dataTable/DataTableToolbar.d.mts +6 -5
  110. package/dist/components/dataTable/DataTableToolbar.d.mts.map +1 -1
  111. package/dist/components/dataTable/DataTableToolbar.d.ts +6 -5
  112. package/dist/components/dataTable/DataTableToolbar.d.ts.map +1 -1
  113. package/dist/components/dataTable/DataTableToolbar.js +123 -94
  114. package/dist/components/dataTable/DataTableToolbar.js.map +2 -2
  115. package/dist/components/dataTable/dataTable.export.cjs +83 -0
  116. package/dist/components/dataTable/dataTable.export.cjs.map +7 -0
  117. package/dist/components/dataTable/dataTable.export.d.cts +11 -0
  118. package/dist/components/dataTable/dataTable.export.d.cts.map +1 -0
  119. package/dist/components/dataTable/dataTable.export.d.mts +11 -0
  120. package/dist/components/dataTable/dataTable.export.d.mts.map +1 -0
  121. package/dist/components/dataTable/dataTable.export.d.ts +11 -0
  122. package/dist/components/dataTable/dataTable.export.d.ts.map +1 -0
  123. package/dist/components/dataTable/dataTable.export.js +63 -0
  124. package/dist/components/dataTable/dataTable.export.js.map +7 -0
  125. package/dist/components/dataTable/dataTable.props.cjs +23 -1
  126. package/dist/components/dataTable/dataTable.props.cjs.map +2 -2
  127. package/dist/components/dataTable/dataTable.props.d.cts +21 -1
  128. package/dist/components/dataTable/dataTable.props.d.cts.map +1 -1
  129. package/dist/components/dataTable/dataTable.props.d.mts +21 -1
  130. package/dist/components/dataTable/dataTable.props.d.mts.map +1 -1
  131. package/dist/components/dataTable/dataTable.props.d.ts +21 -1
  132. package/dist/components/dataTable/dataTable.props.d.ts.map +1 -1
  133. package/dist/components/dataTable/dataTable.props.js +23 -1
  134. package/dist/components/dataTable/dataTable.props.js.map +2 -2
  135. package/dist/components/dialog/Dialog.cjs +2 -1
  136. package/dist/components/dialog/Dialog.cjs.map +2 -2
  137. package/dist/components/dialog/Dialog.d.cts.map +1 -1
  138. package/dist/components/dialog/Dialog.d.mts.map +1 -1
  139. package/dist/components/dialog/Dialog.d.ts.map +1 -1
  140. package/dist/components/dialog/Dialog.js +2 -1
  141. package/dist/components/dialog/Dialog.js.map +2 -2
  142. package/dist/components/dropdown-menu.css +1 -1
  143. package/dist/components/empty-state.css +5 -0
  144. package/dist/components/fileUpload/FileUpload.cjs +10 -1
  145. package/dist/components/fileUpload/FileUpload.cjs.map +2 -2
  146. package/dist/components/fileUpload/FileUpload.d.cts +1 -0
  147. package/dist/components/fileUpload/FileUpload.d.cts.map +1 -1
  148. package/dist/components/fileUpload/FileUpload.d.mts +1 -0
  149. package/dist/components/fileUpload/FileUpload.d.mts.map +1 -1
  150. package/dist/components/fileUpload/FileUpload.d.ts +1 -0
  151. package/dist/components/fileUpload/FileUpload.d.ts.map +1 -1
  152. package/dist/components/fileUpload/FileUpload.js +10 -1
  153. package/dist/components/fileUpload/FileUpload.js.map +2 -2
  154. package/dist/components/filter-bar.css +380 -8
  155. package/dist/components/filterBar/FilterBar.cjs +630 -1
  156. package/dist/components/filterBar/FilterBar.cjs.map +2 -2
  157. package/dist/components/filterBar/FilterBar.d.cts +132 -2
  158. package/dist/components/filterBar/FilterBar.d.cts.map +1 -1
  159. package/dist/components/filterBar/FilterBar.d.mts +132 -2
  160. package/dist/components/filterBar/FilterBar.d.mts.map +1 -1
  161. package/dist/components/filterBar/FilterBar.d.ts +132 -2
  162. package/dist/components/filterBar/FilterBar.d.ts.map +1 -1
  163. package/dist/components/filterBar/FilterBar.js +631 -2
  164. package/dist/components/filterBar/FilterBar.js.map +2 -2
  165. package/dist/components/floating-panel.css +1 -1
  166. package/dist/components/fontProvider/FontProvider.cjs +1 -1
  167. package/dist/components/fontProvider/FontProvider.cjs.map +1 -1
  168. package/dist/components/fontProvider/FontProvider.js +1 -1
  169. package/dist/components/fontProvider/FontProvider.js.map +1 -1
  170. package/dist/components/icon/Icon.cjs +25 -2
  171. package/dist/components/icon/Icon.cjs.map +2 -2
  172. package/dist/components/icon/Icon.d.cts +29 -1
  173. package/dist/components/icon/Icon.d.cts.map +1 -1
  174. package/dist/components/icon/Icon.d.mts +29 -1
  175. package/dist/components/icon/Icon.d.mts.map +1 -1
  176. package/dist/components/icon/Icon.d.ts +29 -1
  177. package/dist/components/icon/Icon.d.ts.map +1 -1
  178. package/dist/components/icon/Icon.js +33 -2
  179. package/dist/components/icon/Icon.js.map +2 -2
  180. package/dist/components/icon/icons.cjs +16 -0
  181. package/dist/components/icon/icons.cjs.map +2 -2
  182. package/dist/components/icon/icons.d.cts +40 -0
  183. package/dist/components/icon/icons.d.cts.map +1 -1
  184. package/dist/components/icon/icons.d.mts +40 -0
  185. package/dist/components/icon/icons.d.mts.map +1 -1
  186. package/dist/components/icon/icons.d.ts +40 -0
  187. package/dist/components/icon/icons.d.ts.map +1 -1
  188. package/dist/components/icon/icons.js +16 -0
  189. package/dist/components/icon/icons.js.map +2 -2
  190. package/dist/components/icon-button.css +29 -0
  191. package/dist/components/index.cjs +1 -1
  192. package/dist/components/index.cjs.map +2 -2
  193. package/dist/components/index.d.cts +1 -1
  194. package/dist/components/index.d.cts.map +1 -1
  195. package/dist/components/index.d.mts +1 -1
  196. package/dist/components/index.d.mts.map +1 -1
  197. package/dist/components/index.d.ts +1 -1
  198. package/dist/components/index.d.ts.map +1 -1
  199. package/dist/components/index.js +1 -1
  200. package/dist/components/index.js.map +1 -1
  201. package/dist/components/item/Item.cjs +1 -1
  202. package/dist/components/item/Item.cjs.map +2 -2
  203. package/dist/components/item/Item.js +1 -1
  204. package/dist/components/item/Item.js.map +2 -2
  205. package/dist/components/item.css +12 -1
  206. package/dist/components/marquee/Marquee.cjs +1 -1
  207. package/dist/components/marquee/Marquee.cjs.map +2 -2
  208. package/dist/components/marquee/Marquee.js +1 -1
  209. package/dist/components/marquee/Marquee.js.map +2 -2
  210. package/dist/components/marquee.css +6 -0
  211. package/dist/components/menu/Menu.cjs +3 -1
  212. package/dist/components/menu/Menu.cjs.map +2 -2
  213. package/dist/components/menu/Menu.d.cts.map +1 -1
  214. package/dist/components/menu/Menu.d.mts.map +1 -1
  215. package/dist/components/menu/Menu.d.ts.map +1 -1
  216. package/dist/components/menu/Menu.js +3 -1
  217. package/dist/components/menu/Menu.js.map +2 -2
  218. package/dist/components/menubar.css +1 -1
  219. package/dist/components/metric.css +5 -0
  220. package/dist/components/pagination/Pagination.cjs +143 -17
  221. package/dist/components/pagination/Pagination.cjs.map +2 -2
  222. package/dist/components/pagination/Pagination.d.cts +64 -4
  223. package/dist/components/pagination/Pagination.d.cts.map +1 -1
  224. package/dist/components/pagination/Pagination.d.mts +64 -4
  225. package/dist/components/pagination/Pagination.d.mts.map +1 -1
  226. package/dist/components/pagination/Pagination.d.ts +64 -4
  227. package/dist/components/pagination/Pagination.d.ts.map +1 -1
  228. package/dist/components/pagination/Pagination.js +143 -17
  229. package/dist/components/pagination/Pagination.js.map +2 -2
  230. package/dist/components/pagination.css +50 -8
  231. package/dist/components/phoneInput/PhoneInput.cjs +18 -13
  232. package/dist/components/phoneInput/PhoneInput.cjs.map +2 -2
  233. package/dist/components/phoneInput/PhoneInput.d.cts.map +1 -1
  234. package/dist/components/phoneInput/PhoneInput.d.mts.map +1 -1
  235. package/dist/components/phoneInput/PhoneInput.d.ts.map +1 -1
  236. package/dist/components/phoneInput/PhoneInput.js +19 -14
  237. package/dist/components/phoneInput/PhoneInput.js.map +2 -2
  238. package/dist/components/popover/Popover.cjs +2 -1
  239. package/dist/components/popover/Popover.cjs.map +2 -2
  240. package/dist/components/popover/Popover.d.cts.map +1 -1
  241. package/dist/components/popover/Popover.d.mts.map +1 -1
  242. package/dist/components/popover/Popover.d.ts.map +1 -1
  243. package/dist/components/popover/Popover.js +2 -1
  244. package/dist/components/popover/Popover.js.map +2 -2
  245. package/dist/components/prose.css +1 -1
  246. package/dist/components/qr-code.css +5 -15
  247. package/dist/components/radio-group.css +19 -0
  248. package/dist/components/radioGroup/RadioGroup.cjs +3 -2
  249. package/dist/components/radioGroup/RadioGroup.cjs.map +2 -2
  250. package/dist/components/radioGroup/RadioGroup.d.cts.map +1 -1
  251. package/dist/components/radioGroup/RadioGroup.d.mts.map +1 -1
  252. package/dist/components/radioGroup/RadioGroup.d.ts.map +1 -1
  253. package/dist/components/radioGroup/RadioGroup.js +3 -2
  254. package/dist/components/radioGroup/RadioGroup.js.map +2 -2
  255. package/dist/components/radioGroup/radioGroup.props.cjs +1 -1
  256. package/dist/components/radioGroup/radioGroup.props.cjs.map +2 -2
  257. package/dist/components/radioGroup/radioGroup.props.d.cts +1 -1
  258. package/dist/components/radioGroup/radioGroup.props.d.mts +1 -1
  259. package/dist/components/radioGroup/radioGroup.props.d.ts +1 -1
  260. package/dist/components/radioGroup/radioGroup.props.js +1 -1
  261. package/dist/components/radioGroup/radioGroup.props.js.map +2 -2
  262. package/dist/components/rating.css +12 -0
  263. package/dist/components/result.css +2 -1
  264. package/dist/components/richTextEditor/RichTextEditor.cjs +11 -3
  265. package/dist/components/richTextEditor/RichTextEditor.cjs.map +2 -2
  266. package/dist/components/richTextEditor/RichTextEditor.d.cts.map +1 -1
  267. package/dist/components/richTextEditor/RichTextEditor.d.mts.map +1 -1
  268. package/dist/components/richTextEditor/RichTextEditor.d.ts.map +1 -1
  269. package/dist/components/richTextEditor/RichTextEditor.js +11 -3
  270. package/dist/components/richTextEditor/RichTextEditor.js.map +2 -2
  271. package/dist/components/segmented-control.css +80 -4
  272. package/dist/components/segmentedControl/SegmentedControl.cjs +18 -5
  273. package/dist/components/segmentedControl/SegmentedControl.cjs.map +2 -2
  274. package/dist/components/segmentedControl/SegmentedControl.d.cts.map +1 -1
  275. package/dist/components/segmentedControl/SegmentedControl.d.mts.map +1 -1
  276. package/dist/components/segmentedControl/SegmentedControl.d.ts.map +1 -1
  277. package/dist/components/segmentedControl/SegmentedControl.js +18 -5
  278. package/dist/components/segmentedControl/SegmentedControl.js.map +2 -2
  279. package/dist/components/segmentedControl/segmentedControl.props.cjs +10 -0
  280. package/dist/components/segmentedControl/segmentedControl.props.cjs.map +2 -2
  281. package/dist/components/segmentedControl/segmentedControl.props.d.cts +9 -0
  282. package/dist/components/segmentedControl/segmentedControl.props.d.cts.map +1 -1
  283. package/dist/components/segmentedControl/segmentedControl.props.d.mts +9 -0
  284. package/dist/components/segmentedControl/segmentedControl.props.d.mts.map +1 -1
  285. package/dist/components/segmentedControl/segmentedControl.props.d.ts +9 -0
  286. package/dist/components/segmentedControl/segmentedControl.props.d.ts.map +1 -1
  287. package/dist/components/segmentedControl/segmentedControl.props.js +10 -0
  288. package/dist/components/segmentedControl/segmentedControl.props.js.map +2 -2
  289. package/dist/components/select/Select.cjs +3 -1
  290. package/dist/components/select/Select.cjs.map +2 -2
  291. package/dist/components/select/Select.d.cts.map +1 -1
  292. package/dist/components/select/Select.d.mts.map +1 -1
  293. package/dist/components/select/Select.d.ts.map +1 -1
  294. package/dist/components/select/Select.js +3 -1
  295. package/dist/components/select/Select.js.map +2 -2
  296. package/dist/components/select.css +1 -1
  297. package/dist/components/sonner.css +1 -1
  298. package/dist/components/sortableList/SortableList.cjs +8 -2
  299. package/dist/components/sortableList/SortableList.cjs.map +2 -2
  300. package/dist/components/sortableList/SortableList.d.cts.map +1 -1
  301. package/dist/components/sortableList/SortableList.d.mts.map +1 -1
  302. package/dist/components/sortableList/SortableList.d.ts.map +1 -1
  303. package/dist/components/sortableList/SortableList.js +8 -2
  304. package/dist/components/sortableList/SortableList.js.map +2 -2
  305. package/dist/components/stat-card.css +2 -0
  306. package/dist/components/table/Table.cjs +3 -2
  307. package/dist/components/table/Table.cjs.map +2 -2
  308. package/dist/components/table/Table.d.cts.map +1 -1
  309. package/dist/components/table/Table.d.mts.map +1 -1
  310. package/dist/components/table/Table.d.ts.map +1 -1
  311. package/dist/components/table/Table.js +3 -2
  312. package/dist/components/table/Table.js.map +2 -2
  313. package/dist/components/table/table.props.cjs +6 -0
  314. package/dist/components/table/table.props.cjs.map +2 -2
  315. package/dist/components/table/table.props.d.cts +5 -0
  316. package/dist/components/table/table.props.d.cts.map +1 -1
  317. package/dist/components/table/table.props.d.mts +5 -0
  318. package/dist/components/table/table.props.d.mts.map +1 -1
  319. package/dist/components/table/table.props.d.ts +5 -0
  320. package/dist/components/table/table.props.d.ts.map +1 -1
  321. package/dist/components/table/table.props.js +6 -0
  322. package/dist/components/table/table.props.js.map +2 -2
  323. package/dist/components/table.css +20 -13
  324. package/dist/components/tabs.css +10 -0
  325. package/dist/components/timeline.css +54 -18
  326. package/dist/components/toast.css +33 -1
  327. package/dist/components/toggle-group.css +5 -0
  328. package/dist/components.css +1 -2
  329. package/dist/docs/README.md +1 -1
  330. package/dist/docs/component-contract.md +4 -4
  331. package/dist/docs/component-index.json +9 -9
  332. package/dist/docs/components/banner.md +152 -0
  333. package/dist/docs/components/button-group.md +4 -3
  334. package/dist/docs/components/button.md +2 -2
  335. package/dist/docs/components/card.md +1 -0
  336. package/dist/docs/components/carousel.md +55 -32
  337. package/dist/docs/components/chart.md +25 -7
  338. package/dist/docs/components/checkbox.md +4 -0
  339. package/dist/docs/components/combobox.md +3 -1
  340. package/dist/docs/components/command.md +2 -2
  341. package/dist/docs/components/copy-field.md +2 -2
  342. package/dist/docs/components/data-list.md +15 -3
  343. package/dist/docs/components/data-table.md +98 -17
  344. package/dist/docs/components/dialog.md +4 -0
  345. package/dist/docs/components/dropdown-menu.md +2 -1
  346. package/dist/docs/components/empty-state.md +3 -1
  347. package/dist/docs/components/file-upload.md +1 -0
  348. package/dist/docs/components/filter-bar.md +193 -8
  349. package/dist/docs/components/floating-panel.md +8 -8
  350. package/dist/docs/components/icon-button.md +4 -1
  351. package/dist/docs/components/item.md +18 -13
  352. package/dist/docs/components/marquee.md +2 -2
  353. package/dist/docs/components/menu.md +4 -1
  354. package/dist/docs/components/metric.md +4 -1
  355. package/dist/docs/components/pagination.md +88 -17
  356. package/dist/docs/components/pills.md +1 -1
  357. package/dist/docs/components/popover.md +2 -0
  358. package/dist/docs/components/prose.md +5 -1
  359. package/dist/docs/components/qr-code.md +14 -13
  360. package/dist/docs/components/radio-group.md +5 -2
  361. package/dist/docs/components/rating.md +2 -0
  362. package/dist/docs/components/result.md +6 -0
  363. package/dist/docs/components/segmented-control.md +7 -2
  364. package/dist/docs/components/select.md +3 -2
  365. package/dist/docs/components/sidebar.md +3 -1
  366. package/dist/docs/components/sonner.md +1 -1
  367. package/dist/docs/components/sortable-list.md +2 -0
  368. package/dist/docs/components/stat-card.md +5 -4
  369. package/dist/docs/components/stepper.md +1 -0
  370. package/dist/docs/components/table.md +14 -5
  371. package/dist/docs/components/tag.md +4 -2
  372. package/dist/docs/components/timeline.md +9 -5
  373. package/dist/docs/components/toast.md +1 -1
  374. package/dist/docs/components/toggle-group.md +2 -1
  375. package/dist/fonts.css +1 -1
  376. package/dist/generated/tokens.cjs +1 -1
  377. package/dist/generated/tokens.cjs.map +1 -1
  378. package/dist/generated/tokens.js +1 -1
  379. package/dist/generated/tokens.js.map +1 -1
  380. package/dist/motion.css +18 -3
  381. package/dist/styles.css +1249 -292
  382. package/dist/tokens.css +21 -15
  383. package/package.json +1 -1
  384. package/dist/components/control-group.css +0 -142
  385. package/dist/components/controlGroup/ControlGroup.cjs.map +0 -7
  386. package/dist/components/controlGroup/ControlGroup.d.cts +0 -16
  387. package/dist/components/controlGroup/ControlGroup.d.cts.map +0 -1
  388. package/dist/components/controlGroup/ControlGroup.d.mts +0 -16
  389. package/dist/components/controlGroup/ControlGroup.d.mts.map +0 -1
  390. package/dist/components/controlGroup/ControlGroup.d.ts +0 -16
  391. package/dist/components/controlGroup/ControlGroup.d.ts.map +0 -1
  392. package/dist/components/controlGroup/ControlGroup.js +0 -26
  393. package/dist/components/controlGroup/ControlGroup.js.map +0 -7
  394. package/dist/components/controlGroup/controlGroup.props.cjs.map +0 -7
  395. package/dist/components/controlGroup/controlGroup.props.d.cts +0 -18
  396. package/dist/components/controlGroup/controlGroup.props.d.cts.map +0 -1
  397. package/dist/components/controlGroup/controlGroup.props.d.mts +0 -18
  398. package/dist/components/controlGroup/controlGroup.props.d.mts.map +0 -1
  399. package/dist/components/controlGroup/controlGroup.props.d.ts +0 -18
  400. package/dist/components/controlGroup/controlGroup.props.d.ts.map +0 -1
  401. package/dist/components/controlGroup/controlGroup.props.js +0 -20
  402. package/dist/components/controlGroup/controlGroup.props.js.map +0 -7
  403. package/dist/docs/components/control-group.md +0 -261
@@ -146,8 +146,8 @@ Every CSS value the component paints is a `var(--dsx-*)` token.
146
146
  | Shell radius | `var(--dsx-rounded-xl)` | Panel corner radius. |
147
147
  | Shell border | `var(--dsx-border-width-sm)` + `var(--dsx-color-outline)` | Panel edge. |
148
148
  | Shell fill | `var(--dsx-color-panel-translucent)` | Panel surface. |
149
- | Shell shadow (rest) | `var(--dsx-shadow-md)` | Resting elevation. |
150
- | Shell shadow (dragging) | `var(--dsx-shadow-xl)` | Active elevation. |
149
+ | Shell shadow (rest) | `var(--dsx-shadow-elevation-2)` | Resting elevation. |
150
+ | Shell shadow (dragging) | `var(--dsx-shadow-elevation-5)` | Active elevation. |
151
151
  | Shell overflow | `hidden` (raw) | Contain children. |
152
152
  | Shell z-index | `var(--dsx-z-index-overlay-local)` | Above page content. |
153
153
  | Header padding | `var(--dsx-space-sm)` block, `var(--dsx-space-md)` inline | Inner gutter. |
@@ -341,8 +341,8 @@ The package does not yet publish a Penpot asset for FloatingPanel. Recipe is vis
341
341
  | Shell | fill | `--dsx-color-panel-translucent` | Color | `fills` |
342
342
  | Shell | stroke | `--dsx-color-outline` | Color | `strokes` |
343
343
  | Shell | radius | `--dsx-rounded-xl` | Radius | `radius` |
344
- | Shell | shadow | `--dsx-shadow-md` | Effect | `shadow` |
345
- | Shell (dragging) | shadow | `--dsx-shadow-xl` | Effect | `shadow` (state) |
344
+ | Shell | shadow | `--dsx-shadow-elevation-2` | Effect | `shadow` |
345
+ | Shell (dragging) | shadow | `--dsx-shadow-elevation-5` | Effect | `shadow` (state) |
346
346
  | Header | fill | `--dsx-color-surface-raised` | Color | `fills` |
347
347
  | Header | stroke | `--dsx-color-outline-variant` | Color | `strokes` |
348
348
  | Content | padding | `--dsx-space-md` | Spacing | `padding` |
@@ -356,10 +356,10 @@ The package does not yet publish a Penpot asset for FloatingPanel. Recipe is vis
356
356
 
357
357
  | State | Shell shadow | Header cursor | Close fill | Handle opacity |
358
358
  |---|---|---|---|---|
359
- | `default` | `--dsx-shadow-md` | `grab` | `transparent` | `--dsx-opacity-muted` |
360
- | `dragging` | `--dsx-shadow-xl` | `grabbing` | `transparent` | `1` |
361
- | `close-hover` | `--dsx-shadow-md` | `grab` | `--dsx-effect-hover-layer` | `--dsx-opacity-muted` |
362
- | `handle-hover` | `--dsx-shadow-md` | `grab` | `transparent` | `1` |
359
+ | `default` | `--dsx-shadow-elevation-2` | `grab` | `transparent` | `--dsx-opacity-muted` |
360
+ | `dragging` | `--dsx-shadow-elevation-5` | `grabbing` | `transparent` | `1` |
361
+ | `close-hover` | `--dsx-shadow-elevation-2` | `grab` | `--dsx-effect-hover-layer` | `--dsx-opacity-muted` |
362
+ | `handle-hover` | `--dsx-shadow-elevation-2` | `grab` | `transparent` | `1` |
363
363
 
364
364
  ### Variant model
365
365
 
@@ -64,7 +64,7 @@ Rules:
64
64
  | `data-high-contrast` | `true` | `.dsx-icon-button:where([data-variant='outline'])[data-high-contrast='true']` etc. (variant-specific HC overrides) | `icon-button.css` |
65
65
  | `data-loading` | `true` | `.dsx-icon-button[data-loading='true']` | `icon-button.css` |
66
66
  | `data-disabled` | `true` | `.dsx-icon-button[data-disabled='true']` | `icon-button.css` |
67
- | `aria-pressed` | `true` | n/a (CSS does not target this attribute) | n/a |
67
+ | `aria-pressed` | `true` | pressed overlay for `primary`/`secondary` (same layers as Button) | n/a |
68
68
 
69
69
  **Internal classes** (implementation detail, not public slots):
70
70
 
@@ -127,6 +127,9 @@ Every CSS value the component paints is a `var(--dsx-*)` token.
127
127
  | Text (destructive) | `var(--dsx-color-on-error)` | Destructive icon. |
128
128
  | Border (destructive) | `var(--dsx-color-error)` | Destructive edge. |
129
129
  | Background (destructive hover) | `linear-gradient(var(--dsx-effect-hover-secondary), var(--dsx-effect-hover-secondary)), var(--dsx-color-error)` | Destructive hover overlay. |
130
+ | Background (primary pressed) | `linear-gradient(var(--dsx-effect-pressed-primary), var(--dsx-effect-pressed-primary)), var(--dsx-color-accent-track)` | Primary pressed overlay (Button parity). |
131
+ | Background (secondary pressed) | `linear-gradient(var(--dsx-effect-pressed-layer), var(--dsx-effect-pressed-layer)), var(--dsx-color-secondary)` | Secondary pressed overlay (Button parity). |
132
+ | Box shadow (halo) | `var(--dsx-shadow-accent-ring)` | Resting halo on every variant (`data-halo`), locked 2026-09-22 — same model as Button. |
130
133
  | Background (destructive HC) | `var(--dsx-color-error)` | High-contrast destructive fill. |
131
134
  | Border (destructive HC) | `var(--dsx-color-high-contrast-border)` | High-contrast destructive edge. |
132
135
  | Focus ring | `var(--dsx-shadow-focus-ring)` | Visible focus ring on `:focus-visible`. |
@@ -25,7 +25,7 @@ A generic list-row surface for settings, notifications, or selectable summaries.
25
25
 
26
26
  | Slot | Element | Renders | Notes |
27
27
  |---|---|---|---|
28
- | `Item` (root) | `<div>` (or `Slot` host) | Root + class | The row surface. Writes `dsx-item`, `data-variant`, `data-size`, and (when `interactive={true}`) `data-interactive="true"`. |
28
+ | `Item` (root) | `<div>` (or `Slot` host) | Root + class | The row surface. Writes `dsx-item`, a size modifier, a non-default variant modifier, and (when `interactive={true}`) `data-interactive="true"`. |
29
29
  | `Item.Media` | `<div>` (or `Slot` host) | Slot class | Leading visual slot (icon, avatar, image). Writes `dsx-item__media`. |
30
30
  | `Item.Content` | `<div>` (or `Slot` host) | Slot class | Text + metadata wrapper. Writes `dsx-item__content`. |
31
31
  | `Item.Title` | `<h4>` (or `Slot` host) | Slot class | Row title. Writes `dsx-item__title`. |
@@ -40,8 +40,8 @@ The root is a flex row with `gap: var(--dsx-space-md)`. `Item.Media`, `Item.Cont
40
40
 
41
41
  | Prop | Type | Default | Required | Description | Responsive |
42
42
  |---|---|---|---|---|---|
43
- | `variant` | `'default' \| 'outline' \| 'muted'` | `'default'` | no | Surface treatment; writes `data-variant`. | no |
44
- | `size` | `'xs' \| 'sm' \| 'md' \| 'lg'` | `'md'` | no | Minimum height; writes `data-size`. `xs` and `sm` are row-density; `md` and `lg` are content-density. | no |
43
+ | `variant` | `'default' \| 'outline' \| 'muted'` | `'default'` | no | Surface treatment through modifier classes. | no |
44
+ | `size` | `'xs' \| 'sm' \| 'md' \| 'lg'` | `'md'` | no | Minimum height and vertical padding through modifier classes. Padding increases from space-xs to space-sm, space-md, and space-lg. | no |
45
45
  | `interactive` | `boolean` | `false` | no | When `true`, adds `cursor: pointer` to the root; writes `data-interactive="true"`. The component does not add hover or focus styles; consumers that want a fully interactive row should wrap with their own Button or `asChild` onto a button. | no |
46
46
  | `asChild` | `boolean` | `false` | no | Renders the root through `Slot`; consumer supplies the host element. | no |
47
47
  | `className` | `string` | `undefined` | no | Extra classes appended to `dsx-item`. | no |
@@ -57,19 +57,19 @@ Each slot also accepts the standard HTML attributes for its host element.
57
57
 
58
58
  Rules:
59
59
 
60
- - The component does not emit `data-radius`, `data-accent-color`, or `data-high-contrast`. The contract calls for `data-variant`, `data-size`, and `data-interactive` only.
61
- - `data-interactive` is emitted only when `interactive={true}`. The CSS does not currently hook it, but the prop is part of the public contract.
60
+ - The component does not emit `data-radius`, `data-accent-color`, or `data-high-contrast`. Variant and size use classes; `data-interactive` is the only owned state attribute.
61
+ - `data-interactive` is emitted only when `interactive={true}`. The CSS hooks it to apply the pointer cursor.
62
62
 
63
63
  ## CSS class contract
64
64
 
65
65
  **Root class:** `dsx-item`
66
66
 
67
- **Modifier classes** (driven by `data-*` attributes written by the component):
67
+ **Modifier classes** (written directly by the component):
68
68
 
69
- | Attribute | Allowed values | Class | CSS file |
69
+ | Prop | Allowed values | Class | CSS file |
70
70
  |---|---|---|---|
71
- | `data-variant` | `default`, `outline`, `muted` | `.dsx-item[data-variant='outline']`, `.dsx-item[data-variant='muted']` | `item.css` |
72
- | `data-size` | `xs`, `sm`, `md`, `lg` | `.dsx-item[data-size='xs']`, `.dsx-item[data-size='sm']`, `.dsx-item[data-size='md']`, `.dsx-item[data-size='lg']` | `item.css` |
71
+ | `variant` | `default`, `outline`, `muted` | `.dsx-item--outline`, `.dsx-item--muted` | `item.css` |
72
+ | `size` | `xs`, `sm`, `md`, `lg` | `.dsx-item--xs`, `.dsx-item--sm`, `.dsx-item--md`, `.dsx-item--lg` | `item.css` |
73
73
  | `data-interactive` | `true` | `.dsx-item[data-interactive='true']` | `item.css` |
74
74
 
75
75
  **Slot classes:**
@@ -87,6 +87,8 @@ Rules:
87
87
 
88
88
  - The component does not write `@media` rules. `size` and `variant` are single-value only.
89
89
 
90
+ - Content can shrink and long labels wrap. Root and trailing actions wrap intrinsically when their combined width exceeds the row, keeping commands reachable without a breakpoint.
91
+
90
92
  **Reduced motion:**
91
93
 
92
94
  - The component is static. No motion is applied.
@@ -109,7 +111,8 @@ Every CSS value the component paints is a `var(--dsx-*)` token.
109
111
  | Interactive cursor | `pointer` | Pointer cursor when `interactive={true}` |
110
112
  | Min-height (xs) | `var(--dsx-size-lg)` | xs row min-height |
111
113
  | Min-height (sm) | `var(--dsx-size-xl)` | sm row min-height |
112
- | Min-height (md, lg) | `var(--dsx-size-2xl)` | md/lg row min-height |
114
+ | Min-height (md) | `var(--dsx-size-2xl)` | md row min-height |
115
+ | Min-height (lg) | `var(--dsx-size-3xl)` | lg row min-height |
113
116
  | Media dimensions | `var(--dsx-size-xl)` | Media slot dimensions |
114
117
  | Content display | `grid` | Title + description layout |
115
118
  | Content gap | `var(--dsx-space-xs)` | Space between Title and Description |
@@ -161,11 +164,11 @@ The component is static.
161
164
 
162
165
  **Variant story:**
163
166
 
164
- - Renders three items with `variant="default"`, `variant="outline"`, and `variant="muted"`. Asserts the matching `data-variant` attribute.
167
+ - Renders three items with `variant="default"`, `variant="outline"`, and `variant="muted"`. Asserts the matching non-default variant class.
165
168
 
166
169
  **Size story:**
167
170
 
168
- - Renders four items with `size="xs"`, `size="sm"`, `size="md"`, and `size="lg"`. Asserts the matching `data-size` attribute.
171
+ - Renders four items with `size="xs"`, `size="sm"`, `size="md"`, and `size="lg"`. Asserts the matching size class and measures distinct rendered heights for identical content.
169
172
 
170
173
  **State story:**
171
174
 
@@ -207,10 +210,12 @@ The component is static.
207
210
 
208
211
  **State boundaries:**
209
212
 
210
- - Owned by Item: the `data-variant`, `data-size`, and `data-interactive` attributes, the flex row layout, and the `dsx-item__*` slot classes.
213
+ - Owned by Item: the variant/size classes and `data-interactive` attribute, the flex row layout, and the `dsx-item__*` slot classes.
211
214
  - Owned by the consumer: the row content, the interactive behavior, the surrounding list semantics, and the heading level on `Item.Title`.
212
215
 
213
216
  **Boundary rules:**
214
217
 
215
218
  - App-owned data: the row content, the action handlers, the selection state, and the surrounding list semantics.
216
219
  - DS-owned visuals: token bindings, slot classes, variant surfaces, and the size min-height.
220
+
221
+ The playground size comparison uses identical content and aligns row starts, avoiding flex stretch that would make all sizes inherit the largest sibling height. Both the variant gallery and the live example show the density scale.
@@ -24,7 +24,7 @@ A horizontally scrolling content strip that animates a duplicated child track ac
24
24
  |---|---|---|---|
25
25
  | `Marquee` (root) | `<div>` | DS primitive + class | Wrapper that owns the `--dsx-marquee-duration`, `--dsx-marquee-direction`, and `--dsx-marquee-edge-fade-width` CSS variables plus the `data-pause-on-hover` and optional `data-edge-fade` attributes. |
26
26
  | internal track | `<div class="dsx-marquee__track">` | internal layout | Flex row that runs the `dsx-marquee-scroll` keyframe. |
27
- | internal content (x2) | `<div class="dsx-marquee__content">` | internal layout | The original `children` and an `aria-hidden="true"` clone. The duplication is what makes the loop seamless. |
27
+ | internal content (x2) | `<div class="dsx-marquee__content">` | internal layout | The original `children` and an `aria-hidden="true"`, inert clone. The duplication is what makes the loop seamless. |
28
28
 
29
29
  The track and content nodes are internal layout, not public slots. The two `dsx-marquee__content` rows are siblings inside the track.
30
30
 
@@ -130,7 +130,7 @@ Rules:
130
130
 
131
131
  **Focus:**
132
132
 
133
- - Focusable children inside the strip remain focusable. The scroll animation does not move focus. The edge mask clears on `:focus-within` so focus indicators are not clipped. Consumers that include interactive children should ensure those children are not announced twice; the `aria-hidden="true"` clone handles the announcement side.
133
+ - Focusable children inside the strip remain focusable. The scroll animation does not move focus. The edge mask clears on `:focus-within` so focus indicators are not clipped. Consumers that include interactive children should ensure those children are not announced twice; the duplicate is both `aria-hidden` and inert, so it cannot add duplicate keyboard stops. Focus within the original pauses animation regardless of `pauseOnHover`.
134
134
 
135
135
  **Reduced motion:**
136
136
 
@@ -166,7 +166,7 @@ Every CSS value the component paints is a `var(--dsx-*)` token, with three docum
166
166
  | Content transform origin | `var(--radix-dropdown-menu-content-transform-origin)` | Radix-provided anchor (not a token). |
167
167
  | Item gap | `var(--dsx-space-sm)` | Gap between item content. |
168
168
  | Item padding | `var(--dsx-space-xs) var(--dsx-space-sm)` | Inner gutter. |
169
- | Item radius | `var(--dsx-rounded-sm)` | Rounded highlight surface. |
169
+ | Item radius | `0` (square); menu first/last/only-child edge rules restore frame-concentric corners | Stacked items read as one joined block instead of floating pills — checked washes, hover washes, and focus rings share one flush geometry. |
170
170
  | Item typography | `var(--dsx-typography-body-medium-*` | Body ramp. |
171
171
  | Item color | `var(--dsx-color-on-surface)` | Resting text. |
172
172
  | Item highlight background | `var(--dsx-effect-hover-ghost)` | Hover / keyboard-focus highlight. |
@@ -175,6 +175,7 @@ Every CSS value the component paints is a `var(--dsx-*)` token, with three docum
175
175
  | Separator margin | `var(--dsx-space-xs)` calc(-1) | Inset margin. |
176
176
  | Separator background | `var(--dsx-color-outline-variant)` | Divider color. |
177
177
  | Overlay z-index | `calc(var(--dsx-z-index-dropdown) - 1)` | Just under the content. |
178
+ | Nested content z-index | `calc(var(--dsx-z-index-modal, 90) + 2)` | Menu-tier content nested inside a modal-tier host (carries `dsx-menu__nested`). |
178
179
  | Animation duration | `var(--dsx-motion-duration-fast)` | Open / close keyframes. |
179
180
  | Animation easing (in) | `var(--dsx-motion-easing-emphasized)` | Open easing. |
180
181
  | Animation easing (out) | `var(--dsx-motion-easing-in)` | Close easing. |
@@ -187,6 +188,7 @@ Rules:
187
188
  - `menu.css` no longer declares `background`, `border`, `border-radius`, `padding`, `min-width`, or `box-shadow` on `.dsx-menu`/`.dsx-menu__content`. Those properties are owned solely by the public surface CSS (`dropdown-menu.css`, `context-menu.css`, `menubar.css`), which already agreed on the same recipe (`--dsx-color-panel-translucent`, `--dsx-rounded-lg`, `--dsx-size-menu-min-width`, `--dsx-shadow-elevation-3`-via-`baseMenu.css`). Previously `menu.css` was imported last in `components.css` and, at equal selector specificity, silently overrode that recipe with a stale one (`surface-raised`, `rounded-md`, hard-coded `8rem`, `shadow-md`/elevation-2) for `DropdownMenu` and `ContextMenu` only — `Menubar` was unaffected because `MenubarContent` never carried the `dsx-menu` class, which is why the three surfaces looked subtly different despite sharing a spec.
188
189
  - The Radix CSS variables (`--radix-dropdown-menu-content-available-height`, `--radix-dropdown-menu-content-transform-origin`) are provided by Radix at runtime and are not design tokens. They are the boundary between the Radix positioning layer and the package's visual layer; the spec keeps them explicit so consumers do not treat them as themable.
189
190
  - Item hover, focus, selected, and disabled states that are shared across the menu family (DropdownMenu, ContextMenu, Menubar, NavigationMenu trigger/link/viewport) live in `_internal/baseMenu.css` rather than `menu.css`. The public menu surfaces import `baseMenu.css` to inherit those rules.
191
+ - **Nested floating tier (shared layering contract).** Menu-tier content (`Select`, `Combobox`, `DropdownMenu`/`ContextMenu`/`Menubar` via `MenuContent`) paints at the dropdown tier (50); modal-tier hosts (`Popover.Content` at `modal + 1`, `Dialog.Content` at `modal` — both body-portaled, with Radix copying the content `z-index` onto its wrapper) sit above it, so a menu opened inside one of those hosts paints behind its own host. Hosts provide `_internal/floatingLayer` `FloatingLayerHostContext` from their content; menu contents consume it and add `dsx-menu__nested`, resolved to `modal + 2` by `_internal/baseMenu.css`. A flat bump of `--dsx-z-index-dropdown` is rejected: a nested menu must clear 91 while a standalone page menu must stay below the modal overlay (80) so an open Dialog still masks page content — one static value cannot do both. Standalone menus never carry the class. The signal is provided at content level (not root) so `Combobox` — itself a `Popover` — never self-escalates. `AlertDialog.Content` inherits the host behavior through `Dialog.Content`. `Drawer` (vaul, own overlay tier) is out of scope.
190
192
 
191
193
  ## Motion contract
192
194
 
@@ -272,6 +274,7 @@ The `test_path` is `packages/d4gger-design-system/src/test/components/menu-migra
272
274
  - `_internal/usePrefersReducedMotion`: gates the framer-motion preset.
273
275
  - `framer-motion` (re-exported from `@d4gger/design-system/motion`): `motion` and `AnimatePresence` for the content animation.
274
276
  - `_internal/baseMenu.css`: shared item hover, focus, selected, and disabled rules. The public menu surfaces import `baseMenu.css` to inherit those rules; the `Menu` CSS file does not import it directly.
277
+ - `_internal/floatingLayer`: `FloatingLayerHostContext` / `useFloatingLayerHost` for the nested floating tier. `MenuContent` consumes it and adds `dsx-menu__nested` when rendered inside a modal-tier host (see the Token mapping contract above).
275
278
 
276
279
  **Used by:**
277
280
 
@@ -29,7 +29,7 @@ A surface-neutral metric anatomy for labels, tabular values, and semantic change
29
29
 
30
30
  | Prop | Type | Default | Required | Description | Responsive |
31
31
  |---|---|---|---|---|---|
32
- | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | no | Metric scale inherited by all slots. | no |
32
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | no | Value typography scale inherited through context; label and delta retain their supporting type ramps. | no |
33
33
  | `asChild` | `boolean` | `false` | no | Uses the consumer host for the root. | no |
34
34
  | `className` | `string` | `undefined` | no | Appended root class. | no |
35
35
 
@@ -40,6 +40,7 @@ A surface-neutral metric anatomy for labels, tabular values, and semantic change
40
40
  - Root: `dsx-metric`; slots: `dsx-metric__label`, `dsx-metric__value`, `dsx-metric__delta`.
41
41
  - Root writes `data-size="sm|md|lg"`; Delta writes `data-tone="positive|negative|neutral"`.
42
42
  - The component is static and breakpoint-agnostic.
43
+ - The root shrinks within the available width and wraps unbroken values or identifiers. Delta content can wrap without creating horizontal overflow. Consumers retain responsibility for meaningful number formatting.
43
44
 
44
45
  ## Token mapping
45
46
 
@@ -68,3 +69,5 @@ Show a default Metric, all three sizes, all three delta tones, a full compositio
68
69
  ## Wiring notes
69
70
 
70
71
  Metric owns anatomy, typography, tabular numerals, and delta presentation. Consumers own values, trend calculations, localization, and the surrounding Card or layout. `StatCard` composes this anatomy while preserving its legacy public contract.
72
+
73
+ Playground appearance follows the global theme switcher. Accent demonstrations inherit that appearance; no forced light/dark example overrides it.
@@ -5,7 +5,8 @@ category: Components
5
5
  archetype: composite
6
6
  depends_on:
7
7
  - "@radix-ui/react-slot (powers `asChild` on the root, list, item, link, and ellipsis slots)"
8
- - Icon (the `chevron-left` / `chevron-right` glyphs on `Previous` / `Next`; the `dots-horizontal` glyph on `Ellipsis`)
8
+ - Icon (the `chevron-left` / `chevron-right` glyphs on `Previous` / `Next`; the `chevrons-left` / `chevrons-right` glyphs on `First` / `Last`; the `dots-horizontal` glyph on `Ellipsis`)
9
+ - Select (powers `Pagination.PageSize`; the option list rides the shared menu tier)
9
10
  ---
10
11
 
11
12
  # Pagination
@@ -14,11 +15,11 @@ depends_on:
14
15
 
15
16
  ## Purpose
16
17
 
17
- A page-based dataset navigation surface that exposes the previous, next, and numbered links, an ellipsis for truncated ranges, an info summary, and a page-size selector. The DS `Pagination` is a flat composite (no Radix primitive), built directly on HTML elements plus the `Slot` helper for `asChild`. It is the canonical surface for page-based datasets; the roster lists `Button` as a composed-from surface because the page links render as button or anchor elements.
18
+ A page-based dataset navigation surface that exposes the previous, next, and numbered links, an ellipsis for truncated ranges, an info summary, a static page-status indicator, and a page-size selector. The DS `Pagination` is a flat composite (no Radix primitive), built directly on HTML elements plus the `Slot` helper for `asChild`. It is the canonical surface for page-based datasets; the roster lists `Button` as a composed-from surface because the page links render as button or anchor elements.
18
19
 
19
20
  ## 2.6 contract
20
21
 
21
- `PaginationBar` uses seven page slots whenever more than seven pages exist, including expanded boundary neighbours so first, middle, and final windows have equal width. `messages` localizes range formatting, zero results, previous/next labels, and page-size options. English remains default; a Russian formatter such as `(start, end, total) => `${start}–${end} из ${total}`` produces `1–8 из 47`.
22
+ `PaginationBar` uses seven page slots whenever more than seven pages exist, including expanded boundary neighbours so first, middle, and final windows have equal width. `messages` localizes range formatting, zero results, previous/next/first/last labels, page-size options, and the page-input `Page` / `of M` text. English remains default; a Russian formatter such as `(start, end, total) => `${start}–${end} из ${total}`` produces `1–8 из 47`. First/Last links and the page-jump input are opt-in (`showFirstLast`, `showPageInput`, both default `false`) so existing bars render unchanged.
22
23
 
23
24
  ## Anatomy & slots
24
25
 
@@ -34,11 +35,15 @@ A page-based dataset navigation surface that exposes the previous, next, and num
34
35
  | `Pagination.Link` | `<a>` (when `href` is set and not disabled), `<button>` (otherwise), or `Slot` child when `asChild` | `dsx-pagination__link` + `--active` modifier (when active) + `--disabled` modifier (when disabled) + optional `data-disabled` + `aria-current="page"` (when active) + `aria-disabled` (when disabled) | A page link. |
35
36
  | `Pagination.Previous` | wraps `Pagination.Link` | `dsx-pagination__link--edge` + `chevron-left` icon + default `aria-label="Previous page"` + default text `Previous` | The previous-page link. |
36
37
  | `Pagination.Next` | wraps `Pagination.Link` | `dsx-pagination__link--edge` + `chevron-right` icon + default `aria-label="Next page"` + default text `Next` | The next-page link. |
38
+ | `Pagination.First` | wraps `Pagination.Link` | `dsx-pagination__link--edge` + `chevrons-left` icon + default `aria-label="First page"` + default text `First` | The first-page link (round-2 gap fill). Opt-in via `showFirstLast` on `PaginationBar` / `DataTablePagination`. |
39
+ | `Pagination.Last` | wraps `Pagination.Link` | `dsx-pagination__link--edge` + `chevrons-right` icon + default `aria-label="Last page"` + default text `Last` | The last-page link (round-2 gap fill). Opt-in via `showFirstLast` on `PaginationBar` / `DataTablePagination`. |
40
+ | `Pagination.PageInput` | `<span>` wrapping a native `<input type="number">` | `dsx-pagination__page-input` + `aria-label="Page number, page N of M"` on the input + visible `Page` / `of M` text | Direct page jump (round-2 gap fill: "Page N of M"). Opt-in via `showPageInput` on `PaginationBar` / `DataTablePagination`. Commits on Enter or blur, clamped to `1..totalPages`. |
37
41
  | `Pagination.Ellipsis` | `<span>` (or `Slot` child when `asChild`) | `dsx-pagination__ellipsis` + `aria-hidden="true"` + `dots-horizontal` icon | A non-interactive truncation marker. |
38
42
  | `Pagination.Info` | `<span>` | `dsx-pagination__info` | A summary of the visible range (for example `Showing 21–40 of 137`). |
39
- | `Pagination.PageSize` | `<select>` | `dsx-pagination__page-size` | The page-size selector with the standard `[20, 50, 100]` options. |
43
+ | `Pagination.Status` | `<span role="status">` | `dsx-pagination__status` | A static page position (for example `Page 1 of 2`). The non-interactive counterpart to `PageInput`: consumers show Status or the Info range, never both (same dedup rule `DataTablePagination` applies in dense mode). `formatStatus` localizes the text; English default. |
44
+ | `Pagination.PageSize` | shared `Select` | `dsx-pagination__page-size` on the trigger | The page-size selector with the standard `[10, 25, 50, 100]` options. The open list is Select content, so it paints in the design language and inherits the shared floating tier. |
40
45
 
41
- The roster's `Parent / Slots` column lists `Pagination.Root`, `Pagination.List`, `Pagination.Item`, `Pagination.Link`, `Pagination.Previous`, `Pagination.Next`, `Pagination.Ellipsis`, `Pagination.Info`, `Pagination.PageSize`. The source exports `Pagination` as the root (no `Object.assign` accessor for `.Root`) and the rest as named exports; `Pagination.Content` is an alias of `Pagination.List`. The spec records the runtime shape; the roster's `Pagination.Root` style is the would-be public API if a `Root` accessor were added.
46
+ The roster's `Parent / Slots` column lists `Pagination.Root`, `Pagination.List`, `Pagination.Item`, `Pagination.Link`, `Pagination.Previous`, `Pagination.Next`, `Pagination.First`, `Pagination.Last`, `Pagination.Ellipsis`, `Pagination.Info`, `Pagination.Status`, `Pagination.PageInput`, `Pagination.PageSize`. The source exports `Pagination` as the root (no `Object.assign` accessor for `.Root`) and the rest as named exports; `Pagination.Content` is an alias of `Pagination.List`. The spec records the runtime shape; the roster's `Pagination.Root` style is the would-be public API if a `Root` accessor were added.
42
47
 
43
48
  ## Props contract
44
49
 
@@ -85,6 +90,32 @@ The roster's `Parent / Slots` column lists `Pagination.Root`, `Pagination.List`,
85
90
  | `className` | `string` | `undefined` | no | Extra classes appended to the edge modifier. | no |
86
91
  | `children` | `React.ReactNode` | `'Previous'` / `'Next'` | no | The text shown next to the chevron. | no |
87
92
 
93
+ ### `Pagination.First` and `Pagination.Last`
94
+
95
+ Same surface as `Previous` / `Next` (thin wrappers over `Link`), with defaults `aria-label="First page"` / `"Last page"` and children `"First"` / `"Last"`.
96
+
97
+ | Prop | Type | Default | Required | Description | Responsive |
98
+ |---|---|---|---|---|---|
99
+ | `active` | `boolean` | `false` | no | Forwarded to the underlying `Pagination.Link`. | no |
100
+ | `disabled` | `boolean` | `false` | no | Forwarded to the underlying `Pagination.Link`. | no |
101
+ | `asChild` | `boolean` | `false` | no | Forwarded to the underlying `Pagination.Link`. | no |
102
+ | `href` | `string` | `undefined` | no | Forwarded to the underlying `Pagination.Link`. | no |
103
+ | `aria-label` | `string` | `'First page'` / `'Last page'` | no | Landmark label. The default is applied when the consumer does not pass one. | no |
104
+ | `className` | `string` | `undefined` | no | Extra classes appended to the edge modifier. | no |
105
+ | `children` | `React.ReactNode` | `'First'` / `'Last'` | no | The text shown next to the chevron. | no |
106
+
107
+ ### `Pagination.PageInput`
108
+
109
+ | Prop | Type | Default | Required | Description | Responsive |
110
+ |---|---|---|---|---|---|
111
+ | `page` | `number` | (required) | yes | Current 1-based page. The input shows this value until the consumer types a draft. | no |
112
+ | `totalPages` | `number` | (required) | yes | Total page count. Clamps commits to `1..max(1, totalPages)` and renders the `of M` text. | no |
113
+ | `onPageChange` | `(page: number) => void` | (required) | yes | Called with the clamped page on Enter or blur. Non-numeric drafts are discarded. | no |
114
+ | `pageLabel` | `React.ReactNode` | `'Page'` | no | Visible label before the input. | no |
115
+ | `formatOf` | `(totalPages: number) => React.ReactNode` | `` (t) => `of ${t}` `` | no | Renders the visible `of M` text after the input. | no |
116
+ | `aria-label` | `string` | `'Page number, page N of M'` | no | Accessible name on the input. The default is applied when the consumer does not pass one. | no |
117
+ | `className` | `string` | `undefined` | no | Extra classes appended to `dsx-pagination__page-input`. | no |
118
+
88
119
  ### `Pagination.Ellipsis`
89
120
 
90
121
  | Prop | Type | Default | Required | Description | Responsive |
@@ -101,19 +132,29 @@ The roster's `Parent / Slots` column lists `Pagination.Root`, `Pagination.List`,
101
132
  | `offset` | `number` | (required) | yes | Zero-based offset of the first record on the current page. | no |
102
133
  | `limit` | `number` | (required) | yes | Page size. The end of the range is `min(offset + limit, totalCount)`. | no |
103
134
  | `className` | `string` | `undefined` | no | Extra classes appended to `dsx-pagination__info`. | no |
135
+ | `formatRange` | `(start: number, end: number, totalCount: number) => React.ReactNode` | `` (s, e, t) => `Showing ${s}–${e} of ${t}` `` | no | Renders the visible range text. | no |
136
+
137
+ ### `Pagination.Status`
138
+
139
+ | Prop | Type | Default | Required | Description | Responsive |
140
+ |---|---|---|---|---|---|
141
+ | `page` | `number` | (required) | yes | Current 1-based page. Clamped for display to `1..max(1, totalPages)`. | no |
142
+ | `totalPages` | `number` | (required) | yes | Total page count. | no |
143
+ | `formatStatus` | `(page: number, totalPages: number) => React.ReactNode` | `` (p, t) => `Page ${p} of ${t}` `` | no | Renders the visible status text. | no |
144
+ | `className` | `string` | `undefined` | no | Extra classes appended to `dsx-pagination__status`. | no |
104
145
 
105
146
  ### `Pagination.PageSize`
106
147
 
107
148
  | Prop | Type | Default | Required | Description | Responsive |
108
149
  |---|---|---|---|---|---|
109
150
  | `value` | `number` | (required) | yes | Current page size. | no |
110
- | `options` | `number[]` | `[20, 50, 100]` | no | Available page-size options. | no |
111
- | `onChange` | `(limit: number) => void` | (required) | yes | Called with the parsed numeric value when the consumer changes the select. | no |
151
+ | `options` | `number[]` | `[10, 25, 50, 100]` | no | Available page-size options. | no |
152
+ | `onChange` | `(limit: number) => void` | (required) | yes | Called with the parsed numeric value when the consumer picks an option. | no |
112
153
  | `className` | `string` | `undefined` | no | Extra classes appended to `dsx-pagination__page-size`. | no |
113
154
 
114
155
  Rules:
115
156
 
116
- - The root, list, item, link, and ellipsis slots all run through `extractProps` with the matching prop def bag. `Previous` and `Next` are thin wrappers over `Link` and inherit the prop surface.
157
+ - The root, list, item, link, and ellipsis slots all run through `extractProps` with the matching prop def bag. `Previous`, `Next`, `First`, and `Last` are thin wrappers over `Link` and inherit the prop surface.
117
158
  - `Link` is polymorphic: it renders `<a>` when `href` is set and the link is not `disabled`, otherwise `<button type="button" disabled>` when `disabled`, otherwise `Slot` when `asChild` is set. The `aria-current`, `aria-disabled`, and `data-disabled` attributes are written in every branch.
118
159
 
119
160
  ## CSS class contract
@@ -138,8 +179,11 @@ Rules:
138
179
  | `Pagination.Link` (active) | `dsx-pagination__link--active` | `pagination.css` |
139
180
  | `Pagination.Link` (disabled) | `dsx-pagination__link--disabled` | `pagination.css` |
140
181
  | `Pagination.Previous` / `Pagination.Next` | `dsx-pagination__link` + `dsx-pagination__link--edge` | `pagination.css` |
182
+ | `Pagination.First` / `Pagination.Last` | `dsx-pagination__link` + `dsx-pagination__link--edge` | `pagination.css` |
183
+ | `Pagination.PageInput` | `dsx-pagination__page-input` | `pagination.css` |
141
184
  | `Pagination.Ellipsis` | `dsx-pagination__ellipsis` | `pagination.css` |
142
185
  | `Pagination.Info` | `dsx-pagination__info` | `pagination.css` |
186
+ | `Pagination.Status` | `dsx-pagination__status` | `pagination.css` |
143
187
  | `Pagination.PageSize` | `dsx-pagination__page-size` | `pagination.css` |
144
188
 
145
189
  **Responsive behavior:**
@@ -170,7 +214,7 @@ Every CSS value the component paints is a `var(--dsx-*)` token.
170
214
  | Link typography | `var(--dsx-typography-label-large-*)` | Font family, size, weight. |
171
215
  | Link hover background | `var(--dsx-effect-hover-ghost)` | Hover surface. |
172
216
  | Link focus ring | `var(--dsx-shadow-focus-ring)` | `:focus-visible` ring. |
173
- | Link active background | `var(--dsx-color-accent-indicator)` | Active fill. |
217
+ | Link active background | `var(--dsx-color-accent-track)` | Active fill (fill step, vivid in both themes — the text-step `accent-indicator` renders near-black in light theme). |
174
218
  | Link active color | `var(--dsx-color-on-primary)` | Active text. |
175
219
  | Link active weight | `var(--dsx-typography-label-large-font-weight, 600)` | Active weight. |
176
220
  | Link edge color | `var(--dsx-color-on-surface-variant)` | Edge variant text. |
@@ -179,12 +223,23 @@ Every CSS value the component paints is a `var(--dsx-*)` token.
179
223
  | Ellipsis color | `var(--dsx-color-on-surface-variant)` | Ellipsis text. |
180
224
  | Info color | `var(--dsx-color-on-surface-variant)` | Info text. |
181
225
  | Info typography | `var(--dsx-typography-body-medium-*)` | Info font family and size. |
182
- | PageSize height | `var(--dsx-size-lg)` | Select height. |
226
+ | PageSize height | `var(--dsx-size-lg)` | Trigger height. |
227
+ | PageSize min-width | `8rem` | Fits the `N per page` label. |
183
228
  | PageSize padding | `0 var(--dsx-space-sm)` | Internal gutter. |
184
- | PageSize border | `var(--dsx-border-width-sm) solid var(--dsx-color-outline)` | Select edge. |
185
- | PageSize background | `var(--dsx-color-surface)` | Select surface. |
186
- | PageSize typography | `var(--dsx-typography-label-large-*)` | Select font family and size. |
229
+ | PageSize border | `var(--dsx-border-width-sm) solid var(--dsx-color-outline)` | Trigger edge. |
230
+ | PageSize typography | `var(--dsx-typography-label-large-*)` | Trigger font family and size. |
187
231
  | PageSize focus ring | `var(--dsx-shadow-focus-ring)` | `:focus-visible` ring. |
232
+ | PageSize option list | (shared `Select` tokens) | The open list rides `select.css` and the shared menu tier. |
233
+ | PageInput text | `var(--dsx-color-on-surface-variant)` | `Page` / `of M` label text. |
234
+ | PageInput typography | `var(--dsx-typography-body-medium-*)` | Label font family and size. |
235
+ | PageInput input width | `var(--dsx-size-3xl)` | Fixed input width for 2–3 digit pages. |
236
+ | PageInput input height | `var(--dsx-size-lg)` | Input height matching link touch targets. |
237
+ | PageInput input padding | `0 var(--dsx-space-sm)` | Internal gutter. |
238
+ | PageInput input border | `var(--dsx-border-width-sm) solid var(--dsx-color-outline)` | Input edge. |
239
+ | PageInput input radius | `var(--dsx-rounded-md)` | Corner roundness. |
240
+ | PageInput input background | `var(--dsx-color-surface)` | Input surface. |
241
+ | PageInput input color | `var(--dsx-color-on-surface)` | Input text. |
242
+ | PageInput focus ring | `var(--dsx-shadow-focus-ring)` | `:focus-visible` ring. |
188
243
  | Motion duration | `var(--dsx-motion-duration-fast, 150ms)` | Link transitions. |
189
244
  | Motion easing | `var(--dsx-motion-easing-standard, ease)` | Link easing. |
190
245
 
@@ -210,9 +265,12 @@ Rules:
210
265
  - `Pagination.List` is a `<ul>`; `Pagination.Item` is a `<li>`.
211
266
  - `Pagination.Link` is an `<a>` (or a `<button disabled>` when `disabled` and no `href`, or a `Slot` child when `asChild`). The active link carries `aria-current="page"`. The disabled link carries `aria-disabled`.
212
267
  - `Pagination.Previous` and `Pagination.Next` carry an `aria-label` (default `Previous page` / `Next page`).
268
+ - `Pagination.First` and `Pagination.Last` carry an `aria-label` (default `First page` / `Last page`).
269
+ - `Pagination.PageInput` is a native number `<input>` with a default `aria-label="Page number, page N of M"`. The visible `Page` / `of M` text is presentational; the input stays operable by keyboard (type, Enter to commit, blur to commit).
213
270
  - `Pagination.Ellipsis` is a non-interactive `<span aria-hidden="true">`.
214
271
  - `Pagination.Info` is a non-interactive `<span>`.
215
- - `Pagination.PageSize` is a native `<select>` with the standard browser semantics.
272
+ - `Pagination.Status` is a non-interactive `<span role="status">` announcing the current page position.
273
+ - `Pagination.PageSize` is the shared `Select` with the standard option semantics.
216
274
 
217
275
  **Keyboard:**
218
276
 
@@ -221,11 +279,11 @@ Rules:
221
279
  | `Tab` | Moves focus to or from the pagination landmark. |
222
280
  | `Enter` (focused link) | Activates the link. |
223
281
  | `Space` (focused link) | Activates the link. |
224
- | `Tab` (focused `PageSize`) | Moves through the page-size options. |
282
+ | `Tab` (focused `PageSize`) | Opens the option list; arrows move, Enter picks. |
225
283
 
226
284
  **Focus:**
227
285
 
228
- - The CSS file paints a `var(--dsx-shadow-focus-ring)` ring on `:focus-visible` for the link and the page-size select. The ring stays visible on dark and light surfaces.
286
+ - The CSS file paints a `var(--dsx-shadow-focus-ring)` ring on `:focus-visible` for the link and the page-size trigger. The ring stays visible on dark and light surfaces.
229
287
 
230
288
  **Reduced motion:**
231
289
 
@@ -239,6 +297,11 @@ Rules:
239
297
 
240
298
  - The `Pagination` landmark has a default `aria-label="Pagination"`. The edge links have default `aria-label` values (`Previous page`, `Next page`). Override the labels when the landmark or edge needs product-specific copy.
241
299
 
300
+ **Responsive (narrow shells):**
301
+
302
+ - `PaginationBar` wraps into stacked rows (info → controls) with no width breakpoints; the pager list wraps its page links the same way. Verified at 320px: zero overflowing descendants, desktop single-row layout unchanged. Narrow stacking is component behavior, not composition guidance — screens arrange the bar, never its internals.
303
+ - Opt-in `dense` mode (`PaginationBar`, mirrored on `DataTablePagination`): info summary + pager only. The page-size block is omitted, and on `DataTablePagination` the "Page X of Y" status (which duplicates the info range) is omitted with it. Default behavior is unchanged — narrow shells opt in explicitly; the component never decides by width, so no breakpoint, container query, or resize observer is involved. Narrow shells that let users choose page size keep the default mode.
304
+
242
305
  ## Playground demo spec
243
306
 
244
307
  **Default story:**
@@ -256,6 +319,12 @@ Rules:
256
319
  **Composition story:**
257
320
 
258
321
  - Renders a `Pagination.List` with `Previous`, an `Ellipsis`, numbered links, another `Ellipsis`, and `Next`. Asserts the list, the ellipsis (with `aria-hidden="true"`), and the edge links all render with their classes.
322
+ - Renders `First` and `Last` edge links with default `aria-label="First page"` / `"Last page"` and the `dsx-pagination__link--edge` modifier.
323
+ - Renders a `PageInput` with `page` / `totalPages`; asserts the input carries the page-number label and commits a clamped page on Enter.
324
+
325
+ **PaginationBar story:**
326
+
327
+ - Renders `PaginationBar` with `showFirstLast` and `showPageInput`; asserts First/Last links and the page-jump input render alongside info, page-size, and numbered links. Without the flags the bar renders info + page-size + Previous/numbered/Next only (default, unchanged). With `dense`, asserts the page-size block is absent and info + pager remain.
259
328
 
260
329
  **Token story:**
261
330
 
@@ -277,11 +346,13 @@ Rules:
277
346
 
278
347
  - `@radix-ui/react-slot`: enables `asChild` on the root, list, item, link, and ellipsis slots.
279
348
  - `_internal/helpers/extractProps`: turns the prop defs into merged class + style output.
280
- - `Icon`: the `chevron-left` / `chevron-right` glyphs on `Previous` / `Next`; the `dots-horizontal` glyph on `Ellipsis`.
349
+ - `Icon`: the `chevron-left` / `chevron-right` glyphs on `Previous` / `Next`; the `chevrons-left` / `chevrons-right` glyphs on `First` / `Last`; the `dots-horizontal` glyph on `Ellipsis`.
350
+ - `Select`: powers the `PageSize` trigger and option list.
281
351
 
282
352
  **Used by:**
283
353
 
284
354
  - App-level paginated lists. The roster lists `DataTable` as a consumer because the table wraps `Pagination` for its bottom toolbar.
355
+ - `DataTable` positions its pagination footer via `paginationPosition` (`top` / `bottom` / `both`, default `bottom`) and justifies it via `paginationAlign` (`start` / `center` / `end`; unset keeps info-left/controls-right). `DataTable` passes `paginationFirstLast` / `paginationPageInput` through to its internal `DataTablePagination` (`showFirstLast` / `showPageInput`). Placement is a `DataTable`-side concern; this spec owns the link/ellipsis/info/page-size/page-input surface only.
285
356
 
286
357
  **State boundaries:**
287
358
 
@@ -15,7 +15,7 @@ depends_on:
15
15
 
16
16
  ## Purpose
17
17
 
18
- A compact cluster of selectable or status pills rendered as a horizontal flex list. Use Pills for filter chips, tag clusters, segmented status indicators, and removable tags. For a single label surface, use `Badge`. For mutually exclusive options rendered as a segmented control, use `SegmentedControl` or `ToggleGroup`.
18
+ A compact cluster of selectable pills rendered as a horizontal flex list. Use Pills for filter chips, multi-select chip rows, and segmented status indicators. For a single label surface, use `Badge`. For a lone removable label, use `Tag`. For mutually exclusive options rendered as a segmented control, use `SegmentedControl` or `ToggleGroup`. Cardinality rule (F6 brief): a row of chips with selection state is Pills; one chip with a remove action is a Tag. Pills claims selection, never lone dismissal.
19
19
 
20
20
  ## Anatomy & slots
21
21
 
@@ -237,6 +237,7 @@ Rules:
237
237
  - `@radix-ui/react-slot`: enables `asChild` on the positioner, arrow, and content.
238
238
  - `framer-motion`: provides the `motion.div` for mount and exit. The reduced motion preset is read from `usePrefersReducedMotion`.
239
239
  - `baseDialog.css`: the shared overlay surface and theme-mirror utilities.
240
+ - `_internal/floatingLayer`: `Popover.Content` provides `FloatingLayerHostContext` to its body, so menu-tier content (`Select`, `Combobox`, `DropdownMenu`) nested inside the popover escalates via `dsx-menu__nested` (see the shared nested floating tier contract in `menu.md`).
240
241
 
241
242
  **Used by:**
242
243
 
@@ -247,6 +248,7 @@ Rules:
247
248
  **State boundaries:**
248
249
 
249
250
  - Owned by `Popover`: open state when uncontrolled, presence context, portal theme mirroring, motion preset, and the auto-wired `aria-labelledby` / `aria-describedby`.
251
+ - Owned by `Popover`: the nested-host signal — `Popover.Content` marks its body as a modal-tier host for the shared nested floating tier contract.
250
252
  - Owned by the consumer: the trigger label, the popover body, and the close behavior (via `Popover.Close` or `Escape`).
251
253
 
252
254
  **Boundary rules:**
@@ -19,6 +19,10 @@ Read-side article typography with an approximately `68ch` measure and `1.65` rea
19
19
 
20
20
  Consumers preserve heading order, stable IDs, meaningful image alt text, captions, and table headers. Wide tables scroll horizontally rather than hiding data.
21
21
 
22
+ The root can shrink within its parent. Long words, URLs, and identifiers wrap inside the reading measure; preformatted code and tables retain their explicit horizontal scrolling.
23
+
22
24
  ## Playground demo spec
23
25
 
24
- Render all supported semantic elements, sanitized HTML, a wide table at mobile width, and each exported authored-node renderer.
26
+ Render all supported semantic elements, sanitized HTML, a wide table at mobile width, and authored blocks in the separate ArticleNodes stream.
27
+
28
+ The live example is a coherent server-selection article with ordered headings, lists, blockquote, a working fragment link, inline/block code, a table with row/column headers, and an image with caption. ArticleNodes stays in the blocks stream.
@@ -30,7 +30,7 @@ No slots: flat export. The component renders a single `<div>` host element (or a
30
30
  | Prop | Type | Default | Required | Description | Responsive |
31
31
  |---|---|---|---|---|---|
32
32
  | `value` | `string` | `undefined` | yes | String payload encoded into the QR modules. Required by `QRCodeSVG`; the host element also omits the native `value` attribute. | no |
33
- | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | no | Container size; selects one of the internal `sizeMap` values (`sm: 128`, `md: 192`, `lg: 256` px) and writes `data-size`. The CSS overrides the rendered SVG width and height with sizing tokens. | no |
33
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | no | Painted size; selects one of the internal `sizeMap` values (`sm: 128`, `md: 192`, `lg: 256` px) and writes `data-size` plus the matching `dsx-qr-code-size-*` class. The SVG paints at exactly the `sizeMap` dimensions — the CSS never constrains it, so every size is scannable. | no |
34
34
  | `level` | `'L' \| 'M' \| 'Q' \| 'H'` | `'M'` | no | Error-correction level passed through to `QRCodeSVG`. `L` is ~7%, `M` is ~15%, `Q` is ~25%, `H` is ~30% recovery. | no |
35
35
  | `marginSize` | `number` | `0` | no | Quiet-zone margin passed through to `QRCodeSVG`. Default `0` matches the adapter default and is the spec baseline. | no |
36
36
  | `fgColor` | `string` | `var(--dsx-color-on-surface)` | no | Module (foreground) color. Default falls back to the token CSS variable; pass an explicit value to override. | no |
@@ -43,7 +43,8 @@ No slots: flat export. The component renders a single `<div>` host element (or a
43
43
  Rules that apply to this row:
44
44
 
45
45
  - The component extends `Omit<ComponentPropsWithoutRef<'div'>, 'value'>` because `value` is redefined by the QR-specific prop. Native `<div>` attributes that are not prop def keys are forwarded.
46
- - `size` is wired through `extractProps` and writes both the modifier class and `data-size`. The runtime `sizeMap` (`sm: 128`, `md: 192`, `lg: 256`) is the actual SVG pixel size; the CSS further constrains the rendered SVG width and height to the `size-{xs|md|xl}` sizing tokens so the visual size matches the container.
46
+ - The three size modifier selectors share the base SVG display and corner treatment; matrix dimensions remain runtime-owned.
47
+ - `size` is wired through `extractProps` and writes both the modifier class and `data-size`. The runtime `sizeMap` (`sm: 128`, `md: 192`, `lg: 256`) is the actual SVG pixel size, painted verbatim through the adapter's own width/height attributes. The `dsx-size-{xs|md|xl}` sizing tokens are NOT applied to the QR matrix — a former revision constrained the SVG to those tokens (16/24/40px) and rendered unscannable codes; the override was removed and must not return.
47
48
  - `level`, `marginSize`, `fgColor`, and `bgColor` are NOT in the prop def bag; they are typed in the `QRCodeProps` interface and consumed in the render path. The prop def only declares `asChild` and `size`. The interface-level defaults (`'M'`, `0`, token fallbacks) are applied at the destructuring site, not via `extractProps`.
48
49
  - The component does not currently expose a `data-high-contrast` prop or write that attribute, even though `qr-code.css` has a high-contrast block. The CSS block is a hook for downstream apps; the runtime does not emit the attribute today (see Anomalies).
49
50
 
@@ -82,9 +83,9 @@ Every CSS value the component paints is a `var(--dsx-*)` token, with runtime fal
82
83
  | Background | `var(--dsx-color-surface-raised)` | Container surface. |
83
84
  | Border | `var(--dsx-border-width-sm)` + `var(--dsx-color-outline)` | Edge. |
84
85
  | SVG border radius | `var(--dsx-rounded-sm)` | SVG corners. |
85
- | Size `sm` | `var(--dsx-size-xs)` | Rendered SVG width and height at the `sm` size. |
86
- | Size `md` | `var(--dsx-size-md)` | Rendered SVG width and height at the `md` size. |
87
- | Size `lg` | `var(--dsx-size-xl)` | Rendered SVG width and height at the `lg` size. |
86
+ | Size `sm` | (runtime `128` px) | Painted SVG width and height at the `sm` size — no token. |
87
+ | Size `md` | (runtime `192` px) | Painted SVG width and height at the `md` size — no token. |
88
+ | Size `lg` | (runtime `256` px) | Painted SVG width and height at the `lg` size — no token. |
88
89
  | Module color (default) | `var(--dsx-color-on-surface)` (runtime fallback) | QR modules. |
89
90
  | Background color (default) | `var(--dsx-color-surface-raised)` (runtime fallback) | Quiet zone. |
90
91
  | High-contrast surface | `var(--dsx-color-surface-raised)` | High-contrast container. |
@@ -93,7 +94,7 @@ Every CSS value the component paints is a `var(--dsx-*)` token, with runtime fal
93
94
 
94
95
  Rules:
95
96
 
96
- - The runtime SVG dimensions (`128`, `192`, `256`) are NOT tokens; they are the adapter's own pixel size used to compute the QR matrix. The CSS overrides the visible width and height with the `size-{xs|md|xl}` sizing tokens. The mismatch between the runtime px and the CSS px means the adapter still draws a sharp matrix; the CSS only constrains the rendered size.
97
+ - The runtime SVG dimensions (`128`, `192`, `256`) are NOT tokens; they are the adapter's own pixel size used to compute the QR matrix, painted verbatim. The CSS must never override the visible width and height with sizing tokens — that revision shipped 16/24/40px unscannable codes.
97
98
  - The `fgColor` and `bgColor` props are passed as CSS variable references (`'var(--dsx-color-on-surface)'`, `'var(--dsx-color-surface-raised)'`) when the consumer does not pass explicit values. The adapter forwards these into SVG attributes; token-driven theming therefore requires the `qr-code.css` rules to win on the modules, which is what the high-contrast block does.
98
99
  - The high-contrast block uses `svg rect[fill]:first-of-type` to recolor the background module; this relies on the adapter emitting the background as a single `<rect>`. If the adapter's output changes, the high-contrast fallback breaks.
99
100
 
@@ -140,11 +141,11 @@ The demo file at `demo_path` exposes the component to the playground. The playgr
140
141
 
141
142
  **Default story:**
142
143
 
143
- - Renders `QRCode` with `value="https://d4gger.example"` and no other props. Asserts the root class is `dsx-qr-code`, the inner element is an `svg`, the `data-size` attribute is `md`, and the SVG width and height resolve to `var(--dsx-size-md)`.
144
+ - Renders `QRCode` with `value="https://d4gger.example"` and no other props. Asserts the root class is `dsx-qr-code`, the inner element is an `svg`, the `data-size` attribute is `md`, and the SVG width and height attributes are `192`.
144
145
 
145
146
  **Variant story** (one per size):
146
147
 
147
- - Renders QRCode with `size="sm"`, `size="md"`, and `size="lg"`. Asserts the matching `dsx-qr-code-size-{sm|md|lg}` class and `data-size` value. Also asserts the SVG width and height resolve to the corresponding sizing token.
148
+ - Renders QRCode with `size="sm"`, `size="md"`, and `size="lg"`. Asserts the matching `dsx-qr-code-size-{sm|md|lg}` class and `data-size` value. Also asserts the SVG width and height attributes are `128` / `192` / `256` — never a sizing token.
148
149
 
149
150
  **Composition story** (for `asChild`):
150
151
 
@@ -194,7 +195,7 @@ The demo file at `demo_path` exposes the component to the playground. The playgr
194
195
  **Boundary rules:**
195
196
 
196
197
  - App-owned data: the encoded payload, the persistence of the payload, the security/rotation policy, the print/download lifecycle, and any analytics on scan events.
197
- - DS-owned visuals: token bindings (`--dsx-space-md`, `--dsx-rounded-xl`, `--dsx-rounded-sm`, `--dsx-color-surface-raised`, `--dsx-color-outline`, `--dsx-color-on-surface`, `--dsx-color-high-contrast-border`, `--dsx-color-high-contrast`, `--dsx-border-width-sm`, `--dsx-size-{xs|md|xl}`), the `dsx-qr-code` root class, the `dsx-qr-code-size-{sm|md|lg}` modifier classes, and the high-contrast CSS hook.
198
+ - DS-owned visuals: token bindings (`--dsx-space-md`, `--dsx-rounded-xl`, `--dsx-rounded-sm`, `--dsx-color-surface-raised`, `--dsx-color-outline`, `--dsx-color-on-surface`, `--dsx-color-high-contrast-border`, `--dsx-color-high-contrast`, `--dsx-border-width-sm`), the `dsx-qr-code` root class, the `dsx-qr-code-size-{sm|md|lg}` modifier classes, the runtime painted sizes (`128`/`192`/`256`), and the high-contrast CSS hook. The `dsx-size-*` tokens are explicitly NOT bound to the matrix.
198
199
 
199
200
  ## Penpot build recipe
200
201
 
@@ -205,7 +206,7 @@ The package does not yet publish a Penpot asset for QRCode. Recipe is visual ref
205
206
  ### Root board
206
207
 
207
208
  - **Name**: `Components / QRCode`.
208
- - **Dimensions**: `var(--dsx-size-md)` × `var(--dsx-size-md)` at the default `md` size; `var(--dsx-size-xs)` at `sm`; `var(--dsx-size-xl)` at `lg`.
209
+ - **Dimensions**: `192` × `192` px at the default `md` size; `128` px at `sm`; `256` px at `lg` (runtime painted sizes, not tokens).
209
210
  - **Layout**: `Fixed`.
210
211
  - **Sizing**: `horizontalSizing = 'fix'`, `verticalSizing = 'fix'`.
211
212
 
@@ -225,9 +226,9 @@ The package does not yet publish a Penpot asset for QRCode. Recipe is visual ref
225
226
  | Root | stroke | `--dsx-color-outline` | Color | `strokes` |
226
227
  | Root | padding | `--dsx-space-md` | Spacing | `padding` |
227
228
  | Root | corner radius | `--dsx-rounded-xl` | Radius | `radius` |
228
- | Root (size sm) | width, height | `--dsx-size-xs` | Sizing | `size` |
229
- | Root (size md) | width, height | `--dsx-size-md` | Sizing | `size` |
230
- | Root (size lg) | width, height | `--dsx-size-xl` | Sizing | `size` |
229
+ | Root (size sm) | width, height | `128` px (runtime, no token) | Sizing | `size` |
230
+ | Root (size md) | width, height | `192` px (runtime, no token) | Sizing | `size` |
231
+ | Root (size lg) | width, height | `256` px (runtime, no token) | Sizing | `size` |
231
232
  | Matrix | fill | `--dsx-color-on-surface` | Color | `fills` |
232
233
  | Matrix (high-contrast) | fill | `--dsx-color-high-contrast` | Color | `fills` (state) |
233
234