@gcsa/console-react 0.1.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 (394) hide show
  1. package/dist/ConsoleHeader.d.ts +9 -0
  2. package/dist/ConsoleHeader.js +21 -0
  3. package/dist/ConsoleHeader.js.map +1 -0
  4. package/dist/ConsolePage.d.ts +8 -0
  5. package/dist/ConsolePage.js +14 -0
  6. package/dist/ConsolePage.js.map +1 -0
  7. package/dist/ConsoleShell.d.ts +23 -0
  8. package/dist/ConsoleShell.js +133 -0
  9. package/dist/ConsoleShell.js.map +1 -0
  10. package/dist/ConsoleSidebar.d.ts +11 -0
  11. package/dist/ConsoleSidebar.js +52 -0
  12. package/dist/ConsoleSidebar.js.map +1 -0
  13. package/dist/GcsaAlert.d.ts +9 -0
  14. package/dist/GcsaAlert.js +24 -0
  15. package/dist/GcsaAlert.js.map +1 -0
  16. package/dist/GcsaAutoComplete.d.ts +15 -0
  17. package/dist/GcsaAutoComplete.js +106 -0
  18. package/dist/GcsaAutoComplete.js.map +1 -0
  19. package/dist/GcsaAvatar.d.ts +8 -0
  20. package/dist/GcsaAvatar.js +13 -0
  21. package/dist/GcsaAvatar.js.map +1 -0
  22. package/dist/GcsaBadge.d.ts +7 -0
  23. package/dist/GcsaBadge.js +8 -0
  24. package/dist/GcsaBadge.js.map +1 -0
  25. package/dist/GcsaBrandMark.d.ts +4 -0
  26. package/dist/GcsaBrandMark.js +21 -0
  27. package/dist/GcsaBrandMark.js.map +1 -0
  28. package/dist/GcsaBreadcrumb.d.ts +9 -0
  29. package/dist/GcsaBreadcrumb.js +20 -0
  30. package/dist/GcsaBreadcrumb.js.map +1 -0
  31. package/dist/GcsaButton.d.ts +8 -0
  32. package/dist/GcsaButton.js +38 -0
  33. package/dist/GcsaButton.js.map +1 -0
  34. package/dist/GcsaCalendar.d.ts +11 -0
  35. package/dist/GcsaCalendar.js +35 -0
  36. package/dist/GcsaCalendar.js.map +1 -0
  37. package/dist/GcsaCard.d.ts +8 -0
  38. package/dist/GcsaCard.js +11 -0
  39. package/dist/GcsaCard.js.map +1 -0
  40. package/dist/GcsaCascader.d.ts +14 -0
  41. package/dist/GcsaCascader.js +91 -0
  42. package/dist/GcsaCascader.js.map +1 -0
  43. package/dist/GcsaChatPanel.d.ts +43 -0
  44. package/dist/GcsaChatPanel.js +180 -0
  45. package/dist/GcsaChatPanel.js.map +1 -0
  46. package/dist/GcsaCheckbox.d.ts +11 -0
  47. package/dist/GcsaCheckbox.js +45 -0
  48. package/dist/GcsaCheckbox.js.map +1 -0
  49. package/dist/GcsaCollapse.d.ts +16 -0
  50. package/dist/GcsaCollapse.js +20 -0
  51. package/dist/GcsaCollapse.js.map +1 -0
  52. package/dist/GcsaConfigProvider.d.ts +13 -0
  53. package/dist/GcsaConfigProvider.js +68 -0
  54. package/dist/GcsaConfigProvider.js.map +1 -0
  55. package/dist/GcsaDataTable.d.ts +119 -0
  56. package/dist/GcsaDataTable.js +508 -0
  57. package/dist/GcsaDataTable.js.map +1 -0
  58. package/dist/GcsaDatePicker.d.ts +16 -0
  59. package/dist/GcsaDatePicker.js +211 -0
  60. package/dist/GcsaDatePicker.js.map +1 -0
  61. package/dist/GcsaDateRangePicker.d.ts +17 -0
  62. package/dist/GcsaDateRangePicker.js +222 -0
  63. package/dist/GcsaDateRangePicker.js.map +1 -0
  64. package/dist/GcsaDateTimePicker.d.ts +13 -0
  65. package/dist/GcsaDateTimePicker.js +300 -0
  66. package/dist/GcsaDateTimePicker.js.map +1 -0
  67. package/dist/GcsaDescriptions.d.ts +9 -0
  68. package/dist/GcsaDescriptions.js +11 -0
  69. package/dist/GcsaDescriptions.js.map +1 -0
  70. package/dist/GcsaDivider.d.ts +4 -0
  71. package/dist/GcsaDivider.js +8 -0
  72. package/dist/GcsaDivider.js.map +1 -0
  73. package/dist/GcsaDrawer.d.ts +15 -0
  74. package/dist/GcsaDrawer.js +68 -0
  75. package/dist/GcsaDrawer.js.map +1 -0
  76. package/dist/GcsaDropdown.d.ts +20 -0
  77. package/dist/GcsaDropdown.js +46 -0
  78. package/dist/GcsaDropdown.js.map +1 -0
  79. package/dist/GcsaEmpty.d.ts +9 -0
  80. package/dist/GcsaEmpty.js +16 -0
  81. package/dist/GcsaEmpty.js.map +1 -0
  82. package/dist/GcsaField.d.ts +11 -0
  83. package/dist/GcsaField.js +26 -0
  84. package/dist/GcsaField.js.map +1 -0
  85. package/dist/GcsaForm.d.ts +13 -0
  86. package/dist/GcsaForm.js +60 -0
  87. package/dist/GcsaForm.js.map +1 -0
  88. package/dist/GcsaFormField.d.ts +16 -0
  89. package/dist/GcsaFormField.js +39 -0
  90. package/dist/GcsaFormField.js.map +1 -0
  91. package/dist/GcsaIcon.d.ts +7 -0
  92. package/dist/GcsaIcon.js +17 -0
  93. package/dist/GcsaIcon.js.map +1 -0
  94. package/dist/GcsaImagePreview.d.ts +8 -0
  95. package/dist/GcsaImagePreview.js +18 -0
  96. package/dist/GcsaImagePreview.js.map +1 -0
  97. package/dist/GcsaInput.d.ts +13 -0
  98. package/dist/GcsaInput.js +76 -0
  99. package/dist/GcsaInput.js.map +1 -0
  100. package/dist/GcsaInputGroup.d.ts +11 -0
  101. package/dist/GcsaInputGroup.js +27 -0
  102. package/dist/GcsaInputGroup.js.map +1 -0
  103. package/dist/GcsaInputNumber.d.ts +18 -0
  104. package/dist/GcsaInputNumber.js +108 -0
  105. package/dist/GcsaInputNumber.js.map +1 -0
  106. package/dist/GcsaLoading.d.ts +24 -0
  107. package/dist/GcsaLoading.js +101 -0
  108. package/dist/GcsaLoading.js.map +1 -0
  109. package/dist/GcsaLoadingMask.d.ts +8 -0
  110. package/dist/GcsaLoadingMask.js +39 -0
  111. package/dist/GcsaLoadingMask.js.map +1 -0
  112. package/dist/GcsaMarkdownRenderer.d.ts +6 -0
  113. package/dist/GcsaMarkdownRenderer.js +32 -0
  114. package/dist/GcsaMarkdownRenderer.js.map +1 -0
  115. package/dist/GcsaMenu.d.ts +16 -0
  116. package/dist/GcsaMenu.js +241 -0
  117. package/dist/GcsaMenu.js.map +1 -0
  118. package/dist/GcsaModal.d.ts +10 -0
  119. package/dist/GcsaModal.js +45 -0
  120. package/dist/GcsaModal.js.map +1 -0
  121. package/dist/GcsaMultiSelect.d.ts +23 -0
  122. package/dist/GcsaMultiSelect.js +149 -0
  123. package/dist/GcsaMultiSelect.js.map +1 -0
  124. package/dist/GcsaPagination.d.ts +17 -0
  125. package/dist/GcsaPagination.js +108 -0
  126. package/dist/GcsaPagination.js.map +1 -0
  127. package/dist/GcsaPopconfirm.d.ts +18 -0
  128. package/dist/GcsaPopconfirm.js +68 -0
  129. package/dist/GcsaPopconfirm.js.map +1 -0
  130. package/dist/GcsaPopover.d.ts +30 -0
  131. package/dist/GcsaPopover.js +65 -0
  132. package/dist/GcsaPopover.js.map +1 -0
  133. package/dist/GcsaPopoverClose.d.ts +6 -0
  134. package/dist/GcsaPopoverClose.js +9 -0
  135. package/dist/GcsaPopoverClose.js.map +1 -0
  136. package/dist/GcsaProgress.d.ts +5 -0
  137. package/dist/GcsaProgress.js +18 -0
  138. package/dist/GcsaProgress.js.map +1 -0
  139. package/dist/GcsaRadioGroup.d.ts +9 -0
  140. package/dist/GcsaRadioGroup.js +37 -0
  141. package/dist/GcsaRadioGroup.js.map +1 -0
  142. package/dist/GcsaResult.d.ts +9 -0
  143. package/dist/GcsaResult.js +14 -0
  144. package/dist/GcsaResult.js.map +1 -0
  145. package/dist/GcsaRow.d.ts +7 -0
  146. package/dist/GcsaRow.js +8 -0
  147. package/dist/GcsaRow.js.map +1 -0
  148. package/dist/GcsaSelect.d.ts +20 -0
  149. package/dist/GcsaSelect.js +117 -0
  150. package/dist/GcsaSelect.js.map +1 -0
  151. package/dist/GcsaSkeleton.d.ts +6 -0
  152. package/dist/GcsaSkeleton.js +19 -0
  153. package/dist/GcsaSkeleton.js.map +1 -0
  154. package/dist/GcsaSpace.d.ts +7 -0
  155. package/dist/GcsaSpace.js +14 -0
  156. package/dist/GcsaSpace.js.map +1 -0
  157. package/dist/GcsaSpin.d.ts +7 -0
  158. package/dist/GcsaSpin.js +16 -0
  159. package/dist/GcsaSpin.js.map +1 -0
  160. package/dist/GcsaStatistic.d.ts +8 -0
  161. package/dist/GcsaStatistic.js +11 -0
  162. package/dist/GcsaStatistic.js.map +1 -0
  163. package/dist/GcsaSteps.d.ts +10 -0
  164. package/dist/GcsaSteps.js +54 -0
  165. package/dist/GcsaSteps.js.map +1 -0
  166. package/dist/GcsaSwitch.d.ts +11 -0
  167. package/dist/GcsaSwitch.js +36 -0
  168. package/dist/GcsaSwitch.js.map +1 -0
  169. package/dist/GcsaTabs.d.ts +15 -0
  170. package/dist/GcsaTabs.js +39 -0
  171. package/dist/GcsaTabs.js.map +1 -0
  172. package/dist/GcsaTag.d.ts +7 -0
  173. package/dist/GcsaTag.js +9 -0
  174. package/dist/GcsaTag.js.map +1 -0
  175. package/dist/GcsaTextarea.d.ts +13 -0
  176. package/dist/GcsaTextarea.js +76 -0
  177. package/dist/GcsaTextarea.js.map +1 -0
  178. package/dist/GcsaTimePicker.d.ts +12 -0
  179. package/dist/GcsaTimePicker.js +221 -0
  180. package/dist/GcsaTimePicker.js.map +1 -0
  181. package/dist/GcsaTimeline.d.ts +5 -0
  182. package/dist/GcsaTimeline.js +19 -0
  183. package/dist/GcsaTimeline.js.map +1 -0
  184. package/dist/GcsaToastStack.d.ts +11 -0
  185. package/dist/GcsaToastStack.js +45 -0
  186. package/dist/GcsaToastStack.js.map +1 -0
  187. package/dist/GcsaTooltip.d.ts +17 -0
  188. package/dist/GcsaTooltip.js +43 -0
  189. package/dist/GcsaTooltip.js.map +1 -0
  190. package/dist/GcsaTransfer.d.ts +11 -0
  191. package/dist/GcsaTransfer.js +95 -0
  192. package/dist/GcsaTransfer.js.map +1 -0
  193. package/dist/GcsaTree.d.ts +17 -0
  194. package/dist/GcsaTree.js +38 -0
  195. package/dist/GcsaTree.js.map +1 -0
  196. package/dist/GcsaTypography.d.ts +8 -0
  197. package/dist/GcsaTypography.js +14 -0
  198. package/dist/GcsaTypography.js.map +1 -0
  199. package/dist/GcsaUpload.d.ts +24 -0
  200. package/dist/GcsaUpload.js +146 -0
  201. package/dist/GcsaUpload.js.map +1 -0
  202. package/dist/hooks/gcsaFormTypes.d.ts +7 -0
  203. package/dist/hooks/useDocumentThemeSync.d.ts +3 -0
  204. package/dist/hooks/useDocumentThemeSync.js +7 -0
  205. package/dist/hooks/useDocumentThemeSync.js.map +1 -0
  206. package/dist/hooks/useGcsaComponentSize.d.ts +5 -0
  207. package/dist/hooks/useGcsaComponentSize.js +21 -0
  208. package/dist/hooks/useGcsaComponentSize.js.map +1 -0
  209. package/dist/hooks/useGcsaFormField.d.ts +26 -0
  210. package/dist/hooks/useGcsaFormField.js +47 -0
  211. package/dist/hooks/useGcsaFormField.js.map +1 -0
  212. package/dist/hooks/useGcsaFormSchema.d.ts +7 -0
  213. package/dist/hooks/useGcsaFormSchema.js +6 -0
  214. package/dist/hooks/useGcsaFormSchema.js.map +1 -0
  215. package/dist/hooks/useGcsaLocale.d.ts +4 -0
  216. package/dist/hooks/useGcsaLocale.js +15 -0
  217. package/dist/hooks/useGcsaLocale.js.map +1 -0
  218. package/dist/hooks/useGcsaPopupZIndex.d.ts +6 -0
  219. package/dist/hooks/useGcsaPopupZIndex.js +18 -0
  220. package/dist/hooks/useGcsaPopupZIndex.js.map +1 -0
  221. package/dist/hooks/useGcsaTextCount.d.ts +16 -0
  222. package/dist/hooks/useGcsaTextCount.js +16 -0
  223. package/dist/hooks/useGcsaTextCount.js.map +1 -0
  224. package/dist/hooks/useGcsaTheme.d.ts +7 -0
  225. package/dist/hooks/useGcsaTheme.js +19 -0
  226. package/dist/hooks/useGcsaTheme.js.map +1 -0
  227. package/dist/hooks/useGcsaZIndex.d.ts +13 -0
  228. package/dist/hooks/useGcsaZIndex.js +37 -0
  229. package/dist/hooks/useGcsaZIndex.js.map +1 -0
  230. package/dist/hooks/useMessage.d.ts +6 -0
  231. package/dist/hooks/useOverlayZIndex.d.ts +8 -0
  232. package/dist/hooks/useOverlayZIndex.js +14 -0
  233. package/dist/hooks/useOverlayZIndex.js.map +1 -0
  234. package/dist/hooks/usePreventHiddenInputScroll.d.ts +13 -0
  235. package/dist/hooks/usePreventHiddenInputScroll.js +124 -0
  236. package/dist/hooks/usePreventHiddenInputScroll.js.map +1 -0
  237. package/dist/icons/iconNames.d.ts +7 -0
  238. package/dist/icons/iconNames.js +24 -0
  239. package/dist/icons/iconNames.js.map +1 -0
  240. package/dist/icons/index.d.ts +2 -0
  241. package/dist/icons/registry.d.ts +3 -0
  242. package/dist/icons/registry.js +58 -0
  243. package/dist/icons/registry.js.map +1 -0
  244. package/dist/icons/svg/alert.svg.js +9 -0
  245. package/dist/icons/svg/alert.svg.js.map +1 -0
  246. package/dist/icons/svg/assets.svg.js +9 -0
  247. package/dist/icons/svg/assets.svg.js.map +1 -0
  248. package/dist/icons/svg/chat.svg.js +8 -0
  249. package/dist/icons/svg/chat.svg.js.map +1 -0
  250. package/dist/icons/svg/check.svg.js +8 -0
  251. package/dist/icons/svg/check.svg.js.map +1 -0
  252. package/dist/icons/svg/chevron-down.svg.js +8 -0
  253. package/dist/icons/svg/chevron-down.svg.js.map +1 -0
  254. package/dist/icons/svg/chevron-left.svg.js +8 -0
  255. package/dist/icons/svg/chevron-left.svg.js.map +1 -0
  256. package/dist/icons/svg/chevron-right.svg.js +8 -0
  257. package/dist/icons/svg/chevron-right.svg.js.map +1 -0
  258. package/dist/icons/svg/chevron-up.svg.js +8 -0
  259. package/dist/icons/svg/chevron-up.svg.js.map +1 -0
  260. package/dist/icons/svg/close.svg.js +6 -0
  261. package/dist/icons/svg/close.svg.js.map +1 -0
  262. package/dist/icons/svg/dashboard.svg.js +8 -0
  263. package/dist/icons/svg/dashboard.svg.js.map +1 -0
  264. package/dist/icons/svg/menu.svg.js +8 -0
  265. package/dist/icons/svg/menu.svg.js.map +1 -0
  266. package/dist/icons/svg/plus.svg.js +6 -0
  267. package/dist/icons/svg/plus.svg.js.map +1 -0
  268. package/dist/icons/svg/result-empty.svg.js +6 -0
  269. package/dist/icons/svg/result-empty.svg.js.map +1 -0
  270. package/dist/icons/svg/settings.svg.js +8 -0
  271. package/dist/icons/svg/settings.svg.js.map +1 -0
  272. package/dist/icons/svg/users.svg.js +11 -0
  273. package/dist/icons/svg/users.svg.js.map +1 -0
  274. package/dist/index.d.ts +151 -0
  275. package/dist/index.js +166 -0
  276. package/dist/index.js.map +1 -0
  277. package/dist/style.css +8028 -0
  278. package/dist/utils/gcsaDateValue.d.ts +25 -0
  279. package/dist/utils/gcsaDateValue.js +60 -0
  280. package/dist/utils/gcsaDateValue.js.map +1 -0
  281. package/dist/utils/gcsaTableColumns.d.ts +19 -0
  282. package/dist/utils/gcsaTableColumns.js +43 -0
  283. package/dist/utils/gcsaTableColumns.js.map +1 -0
  284. package/dist/utils/preserveDrawerScroll.d.ts +2 -0
  285. package/dist/utils/preserveDrawerScroll.js +13 -0
  286. package/dist/utils/preserveDrawerScroll.js.map +1 -0
  287. package/dist/utils/zodValidators.d.ts +21 -0
  288. package/dist/utils/zodValidators.js +35 -0
  289. package/dist/utils/zodValidators.js.map +1 -0
  290. package/package.json +58 -0
  291. package/src/ConsoleHeader.tsx +24 -0
  292. package/src/ConsolePage.tsx +22 -0
  293. package/src/ConsoleShell.tsx +248 -0
  294. package/src/ConsoleSidebar.tsx +61 -0
  295. package/src/GcsaAlert.tsx +29 -0
  296. package/src/GcsaAutoComplete.tsx +163 -0
  297. package/src/GcsaAvatar.tsx +21 -0
  298. package/src/GcsaBadge.tsx +15 -0
  299. package/src/GcsaBrandMark.tsx +18 -0
  300. package/src/GcsaBreadcrumb.tsx +35 -0
  301. package/src/GcsaButton.tsx +44 -0
  302. package/src/GcsaCalendar.tsx +14 -0
  303. package/src/GcsaCard.tsx +21 -0
  304. package/src/GcsaCascader.tsx +121 -0
  305. package/src/GcsaChatPanel.tsx +320 -0
  306. package/src/GcsaCheckbox.tsx +55 -0
  307. package/src/GcsaCollapse.tsx +23 -0
  308. package/src/GcsaConfigProvider.tsx +121 -0
  309. package/src/GcsaDataTable.tsx +779 -0
  310. package/src/GcsaDatePicker.tsx +284 -0
  311. package/src/GcsaDateRangePicker.tsx +310 -0
  312. package/src/GcsaDateTimePicker.tsx +407 -0
  313. package/src/GcsaDescriptions.tsx +22 -0
  314. package/src/GcsaDivider.tsx +7 -0
  315. package/src/GcsaDrawer.tsx +87 -0
  316. package/src/GcsaDropdown.tsx +84 -0
  317. package/src/GcsaEmpty.tsx +27 -0
  318. package/src/GcsaField.tsx +50 -0
  319. package/src/GcsaForm.tsx +82 -0
  320. package/src/GcsaFormField.tsx +67 -0
  321. package/src/GcsaIcon.tsx +21 -0
  322. package/src/GcsaImagePreview.tsx +30 -0
  323. package/src/GcsaInput.tsx +87 -0
  324. package/src/GcsaInputGroup.tsx +32 -0
  325. package/src/GcsaInputNumber.tsx +155 -0
  326. package/src/GcsaLoading.ts +206 -0
  327. package/src/GcsaLoadingMask.tsx +53 -0
  328. package/src/GcsaMarkdownRenderer.tsx +40 -0
  329. package/src/GcsaMenu.tsx +340 -0
  330. package/src/GcsaModal.tsx +68 -0
  331. package/src/GcsaMultiSelect.tsx +246 -0
  332. package/src/GcsaPagination.tsx +194 -0
  333. package/src/GcsaPopconfirm.tsx +104 -0
  334. package/src/GcsaPopover.tsx +131 -0
  335. package/src/GcsaPopoverClose.tsx +11 -0
  336. package/src/GcsaProgress.tsx +18 -0
  337. package/src/GcsaRadioGroup.tsx +42 -0
  338. package/src/GcsaResult.tsx +23 -0
  339. package/src/GcsaRow.tsx +13 -0
  340. package/src/GcsaSelect.tsx +186 -0
  341. package/src/GcsaSkeleton.tsx +19 -0
  342. package/src/GcsaSpace.tsx +17 -0
  343. package/src/GcsaSpin.tsx +25 -0
  344. package/src/GcsaStatistic.tsx +17 -0
  345. package/src/GcsaSteps.tsx +73 -0
  346. package/src/GcsaSwitch.tsx +45 -0
  347. package/src/GcsaTabs.tsx +53 -0
  348. package/src/GcsaTag.tsx +16 -0
  349. package/src/GcsaTextarea.tsx +87 -0
  350. package/src/GcsaTimePicker.tsx +298 -0
  351. package/src/GcsaTimeline.tsx +27 -0
  352. package/src/GcsaToastStack.tsx +67 -0
  353. package/src/GcsaTooltip.tsx +75 -0
  354. package/src/GcsaTransfer.tsx +129 -0
  355. package/src/GcsaTree.tsx +43 -0
  356. package/src/GcsaTypography.tsx +24 -0
  357. package/src/GcsaUpload.tsx +206 -0
  358. package/src/hooks/gcsaFormTypes.ts +23 -0
  359. package/src/hooks/useDocumentThemeSync.ts +6 -0
  360. package/src/hooks/useGcsaComponentSize.ts +24 -0
  361. package/src/hooks/useGcsaFormField.ts +49 -0
  362. package/src/hooks/useGcsaFormSchema.ts +6 -0
  363. package/src/hooks/useGcsaLocale.ts +16 -0
  364. package/src/hooks/useGcsaPopupZIndex.ts +23 -0
  365. package/src/hooks/useGcsaTextCount.ts +44 -0
  366. package/src/hooks/useGcsaTheme.ts +19 -0
  367. package/src/hooks/useGcsaZIndex.ts +60 -0
  368. package/src/hooks/useMessage.ts +7 -0
  369. package/src/hooks/useOverlayZIndex.ts +23 -0
  370. package/src/hooks/usePreventHiddenInputScroll.ts +233 -0
  371. package/src/icons/iconNames.ts +27 -0
  372. package/src/icons/index.ts +8 -0
  373. package/src/icons/registry.ts +38 -0
  374. package/src/icons/svg/alert.svg +4 -0
  375. package/src/icons/svg/assets.svg +4 -0
  376. package/src/icons/svg/chat.svg +3 -0
  377. package/src/icons/svg/check.svg +3 -0
  378. package/src/icons/svg/chevron-down.svg +3 -0
  379. package/src/icons/svg/chevron-left.svg +3 -0
  380. package/src/icons/svg/chevron-right.svg +3 -0
  381. package/src/icons/svg/chevron-up.svg +3 -0
  382. package/src/icons/svg/close.svg +1 -0
  383. package/src/icons/svg/dashboard.svg +3 -0
  384. package/src/icons/svg/menu.svg +3 -0
  385. package/src/icons/svg/plus.svg +1 -0
  386. package/src/icons/svg/result-empty.svg +1 -0
  387. package/src/icons/svg/settings.svg +3 -0
  388. package/src/icons/svg/users.svg +6 -0
  389. package/src/index.ts +166 -0
  390. package/src/utils/gcsaDateValue.ts +99 -0
  391. package/src/utils/gcsaTableColumns.ts +97 -0
  392. package/src/utils/preserveDrawerScroll.ts +20 -0
  393. package/src/utils/zodValidators.ts +45 -0
  394. package/src/vite-env.d.ts +6 -0
