@lucasbernardosn/react-table 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (271) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +268 -2
  3. package/dist/_virtual/_rolldown/runtime.js +13 -0
  4. package/dist/components/column-menu/column-menu-check.d.ts +8 -0
  5. package/dist/components/column-menu/column-menu-check.d.ts.map +1 -0
  6. package/dist/components/column-menu/column-menu-check.js +17 -0
  7. package/dist/components/column-menu/column-menu-check.js.map +1 -0
  8. package/dist/components/column-menu/column-menu-hide-item.d.ts +23 -0
  9. package/dist/components/column-menu/column-menu-hide-item.d.ts.map +1 -0
  10. package/dist/components/column-menu/column-menu-hide-item.js +27 -0
  11. package/dist/components/column-menu/column-menu-hide-item.js.map +1 -0
  12. package/dist/components/column-menu/column-menu-labels.d.ts +21 -0
  13. package/dist/components/column-menu/column-menu-labels.d.ts.map +1 -0
  14. package/dist/components/column-menu/column-menu-labels.js +14 -0
  15. package/dist/components/column-menu/column-menu-labels.js.map +1 -0
  16. package/dist/components/column-menu/column-menu-pin-items.d.ts +25 -0
  17. package/dist/components/column-menu/column-menu-pin-items.d.ts.map +1 -0
  18. package/dist/components/column-menu/column-menu-pin-items.js +64 -0
  19. package/dist/components/column-menu/column-menu-pin-items.js.map +1 -0
  20. package/dist/components/column-menu/column-menu-popup.d.ts +40 -0
  21. package/dist/components/column-menu/column-menu-popup.d.ts.map +1 -0
  22. package/dist/components/column-menu/column-menu-popup.js +67 -0
  23. package/dist/components/column-menu/column-menu-popup.js.map +1 -0
  24. package/dist/components/column-menu/column-menu-root.d.ts +34 -0
  25. package/dist/components/column-menu/column-menu-root.d.ts.map +1 -0
  26. package/dist/components/column-menu/column-menu-root.js +36 -0
  27. package/dist/components/column-menu/column-menu-root.js.map +1 -0
  28. package/dist/components/column-menu/column-menu-sort-items.d.ts +30 -0
  29. package/dist/components/column-menu/column-menu-sort-items.d.ts.map +1 -0
  30. package/dist/components/column-menu/column-menu-sort-items.js +62 -0
  31. package/dist/components/column-menu/column-menu-sort-items.js.map +1 -0
  32. package/dist/components/column-menu/column-menu-trigger.d.ts +23 -0
  33. package/dist/components/column-menu/column-menu-trigger.d.ts.map +1 -0
  34. package/dist/components/column-menu/column-menu-trigger.js +38 -0
  35. package/dist/components/column-menu/column-menu-trigger.js.map +1 -0
  36. package/dist/components/column-menu/index.d.ts +2 -0
  37. package/dist/components/column-menu/index.js +2 -0
  38. package/dist/components/column-menu/index.parts.d.ts +13 -0
  39. package/dist/components/column-menu/index.parts.d.ts.map +1 -0
  40. package/dist/components/column-menu/index.parts.js +20 -0
  41. package/dist/components/column-menu/index.parts.js.map +1 -0
  42. package/dist/components/columns-panel/columns-panel-item.d.ts +34 -0
  43. package/dist/components/columns-panel/columns-panel-item.d.ts.map +1 -0
  44. package/dist/components/columns-panel/columns-panel-item.js +109 -0
  45. package/dist/components/columns-panel/columns-panel-item.js.map +1 -0
  46. package/dist/components/columns-panel/columns-panel-root.d.ts +51 -0
  47. package/dist/components/columns-panel/columns-panel-root.d.ts.map +1 -0
  48. package/dist/components/columns-panel/columns-panel-root.js +134 -0
  49. package/dist/components/columns-panel/columns-panel-root.js.map +1 -0
  50. package/dist/components/columns-panel/get-columns-panel-column-order.d.ts +16 -0
  51. package/dist/components/columns-panel/get-columns-panel-column-order.d.ts.map +1 -0
  52. package/dist/components/columns-panel/get-columns-panel-column-order.js +24 -0
  53. package/dist/components/columns-panel/get-columns-panel-column-order.js.map +1 -0
  54. package/dist/components/columns-panel/index.d.ts +2 -0
  55. package/dist/components/columns-panel/index.js +2 -0
  56. package/dist/components/columns-panel/index.parts.d.ts +8 -0
  57. package/dist/components/columns-panel/index.parts.d.ts.map +1 -0
  58. package/dist/components/columns-panel/index.parts.js +12 -0
  59. package/dist/components/columns-panel/index.parts.js.map +1 -0
  60. package/dist/components/data-table/body/data-table-body.d.ts +58 -0
  61. package/dist/components/data-table/body/data-table-body.d.ts.map +1 -0
  62. package/dist/components/data-table/body/data-table-body.js +99 -0
  63. package/dist/components/data-table/body/data-table-body.js.map +1 -0
  64. package/dist/components/data-table/body/data-table-cell.d.ts +26 -0
  65. package/dist/components/data-table/body/data-table-cell.d.ts.map +1 -0
  66. package/dist/components/data-table/body/data-table-cell.js +80 -0
  67. package/dist/components/data-table/body/data-table-cell.js.map +1 -0
  68. package/dist/components/data-table/body/data-table-empty.d.ts +38 -0
  69. package/dist/components/data-table/body/data-table-empty.d.ts.map +1 -0
  70. package/dist/components/data-table/body/data-table-empty.js +71 -0
  71. package/dist/components/data-table/body/data-table-empty.js.map +1 -0
  72. package/dist/components/data-table/body/data-table-row-focus.d.ts +32 -0
  73. package/dist/components/data-table/body/data-table-row-focus.d.ts.map +1 -0
  74. package/dist/components/data-table/body/data-table-row-focus.js +58 -0
  75. package/dist/components/data-table/body/data-table-row-focus.js.map +1 -0
  76. package/dist/components/data-table/body/data-table-row.d.ts +67 -0
  77. package/dist/components/data-table/body/data-table-row.d.ts.map +1 -0
  78. package/dist/components/data-table/body/data-table-row.js +154 -0
  79. package/dist/components/data-table/body/data-table-row.js.map +1 -0
  80. package/dist/components/data-table/body/use-data-table-row-focus-recovery.d.ts +19 -0
  81. package/dist/components/data-table/body/use-data-table-row-focus-recovery.d.ts.map +1 -0
  82. package/dist/components/data-table/body/use-data-table-row-focus-recovery.js +64 -0
  83. package/dist/components/data-table/body/use-data-table-row-focus-recovery.js.map +1 -0
  84. package/dist/components/data-table/header/data-table-header-button.d.ts +25 -0
  85. package/dist/components/data-table/header/data-table-header-button.d.ts.map +1 -0
  86. package/dist/components/data-table/header/data-table-header-button.js +57 -0
  87. package/dist/components/data-table/header/data-table-header-button.js.map +1 -0
  88. package/dist/components/data-table/header/data-table-header-cell.d.ts +34 -0
  89. package/dist/components/data-table/header/data-table-header-cell.d.ts.map +1 -0
  90. package/dist/components/data-table/header/data-table-header-cell.js +97 -0
  91. package/dist/components/data-table/header/data-table-header-cell.js.map +1 -0
  92. package/dist/components/data-table/header/data-table-header-content.d.ts +21 -0
  93. package/dist/components/data-table/header/data-table-header-content.d.ts.map +1 -0
  94. package/dist/components/data-table/header/data-table-header-content.js +37 -0
  95. package/dist/components/data-table/header/data-table-header-content.js.map +1 -0
  96. package/dist/components/data-table/header/data-table-header-row.d.ts +15 -0
  97. package/dist/components/data-table/header/data-table-header-row.d.ts.map +1 -0
  98. package/dist/components/data-table/header/data-table-header-row.js +28 -0
  99. package/dist/components/data-table/header/data-table-header-row.js.map +1 -0
  100. package/dist/components/data-table/header/data-table-header.d.ts +46 -0
  101. package/dist/components/data-table/header/data-table-header.d.ts.map +1 -0
  102. package/dist/components/data-table/header/data-table-header.js +80 -0
  103. package/dist/components/data-table/header/data-table-header.js.map +1 -0
  104. package/dist/components/data-table/index.d.ts +2 -0
  105. package/dist/components/data-table/index.js +2 -0
  106. package/dist/components/data-table/index.parts.d.ts +33 -0
  107. package/dist/components/data-table/index.parts.d.ts.map +1 -0
  108. package/dist/components/data-table/index.parts.js +62 -0
  109. package/dist/components/data-table/index.parts.js.map +1 -0
  110. package/dist/components/data-table/loading/get-data-table-loading-without-rows.d.ts +16 -0
  111. package/dist/components/data-table/loading/get-data-table-loading-without-rows.d.ts.map +1 -0
  112. package/dist/components/data-table/loading/get-data-table-loading-without-rows.js +18 -0
  113. package/dist/components/data-table/loading/get-data-table-loading-without-rows.js.map +1 -0
  114. package/dist/components/data-table/loading/use-data-table-loading-inert.d.ts +16 -0
  115. package/dist/components/data-table/loading/use-data-table-loading-inert.d.ts.map +1 -0
  116. package/dist/components/data-table/loading/use-data-table-loading-inert.js +54 -0
  117. package/dist/components/data-table/loading/use-data-table-loading-inert.js.map +1 -0
  118. package/dist/components/data-table/loading/use-data-table-loading.d.ts +13 -0
  119. package/dist/components/data-table/loading/use-data-table-loading.d.ts.map +1 -0
  120. package/dist/components/data-table/loading/use-data-table-loading.js +40 -0
  121. package/dist/components/data-table/loading/use-data-table-loading.js.map +1 -0
  122. package/dist/components/data-table/pagination/data-table-page-button.d.ts +45 -0
  123. package/dist/components/data-table/pagination/data-table-page-button.d.ts.map +1 -0
  124. package/dist/components/data-table/pagination/data-table-page-button.js +67 -0
  125. package/dist/components/data-table/pagination/data-table-page-button.js.map +1 -0
  126. package/dist/components/data-table/pagination/data-table-page-size-select.d.ts +47 -0
  127. package/dist/components/data-table/pagination/data-table-page-size-select.d.ts.map +1 -0
  128. package/dist/components/data-table/pagination/data-table-page-size-select.js +68 -0
  129. package/dist/components/data-table/pagination/data-table-page-size-select.js.map +1 -0
  130. package/dist/components/data-table/pagination/data-table-page-status.d.ts +43 -0
  131. package/dist/components/data-table/pagination/data-table-page-status.d.ts.map +1 -0
  132. package/dist/components/data-table/pagination/data-table-page-status.js +48 -0
  133. package/dist/components/data-table/pagination/data-table-page-status.js.map +1 -0
  134. package/dist/components/data-table/pagination/data-table-pagination.d.ts +38 -0
  135. package/dist/components/data-table/pagination/data-table-pagination.d.ts.map +1 -0
  136. package/dist/components/data-table/pagination/data-table-pagination.js +87 -0
  137. package/dist/components/data-table/pagination/data-table-pagination.js.map +1 -0
  138. package/dist/components/data-table/pagination/data-table-row-range.d.ts +49 -0
  139. package/dist/components/data-table/pagination/data-table-row-range.d.ts.map +1 -0
  140. package/dist/components/data-table/pagination/data-table-row-range.js +63 -0
  141. package/dist/components/data-table/pagination/data-table-row-range.js.map +1 -0
  142. package/dist/components/data-table/pagination/data-table-selected-count.d.ts +37 -0
  143. package/dist/components/data-table/pagination/data-table-selected-count.d.ts.map +1 -0
  144. package/dist/components/data-table/pagination/data-table-selected-count.js +44 -0
  145. package/dist/components/data-table/pagination/data-table-selected-count.js.map +1 -0
  146. package/dist/components/data-table/pagination/use-data-table-page-scroll-reset.d.ts +15 -0
  147. package/dist/components/data-table/pagination/use-data-table-page-scroll-reset.d.ts.map +1 -0
  148. package/dist/components/data-table/pagination/use-data-table-page-scroll-reset.js +38 -0
  149. package/dist/components/data-table/pagination/use-data-table-page-scroll-reset.js.map +1 -0
  150. package/dist/components/data-table/resize/data-table-resize-handle.d.ts +48 -0
  151. package/dist/components/data-table/resize/data-table-resize-handle.d.ts.map +1 -0
  152. package/dist/components/data-table/resize/data-table-resize-handle.js +116 -0
  153. package/dist/components/data-table/resize/data-table-resize-handle.js.map +1 -0
  154. package/dist/components/data-table/resize/use-data-table-resize-scroll.d.ts +18 -0
  155. package/dist/components/data-table/resize/use-data-table-resize-scroll.d.ts.map +1 -0
  156. package/dist/components/data-table/resize/use-data-table-resize-scroll.js +55 -0
  157. package/dist/components/data-table/resize/use-data-table-resize-scroll.js.map +1 -0
  158. package/dist/components/data-table/root/data-table-grid-class-names.d.ts +10 -0
  159. package/dist/components/data-table/root/data-table-grid-class-names.d.ts.map +1 -0
  160. package/dist/components/data-table/root/data-table-grid-class-names.js +22 -0
  161. package/dist/components/data-table/root/data-table-grid-class-names.js.map +1 -0
  162. package/dist/components/data-table/root/data-table-root.d.ts +41 -0
  163. package/dist/components/data-table/root/data-table-root.d.ts.map +1 -0
  164. package/dist/components/data-table/root/data-table-root.js +72 -0
  165. package/dist/components/data-table/root/data-table-root.js.map +1 -0
  166. package/dist/components/data-table/root/data-table-scroll-area.d.ts +30 -0
  167. package/dist/components/data-table/root/data-table-scroll-area.d.ts.map +1 -0
  168. package/dist/components/data-table/root/data-table-scroll-area.js +137 -0
  169. package/dist/components/data-table/root/data-table-scroll-area.js.map +1 -0
  170. package/dist/components/data-table/root/get-data-table-column-layout.d.ts +45 -0
  171. package/dist/components/data-table/root/get-data-table-column-layout.d.ts.map +1 -0
  172. package/dist/components/data-table/root/get-data-table-column-layout.js +55 -0
  173. package/dist/components/data-table/root/get-data-table-column-layout.js.map +1 -0
  174. package/dist/components/data-table/root/get-data-table-column-pinning.d.ts +46 -0
  175. package/dist/components/data-table/root/get-data-table-column-pinning.d.ts.map +1 -0
  176. package/dist/components/data-table/root/get-data-table-column-pinning.js +46 -0
  177. package/dist/components/data-table/root/get-data-table-column-pinning.js.map +1 -0
  178. package/dist/components/data-table/root/get-data-table-scroll-parent.d.ts +13 -0
  179. package/dist/components/data-table/root/get-data-table-scroll-parent.d.ts.map +1 -0
  180. package/dist/components/data-table/root/get-data-table-scroll-parent.js +20 -0
  181. package/dist/components/data-table/root/get-data-table-scroll-parent.js.map +1 -0
  182. package/dist/components/data-table/root/use-data-table-column-layout.d.ts +25 -0
  183. package/dist/components/data-table/root/use-data-table-column-layout.d.ts.map +1 -0
  184. package/dist/components/data-table/root/use-data-table-column-layout.js +106 -0
  185. package/dist/components/data-table/root/use-data-table-column-layout.js.map +1 -0
  186. package/dist/components/data-table/root/use-data-table-header-offset.d.ts +15 -0
  187. package/dist/components/data-table/root/use-data-table-header-offset.d.ts.map +1 -0
  188. package/dist/components/data-table/root/use-data-table-header-offset.js +35 -0
  189. package/dist/components/data-table/root/use-data-table-header-offset.js.map +1 -0
  190. package/dist/components/data-table/selection/data-table-row-checkbox.d.ts +33 -0
  191. package/dist/components/data-table/selection/data-table-row-checkbox.d.ts.map +1 -0
  192. package/dist/components/data-table/selection/data-table-row-checkbox.js +50 -0
  193. package/dist/components/data-table/selection/data-table-row-checkbox.js.map +1 -0
  194. package/dist/components/data-table/selection/data-table-select-all-checkbox.d.ts +31 -0
  195. package/dist/components/data-table/selection/data-table-select-all-checkbox.d.ts.map +1 -0
  196. package/dist/components/data-table/selection/data-table-select-all-checkbox.js +44 -0
  197. package/dist/components/data-table/selection/data-table-select-all-checkbox.js.map +1 -0
  198. package/dist/components/data-table/selection/data-table-selection-bar.d.ts +51 -0
  199. package/dist/components/data-table/selection/data-table-selection-bar.d.ts.map +1 -0
  200. package/dist/components/data-table/selection/data-table-selection-bar.js +58 -0
  201. package/dist/components/data-table/selection/data-table-selection-bar.js.map +1 -0
  202. package/dist/components/data-table/selection/selection-column-def.d.ts +54 -0
  203. package/dist/components/data-table/selection/selection-column-def.d.ts.map +1 -0
  204. package/dist/components/data-table/selection/selection-column-def.js +55 -0
  205. package/dist/components/data-table/selection/selection-column-def.js.map +1 -0
  206. package/dist/components/data-table/sorting/data-table-sort-indicator.d.ts +26 -0
  207. package/dist/components/data-table/sorting/data-table-sort-indicator.d.ts.map +1 -0
  208. package/dist/components/data-table/sorting/data-table-sort-indicator.js +64 -0
  209. package/dist/components/data-table/sorting/data-table-sort-indicator.js.map +1 -0
  210. package/dist/components/data-table/sorting/data-table-sort-trigger.d.ts +31 -0
  211. package/dist/components/data-table/sorting/data-table-sort-trigger.d.ts.map +1 -0
  212. package/dist/components/data-table/sorting/data-table-sort-trigger.js +46 -0
  213. package/dist/components/data-table/sorting/data-table-sort-trigger.js.map +1 -0
  214. package/dist/components/data-table/toolbar/data-table-density-select.d.ts +39 -0
  215. package/dist/components/data-table/toolbar/data-table-density-select.d.ts.map +1 -0
  216. package/dist/components/data-table/toolbar/data-table-density-select.js +60 -0
  217. package/dist/components/data-table/toolbar/data-table-density-select.js.map +1 -0
  218. package/dist/components/data-table/toolbar/data-table-sort-column-select.d.ts +48 -0
  219. package/dist/components/data-table/toolbar/data-table-sort-column-select.d.ts.map +1 -0
  220. package/dist/components/data-table/toolbar/data-table-sort-column-select.js +79 -0
  221. package/dist/components/data-table/toolbar/data-table-sort-column-select.js.map +1 -0
  222. package/dist/components/data-table/toolbar/data-table-sort-direction-select.d.ts +40 -0
  223. package/dist/components/data-table/toolbar/data-table-sort-direction-select.d.ts.map +1 -0
  224. package/dist/components/data-table/toolbar/data-table-sort-direction-select.js +66 -0
  225. package/dist/components/data-table/toolbar/data-table-sort-direction-select.js.map +1 -0
  226. package/dist/features/active-row/active-row-feature.d.ts +22 -0
  227. package/dist/features/active-row/active-row-feature.d.ts.map +1 -0
  228. package/dist/features/active-row/active-row-feature.js +55 -0
  229. package/dist/features/active-row/active-row-feature.js.map +1 -0
  230. package/dist/features/active-row/active-row-feature.types.d.ts +64 -0
  231. package/dist/features/active-row/active-row-feature.types.d.ts.map +1 -0
  232. package/dist/features/active-row/active-row-feature.types.js +0 -0
  233. package/dist/features/column-alignment/column-alignment-feature.d.ts +23 -0
  234. package/dist/features/column-alignment/column-alignment-feature.d.ts.map +1 -0
  235. package/dist/features/column-alignment/column-alignment-feature.js +34 -0
  236. package/dist/features/column-alignment/column-alignment-feature.js.map +1 -0
  237. package/dist/features/column-alignment/column-alignment-feature.types.d.ts +34 -0
  238. package/dist/features/column-alignment/column-alignment-feature.types.d.ts.map +1 -0
  239. package/dist/features/column-alignment/column-alignment-feature.types.js +0 -0
  240. package/dist/features/index.d.ts +9 -0
  241. package/dist/features/index.js +5 -0
  242. package/dist/features/loading/loading-feature.d.ts +30 -0
  243. package/dist/features/loading/loading-feature.d.ts.map +1 -0
  244. package/dist/features/loading/loading-feature.js +48 -0
  245. package/dist/features/loading/loading-feature.js.map +1 -0
  246. package/dist/features/loading/loading-feature.types.d.ts +50 -0
  247. package/dist/features/loading/loading-feature.types.d.ts.map +1 -0
  248. package/dist/features/loading/loading-feature.types.js +0 -0
  249. package/dist/features/row-density/row-density-feature.d.ts +26 -0
  250. package/dist/features/row-density/row-density-feature.d.ts.map +1 -0
  251. package/dist/features/row-density/row-density-feature.js +44 -0
  252. package/dist/features/row-density/row-density-feature.js.map +1 -0
  253. package/dist/features/row-density/row-density-feature.types.d.ts +53 -0
  254. package/dist/features/row-density/row-density-feature.types.d.ts.map +1 -0
  255. package/dist/features/row-density/row-density-feature.types.js +0 -0
  256. package/dist/types/index.d.ts +2 -0
  257. package/dist/types/index.js +0 -0
  258. package/dist/types/table-with.d.ts +96 -0
  259. package/dist/types/table-with.d.ts.map +1 -0
  260. package/dist/types/table-with.js +0 -0
  261. package/dist/utils/get-default-column-label.d.ts +17 -0
  262. package/dist/utils/get-default-column-label.d.ts.map +1 -0
  263. package/dist/utils/get-default-column-label.js +18 -0
  264. package/dist/utils/get-default-column-label.js.map +1 -0
  265. package/dist/utils/has-feature.d.ts +54 -0
  266. package/dist/utils/has-feature.d.ts.map +1 -0
  267. package/dist/utils/has-feature.js +55 -0
  268. package/dist/utils/has-feature.js.map +1 -0
  269. package/dist/utils/index.d.ts +3 -0
  270. package/dist/utils/index.js +3 -0
  271. package/package.json +80 -3
