@cimpress-ui/react 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (507) hide show
  1. package/README.md +1 -1
  2. package/dist/commonjs/components/breadcrumbs/breadcrumbs.d.ts +22 -0
  3. package/dist/commonjs/components/breadcrumbs/breadcrumbs.d.ts.map +1 -0
  4. package/dist/commonjs/components/breadcrumbs/breadcrumbs.js +37 -0
  5. package/dist/commonjs/components/breadcrumbs/breadcrumbs.js.map +1 -0
  6. package/dist/commonjs/components/button/button.js +1 -1
  7. package/dist/commonjs/components/button/button.js.map +1 -1
  8. package/dist/commonjs/components/button/icon-button.js +1 -1
  9. package/dist/commonjs/components/button/icon-button.js.map +1 -1
  10. package/dist/commonjs/components/button/types.d.ts.map +1 -1
  11. package/dist/commonjs/components/button/types.js.map +1 -1
  12. package/dist/commonjs/components/card/card-context.d.ts +4 -0
  13. package/dist/commonjs/components/card/card-context.d.ts.map +1 -0
  14. package/dist/commonjs/components/card/card-context.js +6 -0
  15. package/dist/commonjs/components/card/card-context.js.map +1 -0
  16. package/dist/commonjs/components/card/card.d.ts +15 -0
  17. package/dist/commonjs/components/card/card.d.ts.map +1 -0
  18. package/dist/commonjs/components/card/card.js +24 -0
  19. package/dist/commonjs/components/card/card.js.map +1 -0
  20. package/dist/commonjs/components/checkbox/checkbox.d.ts +1 -1
  21. package/dist/commonjs/components/checkbox/checkbox.d.ts.map +1 -1
  22. package/dist/commonjs/components/checkbox/checkbox.js.map +1 -1
  23. package/dist/commonjs/components/combo-box/combo-box.d.ts +5 -1
  24. package/dist/commonjs/components/combo-box/combo-box.d.ts.map +1 -1
  25. package/dist/commonjs/components/combo-box/combo-box.js +6 -6
  26. package/dist/commonjs/components/combo-box/combo-box.js.map +1 -1
  27. package/dist/commonjs/components/disclosure/disclosure-group.d.ts +10 -0
  28. package/dist/commonjs/components/disclosure/disclosure-group.d.ts.map +1 -0
  29. package/dist/commonjs/components/disclosure/disclosure-group.js +18 -0
  30. package/dist/commonjs/components/disclosure/disclosure-group.js.map +1 -0
  31. package/dist/commonjs/components/disclosure/disclosure.d.ts +14 -0
  32. package/dist/commonjs/components/disclosure/disclosure.d.ts.map +1 -0
  33. package/dist/commonjs/components/disclosure/disclosure.js +20 -0
  34. package/dist/commonjs/components/disclosure/disclosure.js.map +1 -0
  35. package/dist/commonjs/components/internal/collapsible-list/collapsible-list.d.ts +0 -14
  36. package/dist/commonjs/components/internal/collapsible-list/collapsible-list.d.ts.map +1 -1
  37. package/dist/commonjs/components/internal/collapsible-list/collapsible-list.js +2 -4
  38. package/dist/commonjs/components/internal/collapsible-list/collapsible-list.js.map +1 -1
  39. package/dist/commonjs/components/internal/form-field/form-field.d.ts +1 -28
  40. package/dist/commonjs/components/internal/form-field/form-field.d.ts.map +1 -1
  41. package/dist/commonjs/components/internal/form-field/form-field.js +10 -0
  42. package/dist/commonjs/components/internal/form-field/form-field.js.map +1 -1
  43. package/dist/commonjs/components/internal/spinner/spinner.d.ts +0 -16
  44. package/dist/commonjs/components/internal/spinner/spinner.d.ts.map +1 -1
  45. package/dist/commonjs/components/modal/modal.d.ts +19 -0
  46. package/dist/commonjs/components/modal/modal.d.ts.map +1 -0
  47. package/dist/commonjs/components/modal/modal.js +25 -0
  48. package/dist/commonjs/components/modal/modal.js.map +1 -0
  49. package/dist/commonjs/components/nav-tabs/nav-tabs.d.ts +23 -0
  50. package/dist/commonjs/components/nav-tabs/nav-tabs.d.ts.map +1 -0
  51. package/dist/commonjs/components/nav-tabs/nav-tabs.js +27 -0
  52. package/dist/commonjs/components/nav-tabs/nav-tabs.js.map +1 -0
  53. package/dist/commonjs/components/number-field/number-field.d.ts +10 -0
  54. package/dist/commonjs/components/number-field/number-field.d.ts.map +1 -0
  55. package/dist/commonjs/components/number-field/number-field.js +32 -0
  56. package/dist/commonjs/components/number-field/number-field.js.map +1 -0
  57. package/dist/commonjs/components/pagination/pagination.d.ts +14 -0
  58. package/dist/commonjs/components/pagination/pagination.d.ts.map +1 -0
  59. package/dist/commonjs/components/pagination/pagination.js +69 -0
  60. package/dist/commonjs/components/pagination/pagination.js.map +1 -0
  61. package/dist/commonjs/components/radio/radio.d.ts +1 -1
  62. package/dist/commonjs/components/radio/radio.d.ts.map +1 -1
  63. package/dist/commonjs/components/radio/radio.js.map +1 -1
  64. package/dist/commonjs/components/table/contexts/focus.d.ts +13 -0
  65. package/dist/commonjs/components/table/contexts/focus.d.ts.map +1 -0
  66. package/dist/commonjs/components/table/contexts/focus.js +51 -0
  67. package/dist/commonjs/components/table/contexts/focus.js.map +1 -0
  68. package/dist/commonjs/components/table/contexts/row-state.d.ts +10 -0
  69. package/dist/commonjs/components/table/contexts/row-state.d.ts.map +1 -0
  70. package/dist/commonjs/components/table/contexts/row-state.js +22 -0
  71. package/dist/commonjs/components/table/contexts/row-state.js.map +1 -0
  72. package/dist/commonjs/components/table/hooks/use-table-cell.d.ts +7 -0
  73. package/dist/commonjs/components/table/hooks/use-table-cell.d.ts.map +1 -0
  74. package/dist/commonjs/components/table/hooks/use-table-cell.js +125 -0
  75. package/dist/commonjs/components/table/hooks/use-table-cell.js.map +1 -0
  76. package/dist/commonjs/components/table/hooks/use-table.d.ts +7 -0
  77. package/dist/commonjs/components/table/hooks/use-table.d.ts.map +1 -0
  78. package/dist/commonjs/components/table/hooks/use-table.js +142 -0
  79. package/dist/commonjs/components/table/hooks/use-table.js.map +1 -0
  80. package/dist/commonjs/components/table/table-body-cell.d.ts +26 -0
  81. package/dist/commonjs/components/table/table-body-cell.d.ts.map +1 -0
  82. package/dist/commonjs/components/table/table-body-cell.js +17 -0
  83. package/dist/commonjs/components/table/table-body-cell.js.map +1 -0
  84. package/dist/commonjs/components/table/table-body.d.ts +8 -0
  85. package/dist/commonjs/components/table/table-body.d.ts.map +1 -0
  86. package/dist/commonjs/components/table/table-body.js +11 -0
  87. package/dist/commonjs/components/table/table-body.js.map +1 -0
  88. package/dist/commonjs/components/table/table-container.d.ts +8 -0
  89. package/dist/commonjs/components/table/table-container.d.ts.map +1 -0
  90. package/dist/commonjs/components/table/table-container.js +40 -0
  91. package/dist/commonjs/components/table/table-container.js.map +1 -0
  92. package/dist/commonjs/components/table/table-header-cell.d.ts +26 -0
  93. package/dist/commonjs/components/table/table-header-cell.d.ts.map +1 -0
  94. package/dist/commonjs/components/table/table-header-cell.js +17 -0
  95. package/dist/commonjs/components/table/table-header-cell.js.map +1 -0
  96. package/dist/commonjs/components/table/table-header.d.ts +8 -0
  97. package/dist/commonjs/components/table/table-header.d.ts.map +1 -0
  98. package/dist/commonjs/components/table/table-header.js +11 -0
  99. package/dist/commonjs/components/table/table-header.js.map +1 -0
  100. package/dist/commonjs/components/table/table-row.d.ts +21 -0
  101. package/dist/commonjs/components/table/table-row.d.ts.map +1 -0
  102. package/dist/commonjs/components/table/table-row.js +14 -0
  103. package/dist/commonjs/components/table/table-row.js.map +1 -0
  104. package/dist/commonjs/components/table/table.d.ts +26 -0
  105. package/dist/commonjs/components/table/table.d.ts.map +1 -0
  106. package/dist/commonjs/components/table/table.js +27 -0
  107. package/dist/commonjs/components/table/table.js.map +1 -0
  108. package/dist/commonjs/components/table/utils/focus-table-child.d.ts +4 -0
  109. package/dist/commonjs/components/table/utils/focus-table-child.d.ts.map +1 -0
  110. package/dist/commonjs/components/table/utils/focus-table-child.js +14 -0
  111. package/dist/commonjs/components/table/utils/focus-table-child.js.map +1 -0
  112. package/dist/commonjs/components/tag/tag-group.d.ts +18 -0
  113. package/dist/commonjs/components/tag/tag-group.d.ts.map +1 -0
  114. package/dist/commonjs/components/tag/tag-group.js +27 -0
  115. package/dist/commonjs/components/tag/tag-group.js.map +1 -0
  116. package/dist/commonjs/components/tag/tag.d.ts +17 -0
  117. package/dist/commonjs/components/tag/tag.d.ts.map +1 -0
  118. package/dist/commonjs/components/tag/tag.js +20 -0
  119. package/dist/commonjs/components/tag/tag.js.map +1 -0
  120. package/dist/commonjs/components/text-inputs/text-area.d.ts.map +1 -1
  121. package/dist/commonjs/components/text-inputs/text-area.js +1 -1
  122. package/dist/commonjs/components/text-inputs/text-area.js.map +1 -1
  123. package/dist/commonjs/components/text-inputs/text-field.d.ts.map +1 -1
  124. package/dist/commonjs/components/text-inputs/text-field.js +1 -1
  125. package/dist/commonjs/components/text-inputs/text-field.js.map +1 -1
  126. package/dist/commonjs/components/tooltip/tooltip.d.ts +9 -0
  127. package/dist/commonjs/components/tooltip/tooltip.d.ts.map +1 -0
  128. package/dist/commonjs/components/tooltip/tooltip.js +15 -0
  129. package/dist/commonjs/components/tooltip/tooltip.js.map +1 -0
  130. package/dist/commonjs/components/types.d.ts +16 -2
  131. package/dist/commonjs/components/types.d.ts.map +1 -1
  132. package/dist/commonjs/components/types.js.map +1 -1
  133. package/dist/commonjs/components/typography/link.d.ts +2 -2
  134. package/dist/commonjs/components/typography/link.d.ts.map +1 -1
  135. package/dist/commonjs/components/typography/link.js +3 -2
  136. package/dist/commonjs/components/typography/link.js.map +1 -1
  137. package/dist/commonjs/components/typography/types.d.ts +2 -1
  138. package/dist/commonjs/components/typography/types.d.ts.map +1 -1
  139. package/dist/commonjs/components/typography/types.js.map +1 -1
  140. package/dist/commonjs/components/typography/utils.d.ts.map +1 -1
  141. package/dist/commonjs/components/typography/utils.js +2 -2
  142. package/dist/commonjs/components/typography/utils.js.map +1 -1
  143. package/dist/commonjs/components/visually-hidden/visually-hidden.d.ts +17 -0
  144. package/dist/commonjs/components/visually-hidden/visually-hidden.d.ts.map +1 -0
  145. package/dist/commonjs/components/visually-hidden/visually-hidden.js +20 -0
  146. package/dist/commonjs/components/visually-hidden/visually-hidden.js.map +1 -0
  147. package/dist/commonjs/icons/accounting-document.d.ts +1 -1
  148. package/dist/commonjs/icons/accounting-document.d.ts.map +1 -1
  149. package/dist/commonjs/icons/accounting-document.js +4 -2
  150. package/dist/commonjs/icons/accounting-document.js.map +1 -1
  151. package/dist/commonjs/icons/add-circle-fill.d.ts +1 -1
  152. package/dist/commonjs/icons/add-circle-fill.d.ts.map +1 -1
  153. package/dist/commonjs/icons/add-circle-fill.js +4 -2
  154. package/dist/commonjs/icons/add-circle-fill.js.map +1 -1
  155. package/dist/commonjs/icons/add-circle.d.ts +1 -1
  156. package/dist/commonjs/icons/add-circle.d.ts.map +1 -1
  157. package/dist/commonjs/icons/add-circle.js +4 -2
  158. package/dist/commonjs/icons/add-circle.js.map +1 -1
  159. package/dist/commonjs/icons/add.d.ts +1 -1
  160. package/dist/commonjs/icons/add.d.ts.map +1 -1
  161. package/dist/commonjs/icons/add.js +4 -2
  162. package/dist/commonjs/icons/add.js.map +1 -1
  163. package/dist/commonjs/icons/alert-triangle.d.ts +1 -1
  164. package/dist/commonjs/icons/alert-triangle.d.ts.map +1 -1
  165. package/dist/commonjs/icons/alert-triangle.js +4 -2
  166. package/dist/commonjs/icons/alert-triangle.js.map +1 -1
  167. package/dist/commonjs/icons/calculator-alt.d.ts +1 -1
  168. package/dist/commonjs/icons/calculator-alt.d.ts.map +1 -1
  169. package/dist/commonjs/icons/calculator-alt.js +4 -2
  170. package/dist/commonjs/icons/calculator-alt.js.map +1 -1
  171. package/dist/commonjs/icons/calculator.d.ts +1 -1
  172. package/dist/commonjs/icons/calculator.d.ts.map +1 -1
  173. package/dist/commonjs/icons/calculator.js +4 -2
  174. package/dist/commonjs/icons/calculator.js.map +1 -1
  175. package/dist/commonjs/icons/checkmark-circle-fill.d.ts +1 -1
  176. package/dist/commonjs/icons/checkmark-circle-fill.d.ts.map +1 -1
  177. package/dist/commonjs/icons/checkmark-circle-fill.js +4 -2
  178. package/dist/commonjs/icons/checkmark-circle-fill.js.map +1 -1
  179. package/dist/commonjs/icons/checkmark-circle.d.ts +1 -1
  180. package/dist/commonjs/icons/checkmark-circle.d.ts.map +1 -1
  181. package/dist/commonjs/icons/checkmark-circle.js +4 -2
  182. package/dist/commonjs/icons/checkmark-circle.js.map +1 -1
  183. package/dist/commonjs/icons/checkmark-small.d.ts +1 -1
  184. package/dist/commonjs/icons/checkmark-small.d.ts.map +1 -1
  185. package/dist/commonjs/icons/checkmark-small.js +4 -2
  186. package/dist/commonjs/icons/checkmark-small.js.map +1 -1
  187. package/dist/commonjs/icons/checkmark.d.ts +1 -1
  188. package/dist/commonjs/icons/checkmark.d.ts.map +1 -1
  189. package/dist/commonjs/icons/checkmark.js +4 -2
  190. package/dist/commonjs/icons/checkmark.js.map +1 -1
  191. package/dist/commonjs/icons/chevron-down-fill.d.ts +1 -1
  192. package/dist/commonjs/icons/chevron-down-fill.d.ts.map +1 -1
  193. package/dist/commonjs/icons/chevron-down-fill.js +4 -2
  194. package/dist/commonjs/icons/chevron-down-fill.js.map +1 -1
  195. package/dist/commonjs/icons/error-circle-fill.d.ts +1 -1
  196. package/dist/commonjs/icons/error-circle-fill.d.ts.map +1 -1
  197. package/dist/commonjs/icons/error-circle-fill.js +5 -3
  198. package/dist/commonjs/icons/error-circle-fill.js.map +1 -1
  199. package/dist/commonjs/icons/index.d.ts +6 -0
  200. package/dist/commonjs/icons/index.d.ts.map +1 -1
  201. package/dist/commonjs/icons/index.js +13 -1
  202. package/dist/commonjs/icons/index.js.map +1 -1
  203. package/dist/commonjs/icons/info-circle-fill.d.ts +1 -1
  204. package/dist/commonjs/icons/info-circle-fill.d.ts.map +1 -1
  205. package/dist/commonjs/icons/info-circle-fill.js +4 -2
  206. package/dist/commonjs/icons/info-circle-fill.js.map +1 -1
  207. package/dist/commonjs/icons/minus-small.d.ts +1 -1
  208. package/dist/commonjs/icons/minus-small.d.ts.map +1 -1
  209. package/dist/commonjs/icons/minus-small.js +4 -2
  210. package/dist/commonjs/icons/minus-small.js.map +1 -1
  211. package/dist/commonjs/icons/minus.d.ts +8 -0
  212. package/dist/commonjs/icons/minus.d.ts.map +1 -0
  213. package/dist/commonjs/icons/minus.js +24 -0
  214. package/dist/commonjs/icons/minus.js.map +1 -0
  215. package/dist/commonjs/icons/unstable-chevron-left-fill.d.ts +8 -0
  216. package/dist/commonjs/icons/unstable-chevron-left-fill.d.ts.map +1 -0
  217. package/dist/commonjs/icons/unstable-chevron-left-fill.js +24 -0
  218. package/dist/commonjs/icons/unstable-chevron-left-fill.js.map +1 -0
  219. package/dist/commonjs/icons/unstable-chevron-right-fill.d.ts +8 -0
  220. package/dist/commonjs/icons/unstable-chevron-right-fill.d.ts.map +1 -0
  221. package/dist/commonjs/icons/unstable-chevron-right-fill.js +24 -0
  222. package/dist/commonjs/icons/unstable-chevron-right-fill.js.map +1 -0
  223. package/dist/commonjs/icons/unstable-close.d.ts +8 -0
  224. package/dist/commonjs/icons/unstable-close.d.ts.map +1 -0
  225. package/dist/commonjs/icons/unstable-close.js +24 -0
  226. package/dist/commonjs/icons/unstable-close.js.map +1 -0
  227. package/dist/commonjs/icons/unstable-info-circle.d.ts +8 -0
  228. package/dist/commonjs/icons/unstable-info-circle.d.ts.map +1 -0
  229. package/dist/commonjs/icons/unstable-info-circle.js +24 -0
  230. package/dist/commonjs/icons/unstable-info-circle.js.map +1 -0
  231. package/dist/commonjs/icons/unstable-placeholder.d.ts +8 -0
  232. package/dist/commonjs/icons/unstable-placeholder.d.ts.map +1 -0
  233. package/dist/commonjs/icons/unstable-placeholder.js +24 -0
  234. package/dist/commonjs/icons/unstable-placeholder.js.map +1 -0
  235. package/dist/commonjs/icons/warning-circle-fill.d.ts +1 -1
  236. package/dist/commonjs/icons/warning-circle-fill.d.ts.map +1 -1
  237. package/dist/commonjs/icons/warning-circle-fill.js +4 -2
  238. package/dist/commonjs/icons/warning-circle-fill.js.map +1 -1
  239. package/dist/commonjs/index.d.ts +21 -1
  240. package/dist/commonjs/index.d.ts.map +1 -1
  241. package/dist/commonjs/index.js +19 -0
  242. package/dist/commonjs/index.js.map +1 -1
  243. package/dist/commonjs/utils/style/tone.d.ts +3 -0
  244. package/dist/commonjs/utils/style/tone.d.ts.map +1 -0
  245. package/dist/commonjs/utils/style/tone.js +7 -0
  246. package/dist/commonjs/utils/style/tone.js.map +1 -0
  247. package/dist/commonjs/utils/style/types.d.ts +2 -0
  248. package/dist/commonjs/utils/style/types.d.ts.map +1 -0
  249. package/dist/commonjs/utils/style/types.js +3 -0
  250. package/dist/commonjs/utils/style/types.js.map +1 -0
  251. package/dist/commonjs/with-style-props.d.ts +1 -1
  252. package/dist/commonjs/with-style-props.d.ts.map +1 -1
  253. package/dist/commonjs/with-style-props.js.map +1 -1
  254. package/dist/esm/components/breadcrumbs/breadcrumbs.d.ts +22 -0
  255. package/dist/esm/components/breadcrumbs/breadcrumbs.d.ts.map +1 -0
  256. package/dist/esm/components/breadcrumbs/breadcrumbs.js +30 -0
  257. package/dist/esm/components/breadcrumbs/breadcrumbs.js.map +1 -0
  258. package/dist/esm/components/button/button.js +1 -1
  259. package/dist/esm/components/button/button.js.map +1 -1
  260. package/dist/esm/components/button/icon-button.js +1 -1
  261. package/dist/esm/components/button/icon-button.js.map +1 -1
  262. package/dist/esm/components/button/types.d.ts.map +1 -1
  263. package/dist/esm/components/button/types.js.map +1 -1
  264. package/dist/esm/components/card/card-context.d.ts +4 -0
  265. package/dist/esm/components/card/card-context.d.ts.map +1 -0
  266. package/dist/esm/components/card/card-context.js +3 -0
  267. package/dist/esm/components/card/card-context.js.map +1 -0
  268. package/dist/esm/components/card/card.d.ts +15 -0
  269. package/dist/esm/components/card/card.d.ts.map +1 -0
  270. package/dist/esm/components/card/card.js +17 -0
  271. package/dist/esm/components/card/card.js.map +1 -0
  272. package/dist/esm/components/checkbox/checkbox.d.ts +1 -1
  273. package/dist/esm/components/checkbox/checkbox.d.ts.map +1 -1
  274. package/dist/esm/components/checkbox/checkbox.js.map +1 -1
  275. package/dist/esm/components/combo-box/combo-box.d.ts +5 -1
  276. package/dist/esm/components/combo-box/combo-box.d.ts.map +1 -1
  277. package/dist/esm/components/combo-box/combo-box.js +7 -7
  278. package/dist/esm/components/combo-box/combo-box.js.map +1 -1
  279. package/dist/esm/components/disclosure/disclosure-group.d.ts +10 -0
  280. package/dist/esm/components/disclosure/disclosure-group.d.ts.map +1 -0
  281. package/dist/esm/components/disclosure/disclosure-group.js +12 -0
  282. package/dist/esm/components/disclosure/disclosure-group.js.map +1 -0
  283. package/dist/esm/components/disclosure/disclosure.d.ts +14 -0
  284. package/dist/esm/components/disclosure/disclosure.d.ts.map +1 -0
  285. package/dist/esm/components/disclosure/disclosure.js +14 -0
  286. package/dist/esm/components/disclosure/disclosure.js.map +1 -0
  287. package/dist/esm/components/internal/collapsible-list/collapsible-list.d.ts +0 -14
  288. package/dist/esm/components/internal/collapsible-list/collapsible-list.d.ts.map +1 -1
  289. package/dist/esm/components/internal/collapsible-list/collapsible-list.js +2 -4
  290. package/dist/esm/components/internal/collapsible-list/collapsible-list.js.map +1 -1
  291. package/dist/esm/components/internal/form-field/form-field.d.ts +1 -28
  292. package/dist/esm/components/internal/form-field/form-field.d.ts.map +1 -1
  293. package/dist/esm/components/internal/form-field/form-field.js +10 -1
  294. package/dist/esm/components/internal/form-field/form-field.js.map +1 -1
  295. package/dist/esm/components/internal/spinner/spinner.d.ts +0 -16
  296. package/dist/esm/components/internal/spinner/spinner.d.ts.map +1 -1
  297. package/dist/esm/components/modal/modal.d.ts +19 -0
  298. package/dist/esm/components/modal/modal.d.ts.map +1 -0
  299. package/dist/esm/components/modal/modal.js +18 -0
  300. package/dist/esm/components/modal/modal.js.map +1 -0
  301. package/dist/esm/components/nav-tabs/nav-tabs.d.ts +23 -0
  302. package/dist/esm/components/nav-tabs/nav-tabs.d.ts.map +1 -0
  303. package/dist/esm/components/nav-tabs/nav-tabs.js +20 -0
  304. package/dist/esm/components/nav-tabs/nav-tabs.js.map +1 -0
  305. package/dist/esm/components/number-field/number-field.d.ts +10 -0
  306. package/dist/esm/components/number-field/number-field.d.ts.map +1 -0
  307. package/dist/esm/components/number-field/number-field.js +26 -0
  308. package/dist/esm/components/number-field/number-field.js.map +1 -0
  309. package/dist/esm/components/pagination/pagination.d.ts +14 -0
  310. package/dist/esm/components/pagination/pagination.d.ts.map +1 -0
  311. package/dist/esm/components/pagination/pagination.js +66 -0
  312. package/dist/esm/components/pagination/pagination.js.map +1 -0
  313. package/dist/esm/components/radio/radio.d.ts +1 -1
  314. package/dist/esm/components/radio/radio.d.ts.map +1 -1
  315. package/dist/esm/components/radio/radio.js.map +1 -1
  316. package/dist/esm/components/table/contexts/focus.d.ts +13 -0
  317. package/dist/esm/components/table/contexts/focus.d.ts.map +1 -0
  318. package/dist/esm/components/table/contexts/focus.js +47 -0
  319. package/dist/esm/components/table/contexts/focus.js.map +1 -0
  320. package/dist/esm/components/table/contexts/row-state.d.ts +10 -0
  321. package/dist/esm/components/table/contexts/row-state.d.ts.map +1 -0
  322. package/dist/esm/components/table/contexts/row-state.js +18 -0
  323. package/dist/esm/components/table/contexts/row-state.js.map +1 -0
  324. package/dist/esm/components/table/hooks/use-table-cell.d.ts +7 -0
  325. package/dist/esm/components/table/hooks/use-table-cell.d.ts.map +1 -0
  326. package/dist/esm/components/table/hooks/use-table-cell.js +122 -0
  327. package/dist/esm/components/table/hooks/use-table-cell.js.map +1 -0
  328. package/dist/esm/components/table/hooks/use-table.d.ts +7 -0
  329. package/dist/esm/components/table/hooks/use-table.d.ts.map +1 -0
  330. package/dist/esm/components/table/hooks/use-table.js +139 -0
  331. package/dist/esm/components/table/hooks/use-table.js.map +1 -0
  332. package/dist/esm/components/table/table-body-cell.d.ts +26 -0
  333. package/dist/esm/components/table/table-body-cell.d.ts.map +1 -0
  334. package/dist/esm/components/table/table-body-cell.js +14 -0
  335. package/dist/esm/components/table/table-body-cell.js.map +1 -0
  336. package/dist/esm/components/table/table-body.d.ts +8 -0
  337. package/dist/esm/components/table/table-body.d.ts.map +1 -0
  338. package/dist/esm/components/table/table-body.js +8 -0
  339. package/dist/esm/components/table/table-body.js.map +1 -0
  340. package/dist/esm/components/table/table-container.d.ts +8 -0
  341. package/dist/esm/components/table/table-container.d.ts.map +1 -0
  342. package/dist/esm/components/table/table-container.js +34 -0
  343. package/dist/esm/components/table/table-container.js.map +1 -0
  344. package/dist/esm/components/table/table-header-cell.d.ts +26 -0
  345. package/dist/esm/components/table/table-header-cell.d.ts.map +1 -0
  346. package/dist/esm/components/table/table-header-cell.js +14 -0
  347. package/dist/esm/components/table/table-header-cell.js.map +1 -0
  348. package/dist/esm/components/table/table-header.d.ts +8 -0
  349. package/dist/esm/components/table/table-header.d.ts.map +1 -0
  350. package/dist/esm/components/table/table-header.js +8 -0
  351. package/dist/esm/components/table/table-header.js.map +1 -0
  352. package/dist/esm/components/table/table-row.d.ts +21 -0
  353. package/dist/esm/components/table/table-row.d.ts.map +1 -0
  354. package/dist/esm/components/table/table-row.js +11 -0
  355. package/dist/esm/components/table/table-row.js.map +1 -0
  356. package/dist/esm/components/table/table.d.ts +26 -0
  357. package/dist/esm/components/table/table.d.ts.map +1 -0
  358. package/dist/esm/components/table/table.js +24 -0
  359. package/dist/esm/components/table/table.js.map +1 -0
  360. package/dist/esm/components/table/utils/focus-table-child.d.ts +4 -0
  361. package/dist/esm/components/table/utils/focus-table-child.d.ts.map +1 -0
  362. package/dist/esm/components/table/utils/focus-table-child.js +11 -0
  363. package/dist/esm/components/table/utils/focus-table-child.js.map +1 -0
  364. package/dist/esm/components/tag/tag-group.d.ts +18 -0
  365. package/dist/esm/components/tag/tag-group.d.ts.map +1 -0
  366. package/dist/esm/components/tag/tag-group.js +21 -0
  367. package/dist/esm/components/tag/tag-group.js.map +1 -0
  368. package/dist/esm/components/tag/tag.d.ts +17 -0
  369. package/dist/esm/components/tag/tag.d.ts.map +1 -0
  370. package/dist/esm/components/tag/tag.js +14 -0
  371. package/dist/esm/components/tag/tag.js.map +1 -0
  372. package/dist/esm/components/text-inputs/text-area.d.ts.map +1 -1
  373. package/dist/esm/components/text-inputs/text-area.js +3 -3
  374. package/dist/esm/components/text-inputs/text-area.js.map +1 -1
  375. package/dist/esm/components/text-inputs/text-field.d.ts.map +1 -1
  376. package/dist/esm/components/text-inputs/text-field.js +3 -3
  377. package/dist/esm/components/text-inputs/text-field.js.map +1 -1
  378. package/dist/esm/components/tooltip/tooltip.d.ts +9 -0
  379. package/dist/esm/components/tooltip/tooltip.d.ts.map +1 -0
  380. package/dist/esm/components/tooltip/tooltip.js +9 -0
  381. package/dist/esm/components/tooltip/tooltip.js.map +1 -0
  382. package/dist/esm/components/types.d.ts +16 -2
  383. package/dist/esm/components/types.d.ts.map +1 -1
  384. package/dist/esm/components/types.js.map +1 -1
  385. package/dist/esm/components/typography/link.d.ts +2 -2
  386. package/dist/esm/components/typography/link.d.ts.map +1 -1
  387. package/dist/esm/components/typography/link.js +3 -2
  388. package/dist/esm/components/typography/link.js.map +1 -1
  389. package/dist/esm/components/typography/types.d.ts +2 -1
  390. package/dist/esm/components/typography/types.d.ts.map +1 -1
  391. package/dist/esm/components/typography/types.js.map +1 -1
  392. package/dist/esm/components/typography/utils.d.ts.map +1 -1
  393. package/dist/esm/components/typography/utils.js +2 -2
  394. package/dist/esm/components/typography/utils.js.map +1 -1
  395. package/dist/esm/components/visually-hidden/visually-hidden.d.ts +17 -0
  396. package/dist/esm/components/visually-hidden/visually-hidden.d.ts.map +1 -0
  397. package/dist/esm/components/visually-hidden/visually-hidden.js +14 -0
  398. package/dist/esm/components/visually-hidden/visually-hidden.js.map +1 -0
  399. package/dist/esm/icons/accounting-document.d.ts +1 -1
  400. package/dist/esm/icons/accounting-document.d.ts.map +1 -1
  401. package/dist/esm/icons/accounting-document.js +4 -2
  402. package/dist/esm/icons/accounting-document.js.map +1 -1
  403. package/dist/esm/icons/add-circle-fill.d.ts +1 -1
  404. package/dist/esm/icons/add-circle-fill.d.ts.map +1 -1
  405. package/dist/esm/icons/add-circle-fill.js +4 -2
  406. package/dist/esm/icons/add-circle-fill.js.map +1 -1
  407. package/dist/esm/icons/add-circle.d.ts +1 -1
  408. package/dist/esm/icons/add-circle.d.ts.map +1 -1
  409. package/dist/esm/icons/add-circle.js +4 -2
  410. package/dist/esm/icons/add-circle.js.map +1 -1
  411. package/dist/esm/icons/add.d.ts +1 -1
  412. package/dist/esm/icons/add.d.ts.map +1 -1
  413. package/dist/esm/icons/add.js +4 -2
  414. package/dist/esm/icons/add.js.map +1 -1
  415. package/dist/esm/icons/alert-triangle.d.ts +1 -1
  416. package/dist/esm/icons/alert-triangle.d.ts.map +1 -1
  417. package/dist/esm/icons/alert-triangle.js +4 -2
  418. package/dist/esm/icons/alert-triangle.js.map +1 -1
  419. package/dist/esm/icons/calculator-alt.d.ts +1 -1
  420. package/dist/esm/icons/calculator-alt.d.ts.map +1 -1
  421. package/dist/esm/icons/calculator-alt.js +4 -2
  422. package/dist/esm/icons/calculator-alt.js.map +1 -1
  423. package/dist/esm/icons/calculator.d.ts +1 -1
  424. package/dist/esm/icons/calculator.d.ts.map +1 -1
  425. package/dist/esm/icons/calculator.js +4 -2
  426. package/dist/esm/icons/calculator.js.map +1 -1
  427. package/dist/esm/icons/checkmark-circle-fill.d.ts +1 -1
  428. package/dist/esm/icons/checkmark-circle-fill.d.ts.map +1 -1
  429. package/dist/esm/icons/checkmark-circle-fill.js +4 -2
  430. package/dist/esm/icons/checkmark-circle-fill.js.map +1 -1
  431. package/dist/esm/icons/checkmark-circle.d.ts +1 -1
  432. package/dist/esm/icons/checkmark-circle.d.ts.map +1 -1
  433. package/dist/esm/icons/checkmark-circle.js +4 -2
  434. package/dist/esm/icons/checkmark-circle.js.map +1 -1
  435. package/dist/esm/icons/checkmark-small.d.ts +1 -1
  436. package/dist/esm/icons/checkmark-small.d.ts.map +1 -1
  437. package/dist/esm/icons/checkmark-small.js +4 -2
  438. package/dist/esm/icons/checkmark-small.js.map +1 -1
  439. package/dist/esm/icons/checkmark.d.ts +1 -1
  440. package/dist/esm/icons/checkmark.d.ts.map +1 -1
  441. package/dist/esm/icons/checkmark.js +4 -2
  442. package/dist/esm/icons/checkmark.js.map +1 -1
  443. package/dist/esm/icons/chevron-down-fill.d.ts +1 -1
  444. package/dist/esm/icons/chevron-down-fill.d.ts.map +1 -1
  445. package/dist/esm/icons/chevron-down-fill.js +4 -2
  446. package/dist/esm/icons/chevron-down-fill.js.map +1 -1
  447. package/dist/esm/icons/error-circle-fill.d.ts +1 -1
  448. package/dist/esm/icons/error-circle-fill.d.ts.map +1 -1
  449. package/dist/esm/icons/error-circle-fill.js +6 -4
  450. package/dist/esm/icons/error-circle-fill.js.map +1 -1
  451. package/dist/esm/icons/index.d.ts +6 -0
  452. package/dist/esm/icons/index.d.ts.map +1 -1
  453. package/dist/esm/icons/index.js +6 -0
  454. package/dist/esm/icons/index.js.map +1 -1
  455. package/dist/esm/icons/info-circle-fill.d.ts +1 -1
  456. package/dist/esm/icons/info-circle-fill.d.ts.map +1 -1
  457. package/dist/esm/icons/info-circle-fill.js +4 -2
  458. package/dist/esm/icons/info-circle-fill.js.map +1 -1
  459. package/dist/esm/icons/minus-small.d.ts +1 -1
  460. package/dist/esm/icons/minus-small.d.ts.map +1 -1
  461. package/dist/esm/icons/minus-small.js +4 -2
  462. package/dist/esm/icons/minus-small.js.map +1 -1
  463. package/dist/esm/icons/minus.d.ts +8 -0
  464. package/dist/esm/icons/minus.d.ts.map +1 -0
  465. package/dist/esm/icons/minus.js +19 -0
  466. package/dist/esm/icons/minus.js.map +1 -0
  467. package/dist/esm/icons/unstable-chevron-left-fill.d.ts +8 -0
  468. package/dist/esm/icons/unstable-chevron-left-fill.d.ts.map +1 -0
  469. package/dist/esm/icons/unstable-chevron-left-fill.js +19 -0
  470. package/dist/esm/icons/unstable-chevron-left-fill.js.map +1 -0
  471. package/dist/esm/icons/unstable-chevron-right-fill.d.ts +8 -0
  472. package/dist/esm/icons/unstable-chevron-right-fill.d.ts.map +1 -0
  473. package/dist/esm/icons/unstable-chevron-right-fill.js +19 -0
  474. package/dist/esm/icons/unstable-chevron-right-fill.js.map +1 -0
  475. package/dist/esm/icons/unstable-close.d.ts +8 -0
  476. package/dist/esm/icons/unstable-close.d.ts.map +1 -0
  477. package/dist/esm/icons/unstable-close.js +19 -0
  478. package/dist/esm/icons/unstable-close.js.map +1 -0
  479. package/dist/esm/icons/unstable-info-circle.d.ts +8 -0
  480. package/dist/esm/icons/unstable-info-circle.d.ts.map +1 -0
  481. package/dist/esm/icons/unstable-info-circle.js +19 -0
  482. package/dist/esm/icons/unstable-info-circle.js.map +1 -0
  483. package/dist/esm/icons/unstable-placeholder.d.ts +8 -0
  484. package/dist/esm/icons/unstable-placeholder.d.ts.map +1 -0
  485. package/dist/esm/icons/unstable-placeholder.js +19 -0
  486. package/dist/esm/icons/unstable-placeholder.js.map +1 -0
  487. package/dist/esm/icons/warning-circle-fill.d.ts +1 -1
  488. package/dist/esm/icons/warning-circle-fill.d.ts.map +1 -1
  489. package/dist/esm/icons/warning-circle-fill.js +4 -2
  490. package/dist/esm/icons/warning-circle-fill.js.map +1 -1
  491. package/dist/esm/index.d.ts +21 -1
  492. package/dist/esm/index.d.ts.map +1 -1
  493. package/dist/esm/index.js +19 -0
  494. package/dist/esm/index.js.map +1 -1
  495. package/dist/esm/utils/style/tone.d.ts +3 -0
  496. package/dist/esm/utils/style/tone.d.ts.map +1 -0
  497. package/dist/esm/utils/style/tone.js +4 -0
  498. package/dist/esm/utils/style/tone.js.map +1 -0
  499. package/dist/esm/utils/style/types.d.ts +2 -0
  500. package/dist/esm/utils/style/types.d.ts.map +1 -0
  501. package/dist/esm/utils/style/types.js +2 -0
  502. package/dist/esm/utils/style/types.js.map +1 -0
  503. package/dist/esm/with-style-props.d.ts +1 -1
  504. package/dist/esm/with-style-props.d.ts.map +1 -1
  505. package/dist/esm/with-style-props.js.map +1 -1
  506. package/dist-styles/styles.css +1 -1
  507. package/package.json +5 -2
