@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,181 @@
1
+ "use client";
2
+ import { toneFor } from "../core/tagTone.mjs";
3
+ import { getCanvasPalette } from "./canvasPalette.mjs";
4
+ import { isGroupTitleRecord, resolveOption } from "../core/cellValue.mjs";
5
+ import { fitLabel } from "./paintUtils.mjs";
6
+ import { getLayoutMapHierarchyIndent, getRowHeight, getStickyShadowRoots, getStickyTitleRows } from "../vtable/vtableAdapter.mjs";
7
+ import { CustomLayout } from "@visactor/vtable";
8
+ /** Resolve the level of a group title row, where `0` is the outermost group. */
9
+ const getGroupTitleLevel = (table, col, row) => Math.max(0, table?.getGroupTitleLevel?.(col, row) ?? 0);
10
+ /** Per-level indent used by VTable's built-in group titles. */
11
+ const getGroupTitleIndent = (table, level) => {
12
+ const indent = getLayoutMapHierarchyIndent(table);
13
+ return Math.max(0, level) * (typeof indent === "number" ? indent : 20);
14
+ };
15
+ /**
16
+ * VTable's sticky group-title plugin stacks sticky titles with a hard-coded 40px
17
+ * offset, which drifts from the real row height (SuperAd defaults to 36px) and
18
+ * leaves gaps between sticky groups. Compute offsets from the actual row heights
19
+ * so sticky titles line up with the header row and with the rows underneath.
20
+ */
21
+ const computeStickyTitleOffsets = (rows, getRowHeight) => {
22
+ const offsets = [];
23
+ let offset = 0;
24
+ rows.forEach((row) => {
25
+ offsets.push(offset);
26
+ offset += Math.max(0, getRowHeight(row) ?? 0);
27
+ });
28
+ return offsets;
29
+ };
30
+ /** 吸顶克隆节点自带的高度(vrender 的 `attribute.height`,即该行行高)。 */
31
+ const readCellHeight = (node) => {
32
+ const height = node?.attribute?.height;
33
+ return typeof height === "number" && height > 0 ? height : void 0;
34
+ };
35
+ /**
36
+ * 从吸顶克隆节点自身的高度推出整摞的 y 偏移。缺任何一个高度就返回 undefined ——
37
+ * 只把缺失的那个当 0 会让它后面的节点全叠在同一位置,比原来的漂移更难查。
38
+ */
39
+ const computeStickyOffsetsFromCells = (children) => {
40
+ const offsets = [];
41
+ let offset = 0;
42
+ for (const child of children) {
43
+ const height = readCellHeight(child);
44
+ if (height === void 0) return void 0;
45
+ offsets.push(offset);
46
+ offset += height;
47
+ }
48
+ return offsets;
49
+ };
50
+ /**
51
+ * VTable positions sticky group titles in a shadow group above the body, but uses
52
+ * a fixed 40px step (`y: 40 * i` in `plugins/list-tree-stick-cell.js`). Re-apply the
53
+ * offsets computed from real row heights so the sticky stack lines up with the header
54
+ * row and the body rows.
55
+ *
56
+ * Offsets come from the sticky clones' own heights: those nodes are already being
57
+ * walked here, and their height *is* the row height, so this needs no read of the
58
+ * plugin's private `showedTitleRows`. That field is only a fallback — if it ever
59
+ * stops matching (`titleRows` is a stack, so nested groups stick several rows), the
60
+ * geometry path keeps working instead of silently reverting to the 40px step.
61
+ */
62
+ const alignStickyGroupTitles = (table, background) => {
63
+ const roots = getStickyShadowRoots(table);
64
+ if (roots.length === 0) return;
65
+ const rowOffsets = (count) => {
66
+ const rows = getStickyTitleRows(table);
67
+ if (rows == null || rows.length === 0) return void 0;
68
+ const offsets = computeStickyTitleOffsets(rows, (row) => getRowHeight(table, row));
69
+ return offsets.length >= count ? offsets : void 0;
70
+ };
71
+ const childrenOf = (node) => {
72
+ if (Array.isArray(node?.children)) return node.children;
73
+ const children = [];
74
+ node?.forEachChildren?.((child) => {
75
+ children.push(child);
76
+ });
77
+ return children;
78
+ };
79
+ roots.forEach((root) => {
80
+ childrenOf(root).forEach((colGroup) => {
81
+ const children = childrenOf(colGroup);
82
+ const offsets = computeStickyOffsetsFromCells(children) ?? rowOffsets(children.length);
83
+ if (offsets == null) return;
84
+ children.forEach((child, index) => {
85
+ const offset = offsets[index];
86
+ if (offset == null) return;
87
+ const attrs = { y: offset };
88
+ if (background != null) attrs.fill = background;
89
+ child.setAttributes?.(attrs);
90
+ });
91
+ });
92
+ });
93
+ };
94
+ /** Pick the grouped column that belongs to the given group level. */
95
+ const getGroupByField = (groupBy, level) => {
96
+ const fields = Array.isArray(groupBy) ? groupBy : [groupBy];
97
+ return fields[level] ?? fields.at(-1) ?? "";
98
+ };
99
+ /** Count the leaf records under a group record (nested groups are traversed). */
100
+ const countGroupRecords = (record) => {
101
+ const children = record?.children;
102
+ if (Array.isArray(children) === false) return 0;
103
+ return children.reduce((total, child) => {
104
+ return total + (isGroupTitleRecord(child) ? countGroupRecords(child) : 1);
105
+ }, 0);
106
+ };
107
+ const createGroupTitleTagLayout = ({ colors, columns, groupBy }) => (args) => {
108
+ const palette = getCanvasPalette(args.table);
109
+ const table = args.table;
110
+ const row = args.row ?? 0;
111
+ const col = args.col ?? 0;
112
+ const width = args.rect?.width ?? 240;
113
+ const height = args.rect?.height ?? 40;
114
+ const record = table?.getCellOriginRecord?.(0, row);
115
+ const label = record?.vtableMergeName == null ? "" : String(record.vtableMergeName);
116
+ const level = getGroupTitleLevel(table, col, row);
117
+ const field = getGroupByField(groupBy, level);
118
+ const column = columns?.find((item) => item.field === field);
119
+ const option = resolveOption(record?.vtableMergeName, column?.options);
120
+ const isDark = palette.isDarkMode;
121
+ const tone = toneFor(option.value, option.color, isDark, palette.checkboxBg);
122
+ const customColor = colors?.[label];
123
+ const background = customColor ? toneFor(option.value, customColor, isDark, palette.checkboxBg).bg : tone.bg;
124
+ const count = countGroupRecords(record);
125
+ const suffix = count > 0 ? `共${count}个` : "";
126
+ const chipHeight = 24;
127
+ const chipTop = Math.max(0, (height - chipHeight) / 2);
128
+ const chipLeft = 26 + getGroupTitleIndent(table, level);
129
+ const estimate = (text) => text.length * 15 + 24;
130
+ const suffixWidth = suffix === "" ? 0 : estimate(suffix) + 8;
131
+ const available = Math.max(64, width - chipLeft - 26 - suffixWidth);
132
+ const fitted = fitLabel(label, available, estimate);
133
+ const chipWidth = Math.min(Math.max(64, estimate(fitted)), available);
134
+ const root = new CustomLayout.Group({
135
+ height,
136
+ pickable: false,
137
+ width
138
+ });
139
+ root.add(new CustomLayout.Rect({
140
+ cornerRadius: 6,
141
+ fill: background,
142
+ height: chipHeight,
143
+ lineWidth: tone.border ? 1 : 0,
144
+ pickable: false,
145
+ stroke: tone.border,
146
+ width: chipWidth,
147
+ x: chipLeft,
148
+ y: chipTop
149
+ }));
150
+ root.add(new CustomLayout.Text({
151
+ fontFamily: palette.fontFamily,
152
+ fill: isDark ? tone.color : palette.text,
153
+ fontSize: 13,
154
+ pickable: false,
155
+ text: fitted,
156
+ textAlign: "left",
157
+ textBaseline: "top",
158
+ x: chipLeft + 10,
159
+ y: chipTop + 4
160
+ }));
161
+ if (suffix !== "") root.add(new CustomLayout.Text({
162
+ fontFamily: palette.fontFamily,
163
+ fill: palette.textMuted,
164
+ fontSize: 12,
165
+ pickable: false,
166
+ text: suffix,
167
+ textAlign: "left",
168
+ textBaseline: "top",
169
+ x: chipLeft + chipWidth + 8,
170
+ y: chipTop + 5
171
+ }));
172
+ return {
173
+ enableCellPadding: false,
174
+ renderDefault: true,
175
+ rootContainer: root
176
+ };
177
+ };
178
+ //#endregion
179
+ export { alignStickyGroupTitles, computeStickyOffsetsFromCells, computeStickyTitleOffsets, countGroupRecords, createGroupTitleTagLayout, getGroupByField, getGroupTitleIndent, getGroupTitleLevel };
180
+
181
+ //# sourceMappingURL=groupTitle.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"groupTitle.mjs","names":[],"sources":["../../../src/Table/canvas/groupTitle.ts"],"sourcesContent":["'use client';\n\nimport { CustomLayout } from '@visactor/vtable';\nimport type { ICustomLayoutFuc } from '@visactor/vtable/es/ts-types/customLayout';\n\nimport { isGroupTitleRecord, resolveOption } from '../core/cellValue';\nimport { toneFor } from '../core/tagTone';\nimport type { TableSelectOption } from '../type';\nimport {\n getLayoutMapHierarchyIndent,\n getRowHeight,\n getStickyShadowRoots,\n getStickyTitleRows,\n} from '../vtable/vtableAdapter';\nimport { getCanvasPalette } from './canvasPalette';\nimport { fitLabel } from './paintUtils';\n\ntype GroupTitleTable = {\n getGroupTitleLevel?: (col: number, row: number) => number | undefined;\n internalProps?: { layoutMap?: { hierarchyIndent?: number } };\n};\n\n/** Horizontal inset before the group-title chip, after the collapse icon. */\nexport const GROUP_TITLE_CHIP_INSET = 26;\n\n/**\n * Fallback for VTable's own default hierarchy indent. Every indented surface should read the\n * live value through getLayoutMapHierarchyIndent and use this only when the layout map is\n * unavailable, so a custom `hierarchyIndent` cannot make them drift apart.\n * (See @visactor/vtable layout/simple-header-layout: `hierarchyIndent ?? 20`.)\n */\nexport const DEFAULT_HIERARCHY_INDENT = 20;\n\n/** Resolve the level of a group title row, where `0` is the outermost group. */\nexport const getGroupTitleLevel = (table: unknown, col: number, row: number): number =>\n Math.max(0, (table as GroupTitleTable | undefined)?.getGroupTitleLevel?.(col, row) ?? 0);\n\n/** Per-level indent used by VTable's built-in group titles. */\nexport const getGroupTitleIndent = (table: unknown, level: number): number => {\n const indent = getLayoutMapHierarchyIndent(table);\n return Math.max(0, level) * (typeof indent === 'number' ? indent : DEFAULT_HIERARCHY_INDENT);\n};\n\n/**\n * VTable's sticky group-title plugin stacks sticky titles with a hard-coded 40px\n * offset, which drifts from the real row height (SuperAd defaults to 36px) and\n * leaves gaps between sticky groups. Compute offsets from the actual row heights\n * so sticky titles line up with the header row and with the rows underneath.\n */\nexport const computeStickyTitleOffsets = (\n rows: readonly number[],\n getRowHeight: (row: number) => number | undefined,\n): number[] => {\n const offsets: number[] = [];\n let offset = 0;\n\n rows.forEach((row) => {\n offsets.push(offset);\n offset += Math.max(0, getRowHeight(row) ?? 0);\n });\n\n return offsets;\n};\n\n/** 吸顶克隆节点自带的高度(vrender 的 `attribute.height`,即该行行高)。 */\nconst readCellHeight = (node: unknown): number | undefined => {\n const height = (node as { attribute?: { height?: unknown } } | undefined)?.attribute?.height;\n return typeof height === 'number' && height > 0 ? height : undefined;\n};\n\n/**\n * 从吸顶克隆节点自身的高度推出整摞的 y 偏移。缺任何一个高度就返回 undefined ——\n * 只把缺失的那个当 0 会让它后面的节点全叠在同一位置,比原来的漂移更难查。\n */\nexport const computeStickyOffsetsFromCells = (\n children: readonly unknown[],\n): number[] | undefined => {\n const offsets: number[] = [];\n let offset = 0;\n\n for (const child of children) {\n const height = readCellHeight(child);\n if (height === undefined) return undefined;\n offsets.push(offset);\n offset += height;\n }\n\n return offsets;\n};\n\n/**\n * VTable positions sticky group titles in a shadow group above the body, but uses\n * a fixed 40px step (`y: 40 * i` in `plugins/list-tree-stick-cell.js`). Re-apply the\n * offsets computed from real row heights so the sticky stack lines up with the header\n * row and the body rows.\n *\n * Offsets come from the sticky clones' own heights: those nodes are already being\n * walked here, and their height *is* the row height, so this needs no read of the\n * plugin's private `showedTitleRows`. That field is only a fallback — if it ever\n * stops matching (`titleRows` is a stack, so nested groups stick several rows), the\n * geometry path keeps working instead of silently reverting to the 40px step.\n */\nexport const alignStickyGroupTitles = (table: any, background?: string): void => {\n const roots = getStickyShadowRoots(table);\n\n if (roots.length === 0) return;\n\n // 兜底:吸顶节点没带高度时,才回去读插件的行号 + 行高表。\n const rowOffsets = (count: number): number[] | undefined => {\n const rows = getStickyTitleRows(table);\n if (rows == null || rows.length === 0) return undefined;\n\n const offsets = computeStickyTitleOffsets(rows, (row) => getRowHeight(table, row));\n return offsets.length >= count ? offsets : undefined;\n };\n // vrender's forEachChildren stops when the callback returns a truthy value, so the\n // collector must never leak Array#push's return value.\n const childrenOf = (node: any): any[] => {\n if (Array.isArray(node?.children)) return node.children;\n\n const children: any[] = [];\n node?.forEachChildren?.((child: any) => {\n children.push(child);\n });\n return children;\n };\n\n roots.forEach((root) => {\n childrenOf(root).forEach((colGroup) => {\n const children = childrenOf(colGroup);\n const offsets = computeStickyOffsetsFromCells(children) ?? rowOffsets(children.length);\n\n if (offsets == null) return;\n\n children.forEach((child, index) => {\n const offset = offsets[index];\n if (offset == null) return;\n const attrs: { fill?: string; y: number } = { y: offset };\n // VTable re-creates merged group titles outside of their merge range, so the\n // background is lost and the sticky row looks transparent. Restore it here.\n if (background != null) attrs.fill = background;\n child.setAttributes?.(attrs);\n });\n });\n });\n};\n\n/** Pick the grouped column that belongs to the given group level. */\nexport const getGroupByField = (groupBy: string | string[], level: number): string => {\n const fields = Array.isArray(groupBy) ? groupBy : [groupBy];\n return fields[level] ?? fields.at(-1) ?? '';\n};\n\n/** Count the leaf records under a group record (nested groups are traversed). */\nexport const countGroupRecords = (record: unknown): number => {\n const children = (record as { children?: unknown[] } | undefined)?.children;\n if (Array.isArray(children) === false) return 0;\n\n return children.reduce<number>((total, child) => {\n return total + (isGroupTitleRecord(child) ? countGroupRecords(child) : 1);\n }, 0);\n};\n\nexport interface CreateGroupTitleTagLayoutOptions {\n colors?: Record<string, string | undefined>;\n columns?: ReadonlyArray<{ field?: unknown; options?: TableSelectOption[] }>;\n groupBy: string | string[];\n}\n\nexport const createGroupTitleTagLayout =\n ({ colors, columns, groupBy }: CreateGroupTitleTagLayoutOptions): ICustomLayoutFuc =>\n (args) => {\n const palette = getCanvasPalette(args.table);\n const table = args.table as any;\n const row = args.row ?? 0;\n const col = args.col ?? 0;\n const width = args.rect?.width ?? 240;\n const height = args.rect?.height ?? 40;\n const record = table?.getCellOriginRecord?.(0, row);\n const label = record?.vtableMergeName == null ? '' : String(record.vtableMergeName);\n const level = getGroupTitleLevel(table, col, row);\n const field = getGroupByField(groupBy, level);\n const column = columns?.find((item) => item.field === field);\n const option = resolveOption(record?.vtableMergeName, column?.options);\n const isDark = palette.isDarkMode;\n const tone = toneFor(option.value, option.color, isDark, palette.checkboxBg);\n const customColor = colors?.[label];\n // 自定义颜色也**吸附进 tone 调色板**再取浅底:直接拿它当背景会「颜色太重」(demo 的\n // stageColors 是中等浅色,普通 chip 的底是 95% 亮度的浅底),与其它标题观感不一致。\n const background = customColor\n ? toneFor(option.value, customColor, isDark, palette.checkboxBg).bg\n : tone.bg;\n // 样式与普通 chip 同口径:浅色用主题文字色、暗色用 tone 的提亮色;描边只在暗色 tone 给\n // `border` 时才有 —— 不再兜底 tone.color(那会画成彩色描边,和普通 chip 观感两套)。\n // 「共 N 个」画在 chip **外面**(N = 叶子记录数),是 chip 后的标注,不参与 chip 配色。\n const count = countGroupRecords(record);\n const suffix = count > 0 ? `共${count}个` : '';\n const chipHeight = 24;\n const chipTop = Math.max(0, (height - chipHeight) / 2);\n const chipLeft = GROUP_TITLE_CHIP_INSET + getGroupTitleIndent(table, level);\n // Deliberately not paintUtils.measureLabelWidth: that model is per-script (CJK at\n // fontSize, ASCII at 0.58x) and tuned for 20px tag chips, whereas a group title is a\n // taller 24px chip whose label is nearly always CJK. This per-character estimate stays\n // generous — it overshoots rather than clips — so do not \"fix\" it into the shared model.\n const estimate = (text: string): number => text.length * 15 + 24;\n // …但**「宁可超出」只对度量本身成立,不能让 chip 越过单元格**:窄表(表宽 − 序号列 ≈ 264)\n // 遇上长分组名时,chip 和标签一起顶出表格右缘被画布硬切,文字断在半个字上且没有省略号。\n // 按可用宽度收口(「共N个」标注也要占位),截断仍走各自的估算法(不切进共享模型)。\n const suffixWidth = suffix === '' ? 0 : estimate(suffix) + 8;\n const available = Math.max(64, width - chipLeft - GROUP_TITLE_CHIP_INSET - suffixWidth);\n const fitted = fitLabel(label, available, estimate);\n const chipWidth = Math.min(Math.max(64, estimate(fitted)), available);\n const root = new CustomLayout.Group({ height, pickable: false, width });\n\n root.add(\n new CustomLayout.Rect({\n cornerRadius: 6,\n fill: background,\n height: chipHeight,\n lineWidth: tone.border ? 1 : 0,\n pickable: false,\n stroke: tone.border,\n width: chipWidth,\n x: chipLeft,\n y: chipTop,\n }),\n );\n root.add(\n new CustomLayout.Text({\n fontFamily: palette.fontFamily,\n fill: isDark ? tone.color : palette.text,\n fontSize: 13,\n pickable: false,\n text: fitted,\n textAlign: 'left',\n textBaseline: 'top',\n x: chipLeft + 10,\n y: chipTop + 4,\n }),\n );\n\n if (suffix !== '') {\n root.add(\n new CustomLayout.Text({\n fontFamily: palette.fontFamily,\n fill: palette.textMuted,\n fontSize: 12,\n pickable: false,\n text: suffix,\n textAlign: 'left',\n textBaseline: 'top',\n x: chipLeft + chipWidth + 8,\n y: chipTop + 5,\n }),\n );\n }\n\n return {\n enableCellPadding: false,\n renderDefault: true,\n rootContainer: root,\n };\n };\n"],"mappings":";;;;;;;;AAkCA,MAAa,sBAAsB,OAAgB,KAAa,QAC9D,KAAK,IAAI,GAAI,OAAuC,qBAAqB,KAAK,GAAG,KAAK,CAAC;;AAGzF,MAAa,uBAAuB,OAAgB,UAA0B;CAC5E,MAAM,SAAS,4BAA4B,KAAK;CAChD,OAAO,KAAK,IAAI,GAAG,KAAK,KAAK,OAAO,WAAW,WAAW,SAAA;AAC5D;;;;;;;AAQA,MAAa,6BACX,MACA,iBACa;CACb,MAAM,UAAoB,CAAC;CAC3B,IAAI,SAAS;CAEb,KAAK,SAAS,QAAQ;EACpB,QAAQ,KAAK,MAAM;EACnB,UAAU,KAAK,IAAI,GAAG,aAAa,GAAG,KAAK,CAAC;CAC9C,CAAC;CAED,OAAO;AACT;;AAGA,MAAM,kBAAkB,SAAsC;CAC5D,MAAM,SAAU,MAA2D,WAAW;CACtF,OAAO,OAAO,WAAW,YAAY,SAAS,IAAI,SAAS,KAAA;AAC7D;;;;;AAMA,MAAa,iCACX,aACyB;CACzB,MAAM,UAAoB,CAAC;CAC3B,IAAI,SAAS;CAEb,KAAK,MAAM,SAAS,UAAU;EAC5B,MAAM,SAAS,eAAe,KAAK;EACnC,IAAI,WAAW,KAAA,GAAW,OAAO,KAAA;EACjC,QAAQ,KAAK,MAAM;EACnB,UAAU;CACZ;CAEA,OAAO;AACT;;;;;;;;;;;;;AAcA,MAAa,0BAA0B,OAAY,eAA8B;CAC/E,MAAM,QAAQ,qBAAqB,KAAK;CAExC,IAAI,MAAM,WAAW,GAAG;CAGxB,MAAM,cAAc,UAAwC;EAC1D,MAAM,OAAO,mBAAmB,KAAK;EACrC,IAAI,QAAQ,QAAQ,KAAK,WAAW,GAAG,OAAO,KAAA;EAE9C,MAAM,UAAU,0BAA0B,OAAO,QAAQ,aAAa,OAAO,GAAG,CAAC;EACjF,OAAO,QAAQ,UAAU,QAAQ,UAAU,KAAA;CAC7C;CAGA,MAAM,cAAc,SAAqB;EACvC,IAAI,MAAM,QAAQ,MAAM,QAAQ,GAAG,OAAO,KAAK;EAE/C,MAAM,WAAkB,CAAC;EACzB,MAAM,mBAAmB,UAAe;GACtC,SAAS,KAAK,KAAK;EACrB,CAAC;EACD,OAAO;CACT;CAEA,MAAM,SAAS,SAAS;EACtB,WAAW,IAAI,CAAC,CAAC,SAAS,aAAa;GACrC,MAAM,WAAW,WAAW,QAAQ;GACpC,MAAM,UAAU,8BAA8B,QAAQ,KAAK,WAAW,SAAS,MAAM;GAErF,IAAI,WAAW,MAAM;GAErB,SAAS,SAAS,OAAO,UAAU;IACjC,MAAM,SAAS,QAAQ;IACvB,IAAI,UAAU,MAAM;IACpB,MAAM,QAAsC,EAAE,GAAG,OAAO;IAGxD,IAAI,cAAc,MAAM,MAAM,OAAO;IACrC,MAAM,gBAAgB,KAAK;GAC7B,CAAC;EACH,CAAC;CACH,CAAC;AACH;;AAGA,MAAa,mBAAmB,SAA4B,UAA0B;CACpF,MAAM,SAAS,MAAM,QAAQ,OAAO,IAAI,UAAU,CAAC,OAAO;CAC1D,OAAO,OAAO,UAAU,OAAO,GAAG,EAAE,KAAK;AAC3C;;AAGA,MAAa,qBAAqB,WAA4B;CAC5D,MAAM,WAAY,QAAiD;CACnE,IAAI,MAAM,QAAQ,QAAQ,MAAM,OAAO,OAAO;CAE9C,OAAO,SAAS,QAAgB,OAAO,UAAU;EAC/C,OAAO,SAAS,mBAAmB,KAAK,IAAI,kBAAkB,KAAK,IAAI;CACzE,GAAG,CAAC;AACN;AAQA,MAAa,6BACV,EAAE,QAAQ,SAAS,eACnB,SAAS;CACR,MAAM,UAAU,iBAAiB,KAAK,KAAK;CAC3C,MAAM,QAAQ,KAAK;CACnB,MAAM,MAAM,KAAK,OAAO;CACxB,MAAM,MAAM,KAAK,OAAO;CACxB,MAAM,QAAQ,KAAK,MAAM,SAAS;CAClC,MAAM,SAAS,KAAK,MAAM,UAAU;CACpC,MAAM,SAAS,OAAO,sBAAsB,GAAG,GAAG;CAClD,MAAM,QAAQ,QAAQ,mBAAmB,OAAO,KAAK,OAAO,OAAO,eAAe;CAClF,MAAM,QAAQ,mBAAmB,OAAO,KAAK,GAAG;CAChD,MAAM,QAAQ,gBAAgB,SAAS,KAAK;CAC5C,MAAM,SAAS,SAAS,MAAM,SAAS,KAAK,UAAU,KAAK;CAC3D,MAAM,SAAS,cAAc,QAAQ,iBAAiB,QAAQ,OAAO;CACrE,MAAM,SAAS,QAAQ;CACvB,MAAM,OAAO,QAAQ,OAAO,OAAO,OAAO,OAAO,QAAQ,QAAQ,UAAU;CAC3E,MAAM,cAAc,SAAS;CAG7B,MAAM,aAAa,cACf,QAAQ,OAAO,OAAO,aAAa,QAAQ,QAAQ,UAAU,CAAC,CAAC,KAC/D,KAAK;CAIT,MAAM,QAAQ,kBAAkB,MAAM;CACtC,MAAM,SAAS,QAAQ,IAAI,IAAI,MAAM,KAAK;CAC1C,MAAM,aAAa;CACnB,MAAM,UAAU,KAAK,IAAI,IAAI,SAAS,cAAc,CAAC;CACrD,MAAM,WAAA,KAAoC,oBAAoB,OAAO,KAAK;CAK1E,MAAM,YAAY,SAAyB,KAAK,SAAS,KAAK;CAI9D,MAAM,cAAc,WAAW,KAAK,IAAI,SAAS,MAAM,IAAI;CAC3D,MAAM,YAAY,KAAK,IAAI,IAAI,QAAQ,WAAA,KAAoC,WAAW;CACtF,MAAM,SAAS,SAAS,OAAO,WAAW,QAAQ;CAClD,MAAM,YAAY,KAAK,IAAI,KAAK,IAAI,IAAI,SAAS,MAAM,CAAC,GAAG,SAAS;CACpE,MAAM,OAAO,IAAI,aAAa,MAAM;EAAE;EAAQ,UAAU;EAAO;CAAM,CAAC;CAEtE,KAAK,IACH,IAAI,aAAa,KAAK;EACpB,cAAc;EACd,MAAM;EACN,QAAQ;EACR,WAAW,KAAK,SAAS,IAAI;EAC7B,UAAU;EACV,QAAQ,KAAK;EACb,OAAO;EACP,GAAG;EACH,GAAG;CACL,CAAC,CACH;CACA,KAAK,IACH,IAAI,aAAa,KAAK;EACpB,YAAY,QAAQ;EACpB,MAAM,SAAS,KAAK,QAAQ,QAAQ;EACpC,UAAU;EACV,UAAU;EACV,MAAM;EACN,WAAW;EACX,cAAc;EACd,GAAG,WAAW;EACd,GAAG,UAAU;CACf,CAAC,CACH;CAEA,IAAI,WAAW,IACb,KAAK,IACH,IAAI,aAAa,KAAK;EACpB,YAAY,QAAQ;EACpB,MAAM,QAAQ;EACd,UAAU;EACV,UAAU;EACV,MAAM;EACN,WAAW;EACX,cAAc;EACd,GAAG,WAAW,YAAY;EAC1B,GAAG,UAAU;CACf,CAAC,CACH;CAGF,OAAO;EACL,mBAAmB;EACnB,eAAe;EACf,eAAe;CACjB;AACF"}
@@ -0,0 +1,70 @@
1
+ "use client";
2
+ /**
3
+ * 可编辑格要给右侧铅笔让出一条槽。画布与 DOM 悬停浮层共用;不可编辑 / 读不到列定义时为 0。
4
+ *
5
+ * 放在 paintUtils(而不是 chipPainters)是为了让 textPainters 也能用,且不跟 chipPainters
6
+ * 形成环(chipPainters → textPainters → …)。
7
+ */
8
+ const editHintGutterFor = (table, col, row) => {
9
+ if (table == null || col == null || row == null) return 0;
10
+ return (table.getBodyColumnDefine?.(col, row))?.superadEditable === true ? 28 : 0;
11
+ };
12
+ const measureLabelWidth = (label, fontSize = 12) => {
13
+ let width = 0;
14
+ for (const char of label) width += (char.codePointAt(0) ?? 0) > 255 ? fontSize : Math.round(fontSize * .58);
15
+ return width;
16
+ };
17
+ const measureTagWidth = (label) => 28 + measureLabelWidth(label, 13);
18
+ /** 「+N」徽标的宽度。 */
19
+ const measureOverflowBadgeWidth = (label) => 16 + measureLabelWidth(label, 13);
20
+ /** 数组 chip 的宽度。与 painter 的绘制、浮层的命中区共用一份。 */
21
+ const measureArrayChipWidth = (label) => 28 + measureLabelWidth(label, 13);
22
+ /** 链接 pill 的宽度。同上。 */
23
+ const measureLinkPillWidth = (label) => 28 + measureLabelWidth(label, 13);
24
+ const packItems = (widths, available, overflowWidth) => {
25
+ if (widths.length === 0) return {
26
+ overflow: 0,
27
+ visible: 0
28
+ };
29
+ let visible = 0;
30
+ let used = 0;
31
+ for (let index = 0; index < widths.length; index += 1) {
32
+ const rest = widths.length - index - 1;
33
+ const next = used + (visible > 0 ? 4 : 0) + (widths[index] ?? 0);
34
+ const reserved = rest > 0 ? 4 + overflowWidth(rest) : 0;
35
+ if (visible > 0 && next + reserved > available) break;
36
+ used = next;
37
+ visible += 1;
38
+ }
39
+ if (visible === 0) visible = 1;
40
+ return {
41
+ overflow: widths.length - visible,
42
+ visible
43
+ };
44
+ };
45
+ /**
46
+ * 把标签截到能放进 `maxWidth` 为止(末尾加省略号)。
47
+ *
48
+ * `packItems` 保证「至少画一个」—— 单个超长值因此会无上限越界,而自定义容器没有 clip,
49
+ * 会盖到相邻单元格上。`widthOf` 由调用方给,因为各 painter 的 chip 宽度模型不同
50
+ * (tag / user / link / array 各自不同)。
51
+ */
52
+ const fitLabel = (label, maxWidth, widthOf) => {
53
+ if (widthOf(label) <= maxWidth) return label;
54
+ const ellipsis = "…";
55
+ const chars = [...label];
56
+ let cut = chars.length;
57
+ while (cut > 1 && widthOf(`${chars.slice(0, cut).join("")}${ellipsis}`) > maxWidth) cut -= 1;
58
+ return `${chars.slice(0, cut).join("")}${ellipsis}`;
59
+ };
60
+ /**
61
+ * 「+N」徽标占的宽度(含它与前一枚 chip 之间的间距)。
62
+ *
63
+ * 四个 chip 布局的 `packItems` 只在**第二枚起**才把徽标算进预算,于是「首枚 chip 就被截断」
64
+ * 的那种值会把徽标顶出单元格 —— 自定义容器没有 clip,出格就是盖住邻格。截断首枚时先减掉它。
65
+ */
66
+ const overflowBadgeWidth = (overflow) => overflow > 0 ? 4 + measureLabelWidth(`+${overflow}`, 13) : 0;
67
+ //#endregion
68
+ export { editHintGutterFor, fitLabel, measureArrayChipWidth, measureLabelWidth, measureLinkPillWidth, measureOverflowBadgeWidth, measureTagWidth, overflowBadgeWidth, packItems };
69
+
70
+ //# sourceMappingURL=paintUtils.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paintUtils.mjs","names":[],"sources":["../../../src/Table/canvas/paintUtils.ts"],"sourcesContent":["'use client';\n\nexport const TAG_GAP = 4;\n/**\n * 悬停时盖在 chip 右端的移除按钮占位(12px 按钮 + 1px 外边距)。\n *\n * 它是 chip 内边距的**下界**,不是内边距之外另加的一截:外加会让未悬停时右侧空一块、文字\n * 视觉偏左;反过来把内边距收到它以下,× 就压在最后一个字上(× 底透明、笔画近黑,叠在深色\n * 字上等于没画)。人员 chip 自己一套,见 `USER_CHIP_TRAILING`。\n */\nexport const CHIP_REMOVE_ROOM = 13;\n/**\n * chip 文字的水平内边距。**左右相同**,且比 `CHIP_REMOVE_ROOM` 多 1px —— × 整颗落在右内边距\n * 里,笔画(10px 图标里 8px 墨迹居中)与文字之间还剩 3px。\n */\nexport const CHIP_PAD = CHIP_REMOVE_ROOM + 1;\n/** 标签文字左侧的内边距。 */\nexport const TAG_PAD_LEFT = CHIP_PAD;\n/** 标签文字右侧的内边距。与左侧对称。 */\nexport const TAG_PAD_RIGHT = CHIP_PAD;\n/**\n * chip 的水平内边距合计。度量 / 打包 / 截断都按它算。\n *\n * demo 标签列 176(可用 160,减去铅笔槽 28 后 132):2 字 chip = 26 + 28 = 54;\n * `54 + 4 + 徽标 35 = 93 ≤ 132`,第二枚要 `2×54 + 4 + 35 = 143 > 132` 放不下。\n */\nexport const TAG_PAD_X = TAG_PAD_LEFT + TAG_PAD_RIGHT;\n/**\n * 「+N」徽标的水平内边距。徽标上没有 ×,因此不受 `CHIP_REMOVE_ROOM` 下界约束,用更紧的一档 ——\n * 它是计数标注,撑到跟 chip 一样宽会抢走本来能多放一枚 chip 的位置。\n */\nexport const BADGE_PAD_X = 16;\n/** 数组 chip 的左右内边距。 */\nexport const ARRAY_PAD_LEFT = CHIP_PAD;\nexport const ARRAY_PAD_RIGHT = CHIP_PAD;\n/** 链接 pill 的左右内边距。 */\nexport const LINK_PAD_LEFT = CHIP_PAD;\nexport const LINK_PAD_RIGHT = CHIP_PAD;\n/**\n * 可编辑格右侧留给铅笔按钮的槽(24 按钮 + 4 内边距)。\n *\n * 画布打包与 hover 浮层**必须共用**这个值,否则铅笔会盖在最后一枚 chip / 文字上。\n */\nexport const EDIT_HINT_GUTTER = 28;\n\n/**\n * 可编辑格要给右侧铅笔让出一条槽。画布与 DOM 悬停浮层共用;不可编辑 / 读不到列定义时为 0。\n *\n * 放在 paintUtils(而不是 chipPainters)是为了让 textPainters 也能用,且不跟 chipPainters\n * 形成环(chipPainters → textPainters → …)。\n */\nexport const editHintGutterFor = (\n table: { getBodyColumnDefine?: (col: number, row: number) => unknown } | undefined,\n col: number | undefined,\n row: number | undefined,\n): number => {\n if (table == null || col == null || row == null) return 0;\n const define = table.getBodyColumnDefine?.(col, row) as { superadEditable?: boolean } | undefined;\n return define?.superadEditable === true ? EDIT_HINT_GUTTER : 0;\n};\n/**\n * tag chip 的文字字号。**度量与渲染必须用同一个值**:度量走默认的 12、渲染写 13 时,\n * `8 + 13n > 16 + 12n` 在 n > 8 就成立 —— ≥9 个全角字符的标签文字会伸出胶囊压到邻格上\n * (chip 间距只有 4)。\n */\nexport const TAG_FONT_SIZE = 13;\n\nexport const measureLabelWidth = (label: string, fontSize = 12): number => {\n let width = 0;\n for (const char of label) {\n width += (char.codePointAt(0) ?? 0) > 255 ? fontSize : Math.round(fontSize * 0.58);\n }\n return width;\n};\n\nexport const measureTagWidth = (label: string): number =>\n TAG_PAD_X + measureLabelWidth(label, TAG_FONT_SIZE);\n\n/** 「+N」徽标的宽度。 */\nexport const measureOverflowBadgeWidth = (label: string): number =>\n BADGE_PAD_X + measureLabelWidth(label, TAG_FONT_SIZE);\n\n/** 数组 chip 的宽度。与 painter 的绘制、浮层的命中区共用一份。 */\nexport const measureArrayChipWidth = (label: string): number =>\n ARRAY_PAD_LEFT + ARRAY_PAD_RIGHT + measureLabelWidth(label, TAG_FONT_SIZE);\n\n/** 链接 pill 的宽度。同上。 */\nexport const measureLinkPillWidth = (label: string): number =>\n LINK_PAD_LEFT + LINK_PAD_RIGHT + measureLabelWidth(label, TAG_FONT_SIZE);\n\nexport const packItems = (\n widths: number[],\n available: number,\n overflowWidth: (rest: number) => number,\n): { overflow: number; visible: number } => {\n if (widths.length === 0) return { overflow: 0, visible: 0 };\n\n let visible = 0;\n let used = 0;\n for (let index = 0; index < widths.length; index += 1) {\n const rest = widths.length - index - 1;\n const next = used + (visible > 0 ? TAG_GAP : 0) + (widths[index] ?? 0);\n const reserved = rest > 0 ? TAG_GAP + overflowWidth(rest) : 0;\n if (visible > 0 && next + reserved > available) break;\n used = next;\n visible += 1;\n }\n\n if (visible === 0) visible = 1;\n return { overflow: widths.length - visible, visible };\n};\n\n/**\n * 把标签截到能放进 `maxWidth` 为止(末尾加省略号)。\n *\n * `packItems` 保证「至少画一个」—— 单个超长值因此会无上限越界,而自定义容器没有 clip,\n * 会盖到相邻单元格上。`widthOf` 由调用方给,因为各 painter 的 chip 宽度模型不同\n * (tag / user / link / array 各自不同)。\n */\nexport const fitLabel = (\n label: string,\n maxWidth: number,\n widthOf: (label: string) => number,\n): string => {\n if (widthOf(label) <= maxWidth) return label;\n\n const ellipsis = '…';\n // **按码点退格,不是按 UTF-16 码元。** `'😀'.length` 是 2:按码元切会切出孤立代理项,\n // 画布上是一个替换字形(tofu)加省略号,而且 `measureLabelWidth` 会把它当宽字符多算一格。\n const chars = [...label];\n let cut = chars.length;\n while (cut > 1 && widthOf(`${chars.slice(0, cut).join('')}${ellipsis}`) > maxWidth) {\n cut -= 1;\n }\n return `${chars.slice(0, cut).join('')}${ellipsis}`;\n};\n\n/**\n * 「+N」徽标占的宽度(含它与前一枚 chip 之间的间距)。\n *\n * 四个 chip 布局的 `packItems` 只在**第二枚起**才把徽标算进预算,于是「首枚 chip 就被截断」\n * 的那种值会把徽标顶出单元格 —— 自定义容器没有 clip,出格就是盖住邻格。截断首枚时先减掉它。\n */\nexport const overflowBadgeWidth = (overflow: number): number =>\n overflow > 0 ? TAG_GAP + measureLabelWidth(`+${overflow}`, TAG_FONT_SIZE) : 0;\n"],"mappings":";;;;;;;AAmDA,MAAa,qBACX,OACA,KACA,QACW;CACX,IAAI,SAAS,QAAQ,OAAO,QAAQ,OAAO,MAAM,OAAO;CAExD,QADe,MAAM,sBAAsB,KAAK,GAAG,EAAA,EACpC,oBAAoB,OAAA,KAA0B;AAC/D;AAQA,MAAa,qBAAqB,OAAe,WAAW,OAAe;CACzE,IAAI,QAAQ;CACZ,KAAK,MAAM,QAAQ,OACjB,UAAU,KAAK,YAAY,CAAC,KAAK,KAAK,MAAM,WAAW,KAAK,MAAM,WAAW,GAAI;CAEnF,OAAO;AACT;AAEA,MAAa,mBAAmB,UAAA,KAClB,kBAAkB,OAAA,EAAoB;;AAGpD,MAAa,6BAA6B,UAAA,KAC1B,kBAAkB,OAAA,EAAoB;;AAGtD,MAAa,yBAAyB,UACpC,KAAmC,kBAAkB,OAAA,EAAoB;;AAG3E,MAAa,wBAAwB,UACnC,KAAiC,kBAAkB,OAAA,EAAoB;AAEzE,MAAa,aACX,QACA,WACA,kBAC0C;CAC1C,IAAI,OAAO,WAAW,GAAG,OAAO;EAAE,UAAU;EAAG,SAAS;CAAE;CAE1D,IAAI,UAAU;CACd,IAAI,OAAO;CACX,KAAK,IAAI,QAAQ,GAAG,QAAQ,OAAO,QAAQ,SAAS,GAAG;EACrD,MAAM,OAAO,OAAO,SAAS,QAAQ;EACrC,MAAM,OAAO,QAAQ,UAAU,IAAA,IAAc,MAAM,OAAO,UAAU;EACpE,MAAM,WAAW,OAAO,IAAA,IAAc,cAAc,IAAI,IAAI;EAC5D,IAAI,UAAU,KAAK,OAAO,WAAW,WAAW;EAChD,OAAO;EACP,WAAW;CACb;CAEA,IAAI,YAAY,GAAG,UAAU;CAC7B,OAAO;EAAE,UAAU,OAAO,SAAS;EAAS;CAAQ;AACtD;;;;;;;;AASA,MAAa,YACX,OACA,UACA,YACW;CACX,IAAI,QAAQ,KAAK,KAAK,UAAU,OAAO;CAEvC,MAAM,WAAW;CAGjB,MAAM,QAAQ,CAAC,GAAG,KAAK;CACvB,IAAI,MAAM,MAAM;CAChB,OAAO,MAAM,KAAK,QAAQ,GAAG,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,EAAE,IAAI,UAAU,IAAI,UACxE,OAAO;CAET,OAAO,GAAG,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,EAAE,IAAI;AAC3C;;;;;;;AAQA,MAAa,sBAAsB,aACjC,WAAW,IAAA,IAAc,kBAAkB,IAAI,YAAA,EAAyB,IAAI"}
@@ -0,0 +1,130 @@
1
+ "use client";
2
+ import { getCanvasPalette } from "./canvasPalette.mjs";
3
+ import { getInternalProps, getScenegraph, getStateManager, getVisibleRowRange, updateCellContent, updateCellContentRange } from "../vtable/vtableAdapter.mjs";
4
+ import { getCascadeRowSelection, isFullRowSelected } from "../core/rowSelection.mjs";
5
+ import { getCascadeHeaderState, getRowCheckboxState, isGroupTitleRow, resolveRowSeriesValue } from "../vtable/seriesSelection.mjs";
6
+ import { drawSeriesCheckbox } from "./controlPainters.mjs";
7
+ import { CustomLayout } from "@visactor/vtable";
8
+ const seriesContentX = (width, showDrag) => showDrag ? 16 + (width - 16) / 2 : width / 2;
9
+ const createRowSeriesLayout = (showIndex = true, showSelection = true, showDrag = false) => (args) => {
10
+ const palette = getCanvasPalette(args.table);
11
+ const width = args.rect?.width ?? 56;
12
+ const height = args.rect?.height ?? 40;
13
+ const table = args.table;
14
+ const row = args.row ?? 0;
15
+ const root = new CustomLayout.Group({
16
+ height,
17
+ pickable: false,
18
+ width
19
+ });
20
+ const groupTitleRow = isGroupTitleRow(table, row);
21
+ const endCol = (table?.colCount ?? 1) - 1;
22
+ const ranges = getStateManager(table)?.select?.ranges ?? [];
23
+ const cascadeSelection = Boolean(getInternalProps(table)?.enableCheckboxCascade);
24
+ const recordState = cascadeSelection ? getRowCheckboxState(table, row) : void 0;
25
+ const rangeChecked = isFullRowSelected(ranges, row, endCol);
26
+ const checked = cascadeSelection ? recordState === true : rangeChecked;
27
+ let indeterminate;
28
+ if (cascadeSelection) indeterminate = recordState === "indeterminate";
29
+ else {
30
+ const cascade = getCascadeRowSelection(table, row, ranges, endCol);
31
+ indeterminate = cascade ? cascade.selectedCount > 0 && cascade.selectedCount < cascade.total : false;
32
+ }
33
+ const hovered = getStateManager(table)?.hover?.cellPos?.row === row;
34
+ const showIndexValue = showIndex && groupTitleRow === false;
35
+ const showCheckbox = showSelection && (showIndex === false || hovered || checked || indeterminate);
36
+ const centerX = seriesContentX(width, showDrag);
37
+ const centerY = height / 2;
38
+ if (showCheckbox) drawSeriesCheckbox(root, centerX, centerY, 16, checked, indeterminate, palette);
39
+ else if (showIndexValue) root.add(new CustomLayout.Text({
40
+ fontFamily: palette.fontFamily,
41
+ fill: palette.text,
42
+ fontSize: 14,
43
+ pickable: false,
44
+ text: String(resolveRowSeriesValue(table, row)),
45
+ textAlign: "center",
46
+ textBaseline: "middle",
47
+ x: centerX,
48
+ y: centerY
49
+ }));
50
+ return {
51
+ enableCellPadding: false,
52
+ renderDefault: showDrag,
53
+ rootContainer: root
54
+ };
55
+ };
56
+ const createRowSeriesHeaderLayout = (showIndex = false, showDrag = false) => (args) => {
57
+ const palette = getCanvasPalette(args.table);
58
+ const width = args.rect?.width ?? 56;
59
+ const height = args.rect?.height ?? 40;
60
+ const table = args.table;
61
+ const row = args.row ?? 0;
62
+ const root = new CustomLayout.Group({
63
+ height,
64
+ pickable: false,
65
+ width
66
+ });
67
+ const startRow = table?.columnHeaderLevelCount ?? 1;
68
+ const endRow = (table?.rowCount ?? 1) - 1;
69
+ const endCol = (table?.colCount ?? 1) - 1;
70
+ const ranges = getStateManager(table)?.select?.ranges ?? [];
71
+ const cascadeSelection = Boolean(getInternalProps(table)?.enableCheckboxCascade);
72
+ let selectedCount = 0;
73
+ if (cascadeSelection === false) {
74
+ for (let cursor = startRow; cursor <= endRow; cursor += 1) if (isFullRowSelected(ranges, cursor, endCol)) selectedCount += 1;
75
+ }
76
+ const total = endRow - startRow + 1;
77
+ const cascadeState = cascadeSelection ? getCascadeHeaderState(table) : void 0;
78
+ const checked = cascadeSelection ? cascadeState === true : total > 0 && selectedCount === total;
79
+ const partiallySelected = cascadeSelection ? cascadeState === "indeterminate" : selectedCount > 0 && checked === false;
80
+ const hovered = getStateManager(table)?.hover?.cellPos?.row === row;
81
+ const hoverScope = getStateManager(table)?.hover?.highlightScope ?? "row";
82
+ const hoverCol = getStateManager(table)?.hover?.cellPos?.col;
83
+ if (hovered && (hoverScope === "row" || hoverScope === "cross" || (hoverScope === "single" || hoverScope === "column") && hoverCol === 0)) root.add(new CustomLayout.Rect({
84
+ fill: palette.rowHover,
85
+ height,
86
+ pickable: false,
87
+ width,
88
+ x: 0,
89
+ y: 0
90
+ }));
91
+ const centerX = seriesContentX(width, showDrag);
92
+ const centerY = Math.min(height, table?.getRowHeight?.(row) ?? height) / 2;
93
+ if (showIndex && hovered === false && (checked || partiallySelected) === false) root.add(new CustomLayout.Text({
94
+ fontFamily: palette.fontFamily,
95
+ fill: palette.textAux,
96
+ fontSize: 13,
97
+ fontWeight: 500,
98
+ pickable: false,
99
+ text: "序号",
100
+ textAlign: "center",
101
+ textBaseline: "middle",
102
+ x: centerX,
103
+ y: centerY
104
+ }));
105
+ else drawSeriesCheckbox(root, centerX, centerY, 16, checked, partiallySelected, palette);
106
+ return {
107
+ enableCellPadding: false,
108
+ renderDefault: false,
109
+ rootContainer: root
110
+ };
111
+ };
112
+ /** Re-render the canvas row-series cells of the visible range. */
113
+ const refreshVisibleRowSeriesCells = (table) => {
114
+ const { endRow, startRow } = getVisibleRowRange(table);
115
+ updateCellContent(table, 0, 0);
116
+ if (endRow < startRow) return;
117
+ updateCellContentRange(table, 0, startRow, 0, endRow);
118
+ getScenegraph(table).updateNextFrame?.();
119
+ };
120
+ /** Re-render the previously and newly hovered row-series cells. */
121
+ const refreshRowSeriesHover = (table, previous, nextRow) => {
122
+ if (previous === nextRow) return;
123
+ if (previous != null && previous >= 0) updateCellContent(table, 0, previous);
124
+ if (nextRow >= 0) updateCellContent(table, 0, nextRow);
125
+ getScenegraph(table).updateNextFrame?.();
126
+ };
127
+ //#endregion
128
+ export { createRowSeriesHeaderLayout, createRowSeriesLayout, refreshRowSeriesHover, refreshVisibleRowSeriesCells };
129
+
130
+ //# sourceMappingURL=rowSeries.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rowSeries.mjs","names":[],"sources":["../../../src/Table/canvas/rowSeries.ts"],"sourcesContent":["'use client';\n\nimport { CustomLayout, type ListTable } from '@visactor/vtable';\nimport type { ICustomLayoutFuc } from '@visactor/vtable/es/ts-types/customLayout';\n\nimport { getCascadeRowSelection, isFullRowSelected } from '../core/rowSelection';\nimport {\n getCascadeHeaderState,\n getRowCheckboxState,\n isGroupTitleRow,\n resolveRowSeriesValue,\n} from '../vtable/seriesSelection';\nimport {\n getInternalProps,\n getScenegraph,\n getStateManager,\n getVisibleRowRange,\n updateCellContent,\n updateCellContentRange,\n} from '../vtable/vtableAdapter';\nimport { getCanvasPalette } from './canvasPalette';\nimport { drawSeriesCheckbox } from './controlPainters';\n\n/** VTable `dragReorder` 图标占的左槽。序号 / 复选框画在右边,避免盖住原生手柄。 */\nexport const SERIES_DRAG_SLOT = 16;\n\nconst seriesContentX = (width: number, showDrag: boolean) =>\n showDrag ? SERIES_DRAG_SLOT + (width - SERIES_DRAG_SLOT) / 2 : width / 2;\n\nexport const createRowSeriesLayout =\n (showIndex = true, showSelection = true, showDrag = false): ICustomLayoutFuc =>\n (args) => {\n const palette = getCanvasPalette(args.table);\n const width = args.rect?.width ?? 56;\n const height = args.rect?.height ?? 40;\n const table = args.table as any;\n const row = args.row ?? 0;\n const root = new CustomLayout.Group({ height, pickable: false, width });\n const groupTitleRow = isGroupTitleRow(table, row);\n const endCol = (table?.colCount ?? 1) - 1;\n const ranges = getStateManager(table)?.select?.ranges ?? [];\n const cascadeSelection = Boolean(getInternalProps(table)?.enableCheckboxCascade);\n const recordState = cascadeSelection ? getRowCheckboxState(table, row) : undefined;\n const rangeChecked = isFullRowSelected(ranges, row, endCol);\n const checked = cascadeSelection ? recordState === true : rangeChecked;\n // 级联模式(`createTableOption` 里恒为 `?? true`)下这个分支根本不会被读到,而\n // `getCascadeRowSelection` 是一次 O(行数) 的全表遍历(按 ranges 内容缓存),所以**惰性求值**:\n // 无条件算等于每张分组/树表在每次 ranges 变化后都白跑一次。平铺表上它会早退,\n // 百万行性能基线因此看不见这项开销。\n let indeterminate: boolean;\n if (cascadeSelection) {\n indeterminate = recordState === 'indeterminate';\n } else {\n const cascade = getCascadeRowSelection(table, row, ranges, endCol);\n indeterminate = cascade\n ? cascade.selectedCount > 0 && cascade.selectedCount < cascade.total\n : false;\n }\n const hovered = getStateManager(table)?.hover?.cellPos?.row === row;\n // Do not paint a hover background for body rows. VTable already styles them: this\n // column's body cells classify as row-header cells and take theme.rowHeaderStyle.hover.\n // Adding a translucent rowHover rect on top stacked a second layer and made this one\n // cell visibly darker — rgb(239,239,239) against rgb(247,247,247) for the rest of the\n // row. The header cell is the exception; see createRowSeriesHeaderLayout.\n\n const showIndexValue = showIndex && groupTitleRow === false;\n // 序号模式下**分组行平时什么也不画**(没有行号可显示,也不常驻一个空复选框 —— 那样整列\n // 看起来全是待选框,而数据行平时显示的是行号),鼠标移到这一行才出现。数据行同理:平时\n // 是行号,hover / 已选 / 半选时换成复选框。不显示序号列时这一列本来只有复选框,常驻。\n const showCheckbox =\n showSelection && (showIndex === false || hovered || checked || indeterminate);\n const centerX = seriesContentX(width, showDrag);\n const centerY = height / 2;\n\n if (showCheckbox) {\n drawSeriesCheckbox(root, centerX, centerY, 16, checked, indeterminate, palette);\n } else if (showIndexValue) {\n root.add(\n new CustomLayout.Text({\n fontFamily: palette.fontFamily,\n // 用 `text` 而不是 `textMuted`:序号列此前比同行的数据文字浅一大截\n // (亮色 #999999 对白底 2.85:1、暗色 #6f6f6f 对 #0d0d0d 3.92:1,都不足 AA)。\n // 数据列走 `createCanvasTextLayout` 的 `fill: palette.text`,这里与它保持一致。\n fill: palette.text,\n // 与 `option.ts` 里这一列的 `style.fontSize` 一致;painter 接管单元格后 VTable 的样式\n // 不再生效,两边写不一样就会让序号比同行的数据文字小一号。\n fontSize: 14,\n pickable: false,\n text: String(resolveRowSeriesValue(table, row)),\n textAlign: 'center',\n textBaseline: 'middle',\n x: centerX,\n y: centerY,\n } as never),\n );\n }\n\n // 行拖拽时 `renderDefault: true`:VTable 只在默认渲染里画 `dragOrder` 手柄。\n // 我们自己画序号 / 复选框,`format` 交空串,避免和默认文字叠两套数字。\n return { enableCellPadding: false, renderDefault: showDrag, rootContainer: root };\n };\n\nexport const createRowSeriesHeaderLayout =\n (showIndex = false, showDrag = false): ICustomLayoutFuc =>\n (args) => {\n const palette = getCanvasPalette(args.table);\n const width = args.rect?.width ?? 56;\n const height = args.rect?.height ?? 40;\n const table = args.table as any;\n const row = args.row ?? 0;\n const root = new CustomLayout.Group({ height, pickable: false, width });\n const startRow = table?.columnHeaderLevelCount ?? 1;\n const endRow = (table?.rowCount ?? 1) - 1;\n const endCol = (table?.colCount ?? 1) - 1;\n const ranges = getStateManager(table)?.select?.ranges ?? [];\n const cascadeSelection = Boolean(getInternalProps(table)?.enableCheckboxCascade);\n let selectedCount = 0;\n\n if (cascadeSelection === false) {\n for (let cursor = startRow; cursor <= endRow; cursor += 1) {\n if (isFullRowSelected(ranges, cursor, endCol)) selectedCount += 1;\n }\n }\n\n const total = endRow - startRow + 1;\n const cascadeState = cascadeSelection ? getCascadeHeaderState(table) : undefined;\n const checked = cascadeSelection ? cascadeState === true : total > 0 && selectedCount === total;\n const partiallySelected = cascadeSelection\n ? cascadeState === 'indeterminate'\n : selectedCount > 0 && checked === false;\n const hovered = getStateManager(table)?.hover?.cellPos?.row === row;\n const hoverScope = getStateManager(table)?.hover?.highlightScope ?? 'row';\n const hoverCol = getStateManager(table)?.hover?.cellPos?.col;\n const hoverCoversRow = hoverScope === 'row' || hoverScope === 'cross';\n const hoverCoversSeriesCell =\n (hoverScope === 'single' || hoverScope === 'column') && hoverCol === 0;\n\n // This painter has to draw the hover background itself, unlike the body layout.\n // VTable picks a hover style by cell kind (@visactor/vtable state/hover/is-cell-hover.js):\n // corner header, column header, row header, frozen rows/columns, then a final\n // `isHeader(col, row) || (hoverStyle = theme.bodyStyle.hover)` branch. That `||`\n // short-circuits, so any cell that is a header but matched none of the earlier kinds\n // ends up with hoverStyle undefined and gets no hover at all. This cell is that case:\n // no theme hook reaches it — theme.rowHeaderStyle.hover, theme.cornerHeaderStyle.hover\n // and this column's own headerStyle.hover were each tested and none of them tint it.\n if (hovered && (hoverCoversRow || hoverCoversSeriesCell)) {\n root.add(\n new CustomLayout.Rect({\n fill: palette.rowHover,\n height,\n pickable: false,\n width,\n x: 0,\n y: 0,\n } as never),\n );\n }\n\n const centerX = seriesContentX(width, showDrag);\n // **不能按 `rect.height` 居中。** 表头是多级时这一格是**跨行合并**的(百万数据 demo 的\n // `full name` 分组让表头变成两行,行号列因此合并 0–1 行):`rect.height` 是合并后的\n // 72,而引擎给每一行各建一个 36 高的节点、各跑一次这个 layout。居中的 16px 框正好落在\n // 两行的接缝上 —— 上半截留在第一行的节点里,下半截被第二行盖掉,看上去就是个空框。\n // 按本行高度居中,框始终完整落在自己那一行内;单级表头两值相等,行为不变。\n const centerY = Math.min(height, table?.getRowHeight?.(row) ?? height) / 2;\n const showIndexValue =\n showIndex && hovered === false && (checked || partiallySelected) === false;\n\n if (showIndexValue) {\n root.add(\n new CustomLayout.Text({\n fontFamily: palette.fontFamily,\n fill: palette.textAux,\n fontSize: 13,\n // `option.ts` 的 `headerStyle.fontWeight` 是 500;painter 接管后要自己带上,\n // 否则表头「序号」比同行的其他表头文字细。\n fontWeight: 500,\n pickable: false,\n text: '序号',\n textAlign: 'center',\n textBaseline: 'middle',\n x: centerX,\n y: centerY,\n } as never),\n );\n } else {\n drawSeriesCheckbox(root, centerX, centerY, 16, checked, partiallySelected, palette);\n }\n\n return { enableCellPadding: false, renderDefault: false, rootContainer: root };\n };\n\n/** Re-render the canvas row-series cells of the visible range. */\nexport const refreshVisibleRowSeriesCells = (table: ListTable): void => {\n const { endRow, startRow } = getVisibleRowRange(table);\n\n updateCellContent(table, 0, 0);\n if (endRow < startRow) return;\n updateCellContentRange(table, 0, startRow, 0, endRow);\n getScenegraph(table).updateNextFrame?.();\n};\n\n/** Re-render the previously and newly hovered row-series cells. */\nexport const refreshRowSeriesHover = (\n table: ListTable,\n previous: number | null,\n nextRow: number,\n): void => {\n if (previous === nextRow) return;\n\n if (previous != null && previous >= 0) updateCellContent(table, 0, previous);\n if (nextRow >= 0) updateCellContent(table, 0, nextRow);\n getScenegraph(table).updateNextFrame?.();\n};\n"],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ "use client";
2
+ import { getCanvasPalette } from "./canvasPalette.mjs";
3
+ import { emptyCellLabel, formatCurrency } from "../core/cellValue.mjs";
4
+ import { editHintGutterFor } from "./paintUtils.mjs";
5
+ import { tableText } from "../core/tableI18n.mjs";
6
+ import { CustomLayout } from "@visactor/vtable";
7
+ //#region src/Table/canvas/textPainters.ts
8
+ /**
9
+ * Empty-state placeholder text ("设置 X"). Every painter that can show a hint draws
10
+ * the same node, so it lives here rather than being repeated per cell type.
11
+ */
12
+ const createEmptyCellText = (placeholder, palette, height, table) => new CustomLayout.Text({
13
+ fontFamily: palette.fontFamily,
14
+ fill: palette.textMuted,
15
+ fontSize: 14,
16
+ pickable: false,
17
+ text: table != null ? tableText(table, placeholder ? "setField" : "set", { title: placeholder }) : emptyCellLabel(placeholder),
18
+ textAlign: "left",
19
+ textBaseline: "middle",
20
+ x: palette.paddingX,
21
+ y: height / 2
22
+ });
23
+ const createCanvasTextLayout = (options = {}) => (args) => {
24
+ const palette = getCanvasPalette(args.table);
25
+ const width = args.rect?.width ?? 120;
26
+ const height = args.rect?.height ?? 40;
27
+ const align = options.align ?? "left";
28
+ const root = new CustomLayout.Group({
29
+ height,
30
+ pickable: false,
31
+ width
32
+ });
33
+ const text = args.value == null ? "" : String(args.value);
34
+ const gutter = editHintGutterFor(args.table, args.col, args.row);
35
+ const contentWidth = Math.max(width - gutter, 1);
36
+ if (text) {
37
+ const paddingX = palette.paddingX;
38
+ const x = align === "center" ? contentWidth / 2 : align === "right" ? contentWidth - paddingX : paddingX;
39
+ root.add(new CustomLayout.Text({
40
+ fontFamily: palette.fontFamily,
41
+ ellipsis: true,
42
+ fill: options.color ?? palette.text,
43
+ fontSize: options.fontSize ?? 14,
44
+ fontWeight: options.fontWeight,
45
+ maxLineWidth: Math.max(0, contentWidth - paddingX * 2),
46
+ pickable: false,
47
+ text,
48
+ textAlign: align,
49
+ textBaseline: "middle",
50
+ x,
51
+ y: height / 2
52
+ }));
53
+ }
54
+ return {
55
+ enableCellPadding: false,
56
+ renderDefault: false,
57
+ rootContainer: root
58
+ };
59
+ };
60
+ const createCurrencyLayout = (currency = "¥", placeholder) => (args) => {
61
+ const palette = getCanvasPalette(args.table);
62
+ const width = args.rect?.width ?? 100;
63
+ const height = args.rect?.height ?? 40;
64
+ const text = formatCurrency(args.value, currency);
65
+ const empty = text === "";
66
+ const root = new CustomLayout.Group({
67
+ height,
68
+ pickable: false,
69
+ width
70
+ });
71
+ const gutter = editHintGutterFor(args.table, args.col, args.row);
72
+ const contentWidth = Math.max(width - gutter, 1);
73
+ if (empty) {
74
+ if (placeholder) root.add(createEmptyCellText(placeholder, palette, height, args.table));
75
+ } else root.add(new CustomLayout.Text({
76
+ fontFamily: palette.fontFamily,
77
+ ellipsis: true,
78
+ fill: palette.text,
79
+ fontSize: 13,
80
+ maxLineWidth: Math.max(0, contentWidth - palette.paddingX * 2),
81
+ pickable: false,
82
+ text,
83
+ textAlign: "right",
84
+ textBaseline: "middle",
85
+ x: contentWidth - palette.paddingX,
86
+ y: height / 2
87
+ }));
88
+ return {
89
+ enableCellPadding: false,
90
+ renderDefault: false,
91
+ rootContainer: root
92
+ };
93
+ };
94
+ //#endregion
95
+ export { createCanvasTextLayout, createCurrencyLayout, createEmptyCellText };
96
+
97
+ //# sourceMappingURL=textPainters.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"textPainters.mjs","names":[],"sources":["../../../src/Table/canvas/textPainters.ts"],"sourcesContent":["'use client';\n\nimport { CustomLayout } from '@visactor/vtable';\nimport type { ICustomLayoutFuc } from '@visactor/vtable/es/ts-types/customLayout';\n\nimport { emptyCellLabel, formatCurrency } from '../core/cellValue';\nimport { tableText } from '../core/tableI18n';\nimport { type CanvasPalette, getCanvasPalette } from './canvasPalette';\nimport { editHintGutterFor } from './paintUtils';\n\nexport interface CreateCanvasTextLayoutOptions {\n align?: 'center' | 'left' | 'right';\n color?: string;\n fontSize?: number;\n fontWeight?: number | string;\n}\n\n/**\n * Empty-state placeholder text (\"设置 X\"). Every painter that can show a hint draws\n * the same node, so it lives here rather than being repeated per cell type.\n */\nexport const createEmptyCellText = (\n placeholder: string,\n palette: CanvasPalette,\n height: number,\n table?: unknown,\n) =>\n new CustomLayout.Text({\n fontFamily: palette.fontFamily,\n // 占位文字统一**弱色 + 与正文同字号**:空值占位有两条路径(这条 canvas 的,与 text /\n // number / date 那些交回 VTable 原生渲染、用列样式的),两边的字号必须一样,否则同一张表里\n // 「设置 名称」和「设置 状态」大小不一。颜色则两边都走弱色 —— 见 columns.ts 的 style。\n fill: palette.textMuted,\n fontSize: 14,\n pickable: false,\n text:\n table != null\n ? tableText(table, placeholder ? 'setField' : 'set', { title: placeholder })\n : emptyCellLabel(placeholder),\n textAlign: 'left',\n textBaseline: 'middle',\n x: palette.paddingX,\n y: height / 2,\n } as never);\n\nexport const createCanvasTextLayout =\n (options: CreateCanvasTextLayoutOptions = {}): ICustomLayoutFuc =>\n (args) => {\n const palette = getCanvasPalette(args.table);\n const width = args.rect?.width ?? 120;\n const height = args.rect?.height ?? 40;\n const align = options.align ?? 'left';\n const root = new CustomLayout.Group({ height, pickable: false, width });\n const text = args.value == null ? '' : String(args.value);\n const gutter = editHintGutterFor(args.table as never, args.col, args.row);\n const contentWidth = Math.max(width - gutter, 1);\n\n if (text) {\n const paddingX = palette.paddingX;\n const x =\n align === 'center'\n ? contentWidth / 2\n : align === 'right'\n ? contentWidth - paddingX\n : paddingX;\n\n root.add(\n new CustomLayout.Text({\n fontFamily: palette.fontFamily,\n ellipsis: true,\n fill: options.color ?? palette.text,\n fontSize: options.fontSize ?? 14,\n fontWeight: options.fontWeight,\n maxLineWidth: Math.max(0, contentWidth - paddingX * 2),\n pickable: false,\n text,\n textAlign: align,\n textBaseline: 'middle',\n x,\n y: height / 2,\n } as never),\n );\n }\n\n return { enableCellPadding: false, renderDefault: false, rootContainer: root };\n };\n\nexport const createCurrencyLayout =\n (currency = '¥', placeholder?: string): ICustomLayoutFuc =>\n (args) => {\n const palette = getCanvasPalette(args.table);\n const width = args.rect?.width ?? 100;\n const height = args.rect?.height ?? 40;\n // 判空交给格式化函数。painter 里再判一次 `Number.isFinite` 会让 `formatCurrency` 的\n // 「非有限数原样显示」分支永远到不了 —— 同一种脏数据(如 `待定`),`number` 列显示原文、\n // `currency` 列显示占位符。两种类型的口径必须一致。\n const text = formatCurrency(args.value, currency);\n const empty = text === '';\n const root = new CustomLayout.Group({ height, pickable: false, width });\n const gutter = editHintGutterFor(args.table as never, args.col, args.row);\n const contentWidth = Math.max(width - gutter, 1);\n\n if (empty) {\n if (placeholder) {\n root.add(createEmptyCellText(placeholder, palette, height, args.table));\n }\n } else {\n root.add(\n new CustomLayout.Text({\n fontFamily: palette.fontFamily,\n // `createCanvasTextLayout` 早就有这两个(右对齐的长金额不加限制会往左压进前一列)。\n ellipsis: true,\n fill: palette.text,\n fontSize: 13,\n maxLineWidth: Math.max(0, contentWidth - palette.paddingX * 2),\n pickable: false,\n text,\n textAlign: 'right',\n textBaseline: 'middle',\n x: contentWidth - palette.paddingX,\n y: height / 2,\n } as never),\n );\n }\n\n return { enableCellPadding: false, renderDefault: false, rootContainer: root };\n };\n"],"mappings":";;;;;;;;;;;AAqBA,MAAa,uBACX,aACA,SACA,QACA,UAEA,IAAI,aAAa,KAAK;CACpB,YAAY,QAAQ;CAIpB,MAAM,QAAQ;CACd,UAAU;CACV,UAAU;CACV,MACE,SAAS,OACL,UAAU,OAAO,cAAc,aAAa,OAAO,EAAE,OAAO,YAAY,CAAC,IACzE,eAAe,WAAW;CAChC,WAAW;CACX,cAAc;CACd,GAAG,QAAQ;CACX,GAAG,SAAS;AACd,CAAU;AAEZ,MAAa,0BACV,UAAyC,CAAC,OAC1C,SAAS;CACR,MAAM,UAAU,iBAAiB,KAAK,KAAK;CAC3C,MAAM,QAAQ,KAAK,MAAM,SAAS;CAClC,MAAM,SAAS,KAAK,MAAM,UAAU;CACpC,MAAM,QAAQ,QAAQ,SAAS;CAC/B,MAAM,OAAO,IAAI,aAAa,MAAM;EAAE;EAAQ,UAAU;EAAO;CAAM,CAAC;CACtE,MAAM,OAAO,KAAK,SAAS,OAAO,KAAK,OAAO,KAAK,KAAK;CACxD,MAAM,SAAS,kBAAkB,KAAK,OAAgB,KAAK,KAAK,KAAK,GAAG;CACxE,MAAM,eAAe,KAAK,IAAI,QAAQ,QAAQ,CAAC;CAE/C,IAAI,MAAM;EACR,MAAM,WAAW,QAAQ;EACzB,MAAM,IACJ,UAAU,WACN,eAAe,IACf,UAAU,UACR,eAAe,WACf;EAER,KAAK,IACH,IAAI,aAAa,KAAK;GACpB,YAAY,QAAQ;GACpB,UAAU;GACV,MAAM,QAAQ,SAAS,QAAQ;GAC/B,UAAU,QAAQ,YAAY;GAC9B,YAAY,QAAQ;GACpB,cAAc,KAAK,IAAI,GAAG,eAAe,WAAW,CAAC;GACrD,UAAU;GACV;GACA,WAAW;GACX,cAAc;GACd;GACA,GAAG,SAAS;EACd,CAAU,CACZ;CACF;CAEA,OAAO;EAAE,mBAAmB;EAAO,eAAe;EAAO,eAAe;CAAK;AAC/E;AAEF,MAAa,wBACV,WAAW,KAAK,iBAChB,SAAS;CACR,MAAM,UAAU,iBAAiB,KAAK,KAAK;CAC3C,MAAM,QAAQ,KAAK,MAAM,SAAS;CAClC,MAAM,SAAS,KAAK,MAAM,UAAU;CAIpC,MAAM,OAAO,eAAe,KAAK,OAAO,QAAQ;CAChD,MAAM,QAAQ,SAAS;CACvB,MAAM,OAAO,IAAI,aAAa,MAAM;EAAE;EAAQ,UAAU;EAAO;CAAM,CAAC;CACtE,MAAM,SAAS,kBAAkB,KAAK,OAAgB,KAAK,KAAK,KAAK,GAAG;CACxE,MAAM,eAAe,KAAK,IAAI,QAAQ,QAAQ,CAAC;CAE/C,IAAI,OACE;MAAA,aACF,KAAK,IAAI,oBAAoB,aAAa,SAAS,QAAQ,KAAK,KAAK,CAAC;CAAA,OAGxE,KAAK,IACH,IAAI,aAAa,KAAK;EACpB,YAAY,QAAQ;EAEpB,UAAU;EACV,MAAM,QAAQ;EACd,UAAU;EACV,cAAc,KAAK,IAAI,GAAG,eAAe,QAAQ,WAAW,CAAC;EAC7D,UAAU;EACV;EACA,WAAW;EACX,cAAc;EACd,GAAG,eAAe,QAAQ;EAC1B,GAAG,SAAS;CACd,CAAU,CACZ;CAGF,OAAO;EAAE,mBAAmB;EAAO,eAAe;EAAO,eAAe;CAAK;AAC/E"}
@@ -0,0 +1,14 @@
1
+ import { TableTheme } from "../type.mjs";
2
+ import { Theme } from "antd-style";
3
+ //#region src/Table/canvas/theme.d.ts
4
+ type TableToken = Pick<Theme, 'colorBgContainer' | 'colorBorderSecondary' | 'colorFillQuaternary' | 'colorFillSecondary' | 'colorFillTertiary' | 'colorInfo' | 'colorPrimary' | 'colorSplit' | 'colorSuccess' | 'colorText' | 'colorTextQuaternary' | 'colorTextSecondary' | 'colorTextTertiary' | 'fontFamily'> & {
5
+ isDarkMode?: boolean;
6
+ };
7
+ interface CreateTableThemeOptions {
8
+ /** Show vertical borders between columns. The row index column never gets one. */
9
+ showVerticalBorder?: boolean;
10
+ }
11
+ declare const createTableTheme: (token: TableToken, { showVerticalBorder }?: CreateTableThemeOptions) => TableTheme;
12
+ //#endregion
13
+ export { CreateTableThemeOptions, TableToken, createTableTheme };
14
+ //# sourceMappingURL=theme.d.mts.map