@@ -0,0 +1,779 @@
1
+ import { Fragment, useEffect, useMemo, useRef, useState, type CSSProperties, type MouseEvent as ReactMouseEvent, type MutableRefObject, type PointerEvent as ReactPointerEvent, type ReactNode } from 'react';
2
+ import {
3
+ flexRender,
4
+ getCoreRowModel,
5
+ getFilteredRowModel,
6
+ getExpandedRowModel,
7
+ getPaginationRowModel,
8
+ getSortedRowModel,
9
+ useReactTable,
10
+ type ColumnDef,
11
+ type ColumnFiltersState,
12
+ type ExpandedState,
13
+ type Row,
14
+ type SortingState
15
+ } from '@tanstack/react-table';
16
+ import type {
17
+ GcsaLegacyTableColumn,
18
+ GcsaPaginationAlign,
19
+ GcsaPaginationLayoutPart,
20
+ GcsaTableColumn,
21
+ GcsaTableColumnFixed,
22
+ GcsaTableColumnInfo
23
+ } from '@gcsa/console-core';
24
+ import {
25
+ GCSA_TABLE_DEFAULT_COLUMN_MIN_WIDTH,
26
+ GCSA_TABLE_EXPAND_COLUMN_WIDTH,
27
+ GCSA_TABLE_SELECTION_COLUMN_WIDTH,
28
+ formatGcsaLocaleMessage,
29
+ getGcsaTableFixedOffset,
30
+ getGcsaTableDefaultExpandedKeys,
31
+ getGcsaTableMinWidth,
32
+ getGcsaTableRowId,
33
+ getGcsaTableSortChange,
34
+ getGcsaTableSorting,
35
+ normalizeGcsaTableColumns
36
+ } from '@gcsa/console-core';
37
+ import { GcsaCheckbox } from './GcsaCheckbox';
38
+ import { GcsaEmpty } from './GcsaEmpty';
39
+ import { GcsaIcon } from './GcsaIcon';
40
+ import { GcsaInput } from './GcsaInput';
41
+ import { GcsaPagination } from './GcsaPagination';
42
+ import { GcsaSelect } from './GcsaSelect';
43
+ import { GcsaSpin } from './GcsaSpin';
44
+ import { formatGcsaTableCellValue, resolveGcsaTableColumns } from './utils/gcsaTableColumns';
45
+ import { useGcsaLocaleMessages } from './hooks/useGcsaLocale';
46
+ import { useGcsaComponentSize } from './hooks/useGcsaComponentSize';
47
+
48
+ type TableMeta = {
49
+ width?: string;
50
+ minWidth?: string;
51
+ align?: 'left' | 'center' | 'right';
52
+ slotKey?: string;
53
+ fixed?: GcsaTableColumnFixed;
54
+ hidden?: boolean;
55
+ showOverflowTooltip?: boolean;
56
+ filter?: { type: 'text' | 'select'; placeholder?: string; options?: Array<{ label: string; value: string; disabled?: boolean }> };
57
+ };
58
+
59
+ function childColumns<T extends Record<string, unknown>>(column: ColumnDef<T, unknown>): ColumnDef<T, unknown>[] {
60
+ return 'columns' in column && Array.isArray(column.columns)
61
+ ? column.columns as ColumnDef<T, unknown>[]
62
+ : [];
63
+ }
64
+
65
+ function flattenColumns<T extends Record<string, unknown>>(columns: ColumnDef<T, unknown>[]): ColumnDef<T, unknown>[] {
66
+ return columns.flatMap(column => {
67
+ const children = childColumns(column);
68
+ return children.length ? flattenColumns(children) : [column];
69
+ });
70
+ }
71
+
72
+ function filterColumnTree<T extends Record<string, unknown>>(columns: ColumnDef<T, unknown>[], visibility: Record<string, boolean>): ColumnDef<T, unknown>[] {
73
+ return columns.flatMap(column => {
74
+ const meta = metaOf(column);
75
+ if (meta.hidden || visibility[column.id ?? ''] === false) return [];
76
+ const columnChildren = childColumns(column);
77
+ if (!columnChildren.length) return [column];
78
+ const children = filterColumnTree(columnChildren, visibility);
79
+ return children.length ? [{ ...column, columns: children }] : [];
80
+ });
81
+ }
82
+
83
+ function TableLoadingState({ label }: { label: string }) {
84
+ return (
85
+ <div className="gcsa-data-table__state gcsa-data-table__state--loading" role="status" aria-live="polite">
86
+ <div className="gcsa-data-table__loading-label">
87
+ <GcsaSpin spinning />
88
+ <span>{label}</span>
89
+ </div>
90
+ </div>
91
+ );
92
+ }
93
+
94
+ export type GcsaDataTableProps<T extends Record<string, unknown>> = {
95
+ data: T[];
96
+ columns?: Array<GcsaTableColumn<T> | ColumnDef<T, unknown>>;
97
+ legacyColumns?: GcsaLegacyTableColumn<T>[];
98
+ total?: number;
99
+ pageSize?: number;
100
+ pageSizeOptions?: number[];
101
+ showPageSize?: boolean;
102
+ showJumper?: boolean;
103
+ pageSizeLabel?: string;
104
+ jumperLabel?: string;
105
+ paginationLayout?: string | GcsaPaginationLayoutPart[];
106
+ paginationAlign?: GcsaPaginationAlign;
107
+ showTotal?: boolean;
108
+ page?: number;
109
+ pagination?: boolean;
110
+ showToolbar?: boolean;
111
+ /** 工具栏是否显示总条数 */
112
+ showCount?: boolean;
113
+ size?: 'sm' | 'md';
114
+ serverSide?: boolean;
115
+ sorting?: SortingState;
116
+ filters?: Record<string, string>;
117
+ defaultSorting?: SortingState;
118
+ defaultFilters?: Record<string, string>;
119
+ loading?: boolean;
120
+ error?: string;
121
+ retryLabel?: string;
122
+ selectable?: boolean | ((row: T, index: number) => boolean);
123
+ selectedRowKeys?: string[];
124
+ columnVisibility?: Record<string, boolean>;
125
+ resizable?: boolean;
126
+ columnWidths?: Record<string, number>;
127
+ treeData?: boolean;
128
+ childrenKey?: keyof T & string;
129
+ treeLazy?: boolean;
130
+ treeHasChildrenKey?: keyof T & string;
131
+ treeHasChildren?: (row: T, index: number) => boolean;
132
+ loadChildren?: (row: T, index: number) => Promise<T[]> | T[];
133
+ treeLoadingText?: string;
134
+ treeLoadErrorText?: string;
135
+ expandedRowKeys?: string[];
136
+ mobileMode?: 'scroll' | 'cards';
137
+ stripe?: boolean;
138
+ bordered?: boolean;
139
+ highlightCurrentRow?: boolean;
140
+ currentRowKey?: string;
141
+ rowClassName?: string | ((row: T, index: number) => string | undefined);
142
+ summary?: (rows: T[]) => Record<string, string | number | null | undefined>;
143
+ summaryLabel?: string;
144
+ apiRef?: MutableRefObject<GcsaDataTableApi<T> | null>;
145
+ rowKey?: keyof T & string | ((row: T, index: number) => string);
146
+ height?: string | number;
147
+ maxHeight?: string | number;
148
+ expandable?: boolean;
149
+ defaultExpandAll?: boolean;
150
+ fixedSelection?: boolean;
151
+ selectionColumnWidth?: number;
152
+ expandColumnWidth?: number;
153
+ renderExpandedRow?: (row: T, index: number) => ReactNode;
154
+ toolbar?: ReactNode;
155
+ onPageChange?: (page: number) => void;
156
+ onPageSizeChange?: (pageSize: number) => void;
157
+ onSortingChange?: (sorting: SortingState) => void;
158
+ /** Element-style sort event payload for migration from el-table. */
159
+ onSortChange?: (change: ReturnType<typeof getGcsaTableSortChange>) => void;
160
+ onFiltersChange?: (filters: Record<string, string>) => void;
161
+ onFilterChange?: (filters: Record<string, string>) => void;
162
+ onSelectionChange?: (rows: T[]) => void;
163
+ onSelect?: (rows: T[], row: T) => void;
164
+ onSelectAll?: (rows: T[]) => void;
165
+ onSelectedRowKeysChange?: (keys: string[]) => void;
166
+ onColumnVisibilityChange?: (visibility: Record<string, boolean>) => void;
167
+ onColumnWidthsChange?: (widths: Record<string, number>) => void;
168
+ onExpandedRowKeysChange?: (keys: string[]) => void;
169
+ onCurrentRowKeyChange?: (key: string | undefined) => void;
170
+ onRowClick?: (row: T, index: number, event: ReactMouseEvent<HTMLTableRowElement>) => void;
171
+ onRowDoubleClick?: (row: T, index: number, event: ReactMouseEvent<HTMLTableRowElement>) => void;
172
+ onCellClick?: (row: T, column: string, value: unknown, index: number, event: ReactMouseEvent<HTMLTableCellElement>) => void;
173
+ onCellDoubleClick?: (row: T, column: string, value: unknown, index: number, event: ReactMouseEvent<HTMLTableCellElement>) => void;
174
+ onHeaderClick?: (column: GcsaTableColumnInfo, event: ReactMouseEvent<HTMLTableCellElement>) => void;
175
+ onRowContextMenu?: (row: T, index: number, event: ReactMouseEvent<HTMLTableRowElement>) => void;
176
+ onCellContextMenu?: (row: T, column: string, value: unknown, index: number, event: ReactMouseEvent<HTMLTableCellElement>) => void;
177
+ onLegacyRowClick?: (row: T, column: GcsaTableColumnInfo, event: ReactMouseEvent<HTMLTableRowElement>) => void;
178
+ onLegacyCellClick?: (row: T, column: GcsaTableColumnInfo, cell: HTMLTableCellElement, event: ReactMouseEvent<HTMLTableCellElement>) => void;
179
+ onLegacyRowContextMenu?: (row: T, column: GcsaTableColumnInfo, event: ReactMouseEvent<HTMLTableRowElement>) => void;
180
+ onLegacyCellContextMenu?: (row: T, column: GcsaTableColumnInfo, cell: HTMLTableCellElement, event: ReactMouseEvent<HTMLTableCellElement>) => void;
181
+ onCurrentChange?: (current: T | undefined, previous: T | undefined) => void;
182
+ onExpandChange?: (row: T, expanded: boolean, expandedRows: T[]) => void;
183
+ columnSelector?: (columns: Array<{ id: string; title: string; visible: boolean }>, toggle: (id: string) => void) => ReactNode;
184
+ onRetry?: () => void;
185
+ onTreeLoadError?: (error: unknown, row: T, index: number) => void;
186
+ };
187
+
188
+ export type GcsaDataTableApi<T extends Record<string, unknown>> = {
189
+ clearSorting: () => void;
190
+ clearFilters: () => void;
191
+ clearSelection: () => void;
192
+ clearExpanded: () => void;
193
+ setRowSelected: (key: string, selected?: boolean) => void;
194
+ setRowExpanded: (key: string, expanded?: boolean) => Promise<void>;
195
+ clearSort: () => void;
196
+ clearFilter: (columnKeys?: string | string[]) => void;
197
+ sort: (prop: string, order: 'ascending' | 'descending' | null) => void;
198
+ toggleRowSelection: (row: T, selected?: boolean) => void;
199
+ toggleAllSelection: () => void;
200
+ toggleRowExpansion: (row: T, expanded?: boolean) => Promise<void>;
201
+ setCurrentRow: (row?: T) => void;
202
+ getSelectionRows: () => T[];
203
+ setScrollTop: (top: number) => void;
204
+ scrollTo: (options: ScrollToOptions | number, y?: number) => void;
205
+ };
206
+
207
+ function metaOf<T>(column: ColumnDef<T, unknown>): TableMeta {
208
+ return (column.meta ?? {}) as TableMeta;
209
+ }
210
+
211
+ function toColumnFilters(filters?: Record<string, string>): ColumnFiltersState {
212
+ return Object.entries(filters ?? {}).filter(([, value]) => value !== '').map(([id, value]) => ({ id, value }));
213
+ }
214
+
215
+ function filterRecord(filters: ColumnFiltersState) {
216
+ return Object.fromEntries(filters.map(filter => [filter.id, String(filter.value)]));
217
+ }
218
+
219
+ function fixedStyle<T extends Record<string, unknown>>(
220
+ columns: ColumnDef<T, unknown>[],
221
+ id: string,
222
+ meta: TableMeta,
223
+ widths: Record<string, number> = {},
224
+ controls: { expandable: boolean; selectable: boolean; fixedSelection: boolean; expandColumnWidth?: number; selectionColumnWidth?: number }
225
+ ): CSSProperties | undefined {
226
+ const override = widths[id];
227
+ const sizing = override
228
+ ? { width: `${override}px`, minWidth: `${override}px` }
229
+ : meta.width || meta.minWidth
230
+ ? { width: meta.width, minWidth: meta.minWidth ?? meta.width }
231
+ : { minWidth: `${GCSA_TABLE_DEFAULT_COLUMN_MIN_WIDTH}px` };
232
+ if (!meta.fixed) return Object.keys(sizing).length ? sizing : undefined;
233
+ const fixedDirection = meta.fixed === true ? 'left' : meta.fixed;
234
+ const offset = getGcsaTableFixedOffset(
235
+ columns.map(column => ({ id: column.id ?? '', ...metaOf(column) })),
236
+ id,
237
+ fixedDirection,
238
+ { ...controls, columnWidths: widths }
239
+ );
240
+ return { ...sizing, position: 'sticky', [fixedDirection]: offset } as CSSProperties;
241
+ }
242
+
243
+ function collectExpandedRows<T extends Record<string, unknown>>(
244
+ rows: T[],
245
+ expanded: ExpandedState,
246
+ getRowId: (row: T, index: number, parent?: Row<T>) => string,
247
+ treeData: boolean,
248
+ childrenKey: keyof T & string
249
+ ) {
250
+ const expandedKeys = expanded === true ? undefined : new Set(Object.keys(expanded).filter(key => expanded[key]));
251
+ const result: T[] = [];
252
+ const visit = (items: T[], parent?: Row<T>) => items.forEach((row, index) => {
253
+ const key = getRowId(row, index, parent);
254
+ if (!expandedKeys || expandedKeys.has(key)) result.push(row);
255
+ if (treeData) {
256
+ const children = (row as Record<string, unknown>)[childrenKey];
257
+ if (Array.isArray(children)) visit(children as T[], { id: key } as Row<T>);
258
+ }
259
+ });
260
+ visit(rows);
261
+ return result;
262
+ }
263
+
264
+ export function GcsaDataTable<T extends Record<string, unknown>>({
265
+ data,
266
+ columns,
267
+ legacyColumns,
268
+ total = data.length,
269
+ pageSize: pageSizeProp = 10,
270
+ pageSizeOptions = [10, 20, 50, 100],
271
+ showPageSize = false,
272
+ showJumper = false,
273
+ pageSizeLabel,
274
+ jumperLabel,
275
+ paginationLayout,
276
+ paginationAlign,
277
+ showTotal = true,
278
+ page = 1,
279
+ pagination = true,
280
+ showToolbar = true,
281
+ showCount = true,
282
+ size,
283
+ serverSide = false,
284
+ sorting: controlledSorting,
285
+ filters: controlledFilters,
286
+ defaultSorting = [],
287
+ defaultFilters = {},
288
+ loading = false,
289
+ error,
290
+ retryLabel,
291
+ selectable,
292
+ selectedRowKeys,
293
+ columnVisibility: controlledColumnVisibility,
294
+ resizable = false,
295
+ columnWidths: controlledColumnWidths,
296
+ treeData = false,
297
+ childrenKey = 'children' as keyof T & string,
298
+ treeLazy = false,
299
+ treeHasChildrenKey = 'hasChildren' as keyof T & string,
300
+ treeHasChildren,
301
+ loadChildren,
302
+ treeLoadingText,
303
+ treeLoadErrorText,
304
+ expandedRowKeys,
305
+ mobileMode = 'scroll',
306
+ stripe = false,
307
+ bordered = false,
308
+ highlightCurrentRow = false,
309
+ currentRowKey: controlledCurrentRowKey,
310
+ rowClassName,
311
+ summary,
312
+ summaryLabel,
313
+ apiRef,
314
+ rowKey,
315
+ expandable,
316
+ height,
317
+ maxHeight,
318
+ defaultExpandAll = false,
319
+ fixedSelection,
320
+ selectionColumnWidth,
321
+ expandColumnWidth,
322
+ renderExpandedRow,
323
+ toolbar,
324
+ onPageChange,
325
+ onPageSizeChange,
326
+ onSortingChange,
327
+ onSortChange,
328
+ onFiltersChange,
329
+ onFilterChange,
330
+ onSelectionChange,
331
+ onSelect,
332
+ onSelectAll,
333
+ onSelectedRowKeysChange,
334
+ onColumnVisibilityChange,
335
+ onColumnWidthsChange,
336
+ onExpandedRowKeysChange,
337
+ onCurrentRowKeyChange,
338
+ onRowClick,
339
+ onRowDoubleClick,
340
+ onCellClick,
341
+ onCellDoubleClick,
342
+ onHeaderClick,
343
+ onRowContextMenu,
344
+ onCellContextMenu,
345
+ onLegacyRowClick,
346
+ onLegacyCellClick,
347
+ onLegacyRowContextMenu,
348
+ onLegacyCellContextMenu,
349
+ onCurrentChange,
350
+ onExpandChange,
351
+ columnSelector,
352
+ onRetry,
353
+ onTreeLoadError
354
+ }: GcsaDataTableProps<T>) {
355
+ const messages = useGcsaLocaleMessages();
356
+ const resolvedPageSizeLabel = pageSizeLabel ?? messages.paginationPageSize;
357
+ const resolvedJumperLabel = jumperLabel ?? messages.paginationJumper;
358
+ const resolvedRetryLabel = retryLabel ?? messages.retry;
359
+ const resolvedTreeLoadingText = treeLoadingText ?? messages.dataTableTreeLoading;
360
+ const resolvedTreeLoadErrorText = treeLoadErrorText ?? messages.dataTableTreeLoadError;
361
+ const resolvedSummaryLabel = summaryLabel ?? messages.dataTableSummary;
362
+ const resolvedSize = useGcsaComponentSize(size);
363
+ const getRowId = (row: T, index: number, parent?: Row<T>) => getGcsaTableRowId(row, index, rowKey, parent?.id);
364
+ const [pageSize, setPageSize] = useState(pageSizeProp);
365
+ const [sorting, setSorting] = useState<SortingState>(() => [...(controlledSorting ?? defaultSorting)]);
366
+ const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>(() => toColumnFilters(controlledFilters ?? defaultFilters));
367
+ const [rowSelection, setRowSelection] = useState<Record<string, boolean>>(() => Object.fromEntries((selectedRowKeys ?? []).map(key => [key, true])));
368
+ const [columnVisibility, setColumnVisibility] = useState<Record<string, boolean>>(controlledColumnVisibility ?? {});
369
+ const [columnWidths, setColumnWidths] = useState<Record<string, number>>(controlledColumnWidths ?? {});
370
+ const [expandedKeys, setExpandedKeys] = useState<ExpandedState>(() => Object.fromEntries((expandedRowKeys ?? (defaultExpandAll ? getGcsaTableDefaultExpandedKeys(data, treeData, childrenKey, rowKey) : [])).map(key => [key, true])));
371
+ const [currentRowKey, setCurrentRowKey] = useState(controlledCurrentRowKey);
372
+ const [treeChildren, setTreeChildren] = useState<Record<string, T[]>>({});
373
+ const [treeLoadingKeys, setTreeLoadingKeys] = useState<Record<string, boolean>>({});
374
+ const [treeErrors, setTreeErrors] = useState<Record<string, unknown>>({});
375
+ const tableWrapRef = useRef<HTMLDivElement>(null);
376
+ useEffect(() => {
377
+ setPageSize(pageSizeProp);
378
+ }, [pageSizeProp]);
379
+ const treeObjectIds = useMemo(() => new WeakMap<object, string>(), []);
380
+ const treeObjectSequence = useRef(0);
381
+ const legacyMigration = useMemo(() => legacyColumns?.length
382
+ ? normalizeGcsaTableColumns(legacyColumns, { page, pageSize })
383
+ : undefined, [legacyColumns, page, pageSize]);
384
+ const effectiveSelectable = legacyMigration?.selectable ?? selectable ?? false;
385
+ const effectiveExpandable = legacyMigration?.expandable ?? expandable ?? false;
386
+ const effectiveFixedSelection = fixedSelection ?? legacyMigration?.fixedSelection ?? false;
387
+ const effectiveSelectionColumnWidth = selectionColumnWidth ?? legacyMigration?.selectionColumnWidth ?? GCSA_TABLE_SELECTION_COLUMN_WIDTH;
388
+ const effectiveExpandColumnWidth = expandColumnWidth ?? legacyMigration?.expandColumnWidth ?? GCSA_TABLE_EXPAND_COLUMN_WIDTH;
389
+ const allColumns = useMemo(() => resolveGcsaTableColumns(legacyMigration?.columns ?? columns ?? []), [legacyMigration, columns]);
390
+ const resolvedColumns = useMemo(() => filterColumnTree(allColumns, columnVisibility), [allColumns, columnVisibility]);
391
+ const leafColumns = useMemo(() => flattenColumns(resolvedColumns), [resolvedColumns]);
392
+ const columnOptions = useMemo(() => flattenColumns(allColumns).filter(column => !metaOf(column).hidden).map(column => ({ id: column.id ?? '', title: typeof column.header === 'string' ? column.header : column.id ?? '', visible: columnVisibility[column.id ?? ''] !== false })), [allColumns, columnVisibility]);
393
+ const treeNodeKey = (row: T, index: number) => {
394
+ const objectRow = row as object;
395
+ const existing = treeObjectIds.get(objectRow);
396
+ if (existing) return existing;
397
+ const key = rowKey ? getRowId(row, index) : `tree-${treeObjectSequence.current++}`;
398
+ treeObjectIds.set(objectRow, key);
399
+ return key;
400
+ };
401
+ const canExpandTreeRow = (row: T, index: number) => {
402
+ const key = treeNodeKey(row, index);
403
+ if (Object.prototype.hasOwnProperty.call(treeChildren, key)) return treeChildren[key].length > 0;
404
+ const children = (row as Record<string, unknown>)[childrenKey as string];
405
+ if (Array.isArray(children) && children.length) return true;
406
+ if (!treeLazy) return false;
407
+ return treeHasChildren ? treeHasChildren(row, index) : (row as Record<string, unknown>)[treeHasChildrenKey as string] === true;
408
+ };
409
+ const tableData = useMemo(() => {
410
+ if (!treeData || !Object.keys(treeChildren).length) return data;
411
+ const merge = (rows: T[]): T[] => rows.map((row, index) => {
412
+ const key = treeNodeKey(row, index);
413
+ const loaded = treeChildren[key];
414
+ const inline = (row as Record<string, unknown>)[childrenKey as string] as T[] | undefined;
415
+ const children = loaded ?? inline;
416
+ if (!children) return row;
417
+ const clone = { ...row, [childrenKey]: merge(children) } as T;
418
+ treeObjectIds.set(clone as object, key);
419
+ return clone;
420
+ });
421
+ return merge(data);
422
+ }, [data, treeChildren, treeData, childrenKey]);
423
+ const getSubRows = (row: T) => treeData ? (((row as Record<string, unknown>)[childrenKey as string] as T[] | undefined) ?? []) : undefined;
424
+ const table = useReactTable({
425
+ data: tableData,
426
+ columns: resolvedColumns,
427
+ state: { pagination: { pageIndex: page - 1, pageSize }, sorting, columnFilters, rowSelection, columnVisibility, expanded: expandedKeys },
428
+ getRowId,
429
+ getSubRows,
430
+ getRowCanExpand: row => treeData ? canExpandTreeRow(row.original, row.index) : false,
431
+ enableRowSelection: row => typeof effectiveSelectable === 'function' ? effectiveSelectable(row.original, row.index) : effectiveSelectable,
432
+ manualPagination: serverSide,
433
+ manualSorting: serverSide,
434
+ manualFiltering: serverSide,
435
+ pageCount: serverSide ? Math.ceil(total / pageSize) : undefined,
436
+ onPaginationChange: updater => { const next = typeof updater === 'function' ? updater({ pageIndex: page - 1, pageSize }) : updater; onPageChange?.(next.pageIndex + 1); },
437
+ onSortingChange: updater => { const next = typeof updater === 'function' ? updater(sorting) : updater; setSorting(next); onSortingChange?.(next); onSortChange?.(getGcsaTableSortChange(next)); },
438
+ onColumnFiltersChange: updater => { const next = typeof updater === 'function' ? updater(columnFilters) : updater; setColumnFilters(next); onFiltersChange?.(filterRecord(next)); },
439
+ onColumnVisibilityChange: updater => { const next = typeof updater === 'function' ? updater(columnVisibility) : updater; setColumnVisibility(next); onColumnVisibilityChange?.(next); },
440
+ onRowSelectionChange: updater => {
441
+ const next = typeof updater === 'function' ? updater(rowSelection) : updater;
442
+ setRowSelection(next);
443
+ onSelectedRowKeysChange?.(Object.keys(next).filter(key => next[key]));
444
+ onSelectionChange?.(selectedRowsForState(next));
445
+ },
446
+ onExpandedChange: updater => {
447
+ const next = typeof updater === 'function' ? updater(expandedKeys) : updater;
448
+ setExpandedKeys(next);
449
+ onExpandedRowKeysChange?.(next === true ? table.getRowModel().flatRows.map(row => row.id) : Object.keys(next).filter(key => next[key]));
450
+ },
451
+ getCoreRowModel: getCoreRowModel(),
452
+ getFilteredRowModel: serverSide ? undefined : getFilteredRowModel(),
453
+ getSortedRowModel: serverSide ? undefined : getSortedRowModel(),
454
+ getPaginationRowModel: serverSide ? undefined : getPaginationRowModel(),
455
+ getExpandedRowModel: treeData ? getExpandedRowModel() : undefined
456
+ });
457
+ useEffect(() => {
458
+ if (controlledSorting) setSorting([...controlledSorting]);
459
+ }, [controlledSorting]);
460
+ useEffect(() => {
461
+ if (defaultExpandAll && !expandedRowKeys) {
462
+ setExpandedKeys(Object.fromEntries(getGcsaTableDefaultExpandedKeys(data, treeData, childrenKey, rowKey).map(key => [key, true])));
463
+ }
464
+ }, [data, treeData, defaultExpandAll, expandedRowKeys, childrenKey, rowKey]);
465
+ useEffect(() => {
466
+ if (controlledFilters) setColumnFilters(toColumnFilters(controlledFilters));
467
+ }, [controlledFilters]);
468
+ useEffect(() => {
469
+ if (selectedRowKeys) setRowSelection(Object.fromEntries(selectedRowKeys.map(key => [key, true])));
470
+ }, [selectedRowKeys]);
471
+ useEffect(() => {
472
+ if (controlledColumnVisibility) setColumnVisibility(controlledColumnVisibility);
473
+ }, [controlledColumnVisibility]);
474
+ useEffect(() => {
475
+ if (controlledColumnWidths) setColumnWidths(controlledColumnWidths);
476
+ }, [controlledColumnWidths]);
477
+ useEffect(() => {
478
+ if (expandedRowKeys) setExpandedKeys(Object.fromEntries(expandedRowKeys.map(key => [key, true])));
479
+ }, [expandedRowKeys]);
480
+ useEffect(() => {
481
+ setCurrentRowKey(controlledCurrentRowKey);
482
+ }, [controlledCurrentRowKey]);
483
+ const selectedCount = table.getSelectedRowModel().rows.length;
484
+ const totalCountText = formatGcsaLocaleMessage(messages.dataTableTotal, { count: total });
485
+ const selectedCountText = formatGcsaLocaleMessage(messages.dataTableSelected, { count: selectedCount });
486
+ const selectableRows = table.getRowModel().rows.filter(row => row.getCanSelect());
487
+ const visibleColumnCount = leafColumns.length + (effectiveSelectable ? 1 : 0) + (effectiveExpandable || treeData ? 1 : 0);
488
+ const fixedControls = Boolean(effectiveSelectable && effectiveFixedSelection);
489
+ const fixedLayout = { expandable: effectiveExpandable || treeData, selectable: Boolean(effectiveSelectable), fixedSelection: effectiveFixedSelection, expandColumnWidth: effectiveExpandColumnWidth, selectionColumnWidth: effectiveSelectionColumnWidth };
490
+ const tableMinWidth = useMemo(
491
+ () => getGcsaTableMinWidth(
492
+ leafColumns.map(column => ({ id: column.id ?? '', ...metaOf(column) })),
493
+ {
494
+ expandable: effectiveExpandable || treeData,
495
+ selectable: Boolean(effectiveSelectable),
496
+ expandColumnWidth: effectiveExpandColumnWidth,
497
+ selectionColumnWidth: effectiveSelectionColumnWidth,
498
+ columnWidths
499
+ }
500
+ ),
501
+ [
502
+ columnWidths,
503
+ effectiveExpandColumnWidth,
504
+ effectiveExpandable,
505
+ effectiveSelectionColumnWidth,
506
+ effectiveSelectable,
507
+ leafColumns,
508
+ treeData
509
+ ]
510
+ );
511
+ const expandColumnStyle: CSSProperties = {
512
+ width: effectiveExpandColumnWidth,
513
+ minWidth: effectiveExpandColumnWidth,
514
+ maxWidth: effectiveExpandColumnWidth,
515
+ ...(fixedControls ? { position: 'sticky', left: 0 } : {})
516
+ };
517
+ const selectionColumnStyle: CSSProperties = {
518
+ width: effectiveSelectionColumnWidth,
519
+ minWidth: effectiveSelectionColumnWidth,
520
+ maxWidth: effectiveSelectionColumnWidth,
521
+ ...(fixedControls ? { position: 'sticky', left: effectiveExpandable || treeData ? effectiveExpandColumnWidth : 0 } : {})
522
+ };
523
+ const filterValue = (id: string) => String(columnFilters.find(filter => filter.id === id)?.value ?? '');
524
+ const updateFilter = (id: string, value: string) => {
525
+ const next = columnFilters.filter(filter => filter.id !== id);
526
+ if (value) next.push({ id, value });
527
+ setColumnFilters(next);
528
+ const filters = filterRecord(next);
529
+ onFiltersChange?.(filters);
530
+ onFilterChange?.(filters);
531
+ };
532
+ const rangeStart = total ? (page - 1) * pageSize + 1 : 0;
533
+ const rangeEnd = Math.min(page * pageSize, total);
534
+ const rangeText = formatGcsaLocaleMessage(messages.dataTableRange, {
535
+ start: rangeStart,
536
+ end: rangeEnd,
537
+ total
538
+ });
539
+ const toggleColumn = (id: string) => {
540
+ const visibleCount = leafColumns.length;
541
+ const next = { ...columnVisibility, [id]: columnVisibility[id] === false };
542
+ if (!next[id] && visibleCount <= 1) return;
543
+ setColumnVisibility(next);
544
+ onColumnVisibilityChange?.(next);
545
+ };
546
+ const startColumnResize = (event: ReactPointerEvent<HTMLSpanElement>, id: string) => {
547
+ const cell = event.currentTarget.parentElement;
548
+ const sourceColumn = leafColumns.find(column => column.id === id) as ColumnDef<T, unknown> | undefined;
549
+ const sourceMeta = sourceColumn ? metaOf(sourceColumn) : {};
550
+ const initialWidth = cell?.getBoundingClientRect().width ?? Number.parseFloat(String(sourceMeta.width ?? '0'));
551
+ const minWidth = Math.max(64, Number.parseFloat(String(sourceMeta.minWidth ?? sourceMeta.width ?? '64')) || 64);
552
+ const startX = event.clientX;
553
+ const move = (moveEvent: PointerEvent) => {
554
+ const next = Math.max(minWidth, Math.round(initialWidth + moveEvent.clientX - startX));
555
+ setColumnWidths(current => ({ ...current, [id]: next }));
556
+ };
557
+ const up = () => {
558
+ setColumnWidths(current => { onColumnWidthsChange?.(current); return current; });
559
+ document.removeEventListener('pointermove', move);
560
+ document.removeEventListener('pointerup', up);
561
+ };
562
+ document.addEventListener('pointermove', move);
563
+ document.addEventListener('pointerup', up, { once: true });
564
+ };
565
+
566
+ const tableRows = table.getRowModel().rows;
567
+ const expandedRowsFor = (expanded: ExpandedState) => collectExpandedRows(tableData, expanded, (row, index, parent) => getRowId(row, index, parent), treeData, childrenKey);
568
+ const summaryValues = summary?.(data);
569
+ const isRowExpanded = (rowIdValue: string) => expandedKeys === true ? true : expandedKeys[rowIdValue] === true;
570
+ const treeLoading = (row: Row<T>) => Boolean(treeLoadingKeys[treeNodeKey(row.original, row.index)]);
571
+ const treeError = (row: Row<T>) => Boolean(treeErrors[treeNodeKey(row.original, row.index)]);
572
+ const applyExpanded = (row: Row<T>, expanded: boolean) => {
573
+ const nextExpanded = { ...(expandedKeys === true ? {} : expandedKeys), [row.id]: expanded };
574
+ setExpandedKeys(nextExpanded);
575
+ onExpandedRowKeysChange?.(Object.keys(nextExpanded).filter(key => nextExpanded[key]));
576
+ onExpandChange?.(row.original, expanded, expandedRowsFor(nextExpanded));
577
+ };
578
+ const toggleExpanded = async (row: Row<T>) => {
579
+ if (treeData && treeLazy && !isRowExpanded(row.id)) {
580
+ const key = treeNodeKey(row.original, row.index);
581
+ if (!Object.prototype.hasOwnProperty.call(treeChildren, key) && loadChildren && canExpandTreeRow(row.original, row.index)) {
582
+ setTreeLoadingKeys(current => ({ ...current, [key]: true }));
583
+ setTreeErrors(current => { const next = { ...current }; delete next[key]; return next; });
584
+ try {
585
+ const children = await loadChildren(row.original, row.index);
586
+ setTreeChildren(current => ({ ...current, [key]: children ?? [] }));
587
+ if (children?.length) {
588
+ applyExpanded(row, true);
589
+ }
590
+ } catch (error) {
591
+ setTreeErrors(current => ({ ...current, [key]: error }));
592
+ onTreeLoadError?.(error, row.original, row.index);
593
+ } finally {
594
+ setTreeLoadingKeys(current => { const next = { ...current }; delete next[key]; return next; });
595
+ }
596
+ } else if (Object.prototype.hasOwnProperty.call(treeChildren, key)) {
597
+ applyExpanded(row, !isRowExpanded(row.id));
598
+ }
599
+ return;
600
+ }
601
+ if (treeData) {
602
+ applyExpanded(row, !isRowExpanded(row.id));
603
+ } else {
604
+ const expanded = !isRowExpanded(row.id);
605
+ applyExpanded(row, expanded);
606
+ }
607
+ };
608
+ const tableClassName = ['gcsa-table', resolvedSize === 'sm' ? 'gcsa-table--sm' : undefined, stripe ? 'gcsa-table--striped' : undefined, bordered ? 'gcsa-table--bordered' : undefined].filter(Boolean).join(' ');
609
+ const getRowClassName = (row: T, index: number) => typeof rowClassName === 'function' ? rowClassName(row, index) : rowClassName;
610
+ const getColumnInfo = (id: string): GcsaTableColumnInfo => {
611
+ const column = leafColumns.find(candidate => candidate.id === id);
612
+ const meta = column ? metaOf(column) : {};
613
+ return { id, prop: id, label: typeof column?.header === 'string' ? column.header : id, width: meta.width, minWidth: meta.minWidth, fixed: meta.fixed };
614
+ };
615
+ const selectCurrentRow = (row: T, index: number) => {
616
+ if (!highlightCurrentRow) return;
617
+ const key = getRowId(row, index);
618
+ setCurrentRowKey(key);
619
+ onCurrentRowKeyChange?.(key);
620
+ };
621
+ const emitSelection = (next: Record<string, boolean>) => {
622
+ setRowSelection(next);
623
+ const keys = Object.keys(next).filter(key => next[key]);
624
+ onSelectedRowKeysChange?.(keys);
625
+ onSelectionChange?.(selectedRowsForState(next));
626
+ };
627
+ const clearSorting = () => { setSorting([]); onSortingChange?.([]); onSortChange?.(getGcsaTableSortChange([])); };
628
+ const clearFilters = () => { setColumnFilters([]); onFiltersChange?.({}); onFilterChange?.({}); };
629
+ const clearFilter = (columnKeys?: string | string[]) => {
630
+ if (columnKeys === undefined) {
631
+ clearFilters();
632
+ return;
633
+ }
634
+ const keys = new Set(Array.isArray(columnKeys) ? columnKeys : [columnKeys]);
635
+ const next = columnFilters.filter(filter => !keys.has(filter.id));
636
+ setColumnFilters(next);
637
+ const filters = filterRecord(next);
638
+ onFiltersChange?.(filters);
639
+ onFilterChange?.(filters);
640
+ };
641
+ const sort = (prop: string, order: 'ascending' | 'descending' | null) => {
642
+ const next = getGcsaTableSorting(prop, order);
643
+ setSorting(next);
644
+ onSortingChange?.(next);
645
+ onSortChange?.(getGcsaTableSortChange(next));
646
+ };
647
+ const clearSelection = () => emitSelection({});
648
+ const clearExpanded = () => { setExpandedKeys({}); onExpandedRowKeysChange?.([]); };
649
+ const setRowSelected = (key: string, selected = true) => {
650
+ const row = table.getCoreRowModel().flatRows.find(candidate => candidate.id === key);
651
+ if (!row || !row.getCanSelect()) return;
652
+ emitSelection({ ...rowSelection, [key]: selected });
653
+ };
654
+ const toggleRowSelection = (row: T, selected?: boolean) => {
655
+ const tableRow = findTableRow(row);
656
+ if (!tableRow || !tableRow.getCanSelect()) return;
657
+ setRowSelected(tableRow.id, selected ?? !tableRow.getIsSelected());
658
+ };
659
+ const rowsForSelection = (selection: Record<string, boolean>) => table.getCoreRowModel().flatRows
660
+ .filter(row => selection[row.id] && row.getCanSelect())
661
+ .map(row => row.original);
662
+ const selectedRowsForState = rowsForSelection;
663
+ const toggleRowSelectionValue = (row: Row<T>, selected: boolean) => {
664
+ const next = { ...rowSelection, [row.id]: selected };
665
+ row.toggleSelected(selected);
666
+ onSelect?.(rowsForSelection(next), row.original);
667
+ };
668
+ const toggleAllSelection = (checked?: boolean) => {
669
+ const allSelected = selectableRows.length > 0 && selectableRows.every(row => row.getIsSelected());
670
+ const nextChecked = checked ?? !allSelected;
671
+ table.toggleAllPageRowsSelected(nextChecked);
672
+ const next = { ...rowSelection };
673
+ selectableRows.forEach(row => { next[row.id] = nextChecked; });
674
+ onSelectAll?.(rowsForSelection(next));
675
+ };
676
+ const setRowExpanded = async (key: string, expanded = true) => {
677
+ const row = table.getCoreRowModel().flatRows.find(candidate => candidate.id === key);
678
+ if (!row) return;
679
+ if (treeData) {
680
+ if (isRowExpanded(key) === expanded) return;
681
+ if (expanded) await toggleExpanded(row);
682
+ else applyExpanded(row, false);
683
+ return;
684
+ }
685
+ const next = { ...(expandedKeys === true ? {} : expandedKeys), [key]: expanded };
686
+ setExpandedKeys(next);
687
+ onExpandedRowKeysChange?.(Object.keys(next).filter(value => next[value]));
688
+ };
689
+ const toggleRowExpansion = async (row: T, expanded?: boolean) => {
690
+ const tableRow = findTableRow(row);
691
+ if (!tableRow) return;
692
+ await setRowExpanded(tableRow.id, expanded ?? !isRowExpanded(tableRow.id));
693
+ };
694
+ const setCurrentRow = (row?: T) => {
695
+ const tableRow = row ? findTableRow(row) : undefined;
696
+ setCurrentRowKey(tableRow?.id);
697
+ onCurrentRowKeyChange?.(tableRow?.id);
698
+ };
699
+ const findTableRow = (row: T) => {
700
+ const rows = table.getCoreRowModel().flatRows;
701
+ const byReference = rows.find(candidate => candidate.original === row);
702
+ if (byReference) return byReference;
703
+ if (rowKey) {
704
+ const key = getRowId(row, 0);
705
+ return rows.find(candidate => candidate.id === key);
706
+ }
707
+ return undefined;
708
+ };
709
+ const getSelectionRows = () => table.getCoreRowModel().flatRows.filter(row => row.getIsSelected()).map(row => row.original);
710
+ const setScrollTop = (top: number) => tableWrapRef.current?.scrollTo({ top });
711
+ const scrollTo = (options: ScrollToOptions | number, y?: number) => {
712
+ if (typeof options === 'number') tableWrapRef.current?.scrollTo(options, y ?? 0);
713
+ else tableWrapRef.current?.scrollTo(options);
714
+ };
715
+ if (apiRef) {
716
+ apiRef.current = {
717
+ clearSorting,
718
+ clearFilters,
719
+ clearSelection,
720
+ clearExpanded,
721
+ setRowSelected,
722
+ setRowExpanded,
723
+ clearSort: clearSorting,
724
+ clearFilter,
725
+ sort,
726
+ toggleRowSelection,
727
+ toggleAllSelection,
728
+ toggleRowExpansion,
729
+ setCurrentRow,
730
+ getSelectionRows,
731
+ setScrollTop,
732
+ scrollTo
733
+ };
734
+ }
735
+ return <div className={`gcsa-data-table${mobileMode === 'cards' ? ' gcsa-data-table--cards' : ''}`}>
736
+ {showToolbar && (toolbar || columnSelector) ? <div className="gcsa-data-table__toolbar"><div className="gcsa-data-table__toolbar-meta">{showCount && !loading ? <span className="gcsa-data-table__count">{totalCountText}</span> : null}{selectedCount ? <span className="gcsa-data-table__selected">{selectedCountText}</span> : null}</div><div className="gcsa-data-table__toolbar-actions">{toolbar}{columnSelector ? <div className="gcsa-data-table__columns-control">{columnSelector(columnOptions, toggleColumn)}</div> : null}</div></div> : null}
737
+ <div ref={tableWrapRef} className="gcsa-table-wrap gcsa-ui-surface" style={{ height: height === undefined ? undefined : typeof height === 'number' ? `${height}px` : height, maxHeight: maxHeight === undefined ? undefined : typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight }}>
738
+ {loading ? <TableLoadingState label={messages.dataTableLoading} /> : null}
739
+ {error ? <div className="gcsa-data-table__state gcsa-data-table__state--error" role="alert"><span>{error}</span><button type="button" className="gcsa-btn gcsa-btn--sm gcsa-btn--secondary" onClick={onRetry}>{resolvedRetryLabel}</button></div> : null}
740
+ {!loading && !error ? <table className={tableClassName} style={{ minWidth: tableMinWidth }}>
741
+ <thead className="gcsa-table__head">
742
+ {table.getHeaderGroups().map((headerGroup, groupIndex) => <tr key={headerGroup.id}>
743
+ {groupIndex === 0 && (effectiveExpandable || treeData) ? <th className="gcsa-table__col-expand" style={expandColumnStyle} rowSpan={table.getHeaderGroups().length} /> : null}
744
+ {groupIndex === 0 && effectiveSelectable ? <th className="gcsa-table__col-check" style={selectionColumnStyle} rowSpan={table.getHeaderGroups().length}><GcsaCheckbox checked={selectableRows.length > 0 && selectableRows.every(row => row.getIsSelected())} disabled={!selectableRows.length} label="" ariaLabel={messages.dataTableSelectAll} onCheckedChange={checked => toggleAllSelection(checked)} /></th> : null}
745
+ {headerGroup.headers.map(header => {
746
+ const meta = metaOf(header.column.columnDef);
747
+ const isLeaf = !header.column.columns.length;
748
+ return <th key={header.id} colSpan={header.colSpan} rowSpan={header.rowSpan > 1 ? header.rowSpan : undefined} style={fixedStyle(leafColumns, header.column.id, meta, columnWidths, fixedLayout)} className={meta.align === 'center' ? 'gcsa-table__align-center' : meta.align === 'right' ? 'gcsa-table__align-right' : undefined} onClick={event => onHeaderClick?.(getColumnInfo(header.column.id), event)}>
749
+ {header.isPlaceholder ? null : isLeaf && header.column.getCanSort() ? <button type="button" className={`gcsa-table__sort${header.column.getIsSorted() ? ' gcsa-table__sort--active' : ''}`} onClick={header.column.getToggleSortingHandler()}><span className="gcsa-table__sort-label">{flexRender(header.column.columnDef.header, header.getContext())}</span><span className="gcsa-table__sort-icon" aria-hidden="true"><GcsaIcon name="chevronUp" size="sm" /><GcsaIcon name="chevronDown" size="sm" /></span></button> : isLeaf ? <span className="gcsa-table__head-text">{flexRender(header.column.columnDef.header, header.getContext())}</span> : <span className="gcsa-table__head-text">{flexRender(header.column.columnDef.header, header.getContext())}</span>}
750
+ {isLeaf && meta.filter ? <div className="gcsa-table__filter">{meta.filter.type === 'text' ? <GcsaInput value={filterValue(header.column.id)} placeholder={meta.filter.placeholder ?? messages.dataTableFilter} onValueChange={value => updateFilter(header.column.id, value)} /> : <GcsaSelect value={filterValue(header.column.id)} options={meta.filter.options ?? []} placeholder={meta.filter.placeholder ?? messages.dataTableFilter} onValueChange={value => updateFilter(header.column.id, value)} />}</div> : null}
751
+ {resizable && isLeaf ? <span className="gcsa-table__resize-handle" role="separator" aria-label={messages.dataTableResizeColumn} onPointerDown={event => { event.stopPropagation(); event.preventDefault(); startColumnResize(event, header.column.id); }} /> : null}
752
+ </th>;
753
+ })}
754
+ </tr>)}
755
+ </thead>
756
+ <tbody className="gcsa-table__body">
757
+ {table.getRowModel().rows.map(row => { const rowExpanded = isRowExpanded(row.id); return <Fragment key={row.id}>
758
+ <tr key={row.id} className={`gcsa-table__row${row.index % 2 === 1 ? ' gcsa-table__row--striped' : ''}${getRowClassName(row.original, row.index) ? ` ${getRowClassName(row.original, row.index)}` : ''}`} data-selected={row.getIsSelected() || undefined} data-current={highlightCurrentRow && currentRowKey === getRowId(row.original, row.index) ? true : undefined} onClick={event => { const previous = highlightCurrentRow ? table.getCoreRowModel().flatRows.find(candidate => candidate.id === currentRowKey)?.original : undefined; selectCurrentRow(row.original, row.index); if (highlightCurrentRow) onCurrentChange?.(row.original, previous); onRowClick?.(row.original, row.index, event); onLegacyRowClick?.(row.original, getColumnInfo(row.getVisibleCells()[0]?.column.id ?? ''), event); }} onDoubleClick={event => onRowDoubleClick?.(row.original, row.index, event)} onContextMenu={event => { event.preventDefault(); onRowContextMenu?.(row.original, row.index, event); onLegacyRowContextMenu?.(row.original, getColumnInfo(row.getVisibleCells()[0]?.column.id ?? ''), event); }}>
759
+ {effectiveExpandable || treeData ? <td className="gcsa-table__col-expand" style={expandColumnStyle} onClick={event => event.stopPropagation()}>{(!treeData || row.getCanExpand()) ? <><button type="button" className="gcsa-table__expand gcsa-focus-ring" disabled={treeLoading(row)} aria-label={treeLoading(row) ? messages.dataTableLoadChildren : treeError(row) ? messages.dataTableRetryChildren : rowExpanded ? messages.dataTableCollapseRow : messages.dataTableExpandRow} aria-expanded={rowExpanded} onClick={() => toggleExpanded(row)}><GcsaIcon name="chevronDown" size="sm" className={rowExpanded ? 'gcsa-table__expand-icon--open' : undefined} /></button>{treeLoading(row) ? <span className="gcsa-table__tree-state" role="status">{resolvedTreeLoadingText}</span> : treeError(row) ? <button type="button" className="gcsa-table__tree-retry" onClick={() => toggleExpanded(row)}>{resolvedTreeLoadErrorText}</button> : null}</> : null}</td> : null}
760
+ {effectiveSelectable ? <td className="gcsa-table__col-check" onClick={event => event.stopPropagation()} style={selectionColumnStyle}><GcsaCheckbox checked={row.getIsSelected()} disabled={!row.getCanSelect()} label="" ariaLabel={messages.dataTableSelectRow} onCheckedChange={checked => toggleRowSelectionValue(row, checked)} /></td> : null}
761
+ {row.getVisibleCells().map((cell, cellIndex) => { const cellMeta = metaOf(cell.column.columnDef); const cellValue = cell.getValue(); return <td key={cell.id} data-label={typeof cell.column.columnDef.header === 'string' ? cell.column.columnDef.header : cell.column.id} title={cellMeta.showOverflowTooltip ? formatGcsaTableCellValue(cellValue) : undefined} className={`${cellMeta.align === 'center' ? 'gcsa-table__align-center' : cellMeta.align === 'right' ? 'gcsa-table__align-right' : ''}${cellMeta.showOverflowTooltip ? ' gcsa-table__cell--overflow' : ''}`} style={fixedStyle(leafColumns, cell.column.id, cellMeta, columnWidths, fixedLayout)} onClick={event => { event.stopPropagation(); selectCurrentRow(row.original, row.index); onCellClick?.(row.original, cell.column.id, cellValue, row.index, event); onLegacyCellClick?.(row.original, getColumnInfo(cell.column.id), event.currentTarget, event); }} onDoubleClick={event => { event.stopPropagation(); onCellDoubleClick?.(row.original, cell.column.id, cellValue, row.index, event); }} onContextMenu={event => { event.stopPropagation(); event.preventDefault(); onCellContextMenu?.(row.original, cell.column.id, cellValue, row.index, event); onLegacyCellContextMenu?.(row.original, getColumnInfo(cell.column.id), event.currentTarget, event); }}><div className="gcsa-table__cell" style={treeData && cellIndex === 0 ? { paddingInlineStart: `${row.depth * 18}px` } : undefined}>{cell.column.columnDef.cell ? flexRender(cell.column.columnDef.cell, cell.getContext()) : formatGcsaTableCellValue(cellValue)}</div></td>; })}
762
+ </tr>
763
+ {!treeData && rowExpanded && renderExpandedRow ? <tr key={`${row.id}-expanded`} className="gcsa-table__expanded-row"><td colSpan={visibleColumnCount}>{renderExpandedRow(row.original, row.index)}</td></tr> : null}
764
+ </Fragment>; })}
765
+ </tbody>
766
+ {summaryValues ? <tfoot className="gcsa-table__foot"><tr className="gcsa-table__summary-row">
767
+ {effectiveExpandable || treeData ? <th className="gcsa-table__col-expand" scope="row" style={expandColumnStyle} /> : null}
768
+ {effectiveSelectable ? <th className="gcsa-table__col-check" scope="row" style={selectionColumnStyle} /> : null}
769
+ {leafColumns.map((column, summaryIndex) => {
770
+ const columnMeta = metaOf(column);
771
+ return <td key={column.id} className={columnMeta.align === 'center' ? 'gcsa-table__align-center' : columnMeta.align === 'right' ? 'gcsa-table__align-right' : undefined} style={fixedStyle(leafColumns, column.id ?? '', columnMeta, columnWidths, fixedLayout)}>{summaryValues[column.id ?? ''] ?? (summaryIndex === 0 ? resolvedSummaryLabel : '')}</td>;
772
+ })}
773
+ </tr></tfoot> : null}
774
+ </table> : null}
775
+ {!loading && !error && tableRows.length === 0 ? <div className="gcsa-data-table__empty"><GcsaEmpty title={messages.dataTableEmpty} /></div> : null}
776
+ </div>
777
+ {pagination && total > 0 && !loading && !error ? <div className="gcsa-data-table__footer">{showTotal ? <div className="gcsa-data-table__footer-meta">{rangeText}</div> : null}<GcsaPagination page={page} total={total} pageSize={pageSize} pageSizeOptions={pageSizeOptions} showPageSize={showPageSize} showJumper={showJumper} pageSizeLabel={resolvedPageSizeLabel} jumperLabel={resolvedJumperLabel} layout={paginationLayout} align={paginationAlign} onPageChange={onPageChange} onPageSizeChange={next => { setPageSize(next); onPageSizeChange?.(next); }} /></div> : null}
778
+ </div>;
779
+ }