@@ -0,0 +1,66 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { UNSTABLE_IconChevronLeftFill, UNSTABLE_IconChevronRightFill } from '../../icons/index.js';
3
+ import { Button } from '../button/button.js';
4
+ import { IconButton } from '../button/icon-button.js';
5
+ import { IconLinkButton } from '../button/icon-link-button.js';
6
+ import { LinkButton } from '../button/link-button.js';
7
+ export function UNSTABLE_Pagination({ value, count, onPageChange, href, 'aria-label': ariaLabel }) {
8
+ const visiblePages = getVisiblePages(value, count);
9
+ const previousButtonProps = {
10
+ // TODO: icon doesn't look optically centered, see: https://www.figma.com/design/JVWmaCjDeOlrYAkLlJD5gr?node-id=10376-1487#1082340181
11
+ icon: _jsx(UNSTABLE_IconChevronLeftFill, {}),
12
+ isDisabled: value === 1,
13
+ // TODO: internationalization
14
+ 'aria-label': 'Previous',
15
+ };
16
+ const nextButtonProps = {
17
+ // TODO: icon doesn't look optically centered, see: https://www.figma.com/design/JVWmaCjDeOlrYAkLlJD5gr?node-id=10376-1487#1082340181
18
+ icon: _jsx(UNSTABLE_IconChevronRightFill, {}),
19
+ isDisabled: value === count,
20
+ // TODO: internationalization
21
+ 'aria-label': 'Next',
22
+ };
23
+ return (_jsx("nav", { className: "cim-pagination", "aria-label": ariaLabel, children: _jsxs("ul", { className: "cim-pagination-list", children: [_jsx("li", { children: href ? (_jsx(IconLinkButton, { ...previousButtonProps, href: href?.(value - 1) })) : (_jsx(IconButton, { ...previousButtonProps, onPress: () => onPageChange?.(value - 1) })) }), visiblePages.map((page) => {
24
+ const isCurrentPage = typeof page === 'number' && page === value;
25
+ const pageNumber = typeof page === 'number' ? page : page.page;
26
+ const pageButtonProps = {
27
+ // TODO: internationalization
28
+ // TODO: review if "Current page" is needed once we put `aria-current` on the `button`/`link`
29
+ 'aria-label': isCurrentPage ? `Current page, page ${pageNumber}` : `Go to page ${pageNumber}`,
30
+ children: typeof page === 'number' ? page : '…',
31
+ };
32
+ return (
33
+ // TODO: Put `aria-current` on the `button`/`link` instead of the `li` for better accessibility/screen reader support
34
+ // RAC Button doesn't support `aria-current` as of now
35
+ _jsx("li", { "aria-current": isCurrentPage && href != null ? 'page' : isCurrentPage, children: href ? (_jsx(LinkButton, { href: href?.(pageNumber), ...pageButtonProps })) : (_jsx(Button, { onPress: () => onPageChange?.(pageNumber), ...pageButtonProps })) }, pageNumber));
36
+ }), _jsx("li", { children: href ? (_jsx(IconLinkButton, { ...nextButtonProps, href: href?.(value + 1) })) : (_jsx(IconButton, { ...nextButtonProps, onPress: () => onPageChange?.(value + 1) })) })] }) }));
37
+ }
38
+ function getVisiblePages(currentPage, totalPages) {
39
+ if (totalPages <= 7) {
40
+ return Array.from({ length: totalPages }, (_, index) => index + 1);
41
+ }
42
+ if (currentPage <= 4) {
43
+ return [1, 2, 3, 4, { type: 'ellipsis', page: 5 }, totalPages - 1, totalPages];
44
+ }
45
+ if (currentPage >= totalPages - 3) {
46
+ return [
47
+ 1,
48
+ 2,
49
+ { type: 'ellipsis', page: totalPages - 4 },
50
+ totalPages - 3,
51
+ totalPages - 2,
52
+ totalPages - 1,
53
+ totalPages,
54
+ ];
55
+ }
56
+ return [
57
+ 1,
58
+ { type: 'ellipsis', page: currentPage - 2 },
59
+ currentPage - 1,
60
+ currentPage,
61
+ currentPage + 1,
62
+ { type: 'ellipsis', page: currentPage + 2 },
63
+ totalPages,
64
+ ];
65
+ }
66
+ //# sourceMappingURL=pagination.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../../../src/components/pagination/pagination.tsx"],"names":[],"mappings":"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","sourcesContent":["import { UNSTABLE_IconChevronLeftFill, UNSTABLE_IconChevronRightFill } from '../../icons/index.js';\nimport { Button } from '../button/button.js';\nimport { IconButton } from '../button/icon-button.js';\nimport { IconLinkButton } from '../button/icon-link-button.js';\nimport { LinkButton } from '../button/link-button.js';\n\nexport interface PaginationProps {\n /** The current page number. */\n value: number;\n /** The total number of pages. */\n count: number;\n /** The accessibility label for the pagination navigation, must be unique to the page. */\n 'aria-label': string;\n /** A callback function that is called when the page number changes. */\n onPageChange?: (page: number) => void;\n /** A function that returns a URL for a given page number. */\n href?: (page: number) => string;\n}\n\nexport function UNSTABLE_Pagination({ value, count, onPageChange, href, 'aria-label': ariaLabel }: PaginationProps) {\n const visiblePages = getVisiblePages(value, count);\n\n const previousButtonProps = {\n // TODO: icon doesn't look optically centered, see: https://www.figma.com/design/JVWmaCjDeOlrYAkLlJD5gr?node-id=10376-1487#1082340181\n icon: <UNSTABLE_IconChevronLeftFill />,\n isDisabled: value === 1,\n // TODO: internationalization\n 'aria-label': 'Previous',\n };\n\n const nextButtonProps = {\n // TODO: icon doesn't look optically centered, see: https://www.figma.com/design/JVWmaCjDeOlrYAkLlJD5gr?node-id=10376-1487#1082340181\n icon: <UNSTABLE_IconChevronRightFill />,\n isDisabled: value === count,\n // TODO: internationalization\n 'aria-label': 'Next',\n };\n\n return (\n <nav className=\"cim-pagination\" aria-label={ariaLabel}>\n <ul className=\"cim-pagination-list\">\n <li>\n {href ? (\n <IconLinkButton {...previousButtonProps} href={href?.(value - 1)} />\n ) : (\n <IconButton {...previousButtonProps} onPress={() => onPageChange?.(value - 1)} />\n )}\n </li>\n\n {visiblePages.map((page) => {\n const isCurrentPage = typeof page === 'number' && page === value;\n const pageNumber = typeof page === 'number' ? page : page.page;\n const pageButtonProps = {\n // TODO: internationalization\n // TODO: review if \"Current page\" is needed once we put `aria-current` on the `button`/`link`\n 'aria-label': isCurrentPage ? `Current page, page ${pageNumber}` : `Go to page ${pageNumber}`,\n children: typeof page === 'number' ? page : '…',\n };\n\n return (\n // TODO: Put `aria-current` on the `button`/`link` instead of the `li` for better accessibility/screen reader support\n // RAC Button doesn't support `aria-current` as of now\n <li key={pageNumber} aria-current={isCurrentPage && href != null ? 'page' : isCurrentPage}>\n {href ? (\n <LinkButton href={href?.(pageNumber)} {...pageButtonProps} />\n ) : (\n <Button onPress={() => onPageChange?.(pageNumber)} {...pageButtonProps} />\n )}\n </li>\n );\n })}\n\n <li>\n {href ? (\n <IconLinkButton {...nextButtonProps} href={href?.(value + 1)} />\n ) : (\n <IconButton {...nextButtonProps} onPress={() => onPageChange?.(value + 1)} />\n )}\n </li>\n </ul>\n </nav>\n );\n}\n\nfunction getVisiblePages(currentPage: number, totalPages: number): (number | { type: 'ellipsis'; page: number })[] {\n if (totalPages <= 7) {\n return Array.from({ length: totalPages }, (_, index) => index + 1);\n }\n\n if (currentPage <= 4) {\n return [1, 2, 3, 4, { type: 'ellipsis', page: 5 }, totalPages - 1, totalPages];\n }\n\n if (currentPage >= totalPages - 3) {\n return [\n 1,\n 2,\n { type: 'ellipsis', page: totalPages - 4 },\n totalPages - 3,\n totalPages - 2,\n totalPages - 1,\n totalPages,\n ];\n }\n\n return [\n 1,\n { type: 'ellipsis', page: currentPage - 2 },\n currentPage - 1,\n currentPage,\n currentPage + 1,\n { type: 'ellipsis', page: currentPage + 2 },\n totalPages,\n ];\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import { type RadioProps as RACRadioProps } from 'react-aria-components';
2
2
  import type { CommonProps, LabellableProps, StringLikeChildren } from '../types.js';
