@superad/ui 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (343) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +42 -0
  3. package/es/Button/Button.d.mts +7 -0
  4. package/es/Button/Button.mjs +29 -0
  5. package/es/Button/Button.mjs.map +1 -0
  6. package/es/Button/index.d.mts +3 -0
  7. package/es/Button/index.d.ts +1 -0
  8. package/es/Button/index.js +1 -0
  9. package/es/Button/index.mjs +2 -0
  10. package/es/Button/style.mjs +33 -0
  11. package/es/Button/style.mjs.map +1 -0
  12. package/es/Button/type.d.mts +21 -0
  13. package/es/ConfigProvider/index.d.mts +9 -0
  14. package/es/ConfigProvider/index.d.ts +1 -0
  15. package/es/ConfigProvider/index.js +1 -0
  16. package/es/ConfigProvider/index.mjs +82 -0
  17. package/es/ConfigProvider/index.mjs.map +1 -0
  18. package/es/ConfigProvider/type.d.mts +24 -0
  19. package/es/DraggablePanel/DraggablePanel.d.mts +6 -0
  20. package/es/DraggablePanel/DraggablePanel.mjs +104 -0
  21. package/es/DraggablePanel/DraggablePanel.mjs.map +1 -0
  22. package/es/DraggablePanel/index.d.mts +3 -0
  23. package/es/DraggablePanel/index.d.ts +1 -0
  24. package/es/DraggablePanel/index.js +1 -0
  25. package/es/DraggablePanel/index.mjs +3 -0
  26. package/es/DraggablePanel/style.mjs +86 -0
  27. package/es/DraggablePanel/style.mjs.map +1 -0
  28. package/es/DraggablePanel/type.d.mts +27 -0
  29. package/es/Flex/Center.d.mts +7 -0
  30. package/es/Flex/Center.mjs +14 -0
  31. package/es/Flex/Center.mjs.map +1 -0
  32. package/es/Flex/FlexBasic.d.mts +6 -0
  33. package/es/Flex/FlexBasic.mjs +46 -0
  34. package/es/Flex/FlexBasic.mjs.map +1 -0
  35. package/es/Flex/Flexbox.d.mts +2 -0
  36. package/es/Flex/index.d.mts +5 -0
  37. package/es/Flex/index.d.ts +1 -0
  38. package/es/Flex/index.js +1 -0
  39. package/es/Flex/index.mjs +3 -0
  40. package/es/Flex/type.d.mts +35 -0
  41. package/es/Flex/utils.mjs +24 -0
  42. package/es/Flex/utils.mjs.map +1 -0
  43. package/es/FontLoader/index.d.mts +9 -0
  44. package/es/FontLoader/index.d.ts +1 -0
  45. package/es/FontLoader/index.js +1 -0
  46. package/es/FontLoader/index.mjs +23 -0
  47. package/es/FontLoader/index.mjs.map +1 -0
  48. package/es/GlobalFocusRing/index.d.mts +6 -0
  49. package/es/GlobalFocusRing/index.d.ts +1 -0
  50. package/es/GlobalFocusRing/index.js +1 -0
  51. package/es/GlobalFocusRing/index.mjs +204 -0
  52. package/es/GlobalFocusRing/index.mjs.map +1 -0
  53. package/es/GlobalFocusRing/style.mjs +35 -0
  54. package/es/GlobalFocusRing/style.mjs.map +1 -0
  55. package/es/Provider.d.mts +5 -0
  56. package/es/Table/canvas/canvasPalette.mjs +11 -0
  57. package/es/Table/canvas/canvasPalette.mjs.map +1 -0
  58. package/es/Table/canvas/chipPainters.mjs +408 -0
  59. package/es/Table/canvas/chipPainters.mjs.map +1 -0
  60. package/es/Table/canvas/controlPainters.mjs +193 -0
  61. package/es/Table/canvas/controlPainters.mjs.map +1 -0
  62. package/es/Table/canvas/groupTitle.mjs +181 -0
  63. package/es/Table/canvas/groupTitle.mjs.map +1 -0
  64. package/es/Table/canvas/paintUtils.mjs +70 -0
  65. package/es/Table/canvas/paintUtils.mjs.map +1 -0
  66. package/es/Table/canvas/rowSeries.mjs +130 -0
  67. package/es/Table/canvas/rowSeries.mjs.map +1 -0
  68. package/es/Table/canvas/textPainters.mjs +97 -0
  69. package/es/Table/canvas/textPainters.mjs.map +1 -0
  70. package/es/Table/canvas/theme.d.mts +14 -0
  71. package/es/Table/canvas/theme.mjs +276 -0
  72. package/es/Table/canvas/theme.mjs.map +1 -0
  73. package/es/Table/core/cellValue.d.mts +1 -0
  74. package/es/Table/core/cellValue.mjs +240 -0
  75. package/es/Table/core/cellValue.mjs.map +1 -0
  76. package/es/Table/core/rowSelection.mjs +138 -0
  77. package/es/Table/core/rowSelection.mjs.map +1 -0
  78. package/es/Table/core/size.mjs +60 -0
  79. package/es/Table/core/size.mjs.map +1 -0
  80. package/es/Table/core/tableI18n.d.mts +11 -0
  81. package/es/Table/core/tableI18n.mjs +123 -0
  82. package/es/Table/core/tableI18n.mjs.map +1 -0
  83. package/es/Table/core/tagTone.mjs +245 -0
  84. package/es/Table/core/tagTone.mjs.map +1 -0
  85. package/es/Table/core/zIndex.mjs +7 -0
  86. package/es/Table/core/zIndex.mjs.map +1 -0
  87. package/es/Table/index.d.mts +6 -0
  88. package/es/Table/index.d.ts +1 -0
  89. package/es/Table/index.js +1 -0
  90. package/es/Table/index.mjs +6 -0
  91. package/es/Table/react/Table.d.mts +9 -0
  92. package/es/Table/react/Table.mjs +407 -0
  93. package/es/Table/react/Table.mjs.map +1 -0
  94. package/es/Table/react/TableColumnSettings.mjs +65 -0
  95. package/es/Table/react/TableColumnSettings.mjs.map +1 -0
  96. package/es/Table/react/a11y.mjs +72 -0
  97. package/es/Table/react/a11y.mjs.map +1 -0
  98. package/es/Table/react/editors/base.mjs +427 -0
  99. package/es/Table/react/editors/base.mjs.map +1 -0
  100. package/es/Table/react/editors/inline.mjs +225 -0
  101. package/es/Table/react/editors/inline.mjs.map +1 -0
  102. package/es/Table/react/editors/picker.mjs +368 -0
  103. package/es/Table/react/editors/picker.mjs.map +1 -0
  104. package/es/Table/react/overlayChips.mjs +50 -0
  105. package/es/Table/react/overlayChips.mjs.map +1 -0
  106. package/es/Table/react/sameRenderInputs.mjs +50 -0
  107. package/es/Table/react/sameRenderInputs.mjs.map +1 -0
  108. package/es/Table/react/style.mjs +650 -0
  109. package/es/Table/react/style.mjs.map +1 -0
  110. package/es/Table/react/useTableCellEvents.mjs +32 -0
  111. package/es/Table/react/useTableCellEvents.mjs.map +1 -0
  112. package/es/Table/react/useTableColumnSettings.mjs +107 -0
  113. package/es/Table/react/useTableColumnSettings.mjs.map +1 -0
  114. package/es/Table/react/useTableEditorSync.mjs +41 -0
  115. package/es/Table/react/useTableEditorSync.mjs.map +1 -0
  116. package/es/Table/react/useTableHoverHint.mjs +62 -0
  117. package/es/Table/react/useTableHoverHint.mjs.map +1 -0
  118. package/es/Table/react/useTableKeyboard.mjs +41 -0
  119. package/es/Table/react/useTableKeyboard.mjs.map +1 -0
  120. package/es/Table/react/useTableRenderState.mjs +194 -0
  121. package/es/Table/react/useTableRenderState.mjs.map +1 -0
  122. package/es/Table/react/useTableScroll.mjs +33 -0
  123. package/es/Table/react/useTableScroll.mjs.map +1 -0
  124. package/es/Table/react/useTableSelectionInfo.mjs +48 -0
  125. package/es/Table/react/useTableSelectionInfo.mjs.map +1 -0
  126. package/es/Table/react/useTableVTableEvents.mjs +132 -0
  127. package/es/Table/react/useTableVTableEvents.mjs.map +1 -0
  128. package/es/Table/type.d.mts +279 -0
  129. package/es/Table/type.mjs +34 -0
  130. package/es/Table/type.mjs.map +1 -0
  131. package/es/Table/vtable/columns.d.mts +17 -0
  132. package/es/Table/vtable/columns.mjs +381 -0
  133. package/es/Table/vtable/columns.mjs.map +1 -0
  134. package/es/Table/vtable/frozenShadow.mjs +27 -0
  135. package/es/Table/vtable/frozenShadow.mjs.map +1 -0
  136. package/es/Table/vtable/interaction.mjs +175 -0
  137. package/es/Table/vtable/interaction.mjs.map +1 -0
  138. package/es/Table/vtable/option.d.mts +39 -0
  139. package/es/Table/vtable/option.mjs +232 -0
  140. package/es/Table/vtable/option.mjs.map +1 -0
  141. package/es/Table/vtable/seriesSelection.mjs +374 -0
  142. package/es/Table/vtable/seriesSelection.mjs.map +1 -0
  143. package/es/Table/vtable/vtableAdapter.mjs +96 -0
  144. package/es/Table/vtable/vtableAdapter.mjs.map +1 -0
  145. package/es/ThemeProvider/AppElementContext.d.mts +5 -0
  146. package/es/ThemeProvider/AppElementContext.mjs +10 -0
  147. package/es/ThemeProvider/AppElementContext.mjs.map +1 -0
  148. package/es/ThemeProvider/ConfigProvider.mjs +29 -0
  149. package/es/ThemeProvider/ConfigProvider.mjs.map +1 -0
  150. package/es/ThemeProvider/GlobalStyle/antdOverride.mjs +73 -0
  151. package/es/ThemeProvider/GlobalStyle/antdOverride.mjs.map +1 -0
  152. package/es/ThemeProvider/GlobalStyle/essential.mjs +50 -0
  153. package/es/ThemeProvider/GlobalStyle/essential.mjs.map +1 -0
  154. package/es/ThemeProvider/GlobalStyle/global.mjs +90 -0
  155. package/es/ThemeProvider/GlobalStyle/global.mjs.map +1 -0
  156. package/es/ThemeProvider/GlobalStyle/index.mjs +14 -0
  157. package/es/ThemeProvider/GlobalStyle/index.mjs.map +1 -0
  158. package/es/ThemeProvider/Meta.d.mts +7 -0
  159. package/es/ThemeProvider/Meta.mjs +48 -0
  160. package/es/ThemeProvider/Meta.mjs.map +1 -0
  161. package/es/ThemeProvider/ThemeProvider.d.mts +6 -0
  162. package/es/ThemeProvider/ThemeProvider.mjs +89 -0
  163. package/es/ThemeProvider/ThemeProvider.mjs.map +1 -0
  164. package/es/ThemeProvider/constants.d.mts +5 -0
  165. package/es/ThemeProvider/constants.mjs +6 -0
  166. package/es/ThemeProvider/constants.mjs.map +1 -0
  167. package/es/ThemeProvider/index.d.mts +6 -0
  168. package/es/ThemeProvider/index.d.ts +1 -0
  169. package/es/ThemeProvider/index.js +1 -0
  170. package/es/ThemeProvider/index.mjs +5 -0
  171. package/es/ThemeProvider/type.d.mts +48 -0
  172. package/es/_virtual/_rolldown/runtime.mjs +13 -0
  173. package/es/color/colors/blue.d.mts +6 -0
  174. package/es/color/colors/blue.mjs +67 -0
  175. package/es/color/colors/blue.mjs.map +1 -0
  176. package/es/color/colors/cyan.d.mts +6 -0
  177. package/es/color/colors/cyan.mjs +67 -0
  178. package/es/color/colors/cyan.mjs.map +1 -0
  179. package/es/color/colors/geekblue.d.mts +6 -0
  180. package/es/color/colors/geekblue.mjs +67 -0
  181. package/es/color/colors/geekblue.mjs.map +1 -0
  182. package/es/color/colors/gold.d.mts +6 -0
  183. package/es/color/colors/gold.mjs +67 -0
  184. package/es/color/colors/gold.mjs.map +1 -0
  185. package/es/color/colors/gray.d.mts +6 -0
  186. package/es/color/colors/gray.mjs +67 -0
  187. package/es/color/colors/gray.mjs.map +1 -0
  188. package/es/color/colors/green.d.mts +6 -0
  189. package/es/color/colors/green.mjs +67 -0
  190. package/es/color/colors/green.mjs.map +1 -0
  191. package/es/color/colors/index.d.mts +22 -0
  192. package/es/color/colors/index.mjs +35 -0
  193. package/es/color/colors/index.mjs.map +1 -0
  194. package/es/color/colors/lime.d.mts +6 -0
  195. package/es/color/colors/lime.mjs +67 -0
  196. package/es/color/colors/lime.mjs.map +1 -0
  197. package/es/color/colors/magenta.d.mts +6 -0
  198. package/es/color/colors/magenta.mjs +67 -0
  199. package/es/color/colors/magenta.mjs.map +1 -0
  200. package/es/color/colors/orange.d.mts +6 -0
  201. package/es/color/colors/orange.mjs +67 -0
  202. package/es/color/colors/orange.mjs.map +1 -0
  203. package/es/color/colors/primary.d.mts +6 -0
  204. package/es/color/colors/primary.mjs +67 -0
  205. package/es/color/colors/primary.mjs.map +1 -0
  206. package/es/color/colors/purple.d.mts +6 -0
  207. package/es/color/colors/purple.mjs +67 -0
  208. package/es/color/colors/purple.mjs.map +1 -0
  209. package/es/color/colors/red.d.mts +6 -0
  210. package/es/color/colors/red.mjs +67 -0
  211. package/es/color/colors/red.mjs.map +1 -0
  212. package/es/color/colors/volcano.d.mts +6 -0
  213. package/es/color/colors/volcano.mjs +67 -0
  214. package/es/color/colors/volcano.mjs.map +1 -0
  215. package/es/color/colors/yellow.d.mts +6 -0
  216. package/es/color/colors/yellow.mjs +67 -0
  217. package/es/color/colors/yellow.mjs.map +1 -0
  218. package/es/color/index.d.mts +23 -0
  219. package/es/color/index.d.ts +1 -0
  220. package/es/color/index.js +1 -0
  221. package/es/color/index.mjs +22 -0
  222. package/es/color/neutrals/index.d.mts +13 -0
  223. package/es/color/neutrals/index.mjs +17 -0
  224. package/es/color/neutrals/index.mjs.map +1 -0
  225. package/es/color/neutrals/mauve.d.mts +6 -0
  226. package/es/color/neutrals/mauve.mjs +67 -0
  227. package/es/color/neutrals/mauve.mjs.map +1 -0
  228. package/es/color/neutrals/olive.d.mts +6 -0
  229. package/es/color/neutrals/olive.mjs +67 -0
  230. package/es/color/neutrals/olive.mjs.map +1 -0
  231. package/es/color/neutrals/sage.d.mts +6 -0
  232. package/es/color/neutrals/sage.mjs +67 -0
  233. package/es/color/neutrals/sage.mjs.map +1 -0
  234. package/es/color/neutrals/sand.d.mts +6 -0
  235. package/es/color/neutrals/sand.mjs +67 -0
  236. package/es/color/neutrals/sand.mjs.map +1 -0
  237. package/es/color/neutrals/slate.d.mts +6 -0
  238. package/es/color/neutrals/slate.mjs +67 -0
  239. package/es/color/neutrals/slate.mjs.map +1 -0
  240. package/es/color/types.d.mts +16 -0
  241. package/es/eslint/index.d.mts +26 -0
  242. package/es/eslint/index.d.ts +1 -0
  243. package/es/eslint/index.js +1 -0
  244. package/es/eslint/index.mjs +11 -0
  245. package/es/eslint/index.mjs.map +1 -0
  246. package/es/hooks/useIsClient.d.mts +8 -0
  247. package/es/hooks/useIsClient.mjs +13 -0
  248. package/es/hooks/useIsClient.mjs.map +1 -0
  249. package/es/i18n/context.d.mts +7 -0
  250. package/es/i18n/context.mjs +16 -0
  251. package/es/i18n/context.mjs.map +1 -0
  252. package/es/i18n/index.d.mts +6 -0
  253. package/es/i18n/index.d.ts +1 -0
  254. package/es/i18n/index.js +1 -0
  255. package/es/i18n/index.mjs +5 -0
  256. package/es/i18n/resources/en/common.d.mts +35 -0
  257. package/es/i18n/resources/en/common.mjs +36 -0
  258. package/es/i18n/resources/en/common.mjs.map +1 -0
  259. package/es/i18n/resources/en/index.d.mts +7 -0
  260. package/es/i18n/resources/en/index.mjs +8 -0
  261. package/es/i18n/resources/en/index.mjs.map +1 -0
  262. package/es/i18n/resources/zhCn/common.d.mts +35 -0
  263. package/es/i18n/resources/zhCn/common.mjs +36 -0
  264. package/es/i18n/resources/zhCn/common.mjs.map +1 -0
  265. package/es/i18n/resources/zhCn/index.d.mts +7 -0
  266. package/es/i18n/resources/zhCn/index.mjs +8 -0
  267. package/es/i18n/resources/zhCn/index.mjs.map +1 -0
  268. package/es/i18n/types.d.mts +22 -0
  269. package/es/i18n/useTranslation.d.mts +12 -0
  270. package/es/i18n/useTranslation.mjs +22 -0
  271. package/es/i18n/useTranslation.mjs.map +1 -0
  272. package/es/index.d.mts +43 -0
  273. package/es/index.mjs +26 -0
  274. package/es/storybook/StoryBook/StoryBook.d.mts +7 -0
  275. package/es/storybook/StoryBook/StoryBook.mjs +52 -0
  276. package/es/storybook/StoryBook/StoryBook.mjs.map +1 -0
  277. package/es/storybook/StoryBook/index.d.mts +3 -0
  278. package/es/storybook/StoryBook/style.mjs +97 -0
  279. package/es/storybook/StoryBook/style.mjs.map +1 -0
  280. package/es/storybook/StoryBook/type.d.mts +13 -0
  281. package/es/storybook/index.d.mts +4 -0
  282. package/es/storybook/index.d.ts +1 -0
  283. package/es/storybook/index.js +1 -0
  284. package/es/storybook/index.mjs +2 -0
  285. package/es/styles/classNames.d.mts +11 -0
  286. package/es/styles/classNames.mjs +12 -0
  287. package/es/styles/classNames.mjs.map +1 -0
  288. package/es/styles/customTheme.d.mts +36 -0
  289. package/es/styles/customTheme.mjs +71 -0
  290. package/es/styles/customTheme.mjs.map +1 -0
  291. package/es/styles/index.d.mts +6 -0
  292. package/es/styles/index.d.ts +1 -0
  293. package/es/styles/index.js +1 -0
  294. package/es/styles/index.mjs +6 -0
  295. package/es/styles/theme/algorithms/darkAlgorithm.mjs +18 -0
  296. package/es/styles/theme/algorithms/darkAlgorithm.mjs.map +1 -0
  297. package/es/styles/theme/algorithms/lightAlgorithm.mjs +18 -0
  298. package/es/styles/theme/algorithms/lightAlgorithm.mjs.map +1 -0
  299. package/es/styles/theme/algorithms/resolveScales.mjs +25 -0
  300. package/es/styles/theme/algorithms/resolveScales.mjs.map +1 -0
  301. package/es/styles/theme/antdTheme.mjs +31 -0
  302. package/es/styles/theme/antdTheme.mjs.map +1 -0
  303. package/es/styles/theme/customStylish.d.mts +7 -0
  304. package/es/styles/theme/customStylish.mjs +158 -0
  305. package/es/styles/theme/customStylish.mjs.map +1 -0
  306. package/es/styles/theme/customStylishStatic.d.mts +6 -0
  307. package/es/styles/theme/customStylishStatic.mjs +156 -0
  308. package/es/styles/theme/customStylishStatic.mjs.map +1 -0
  309. package/es/styles/theme/customToken.d.mts +7 -0
  310. package/es/styles/theme/customToken.mjs +127 -0
  311. package/es/styles/theme/customToken.mjs.map +1 -0
  312. package/es/styles/theme/generateColorPalette.d.mts +16 -0
  313. package/es/styles/theme/generateColorPalette.mjs +170 -0
  314. package/es/styles/theme/generateColorPalette.mjs.map +1 -0
  315. package/es/styles/theme/token/base.mjs +64 -0
  316. package/es/styles/theme/token/base.mjs.map +1 -0
  317. package/es/styles/theme/token/dark.mjs +37 -0
  318. package/es/styles/theme/token/dark.mjs.map +1 -0
  319. package/es/styles/theme/token/light.mjs +37 -0
  320. package/es/styles/theme/token/light.mjs.map +1 -0
  321. package/es/types/customStylish.d.mts +28 -0
  322. package/es/types/customToken.d.mts +34 -0
  323. package/es/types/customToken.mjs +32 -0
  324. package/es/types/customToken.mjs.map +1 -0
  325. package/es/types/index.d.mts +15 -0
  326. package/es/types/index.d.ts +1 -0
  327. package/es/types/index.js +1 -0
  328. package/es/types/index.mjs +2 -0
  329. package/es/utils/composeEventHandlers.d.mts +5 -0
  330. package/es/utils/composeEventHandlers.mjs +10 -0
  331. package/es/utils/composeEventHandlers.mjs.map +1 -0
  332. package/es/utils/copyToClipboard.d.mts +5 -0
  333. package/es/utils/copyToClipboard.mjs +28 -0
  334. package/es/utils/copyToClipboard.mjs.map +1 -0
  335. package/es/utils/dom.d.mts +15 -0
  336. package/es/utils/dom.mjs +16 -0
  337. package/es/utils/dom.mjs.map +1 -0
  338. package/es/utils/genCdnUrl.d.mts +12 -0
  339. package/es/utils/genCdnUrl.mjs +17 -0
  340. package/es/utils/genCdnUrl.mjs.map +1 -0
  341. package/es/utils/safeReadableColor.mjs +6 -0
  342. package/es/utils/safeReadableColor.mjs.map +1 -0
  343. package/package.json +96 -0