@@ -0,0 +1,71 @@
1
+ import { hasTableFeature } from "../../../utils/has-feature.js";
2
+ import { TrayIcon } from "@phosphor-icons/react";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ import { mergeProps, useRender } from "@base-ui/react";
5
+ import { useSelector } from "@tanstack/react-store";
6
+ import { mergeTwClassNames } from "@lucasbernardosn/react-ui/utils";
7
+ import { EmptyState } from "@lucasbernardosn/react-ui/feedback/empty-state";
8
+ //#region src/components/data-table/body/data-table-empty.tsx
9
+ /**
10
+ * O estado vazio da tabela, para depois do `DataTable.Body`, dentro do `DataTable.Root`. Aparece
11
+ * quando o row model não tem linhas e a tabela não está carregando: com `loadingFeature`, a carga
12
+ * sem linhas mostra as linhas-fantasma do corpo, e não o vazio.
13
+ *
14
+ * Sem `children`, mostra o `EmptyState` do `ui`, sem moldura, com "Nenhum registro encontrado"
15
+ * e uma descrição que sugere ajustar os filtros. Com `children`, o conteúdo do app, como uma
16
+ * mensagem do filtro e um botão para limpá-lo. Fica centralizado na largura da tabela.
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * <DataTable.Root table={table}>
21
+ * <DataTable.Header table={table} />
22
+ * <DataTable.Body table={table} />
23
+ * <DataTable.Empty table={table}>
24
+ * <EmptyState.Root variant="plain">
25
+ * <EmptyState.Content>
26
+ * <EmptyState.Title>Nenhum cliente para este filtro</EmptyState.Title>
27
+ * </EmptyState.Content>
28
+ * </EmptyState.Root>
29
+ * </DataTable.Empty>
30
+ * </DataTable.Root>
31
+ * ```
32
+ */
33
+ const DataTableEmpty = (props) => {
34
+ const { table, render, className, children, ...rest } = props;
35
+ /**
36
+ * Re-renderiza quando a tabela fica vazia ou deixa de ficar. O store: as linhas mudam com os
37
+ * dados, e o carregamento, com a feature opcional.
38
+ */
39
+ const isEmpty = useSelector(table.store, () => table.getRowModel().rows.length === 0 && !(hasTableFeature(table, "loadingFeature") && table.atoms.isLoading.get()));
40
+ /** Dentro do `grid` do `DataTable.Root`, que a navegação por teclado liga, a célula é `gridcell`. */
41
+ const cellRole = hasTableFeature(table, "activeRowFeature") ? "gridcell" : "cell";
42
+ const baseProps = {
43
+ "data-component": "DataTable.Empty",
44
+ role: "row",
45
+ className: mergeTwClassNames(["py-8"], className),
46
+ children: /* @__PURE__ */ jsx("div", {
47
+ role: cellRole,
48
+ children: children === void 0 ? /* @__PURE__ */ jsxs(EmptyState.Root, {
49
+ variant: "plain",
50
+ children: [/* @__PURE__ */ jsx(EmptyState.Indicator, {
51
+ className: "text-gray-11",
52
+ children: /* @__PURE__ */ jsx(TrayIcon, {})
53
+ }), /* @__PURE__ */ jsxs(EmptyState.Content, { children: [/* @__PURE__ */ jsx(EmptyState.Title, {
54
+ className: "text-gray-11",
55
+ children: "Nenhum registro encontrado"
56
+ }), /* @__PURE__ */ jsx(EmptyState.Description, { children: "Não há registros para mostrar. Se houver filtros aplicados, tente ajustá-los." })] })]
57
+ }) : children
58
+ })
59
+ };
60
+ const element = useRender({
61
+ render,
62
+ defaultTagName: "div",
63
+ props: mergeProps(baseProps, rest)
64
+ });
65
+ return isEmpty ? element : null;
66
+ };
67
+ DataTableEmpty.displayName = "DataTable.Empty";
68
+ //#endregion
69
+ export { DataTableEmpty };
70
+
71
+ //# sourceMappingURL=data-table-empty.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-table-empty.js","names":[],"sources":["../../../../src/components/data-table/body/data-table-empty.tsx"],"sourcesContent":["import { mergeProps, useRender } from '@base-ui/react';\nimport { EmptyState } from '@lucasbernardosn/react-ui/feedback/empty-state';\nimport { mergeTwClassNames } from '@lucasbernardosn/react-ui/utils';\nimport type { MergeOverride } from '@lucasbernardosn/utils';\nimport { TrayIcon } from '@phosphor-icons/react';\nimport { useSelector } from '@tanstack/react-store';\nimport type { RowData, Table, TableFeatures } from '@tanstack/react-table';\nimport { hasTableFeature } from '../../../utils';\n\nexport type DataTableEmptyProps<\n TFeatures extends TableFeatures,\n TData extends RowData,\n> = MergeOverride<\n useRender.ComponentProps<'div'>,\n {\n /** A tabela do `useTable`. */\n table: Table<TFeatures, TData>;\n }\n>;\n\n/**\n * O estado vazio da tabela, para depois do `DataTable.Body`, dentro do `DataTable.Root`. Aparece\n * quando o row model não tem linhas e a tabela não está carregando: com `loadingFeature`, a carga\n * sem linhas mostra as linhas-fantasma do corpo, e não o vazio.\n *\n * Sem `children`, mostra o `EmptyState` do `ui`, sem moldura, com \"Nenhum registro encontrado\"\n * e uma descrição que sugere ajustar os filtros. Com `children`, o conteúdo do app, como uma\n * mensagem do filtro e um botão para limpá-lo. Fica centralizado na largura da tabela.\n *\n * @example\n * ```tsx\n * <DataTable.Root table={table}>\n * <DataTable.Header table={table} />\n * <DataTable.Body table={table} />\n * <DataTable.Empty table={table}>\n * <EmptyState.Root variant=\"plain\">\n * <EmptyState.Content>\n * <EmptyState.Title>Nenhum cliente para este filtro</EmptyState.Title>\n * </EmptyState.Content>\n * </EmptyState.Root>\n * </DataTable.Empty>\n * </DataTable.Root>\n * ```\n */\nexport const DataTableEmpty = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n props: DataTableEmptyProps<TFeatures, TData>,\n) => {\n const { table, render, className, children, ...rest } = props;\n\n /**\n * Re-renderiza quando a tabela fica vazia ou deixa de ficar. O store: as linhas mudam com os\n * dados, e o carregamento, com a feature opcional.\n */\n const isEmpty = useSelector(\n table.store,\n () =>\n table.getRowModel().rows.length === 0 &&\n !(\n hasTableFeature(table, 'loadingFeature') && table.atoms.isLoading.get()\n ),\n );\n\n /** Dentro do `grid` do `DataTable.Root`, que a navegação por teclado liga, a célula é `gridcell`. */\n const cellRole = hasTableFeature(table, 'activeRowFeature')\n ? 'gridcell'\n : 'cell';\n\n const baseProps = {\n 'data-component': 'DataTable.Empty',\n // Uma linha com uma célula: dentro de `table` e `grid`, o ARIA só aceita linhas.\n role: 'row',\n className: mergeTwClassNames(['py-8'], className),\n children: (\n <div role={cellRole}>\n {children === undefined ? (\n <EmptyState.Root variant=\"plain\">\n <EmptyState.Indicator className=\"text-gray-11\">\n <TrayIcon />\n </EmptyState.Indicator>\n\n <EmptyState.Content>\n <EmptyState.Title className=\"text-gray-11\">\n Nenhum registro encontrado\n </EmptyState.Title>\n <EmptyState.Description>\n Não há registros para mostrar. Se houver filtros aplicados,\n tente ajustá-los.\n </EmptyState.Description>\n </EmptyState.Content>\n </EmptyState.Root>\n ) : (\n children\n )}\n </div>\n ),\n };\n\n const element = useRender({\n render,\n defaultTagName: 'div',\n props: mergeProps(baseProps, rest),\n });\n\n return isEmpty ? element : null;\n};\n\nDataTableEmpty.displayName = 'DataTable.Empty';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CA,MAAa,kBAIX,UACG;CACH,MAAM,EAAE,OAAO,QAAQ,WAAW,UAAU,GAAG,SAAS;;;;;CAMxD,MAAM,UAAU,YACd,MAAM,aAEJ,MAAM,YAAY,CAAC,CAAC,KAAK,WAAW,KACpC,EACE,gBAAgB,OAAO,gBAAgB,KAAK,MAAM,MAAM,UAAU,IAAI,EAE5E;;CAGA,MAAM,WAAW,gBAAgB,OAAO,kBAAkB,IACtD,aACA;CAEJ,MAAM,YAAY;EAChB,kBAAkB;EAElB,MAAM;EACN,WAAW,kBAAkB,CAAC,MAAM,GAAG,SAAS;EAChD,UACE,oBAAC,OAAD;GAAK,MAAM;GACR,UAAA,aAAa,KAAA,IACZ,qBAAC,WAAW,MAAZ;IAAiB,SAAQ;IAAzB,UAAA,CACE,oBAAC,WAAW,WAAZ;KAAsB,WAAU;KAC9B,UAAA,oBAAC,UAAD,CAAW,CAAA;IACS,CAAA,GAEtB,qBAAC,WAAW,SAAZ,EAAA,UAAA,CACE,oBAAC,WAAW,OAAZ;KAAkB,WAAU;KAAe,UAAA;IAEzB,CAAA,GAClB,oBAAC,WAAW,aAAZ,EAAA,UAAwB,gFAGA,CAAA,CACN,EAAA,CAAA,CACL;GAEjB,CAAA,IAAA;EAEC,CAAA;CAET;CAEA,MAAM,UAAU,UAAU;EACxB;EACA,gBAAgB;EAChB,OAAO,WAAW,WAAW,IAAI;CACnC,CAAC;CAED,OAAO,UAAU,UAAU;AAC7B;AAEA,eAAe,cAAc"}
@@ -0,0 +1,32 @@
1
+ //#region src/components/data-table/body/data-table-row-focus.d.ts
2
+ /**
3
+ * As linhas do corpo que contém o elemento, na ordem do DOM.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * getDataTableRowElements(rowElement).indexOf(rowElement);
8
+ * // → a posição da linha no corpo
9
+ * ```
10
+ */
11
+ export declare const getDataTableRowElements: (element: Element) => HTMLElement[];
12
+ /**
13
+ * A linha para onde uma tecla leva o foco: ↑↓ uma linha, Home e End a primeira e a última,
14
+ * PageUp e PageDown uma tela. Sem destino (outra tecla, um modificador, um campo de texto ou a
15
+ * ponta da tabela), `undefined`, e a tecla segue para o navegador.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * getDataTableRowKeyTarget(rowElement, event);
20
+ * // ↓ na terceira linha → o elemento da quarta
21
+ * ```
22
+ */
23
+ export declare const getDataTableRowKeyTarget: (rowElement: HTMLElement, event: Pick<KeyboardEvent, "key" | "target" | "altKey" | "ctrlKey" | "metaKey" | "shiftKey">) => HTMLElement | undefined;
24
+ /**
25
+ * Foca a linha e a traz para a vista pelo caminho mais curto. O `focus()` sozinho às vezes
26
+ * centraliza a linha e a tabela pula; o `nearest` rola só o que falta, respeita o
27
+ * `scroll-padding-top` (a linha para abaixo do cabeçalho) e não mexe na rolagem horizontal, já
28
+ * que a linha é mais larga que a área visível.
29
+ */
30
+ export declare const focusDataTableRow: (rowElement: HTMLElement) => void;
31
+ //#endregion
32
+ //# sourceMappingURL=data-table-row-focus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-table-row-focus.d.ts","names":[],"sources":["../../../../src/components/data-table/body/data-table-row-focus.ts"],"mappings":";;;;;;;;;;qBAqBa,0BAA2B,SAAS,YAAO;;;;;;;;;;;;qBAmC3C,2BACX,YAAY,aACZ,OAAO,KACL,qFAED;;;;;;;qBA2CU,oBAAqB,YAAY"}
@@ -0,0 +1,58 @@
1
+ import { getDataTableScrollParent } from "../root/get-data-table-scroll-parent.js";
2
+ //#region src/components/data-table/body/data-table-row-focus.ts
3
+ /** Um campo de texto dentro da linha fica com as setas, que movem o cursor nele. */
4
+ const TEXT_ENTRY_SELECTOR = "input:not([type=\"checkbox\"], [type=\"radio\"], [type=\"button\"], [type=\"submit\"], [type=\"reset\"]), textarea, select, [contenteditable]:not([contenteditable=\"false\"])";
5
+ /**
6
+ * As linhas do corpo que contém o elemento, na ordem do DOM.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * getDataTableRowElements(rowElement).indexOf(rowElement);
11
+ * // → a posição da linha no corpo
12
+ * ```
13
+ */
14
+ const getDataTableRowElements = (element) => Array.from(element.closest("[role=\"rowgroup\"]")?.querySelectorAll("[role=\"row\"]") ?? []);
15
+ /**
16
+ * Quantas linhas inteiras cabem na área visível, abaixo do cabeçalho: o passo do PageUp e do
17
+ * PageDown.
18
+ */
19
+ const getPageSize = (rowElement) => {
20
+ const scrollParent = getDataTableScrollParent(rowElement);
21
+ const visibleHeight = scrollParent ? scrollParent.clientHeight - (Number.parseFloat(getComputedStyle(scrollParent).scrollPaddingTop) || 0) : window.innerHeight;
22
+ return Math.max(1, Math.floor(visibleHeight / Math.max(1, rowElement.offsetHeight)));
23
+ };
24
+ /**
25
+ * A linha para onde uma tecla leva o foco: ↑↓ uma linha, Home e End a primeira e a última,
26
+ * PageUp e PageDown uma tela. Sem destino (outra tecla, um modificador, um campo de texto ou a
27
+ * ponta da tabela), `undefined`, e a tecla segue para o navegador.
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * getDataTableRowKeyTarget(rowElement, event);
32
+ * // ↓ na terceira linha → o elemento da quarta
33
+ * ```
34
+ */
35
+ const getDataTableRowKeyTarget = (rowElement, event) => {
36
+ if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey || event.target instanceof Element && event.target.matches(TEXT_ENTRY_SELECTOR)) return;
37
+ const rowElements = getDataTableRowElements(rowElement);
38
+ const index = rowElements.indexOf(rowElement);
39
+ const targetIndex = event.key === "ArrowDown" ? index + 1 : event.key === "ArrowUp" ? index - 1 : event.key === "Home" ? 0 : event.key === "End" ? rowElements.length - 1 : event.key === "PageDown" ? Math.min(index + getPageSize(rowElement), rowElements.length - 1) : event.key === "PageUp" ? Math.max(index - getPageSize(rowElement), 0) : -1;
40
+ return targetIndex === index ? void 0 : rowElements[targetIndex];
41
+ };
42
+ /**
43
+ * Foca a linha e a traz para a vista pelo caminho mais curto. O `focus()` sozinho às vezes
44
+ * centraliza a linha e a tabela pula; o `nearest` rola só o que falta, respeita o
45
+ * `scroll-padding-top` (a linha para abaixo do cabeçalho) e não mexe na rolagem horizontal, já
46
+ * que a linha é mais larga que a área visível.
47
+ */
48
+ const focusDataTableRow = (rowElement) => {
49
+ rowElement.focus({ preventScroll: true });
50
+ rowElement.scrollIntoView({
51
+ block: "nearest",
52
+ inline: "nearest"
53
+ });
54
+ };
55
+ //#endregion
56
+ export { focusDataTableRow, getDataTableRowElements, getDataTableRowKeyTarget };
57
+
58
+ //# sourceMappingURL=data-table-row-focus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-table-row-focus.js","names":[],"sources":["../../../../src/components/data-table/body/data-table-row-focus.ts"],"sourcesContent":["import { getDataTableScrollParent } from '../root/get-data-table-scroll-parent';\n\n/*\n * O foco entre as linhas, pelo DOM: as setas movem o foco para o elemento da linha vizinha, e a\n * `DataTable.Row` grava a linha ativa quando o recebe. A ordem das linhas é a do DOM, que é a do\n * row model.\n */\n\n/** Um campo de texto dentro da linha fica com as setas, que movem o cursor nele. */\nconst TEXT_ENTRY_SELECTOR =\n 'input:not([type=\"checkbox\"], [type=\"radio\"], [type=\"button\"], [type=\"submit\"], [type=\"reset\"]), textarea, select, [contenteditable]:not([contenteditable=\"false\"])';\n\n/**\n * As linhas do corpo que contém o elemento, na ordem do DOM.\n *\n * @example\n * ```ts\n * getDataTableRowElements(rowElement).indexOf(rowElement);\n * // → a posição da linha no corpo\n * ```\n */\nexport const getDataTableRowElements = (element: Element) =>\n Array.from(\n element\n .closest('[role=\"rowgroup\"]')\n ?.querySelectorAll<HTMLElement>('[role=\"row\"]') ?? [],\n );\n\n/**\n * Quantas linhas inteiras cabem na área visível, abaixo do cabeçalho: o passo do PageUp e do\n * PageDown.\n */\nconst getPageSize = (rowElement: HTMLElement) => {\n const scrollParent = getDataTableScrollParent(rowElement);\n const visibleHeight = scrollParent\n ? scrollParent.clientHeight -\n (Number.parseFloat(getComputedStyle(scrollParent).scrollPaddingTop) || 0)\n : window.innerHeight;\n\n return Math.max(\n 1,\n Math.floor(visibleHeight / Math.max(1, rowElement.offsetHeight)),\n );\n};\n\n/**\n * A linha para onde uma tecla leva o foco: ↑↓ uma linha, Home e End a primeira e a última,\n * PageUp e PageDown uma tela. Sem destino (outra tecla, um modificador, um campo de texto ou a\n * ponta da tabela), `undefined`, e a tecla segue para o navegador.\n *\n * @example\n * ```ts\n * getDataTableRowKeyTarget(rowElement, event);\n * // ↓ na terceira linha → o elemento da quarta\n * ```\n */\nexport const getDataTableRowKeyTarget = (\n rowElement: HTMLElement,\n event: Pick<\n KeyboardEvent,\n 'key' | 'target' | 'altKey' | 'ctrlKey' | 'metaKey' | 'shiftKey'\n >,\n) => {\n if (\n event.altKey ||\n event.ctrlKey ||\n event.metaKey ||\n event.shiftKey ||\n (event.target instanceof Element &&\n event.target.matches(TEXT_ENTRY_SELECTOR))\n ) {\n return undefined;\n }\n\n const rowElements = getDataTableRowElements(rowElement);\n const index = rowElements.indexOf(rowElement);\n\n const targetIndex =\n event.key === 'ArrowDown'\n ? index + 1\n : event.key === 'ArrowUp'\n ? index - 1\n : event.key === 'Home'\n ? 0\n : event.key === 'End'\n ? rowElements.length - 1\n : event.key === 'PageDown'\n ? Math.min(\n index + getPageSize(rowElement),\n rowElements.length - 1,\n )\n : event.key === 'PageUp'\n ? Math.max(index - getPageSize(rowElement), 0)\n : -1;\n\n return targetIndex === index ? undefined : rowElements[targetIndex];\n};\n\n/**\n * Foca a linha e a traz para a vista pelo caminho mais curto. O `focus()` sozinho às vezes\n * centraliza a linha e a tabela pula; o `nearest` rola só o que falta, respeita o\n * `scroll-padding-top` (a linha para abaixo do cabeçalho) e não mexe na rolagem horizontal, já\n * que a linha é mais larga que a área visível.\n */\nexport const focusDataTableRow = (rowElement: HTMLElement) => {\n rowElement.focus({ preventScroll: true });\n rowElement.scrollIntoView({ block: 'nearest', inline: 'nearest' });\n};\n"],"mappings":";;;AASA,MAAM,sBACJ;;;;;;;;;;AAWF,MAAa,2BAA2B,YACtC,MAAM,KACJ,QACG,QAAQ,qBAAmB,CAAC,EAC3B,iBAA8B,gBAAc,KAAK,CAAC,CACxD;;;;;AAMF,MAAM,eAAe,eAA4B;CAC/C,MAAM,eAAe,yBAAyB,UAAU;CACxD,MAAM,gBAAgB,eAClB,aAAa,gBACZ,OAAO,WAAW,iBAAiB,YAAY,CAAC,CAAC,gBAAgB,KAAK,KACvE,OAAO;CAEX,OAAO,KAAK,IACV,GACA,KAAK,MAAM,gBAAgB,KAAK,IAAI,GAAG,WAAW,YAAY,CAAC,CACjE;AACF;;;;;;;;;;;;AAaA,MAAa,4BACX,YACA,UAIG;CACH,IACE,MAAM,UACN,MAAM,WACN,MAAM,WACN,MAAM,YACL,MAAM,kBAAkB,WACvB,MAAM,OAAO,QAAQ,mBAAmB,GAE1C;CAGF,MAAM,cAAc,wBAAwB,UAAU;CACtD,MAAM,QAAQ,YAAY,QAAQ,UAAU;CAE5C,MAAM,cACJ,MAAM,QAAQ,cACV,QAAQ,IACR,MAAM,QAAQ,YACZ,QAAQ,IACR,MAAM,QAAQ,SACZ,IACA,MAAM,QAAQ,QACZ,YAAY,SAAS,IACrB,MAAM,QAAQ,aACZ,KAAK,IACH,QAAQ,YAAY,UAAU,GAC9B,YAAY,SAAS,CACvB,IACA,MAAM,QAAQ,WACZ,KAAK,IAAI,QAAQ,YAAY,UAAU,GAAG,CAAC,IAC3C;CAEhB,OAAO,gBAAgB,QAAQ,KAAA,IAAY,YAAY;AACzD;;;;;;;AAQA,MAAa,qBAAqB,eAA4B;CAC5D,WAAW,MAAM,EAAE,eAAe,KAAK,CAAC;CACxC,WAAW,eAAe;EAAE,OAAO;EAAW,QAAQ;CAAU,CAAC;AACnE"}
@@ -0,0 +1,67 @@
1
+ import { Cell, Row, RowData, TableFeatures } from "@tanstack/react-table";
2
+ import { useRender } from "@base-ui/react";
3
+ import React from "react";
4
+ import { MergeOverride } from "@lucasbernardosn/utils";
5
+ //#region src/components/data-table/body/data-table-row.d.ts
6
+ export type DataTableRowProps<TFeatures extends TableFeatures, TData extends RowData> = MergeOverride<useRender.ComponentProps<'div'>, {
7
+ /** A linha do row model. */
8
+ row: Row<TFeatures, TData>;
9
+ /**
10
+ * Uma função que recebe cada célula visível e devolve o elemento dela. Com nós comuns, quem
11
+ * usa faz o laço.
12
+ * @default (cell) => <DataTable.Cell cell={cell} />
13
+ */
14
+ children?: React.ReactNode | ((cell: Cell<TFeatures, TData>) => React.ReactNode);
15
+ }>;
16
+ /**
17
+ * Uma linha do corpo (`role="row"`). É um grid com as colunas do `--data-table-template`, que o
18
+ * `DataTable.Root` escreve.
19
+ *
20
+ * Com render-prop ou sem `children`, faz o laço das células sozinha: assina as próprias células e
21
+ * re-renderiza quando a ordem, a visibilidade ou o pinning das colunas mudam, que não mudam o row
22
+ * model e não passam pelo `DataTable.Body`. Com `columnVisibilityFeature`, são as células
23
+ * visíveis; sem ela, todas. Com `columnPinningFeature`, vêm na ordem das regiões: as fixadas no
24
+ * início, as do centro e as fixadas no fim.
25
+ *
26
+ * Com `rowSelectionFeature`, a linha selecionada ganha `data-selected` e o fundo destacado, e com
27
+ * `activeRowFeature`, também o `aria-selected`. O clique na linha não seleciona: o `onClick` fica
28
+ * livre, e a seleção é do `DataTable.RowCheckbox` e do Espaço.
29
+ *
30
+ * Com `activeRowFeature`, entra na navegação por teclado. A linha ativa tem o ponto de Tab (sem
31
+ * ela no row model, a primeira), e receber o foco, pelo teclado ou pelo clique, torna esta a
32
+ * ativa, marcada com `data-active`. ↑↓, Home, End, PageUp e PageDown movem o foco entre as
33
+ * linhas, e o Espaço alterna a seleção, com Shift para o intervalo. Os atalhos são do app, no
34
+ * `onKeyDown`, que roda antes: um `preventDefault()` cancela o da linha. Num campo de texto de
35
+ * dentro, as setas ficam com o campo.
36
+ *
37
+ * O fundo fica na variável `--data-table-row-background`, que as células fixadas repetem: o
38
+ * hover a troca para `gray-2`, a selecionada para `gray-3`, e as duas juntas, para `gray-4`. Para
39
+ * colorir uma linha, troque a variável, e não use `bg-*`, que deixaria as fixadas com a cor
40
+ * antiga. A cor do texto fica na linha, e as células herdam.
41
+ *
42
+ * @example
43
+ * ```tsx
44
+ * <DataTable.Row
45
+ * row={row}
46
+ * onClick={() => openCustomer(row.original)}
47
+ * onKeyDown={(event) => {
48
+ * if (event.key === 'Enter') {
49
+ * openCustomer(row.original);
50
+ * }
51
+ * }}
52
+ * className={
53
+ * row.original.overdue
54
+ * ? '[--data-table-row-background:var(--color-gray-2)] text-gray-11'
55
+ * : undefined
56
+ * }
57
+ * >
58
+ * {(cell) => <DataTable.Cell cell={cell} />}
59
+ * </DataTable.Row>
60
+ * ```
61
+ */
62
+ export declare const DataTableRow: {
63
+ <TFeatures extends TableFeatures, TData extends RowData>(props: DataTableRowProps<TFeatures, TData>): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>;
64
+ displayName: string;
65
+ };
66
+ //#endregion
67
+ //# sourceMappingURL=data-table-row.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-table-row.d.ts","names":[],"sources":["../../../../src/components/data-table/body/data-table-row.tsx"],"mappings":";;;;;YAeY,kBACV,kBAAkB,eAClB,cAAc,WACZ,cACF,UAAU;;EAGR,KAAK,IAAI,WAAW;;;;;;EAMpB,WACI,MAAM,cACJ,MAAM,KAAK,WAAW,WAAW,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAkDpC;GACX,kBAAkB,eAClB,cAAc,SAAO,OAEd,kBAAkB,WAAW,SAAM,MAAA,+BAAA,MAAA"}
@@ -0,0 +1,154 @@
1
+ import { hasRowFeature } from "../../../utils/has-feature.js";
2
+ import { focusDataTableRow, getDataTableRowKeyTarget } from "./data-table-row-focus.js";
3
+ import { dataTableGridClassNames } from "../root/data-table-grid-class-names.js";
4
+ import { DataTableCell } from "./data-table-cell.js";
5
+ import { jsx } from "react/jsx-runtime";
6
+ import { mergeProps, useRender } from "@base-ui/react";
7
+ import { shallow, useSelector } from "@tanstack/react-store";
8
+ import { mergeTwClassNames } from "@lucasbernardosn/react-ui/utils";
9
+ import { Fragment as Fragment$1 } from "react";
10
+ //#region src/components/data-table/body/data-table-row.tsx
11
+ /**
12
+ * Uma linha do corpo (`role="row"`). É um grid com as colunas do `--data-table-template`, que o
13
+ * `DataTable.Root` escreve.
14
+ *
15
+ * Com render-prop ou sem `children`, faz o laço das células sozinha: assina as próprias células e
16
+ * re-renderiza quando a ordem, a visibilidade ou o pinning das colunas mudam, que não mudam o row
17
+ * model e não passam pelo `DataTable.Body`. Com `columnVisibilityFeature`, são as células
18
+ * visíveis; sem ela, todas. Com `columnPinningFeature`, vêm na ordem das regiões: as fixadas no
19
+ * início, as do centro e as fixadas no fim.
20
+ *
21
+ * Com `rowSelectionFeature`, a linha selecionada ganha `data-selected` e o fundo destacado, e com
22
+ * `activeRowFeature`, também o `aria-selected`. O clique na linha não seleciona: o `onClick` fica
23
+ * livre, e a seleção é do `DataTable.RowCheckbox` e do Espaço.
24
+ *
25
+ * Com `activeRowFeature`, entra na navegação por teclado. A linha ativa tem o ponto de Tab (sem
26
+ * ela no row model, a primeira), e receber o foco, pelo teclado ou pelo clique, torna esta a
27
+ * ativa, marcada com `data-active`. ↑↓, Home, End, PageUp e PageDown movem o foco entre as
28
+ * linhas, e o Espaço alterna a seleção, com Shift para o intervalo. Os atalhos são do app, no
29
+ * `onKeyDown`, que roda antes: um `preventDefault()` cancela o da linha. Num campo de texto de
30
+ * dentro, as setas ficam com o campo.
31
+ *
32
+ * O fundo fica na variável `--data-table-row-background`, que as células fixadas repetem: o
33
+ * hover a troca para `gray-2`, a selecionada para `gray-3`, e as duas juntas, para `gray-4`. Para
34
+ * colorir uma linha, troque a variável, e não use `bg-*`, que deixaria as fixadas com a cor
35
+ * antiga. A cor do texto fica na linha, e as células herdam.
36
+ *
37
+ * @example
38
+ * ```tsx
39
+ * <DataTable.Row
40
+ * row={row}
41
+ * onClick={() => openCustomer(row.original)}
42
+ * onKeyDown={(event) => {
43
+ * if (event.key === 'Enter') {
44
+ * openCustomer(row.original);
45
+ * }
46
+ * }}
47
+ * className={
48
+ * row.original.overdue
49
+ * ? '[--data-table-row-background:var(--color-gray-2)] text-gray-11'
50
+ * : undefined
51
+ * }
52
+ * >
53
+ * {(cell) => <DataTable.Cell cell={cell} />}
54
+ * </DataTable.Row>
55
+ * ```
56
+ */
57
+ const DataTableRow = (props) => {
58
+ const { row, render, className, children, ...rest } = props;
59
+ const cells = useSelector(row.table.store, () => hasRowFeature(row, "columnPinningFeature") ? [
60
+ row.getStartVisibleCells(),
61
+ row.getCenterVisibleCells(),
62
+ row.getEndVisibleCells()
63
+ ] : hasRowFeature(row, "columnVisibilityFeature") ? [row.getVisibleCells()] : [row.getAllCells()], { compare: shallow }).flat();
64
+ /**
65
+ * Só re-renderiza quando esta linha é marcada ou desmarcada. A seleção é opcional, então assina
66
+ * o store; sem `rowSelectionFeature`, nenhuma linha fica selecionada.
67
+ */
68
+ const isSelected = useSelector(row.table.store, () => hasRowFeature(row, "rowSelectionFeature") && row.getIsSelected());
69
+ /**
70
+ * O ponto de Tab da tabela: a linha ativa ou, sem ela no row model, a primeira. Re-renderiza
71
+ * quando o ponto de Tab entra ou sai daqui. A navegação é opcional, então assina o store; sem
72
+ * `activeRowFeature`, nenhuma linha entra no Tab.
73
+ */
74
+ const isTabStop = useSelector(row.table.store, () => {
75
+ if (!hasRowFeature(row, "activeRowFeature")) return false;
76
+ const activeRow = row.table.getActiveRow();
77
+ return activeRow ? activeRow.id === row.id : row.table.getRowModel().rows[0]?.id === row.id;
78
+ });
79
+ /** Só re-renderiza quando esta linha vira ou deixa de ser a ativa. */
80
+ const isActive = useSelector(row.table.store, () => hasRowFeature(row, "activeRowFeature") && row.getIsActive());
81
+ /** Receber o foco, nela ou num controle de dentro, torna esta a linha ativa. */
82
+ const handleFocus = () => {
83
+ if (hasRowFeature(row, "activeRowFeature") && !row.getIsActive()) row.table.setActiveRowId(row.id);
84
+ };
85
+ /** As teclas da navegação. O `onKeyDown` do app roda antes e cancela com `preventDefault()`. */
86
+ const handleKeyDown = (event) => {
87
+ if (!hasRowFeature(row, "activeRowFeature") || event.defaultPrevented) return;
88
+ /** Na própria linha: num controle de dentro, como o checkbox, o Espaço é dele. */
89
+ if (event.key === " " && event.target === event.currentTarget) {
90
+ if (hasRowFeature(row, "rowSelectionFeature") && row.getCanSelect()) {
91
+ event.preventDefault();
92
+ /** O handler do checkbox: lê o Shift do evento, para o intervalo, e move a âncora. */
93
+ row.getToggleSelectedHandler()({
94
+ target: { checked: !row.getIsSelected() },
95
+ nativeEvent: event.nativeEvent
96
+ });
97
+ }
98
+ return;
99
+ }
100
+ const targetRow = getDataTableRowKeyTarget(event.currentTarget, event);
101
+ if (targetRow) {
102
+ event.preventDefault();
103
+ focusDataTableRow(targetRow);
104
+ }
105
+ };
106
+ const isNavigable = hasRowFeature(row, "activeRowFeature");
107
+ /** Com render-prop ou sem `children`, o laço é daqui; com nós comuns, de quem usa. */
108
+ const content = typeof children === "function" || children === void 0 ? cells.map((cell) => /* @__PURE__ */ jsx(Fragment$1, { children: children === void 0 ? /* @__PURE__ */ jsx(DataTableCell, { cell }) : children(cell) }, cell.id)) : children;
109
+ const baseProps = {
110
+ "data-component": "DataTable.Row",
111
+ "data-selected": isSelected ? "" : void 0,
112
+ "data-active": isActive ? "" : void 0,
113
+ role: "row",
114
+ "aria-selected": isNavigable && hasRowFeature(row, "rowSelectionFeature") ? isSelected : void 0,
115
+ tabIndex: isNavigable ? isTabStop ? 0 : -1 : void 0,
116
+ onFocus: handleFocus,
117
+ onKeyDown: handleKeyDown,
118
+ className: mergeTwClassNames([
119
+ "relative",
120
+ dataTableGridClassNames,
121
+ "last:border-b-0",
122
+ "[--data-table-row-base:var(--color-white)]",
123
+ "dark:[--data-table-row-base:#0b0b0b]",
124
+ "[--data-table-row-background:var(--data-table-row-base)]",
125
+ "hover:[--data-table-row-background:var(--color-gray-2)]",
126
+ "data-selected:[--data-table-row-background:var(--color-gray-3)]",
127
+ "data-selected:hover:[--data-table-row-background:var(--color-gray-4)]",
128
+ "has-[[data-popup-open]]:[--data-table-row-background:var(--color-gray-2)]",
129
+ "data-selected:has-[[data-popup-open]]:[--data-table-row-background:var(--color-gray-4)]",
130
+ "bg-(--data-table-row-background)",
131
+ "text-gray-12",
132
+ "outline-none",
133
+ "after:pointer-events-none",
134
+ "after:absolute",
135
+ "after:inset-0",
136
+ "after:z-2",
137
+ "after:content-[\"\"]",
138
+ "focus-within:after:outline-2",
139
+ "focus-within:after:-outline-offset-2",
140
+ "focus-within:after:outline-gray-12"
141
+ ], className),
142
+ children: content
143
+ };
144
+ return useRender({
145
+ render,
146
+ defaultTagName: "div",
147
+ props: mergeProps(baseProps, rest)
148
+ });
149
+ };
150
+ DataTableRow.displayName = "DataTable.Row";
151
+ //#endregion
152
+ export { DataTableRow };
153
+
154
+ //# sourceMappingURL=data-table-row.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-table-row.js","names":["Fragment"],"sources":["../../../../src/components/data-table/body/data-table-row.tsx"],"sourcesContent":["import { mergeProps, useRender } from '@base-ui/react';\nimport { mergeTwClassNames } from '@lucasbernardosn/react-ui/utils';\nimport type { MergeOverride } from '@lucasbernardosn/utils';\nimport { shallow, useSelector } from '@tanstack/react-store';\nimport type { Cell, Row, RowData, TableFeatures } from '@tanstack/react-table';\nimport type React from 'react';\nimport { Fragment } from 'react';\nimport { hasRowFeature } from '../../../utils';\nimport { dataTableGridClassNames } from '../root/data-table-grid-class-names';\nimport { DataTableCell } from './data-table-cell';\nimport {\n focusDataTableRow,\n getDataTableRowKeyTarget,\n} from './data-table-row-focus';\n\nexport type DataTableRowProps<\n TFeatures extends TableFeatures,\n TData extends RowData,\n> = MergeOverride<\n useRender.ComponentProps<'div'>,\n {\n /** A linha do row model. */\n row: Row<TFeatures, TData>;\n /**\n * Uma função que recebe cada célula visível e devolve o elemento dela. Com nós comuns, quem\n * usa faz o laço.\n * @default (cell) => <DataTable.Cell cell={cell} />\n */\n children?:\n | React.ReactNode\n | ((cell: Cell<TFeatures, TData>) => React.ReactNode);\n }\n>;\n\n/**\n * Uma linha do corpo (`role=\"row\"`). É um grid com as colunas do `--data-table-template`, que o\n * `DataTable.Root` escreve.\n *\n * Com render-prop ou sem `children`, faz o laço das células sozinha: assina as próprias células e\n * re-renderiza quando a ordem, a visibilidade ou o pinning das colunas mudam, que não mudam o row\n * model e não passam pelo `DataTable.Body`. Com `columnVisibilityFeature`, são as células\n * visíveis; sem ela, todas. Com `columnPinningFeature`, vêm na ordem das regiões: as fixadas no\n * início, as do centro e as fixadas no fim.\n *\n * Com `rowSelectionFeature`, a linha selecionada ganha `data-selected` e o fundo destacado, e com\n * `activeRowFeature`, também o `aria-selected`. O clique na linha não seleciona: o `onClick` fica\n * livre, e a seleção é do `DataTable.RowCheckbox` e do Espaço.\n *\n * Com `activeRowFeature`, entra na navegação por teclado. A linha ativa tem o ponto de Tab (sem\n * ela no row model, a primeira), e receber o foco, pelo teclado ou pelo clique, torna esta a\n * ativa, marcada com `data-active`. ↑↓, Home, End, PageUp e PageDown movem o foco entre as\n * linhas, e o Espaço alterna a seleção, com Shift para o intervalo. Os atalhos são do app, no\n * `onKeyDown`, que roda antes: um `preventDefault()` cancela o da linha. Num campo de texto de\n * dentro, as setas ficam com o campo.\n *\n * O fundo fica na variável `--data-table-row-background`, que as células fixadas repetem: o\n * hover a troca para `gray-2`, a selecionada para `gray-3`, e as duas juntas, para `gray-4`. Para\n * colorir uma linha, troque a variável, e não use `bg-*`, que deixaria as fixadas com a cor\n * antiga. A cor do texto fica na linha, e as células herdam.\n *\n * @example\n * ```tsx\n * <DataTable.Row\n * row={row}\n * onClick={() => openCustomer(row.original)}\n * onKeyDown={(event) => {\n * if (event.key === 'Enter') {\n * openCustomer(row.original);\n * }\n * }}\n * className={\n * row.original.overdue\n * ? '[--data-table-row-background:var(--color-gray-2)] text-gray-11'\n * : undefined\n * }\n * >\n * {(cell) => <DataTable.Cell cell={cell} />}\n * </DataTable.Row>\n * ```\n */\nexport const DataTableRow = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n props: DataTableRowProps<TFeatures, TData>,\n) => {\n const { row, render, className, children, ...rest } = props;\n\n /**\n * As listas que o TanStack memoiza, numa tupla: o `shallow` compara item a item, e só\n * re-renderiza quando uma delas muda com as colunas. Todas seguem a ordem dos headers folha, que\n * é a do template, e as células caem nos tracks certos. Com pinning, as três regiões, que\n * ordenam as fixadas mesmo sem `columnVisibilityFeature`.\n */\n const cellGroups = useSelector(\n row.table.store,\n () =>\n hasRowFeature(row, 'columnPinningFeature')\n ? [\n row.getStartVisibleCells(),\n row.getCenterVisibleCells(),\n row.getEndVisibleCells(),\n ]\n : hasRowFeature(row, 'columnVisibilityFeature')\n ? [row.getVisibleCells()]\n : [row.getAllCells()],\n { compare: shallow },\n );\n\n const cells = cellGroups.flat();\n\n /**\n * Só re-renderiza quando esta linha é marcada ou desmarcada. A seleção é opcional, então assina\n * o store; sem `rowSelectionFeature`, nenhuma linha fica selecionada.\n */\n const isSelected = useSelector(\n row.table.store,\n () => hasRowFeature(row, 'rowSelectionFeature') && row.getIsSelected(),\n );\n\n /**\n * O ponto de Tab da tabela: a linha ativa ou, sem ela no row model, a primeira. Re-renderiza\n * quando o ponto de Tab entra ou sai daqui. A navegação é opcional, então assina o store; sem\n * `activeRowFeature`, nenhuma linha entra no Tab.\n */\n const isTabStop = useSelector(row.table.store, () => {\n if (!hasRowFeature(row, 'activeRowFeature')) {\n return false;\n }\n\n const activeRow = row.table.getActiveRow();\n\n return activeRow\n ? activeRow.id === row.id\n : row.table.getRowModel().rows[0]?.id === row.id;\n });\n\n /** Só re-renderiza quando esta linha vira ou deixa de ser a ativa. */\n const isActive = useSelector(\n row.table.store,\n () => hasRowFeature(row, 'activeRowFeature') && row.getIsActive(),\n );\n\n /** Receber o foco, nela ou num controle de dentro, torna esta a linha ativa. */\n const handleFocus = () => {\n if (hasRowFeature(row, 'activeRowFeature') && !row.getIsActive()) {\n row.table.setActiveRowId(row.id);\n }\n };\n\n /** As teclas da navegação. O `onKeyDown` do app roda antes e cancela com `preventDefault()`. */\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (!hasRowFeature(row, 'activeRowFeature') || event.defaultPrevented) {\n return;\n }\n\n /** Na própria linha: num controle de dentro, como o checkbox, o Espaço é dele. */\n if (event.key === ' ' && event.target === event.currentTarget) {\n if (hasRowFeature(row, 'rowSelectionFeature') && row.getCanSelect()) {\n event.preventDefault();\n\n /** O handler do checkbox: lê o Shift do evento, para o intervalo, e move a âncora. */\n row.getToggleSelectedHandler()({\n target: { checked: !row.getIsSelected() },\n nativeEvent: event.nativeEvent,\n });\n }\n\n return;\n }\n\n const targetRow = getDataTableRowKeyTarget(event.currentTarget, event);\n\n if (targetRow) {\n event.preventDefault();\n focusDataTableRow(targetRow);\n }\n };\n\n const isNavigable = hasRowFeature(row, 'activeRowFeature');\n\n /** Com render-prop ou sem `children`, o laço é daqui; com nós comuns, de quem usa. */\n const content =\n typeof children === 'function' || children === undefined\n ? cells.map((cell) => (\n <Fragment key={cell.id}>\n {children === undefined ? (\n <DataTableCell cell={cell} />\n ) : (\n children(cell)\n )}\n </Fragment>\n ))\n : children;\n\n const baseProps = {\n 'data-component': 'DataTable.Row',\n 'data-selected': isSelected ? '' : undefined,\n 'data-active': isActive ? '' : undefined,\n role: 'row',\n // Só no `grid`: o ARIA não define o atributo na linha de uma `table`, e o leitor o ignora.\n 'aria-selected':\n isNavigable && hasRowFeature(row, 'rowSelectionFeature')\n ? isSelected\n : undefined,\n tabIndex: isNavigable ? (isTabStop ? 0 : -1) : undefined,\n onFocus: handleFocus,\n onKeyDown: handleKeyDown,\n className: mergeTwClassNames(\n [\n // O anel de foco se posiciona por aqui.\n 'relative',\n\n dataTableGridClassNames,\n // Sem a linha horizontal na última: embaixo dela já vem a borda da área de rolagem, e as\n // duas somariam 2px.\n 'last:border-b-0',\n\n // O fundo numa variável, que as células fixadas repetem para ficarem opacas. A base é\n // branca no claro e quase preta no escuro, numa variável à parte: a variante `dark` e o\n // `hover` disputariam a mesma propriedade, e a ordem delas no CSS decidiria. O hover sobe\n // um passo, a selecionada outro, e a selecionada com hover mais um: sem isso, passar o\n // mouse por ela não mudaria nada. Escala curta, para o fundo dos botões `ghost` das\n // células (`gray-3`) aparecer sobre a linha em hover.\n '[--data-table-row-base:var(--color-white)]',\n 'dark:[--data-table-row-base:#0b0b0b]',\n '[--data-table-row-background:var(--data-table-row-base)]',\n 'hover:[--data-table-row-background:var(--color-gray-2)]',\n 'data-selected:[--data-table-row-background:var(--color-gray-3)]',\n 'data-selected:hover:[--data-table-row-background:var(--color-gray-4)]',\n // Com um menu aberto num controle da linha, ela fica como em hover, com o ponteiro onde\n // estiver: o backdrop do menu cobre o resto da linha e deixa um recorte só sobre o\n // gatilho, e o `:hover` acenderia e apagaria a linha conforme o ponteiro passa por ele.\n 'has-[[data-popup-open]]:[--data-table-row-background:var(--color-gray-2)]',\n 'data-selected:has-[[data-popup-open]]:[--data-table-row-background:var(--color-gray-4)]',\n 'bg-(--data-table-row-background)',\n\n 'text-gray-12',\n\n // O anel de foco, com o foco na linha ou num controle de dentro, pelo teclado ou pelo\n // clique: com `focus-visible`, o clique tornaria a linha ativa sem mostrar qual é. Num\n // `::after` por cima das células fixadas (`z-1`), que cobririam o `outline` e o\n // `box-shadow` da própria linha. Por dentro: a linha seguinte cobriria o que sai por baixo.\n 'outline-none',\n 'after:pointer-events-none',\n 'after:absolute',\n 'after:inset-0',\n 'after:z-2',\n 'after:content-[\"\"]',\n 'focus-within:after:outline-2',\n 'focus-within:after:-outline-offset-2',\n 'focus-within:after:outline-gray-12',\n ],\n className,\n ),\n children: content,\n };\n\n return useRender({\n render,\n defaultTagName: 'div',\n props: mergeProps(baseProps, rest),\n });\n};\n\nDataTableRow.displayName = 'DataTable.Row';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgFA,MAAa,gBAIX,UACG;CACH,MAAM,EAAE,KAAK,QAAQ,WAAW,UAAU,GAAG,SAAS;CAuBtD,MAAM,QAfa,YACjB,IAAI,MAAM,aAER,cAAc,KAAK,sBAAsB,IACrC;EACE,IAAI,qBAAqB;EACzB,IAAI,sBAAsB;EAC1B,IAAI,mBAAmB;CACzB,IACA,cAAc,KAAK,yBAAyB,IAC1C,CAAC,IAAI,gBAAgB,CAAC,IACtB,CAAC,IAAI,YAAY,CAAC,GAC1B,EAAE,SAAS,QAAQ,CAGE,CAAC,CAAC,KAAK;;;;;CAM9B,MAAM,aAAa,YACjB,IAAI,MAAM,aACJ,cAAc,KAAK,qBAAqB,KAAK,IAAI,cAAc,CACvE;;;;;;CAOA,MAAM,YAAY,YAAY,IAAI,MAAM,aAAa;EACnD,IAAI,CAAC,cAAc,KAAK,kBAAkB,GACxC,OAAO;EAGT,MAAM,YAAY,IAAI,MAAM,aAAa;EAEzC,OAAO,YACH,UAAU,OAAO,IAAI,KACrB,IAAI,MAAM,YAAY,CAAC,CAAC,KAAK,EAAE,EAAE,OAAO,IAAI;CAClD,CAAC;;CAGD,MAAM,WAAW,YACf,IAAI,MAAM,aACJ,cAAc,KAAK,kBAAkB,KAAK,IAAI,YAAY,CAClE;;CAGA,MAAM,oBAAoB;EACxB,IAAI,cAAc,KAAK,kBAAkB,KAAK,CAAC,IAAI,YAAY,GAC7D,IAAI,MAAM,eAAe,IAAI,EAAE;CAEnC;;CAGA,MAAM,iBAAiB,UAA+C;EACpE,IAAI,CAAC,cAAc,KAAK,kBAAkB,KAAK,MAAM,kBACnD;;EAIF,IAAI,MAAM,QAAQ,OAAO,MAAM,WAAW,MAAM,eAAe;GAC7D,IAAI,cAAc,KAAK,qBAAqB,KAAK,IAAI,aAAa,GAAG;IACnE,MAAM,eAAe;;IAGrB,IAAI,yBAAyB,CAAC,CAAC;KAC7B,QAAQ,EAAE,SAAS,CAAC,IAAI,cAAc,EAAE;KACxC,aAAa,MAAM;IACrB,CAAC;GACH;GAEA;EACF;EAEA,MAAM,YAAY,yBAAyB,MAAM,eAAe,KAAK;EAErE,IAAI,WAAW;GACb,MAAM,eAAe;GACrB,kBAAkB,SAAS;EAC7B;CACF;CAEA,MAAM,cAAc,cAAc,KAAK,kBAAkB;;CAGzD,MAAM,UACJ,OAAO,aAAa,cAAc,aAAa,KAAA,IAC3C,MAAM,KAAK,SACT,oBAACA,YAAD,EAAA,UACG,aAAa,KAAA,IACZ,oBAAC,eAAD,EAAqB,KAAO,CAAA,IAE5B,SAAS,IAAI,EAEP,GANK,KAAK,EAMV,CACX,IACD;CAEN,MAAM,YAAY;EAChB,kBAAkB;EAClB,iBAAiB,aAAa,KAAK,KAAA;EACnC,eAAe,WAAW,KAAK,KAAA;EAC/B,MAAM;EAEN,iBACE,eAAe,cAAc,KAAK,qBAAqB,IACnD,aACA,KAAA;EACN,UAAU,cAAe,YAAY,IAAI,KAAM,KAAA;EAC/C,SAAS;EACT,WAAW;EACX,WAAW,kBACT;GAEE;GAEA;GAGA;GAQA;GACA;GACA;GACA;GACA;GACA;GAIA;GACA;GACA;GAEA;GAMA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF,GACA,SACF;EACA,UAAU;CACZ;CAEA,OAAO,UAAU;EACf;EACA,gBAAgB;EAChB,OAAO,WAAW,WAAW,IAAI;CACnC,CAAC;AACH;AAEA,aAAa,cAAc"}
@@ -0,0 +1,19 @@
1
+ import { Row, RowData, Table, TableFeatures } from "@tanstack/react-table";
2
+ import React from "react";
3
+ //#region src/components/data-table/body/use-data-table-row-focus-recovery.d.ts
4
+ /**
5
+ * Devolve o foco a uma linha quando a que o tinha sai do corpo: apagada, de outra página,
6
+ * filtrada ou movida pela ordenação. Sem isto, o foco cai no `body`, e o teclado perde a tabela.
7
+ *
8
+ * O foco vai para a linha ativa, se ela continua no corpo; senão, para a que ficou na posição da
9
+ * que saiu, ou para a última. Com o foco fora da tabela, nada muda. Só com `activeRowFeature`.
10
+ *
11
+ * Devolve o ref e os handlers de foco do elemento do corpo.
12
+ */
13
+ export declare const useDataTableRowFocusRecovery: <TFeatures extends TableFeatures, TData extends RowData>(table: Table<TFeatures, TData>, rows: Row<TFeatures, TData>[]) => {
14
+ ref: React.RefObject<HTMLDivElement | null>;
15
+ onFocus: (event: React.FocusEvent<HTMLDivElement>) => void;
16
+ onBlur: (event: React.FocusEvent<HTMLDivElement>) => void;
17
+ };
18
+ //#endregion
19
+ //# sourceMappingURL=use-data-table-row-focus-recovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-data-table-row-focus-recovery.d.ts","names":[],"sources":["../../../../src/components/data-table/body/use-data-table-row-focus-recovery.ts"],"mappings":";;;;;;;;;;;;qBAkBa,+BACX,kBAAkB,eAClB,cAAc,SAEd,OAAO,MAAM,WAAW,QACxB,MAAM,IAAI,WAAW;;EAQG,UAAA,OAAA,MAAM,WAAW;EAUlB,SAAA,OAAA,MAAM,WAAW"}
@@ -0,0 +1,64 @@
1
+ import { hasTableFeature } from "../../../utils/has-feature.js";
2
+ import { focusDataTableRow, getDataTableRowElements } from "./data-table-row-focus.js";
3
+ import { useLayoutEffect, useRef } from "react";
4
+ //#region src/components/data-table/body/use-data-table-row-focus-recovery.ts
5
+ /**
6
+ * Devolve o foco a uma linha quando a que o tinha sai do corpo: apagada, de outra página,
7
+ * filtrada ou movida pela ordenação. Sem isto, o foco cai no `body`, e o teclado perde a tabela.
8
+ *
9
+ * O foco vai para a linha ativa, se ela continua no corpo; senão, para a que ficou na posição da
10
+ * que saiu, ou para a última. Com o foco fora da tabela, nada muda. Só com `activeRowFeature`.
11
+ *
12
+ * Devolve o ref e os handlers de foco do elemento do corpo.
13
+ */
14
+ const useDataTableRowFocusRecovery = (table, rows) => {
15
+ /** O elemento do corpo. */
16
+ const ref = useRef(null);
17
+ /** Se o foco está numa linha daqui, e a posição dela, gravados a cada foco recebido. */
18
+ const focusRef = useRef({
19
+ isInside: false,
20
+ index: 0
21
+ });
22
+ const onFocus = (event) => {
23
+ const rowElement = event.target.closest("[role=\"row\"]");
24
+ const index = rowElement instanceof HTMLElement ? getDataTableRowElements(event.currentTarget).indexOf(rowElement) : -1;
25
+ focusRef.current = {
26
+ isInside: true,
27
+ index: Math.max(index, 0)
28
+ };
29
+ };
30
+ const onBlur = (event) => {
31
+ if (event.relatedTarget && event.currentTarget.contains(event.relatedTarget)) return;
32
+ /**
33
+ * O Chrome também avisa a saída quando a linha com foco é removida, antes de tirá-la do DOM.
34
+ * Só depois do commit dá para separar: se o efeito abaixo devolveu o foco, ele não saiu.
35
+ */
36
+ queueMicrotask(() => {
37
+ focusRef.current.isInside = Boolean(ref.current?.contains(document.activeElement));
38
+ });
39
+ };
40
+ /**
41
+ * Depois de cada mudança das linhas, já com o DOM atualizado. Layout effect, e não effect, para
42
+ * o foco voltar antes da pintura.
43
+ */
44
+ useLayoutEffect(() => {
45
+ const element = ref.current;
46
+ const { activeElement } = document;
47
+ if (!(element && focusRef.current.isInside) || activeElement && activeElement !== document.body || !hasTableFeature(table, "activeRowFeature")) return;
48
+ const rowElements = getDataTableRowElements(element);
49
+ const activeRowId = table.getActiveRow()?.id;
50
+ const activeIndex = rows.findIndex((row) => row.id === activeRowId);
51
+ const targetRow = rowElements[activeIndex >= 0 ? activeIndex : Math.min(focusRef.current.index, rowElements.length - 1)];
52
+ if (targetRow) focusDataTableRow(targetRow);
53
+ else focusRef.current.isInside = false;
54
+ }, [table, rows]);
55
+ return {
56
+ ref,
57
+ onFocus,
58
+ onBlur
59
+ };
60
+ };
61
+ //#endregion
62
+ export { useDataTableRowFocusRecovery };
63
+
64
+ //# sourceMappingURL=use-data-table-row-focus-recovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-data-table-row-focus-recovery.js","names":[],"sources":["../../../../src/components/data-table/body/use-data-table-row-focus-recovery.ts"],"sourcesContent":["import type { Row, RowData, Table, TableFeatures } from '@tanstack/react-table';\nimport type React from 'react';\nimport { useLayoutEffect, useRef } from 'react';\nimport { hasTableFeature } from '../../../utils';\nimport {\n focusDataTableRow,\n getDataTableRowElements,\n} from './data-table-row-focus';\n\n/**\n * Devolve o foco a uma linha quando a que o tinha sai do corpo: apagada, de outra página,\n * filtrada ou movida pela ordenação. Sem isto, o foco cai no `body`, e o teclado perde a tabela.\n *\n * O foco vai para a linha ativa, se ela continua no corpo; senão, para a que ficou na posição da\n * que saiu, ou para a última. Com o foco fora da tabela, nada muda. Só com `activeRowFeature`.\n *\n * Devolve o ref e os handlers de foco do elemento do corpo.\n */\nexport const useDataTableRowFocusRecovery = <\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n table: Table<TFeatures, TData>,\n rows: Row<TFeatures, TData>[],\n) => {\n /** O elemento do corpo. */\n const ref = useRef<HTMLDivElement | null>(null);\n\n /** Se o foco está numa linha daqui, e a posição dela, gravados a cada foco recebido. */\n const focusRef = useRef({ isInside: false, index: 0 });\n\n const onFocus = (event: React.FocusEvent<HTMLDivElement>) => {\n const rowElement = event.target.closest('[role=\"row\"]');\n const index =\n rowElement instanceof HTMLElement\n ? getDataTableRowElements(event.currentTarget).indexOf(rowElement)\n : -1;\n\n focusRef.current = { isInside: true, index: Math.max(index, 0) };\n };\n\n const onBlur = (event: React.FocusEvent<HTMLDivElement>) => {\n if (\n event.relatedTarget &&\n event.currentTarget.contains(event.relatedTarget)\n ) {\n return;\n }\n\n /**\n * O Chrome também avisa a saída quando a linha com foco é removida, antes de tirá-la do DOM.\n * Só depois do commit dá para separar: se o efeito abaixo devolveu o foco, ele não saiu.\n */\n queueMicrotask(() => {\n focusRef.current.isInside = Boolean(\n ref.current?.contains(document.activeElement),\n );\n });\n };\n\n /**\n * Depois de cada mudança das linhas, já com o DOM atualizado. Layout effect, e não effect, para\n * o foco voltar antes da pintura.\n */\n useLayoutEffect(() => {\n const element = ref.current;\n const { activeElement } = document;\n\n if (\n !(element && focusRef.current.isInside) ||\n (activeElement && activeElement !== document.body) ||\n !hasTableFeature(table, 'activeRowFeature')\n ) {\n return;\n }\n\n const rowElements = getDataTableRowElements(element);\n const activeRowId = table.getActiveRow()?.id;\n const activeIndex = rows.findIndex((row) => row.id === activeRowId);\n const targetRow =\n rowElements[\n activeIndex >= 0\n ? activeIndex\n : Math.min(focusRef.current.index, rowElements.length - 1)\n ];\n\n if (targetRow) {\n focusDataTableRow(targetRow);\n } else {\n focusRef.current.isInside = false;\n }\n }, [table, rows]);\n\n return { ref, onFocus, onBlur };\n};\n"],"mappings":";;;;;;;;;;;;;AAkBA,MAAa,gCAIX,OACA,SACG;;CAEH,MAAM,MAAM,OAA8B,IAAI;;CAG9C,MAAM,WAAW,OAAO;EAAE,UAAU;EAAO,OAAO;CAAE,CAAC;CAErD,MAAM,WAAW,UAA4C;EAC3D,MAAM,aAAa,MAAM,OAAO,QAAQ,gBAAc;EACtD,MAAM,QACJ,sBAAsB,cAClB,wBAAwB,MAAM,aAAa,CAAC,CAAC,QAAQ,UAAU,IAC/D;EAEN,SAAS,UAAU;GAAE,UAAU;GAAM,OAAO,KAAK,IAAI,OAAO,CAAC;EAAE;CACjE;CAEA,MAAM,UAAU,UAA4C;EAC1D,IACE,MAAM,iBACN,MAAM,cAAc,SAAS,MAAM,aAAa,GAEhD;;;;;EAOF,qBAAqB;GACnB,SAAS,QAAQ,WAAW,QAC1B,IAAI,SAAS,SAAS,SAAS,aAAa,CAC9C;EACF,CAAC;CACH;;;;;CAMA,sBAAsB;EACpB,MAAM,UAAU,IAAI;EACpB,MAAM,EAAE,kBAAkB;EAE1B,IACE,EAAE,WAAW,SAAS,QAAQ,aAC7B,iBAAiB,kBAAkB,SAAS,QAC7C,CAAC,gBAAgB,OAAO,kBAAkB,GAE1C;EAGF,MAAM,cAAc,wBAAwB,OAAO;EACnD,MAAM,cAAc,MAAM,aAAa,CAAC,EAAE;EAC1C,MAAM,cAAc,KAAK,WAAW,QAAQ,IAAI,OAAO,WAAW;EAClE,MAAM,YACJ,YACE,eAAe,IACX,cACA,KAAK,IAAI,SAAS,QAAQ,OAAO,YAAY,SAAS,CAAC;EAG/D,IAAI,WACF,kBAAkB,SAAS;OAE3B,SAAS,QAAQ,WAAW;CAEhC,GAAG,CAAC,OAAO,IAAI,CAAC;CAEhB,OAAO;EAAE;EAAK;EAAS;CAAO;AAChC"}
@@ -0,0 +1,25 @@
1
+ import { useRender } from "@base-ui/react";
2
+ //#region src/components/data-table/header/data-table-header-button.d.ts
3
+ export type DataTableHeaderButtonProps = useRender.ComponentProps<'button'>;
4
+ /**
5
+ * O botão do tamanho da célula do header, sem ação: a base do `DataTable.SortTrigger` e de outros
6
+ * gatilhos do header, como o de um popover da coluna. Ocupa a `DataTable.HeaderCell` inteira; nas
7
+ * bordas, a área de agarre do `DataTable.ResizeHandle` fica por cima. Alinha o conteúdo pelo
8
+ * `data-align` da `DataTable.HeaderCell`, sem precisar do header.
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * <Popover.Root>
13
+ * <Popover.Trigger render={<DataTable.HeaderButton />}>
14
+ * <DataTable.HeaderContent header={header} />
15
+ * </Popover.Trigger>
16
+ * …
17
+ * </Popover.Root>
18
+ * ```
19
+ */
20
+ export declare const DataTableHeaderButton: {
21
+ (props: DataTableHeaderButtonProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
22
+ displayName: string;
23
+ };
24
+ //#endregion
25
+ //# sourceMappingURL=data-table-header-button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-table-header-button.d.ts","names":[],"sources":["../../../../src/components/data-table/header/data-table-header-button.tsx"],"mappings":";;YAGY,6BAA6B,UAAU;;;;;;;;;;;;;;;;;qBAkBtC;GAAgC,OAAA,6CAA0B,+CAAA"}
@@ -0,0 +1,57 @@
1
+ import { mergeProps, useRender } from "@base-ui/react";
2
+ import { mergeTwClassNames } from "@lucasbernardosn/react-ui/utils";
3
+ //#region src/components/data-table/header/data-table-header-button.tsx
4
+ /**
5
+ * O botão do tamanho da célula do header, sem ação: a base do `DataTable.SortTrigger` e de outros
6
+ * gatilhos do header, como o de um popover da coluna. Ocupa a `DataTable.HeaderCell` inteira; nas
7
+ * bordas, a área de agarre do `DataTable.ResizeHandle` fica por cima. Alinha o conteúdo pelo
8
+ * `data-align` da `DataTable.HeaderCell`, sem precisar do header.
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * <Popover.Root>
13
+ * <Popover.Trigger render={<DataTable.HeaderButton />}>
14
+ * <DataTable.HeaderContent header={header} />
15
+ * </Popover.Trigger>
16
+ * …
17
+ * </Popover.Root>
18
+ * ```
19
+ */
20
+ const DataTableHeaderButton = (props) => {
21
+ const { render, className, ...rest } = props;
22
+ const baseProps = {
23
+ "data-component": "DataTable.HeaderButton",
24
+ type: render === void 0 ? "button" : void 0,
25
+ className: mergeTwClassNames([
26
+ "flex-1",
27
+ "self-stretch",
28
+ "min-w-0",
29
+ "-mx-(--data-table-cell-padding)",
30
+ "px-(--data-table-cell-padding)",
31
+ "flex",
32
+ "items-center",
33
+ "gap-1",
34
+ "in-data-[align=center]:justify-center",
35
+ "in-data-[align=end]:[justify-content:end]",
36
+ "text-start",
37
+ "enabled:cursor-pointer",
38
+ "enabled:hover:bg-gray-3",
39
+ "enabled:hover:transition-[background-color]",
40
+ "enabled:hover:ease-in",
41
+ "enabled:hover:duration-150",
42
+ "focus-ring-outside",
43
+ "[--focus-ring-offset:-2px]",
44
+ "ring-gray-12"
45
+ ], className)
46
+ };
47
+ return useRender({
48
+ render,
49
+ defaultTagName: "button",
50
+ props: mergeProps(baseProps, rest)
51
+ });
52
+ };
53
+ DataTableHeaderButton.displayName = "DataTable.HeaderButton";
54
+ //#endregion
55
+ export { DataTableHeaderButton };
56
+
57
+ //# sourceMappingURL=data-table-header-button.js.map