3
- export interface RadioProps extends CommonProps, Omit<LabellableProps, 'label'>, Pick<RACRadioProps, 'value' | 'isDisabled'> {
3
+ export interface RadioProps extends CommonProps, Omit<LabellableProps, 'label'>, Pick<RACRadioProps, 'value' | 'isDisabled' | 'autoFocus'> {
4
4
  /** The label rendered next to the radio. */
5
5
  children?: StringLikeChildren;
6
6
  }
@@ -1 +1 @@
1
- {"version":3,"file":"radio.d.ts","sourceRoot":"","sources":["../../../../src/components/radio/radio.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAqB,KAAK,UAAU,IAAI,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAG5F,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAGpF,MAAM,WAAW,UACf,SAAQ,WAAW,EACjB,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,EAC9B,IAAI,CAAC,aAAa,EAAE,OAAO,GAAG,YAAY,CAAC;IAC7C,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,kBAAkB,CAAC;CAC/B;AA8BD;;;;GAIG;AACH,QAAA,MAAM,MAAM,8JAA6C,CAAC;AAE1D,OAAO,EAAE,MAAM,IAAI,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"radio.d.ts","sourceRoot":"","sources":["../../../../src/components/radio/radio.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAqB,KAAK,UAAU,IAAI,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAG5F,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAGpF,MAAM,WAAW,UACf,SAAQ,WAAW,EACjB,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,EAC9B,IAAI,CAAC,aAAa,EAAE,OAAO,GAAG,YAAY,GAAG,WAAW,CAAC;IAC3D,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,kBAAkB,CAAC;CAC/B;AA8BD;;;;GAIG;AACH,QAAA,MAAM,MAAM,8JAA6C,CAAC;AAE1D,OAAO,EAAE,MAAM,IAAI,KAAK,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"radio.js","sourceRoot":"","sources":["../../../../src/components/radio/radio.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,SAAS,EAAqB,MAAM,OAAO,CAAC;AACrD,OAAO,EAAE,KAAK,IAAI,QAAQ,EAAoC,MAAM,uBAAuB,CAAC;AAC5F,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAU7C,SAAS,KAAK,CACZ,EAAE,QAAQ,EAAE,gBAAgB,EAAE,YAAY,EAAE,GAAG,KAAK,EAAc,EAClE,GAAmC;IAEnC,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,iBAAiB,EAAE,cAAc,EAAE,GAAG,KAAK,CAAC;IAE7E,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,QAAQ,IAAI,CAAC,SAAS,IAAI,CAAC,cAAc,EAAE,CAAC;YAC/C,OAAO,CAAC,IAAI,CAAC,iFAAiF,CAAC,CAAC;QAClG,CAAC;IACH,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC;IAE1C,OAAO,CACL,MAAC,QAAQ,OAAK,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,GAAG,aAChG,cAAK,SAAS,EAAC,0BAA0B,YACvC,cAAK,SAAS,EAAC,kBAAkB,YAC/B,cAAK,SAAS,EAAC,wBAAwB,GAAG,GACtC,GACF,EACL,QAAQ,IAAI,CACX,KAAC,IAAI,IAAC,EAAE,EAAC,MAAM,EAAC,OAAO,EAAC,MAAM,YAC3B,QAAQ,GACJ,CACR,IACQ,CACZ,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,MAAM,GAAG,cAAc,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;AAE1D,OAAO,EAAE,MAAM,IAAI,KAAK,EAAE,CAAC","sourcesContent":["'use client';\n\nimport clsx from 'clsx';\nimport { useEffect, type ForwardedRef } from 'react';\nimport { Radio as RACRadio, type RadioProps as RACRadioProps } from 'react-aria-components';\nimport { forwardRef } from '../../forward-ref.js';\nimport { withStyleProps } from '../../with-style-props.js';\nimport type { CommonProps, LabellableProps, StringLikeChildren } from '../types.js';\nimport { Text } from '../typography/text.js';\n\nexport interface RadioProps\n extends CommonProps,\n Omit<LabellableProps, 'label'>,\n Pick<RACRadioProps, 'value' | 'isDisabled'> {\n /** The label rendered next to the radio. */\n children?: StringLikeChildren;\n}\n\nfunction Radio(\n { children, UNSAFE_className, UNSAFE_style, ...props }: RadioProps,\n ref: ForwardedRef<HTMLLabelElement>,\n) {\n const { 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy } = props;\n\n useEffect(() => {\n if (!children && !ariaLabel && !ariaLabelledBy) {\n console.warn('Radio requires one of children / aria-label / aria-labelledby for accessibility');\n }\n }, [children, ariaLabel, ariaLabelledBy]);\n\n return (\n <RACRadio {...props} className={clsx('cim-radio', UNSAFE_className)} style={UNSAFE_style} ref={ref}>\n <div className=\"cim-radio-toggle-wrapper\">\n <div className=\"cim-radio-toggle\">\n <div className=\"cim-radio-toggle-inner\" />\n </div>\n </div>\n {children && (\n <Text as=\"span\" variant=\"body\">\n {children}\n </Text>\n )}\n </RACRadio>\n );\n}\n\n/**\n * Renders a single option within `RadioGroup`.\n *\n * See [radio group usage guidelines](https://ui.cimpress.io/components/radio-group/).\n */\nconst _Radio = withStyleProps(forwardRef(Radio), 'Radio');\n\nexport { _Radio as Radio };\n"]}
1
+ {"version":3,"file":"radio.js","sourceRoot":"","sources":["../../../../src/components/radio/radio.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,SAAS,EAAqB,MAAM,OAAO,CAAC;AACrD,OAAO,EAAE,KAAK,IAAI,QAAQ,EAAoC,MAAM,uBAAuB,CAAC;AAC5F,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAU7C,SAAS,KAAK,CACZ,EAAE,QAAQ,EAAE,gBAAgB,EAAE,YAAY,EAAE,GAAG,KAAK,EAAc,EAClE,GAAmC;IAEnC,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,iBAAiB,EAAE,cAAc,EAAE,GAAG,KAAK,CAAC;IAE7E,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,QAAQ,IAAI,CAAC,SAAS,IAAI,CAAC,cAAc,EAAE,CAAC;YAC/C,OAAO,CAAC,IAAI,CAAC,iFAAiF,CAAC,CAAC;QAClG,CAAC;IACH,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC;IAE1C,OAAO,CACL,MAAC,QAAQ,OAAK,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,GAAG,aAChG,cAAK,SAAS,EAAC,0BAA0B,YACvC,cAAK,SAAS,EAAC,kBAAkB,YAC/B,cAAK,SAAS,EAAC,wBAAwB,GAAG,GACtC,GACF,EACL,QAAQ,IAAI,CACX,KAAC,IAAI,IAAC,EAAE,EAAC,MAAM,EAAC,OAAO,EAAC,MAAM,YAC3B,QAAQ,GACJ,CACR,IACQ,CACZ,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,MAAM,GAAG,cAAc,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;AAE1D,OAAO,EAAE,MAAM,IAAI,KAAK,EAAE,CAAC","sourcesContent":["'use client';\n\nimport clsx from 'clsx';\nimport { useEffect, type ForwardedRef } from 'react';\nimport { Radio as RACRadio, type RadioProps as RACRadioProps } from 'react-aria-components';\nimport { forwardRef } from '../../forward-ref.js';\nimport { withStyleProps } from '../../with-style-props.js';\nimport type { CommonProps, LabellableProps, StringLikeChildren } from '../types.js';\nimport { Text } from '../typography/text.js';\n\nexport interface RadioProps\n extends CommonProps,\n Omit<LabellableProps, 'label'>,\n Pick<RACRadioProps, 'value' | 'isDisabled' | 'autoFocus'> {\n /** The label rendered next to the radio. */\n children?: StringLikeChildren;\n}\n\nfunction Radio(\n { children, UNSAFE_className, UNSAFE_style, ...props }: RadioProps,\n ref: ForwardedRef<HTMLLabelElement>,\n) {\n const { 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy } = props;\n\n useEffect(() => {\n if (!children && !ariaLabel && !ariaLabelledBy) {\n console.warn('Radio requires one of children / aria-label / aria-labelledby for accessibility');\n }\n }, [children, ariaLabel, ariaLabelledBy]);\n\n return (\n <RACRadio {...props} className={clsx('cim-radio', UNSAFE_className)} style={UNSAFE_style} ref={ref}>\n <div className=\"cim-radio-toggle-wrapper\">\n <div className=\"cim-radio-toggle\">\n <div className=\"cim-radio-toggle-inner\" />\n </div>\n </div>\n {children && (\n <Text as=\"span\" variant=\"body\">\n {children}\n </Text>\n )}\n </RACRadio>\n );\n}\n\n/**\n * Renders a single option within `RadioGroup`.\n *\n * See [radio group usage guidelines](https://ui.cimpress.io/components/radio-group/).\n */\nconst _Radio = withStyleProps(forwardRef(Radio), 'Radio');\n\nexport { _Radio as Radio };\n"]}
@@ -0,0 +1,13 @@
1
+ import { type ReactNode } from 'react';
2
+ export interface TableFocus {
3
+ focusedRowKey: string;
4
+ focusedColumnKey: string;
5
+ childFocusStrategy: ChildFocusStrategy;
6
+ setFocus: (rowKey: string, columnKey: string, childFocusStrategy?: ChildFocusStrategy) => void;
7
+ }
8
+ export type ChildFocusStrategy = 'first' | 'last';
9
+ export declare function TableFocusProvider({ children }: {
10
+ children: ReactNode;
11
+ }): import("react/jsx-runtime").JSX.Element;
12
+ export declare function useTableFocus(): TableFocus;
13
+ //# sourceMappingURL=focus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus.d.ts","sourceRoot":"","sources":["../../../../../src/components/table/contexts/focus.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,SAAS,EAAyC,MAAM,OAAO,CAAC;AAE7F,MAAM,WAAW,UAAU;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,kBAAkB,CAAC,EAAE,kBAAkB,KAAK,IAAI,CAAC;CAChG;AAED,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,MAAM,CAAC;AAIlD,wBAAgB,kBAAkB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,2CAwCvE;AAGD,wBAAgB,aAAa,IAAI,UAAU,CAO1C"}
@@ -0,0 +1,47 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext, useMemo, useRef, useState } from 'react';
3
+ const TableFocusContext = createContext(null);
4
+ export function TableFocusProvider({ children }) {
5
+ // When table focus is updated, we want to trigger a re-render,
6
+ // but we also want immediate access to the new values.
7
+ // Hence why they are stored as both a ref and a state.
8
+ const focusedRowKeyRef = useRef('');
9
+ const [_focusedRowKey, setFocusedRowKey] = useState('');
10
+ const focusedColumnKeyRef = useRef('');
11
+ const [_focusedColumnKey, setFocusedColumnKey] = useState('');
12
+ const childFocusStrategyRef = useRef('first');
13
+ const [_childFocusStrategy, setChildFocusStrategy] = useState('first');
14
+ const tableFocus = useMemo(() => ({
15
+ get focusedRowKey() {
16
+ return focusedRowKeyRef.current;
17
+ },
18
+ get focusedColumnKey() {
19
+ return focusedColumnKeyRef.current;
20
+ },
21
+ get childFocusStrategy() {
22
+ return childFocusStrategyRef.current;
23
+ },
24
+ setFocus: (rowKey, columnKey, childFocusStrategy) => {
25
+ focusedRowKeyRef.current = rowKey;
26
+ setFocusedRowKey(rowKey);
27
+ focusedColumnKeyRef.current = columnKey;
28
+ setFocusedColumnKey(columnKey);
29
+ if (childFocusStrategy) {
30
+ childFocusStrategyRef.current = childFocusStrategy;
31
+ setChildFocusStrategy(childFocusStrategy);
32
+ }
33
+ },
34
+ }),
35
+ // eslint-disable-next-line react-hooks/exhaustive-deps
36
+ [_focusedRowKey, _focusedColumnKey, _childFocusStrategy]);
37
+ return _jsx(TableFocusContext.Provider, { value: tableFocus, children: children });
38
+ }
39
+ // eslint-disable-next-line react-refresh/only-export-components
40
+ export function useTableFocus() {
41
+ const tableFocus = useContext(TableFocusContext);
42
+ if (!tableFocus) {
43
+ throw new Error('Cannot use table focus outside of a table');
44
+ }
45
+ return tableFocus;
46
+ }
47
+ //# sourceMappingURL=focus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus.js","sourceRoot":"","sources":["../../../../../src/components/table/contexts/focus.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAkB,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAW7F,MAAM,iBAAiB,GAAG,aAAa,CAAoB,IAAI,CAAC,CAAC;AAEjE,MAAM,UAAU,kBAAkB,CAAC,EAAE,QAAQ,EAA2B;IACtE,+DAA+D;IAC/D,uDAAuD;IACvD,uDAAuD;IACvD,MAAM,gBAAgB,GAAG,MAAM,CAAS,EAAE,CAAC,CAAC;IAC5C,MAAM,CAAC,cAAc,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAS,EAAE,CAAC,CAAC;IAChE,MAAM,mBAAmB,GAAG,MAAM,CAAS,EAAE,CAAC,CAAC;IAC/C,MAAM,CAAC,iBAAiB,EAAE,mBAAmB,CAAC,GAAG,QAAQ,CAAS,EAAE,CAAC,CAAC;IACtE,MAAM,qBAAqB,GAAG,MAAM,CAAqB,OAAO,CAAC,CAAC;IAClE,MAAM,CAAC,mBAAmB,EAAE,qBAAqB,CAAC,GAAG,QAAQ,CAAqB,OAAO,CAAC,CAAC;IAE3F,MAAM,UAAU,GAAe,OAAO,CACpC,GAAG,EAAE,CAAC,CAAC;QACL,IAAI,aAAa;YACf,OAAO,gBAAgB,CAAC,OAAO,CAAC;QAClC,CAAC;QACD,IAAI,gBAAgB;YAClB,OAAO,mBAAmB,CAAC,OAAO,CAAC;QACrC,CAAC;QACD,IAAI,kBAAkB;YACpB,OAAO,qBAAqB,CAAC,OAAO,CAAC;QACvC,CAAC;QACD,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,kBAAkB,EAAE,EAAE;YAClD,gBAAgB,CAAC,OAAO,GAAG,MAAM,CAAC;YAClC,gBAAgB,CAAC,MAAM,CAAC,CAAC;YAEzB,mBAAmB,CAAC,OAAO,GAAG,SAAS,CAAC;YACxC,mBAAmB,CAAC,SAAS,CAAC,CAAC;YAE/B,IAAI,kBAAkB,EAAE,CAAC;gBACvB,qBAAqB,CAAC,OAAO,GAAG,kBAAkB,CAAC;gBACnD,qBAAqB,CAAC,kBAAkB,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;KACF,CAAC;IACF,uDAAuD;IACvD,CAAC,cAAc,EAAE,iBAAiB,EAAE,mBAAmB,CAAC,CACzD,CAAC;IAEF,OAAO,KAAC,iBAAiB,CAAC,QAAQ,IAAC,KAAK,EAAE,UAAU,YAAG,QAAQ,GAA8B,CAAC;AAChG,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,aAAa;IAC3B,MAAM,UAAU,GAAG,UAAU,CAAC,iBAAiB,CAAC,CAAC;IACjD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC","sourcesContent":["import { createContext, type ReactNode, useContext, useMemo, useRef, useState } from 'react';\n\nexport interface TableFocus {\n focusedRowKey: string;\n focusedColumnKey: string;\n childFocusStrategy: ChildFocusStrategy;\n setFocus: (rowKey: string, columnKey: string, childFocusStrategy?: ChildFocusStrategy) => void;\n}\n\nexport type ChildFocusStrategy = 'first' | 'last';\n\nconst TableFocusContext = createContext<TableFocus | null>(null);\n\nexport function TableFocusProvider({ children }: { children: ReactNode }) {\n // When table focus is updated, we want to trigger a re-render,\n // but we also want immediate access to the new values.\n // Hence why they are stored as both a ref and a state.\n const focusedRowKeyRef = useRef<string>('');\n const [_focusedRowKey, setFocusedRowKey] = useState<string>('');\n const focusedColumnKeyRef = useRef<string>('');\n const [_focusedColumnKey, setFocusedColumnKey] = useState<string>('');\n const childFocusStrategyRef = useRef<ChildFocusStrategy>('first');\n const [_childFocusStrategy, setChildFocusStrategy] = useState<ChildFocusStrategy>('first');\n\n const tableFocus: TableFocus = useMemo(\n () => ({\n get focusedRowKey() {\n return focusedRowKeyRef.current;\n },\n get focusedColumnKey() {\n return focusedColumnKeyRef.current;\n },\n get childFocusStrategy() {\n return childFocusStrategyRef.current;\n },\n setFocus: (rowKey, columnKey, childFocusStrategy) => {\n focusedRowKeyRef.current = rowKey;\n setFocusedRowKey(rowKey);\n\n focusedColumnKeyRef.current = columnKey;\n setFocusedColumnKey(columnKey);\n\n if (childFocusStrategy) {\n childFocusStrategyRef.current = childFocusStrategy;\n setChildFocusStrategy(childFocusStrategy);\n }\n },\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [_focusedRowKey, _focusedColumnKey, _childFocusStrategy],\n );\n\n return <TableFocusContext.Provider value={tableFocus}>{children}</TableFocusContext.Provider>;\n}\n\n// eslint-disable-next-line react-refresh/only-export-components\nexport function useTableFocus(): TableFocus {\n const tableFocus = useContext(TableFocusContext);\n if (!tableFocus) {\n throw new Error('Cannot use table focus outside of a table');\n }\n\n return tableFocus;\n}\n"]}
@@ -0,0 +1,10 @@
1
+ import { type ReactNode } from 'react';
2
+ export interface TableRowState {
3
+ rowKey: string;
4
+ }
5
+ export declare function TableRowStateProvider({ children, rowKey }: {
6
+ children: ReactNode;
7
+ rowKey: string;
8
+ }): import("react/jsx-runtime").JSX.Element;
9
+ export declare function useTableRowState(): TableRowState;
10
+ //# sourceMappingURL=row-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"row-state.d.ts","sourceRoot":"","sources":["../../../../../src/components/table/contexts/row-state.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,SAAS,EAAuB,MAAM,OAAO,CAAC;AAE3E,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;CAChB;AAID,wBAAgB,qBAAqB,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,2CASlG;AAGD,wBAAgB,gBAAgB,IAAI,aAAa,CAOhD"}
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext, useMemo } from 'react';
3
+ const TableRowStateContext = createContext(null);
4
+ export function TableRowStateProvider({ children, rowKey }) {
5
+ const tableRowState = useMemo(() => ({
6
+ rowKey,
7
+ }), [rowKey]);
8
+ return _jsx(TableRowStateContext.Provider, { value: tableRowState, children: children });
9
+ }
10
+ // eslint-disable-next-line react-refresh/only-export-components
11
+ export function useTableRowState() {
12
+ const tableRowState = useContext(TableRowStateContext);
13
+ if (!tableRowState) {
14
+ throw new Error('Cannot use table row state outside of a table row');
15
+ }
16
+ return tableRowState;
17
+ }
18
+ //# sourceMappingURL=row-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"row-state.js","sourceRoot":"","sources":["../../../../../src/components/table/contexts/row-state.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAkB,UAAU,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAM3E,MAAM,oBAAoB,GAAG,aAAa,CAAuB,IAAI,CAAC,CAAC;AAEvE,MAAM,UAAU,qBAAqB,CAAC,EAAE,QAAQ,EAAE,MAAM,EAA2C;IACjG,MAAM,aAAa,GAAkB,OAAO,CAC1C,GAAG,EAAE,CAAC,CAAC;QACL,MAAM;KACP,CAAC,EACF,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,OAAO,KAAC,oBAAoB,CAAC,QAAQ,IAAC,KAAK,EAAE,aAAa,YAAG,QAAQ,GAAiC,CAAC;AACzG,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,gBAAgB;IAC9B,MAAM,aAAa,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC;IACvD,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC","sourcesContent":["import { createContext, type ReactNode, useContext, useMemo } from 'react';\n\nexport interface TableRowState {\n rowKey: string;\n}\n\nconst TableRowStateContext = createContext<TableRowState | null>(null);\n\nexport function TableRowStateProvider({ children, rowKey }: { children: ReactNode; rowKey: string }) {\n const tableRowState: TableRowState = useMemo(\n () => ({\n rowKey,\n }),\n [rowKey],\n );\n\n return <TableRowStateContext.Provider value={tableRowState}>{children}</TableRowStateContext.Provider>;\n}\n\n// eslint-disable-next-line react-refresh/only-export-components\nexport function useTableRowState(): TableRowState {\n const tableRowState = useContext(TableRowStateContext);\n if (!tableRowState) {\n throw new Error('Cannot use table row state outside of a table row');\n }\n\n return tableRowState;\n}\n"]}
@@ -0,0 +1,7 @@
1
+ import { type RefObject } from 'react';
2
+ import type { NativeElementProps } from '../../types.js';
3
+ export interface UseTableCell {
4
+ cellProps: NativeElementProps<HTMLTableCellElement>;
5
+ }
6
+ export declare function useTableCell(ref: RefObject<HTMLTableCellElement>, rowKey: string, columnKey: string): UseTableCell;
7
+ //# sourceMappingURL=use-table-cell.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-table-cell.d.ts","sourceRoot":"","sources":["../../../../../src/components/table/hooks/use-table-cell.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC3G,OAAO,KAAK,EAAoB,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAI3E,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,kBAAkB,CAAC,oBAAoB,CAAC,CAAC;CACrD;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,SAAS,CAAC,oBAAoB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,CA6HlH"}
@@ -0,0 +1,122 @@
1
+ import { getFocusableTreeWalker, useFocusRing } from '@react-aria/focus';
2
+ import { isFocusVisible } from '@react-aria/interactions';
3
+ import { mergeProps } from '@react-aria/utils';
4
+ import { useLayoutEffect } from 'react';
5
+ import { useTableFocus } from '../contexts/focus.js';
6
+ import { focusTableChild } from '../utils/focus-table-child.js';
7
+ export function useTableCell(ref, rowKey, columnKey) {
8
+ const tableFocus = useTableFocus();
9
+ const isTabbable = rowKey === tableFocus.focusedRowKey && columnKey === tableFocus.focusedColumnKey;
10
+ // Handles focusing the cell.
11
+ // If there is a focusable child, it is focused, otherwise the cell itself is focused.
12
+ const focusCell = () => {
13
+ if (!ref.current) {
14
+ return;
15
+ }
16
+ // If focus is already on a focusable child within the cell, early return so we don't shift focus
17
+ if (ref.current.contains(document.activeElement) && ref.current !== document.activeElement) {
18
+ return;
19
+ }
20
+ const treeWalker = getFocusableTreeWalker(ref.current);
21
+ const focusable = tableFocus.childFocusStrategy === 'last' ? treeWalker.lastChild() : treeWalker.firstChild();
22
+ if (focusable) {
23
+ // Cell has focusable children, focus the child
24
+ focusTableChild(focusable);
25
+ }
26
+ else if (!ref.current.contains(document.activeElement)) {
27
+ // Cell has no focusable children and current focus is outside of the cell, focus the cell itself
28
+ focusTableChild(ref.current);
29
+ }
30
+ else if (ref.current === document.activeElement && !isTabbable) {
31
+ // Focus is on the current cell, but table focus is elsewhere, update table focus state
32
+ tableFocus.setFocus(rowKey, columnKey);
33
+ }
34
+ };
35
+ // Focus the cell DOM node when table focus moves to this cell
36
+ useLayoutEffect(() => {
37
+ if (isTabbable && !ref.current.contains(document.activeElement)) {
38
+ focusCell();
39
+ }
40
+ // eslint-disable-next-line react-hooks/exhaustive-deps
41
+ }, [ref, isTabbable]);
42
+ const onFocus = (e) => {
43
+ // Ignore focus events bubbling through portals
44
+ if (!e.currentTarget.contains(e.target)) {
45
+ return;
46
+ }
47
+ // If cell is already focused, return early
48
+ if (e.currentTarget.contains(e.relatedTarget)) {
49
+ return;
50
+ }
51
+ if (e.target !== ref.current) {
52
+ // If a child element of the cell receives focus, there are 3 scenarios:
53
+ // - focus happens through a press, we need to update table focus state to the current cell
54
+ // - focus happens through arrow key navigation within the table,
55
+ // we do nothing as table focus state would have already been updated earlier
56
+ // - focus happens through tabbing into the table from outside,
57
+ // we do nothing because we want to restore focus to the previously focused cell,
58
+ // and overriding table focus state would make that impossible
59
+ if (!isFocusVisible()) {
60
+ tableFocus.setFocus(rowKey, columnKey);
61
+ }
62
+ }
63
+ else {
64
+ // If the cell itself receives focus, wait a frame so that focus finishes propagating
65
+ // up to the tree, and move focus to a focusable child if possible.
66
+ requestAnimationFrame(() => {
67
+ if (document.activeElement === ref.current) {
68
+ focusCell();
69
+ }
70
+ });
71
+ }
72
+ };
73
+ // Handles keyboard navigation between focusable children within the cell.
74
+ const onKeyDownCapture = (e) => {
75
+ // Ignore keyboard events bubbling through portals
76
+ if (!e.currentTarget.contains(e.target) || !ref.current || !document.activeElement) {
77
+ return;
78
+ }
79
+ const walker = getFocusableTreeWalker(ref.current);
80
+ walker.currentNode = document.activeElement;
81
+ if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
82
+ // Move to the previous/next focusable element within the cell
83
+ const childElementToFocus = e.key === 'ArrowLeft' ? walker.previousNode() : walker.nextNode();
84
+ if (childElementToFocus && childElementToFocus !== ref.current) {
85
+ focusTableChild(childElementToFocus);
86
+ }
87
+ else {
88
+ // If there is no previous/next focusable element within the current cell, focus should move to the previous/next cell.
89
+ // This is handled by `useTable`, so we need to let the event bubble up to it.
90
+ // But we also don't want this event to reach children of the current cell, as arrow keys should be used exclusively for table navigation.
91
+ // Solution: re-dispatch the event from a parent element of the current cell.
92
+ ref.current.parentElement.dispatchEvent(new KeyboardEvent(e.nativeEvent.type, e.nativeEvent));
93
+ }
94
+ }
95
+ else if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
96
+ // Move to the previous/next cell in the current column.
97
+ // This is handled by `useTable`, so we need to let the event bubble up to it.
98
+ // But we also don't want this event to reach children of the current cell, as arrow keys should be used exclusively for table navigation.
99
+ // Solution: re-dispatch the event from a parent element of the current cell.
100
+ ref.current.parentElement?.dispatchEvent(new KeyboardEvent(e.nativeEvent.type, e.nativeEvent));
101
+ }
102
+ else {
103
+ // if we didn't handle anything, return early so we don't stop propagation and preventDefault
104
+ return;
105
+ }
106
+ e.preventDefault();
107
+ e.stopPropagation();
108
+ };
109
+ const { focusProps, isFocused } = useFocusRing();
110
+ const customProps = {
111
+ tabIndex: isTabbable ? 0 : -1,
112
+ onFocus,
113
+ onKeyDownCapture,
114
+ 'data-cell-row-key': rowKey,
115
+ 'data-cell-column-key': columnKey,
116
+ 'data-focused': isFocused || undefined,
117
+ };
118
+ return {
119
+ cellProps: mergeProps(focusProps, customProps),
120
+ };
121
+ }
122
+ //# sourceMappingURL=use-table-cell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-table-cell.js","sourceRoot":"","sources":["../../../../../src/components/table/hooks/use-table-cell.ts"],"names":[],"mappings":"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","sourcesContent":["import { getFocusableTreeWalker, useFocusRing } from '@react-aria/focus';\nimport { isFocusVisible } from '@react-aria/interactions';\nimport { mergeProps } from '@react-aria/utils';\nimport { type KeyboardEventHandler, useLayoutEffect, type FocusEventHandler, type RefObject } from 'react';\nimport type { FocusableElement, NativeElementProps } from '../../types.js';\nimport { useTableFocus } from '../contexts/focus.js';\nimport { focusTableChild } from '../utils/focus-table-child.js';\n\nexport interface UseTableCell {\n cellProps: NativeElementProps<HTMLTableCellElement>;\n}\n\nexport function useTableCell(ref: RefObject<HTMLTableCellElement>, rowKey: string, columnKey: string): UseTableCell {\n const tableFocus = useTableFocus();\n\n const isTabbable = rowKey === tableFocus.focusedRowKey && columnKey === tableFocus.focusedColumnKey;\n\n // Handles focusing the cell.\n // If there is a focusable child, it is focused, otherwise the cell itself is focused.\n const focusCell = () => {\n if (!ref.current) {\n return;\n }\n\n // If focus is already on a focusable child within the cell, early return so we don't shift focus\n if (ref.current.contains(document.activeElement) && ref.current !== document.activeElement) {\n return;\n }\n\n const treeWalker = getFocusableTreeWalker(ref.current);\n const focusable = tableFocus.childFocusStrategy === 'last' ? treeWalker.lastChild() : treeWalker.firstChild();\n\n if (focusable) {\n // Cell has focusable children, focus the child\n focusTableChild(focusable as FocusableElement);\n } else if (!ref.current.contains(document.activeElement)) {\n // Cell has no focusable children and current focus is outside of the cell, focus the cell itself\n focusTableChild(ref.current);\n } else if (ref.current === document.activeElement && !isTabbable) {\n // Focus is on the current cell, but table focus is elsewhere, update table focus state\n tableFocus.setFocus(rowKey, columnKey);\n }\n };\n\n // Focus the cell DOM node when table focus moves to this cell\n useLayoutEffect(() => {\n if (isTabbable && !ref.current!.contains(document.activeElement)) {\n focusCell();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [ref, isTabbable]);\n\n const onFocus: FocusEventHandler = (e) => {\n // Ignore focus events bubbling through portals\n if (!e.currentTarget.contains(e.target)) {\n return;\n }\n\n // If cell is already focused, return early\n if (e.currentTarget.contains(e.relatedTarget)) {\n return;\n }\n\n if (e.target !== ref.current) {\n // If a child element of the cell receives focus, there are 3 scenarios:\n // - focus happens through a press, we need to update table focus state to the current cell\n // - focus happens through arrow key navigation within the table,\n // we do nothing as table focus state would have already been updated earlier\n // - focus happens through tabbing into the table from outside,\n // we do nothing because we want to restore focus to the previously focused cell,\n // and overriding table focus state would make that impossible\n if (!isFocusVisible()) {\n tableFocus.setFocus(rowKey, columnKey);\n }\n } else {\n // If the cell itself receives focus, wait a frame so that focus finishes propagating\n // up to the tree, and move focus to a focusable child if possible.\n requestAnimationFrame(() => {\n if (document.activeElement === ref.current) {\n focusCell();\n }\n });\n }\n };\n\n // Handles keyboard navigation between focusable children within the cell.\n const onKeyDownCapture: KeyboardEventHandler = (e) => {\n // Ignore keyboard events bubbling through portals\n if (!e.currentTarget.contains(e.target as Element) || !ref.current || !document.activeElement) {\n return;\n }\n\n const walker = getFocusableTreeWalker(ref.current);\n walker.currentNode = document.activeElement;\n\n if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {\n // Move to the previous/next focusable element within the cell\n const childElementToFocus = e.key === 'ArrowLeft' ? walker.previousNode() : walker.nextNode();\n\n if (childElementToFocus && childElementToFocus !== ref.current) {\n focusTableChild(childElementToFocus as FocusableElement);\n } else {\n // If there is no previous/next focusable element within the current cell, focus should move to the previous/next cell.\n // This is handled by `useTable`, so we need to let the event bubble up to it.\n // But we also don't want this event to reach children of the current cell, as arrow keys should be used exclusively for table navigation.\n // Solution: re-dispatch the event from a parent element of the current cell.\n ref.current.parentElement!.dispatchEvent(new KeyboardEvent(e.nativeEvent.type, e.nativeEvent));\n }\n } else if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {\n // Move to the previous/next cell in the current column.\n // This is handled by `useTable`, so we need to let the event bubble up to it.\n // But we also don't want this event to reach children of the current cell, as arrow keys should be used exclusively for table navigation.\n // Solution: re-dispatch the event from a parent element of the current cell.\n ref.current.parentElement?.dispatchEvent(new KeyboardEvent(e.nativeEvent.type, e.nativeEvent));\n } else {\n // if we didn't handle anything, return early so we don't stop propagation and preventDefault\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n };\n\n const { focusProps, isFocused } = useFocusRing();\n\n const customProps: NativeElementProps<HTMLTableCellElement> = {\n tabIndex: isTabbable ? 0 : -1,\n onFocus,\n onKeyDownCapture,\n 'data-cell-row-key': rowKey,\n 'data-cell-column-key': columnKey,\n 'data-focused': isFocused || undefined,\n };\n\n return {\n cellProps: mergeProps(focusProps, customProps),\n };\n}\n"]}
@@ -0,0 +1,7 @@
1
+ import type { RefObject } from 'react';
2
+ import type { NativeElementProps } from '../../types.js';
3
+ export interface UseTable {
4
+ tableProps: NativeElementProps<HTMLTableElement>;
5
+ }
6
+ export declare function useTable(ref: RefObject<HTMLTableElement>): UseTable;
7
+ //# sourceMappingURL=use-table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-table.d.ts","sourceRoot":"","sources":["../../../../../src/components/table/hooks/use-table.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAqB,SAAS,EAAE,MAAM,OAAO,CAAC;AAC1D,OAAO,KAAK,EAAoB,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAI3E,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;CAClD;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC,gBAAgB,CAAC,GAAG,QAAQ,CAsJnE"}
@@ -0,0 +1,139 @@
1
+ import { getFocusableTreeWalker, useFocusable } from '@react-aria/focus';
2
+ import { getInteractionModality, useKeyboard } from '@react-aria/interactions';
3
+ import { isMac, mergeProps } from '@react-aria/utils';
4
+ import { useTableFocus } from '../contexts/focus.js';
5
+ import { focusTableChild } from '../utils/focus-table-child.js';
6
+ export function useTable(ref) {
7
+ const tableFocus = useTableFocus();
8
+ const restoreCellFocus = (e) => {
9
+ if (!tableFocus.focusedRowKey || !tableFocus.focusedColumnKey) {
10
+ // User hasn't interacted with the table yet.
11
+ // Focus the first or last cell, depending on which direction the user is tabbing from.
12
+ const lastFocusedElement = e.relatedTarget;
13
+ const cellElements = e.currentTarget.querySelectorAll('[data-cell-row-key][data-cell-column-key]');
14
+ let cellElementToFocus;
15
+ if (lastFocusedElement &&
16
+ e.currentTarget.compareDocumentPosition(lastFocusedElement) & Node.DOCUMENT_POSITION_FOLLOWING) {
17
+ cellElementToFocus = cellElements[cellElements.length - 1];
18
+ }
19
+ else {
20
+ cellElementToFocus = cellElements[0];
21
+ }
22
+ const { cellRowKey, cellColumnKey } = cellElementToFocus.dataset;
23
+ // We know the keys are defined, because we queried the DOM for elements that have them
24
+ tableFocus.setFocus(cellRowKey, cellColumnKey);
25
+ }
26
+ else {
27
+ const element = e.currentTarget.querySelector(`[data-cell-row-key='${CSS.escape(tableFocus.focusedRowKey)}'][data-cell-column-key='${CSS.escape(tableFocus.focusedColumnKey)}']`);
28
+ if (element) {
29
+ // If focus is already within the cell, don't refocus
30
+ if (!element.contains(document.activeElement)) {
31
+ focusTableChild(element);
32
+ }
33
+ }
34
+ }
35
+ };
36
+ const { focusableProps } = useFocusable({
37
+ onFocus: (e) => {
38
+ // Ignore focus events bubbling through portals
39
+ if (!e.currentTarget.contains(e.target)) {
40
+ return;
41
+ }
42
+ restoreCellFocus(e);
43
+ },
44
+ }, ref);
45
+ const { keyboardProps } = useKeyboard({
46
+ onKeyDown: (e) => {
47
+ // Ignore keyboard events bubbling through portals
48
+ if (!e.currentTarget.contains(e.target)) {
49
+ return;
50
+ }
51
+ const focusedCellElement = e.currentTarget.querySelector(`[data-cell-row-key='${CSS.escape(tableFocus.focusedRowKey)}'][data-cell-column-key='${CSS.escape(tableFocus.focusedColumnKey)}']`);
52
+ let cellElementToFocus = null;
53
+ let newChildFocusStrategy;
54
+ if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
55
+ // Focus previous/next cell in the same row
56
+ const selector = `[data-cell-row-key='${CSS.escape(tableFocus.focusedRowKey)}']:not([data-cell-column-key='${CSS.escape(tableFocus.focusedColumnKey)}'])`;
57
+ const walker = getFocusableTreeWalker(e.currentTarget, { accept: (node) => node.matches(selector) });
58
+ walker.currentNode = focusedCellElement;
59
+ cellElementToFocus = e.key === 'ArrowLeft' ? walker.previousNode() : walker.nextNode();
60
+ newChildFocusStrategy = e.key === 'ArrowLeft' ? 'last' : 'first';
61
+ }
62
+ else if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
63
+ // Focus previous/next cell in the same column
64
+ const selector = `[data-cell-column-key='${CSS.escape(tableFocus.focusedColumnKey)}']:not([data-cell-row-key='${CSS.escape(tableFocus.focusedRowKey)}'])`;
65
+ const walker = getFocusableTreeWalker(e.currentTarget, { accept: (node) => node.matches(selector) });
66
+ walker.currentNode = focusedCellElement;
67
+ cellElementToFocus = e.key === 'ArrowUp' ? walker.previousNode() : walker.nextNode();
68
+ }
69
+ else if (e.key === 'PageUp' || e.key === 'PageDown') {
70
+ // Move focus up/down by 5 rows
71
+ const selector = `[data-cell-column-key='${CSS.escape(tableFocus.focusedColumnKey)}']:not([data-cell-row-key='${CSS.escape(tableFocus.focusedRowKey)}'])`;
72
+ const walker = getFocusableTreeWalker(e.currentTarget, { accept: (node) => node.matches(selector) });
73
+ walker.currentNode = focusedCellElement;
74
+ const advance = e.key === 'PageUp' ? walker.previousNode.bind(walker) : walker.nextNode.bind(walker);
75
+ // `advance()` will do nothing if there's no appropriate node found, so it's safe to just call it 5 times
76
+ for (let i = 0; i < 5; i++) {
77
+ advance();
78
+ }
79
+ cellElementToFocus = walker.currentNode;
80
+ }
81
+ else if (e.key === 'Home' || e.key === 'End') {
82
+ // If Ctrl/Cmd is pressed, move focus to the first/last cell of the table;
83
+ // otherwise, move focus to the first/last cell of the current row
84
+ const selector = '[data-cell-row-key][data-cell-column-key]';
85
+ const walker = getFocusableTreeWalker(e.currentTarget, { accept: (node) => node.matches(selector) });
86
+ walker.currentNode = isCtrlKeyPressed(e) ? e.currentTarget : focusedCellElement.parentElement;
87
+ cellElementToFocus = e.key === 'Home' ? walker.firstChild() : walker.lastChild();
88
+ newChildFocusStrategy = e.key === 'Home' ? 'first' : 'last';
89
+ }
90
+ else if (e.key === 'Tab') {
91
+ // Table is supposed to be a single Tab stop, but cells may contain elements that are tabbable (checkboxes, buttons, menus, etc.).
92
+ // We don't control the rendering of these elements, so we can't override their tabIndex to prevent tabbing.
93
+ // Instead, we detect when Tab key is pressed, and move focus manually to the guard element before/after the table,
94
+ // so that the browser default behavior will apply starting from that element rather than the currently focused one.
95
+ const tableElement = e.currentTarget;
96
+ const guardElement = e.shiftKey ? tableElement.previousElementSibling : tableElement.nextElementSibling;
97
+ if (guardElement) {
98
+ focusTableChild(guardElement);
99
+ }
100
+ return;
101
+ }
102
+ else {
103
+ // if we didn't handle anything, return early so we don't preventDefault
104
+ return;
105
+ }
106
+ if (cellElementToFocus) {
107
+ const { cellRowKey, cellColumnKey } = cellElementToFocus.dataset;
108
+ // We know the keys are defined, because we queried the DOM for elements that have them
109
+ tableFocus.setFocus(cellRowKey, cellColumnKey, newChildFocusStrategy);
110
+ }
111
+ e.preventDefault();
112
+ },
113
+ });
114
+ const customProps = {
115
+ role: 'grid',
116
+ // If no cell is tabbable within the table, make the table itself tabbable,
117
+ // otherwise the Tab key will just skip it
118
+ tabIndex: tableFocus.focusedRowKey && tableFocus.focusedColumnKey ? -1 : 0,
119
+ onFocusCapture: (e) => {
120
+ // If we're navigating into the table with a keyboard, focus the last focused cell instead of the first tabbable element
121
+ if (getInteractionModality() === 'keyboard' &&
122
+ !e.currentTarget.contains(e.relatedTarget) &&
123
+ e.currentTarget.contains(e.target)) {
124
+ restoreCellFocus(e);
125
+ }
126
+ },
127
+ };
128
+ return {
129
+ tableProps: mergeProps(focusableProps, keyboardProps, customProps),
130
+ };
131
+ }
132
+ // TODO: use `isCtrlKeyPressed` from `@react-aria/utils` after version upgrade
133
+ function isCtrlKeyPressed(e) {
134
+ if (isMac()) {
135
+ return e.metaKey;
136
+ }
137
+ return e.ctrlKey;
138
+ }
139
+ //# sourceMappingURL=use-table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-table.js","sourceRoot":"","sources":["../../../../../src/components/table/hooks/use-table.ts"],"names":[],"mappings":"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","sourcesContent":["import { getFocusableTreeWalker, useFocusable } from '@react-aria/focus';\nimport { getInteractionModality, useKeyboard } from '@react-aria/interactions';\nimport { isMac, mergeProps } from '@react-aria/utils';\nimport type { FocusEventHandler, RefObject } from 'react';\nimport type { FocusableElement, NativeElementProps } from '../../types.js';\nimport { type ChildFocusStrategy, useTableFocus } from '../contexts/focus.js';\nimport { focusTableChild } from '../utils/focus-table-child.js';\n\nexport interface UseTable {\n tableProps: NativeElementProps<HTMLTableElement>;\n}\n\nexport function useTable(ref: RefObject<HTMLTableElement>): UseTable {\n const tableFocus = useTableFocus();\n\n const restoreCellFocus: FocusEventHandler = (e) => {\n if (!tableFocus.focusedRowKey || !tableFocus.focusedColumnKey) {\n // User hasn't interacted with the table yet.\n // Focus the first or last cell, depending on which direction the user is tabbing from.\n const lastFocusedElement = e.relatedTarget as Element;\n const cellElements = e.currentTarget.querySelectorAll('[data-cell-row-key][data-cell-column-key]');\n let cellElementToFocus: Element | undefined;\n\n if (\n lastFocusedElement &&\n e.currentTarget.compareDocumentPosition(lastFocusedElement) & Node.DOCUMENT_POSITION_FOLLOWING\n ) {\n cellElementToFocus = cellElements[cellElements.length - 1];\n } else {\n cellElementToFocus = cellElements[0];\n }\n\n const { cellRowKey, cellColumnKey } = (cellElementToFocus as HTMLTableCellElement).dataset;\n\n // We know the keys are defined, because we queried the DOM for elements that have them\n tableFocus.setFocus(cellRowKey!, cellColumnKey!);\n } else {\n const element = e.currentTarget.querySelector(\n `[data-cell-row-key='${CSS.escape(tableFocus.focusedRowKey)}'][data-cell-column-key='${CSS.escape(tableFocus.focusedColumnKey)}']`,\n ) as HTMLTableCellElement;\n\n if (element) {\n // If focus is already within the cell, don't refocus\n if (!element.contains(document.activeElement)) {\n focusTableChild(element);\n }\n }\n }\n };\n\n const { focusableProps } = useFocusable(\n {\n onFocus: (e) => {\n // Ignore focus events bubbling through portals\n if (!e.currentTarget.contains(e.target)) {\n return;\n }\n\n restoreCellFocus(e);\n },\n },\n ref,\n );\n\n const { keyboardProps } = useKeyboard({\n onKeyDown: (e) => {\n // Ignore keyboard events bubbling through portals\n if (!e.currentTarget.contains(e.target)) {\n return;\n }\n\n const focusedCellElement = e.currentTarget.querySelector(\n `[data-cell-row-key='${CSS.escape(tableFocus.focusedRowKey)}'][data-cell-column-key='${CSS.escape(tableFocus.focusedColumnKey)}']`,\n ) as HTMLTableCellElement;\n\n let cellElementToFocus: Node | null = null;\n let newChildFocusStrategy: ChildFocusStrategy | undefined;\n\n if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {\n // Focus previous/next cell in the same row\n const selector = `[data-cell-row-key='${CSS.escape(tableFocus.focusedRowKey)}']:not([data-cell-column-key='${CSS.escape(tableFocus.focusedColumnKey)}'])`;\n const walker = getFocusableTreeWalker(e.currentTarget, { accept: (node) => node.matches(selector) });\n walker.currentNode = focusedCellElement;\n cellElementToFocus = e.key === 'ArrowLeft' ? walker.previousNode() : walker.nextNode();\n newChildFocusStrategy = e.key === 'ArrowLeft' ? 'last' : 'first';\n } else if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {\n // Focus previous/next cell in the same column\n const selector = `[data-cell-column-key='${CSS.escape(tableFocus.focusedColumnKey)}']:not([data-cell-row-key='${CSS.escape(tableFocus.focusedRowKey)}'])`;\n const walker = getFocusableTreeWalker(e.currentTarget, { accept: (node) => node.matches(selector) });\n walker.currentNode = focusedCellElement;\n cellElementToFocus = e.key === 'ArrowUp' ? walker.previousNode() : walker.nextNode();\n } else if (e.key === 'PageUp' || e.key === 'PageDown') {\n // Move focus up/down by 5 rows\n const selector = `[data-cell-column-key='${CSS.escape(tableFocus.focusedColumnKey)}']:not([data-cell-row-key='${CSS.escape(tableFocus.focusedRowKey)}'])`;\n const walker = getFocusableTreeWalker(e.currentTarget, { accept: (node) => node.matches(selector) });\n walker.currentNode = focusedCellElement;\n\n const advance = e.key === 'PageUp' ? walker.previousNode.bind(walker) : walker.nextNode.bind(walker);\n\n // `advance()` will do nothing if there's no appropriate node found, so it's safe to just call it 5 times\n for (let i = 0; i < 5; i++) {\n advance();\n }\n\n cellElementToFocus = walker.currentNode;\n } else if (e.key === 'Home' || e.key === 'End') {\n // If Ctrl/Cmd is pressed, move focus to the first/last cell of the table;\n // otherwise, move focus to the first/last cell of the current row\n const selector = '[data-cell-row-key][data-cell-column-key]';\n const walker = getFocusableTreeWalker(e.currentTarget, { accept: (node) => node.matches(selector) });\n walker.currentNode = isCtrlKeyPressed(e) ? e.currentTarget : focusedCellElement.parentElement!;\n cellElementToFocus = e.key === 'Home' ? walker.firstChild() : walker.lastChild();\n newChildFocusStrategy = e.key === 'Home' ? 'first' : 'last';\n } else if (e.key === 'Tab') {\n // Table is supposed to be a single Tab stop, but cells may contain elements that are tabbable (checkboxes, buttons, menus, etc.).\n // We don't control the rendering of these elements, so we can't override their tabIndex to prevent tabbing.\n // Instead, we detect when Tab key is pressed, and move focus manually to the guard element before/after the table,\n // so that the browser default behavior will apply starting from that element rather than the currently focused one.\n const tableElement = e.currentTarget as HTMLTableElement;\n const guardElement = e.shiftKey ? tableElement.previousElementSibling : tableElement.nextElementSibling;\n\n if (guardElement) {\n focusTableChild(guardElement as FocusableElement);\n }\n\n return;\n } else {\n // if we didn't handle anything, return early so we don't preventDefault\n return;\n }\n\n if (cellElementToFocus) {\n const { cellRowKey, cellColumnKey } = (cellElementToFocus as HTMLTableCellElement).dataset;\n\n // We know the keys are defined, because we queried the DOM for elements that have them\n tableFocus.setFocus(cellRowKey!, cellColumnKey!, newChildFocusStrategy);\n }\n\n e.preventDefault();\n },\n });\n\n const customProps: NativeElementProps<HTMLTableElement> = {\n role: 'grid',\n // If no cell is tabbable within the table, make the table itself tabbable,\n // otherwise the Tab key will just skip it\n tabIndex: tableFocus.focusedRowKey && tableFocus.focusedColumnKey ? -1 : 0,\n onFocusCapture: (e) => {\n // If we're navigating into the table with a keyboard, focus the last focused cell instead of the first tabbable element\n if (\n getInteractionModality() === 'keyboard' &&\n !e.currentTarget.contains(e.relatedTarget) &&\n e.currentTarget.contains(e.target)\n ) {\n restoreCellFocus(e);\n }\n },\n };\n\n return {\n tableProps: mergeProps(focusableProps, keyboardProps, customProps),\n };\n}\n\n// TODO: use `isCtrlKeyPressed` from `@react-aria/utils` after version upgrade\nfunction isCtrlKeyPressed(e: { ctrlKey: boolean; metaKey: boolean }): boolean {\n if (isMac()) {\n return e.metaKey;\n }\n\n return e.ctrlKey;\n}\n"]}
@@ -0,0 +1,26 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { CommonProps } from '../types.js';
3
+ export interface UNSTABLE_TableBodyCellProps extends CommonProps {
4
+ children: ReactNode;
5
+ /**
6
+ * A unique identifier for the column that this cell belongs to.
7
+ * Cells that belong to the same column must have the same `columnKey`.
8
+ */
9
+ columnKey: string;
10
+ /**
11
+ * The position of the column that this cell belongs to within the full dataset.
12
+ *
13
+ * Provide this value if your table presents a subset of columns, such as when the user toggles column visibility.
14
+ *
15
+ * This number must be:
16
+ * - greater than or equal to `1`
17
+ * - greater than the `columnNumber` of any previous cells in the current row
18
+ * - less than or equal to the `totalColumnCount` of the parent `Table`
19
+ *
20
+ * Use together with `totalColumnCount` on the `Table` component.
21
+ */
22
+ columnNumber?: number;
23
+ }
24
+ declare const _UNSTABLE_TableBodyCell: (props: UNSTABLE_TableBodyCellProps & import("react").RefAttributes<HTMLTableCellElement>) => import("react").JSX.Element | null;
25
+ export { _UNSTABLE_TableBodyCell as UNSTABLE_TableBodyCell };
26
+ //# sourceMappingURL=table-body-cell.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table-body-cell.d.ts","sourceRoot":"","sources":["../../../../src/components/table/table-body-cell.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAgB,SAAS,EAAE,MAAM,OAAO,CAAC;AAErD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI/C,MAAM,WAAW,2BAA4B,SAAQ,WAAW;IAC9D,QAAQ,EAAE,SAAS,CAAC;IACpB;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;;;;;;OAWG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAuBD,QAAA,MAAM,uBAAuB,kIAAsD,CAAC;AAEpF,OAAO,EAAE,uBAAuB,IAAI,sBAAsB,EAAE,CAAC"}