@@ -0,0 +1,374 @@
1
+ import { isGroupTitleRecord } from "../core/cellValue.mjs";
2
+ import { clearCheckboxState, clearSelected, fireTableEvent, getDataSource, getIndexKey, getInternalProps, getLayoutMapRowSeriesField, getRecordIndexByCell, getRecordShowIndexByCell, getRecords, getScenegraph, getStateManager, getVisibleRowRange, selectCells, setCellCheckboxStateByRecordIndex, updateCellContent, updateCellContentRange, updateNextFrame } from "./vtableAdapter.mjs";
3
+ import { createFullRowRange, isFullRowRange, selectAllRows, toggleRowSelection } from "../core/rowSelection.mjs";
4
+ import { TABLE_EVENT_TYPE } from "@visactor/vtable";
5
+ //#region src/Table/vtable/seriesSelection.ts
6
+ const isGroupTitleRow = (table, row) => Boolean(getInternalProps(table)?.groupBy && isGroupTitleRecord(table?.getCellOriginRecord?.(0, row)));
7
+ /**
8
+ * Last body row select-all should cover. Group title rows carry no data — the row series
9
+ * skips them when numbering, the header checkbox route walks past them, and
10
+ * `getCascadeSelectedRowIndexes` leaves them out — so select-all has to agree with all of
11
+ * them. Returns a row below the header when every body row is a group.
12
+ */
13
+ const resolveSelectionEndRow = (table) => {
14
+ const firstRow = table?.columnHeaderLevelCount ?? 1;
15
+ let row = (table?.rowCount ?? 1) - 1;
16
+ while (row >= firstRow && isGroupTitleRow(table, row)) row -= 1;
17
+ return row;
18
+ };
19
+ /**
20
+ * First body row a select-all range may start on. Group title rows carry no data — the row
21
+ * series skips them when numbering and the header checkbox leaves them out — so select-all
22
+ * has to agree with both. Returns a row past the last body row when every one is a group.
23
+ */
24
+ const resolveSelectionStartRow = (table) => {
25
+ const firstRow = table?.columnHeaderLevelCount ?? 1;
26
+ const lastRow = (table?.rowCount ?? 1) - 1;
27
+ let row = firstRow;
28
+ while (row <= lastRow && isGroupTitleRow(table, row)) row += 1;
29
+ return row;
30
+ };
31
+ /** 超过这个行数就不建索引:一份 rowCount 长的数组本身就是内存开销。 */
32
+ const ROW_INDEX_CACHE_LIMIT = 1e5;
33
+ /**
34
+ * 分组表的行号索引缓存。
35
+ *
36
+ * `resolveRowSeriesIndex` 每画一个可见行都要从第一个体行数到它自己,每个 cursor 一次
37
+ * `isGroupTitleRow`(内含 `getCellOriginRecord`)。两万行的分组表滚到中部时,单个可见行就是
38
+ * 两万次记录查询,而一屏几十行、每帧都要重画 —— **序号列自己成了滚动卡顿源**(它只画一个数字)。
39
+ *
40
+ * 索引只跟「表头层数 + 总行数」有关(折叠 / 展开会改变行数),按它们失效,重建一次 O(行数)。
41
+ */
42
+ const rowIndexCaches = /* @__PURE__ */ new WeakMap();
43
+ const resolveGroupedRowIndex = (table, row, firstRow) => {
44
+ const rowCount = table?.rowCount ?? 0;
45
+ if (rowCount > ROW_INDEX_CACHE_LIMIT || rowCount <= firstRow) {
46
+ let index = 0;
47
+ for (let cursor = firstRow; cursor <= row; cursor += 1) if (isGroupTitleRow(table, cursor) === false) index += 1;
48
+ return index;
49
+ }
50
+ let cache = rowIndexCaches.get(table);
51
+ if (cache == null || cache.rowCount !== rowCount || cache.firstRow !== firstRow) {
52
+ const counts = [];
53
+ let index = 0;
54
+ for (let cursor = firstRow; cursor < rowCount; cursor += 1) {
55
+ if (isGroupTitleRow(table, cursor) === false) index += 1;
56
+ counts[cursor] = index;
57
+ }
58
+ cache = {
59
+ counts,
60
+ firstRow,
61
+ rowCount
62
+ };
63
+ rowIndexCaches.set(table, cache);
64
+ }
65
+ return cache.counts[row] ?? 0;
66
+ };
67
+ /** Row number that skips group title rows, so only data records are counted. */
68
+ const resolveRowSeriesIndex = (table, row) => {
69
+ const firstRow = table?.columnHeaderLevelCount ?? 1;
70
+ if (row < firstRow) return 0;
71
+ if (getInternalProps(table)?.groupBy == null) return row - firstRow + 1;
72
+ return resolveGroupedRowIndex(table, row, firstRow);
73
+ };
74
+ /** Display value for a row series cell: group rows show no number. */
75
+ const resolveRowSeriesValue = (table, row) => isGroupTitleRow(table, row) ? "" : resolveRowSeriesIndex(table, row);
76
+ /**
77
+ * VTable 在 `rowSeriesNumber.field` 缺省时用的字段名。**只在读不到解析结果时兜底** ——
78
+ * 它是引擎的默认值,不是我们的契约;使用方覆盖 `field` 后就该以 `layoutMap` 里的为准。
79
+ */
80
+ const FALLBACK_ROW_SERIES_CHECKBOX_FIELD = "_vtable_rowSeries_number";
81
+ /**
82
+ * 行号列复选框状态存在哪个键下。复选框的勾选态、底部「已选 N 行」计数、`selectionActions`
83
+ * 和级联同步全都按这个键读写 `stateManager.checkedState`;读错键就**所有复选框恒为未选中、
84
+ * 点选也不动**,而且不报任何错。
85
+ *
86
+ * 取值必须问 table 自己(见 `getLayoutMapRowSeriesField`):写死默认名会在使用方给
87
+ * `rowSeriesNumber` 传了自定义 `field` 时静默失效。
88
+ */
89
+ const resolveRowSeriesField = (table) => getLayoutMapRowSeriesField(table) ?? FALLBACK_ROW_SERIES_CHECKBOX_FIELD;
90
+ /**
91
+ * 这张表有没有可以直接遍历的 `records`。
92
+ *
93
+ * **不能假设 `table.records` 就是数据。** 使用方传 `dataSource`(VTable 的懒加载形态,
94
+ * 百万行 demo 就是)时,引擎在 `_setDataSource` 里把 `internalProps.records` 置空,react
95
+ * 包装层再补一个 `[]`,取行只剩 `dataSource.get(i)` 一条路。此时所有按 records 遍历的
96
+ * 代码全部**静默**走空:勾选确实写进了 `checkedState`,但「已选 N 行」恒为 0(浮动条根本
97
+ * 不渲染)、表头全选一行都选不中 —— 和另外几张传 `records` 的表行为对不上。
98
+ */
99
+ const hasRecordTree = (table) => Array.isArray(table?.records) && table.records.length > 0;
100
+ /** 可被选中的数据行数。数据源表上分组标题行不存在(分组表一律按 records 走)。 */
101
+ const sourceRowTotal = (table) => Math.max(0, (table?.rowCount ?? 0) - (table?.columnHeaderLevelCount ?? 0));
102
+ /**
103
+ * 数据源表的全选标记。
104
+ *
105
+ * **不能靠往 `checkedState` 里灌满所有行来全选**:百万行实测要 1 秒、66MB 堆,而懒加载
106
+ * 数据源存在的意义正是不碰全部行。一个标记就够表达"整表选中",`checkedState` 里留下的
107
+ * 条目反过来变成**例外**(被单独取消的行),内存是 O(例外数)。数据源一换标记自动失效,
108
+ * 不会把新数据整片画成已选。
109
+ */
110
+ const selectAllStates = /* @__PURE__ */ new WeakMap();
111
+ const isSelectAllActive = (table) => {
112
+ if (table == null) return false;
113
+ const state = selectAllStates.get(table);
114
+ return state != null && state.source === getDataSource(table);
115
+ };
116
+ const setSelectAllActive = (table, active) => {
117
+ if (table == null) return;
118
+ if (active) selectAllStates.set(table, { source: getDataSource(table) });
119
+ else selectAllStates.delete(table);
120
+ };
121
+ /**
122
+ * 遍历这一列在 `checkedState` 里的所有取值。级联模式下这张表是**稀疏**的 —— 只有被点过
123
+ * 的行才有条目,所以规模是「点过的行数」而不是表行数。
124
+ */
125
+ const forEachRowSeriesState = (table, visit) => {
126
+ const field = resolveRowSeriesField(table);
127
+ getStateManager(table)?.checkedState?.forEach((entry) => {
128
+ if (entry != null) visit(entry[field]);
129
+ });
130
+ };
131
+ const countRowSeriesStates = (table) => {
132
+ let checked = 0;
133
+ let unchecked = 0;
134
+ forEachRowSeriesState(table, (value) => {
135
+ if (value === true) checked += 1;
136
+ else if (value === false) unchecked += 1;
137
+ });
138
+ return {
139
+ checked,
140
+ unchecked
141
+ };
142
+ };
143
+ /**
144
+ * 直接写一条记录的勾选态。**只在批量化路径上用**(避开引擎逐行接口里的全树遍历,见
145
+ * `setAllCascadeRows`);单行勾选仍走 `setCellCheckboxStateByRecordIndex`,那条路要引擎
146
+ * 顺手做级联与重绘。
147
+ */
148
+ const setRowSeriesState = (table, key, value) => {
149
+ const checkedState = getStateManager(table)?.checkedState;
150
+ if (checkedState == null) return;
151
+ const field = resolveRowSeriesField(table);
152
+ const entry = checkedState.get(key) ?? {};
153
+ entry[field] = value;
154
+ checkedState.set(key, entry);
155
+ };
156
+ /** 只清本组件这一列:`checkedState` 里还可能存着使用方自己 checkbox 列的状态。 */
157
+ const clearRowSeriesStates = (table) => {
158
+ const field = resolveRowSeriesField(table);
159
+ getStateManager(table)?.checkedState?.forEach((entry) => {
160
+ if (entry != null) delete entry[field];
161
+ });
162
+ };
163
+ /**
164
+ * 重画序号列(表头 + 可见体行)。
165
+ *
166
+ * 这一列被自定义 layout 接管后,VTable 不会自己发现 `checkedState` 变了 —— records 那条路
167
+ * 是靠 `setCellCheckboxStateByRecordIndex` 内部的 `table.render()` 顺带重画的,走标记的
168
+ * 这条路没有那个调用,不自己标脏就要等下一次整表渲染才看得见勾。
169
+ */
170
+ const refreshRowSeriesCells = (table) => {
171
+ if (getScenegraph(table) == null) return;
172
+ updateCellContent(table, 0, 0);
173
+ const { endRow, startRow } = getVisibleRowRange(table);
174
+ if (endRow >= startRow) updateCellContentRange(table, 0, startRow, 0, endRow);
175
+ updateNextFrame(table);
176
+ };
177
+ /**
178
+ * 需要遍历的**可见**行范围。
179
+ *
180
+ * **不能扫全表。** 这两条路径每次勾选都会跑一遍,百万行的表上就是 100 万次
181
+ * `getRecordIndexByCell` + Map 查询 —— 页面直接卡住,观感是「**复选框点不动**」。
182
+ * 而 `select.ranges` 只影响**可见行**的画布高亮(VTable 渲染时本来也会裁到视口),
183
+ * 所以扫可见窗口就够。
184
+ *
185
+ * 拿得到 `scenegraph.proxy` 时用它给的真实可视区;拿不到(未渲染 / 单测桩)就退到一个
186
+ * 有上界的窗口,绝不能退回 `rowCount - 1`。
187
+ */
188
+ const ROW_SCAN_LIMIT = 500;
189
+ const selectionScanRange = (table) => {
190
+ const firstRow = table?.columnHeaderLevelCount ?? 1;
191
+ const lastRow = (table?.rowCount ?? 1) - 1;
192
+ const proxy = getScenegraph(table)?.proxy;
193
+ const startRow = Math.max(firstRow, proxy?.rowStart ?? firstRow);
194
+ return {
195
+ endRow: Math.min(lastRow, proxy?.rowEnd ?? startRow + ROW_SCAN_LIMIT),
196
+ startRow
197
+ };
198
+ };
199
+ const isCascadeSelectionTable = (table) => Boolean(getInternalProps(table)?.enableCheckboxCascade);
200
+ const getRowRecordKey = (table, row) => {
201
+ const path = getRecordIndexByCell(table, 0, row) ?? getIndexKey(table, getRecordShowIndexByCell(table, 0, row));
202
+ if (path == null) return void 0;
203
+ return Array.isArray(path) ? path.toString() : String(path);
204
+ };
205
+ const getRowCheckboxState = (table, row) => {
206
+ const key = getRowRecordKey(table, row);
207
+ if (key == null) return void 0;
208
+ const state = getStateManager(table)?.checkedState?.get(key)?.[resolveRowSeriesField(table)];
209
+ if (state === void 0 && isSelectAllActive(table)) return true;
210
+ return state;
211
+ };
212
+ /** Toggle through VTable's record-index checkbox cascade. */
213
+ const setRowCheckboxState = (table, row, checked) => {
214
+ const path = getRecordIndexByCell(table, 0, row);
215
+ if (path == null) return;
216
+ setCellCheckboxStateByRecordIndex(table, path, resolveRowSeriesField(table), checked);
217
+ syncCascadeSelectionRanges(table);
218
+ refreshRowSeriesCells(table);
219
+ fireTableEvent(table, TABLE_EVENT_TYPE.SELECTED_CHANGED, { ranges: getStateManager(table)?.select?.ranges ?? [] });
220
+ };
221
+ /** Keep VTable selection ranges in sync with checkbox state for row highlight. */
222
+ const syncCascadeSelectionRanges = (table) => {
223
+ if (isCascadeSelectionTable(table) === false) return;
224
+ const { endRow, startRow } = selectionScanRange(table);
225
+ const endCol = (table?.colCount ?? 1) - 1;
226
+ const ranges = [];
227
+ let rangeStart = -1;
228
+ let rangeEnd = -1;
229
+ for (let row = startRow; row <= endRow; row += 1) {
230
+ if (isGroupTitleRow(table, row)) continue;
231
+ const state = getRowCheckboxState(table, row);
232
+ if (state === true || state === "indeterminate") {
233
+ if (rangeStart < 0) rangeStart = row;
234
+ rangeEnd = row;
235
+ continue;
236
+ }
237
+ if (rangeStart >= 0) {
238
+ ranges.push(createFullRowRange(rangeStart, rangeEnd, endCol));
239
+ rangeStart = -1;
240
+ rangeEnd = -1;
241
+ }
242
+ }
243
+ if (rangeStart >= 0) ranges.push(createFullRowRange(rangeStart, rangeEnd, endCol));
244
+ if (ranges.length === 0) clearSelected(table);
245
+ else selectCells(table, ranges);
246
+ };
247
+ const getCascadeHeaderState = (table) => {
248
+ if (hasRecordTree(table) === false) {
249
+ const { checked, unchecked } = countRowSeriesStates(table);
250
+ if (isSelectAllActive(table)) return unchecked > 0 ? "indeterminate" : true;
251
+ if (checked === 0) return false;
252
+ return checked >= sourceRowTotal(table) ? true : "indeterminate";
253
+ }
254
+ return getStateManager(table)?.headerCheckedState?.[resolveRowSeriesField(table)];
255
+ };
256
+ const setAllCascadeRows = (table, checked) => {
257
+ if (hasRecordTree(table) === false) {
258
+ setSelectAllActive(table, checked);
259
+ clearRowSeriesStates(table);
260
+ syncCascadeSelectionRanges(table);
261
+ refreshRowSeriesCells(table);
262
+ return;
263
+ }
264
+ if (checked === false) {
265
+ clearCascadeSelection(table);
266
+ clearSelected(table);
267
+ return;
268
+ }
269
+ const records = getRecords(table);
270
+ if (Array.isArray(records)) {
271
+ const field = resolveRowSeriesField(table);
272
+ const headerCheckedState = getStateManager(table)?.headerCheckedState;
273
+ forEachRecordPath(records, (path) => setRowSeriesState(table, path.toString(), true));
274
+ if (headerCheckedState != null) headerCheckedState[field] = true;
275
+ }
276
+ syncCascadeSelectionRanges(table);
277
+ refreshRowSeriesCells(table);
278
+ };
279
+ const toggleSeriesRow = (table, row, shiftKey) => {
280
+ if (Boolean(getInternalProps(table)?.enableCheckboxCascade)) {
281
+ setRowCheckboxState(table, row, getRowCheckboxState(table, row) === true ? false : true);
282
+ return;
283
+ }
284
+ toggleRowSelection(table, row, Boolean(shiftKey));
285
+ };
286
+ /**
287
+ * 全选数据行,级联开着时走复选框(那才是选中态的真身)。
288
+ *
289
+ * 键盘必须走这里而不是自己拼区间:级联模式下 `clearSelected` / `selectCells` 只动
290
+ * `select.ranges`,不动 `stateManager.checkedState` —— 而复选框的勾选态、底部「已选 N 行」
291
+ * 计数、`selectionActions` 全都读 checkedState。只写 ranges 会得到「行高亮了但一个勾都没有、
292
+ * 计数为 0」,而且下一次同步就把高亮抹掉。
293
+ *
294
+ * 返回是否真的选中了东西 —— 调用方要先拿它决定要不要 preventDefault,否则没有体行时也会
295
+ * 吞掉浏览器的全选快捷键。
296
+ */
297
+ const selectAllSeriesRows = (table) => {
298
+ if (isCascadeSelectionTable(table)) {
299
+ setAllCascadeRows(table, true);
300
+ return true;
301
+ }
302
+ const startRow = resolveSelectionStartRow(table);
303
+ const endRow = resolveSelectionEndRow(table);
304
+ if (endRow < startRow) return false;
305
+ selectAllRows(table, startRow, endRow, (table?.colCount ?? 1) - 1);
306
+ return true;
307
+ };
308
+ const toggleSeriesHeader = (table) => {
309
+ if (Boolean(getInternalProps(table)?.enableCheckboxCascade)) {
310
+ setAllCascadeRows(table, getCascadeHeaderState(table) === true ? false : true);
311
+ return;
312
+ }
313
+ const startRow = resolveSelectionStartRow(table);
314
+ const endRow = resolveSelectionEndRow(table);
315
+ if (endRow < startRow) return;
316
+ const endCol = (table?.colCount ?? 1) - 1;
317
+ if ((getStateManager(table)?.select?.ranges ?? []).some((range) => isFullRowRange(range, endCol) && Math.min(range.start.row, range.end.row) <= startRow && Math.max(range.start.row, range.end.row) >= endRow)) {
318
+ clearSelected(table);
319
+ return;
320
+ }
321
+ selectAllRows(table, startRow, endRow, endCol);
322
+ };
323
+ const forEachRecordPath = (records, visit, parentPath = []) => {
324
+ if (Array.isArray(records) === false) return;
325
+ records.forEach((item, index) => {
326
+ const record = item ?? {};
327
+ const path = [...parentPath, index];
328
+ visit(path, record);
329
+ if (Array.isArray(record.children)) forEachRecordPath(record.children, visit, path);
330
+ });
331
+ };
332
+ /** Visible rows whose VTable checkbox state is checked or indeterminate. */
333
+ const getCascadeSelectedRowIndexes = (table) => {
334
+ const { endRow, startRow } = selectionScanRange(table);
335
+ const rows = [];
336
+ for (let row = startRow; row <= endRow; row += 1) {
337
+ if (isGroupTitleRow(table, row)) continue;
338
+ const state = getRowCheckboxState(table, row);
339
+ if (state === true || state === "indeterminate") rows.push(row);
340
+ }
341
+ return rows;
342
+ };
343
+ /**
344
+ * 勾选了多少**行**:每条状态为 `true` 的记录算一行,含被折叠隐藏的那些。
345
+ *
346
+ * 树里的父行也算 —— 它有行号、能勾,级联全选时状态就是 `true`;只数叶子会把它漏掉
347
+ * (实测四张表全选后全都少报,见函数内注释)。
348
+ */
349
+ const getCascadeSelectedCount = (table) => {
350
+ if (hasRecordTree(table) === false) {
351
+ const { checked, unchecked } = countRowSeriesStates(table);
352
+ if (isSelectAllActive(table)) return Math.max(0, sourceRowTotal(table) - unchecked);
353
+ return checked;
354
+ }
355
+ let count = 0;
356
+ const field = resolveRowSeriesField(table);
357
+ forEachRecordPath(getRecords(table), (path, record) => {
358
+ if (isGroupTitleRecord(record)) return;
359
+ if (getStateManager(table)?.checkedState?.get(path.toString())?.[field] === true) count += 1;
360
+ });
361
+ return count;
362
+ };
363
+ const clearCascadeSelection = (table) => {
364
+ const sourceSelection = hasRecordTree(table) === false;
365
+ setSelectAllActive(table, false);
366
+ clearCheckboxState(table, resolveRowSeriesField(table));
367
+ if (sourceSelection) clearRowSeriesStates(table);
368
+ syncCascadeSelectionRanges(table);
369
+ refreshRowSeriesCells(table);
370
+ };
371
+ //#endregion
372
+ export { clearCascadeSelection, getCascadeHeaderState, getCascadeSelectedCount, getCascadeSelectedRowIndexes, getRowCheckboxState, isCascadeSelectionTable, isGroupTitleRow, resolveRowSeriesIndex, resolveRowSeriesValue, resolveSelectionEndRow, resolveSelectionStartRow, selectAllSeriesRows, syncCascadeSelectionRanges, toggleSeriesHeader, toggleSeriesRow };
373
+
374
+ //# sourceMappingURL=seriesSelection.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seriesSelection.mjs","names":[],"sources":["../../../src/Table/vtable/seriesSelection.ts"],"sourcesContent":["import { TABLE_EVENT_TYPE } from '@visactor/vtable';\n\nimport { isGroupTitleRecord } from '../core/cellValue';\nimport {\n createFullRowRange,\n isFullRowRange,\n selectAllRows,\n type TableCellRange,\n toggleRowSelection,\n} from '../core/rowSelection';\nimport {\n clearCheckboxState,\n clearSelected,\n fireTableEvent,\n getDataSource,\n getIndexKey,\n getInternalProps,\n getLayoutMapRowSeriesField,\n getRecordIndexByCell,\n getRecords,\n getRecordShowIndexByCell,\n getScenegraph,\n getStateManager,\n getVisibleRowRange,\n selectCells,\n setCellCheckboxStateByRecordIndex,\n updateCellContent,\n updateCellContentRange,\n updateNextFrame,\n} from './vtableAdapter';\n\nexport const isGroupTitleRow = (table: any, row: number): boolean =>\n Boolean(\n getInternalProps(table)?.groupBy && isGroupTitleRecord(table?.getCellOriginRecord?.(0, row)),\n );\n\n/**\n * Last body row select-all should cover. Group title rows carry no data — the row series\n * skips them when numbering, the header checkbox route walks past them, and\n * `getCascadeSelectedRowIndexes` leaves them out — so select-all has to agree with all of\n * them. Returns a row below the header when every body row is a group.\n */\nexport const resolveSelectionEndRow = (table: any): number => {\n const firstRow = table?.columnHeaderLevelCount ?? 1;\n let row = (table?.rowCount ?? 1) - 1;\n\n while (row >= firstRow && isGroupTitleRow(table, row)) row -= 1;\n\n return row;\n};\n\n/**\n * First body row a select-all range may start on. Group title rows carry no data — the row\n * series skips them when numbering and the header checkbox leaves them out — so select-all\n * has to agree with both. Returns a row past the last body row when every one is a group.\n */\nexport const resolveSelectionStartRow = (table: any): number => {\n const firstRow = table?.columnHeaderLevelCount ?? 1;\n const lastRow = (table?.rowCount ?? 1) - 1;\n let row = firstRow;\n\n while (row <= lastRow && isGroupTitleRow(table, row)) row += 1;\n\n return row;\n};\n\n/** 超过这个行数就不建索引:一份 rowCount 长的数组本身就是内存开销。 */\nconst ROW_INDEX_CACHE_LIMIT = 100_000;\n\n/**\n * 分组表的行号索引缓存。\n *\n * `resolveRowSeriesIndex` 每画一个可见行都要从第一个体行数到它自己,每个 cursor 一次\n * `isGroupTitleRow`(内含 `getCellOriginRecord`)。两万行的分组表滚到中部时,单个可见行就是\n * 两万次记录查询,而一屏几十行、每帧都要重画 —— **序号列自己成了滚动卡顿源**(它只画一个数字)。\n *\n * 索引只跟「表头层数 + 总行数」有关(折叠 / 展开会改变行数),按它们失效,重建一次 O(行数)。\n */\nconst rowIndexCaches = new WeakMap<\n object,\n { counts: number[]; firstRow: number; rowCount: number }\n>();\n\nconst resolveGroupedRowIndex = (table: any, row: number, firstRow: number): number => {\n const rowCount = table?.rowCount ?? 0;\n\n if (rowCount > ROW_INDEX_CACHE_LIMIT || rowCount <= firstRow) {\n let index = 0;\n for (let cursor = firstRow; cursor <= row; cursor += 1) {\n if (isGroupTitleRow(table, cursor) === false) index += 1;\n }\n return index;\n }\n\n let cache = rowIndexCaches.get(table);\n if (cache == null || cache.rowCount !== rowCount || cache.firstRow !== firstRow) {\n const counts: number[] = [];\n let index = 0;\n for (let cursor = firstRow; cursor < rowCount; cursor += 1) {\n if (isGroupTitleRow(table, cursor) === false) index += 1;\n counts[cursor] = index;\n }\n cache = { counts, firstRow, rowCount };\n rowIndexCaches.set(table, cache);\n }\n\n return cache.counts[row] ?? 0;\n};\n\n/** Row number that skips group title rows, so only data records are counted. */\nexport const resolveRowSeriesIndex = (table: any, row: number): number => {\n const firstRow = table?.columnHeaderLevelCount ?? 1;\n if (row < firstRow) return 0;\n\n if (getInternalProps(table)?.groupBy == null) return row - firstRow + 1;\n\n return resolveGroupedRowIndex(table, row, firstRow);\n};\n\n/** Display value for a row series cell: group rows show no number. */\nexport const resolveRowSeriesValue = (table: any, row: number): string | number =>\n isGroupTitleRow(table, row) ? '' : resolveRowSeriesIndex(table, row);\n\n/**\n * VTable 在 `rowSeriesNumber.field` 缺省时用的字段名。**只在读不到解析结果时兜底** ——\n * 它是引擎的默认值,不是我们的契约;使用方覆盖 `field` 后就该以 `layoutMap` 里的为准。\n */\nconst FALLBACK_ROW_SERIES_CHECKBOX_FIELD = '_vtable_rowSeries_number';\n\n/**\n * 行号列复选框状态存在哪个键下。复选框的勾选态、底部「已选 N 行」计数、`selectionActions`\n * 和级联同步全都按这个键读写 `stateManager.checkedState`;读错键就**所有复选框恒为未选中、\n * 点选也不动**,而且不报任何错。\n *\n * 取值必须问 table 自己(见 `getLayoutMapRowSeriesField`):写死默认名会在使用方给\n * `rowSeriesNumber` 传了自定义 `field` 时静默失效。\n */\nconst resolveRowSeriesField = (table: any): string =>\n getLayoutMapRowSeriesField(table) ?? FALLBACK_ROW_SERIES_CHECKBOX_FIELD;\n\n/**\n * 这张表有没有可以直接遍历的 `records`。\n *\n * **不能假设 `table.records` 就是数据。** 使用方传 `dataSource`(VTable 的懒加载形态,\n * 百万行 demo 就是)时,引擎在 `_setDataSource` 里把 `internalProps.records` 置空,react\n * 包装层再补一个 `[]`,取行只剩 `dataSource.get(i)` 一条路。此时所有按 records 遍历的\n * 代码全部**静默**走空:勾选确实写进了 `checkedState`,但「已选 N 行」恒为 0(浮动条根本\n * 不渲染)、表头全选一行都选不中 —— 和另外几张传 `records` 的表行为对不上。\n */\nconst hasRecordTree = (table: any): boolean =>\n Array.isArray(table?.records) && table.records.length > 0;\n\n/** 可被选中的数据行数。数据源表上分组标题行不存在(分组表一律按 records 走)。 */\nconst sourceRowTotal = (table: any): number =>\n Math.max(0, (table?.rowCount ?? 0) - (table?.columnHeaderLevelCount ?? 0));\n\ninterface SelectAllState {\n /** 数据源换掉就作废 —— `_setDataSource` 每次都会新建一个实例。 */\n source: unknown;\n}\n\n/**\n * 数据源表的全选标记。\n *\n * **不能靠往 `checkedState` 里灌满所有行来全选**:百万行实测要 1 秒、66MB 堆,而懒加载\n * 数据源存在的意义正是不碰全部行。一个标记就够表达\"整表选中\",`checkedState` 里留下的\n * 条目反过来变成**例外**(被单独取消的行),内存是 O(例外数)。数据源一换标记自动失效,\n * 不会把新数据整片画成已选。\n */\nconst selectAllStates = new WeakMap<object, SelectAllState>();\n\nconst isSelectAllActive = (table: any): boolean => {\n if (table == null) return false;\n\n const state = selectAllStates.get(table);\n\n return state != null && state.source === getDataSource(table);\n};\n\nconst setSelectAllActive = (table: any, active: boolean): void => {\n if (table == null) return;\n\n if (active) selectAllStates.set(table, { source: getDataSource(table) });\n else selectAllStates.delete(table);\n};\n\n/**\n * 遍历这一列在 `checkedState` 里的所有取值。级联模式下这张表是**稀疏**的 —— 只有被点过\n * 的行才有条目,所以规模是「点过的行数」而不是表行数。\n */\nconst forEachRowSeriesState = (table: any, visit: (value: unknown) => void): void => {\n const field = resolveRowSeriesField(table);\n\n getStateManager(table)?.checkedState?.forEach((entry: Record<string, unknown> | undefined) => {\n if (entry != null) visit(entry[field]);\n });\n};\n\nconst countRowSeriesStates = (table: any): { checked: number; unchecked: number } => {\n let checked = 0;\n let unchecked = 0;\n\n forEachRowSeriesState(table, (value) => {\n if (value === true) checked += 1;\n else if (value === false) unchecked += 1;\n });\n\n return { checked, unchecked };\n};\n\n/**\n * 直接写一条记录的勾选态。**只在批量化路径上用**(避开引擎逐行接口里的全树遍历,见\n * `setAllCascadeRows`);单行勾选仍走 `setCellCheckboxStateByRecordIndex`,那条路要引擎\n * 顺手做级联与重绘。\n */\nconst setRowSeriesState = (table: any, key: string, value: boolean): void => {\n const checkedState = getStateManager(table)?.checkedState;\n if (checkedState == null) return;\n\n const field = resolveRowSeriesField(table);\n const entry = checkedState.get(key) ?? {};\n\n entry[field] = value;\n checkedState.set(key, entry);\n};\n\n/** 只清本组件这一列:`checkedState` 里还可能存着使用方自己 checkbox 列的状态。 */\nconst clearRowSeriesStates = (table: any): void => {\n const field = resolveRowSeriesField(table);\n\n getStateManager(table)?.checkedState?.forEach((entry: Record<string, unknown> | undefined) => {\n if (entry != null) delete entry[field];\n });\n};\n\n/**\n * 重画序号列(表头 + 可见体行)。\n *\n * 这一列被自定义 layout 接管后,VTable 不会自己发现 `checkedState` 变了 —— records 那条路\n * 是靠 `setCellCheckboxStateByRecordIndex` 内部的 `table.render()` 顺带重画的,走标记的\n * 这条路没有那个调用,不自己标脏就要等下一次整表渲染才看得见勾。\n */\nconst refreshRowSeriesCells = (table: any): void => {\n if (getScenegraph(table) == null) return;\n\n updateCellContent(table, 0, 0);\n const { endRow, startRow } = getVisibleRowRange(table);\n if (endRow >= startRow) updateCellContentRange(table, 0, startRow, 0, endRow);\n updateNextFrame(table);\n};\n\n/**\n * 需要遍历的**可见**行范围。\n *\n * **不能扫全表。** 这两条路径每次勾选都会跑一遍,百万行的表上就是 100 万次\n * `getRecordIndexByCell` + Map 查询 —— 页面直接卡住,观感是「**复选框点不动**」。\n * 而 `select.ranges` 只影响**可见行**的画布高亮(VTable 渲染时本来也会裁到视口),\n * 所以扫可见窗口就够。\n *\n * 拿得到 `scenegraph.proxy` 时用它给的真实可视区;拿不到(未渲染 / 单测桩)就退到一个\n * 有上界的窗口,绝不能退回 `rowCount - 1`。\n */\nconst ROW_SCAN_LIMIT = 500;\n\nconst selectionScanRange = (table: any): { endRow: number; startRow: number } => {\n const firstRow = table?.columnHeaderLevelCount ?? 1;\n const lastRow = (table?.rowCount ?? 1) - 1;\n const proxy = getScenegraph(table)?.proxy;\n const startRow = Math.max(firstRow, proxy?.rowStart ?? firstRow);\n const endRow = Math.min(lastRow, proxy?.rowEnd ?? startRow + ROW_SCAN_LIMIT);\n\n return { endRow, startRow };\n};\n\nexport const isCascadeSelectionTable = (table: any): boolean =>\n Boolean(getInternalProps(table)?.enableCheckboxCascade);\n\nconst getRowRecordKey = (table: any, row: number): string | undefined => {\n const path =\n getRecordIndexByCell(table, 0, row) ??\n getIndexKey(table, getRecordShowIndexByCell(table, 0, row));\n if (path == null) return undefined;\n return Array.isArray(path) ? path.toString() : String(path);\n};\n\nexport const getRowCheckboxState = (table: any, row: number): unknown => {\n const key = getRowRecordKey(table, row);\n if (key == null) return undefined;\n\n const state = getStateManager(table)?.checkedState?.get(key)?.[resolveRowSeriesField(table)];\n // 全选态下没有条目的行默认选中;条目里留下的就是**例外**(被单独取消的行)。\n if (state === undefined && isSelectAllActive(table)) return true;\n\n return state;\n};\n\n/** Toggle through VTable's record-index checkbox cascade. */\nconst setRowCheckboxState = (table: any, row: number, checked: boolean): void => {\n const path = getRecordIndexByCell(table, 0, row);\n if (path == null) return;\n\n setCellCheckboxStateByRecordIndex(table, path, resolveRowSeriesField(table), checked);\n syncCascadeSelectionRanges(table);\n // 勾一行会连带改**表头**的勾选/半选态,而表头那格同样不会自己重建(键盘勾行没有画布点击\n // 兜底)。只重画可见的序号列,代价是 O(可视行数)。\n refreshRowSeriesCells(table);\n fireTableEvent(table, TABLE_EVENT_TYPE.SELECTED_CHANGED, {\n ranges: getStateManager(table)?.select?.ranges ?? [],\n });\n};\n\n/** Keep VTable selection ranges in sync with checkbox state for row highlight. */\nexport const syncCascadeSelectionRanges = (table: any): void => {\n // 非级联模式的选中态在 `select.ranges` 里,`checkedState` 全是 `undefined` —— 照这里反推会\n // 得到空区间,然后 `clearSelected`。而它在 `TREE_HIERARCHY_STATE_CHANGE`(折叠/展开)时照样\n // 被调用(见 useTableVTableEvents),于是**折叠一次分组就把整片选区清空**。\n if (isCascadeSelectionTable(table) === false) return;\n\n const { endRow, startRow } = selectionScanRange(table);\n const endCol = (table?.colCount ?? 1) - 1;\n const ranges: Array<ReturnType<typeof createFullRowRange>> = [];\n let rangeStart = -1;\n // Tracked rather than derived from the next row: the walk skips group title rows, so\n // \"the row before the first unchecked one\" can land on a skipped group title and end the\n // range on a row that has no checkbox to justify it.\n let rangeEnd = -1;\n\n for (let row = startRow; row <= endRow; row += 1) {\n if (isGroupTitleRow(table, row)) continue;\n\n const state = getRowCheckboxState(table, row);\n const selected = state === true || state === 'indeterminate';\n\n if (selected) {\n if (rangeStart < 0) rangeStart = row;\n rangeEnd = row;\n continue;\n }\n\n if (rangeStart >= 0) {\n ranges.push(createFullRowRange(rangeStart, rangeEnd, endCol));\n rangeStart = -1;\n rangeEnd = -1;\n }\n }\n\n if (rangeStart >= 0) ranges.push(createFullRowRange(rangeStart, rangeEnd, endCol));\n\n if (ranges.length === 0) clearSelected(table);\n else selectCells(table, ranges);\n};\n\nexport const getCascadeHeaderState = (table: any): unknown => {\n if (hasRecordTree(table) === false) {\n const { checked, unchecked } = countRowSeriesStates(table);\n if (isSelectAllActive(table)) return unchecked > 0 ? 'indeterminate' : true;\n if (checked === 0) return false;\n\n return checked >= sourceRowTotal(table) ? true : 'indeterminate';\n }\n\n return getStateManager(table)?.headerCheckedState?.[resolveRowSeriesField(table)];\n};\n\nconst setAllCascadeRows = (table: any, checked: boolean): void => {\n if (hasRecordTree(table) === false) {\n setSelectAllActive(table, checked);\n clearRowSeriesStates(table);\n syncCascadeSelectionRanges(table);\n refreshRowSeriesCells(table);\n return;\n }\n\n if (checked === false) {\n clearCascadeSelection(table);\n clearSelected(table);\n return;\n }\n\n // **不能逐行调 `setCellCheckboxStateByRecordIndex`。** 那个接口末尾无条件跑一次\n // `updateHeaderCheckboxStateByField`,而它要 `traverseRecords(table.records)` 走完整棵树\n // —— 逐行调用就是 O(N²):实测 500 行 54ms、2000 行 147ms、5000 行 566ms(一次全选卡半秒)。\n // 这里直接写 `checkedState`(键的形状与引擎的 `getIndexKey(...).toString()` 一致,读写两侧\n // 本来就共用它),再自己收尾更新一次表头状态。\n const records = getRecords(table);\n if (Array.isArray(records)) {\n const field = resolveRowSeriesField(table);\n const headerCheckedState = getStateManager(table)?.headerCheckedState;\n\n forEachRecordPath(records, (path) => setRowSeriesState(table, path.toString(), true));\n if (headerCheckedState != null) headerCheckedState[field] = true;\n }\n\n syncCascadeSelectionRanges(table);\n refreshRowSeriesCells(table);\n};\n\nexport const toggleSeriesRow = (table: any, row: number, shiftKey?: boolean): void => {\n const cascadeSelection = Boolean(getInternalProps(table)?.enableCheckboxCascade);\n\n if (cascadeSelection) {\n setRowCheckboxState(table, row, getRowCheckboxState(table, row) === true ? false : true);\n return;\n }\n\n toggleRowSelection(table, row, Boolean(shiftKey));\n};\n\n/**\n * 全选数据行,级联开着时走复选框(那才是选中态的真身)。\n *\n * 键盘必须走这里而不是自己拼区间:级联模式下 `clearSelected` / `selectCells` 只动\n * `select.ranges`,不动 `stateManager.checkedState` —— 而复选框的勾选态、底部「已选 N 行」\n * 计数、`selectionActions` 全都读 checkedState。只写 ranges 会得到「行高亮了但一个勾都没有、\n * 计数为 0」,而且下一次同步就把高亮抹掉。\n *\n * 返回是否真的选中了东西 —— 调用方要先拿它决定要不要 preventDefault,否则没有体行时也会\n * 吞掉浏览器的全选快捷键。\n */\nexport const selectAllSeriesRows = (table: any): boolean => {\n if (isCascadeSelectionTable(table)) {\n setAllCascadeRows(table, true);\n return true;\n }\n\n const startRow = resolveSelectionStartRow(table);\n const endRow = resolveSelectionEndRow(table);\n if (endRow < startRow) return false;\n\n selectAllRows(table, startRow, endRow, (table?.colCount ?? 1) - 1);\n return true;\n};\n\nexport const toggleSeriesHeader = (table: any): void => {\n const cascadeSelection = Boolean(getInternalProps(table)?.enableCheckboxCascade);\n\n if (cascadeSelection) {\n setAllCascadeRows(table, getCascadeHeaderState(table) === true ? false : true);\n return;\n }\n\n // 非级联模式的区间必须与 Ctrl+A **完全一致**(`resolveSelectionStartRow/EndRow` 的整表),\n // 原先这里用的是可视窗口(`selectionScanRange`,代理窗口约 200 行):1000 行的表点表头只\n // 选中前约 200 行,而表头照样显示「已全选」。ARCHITECTURE §「选区一端要为『全选』定边界」\n // 要的就是两条路径同一区间。\n const startRow = resolveSelectionStartRow(table);\n const endRow = resolveSelectionEndRow(table);\n // 一个体行都没有:**别下发反序区间** —— `createFullRowRange` 会 min/max 归一成 [表头行, 下一行],\n // 空表点一下表头反而高亮表头。`selectAllSeriesRows` 早就有这条守卫。\n if (endRow < startRow) return;\n\n const endCol = (table?.colCount ?? 1) - 1;\n const ranges = getStateManager(table)?.select?.ranges ?? [];\n // 是否「已全选」:只要有一个整行区间盖住 [startRow, endRow] 即可 —— 逐行 `isFullRowSelected`\n // 是大表上的 O(行数) 扫描,而表头点击只需要这个布尔值。\n const checked = ranges.some(\n (range: TableCellRange) =>\n isFullRowRange(range, endCol) &&\n Math.min(range.start.row, range.end.row) <= startRow &&\n Math.max(range.start.row, range.end.row) >= endRow,\n );\n\n if (checked) {\n clearSelected(table);\n return;\n }\n\n selectAllRows(table, startRow, endRow, endCol);\n};\n\nconst forEachRecordPath = (\n records: unknown,\n visit: (path: number[], record: { children?: unknown[] }) => void,\n parentPath: number[] = [],\n): void => {\n if (Array.isArray(records) === false) return;\n\n records.forEach((item, index) => {\n const record = (item ?? {}) as { children?: unknown[] };\n const path = [...parentPath, index];\n visit(path, record);\n\n if (Array.isArray(record.children)) forEachRecordPath(record.children, visit, path);\n });\n};\n\n/** Visible rows whose VTable checkbox state is checked or indeterminate. */\nexport const getCascadeSelectedRowIndexes = (table: any): number[] => {\n // 返回的本来就是**可见**行,所以只扫可见窗口 —— 见 selectionScanRange。\n const { endRow, startRow } = selectionScanRange(table);\n const rows: number[] = [];\n\n for (let row = startRow; row <= endRow; row += 1) {\n if (isGroupTitleRow(table, row)) continue;\n\n const state = getRowCheckboxState(table, row);\n if (state === true || state === 'indeterminate') rows.push(row);\n }\n\n return rows;\n};\n\n/**\n * 勾选了多少**行**:每条状态为 `true` 的记录算一行,含被折叠隐藏的那些。\n *\n * 树里的父行也算 —— 它有行号、能勾,级联全选时状态就是 `true`;只数叶子会把它漏掉\n * (实测四张表全选后全都少报,见函数内注释)。\n */\nexport const getCascadeSelectedCount = (table: any): number => {\n if (hasRecordTree(table) === false) {\n const { checked, unchecked } = countRowSeriesStates(table);\n if (isSelectAllActive(table)) return Math.max(0, sourceRowTotal(table) - unchecked);\n\n return checked;\n }\n\n let count = 0;\n const field = resolveRowSeriesField(table);\n\n // **每条状态为 true 的**数据**记录算一行**,两条边界:\n //\n // - 树里的**父行要算** —— 它有行号、能勾,级联全选时状态就是 true(半选才是\n // 'indeterminate')。只数叶子会漏掉它:实测树形表格 62 行全选后只写 41。\n // - `groupBy` 合成的**分组标题行不算** —— 它在记录树里也是父节点(`vtableMerge`),\n // 全选时同样打勾,但「已选 N 行」数的是数据行:Tree 分组 30 行里 3 个是分组行,\n // 全选后条上该写 27。\n //\n // 折叠不影响这个口径:子孙的状态没变,照样计入。\n forEachRecordPath(getRecords(table), (path, record) => {\n if (isGroupTitleRecord(record)) return;\n\n const state = getStateManager(table)?.checkedState?.get(path.toString())?.[field];\n if (state === true) count += 1;\n });\n\n return count;\n};\n\nexport const clearCascadeSelection = (table: any): void => {\n const sourceSelection = hasRecordTree(table) === false;\n\n setSelectAllActive(table, false);\n clearCheckboxState(table, resolveRowSeriesField(table));\n // VTable 的 clearCheckboxState 是按 `table.records` 遍历的,数据源表上它自己什么也清不掉\n // —— 条目都还在 checkedState 里,只清画面不清状态,下一次同步就把勾选态画回来。\n if (sourceSelection) clearRowSeriesStates(table);\n syncCascadeSelectionRanges(table);\n // **两条路都要重绘。** VTable 的 `clearCheckboxState` 里那次 render 不重建序号列的自定义\n // layout,records 表上一样会留下满屏的勾:实测 Basic demo 点「取消选择」后浮动条消失了、\n // 表头与整列的勾还在,看上去就是「从工具栏取消不生效」。\n refreshRowSeriesCells(table);\n};\n"],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ "use client";
2
+ //#region src/Table/vtable/vtableAdapter.ts
3
+ const getScenegraph = (table) => table.scenegraph;
4
+ /**
5
+ * VTable 的 `release()` 会把 `scenegraph` 与 `internalProps` 一起置 null,之后再读任何
6
+ * getter(`columnHeaderLevelCount`、`getCellValue` …)都会抛 TypeError。表实例被 react-vtable
7
+ * 拆掉之后 `tableRef` 仍然指着它,所以持有实例的渲染路径必须先问这一句。
8
+ */
9
+ const isTableReleased = (table) => table == null || getScenegraph(table) == null;
10
+ const getScenegraphComponent = (table) => table.scenegraph.component;
11
+ const updateNextFrame = (table) => {
12
+ getScenegraph(table).updateNextFrame?.();
13
+ };
14
+ const updateCellContent = (table, col, row) => {
15
+ getScenegraph(table).updateCellContent?.(col, row);
16
+ };
17
+ const updateCellContentRange = (table, startCol, startRow, endCol, endRow) => {
18
+ table.updateCellContentRange?.(startCol, startRow, endCol, endRow);
19
+ };
20
+ const getVisibleRowRange = (table, maxRows = 80) => {
21
+ const scenegraph = getScenegraph(table);
22
+ const headerRows = table.columnHeaderLevelCount ?? 1;
23
+ const startRow = Math.max(headerRows, scenegraph.proxy?.rowStart ?? headerRows);
24
+ return {
25
+ endRow: Math.min(scenegraph.proxy?.rowEnd ?? startRow + maxRows, startRow + maxRows, (table.rowCount ?? 1) - 1),
26
+ startRow
27
+ };
28
+ };
29
+ const getLayoutMapHierarchyIndent = (table) => table?.internalProps?.layoutMap?.hierarchyIndent;
30
+ /**
31
+ * 行号列复选框状态存在哪个字段下。**不要写死** —— VTable 把字段名解析成
32
+ * `rowSeriesNumber.field ?? '_vtable_rowSeries_number'`(`layout/simple-header-layout.js`
33
+ * 的 `handleRowSeriesNumber`),解析结果就在这里。使用方覆盖了 `field` 时,只有读这里才对。
34
+ */
35
+ const getLayoutMapRowSeriesField = (table) => {
36
+ const field = table?.internalProps?.layoutMap?.rowSeriesNumberColumn?.[0]?.field;
37
+ return typeof field === "string" && field !== "" ? field : void 0;
38
+ };
39
+ /**
40
+ * 吸顶插件挂在 `scenegraph.plugins` 里,字段名取自 VTable 1.26.x 的
41
+ * `plugins/list-tree-stick-cell.js`(`showedTitleRows` / `titleRows`)。这是**没有类型声明**
42
+ * 的私有结构,全部走可选链:升版后失效会静默退回 VTable 写死的 40px 行高偏移,而不是报错。
43
+ */
44
+ const getStickyTitleRows = (table) => {
45
+ const plugin = table?.listTreeStickCellPlugin;
46
+ return plugin?.showedTitleRows ?? plugin?.titleRows;
47
+ };
48
+ const getStickyShadowRoots = (table) => {
49
+ const scenegraph = table?.scenegraph;
50
+ return [scenegraph?.colHeaderGroup?.border?.shadowRoot, scenegraph?.cornerHeaderGroup?.border?.shadowRoot].filter(Boolean);
51
+ };
52
+ const getRowHeight = (table, row) => table?.getRowHeight?.(row);
53
+ /**
54
+ * 引擎当前实际排布出来的总行高(含表头行,不含底部那 8px 的槽)。
55
+ *
56
+ * 折叠 / 展开之后**只有引擎知道现在有多少行**:树节点的 `hierarchyState` 引擎会写回记录,但
57
+ * 分组标题行(`groupBy` 生成的那些)的折叠状态只存在引擎的分组结构里,`records` 上根本没有
58
+ * —— 所以容器高度不能在那之后按数据重算,只能问引擎。
59
+ */
60
+ const getAllRowsHeight = (table) => {
61
+ const height = table?.getAllRowsHeight?.();
62
+ return typeof height === "number" && Number.isFinite(height) && height > 0 ? height : void 0;
63
+ };
64
+ const getInternalProps = (table) => table?.internalProps;
65
+ /**
66
+ * VTable 把当前编辑态挂在 `editorManager` 上(d.ts 里是 `ListTableProtected`)。
67
+ * 这些字段在 1.26.x 上核对过;升版后若 `release()` 与 `doExit()` 的语义变化,这里的
68
+ * 读取会静默返回 undefined,表现为「编辑浮层不跟随」。
69
+ */
70
+ const getEditingEditor = (table) => table?.editorManager?.editingEditor;
71
+ const getEditCell = (table) => table?.editorManager?.editCell;
72
+ const getStateManager = (table) => table?.stateManager;
73
+ const getDataSource = (table) => table?.dataSource;
74
+ const getRecords = (table) => table?.records;
75
+ const getRecordIndexByCell = (table, col, row) => table?.getRecordIndexByCell?.(col, row);
76
+ const getRecordShowIndexByCell = (table, col, row) => table?.getRecordShowIndexByCell?.(col, row);
77
+ const getIndexKey = (table, showIndex) => showIndex == null ? void 0 : getDataSource(table)?.getIndexKey?.(showIndex);
78
+ const setCellCheckboxStateByRecordIndex = (table, path, field, checked) => {
79
+ table?.setCellCheckboxStateByRecordIndex?.(path, field, checked);
80
+ };
81
+ const fireTableEvent = (table, event, payload) => {
82
+ table?.fireListeners?.(event, payload);
83
+ };
84
+ const clearCheckboxState = (table, field) => {
85
+ table?.clearCheckboxState?.(field);
86
+ };
87
+ const clearSelected = (table) => {
88
+ table?.clearSelected?.();
89
+ };
90
+ const selectCells = (table, ranges) => {
91
+ table?.selectCells?.(ranges);
92
+ };
93
+ //#endregion
94
+ export { clearCheckboxState, clearSelected, fireTableEvent, getAllRowsHeight, getDataSource, getEditCell, getEditingEditor, getIndexKey, getInternalProps, getLayoutMapHierarchyIndent, getLayoutMapRowSeriesField, getRecordIndexByCell, getRecordShowIndexByCell, getRecords, getRowHeight, getScenegraph, getScenegraphComponent, getStateManager, getStickyShadowRoots, getStickyTitleRows, getVisibleRowRange, isTableReleased, selectCells, setCellCheckboxStateByRecordIndex, updateCellContent, updateCellContentRange, updateNextFrame };
95
+
96
+ //# sourceMappingURL=vtableAdapter.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vtableAdapter.mjs","names":[],"sources":["../../../src/Table/vtable/vtableAdapter.ts"],"sourcesContent":["'use client';\n\nimport type { ListTable as ListTableInstance } from '@visactor/vtable';\n\nexport interface PrivateScenegraph {\n proxy?: { rowEnd?: number; rowStart?: number };\n updateCellContent?: (col: number, row: number) => void;\n updateNextFrame?: () => void;\n}\n\nexport const getScenegraph = (table: ListTableInstance): PrivateScenegraph =>\n table.scenegraph as unknown as PrivateScenegraph;\n\n/**\n * VTable 的 `release()` 会把 `scenegraph` 与 `internalProps` 一起置 null,之后再读任何\n * getter(`columnHeaderLevelCount`、`getCellValue` …)都会抛 TypeError。表实例被 react-vtable\n * 拆掉之后 `tableRef` 仍然指着它,所以持有实例的渲染路径必须先问这一句。\n */\nexport const isTableReleased = (table: unknown): boolean =>\n table == null || getScenegraph(table as ListTableInstance) == null;\n\nexport interface PrivateScenegraphComponent {\n frozenShadowLine?: { setAttribute: (key: string, value: boolean) => void };\n hideFrozenColumnShadow?: () => void;\n showFrozenColumnShadow?: () => void;\n}\n\nexport const getScenegraphComponent = (\n table: ListTableInstance,\n): PrivateScenegraphComponent | undefined =>\n (table.scenegraph as unknown as { component?: PrivateScenegraphComponent }).component;\n\nexport const updateNextFrame = (table: ListTableInstance): void => {\n getScenegraph(table).updateNextFrame?.();\n};\n\nexport const updateCellContent = (table: ListTableInstance, col: number, row: number): void => {\n getScenegraph(table).updateCellContent?.(col, row);\n};\n\nexport const updateCellContentRange = (\n table: ListTableInstance,\n startCol: number,\n startRow: number,\n endCol: number,\n endRow: number,\n): void => {\n (\n table as ListTableInstance & {\n updateCellContentRange?: (\n colStart: number,\n rowStart: number,\n colEnd: number,\n rowEnd: number,\n ) => void;\n }\n ).updateCellContentRange?.(startCol, startRow, endCol, endRow);\n};\n\nexport const getVisibleRowRange = (\n table: ListTableInstance,\n maxRows = 80,\n): { endRow: number; startRow: number } => {\n const scenegraph = getScenegraph(table);\n const headerRows = table.columnHeaderLevelCount ?? 1;\n const startRow = Math.max(headerRows, scenegraph.proxy?.rowStart ?? headerRows);\n const endRow = Math.min(\n scenegraph.proxy?.rowEnd ?? startRow + maxRows,\n startRow + maxRows,\n (table.rowCount ?? 1) - 1,\n );\n\n return { endRow, startRow };\n};\n\nexport interface PrivateLayoutMap {\n hierarchyIndent?: number;\n rowSeriesNumberColumn?: ReadonlyArray<{ field?: unknown }>;\n}\n\nexport const getLayoutMapHierarchyIndent = (table: unknown): number | undefined =>\n (table as { internalProps?: { layoutMap?: PrivateLayoutMap } } | undefined)?.internalProps\n ?.layoutMap?.hierarchyIndent;\n\n/**\n * 行号列复选框状态存在哪个字段下。**不要写死** —— VTable 把字段名解析成\n * `rowSeriesNumber.field ?? '_vtable_rowSeries_number'`(`layout/simple-header-layout.js`\n * 的 `handleRowSeriesNumber`),解析结果就在这里。使用方覆盖了 `field` 时,只有读这里才对。\n */\nexport const getLayoutMapRowSeriesField = (table: unknown): string | undefined => {\n const field = (table as { internalProps?: { layoutMap?: PrivateLayoutMap } } | undefined)\n ?.internalProps?.layoutMap?.rowSeriesNumberColumn?.[0]?.field;\n return typeof field === 'string' && field !== '' ? field : undefined;\n};\n\nexport interface PrivateStickyPlugin {\n showedTitleRows?: readonly number[];\n titleRows?: readonly number[];\n}\n\nexport interface PrivateStickyShadowRoot {\n children?: unknown[];\n forEachChildren?: (callback: (child: unknown) => unknown) => void;\n}\n\nexport interface PrivateStickyScenegraph {\n colHeaderGroup?: { border?: { shadowRoot?: PrivateStickyShadowRoot } };\n cornerHeaderGroup?: { border?: { shadowRoot?: PrivateStickyShadowRoot } };\n}\n\n/**\n * 吸顶插件挂在 `scenegraph.plugins` 里,字段名取自 VTable 1.26.x 的\n * `plugins/list-tree-stick-cell.js`(`showedTitleRows` / `titleRows`)。这是**没有类型声明**\n * 的私有结构,全部走可选链:升版后失效会静默退回 VTable 写死的 40px 行高偏移,而不是报错。\n */\nexport const getStickyTitleRows = (table: unknown): readonly number[] | undefined => {\n const plugin = (table as { listTreeStickCellPlugin?: PrivateStickyPlugin } | undefined)\n ?.listTreeStickCellPlugin;\n return plugin?.showedTitleRows ?? plugin?.titleRows;\n};\n\nexport const getStickyShadowRoots = (table: unknown): PrivateStickyShadowRoot[] => {\n const scenegraph = (table as { scenegraph?: PrivateStickyScenegraph } | undefined)?.scenegraph;\n const roots = [\n scenegraph?.colHeaderGroup?.border?.shadowRoot,\n scenegraph?.cornerHeaderGroup?.border?.shadowRoot,\n ];\n return roots.filter(Boolean) as PrivateStickyShadowRoot[];\n};\n\nexport const getRowHeight = (table: unknown, row: number): number | undefined =>\n (table as { getRowHeight?: (index: number) => number | undefined } | undefined)?.getRowHeight?.(\n row,\n );\n\n/**\n * 引擎当前实际排布出来的总行高(含表头行,不含底部那 8px 的槽)。\n *\n * 折叠 / 展开之后**只有引擎知道现在有多少行**:树节点的 `hierarchyState` 引擎会写回记录,但\n * 分组标题行(`groupBy` 生成的那些)的折叠状态只存在引擎的分组结构里,`records` 上根本没有\n * —— 所以容器高度不能在那之后按数据重算,只能问引擎。\n */\nexport const getAllRowsHeight = (table: unknown): number | undefined => {\n const height = (\n table as { getAllRowsHeight?: () => number | undefined } | undefined\n )?.getAllRowsHeight?.();\n\n return typeof height === 'number' && Number.isFinite(height) && height > 0 ? height : undefined;\n};\n\nexport interface PrivateTableInternalProps {\n bodyHelper?: {\n getHierarchyIcon?: (col: number, row: number) => unknown;\n getHierarchyIconWidth?: () => number;\n };\n enableCheckboxCascade?: boolean;\n groupBy?: string | string[];\n layoutMap?: PrivateLayoutMap;\n}\n\nexport const getInternalProps = (table: unknown): PrivateTableInternalProps | undefined =>\n (table as { internalProps?: PrivateTableInternalProps } | undefined)?.internalProps;\n\n/**\n * VTable 把当前编辑态挂在 `editorManager` 上(d.ts 里是 `ListTableProtected`)。\n * 这些字段在 1.26.x 上核对过;升版后若 `release()` 与 `doExit()` 的语义变化,这里的\n * 读取会静默返回 undefined,表现为「编辑浮层不跟随」。\n */\nexport const getEditingEditor = (table: unknown): any =>\n (table as { editorManager?: { editingEditor?: unknown } } | undefined)?.editorManager\n ?.editingEditor;\n\nexport const getEditCell = (table: unknown): { col: number; row: number } | undefined =>\n (table as { editorManager?: { editCell?: { col: number; row: number } } } | undefined)\n ?.editorManager?.editCell;\n\nexport const getStateManager = (table: unknown): any =>\n (table as { stateManager?: any } | undefined)?.stateManager;\n\nexport const getDataSource = (table: unknown): any =>\n (table as { dataSource?: any } | undefined)?.dataSource;\n\nexport const getRecords = (table: unknown): unknown[] | undefined =>\n (table as { records?: unknown[] } | undefined)?.records;\n\nexport const getRecordIndexByCell = (table: unknown, col: number, row: number): unknown =>\n (\n table as { getRecordIndexByCell?: (col: number, row: number) => unknown } | undefined\n )?.getRecordIndexByCell?.(col, row);\n\nexport const getRecordShowIndexByCell = (\n table: unknown,\n col: number,\n row: number,\n): number | undefined =>\n (\n table as { getRecordShowIndexByCell?: (col: number, row: number) => number } | undefined\n )?.getRecordShowIndexByCell?.(col, row);\n\nexport const getIndexKey = (table: unknown, showIndex: number | undefined): unknown =>\n showIndex == null ? undefined : getDataSource(table)?.getIndexKey?.(showIndex);\n\nexport const getRecordIndexPaths = (table: unknown, showIndex: number | undefined): unknown =>\n showIndex == null ? undefined : getDataSource(table)?.getRecordIndexPaths?.(showIndex);\n\nexport const setCellCheckboxStateByRecordIndex = (\n table: unknown,\n path: unknown,\n field: string,\n checked: boolean,\n): void => {\n (\n table as {\n setCellCheckboxStateByRecordIndex?: (\n recordIndex: unknown,\n field: string,\n checked: boolean,\n ) => void;\n }\n )?.setCellCheckboxStateByRecordIndex?.(path, field, checked);\n};\n\nexport const fireTableEvent = (table: unknown, event: string, payload: unknown): void => {\n (\n table as { fireListeners?: (event: string, payload: unknown) => void } | undefined\n )?.fireListeners?.(event, payload);\n};\n\nexport const clearCheckboxState = (table: unknown, field: string): void => {\n (table as { clearCheckboxState?: (field: string) => void } | undefined)?.clearCheckboxState?.(\n field,\n );\n};\n\nexport const clearSelected = (table: unknown): void => {\n (table as { clearSelected?: () => void } | undefined)?.clearSelected?.();\n};\n\nexport const selectCells = (table: unknown, ranges: unknown[]): void => {\n (table as { selectCells?: (ranges: unknown[]) => void } | undefined)?.selectCells?.(ranges);\n};\n"],"mappings":";;AAUA,MAAa,iBAAiB,UAC5B,MAAM;;;;;;AAOR,MAAa,mBAAmB,UAC9B,SAAS,QAAQ,cAAc,KAA0B,KAAK;AAQhE,MAAa,0BACX,UAEC,MAAM,WAAqE;AAE9E,MAAa,mBAAmB,UAAmC;CACjE,cAAc,KAAK,CAAC,CAAC,kBAAkB;AACzC;AAEA,MAAa,qBAAqB,OAA0B,KAAa,QAAsB;CAC7F,cAAc,KAAK,CAAC,CAAC,oBAAoB,KAAK,GAAG;AACnD;AAEA,MAAa,0BACX,OACA,UACA,UACA,QACA,WACS;CACT,MASE,yBAAyB,UAAU,UAAU,QAAQ,MAAM;AAC/D;AAEA,MAAa,sBACX,OACA,UAAU,OAC+B;CACzC,MAAM,aAAa,cAAc,KAAK;CACtC,MAAM,aAAa,MAAM,0BAA0B;CACnD,MAAM,WAAW,KAAK,IAAI,YAAY,WAAW,OAAO,YAAY,UAAU;CAO9E,OAAO;EAAE,QANM,KAAK,IAClB,WAAW,OAAO,UAAU,WAAW,SACvC,WAAW,UACV,MAAM,YAAY,KAAK,CAGZ;EAAG;CAAS;AAC5B;AAOA,MAAa,+BAA+B,UACzC,OAA4E,eACzE,WAAW;;;;;;AAOjB,MAAa,8BAA8B,UAAuC;CAChF,MAAM,QAAS,OACX,eAAe,WAAW,wBAAwB,EAAE,EAAE;CAC1D,OAAO,OAAO,UAAU,YAAY,UAAU,KAAK,QAAQ,KAAA;AAC7D;;;;;;AAsBA,MAAa,sBAAsB,UAAkD;CACnF,MAAM,SAAU,OACZ;CACJ,OAAO,QAAQ,mBAAmB,QAAQ;AAC5C;AAEA,MAAa,wBAAwB,UAA8C;CACjF,MAAM,aAAc,OAAgE;CAKpF,OAAO,CAHL,YAAY,gBAAgB,QAAQ,YACpC,YAAY,mBAAmB,QAAQ,UAE9B,CAAC,CAAC,OAAO,OAAO;AAC7B;AAEA,MAAa,gBAAgB,OAAgB,QAC1C,OAAgF,eAC/E,GACF;;;;;;;;AASF,MAAa,oBAAoB,UAAuC;CACtE,MAAM,SACJ,OACC,mBAAmB;CAEtB,OAAO,OAAO,WAAW,YAAY,OAAO,SAAS,MAAM,KAAK,SAAS,IAAI,SAAS,KAAA;AACxF;AAYA,MAAa,oBAAoB,UAC9B,OAAqE;;;;;;AAOxE,MAAa,oBAAoB,UAC9B,OAAuE,eACpE;AAEN,MAAa,eAAe,UACzB,OACG,eAAe;AAErB,MAAa,mBAAmB,UAC7B,OAA8C;AAEjD,MAAa,iBAAiB,UAC3B,OAA4C;AAE/C,MAAa,cAAc,UACxB,OAA+C;AAElD,MAAa,wBAAwB,OAAgB,KAAa,QAE9D,OACC,uBAAuB,KAAK,GAAG;AAEpC,MAAa,4BACX,OACA,KACA,QAGE,OACC,2BAA2B,KAAK,GAAG;AAExC,MAAa,eAAe,OAAgB,cAC1C,aAAa,OAAO,KAAA,IAAY,cAAc,KAAK,CAAC,EAAE,cAAc,SAAS;AAK/E,MAAa,qCACX,OACA,MACA,OACA,YACS;CACT,OAQG,oCAAoC,MAAM,OAAO,OAAO;AAC7D;AAEA,MAAa,kBAAkB,OAAgB,OAAe,YAA2B;CACvF,OAEG,gBAAgB,OAAO,OAAO;AACnC;AAEA,MAAa,sBAAsB,OAAgB,UAAwB;CACzE,OAAyE,qBACvE,KACF;AACF;AAEA,MAAa,iBAAiB,UAAyB;CACrD,OAAuD,gBAAgB;AACzE;AAEA,MAAa,eAAe,OAAgB,WAA4B;CACtE,OAAsE,cAAc,MAAM;AAC5F"}
@@ -0,0 +1,5 @@
1
+ //#region src/ThemeProvider/AppElementContext.d.ts
2
+ declare const useAppElement: () => HTMLDivElement | null;
3
+ //#endregion
4
+ export { useAppElement };
5
+ //# sourceMappingURL=AppElementContext.d.mts.map
@@ -0,0 +1,10 @@
1
+ "use client";
2
+ import { createContext, use } from "react";
3
+ //#region src/ThemeProvider/AppElementContext.tsx
4
+ /** Portal 宿主元素(`data-superad-portal-host`)的上下文,弹层类组件据此定位挂载点。 */
5
+ const AppElementContext = createContext(null);
6
+ const useAppElement = () => use(AppElementContext);
7
+ //#endregion
8
+ export { AppElementContext as default, useAppElement };
9
+
10
+ //# sourceMappingURL=AppElementContext.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppElementContext.mjs","names":[],"sources":["../../src/ThemeProvider/AppElementContext.tsx"],"sourcesContent":["'use client';\n\nimport { createContext, use } from 'react';\n\n/** Portal 宿主元素(`data-superad-portal-host`)的上下文,弹层类组件据此定位挂载点。 */\nconst AppElementContext = createContext<HTMLDivElement | null>(null);\n\nexport const useAppElement = (): HTMLDivElement | null => use(AppElementContext);\n\nexport default AppElementContext;\n"],"mappings":";;;;AAKA,MAAM,oBAAoB,cAAqC,IAAI;AAEnE,MAAa,sBAA6C,IAAI,iBAAiB"}
@@ -0,0 +1,29 @@
1
+ "use client";
2
+ import { ConfigProvider } from "antd";
3
+ import { cssVar } from "antd-style";
4
+ import { jsx } from "react/jsx-runtime";
5
+ import { memo } from "react";
6
+ //#region src/ThemeProvider/ConfigProvider.tsx
7
+ /** 录入类组件统一锁定边框色:hover / focus 时不变色,保持发丝边框稳定。 */
8
+ const STEADY_BORDER_COMPONENTS = [
9
+ "DatePicker",
10
+ "Input",
11
+ "InputNumber",
12
+ "Mentions",
13
+ "Select"
14
+ ];
15
+ const steadyBorderTheme = {
16
+ activeBorderColor: cssVar.colorBorder,
17
+ hoverBorderColor: cssVar.colorBorder
18
+ };
19
+ const ConfigProvider$1 = memo(({ children }) => /* @__PURE__ */ jsx(ConfigProvider, {
20
+ theme: { components: {
21
+ ...Object.fromEntries(STEADY_BORDER_COMPONENTS.map((name) => [name, steadyBorderTheme])),
22
+ Button: { contentFontSizeSM: 12 }
23
+ } },
24
+ children
25
+ }));
26
+ //#endregion
27
+ export { ConfigProvider$1 as default };
28
+
29
+ //# sourceMappingURL=ConfigProvider.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfigProvider.mjs","names":["ConfigProvider","AntdConfigProvider"],"sources":["../../src/ThemeProvider/ConfigProvider.tsx"],"sourcesContent":["'use client';\n\nimport { ConfigProvider as AntdConfigProvider } from 'antd';\nimport { cssVar } from 'antd-style';\nimport { memo, type PropsWithChildren } from 'react';\n\n/** 录入类组件统一锁定边框色:hover / focus 时不变色,保持发丝边框稳定。 */\nconst STEADY_BORDER_COMPONENTS = ['DatePicker', 'Input', 'InputNumber', 'Mentions', 'Select'];\n\nconst steadyBorderTheme = {\n activeBorderColor: cssVar.colorBorder,\n hoverBorderColor: cssVar.colorBorder,\n};\n\nconst ConfigProvider = memo<PropsWithChildren>(({ children }) => (\n <AntdConfigProvider\n theme={{\n components: {\n ...Object.fromEntries(STEADY_BORDER_COMPONENTS.map((name) => [name, steadyBorderTheme])),\n Button: {\n contentFontSizeSM: 12,\n },\n },\n }}\n >\n {children}\n </AntdConfigProvider>\n));\n\nexport default ConfigProvider;\n"],"mappings":";;;;;;;AAOA,MAAM,2BAA2B;CAAC;CAAc;CAAS;CAAe;CAAY;AAAQ;AAE5F,MAAM,oBAAoB;CACxB,mBAAmB,OAAO;CAC1B,kBAAkB,OAAO;AAC3B;AAEA,MAAMA,mBAAiB,MAAyB,EAAE,eAChD,oBAACC,gBAAD;CACE,OAAO,EACL,YAAY;EACV,GAAG,OAAO,YAAY,yBAAyB,KAAK,SAAS,CAAC,MAAM,iBAAiB,CAAC,CAAC;EACvF,QAAQ,EACN,mBAAmB,GACrB;CACF,EACF;CAEC;AACiB,CAAA,CACrB"}