@chenzy-design/svelte 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (974) hide show
  1. package/README.md +66 -0
  2. package/dist/badge/Badge.svelte +5 -2
  3. package/dist/badge/Badge.svelte.d.ts.map +1 -1
  4. package/dist/components.json +1 -1
  5. package/package.json +9 -9
  6. package/dist/anchor/Anchor.a11y.test.d.ts +0 -2
  7. package/dist/anchor/Anchor.a11y.test.d.ts.map +0 -1
  8. package/dist/anchor/Anchor.a11y.test.js +0 -44
  9. package/dist/anchor/Anchor.kbd.test.d.ts +0 -2
  10. package/dist/anchor/Anchor.kbd.test.d.ts.map +0 -1
  11. package/dist/anchor/Anchor.kbd.test.js +0 -59
  12. package/dist/anchor/AnchorKbdFixture.svelte +0 -24
  13. package/dist/anchor/AnchorKbdFixture.svelte.d.ts +0 -19
  14. package/dist/anchor/AnchorKbdFixture.svelte.d.ts.map +0 -1
  15. package/dist/autocomplete/AutoComplete.a11y.test.d.ts +0 -2
  16. package/dist/autocomplete/AutoComplete.a11y.test.d.ts.map +0 -1
  17. package/dist/autocomplete/AutoComplete.a11y.test.js +0 -45
  18. package/dist/autocomplete/AutoComplete.kbd.test.d.ts +0 -2
  19. package/dist/autocomplete/AutoComplete.kbd.test.d.ts.map +0 -1
  20. package/dist/autocomplete/AutoComplete.kbd.test.js +0 -60
  21. package/dist/autocomplete/AutoCompleteKbdFixture.svelte +0 -24
  22. package/dist/autocomplete/AutoCompleteKbdFixture.svelte.d.ts +0 -4
  23. package/dist/autocomplete/AutoCompleteKbdFixture.svelte.d.ts.map +0 -1
  24. package/dist/avatar/Avatar.a11y.test.d.ts +0 -2
  25. package/dist/avatar/Avatar.a11y.test.d.ts.map +0 -1
  26. package/dist/avatar/Avatar.a11y.test.js +0 -34
  27. package/dist/back-top/BackTop.a11y.test.d.ts +0 -2
  28. package/dist/back-top/BackTop.a11y.test.d.ts.map +0 -1
  29. package/dist/back-top/BackTop.a11y.test.js +0 -37
  30. package/dist/badge/Badge.a11y.test.d.ts +0 -2
  31. package/dist/badge/Badge.a11y.test.d.ts.map +0 -1
  32. package/dist/badge/Badge.a11y.test.js +0 -32
  33. package/dist/badge/BadgeA11yFixture.svelte +0 -18
  34. package/dist/badge/BadgeA11yFixture.svelte.d.ts +0 -7
  35. package/dist/badge/BadgeA11yFixture.svelte.d.ts.map +0 -1
  36. package/dist/banner/Banner.a11y.test.d.ts +0 -2
  37. package/dist/banner/Banner.a11y.test.d.ts.map +0 -1
  38. package/dist/banner/Banner.a11y.test.js +0 -43
  39. package/dist/breadcrumb/Breadcrumb.a11y.test.d.ts +0 -2
  40. package/dist/breadcrumb/Breadcrumb.a11y.test.d.ts.map +0 -1
  41. package/dist/breadcrumb/Breadcrumb.a11y.test.js +0 -31
  42. package/dist/breadcrumb/Breadcrumb.kbd.test.d.ts +0 -2
  43. package/dist/breadcrumb/Breadcrumb.kbd.test.d.ts.map +0 -1
  44. package/dist/breadcrumb/Breadcrumb.kbd.test.js +0 -37
  45. package/dist/breadcrumb/BreadcrumbKbdFixture.svelte +0 -23
  46. package/dist/breadcrumb/BreadcrumbKbdFixture.svelte.d.ts +0 -19
  47. package/dist/breadcrumb/BreadcrumbKbdFixture.svelte.d.ts.map +0 -1
  48. package/dist/button/Button.a11y.test.d.ts +0 -2
  49. package/dist/button/Button.a11y.test.d.ts.map +0 -1
  50. package/dist/button/Button.a11y.test.js +0 -49
  51. package/dist/calendar/Calendar.a11y.test.d.ts +0 -2
  52. package/dist/calendar/Calendar.a11y.test.d.ts.map +0 -1
  53. package/dist/calendar/Calendar.a11y.test.js +0 -46
  54. package/dist/calendar/Calendar.kbd.test.d.ts +0 -2
  55. package/dist/calendar/Calendar.kbd.test.d.ts.map +0 -1
  56. package/dist/calendar/Calendar.kbd.test.js +0 -50
  57. package/dist/calendar/CalendarKbdFixture.svelte +0 -23
  58. package/dist/calendar/CalendarKbdFixture.svelte.d.ts +0 -19
  59. package/dist/calendar/CalendarKbdFixture.svelte.d.ts.map +0 -1
  60. package/dist/card/Card.a11y.test.d.ts +0 -2
  61. package/dist/card/Card.a11y.test.d.ts.map +0 -1
  62. package/dist/card/Card.a11y.test.js +0 -35
  63. package/dist/carousel/Carousel.a11y.test.d.ts +0 -2
  64. package/dist/carousel/Carousel.a11y.test.d.ts.map +0 -1
  65. package/dist/carousel/Carousel.a11y.test.js +0 -43
  66. package/dist/carousel/Carousel.kbd.test.d.ts +0 -2
  67. package/dist/carousel/Carousel.kbd.test.d.ts.map +0 -1
  68. package/dist/carousel/Carousel.kbd.test.js +0 -51
  69. package/dist/carousel/CarouselA11yFixture.svelte +0 -25
  70. package/dist/carousel/CarouselA11yFixture.svelte.d.ts +0 -8
  71. package/dist/carousel/CarouselA11yFixture.svelte.d.ts.map +0 -1
  72. package/dist/carousel/CarouselKbdFixture.svelte +0 -24
  73. package/dist/carousel/CarouselKbdFixture.svelte.d.ts +0 -19
  74. package/dist/carousel/CarouselKbdFixture.svelte.d.ts.map +0 -1
  75. package/dist/cascader/Cascader.a11y.test.d.ts +0 -2
  76. package/dist/cascader/Cascader.a11y.test.d.ts.map +0 -1
  77. package/dist/cascader/Cascader.a11y.test.js +0 -55
  78. package/dist/cascader/Cascader.kbd.test.d.ts +0 -2
  79. package/dist/cascader/Cascader.kbd.test.d.ts.map +0 -1
  80. package/dist/cascader/Cascader.kbd.test.js +0 -47
  81. package/dist/cascader/CascaderKbdFixture.svelte +0 -31
  82. package/dist/cascader/CascaderKbdFixture.svelte.d.ts +0 -19
  83. package/dist/cascader/CascaderKbdFixture.svelte.d.ts.map +0 -1
  84. package/dist/checkbox/CheckboxGroup.a11y.test.d.ts +0 -2
  85. package/dist/checkbox/CheckboxGroup.a11y.test.d.ts.map +0 -1
  86. package/dist/checkbox/CheckboxGroup.a11y.test.js +0 -38
  87. package/dist/checkbox/CheckboxGroup.kbd.test.d.ts +0 -2
  88. package/dist/checkbox/CheckboxGroup.kbd.test.d.ts.map +0 -1
  89. package/dist/checkbox/CheckboxGroup.kbd.test.js +0 -33
  90. package/dist/checkbox/CheckboxGroupKbdFixture.svelte +0 -20
  91. package/dist/checkbox/CheckboxGroupKbdFixture.svelte.d.ts +0 -19
  92. package/dist/checkbox/CheckboxGroupKbdFixture.svelte.d.ts.map +0 -1
  93. package/dist/collapse/Collapse.a11y.test.d.ts +0 -2
  94. package/dist/collapse/Collapse.a11y.test.d.ts.map +0 -1
  95. package/dist/collapse/Collapse.a11y.test.js +0 -46
  96. package/dist/collapse/Collapse.kbd.test.d.ts +0 -2
  97. package/dist/collapse/Collapse.kbd.test.d.ts.map +0 -1
  98. package/dist/collapse/Collapse.kbd.test.js +0 -70
  99. package/dist/collapse/CollapseA11yFixture.svelte +0 -27
  100. package/dist/collapse/CollapseA11yFixture.svelte.d.ts +0 -9
  101. package/dist/collapse/CollapseA11yFixture.svelte.d.ts.map +0 -1
  102. package/dist/collapse/CollapseKbdFixture.svelte +0 -25
  103. package/dist/collapse/CollapseKbdFixture.svelte.d.ts +0 -19
  104. package/dist/collapse/CollapseKbdFixture.svelte.d.ts.map +0 -1
  105. package/dist/color-picker/ColorPicker.a11y.test.d.ts +0 -2
  106. package/dist/color-picker/ColorPicker.a11y.test.d.ts.map +0 -1
  107. package/dist/color-picker/ColorPicker.a11y.test.js +0 -54
  108. package/dist/color-picker/ColorPicker.kbd.test.d.ts +0 -2
  109. package/dist/color-picker/ColorPicker.kbd.test.d.ts.map +0 -1
  110. package/dist/color-picker/ColorPicker.kbd.test.js +0 -59
  111. package/dist/color-picker/ColorPickerKbdFixture.svelte +0 -25
  112. package/dist/color-picker/ColorPickerKbdFixture.svelte.d.ts +0 -4
  113. package/dist/color-picker/ColorPickerKbdFixture.svelte.d.ts.map +0 -1
  114. package/dist/date-picker/DatePicker.a11y.test.d.ts +0 -2
  115. package/dist/date-picker/DatePicker.a11y.test.d.ts.map +0 -1
  116. package/dist/date-picker/DatePicker.a11y.test.js +0 -42
  117. package/dist/date-picker/DatePicker.kbd.test.d.ts +0 -2
  118. package/dist/date-picker/DatePicker.kbd.test.d.ts.map +0 -1
  119. package/dist/date-picker/DatePicker.kbd.test.js +0 -59
  120. package/dist/date-picker/DatePickerKbdFixture.svelte +0 -26
  121. package/dist/date-picker/DatePickerKbdFixture.svelte.d.ts +0 -4
  122. package/dist/date-picker/DatePickerKbdFixture.svelte.d.ts.map +0 -1
  123. package/dist/date-picker/RangePicker.kbd.test.d.ts +0 -2
  124. package/dist/date-picker/RangePicker.kbd.test.d.ts.map +0 -1
  125. package/dist/date-picker/RangePicker.kbd.test.js +0 -60
  126. package/dist/date-picker/RangePickerKbdFixture.svelte +0 -30
  127. package/dist/date-picker/RangePickerKbdFixture.svelte.d.ts +0 -7
  128. package/dist/date-picker/RangePickerKbdFixture.svelte.d.ts.map +0 -1
  129. package/dist/descriptions/Descriptions.a11y.test.d.ts +0 -2
  130. package/dist/descriptions/Descriptions.a11y.test.d.ts.map +0 -1
  131. package/dist/descriptions/Descriptions.a11y.test.js +0 -31
  132. package/dist/divider/Divider.a11y.test.d.ts +0 -2
  133. package/dist/divider/Divider.a11y.test.d.ts.map +0 -1
  134. package/dist/divider/Divider.a11y.test.js +0 -21
  135. package/dist/drawer/Drawer.a11y.test.d.ts +0 -2
  136. package/dist/drawer/Drawer.a11y.test.d.ts.map +0 -1
  137. package/dist/drawer/Drawer.a11y.test.js +0 -33
  138. package/dist/drawer/Drawer.kbd.test.d.ts +0 -2
  139. package/dist/drawer/Drawer.kbd.test.d.ts.map +0 -1
  140. package/dist/drawer/Drawer.kbd.test.js +0 -53
  141. package/dist/drawer/DrawerKbdFixture.svelte +0 -28
  142. package/dist/drawer/DrawerKbdFixture.svelte.d.ts +0 -4
  143. package/dist/drawer/DrawerKbdFixture.svelte.d.ts.map +0 -1
  144. package/dist/dropdown/Dropdown.a11y.test.d.ts +0 -2
  145. package/dist/dropdown/Dropdown.a11y.test.d.ts.map +0 -1
  146. package/dist/dropdown/Dropdown.a11y.test.js +0 -39
  147. package/dist/dropdown/Dropdown.kbd.test.d.ts +0 -2
  148. package/dist/dropdown/Dropdown.kbd.test.d.ts.map +0 -1
  149. package/dist/dropdown/Dropdown.kbd.test.js +0 -47
  150. package/dist/dropdown/DropdownA11yFixture.svelte +0 -24
  151. package/dist/dropdown/DropdownA11yFixture.svelte.d.ts +0 -11
  152. package/dist/dropdown/DropdownA11yFixture.svelte.d.ts.map +0 -1
  153. package/dist/dropdown/DropdownKbdFixture.svelte +0 -26
  154. package/dist/dropdown/DropdownKbdFixture.svelte.d.ts +0 -19
  155. package/dist/dropdown/DropdownKbdFixture.svelte.d.ts.map +0 -1
  156. package/dist/dropdown/types.test.d.ts +0 -2
  157. package/dist/dropdown/types.test.d.ts.map +0 -1
  158. package/dist/dropdown/types.test.js +0 -40
  159. package/dist/empty/Empty.a11y.test.d.ts +0 -2
  160. package/dist/empty/Empty.a11y.test.d.ts.map +0 -1
  161. package/dist/empty/Empty.a11y.test.js +0 -22
  162. package/dist/form/Form.a11y.test.d.ts +0 -2
  163. package/dist/form/Form.a11y.test.d.ts.map +0 -1
  164. package/dist/form/Form.a11y.test.js +0 -36
  165. package/dist/form/FormA11yFixture.svelte +0 -31
  166. package/dist/form/FormA11yFixture.svelte.d.ts +0 -19
  167. package/dist/form/FormA11yFixture.svelte.d.ts.map +0 -1
  168. package/dist/grid/Grid.a11y.test.d.ts +0 -2
  169. package/dist/grid/Grid.a11y.test.d.ts.map +0 -1
  170. package/dist/grid/Grid.a11y.test.js +0 -13
  171. package/dist/grid/GridA11yFixture.svelte +0 -12
  172. package/dist/grid/GridA11yFixture.svelte.d.ts +0 -19
  173. package/dist/grid/GridA11yFixture.svelte.d.ts.map +0 -1
  174. package/dist/highlight/Highlight.a11y.test.d.ts +0 -2
  175. package/dist/highlight/Highlight.a11y.test.d.ts.map +0 -1
  176. package/dist/highlight/Highlight.a11y.test.js +0 -23
  177. package/dist/image/Image.a11y.test.d.ts +0 -2
  178. package/dist/image/Image.a11y.test.d.ts.map +0 -1
  179. package/dist/image/Image.a11y.test.js +0 -27
  180. package/dist/image/ImagePreview.kbd.test.d.ts +0 -2
  181. package/dist/image/ImagePreview.kbd.test.d.ts.map +0 -1
  182. package/dist/image/ImagePreview.kbd.test.js +0 -44
  183. package/dist/image/ImagePreviewKbdFixture.svelte +0 -32
  184. package/dist/image/ImagePreviewKbdFixture.svelte.d.ts +0 -4
  185. package/dist/image/ImagePreviewKbdFixture.svelte.d.ts.map +0 -1
  186. package/dist/input/Input.a11y.test.d.ts +0 -2
  187. package/dist/input/Input.a11y.test.d.ts.map +0 -1
  188. package/dist/input/Input.a11y.test.js +0 -53
  189. package/dist/input-number/InputNumber.a11y.test.d.ts +0 -2
  190. package/dist/input-number/InputNumber.a11y.test.d.ts.map +0 -1
  191. package/dist/input-number/InputNumber.a11y.test.js +0 -40
  192. package/dist/input-number/InputNumber.kbd.test.d.ts +0 -2
  193. package/dist/input-number/InputNumber.kbd.test.d.ts.map +0 -1
  194. package/dist/input-number/InputNumber.kbd.test.js +0 -35
  195. package/dist/input-number/InputNumberKbdFixture.svelte +0 -15
  196. package/dist/input-number/InputNumberKbdFixture.svelte.d.ts +0 -19
  197. package/dist/input-number/InputNumberKbdFixture.svelte.d.ts.map +0 -1
  198. package/dist/layout/Layout.a11y.test.d.ts +0 -2
  199. package/dist/layout/Layout.a11y.test.d.ts.map +0 -1
  200. package/dist/layout/Layout.a11y.test.js +0 -32
  201. package/dist/layout/LayoutA11yFixture.svelte +0 -21
  202. package/dist/layout/LayoutA11yFixture.svelte.d.ts +0 -7
  203. package/dist/layout/LayoutA11yFixture.svelte.d.ts.map +0 -1
  204. package/dist/list/List.a11y.test.d.ts +0 -2
  205. package/dist/list/List.a11y.test.d.ts.map +0 -1
  206. package/dist/list/List.a11y.test.js +0 -62
  207. package/dist/list/List.bench.d.ts +0 -2
  208. package/dist/list/List.bench.d.ts.map +0 -1
  209. package/dist/list/List.bench.js +0 -16
  210. package/dist/list/List.kbd.test.d.ts +0 -2
  211. package/dist/list/List.kbd.test.d.ts.map +0 -1
  212. package/dist/list/List.kbd.test.js +0 -60
  213. package/dist/list/ListA11yFixture.svelte +0 -38
  214. package/dist/list/ListA11yFixture.svelte.d.ts +0 -10
  215. package/dist/list/ListA11yFixture.svelte.d.ts.map +0 -1
  216. package/dist/list/ListBenchFixture.svelte +0 -22
  217. package/dist/list/ListBenchFixture.svelte.d.ts +0 -7
  218. package/dist/list/ListBenchFixture.svelte.d.ts.map +0 -1
  219. package/dist/list/ListKbdFixture.svelte +0 -31
  220. package/dist/list/ListKbdFixture.svelte.d.ts +0 -19
  221. package/dist/list/ListKbdFixture.svelte.d.ts.map +0 -1
  222. package/dist/menu/Menu.a11y.test.d.ts +0 -2
  223. package/dist/menu/Menu.a11y.test.d.ts.map +0 -1
  224. package/dist/menu/Menu.a11y.test.js +0 -49
  225. package/dist/menu/Menu.kbd.test.d.ts +0 -2
  226. package/dist/menu/Menu.kbd.test.d.ts.map +0 -1
  227. package/dist/menu/Menu.kbd.test.js +0 -56
  228. package/dist/menu/MenuKbdFixture.svelte +0 -22
  229. package/dist/menu/MenuKbdFixture.svelte.d.ts +0 -19
  230. package/dist/menu/MenuKbdFixture.svelte.d.ts.map +0 -1
  231. package/dist/meta.test.d.ts +0 -2
  232. package/dist/meta.test.d.ts.map +0 -1
  233. package/dist/meta.test.js +0 -164
  234. package/dist/modal/Modal.a11y.test.d.ts +0 -2
  235. package/dist/modal/Modal.a11y.test.d.ts.map +0 -1
  236. package/dist/modal/Modal.a11y.test.js +0 -38
  237. package/dist/modal/Modal.kbd.test.d.ts +0 -2
  238. package/dist/modal/Modal.kbd.test.d.ts.map +0 -1
  239. package/dist/modal/Modal.kbd.test.js +0 -52
  240. package/dist/modal/ModalKbdFixture.svelte +0 -24
  241. package/dist/modal/ModalKbdFixture.svelte.d.ts +0 -4
  242. package/dist/modal/ModalKbdFixture.svelte.d.ts.map +0 -1
  243. package/dist/notification/NotificationItem.a11y.test.d.ts +0 -2
  244. package/dist/notification/NotificationItem.a11y.test.d.ts.map +0 -1
  245. package/dist/notification/NotificationItem.a11y.test.js +0 -64
  246. package/dist/overflow-list/OverflowList.a11y.test.d.ts +0 -2
  247. package/dist/overflow-list/OverflowList.a11y.test.d.ts.map +0 -1
  248. package/dist/overflow-list/OverflowList.a11y.test.js +0 -41
  249. package/dist/overflow-list/OverflowList.kbd.test.d.ts +0 -2
  250. package/dist/overflow-list/OverflowList.kbd.test.d.ts.map +0 -1
  251. package/dist/overflow-list/OverflowList.kbd.test.js +0 -28
  252. package/dist/overflow-list/OverflowListA11yFixture.svelte +0 -22
  253. package/dist/overflow-list/OverflowListA11yFixture.svelte.d.ts +0 -8
  254. package/dist/overflow-list/OverflowListA11yFixture.svelte.d.ts.map +0 -1
  255. package/dist/overflow-list/OverflowListKbdFixture.svelte +0 -21
  256. package/dist/overflow-list/OverflowListKbdFixture.svelte.d.ts +0 -19
  257. package/dist/overflow-list/OverflowListKbdFixture.svelte.d.ts.map +0 -1
  258. package/dist/pagination/Pagination.a11y.test.d.ts +0 -2
  259. package/dist/pagination/Pagination.a11y.test.d.ts.map +0 -1
  260. package/dist/pagination/Pagination.a11y.test.js +0 -57
  261. package/dist/pagination/Pagination.kbd.test.d.ts +0 -2
  262. package/dist/pagination/Pagination.kbd.test.d.ts.map +0 -1
  263. package/dist/pagination/Pagination.kbd.test.js +0 -54
  264. package/dist/pagination/PaginationKbdFixture.svelte +0 -15
  265. package/dist/pagination/PaginationKbdFixture.svelte.d.ts +0 -19
  266. package/dist/pagination/PaginationKbdFixture.svelte.d.ts.map +0 -1
  267. package/dist/popconfirm/Popconfirm.a11y.test.d.ts +0 -2
  268. package/dist/popconfirm/Popconfirm.a11y.test.d.ts.map +0 -1
  269. package/dist/popconfirm/Popconfirm.a11y.test.js +0 -37
  270. package/dist/popconfirm/Popconfirm.kbd.test.d.ts +0 -2
  271. package/dist/popconfirm/Popconfirm.kbd.test.d.ts.map +0 -1
  272. package/dist/popconfirm/Popconfirm.kbd.test.js +0 -36
  273. package/dist/popconfirm/PopconfirmA11yFixture.svelte +0 -34
  274. package/dist/popconfirm/PopconfirmA11yFixture.svelte.d.ts +0 -11
  275. package/dist/popconfirm/PopconfirmA11yFixture.svelte.d.ts.map +0 -1
  276. package/dist/popconfirm/PopconfirmKbdFixture.svelte +0 -17
  277. package/dist/popconfirm/PopconfirmKbdFixture.svelte.d.ts +0 -19
  278. package/dist/popconfirm/PopconfirmKbdFixture.svelte.d.ts.map +0 -1
  279. package/dist/popover/Popover.a11y.test.d.ts +0 -2
  280. package/dist/popover/Popover.a11y.test.d.ts.map +0 -1
  281. package/dist/popover/Popover.a11y.test.js +0 -47
  282. package/dist/popover/Popover.kbd.test.d.ts +0 -2
  283. package/dist/popover/Popover.kbd.test.d.ts.map +0 -1
  284. package/dist/popover/Popover.kbd.test.js +0 -36
  285. package/dist/popover/PopoverA11yFixture.svelte +0 -35
  286. package/dist/popover/PopoverA11yFixture.svelte.d.ts +0 -11
  287. package/dist/popover/PopoverA11yFixture.svelte.d.ts.map +0 -1
  288. package/dist/popover/PopoverKbdFixture.svelte +0 -18
  289. package/dist/popover/PopoverKbdFixture.svelte.d.ts +0 -19
  290. package/dist/popover/PopoverKbdFixture.svelte.d.ts.map +0 -1
  291. package/dist/progress/Progress.a11y.test.d.ts +0 -2
  292. package/dist/progress/Progress.a11y.test.d.ts.map +0 -1
  293. package/dist/progress/Progress.a11y.test.js +0 -34
  294. package/dist/radio/RadioGroup.a11y.test.d.ts +0 -2
  295. package/dist/radio/RadioGroup.a11y.test.d.ts.map +0 -1
  296. package/dist/radio/RadioGroup.a11y.test.js +0 -38
  297. package/dist/radio/RadioGroup.kbd.test.d.ts +0 -2
  298. package/dist/radio/RadioGroup.kbd.test.d.ts.map +0 -1
  299. package/dist/radio/RadioGroup.kbd.test.js +0 -59
  300. package/dist/radio/RadioGroupKbdFixture.svelte +0 -21
  301. package/dist/radio/RadioGroupKbdFixture.svelte.d.ts +0 -19
  302. package/dist/radio/RadioGroupKbdFixture.svelte.d.ts.map +0 -1
  303. package/dist/rating/Rating.a11y.test.d.ts +0 -2
  304. package/dist/rating/Rating.a11y.test.d.ts.map +0 -1
  305. package/dist/rating/Rating.a11y.test.js +0 -38
  306. package/dist/rating/Rating.kbd.test.d.ts +0 -2
  307. package/dist/rating/Rating.kbd.test.d.ts.map +0 -1
  308. package/dist/rating/Rating.kbd.test.js +0 -41
  309. package/dist/rating/RatingKbdFixture.svelte +0 -15
  310. package/dist/rating/RatingKbdFixture.svelte.d.ts +0 -19
  311. package/dist/rating/RatingKbdFixture.svelte.d.ts.map +0 -1
  312. package/dist/select/Select.a11y.test.d.ts +0 -2
  313. package/dist/select/Select.a11y.test.d.ts.map +0 -1
  314. package/dist/select/Select.a11y.test.js +0 -53
  315. package/dist/select/Select.kbd.test.d.ts +0 -2
  316. package/dist/select/Select.kbd.test.d.ts.map +0 -1
  317. package/dist/select/Select.kbd.test.js +0 -47
  318. package/dist/select/SelectKbdFixture.svelte +0 -29
  319. package/dist/select/SelectKbdFixture.svelte.d.ts +0 -4
  320. package/dist/select/SelectKbdFixture.svelte.d.ts.map +0 -1
  321. package/dist/side-sheet/SideSheet.a11y.test.d.ts +0 -2
  322. package/dist/side-sheet/SideSheet.a11y.test.d.ts.map +0 -1
  323. package/dist/side-sheet/SideSheet.a11y.test.js +0 -46
  324. package/dist/side-sheet/SideSheet.kbd.test.d.ts +0 -2
  325. package/dist/side-sheet/SideSheet.kbd.test.d.ts.map +0 -1
  326. package/dist/side-sheet/SideSheet.kbd.test.js +0 -49
  327. package/dist/side-sheet/SideSheetKbdFixture.svelte +0 -30
  328. package/dist/side-sheet/SideSheetKbdFixture.svelte.d.ts +0 -4
  329. package/dist/side-sheet/SideSheetKbdFixture.svelte.d.ts.map +0 -1
  330. package/dist/skeleton/Skeleton.a11y.test.d.ts +0 -2
  331. package/dist/skeleton/Skeleton.a11y.test.d.ts.map +0 -1
  332. package/dist/skeleton/Skeleton.a11y.test.js +0 -32
  333. package/dist/slider/Slider.a11y.test.d.ts +0 -2
  334. package/dist/slider/Slider.a11y.test.d.ts.map +0 -1
  335. package/dist/slider/Slider.a11y.test.js +0 -40
  336. package/dist/slider/Slider.kbd.test.d.ts +0 -2
  337. package/dist/slider/Slider.kbd.test.d.ts.map +0 -1
  338. package/dist/slider/Slider.kbd.test.js +0 -63
  339. package/dist/slider/SliderKbdFixture.svelte +0 -21
  340. package/dist/slider/SliderKbdFixture.svelte.d.ts +0 -19
  341. package/dist/slider/SliderKbdFixture.svelte.d.ts.map +0 -1
  342. package/dist/space/Space.a11y.test.d.ts +0 -2
  343. package/dist/space/Space.a11y.test.d.ts.map +0 -1
  344. package/dist/space/Space.a11y.test.js +0 -20
  345. package/dist/space/SpaceA11yFixture.svelte +0 -17
  346. package/dist/space/SpaceA11yFixture.svelte.d.ts +0 -7
  347. package/dist/space/SpaceA11yFixture.svelte.d.ts.map +0 -1
  348. package/dist/spin/Spin.a11y.test.d.ts +0 -2
  349. package/dist/spin/Spin.a11y.test.d.ts.map +0 -1
  350. package/dist/spin/Spin.a11y.test.js +0 -27
  351. package/dist/spin/SpinA11yFixture.svelte +0 -18
  352. package/dist/spin/SpinA11yFixture.svelte.d.ts +0 -7
  353. package/dist/spin/SpinA11yFixture.svelte.d.ts.map +0 -1
  354. package/dist/steps/Steps.a11y.test.d.ts +0 -2
  355. package/dist/steps/Steps.a11y.test.d.ts.map +0 -1
  356. package/dist/steps/Steps.a11y.test.js +0 -35
  357. package/dist/steps/Steps.kbd.test.d.ts +0 -2
  358. package/dist/steps/Steps.kbd.test.d.ts.map +0 -1
  359. package/dist/steps/Steps.kbd.test.js +0 -59
  360. package/dist/steps/StepsKbdFixture.svelte +0 -21
  361. package/dist/steps/StepsKbdFixture.svelte.d.ts +0 -19
  362. package/dist/steps/StepsKbdFixture.svelte.d.ts.map +0 -1
  363. package/dist/switch/Switch.a11y.test.d.ts +0 -2
  364. package/dist/switch/Switch.a11y.test.d.ts.map +0 -1
  365. package/dist/switch/Switch.a11y.test.js +0 -42
  366. package/dist/switch/Switch.kbd.test.d.ts +0 -2
  367. package/dist/switch/Switch.kbd.test.d.ts.map +0 -1
  368. package/dist/switch/Switch.kbd.test.js +0 -34
  369. package/dist/switch/SwitchKbdFixture.svelte +0 -22
  370. package/dist/switch/SwitchKbdFixture.svelte.d.ts +0 -4
  371. package/dist/switch/SwitchKbdFixture.svelte.d.ts.map +0 -1
  372. package/dist/table/Table.a11y.test.d.ts +0 -2
  373. package/dist/table/Table.a11y.test.d.ts.map +0 -1
  374. package/dist/table/Table.a11y.test.js +0 -59
  375. package/dist/table/Table.bench.d.ts +0 -2
  376. package/dist/table/Table.bench.d.ts.map +0 -1
  377. package/dist/table/Table.bench.js +0 -31
  378. package/dist/table/Table.kbd.test.d.ts +0 -2
  379. package/dist/table/Table.kbd.test.d.ts.map +0 -1
  380. package/dist/table/Table.kbd.test.js +0 -74
  381. package/dist/table/TableKbdFixture.svelte +0 -35
  382. package/dist/table/TableKbdFixture.svelte.d.ts +0 -19
  383. package/dist/table/TableKbdFixture.svelte.d.ts.map +0 -1
  384. package/dist/table/grid-nav.test.d.ts +0 -2
  385. package/dist/table/grid-nav.test.d.ts.map +0 -1
  386. package/dist/table/grid-nav.test.js +0 -133
  387. package/dist/tabs/Tabs.a11y.test.d.ts +0 -2
  388. package/dist/tabs/Tabs.a11y.test.d.ts.map +0 -1
  389. package/dist/tabs/Tabs.a11y.test.js +0 -43
  390. package/dist/tabs/Tabs.kbd.test.d.ts +0 -2
  391. package/dist/tabs/Tabs.kbd.test.d.ts.map +0 -1
  392. package/dist/tabs/Tabs.kbd.test.js +0 -63
  393. package/dist/tabs/TabsA11yFixture.svelte +0 -20
  394. package/dist/tabs/TabsA11yFixture.svelte.d.ts +0 -8
  395. package/dist/tabs/TabsA11yFixture.svelte.d.ts.map +0 -1
  396. package/dist/tabs/TabsKbdFixture.svelte +0 -25
  397. package/dist/tabs/TabsKbdFixture.svelte.d.ts +0 -7
  398. package/dist/tabs/TabsKbdFixture.svelte.d.ts.map +0 -1
  399. package/dist/tag/Tag.a11y.test.d.ts +0 -2
  400. package/dist/tag/Tag.a11y.test.d.ts.map +0 -1
  401. package/dist/tag/Tag.a11y.test.js +0 -30
  402. package/dist/tag/TagA11yFixture.svelte +0 -18
  403. package/dist/tag/TagA11yFixture.svelte.d.ts +0 -8
  404. package/dist/tag/TagA11yFixture.svelte.d.ts.map +0 -1
  405. package/dist/tag-input/TagInput.a11y.test.d.ts +0 -2
  406. package/dist/tag-input/TagInput.a11y.test.d.ts.map +0 -1
  407. package/dist/tag-input/TagInput.a11y.test.js +0 -38
  408. package/dist/tag-input/reorder.test.d.ts +0 -2
  409. package/dist/tag-input/reorder.test.d.ts.map +0 -1
  410. package/dist/tag-input/reorder.test.js +0 -48
  411. package/dist/test-utils/LocaleHarness.svelte +0 -29
  412. package/dist/test-utils/LocaleHarness.svelte.d.ts +0 -11
  413. package/dist/test-utils/LocaleHarness.svelte.d.ts.map +0 -1
  414. package/dist/test-utils/a11y.d.ts +0 -36
  415. package/dist/test-utils/a11y.d.ts.map +0 -1
  416. package/dist/test-utils/a11y.js +0 -68
  417. package/dist/test-utils/kbd.d.ts +0 -26
  418. package/dist/test-utils/kbd.d.ts.map +0 -1
  419. package/dist/test-utils/kbd.js +0 -38
  420. package/dist/textarea/TextArea.a11y.test.d.ts +0 -2
  421. package/dist/textarea/TextArea.a11y.test.d.ts.map +0 -1
  422. package/dist/textarea/TextArea.a11y.test.js +0 -41
  423. package/dist/time-picker/TimePicker.a11y.test.d.ts +0 -2
  424. package/dist/time-picker/TimePicker.a11y.test.d.ts.map +0 -1
  425. package/dist/time-picker/TimePicker.a11y.test.js +0 -42
  426. package/dist/time-picker/TimePicker.kbd.test.d.ts +0 -2
  427. package/dist/time-picker/TimePicker.kbd.test.d.ts.map +0 -1
  428. package/dist/time-picker/TimePicker.kbd.test.js +0 -59
  429. package/dist/time-picker/TimePickerKbdFixture.svelte +0 -23
  430. package/dist/time-picker/TimePickerKbdFixture.svelte.d.ts +0 -4
  431. package/dist/time-picker/TimePickerKbdFixture.svelte.d.ts.map +0 -1
  432. package/dist/timeline/Timeline.a11y.test.d.ts +0 -2
  433. package/dist/timeline/Timeline.a11y.test.d.ts.map +0 -1
  434. package/dist/timeline/Timeline.a11y.test.js +0 -51
  435. package/dist/toast/Toast.a11y.test.d.ts +0 -2
  436. package/dist/toast/Toast.a11y.test.d.ts.map +0 -1
  437. package/dist/toast/Toast.a11y.test.js +0 -58
  438. package/dist/tooltip/Tooltip.a11y.test.d.ts +0 -2
  439. package/dist/tooltip/Tooltip.a11y.test.d.ts.map +0 -1
  440. package/dist/tooltip/Tooltip.a11y.test.js +0 -33
  441. package/dist/tooltip/Tooltip.kbd.test.d.ts +0 -2
  442. package/dist/tooltip/Tooltip.kbd.test.d.ts.map +0 -1
  443. package/dist/tooltip/Tooltip.kbd.test.js +0 -31
  444. package/dist/tooltip/TooltipA11yFixture.svelte +0 -31
  445. package/dist/tooltip/TooltipA11yFixture.svelte.d.ts +0 -11
  446. package/dist/tooltip/TooltipA11yFixture.svelte.d.ts.map +0 -1
  447. package/dist/tooltip/TooltipKbdFixture.svelte +0 -16
  448. package/dist/tooltip/TooltipKbdFixture.svelte.d.ts +0 -19
  449. package/dist/tooltip/TooltipKbdFixture.svelte.d.ts.map +0 -1
  450. package/dist/transfer/Transfer.a11y.test.d.ts +0 -2
  451. package/dist/transfer/Transfer.a11y.test.d.ts.map +0 -1
  452. package/dist/transfer/Transfer.a11y.test.js +0 -59
  453. package/dist/transfer/Transfer.kbd.test.d.ts +0 -2
  454. package/dist/transfer/Transfer.kbd.test.d.ts.map +0 -1
  455. package/dist/transfer/Transfer.kbd.test.js +0 -64
  456. package/dist/transfer/TransferKbdFixture.svelte +0 -23
  457. package/dist/transfer/TransferKbdFixture.svelte.d.ts +0 -4
  458. package/dist/transfer/TransferKbdFixture.svelte.d.ts.map +0 -1
  459. package/dist/transfer/group.test.d.ts +0 -2
  460. package/dist/transfer/group.test.d.ts.map +0 -1
  461. package/dist/transfer/group.test.js +0 -47
  462. package/dist/transfer/reorder.test.d.ts +0 -2
  463. package/dist/transfer/reorder.test.d.ts.map +0 -1
  464. package/dist/transfer/reorder.test.js +0 -42
  465. package/dist/transfer/tree.test.d.ts +0 -2
  466. package/dist/transfer/tree.test.d.ts.map +0 -1
  467. package/dist/transfer/tree.test.js +0 -39
  468. package/dist/tree/Tree.a11y.test.d.ts +0 -2
  469. package/dist/tree/Tree.a11y.test.d.ts.map +0 -1
  470. package/dist/tree/Tree.a11y.test.js +0 -56
  471. package/dist/tree/Tree.kbd.test.d.ts +0 -2
  472. package/dist/tree/Tree.kbd.test.d.ts.map +0 -1
  473. package/dist/tree/Tree.kbd.test.js +0 -78
  474. package/dist/tree/TreeKbdFixture.svelte +0 -30
  475. package/dist/tree/TreeKbdFixture.svelte.d.ts +0 -19
  476. package/dist/tree/TreeKbdFixture.svelte.d.ts.map +0 -1
  477. package/dist/tree-select/TreeSelect.a11y.test.d.ts +0 -2
  478. package/dist/tree-select/TreeSelect.a11y.test.d.ts.map +0 -1
  479. package/dist/tree-select/TreeSelect.a11y.test.js +0 -48
  480. package/dist/tree-select/TreeSelect.kbd.test.d.ts +0 -2
  481. package/dist/tree-select/TreeSelect.kbd.test.d.ts.map +0 -1
  482. package/dist/tree-select/TreeSelect.kbd.test.js +0 -46
  483. package/dist/tree-select/TreeSelectKbdFixture.svelte +0 -20
  484. package/dist/tree-select/TreeSelectKbdFixture.svelte.d.ts +0 -19
  485. package/dist/tree-select/TreeSelectKbdFixture.svelte.d.ts.map +0 -1
  486. package/dist/tree-select/virtual.test.d.ts +0 -2
  487. package/dist/tree-select/virtual.test.d.ts.map +0 -1
  488. package/dist/tree-select/virtual.test.js +0 -86
  489. package/dist/typography/Typography.a11y.test.d.ts +0 -2
  490. package/dist/typography/Typography.a11y.test.d.ts.map +0 -1
  491. package/dist/typography/Typography.a11y.test.js +0 -31
  492. package/dist/typography/TypographyA11yFixture.svelte +0 -27
  493. package/dist/typography/TypographyA11yFixture.svelte.d.ts +0 -9
  494. package/dist/typography/TypographyA11yFixture.svelte.d.ts.map +0 -1
  495. package/dist/upload/Upload.a11y.test.d.ts +0 -2
  496. package/dist/upload/Upload.a11y.test.d.ts.map +0 -1
  497. package/dist/upload/Upload.a11y.test.js +0 -49
  498. package/dist/upload/UploadA11yFixture.svelte +0 -23
  499. package/dist/upload/UploadA11yFixture.svelte.d.ts +0 -10
  500. package/dist/upload/UploadA11yFixture.svelte.d.ts.map +0 -1
  501. package/src/_floating/use-floating.ts +0 -208
  502. package/src/anchor/Anchor.a11y.test.ts +0 -49
  503. package/src/anchor/Anchor.kbd.test.ts +0 -70
  504. package/src/anchor/Anchor.svelte +0 -359
  505. package/src/anchor/AnchorKbdFixture.svelte +0 -24
  506. package/src/anchor/index.ts +0 -3
  507. package/src/anchor/meta.ts +0 -70
  508. package/src/anchor/types.ts +0 -8
  509. package/src/autocomplete/AutoComplete.a11y.test.ts +0 -49
  510. package/src/autocomplete/AutoComplete.kbd.test.ts +0 -69
  511. package/src/autocomplete/AutoComplete.svelte +0 -706
  512. package/src/autocomplete/AutoCompleteKbdFixture.svelte +0 -24
  513. package/src/autocomplete/index.ts +0 -2
  514. package/src/autocomplete/meta.ts +0 -41
  515. package/src/avatar/Avatar.a11y.test.ts +0 -37
  516. package/src/avatar/Avatar.svelte +0 -315
  517. package/src/avatar/AvatarGroup.svelte +0 -142
  518. package/src/avatar/context.ts +0 -21
  519. package/src/avatar/index.ts +0 -10
  520. package/src/avatar/meta.ts +0 -73
  521. package/src/back-top/BackTop.a11y.test.ts +0 -40
  522. package/src/back-top/BackTop.svelte +0 -314
  523. package/src/back-top/index.ts +0 -2
  524. package/src/back-top/meta.ts +0 -108
  525. package/src/badge/Badge.a11y.test.ts +0 -35
  526. package/src/badge/Badge.svelte +0 -328
  527. package/src/badge/BadgeA11yFixture.svelte +0 -18
  528. package/src/badge/index.ts +0 -2
  529. package/src/badge/meta.ts +0 -62
  530. package/src/banner/Banner.a11y.test.ts +0 -48
  531. package/src/banner/Banner.svelte +0 -368
  532. package/src/banner/index.ts +0 -3
  533. package/src/banner/meta.ts +0 -121
  534. package/src/breadcrumb/Breadcrumb.a11y.test.ts +0 -35
  535. package/src/breadcrumb/Breadcrumb.kbd.test.ts +0 -45
  536. package/src/breadcrumb/Breadcrumb.svelte +0 -414
  537. package/src/breadcrumb/BreadcrumbKbdFixture.svelte +0 -23
  538. package/src/breadcrumb/Item.svelte +0 -77
  539. package/src/breadcrumb/context.ts +0 -27
  540. package/src/breadcrumb/index.ts +0 -21
  541. package/src/breadcrumb/meta.ts +0 -128
  542. package/src/breadcrumb/types.ts +0 -4
  543. package/src/button/Button.a11y.test.ts +0 -54
  544. package/src/button/Button.svelte +0 -176
  545. package/src/button/index.ts +0 -2
  546. package/src/button/meta.ts +0 -28
  547. package/src/calendar/Calendar.a11y.test.ts +0 -51
  548. package/src/calendar/Calendar.kbd.test.ts +0 -59
  549. package/src/calendar/Calendar.svelte +0 -1344
  550. package/src/calendar/CalendarKbdFixture.svelte +0 -23
  551. package/src/calendar/index.ts +0 -3
  552. package/src/calendar/meta.ts +0 -117
  553. package/src/card/Card.a11y.test.ts +0 -38
  554. package/src/card/Card.svelte +0 -341
  555. package/src/card/CardMeta.svelte +0 -60
  556. package/src/card/index.ts +0 -8
  557. package/src/card/meta.ts +0 -83
  558. package/src/carousel/Carousel.a11y.test.ts +0 -53
  559. package/src/carousel/Carousel.kbd.test.ts +0 -67
  560. package/src/carousel/Carousel.svelte +0 -806
  561. package/src/carousel/CarouselA11yFixture.svelte +0 -25
  562. package/src/carousel/CarouselKbdFixture.svelte +0 -24
  563. package/src/carousel/index.ts +0 -2
  564. package/src/carousel/meta.ts +0 -74
  565. package/src/cascader/Cascader.a11y.test.ts +0 -59
  566. package/src/cascader/Cascader.kbd.test.ts +0 -56
  567. package/src/cascader/Cascader.svelte +0 -1570
  568. package/src/cascader/CascaderKbdFixture.svelte +0 -31
  569. package/src/cascader/index.ts +0 -3
  570. package/src/cascader/meta.ts +0 -57
  571. package/src/cascader/types.ts +0 -9
  572. package/src/checkbox/Checkbox.svelte +0 -281
  573. package/src/checkbox/CheckboxGroup.a11y.test.ts +0 -43
  574. package/src/checkbox/CheckboxGroup.kbd.test.ts +0 -40
  575. package/src/checkbox/CheckboxGroup.svelte +0 -122
  576. package/src/checkbox/CheckboxGroupKbdFixture.svelte +0 -20
  577. package/src/checkbox/context.ts +0 -31
  578. package/src/checkbox/index.ts +0 -4
  579. package/src/checkbox/meta.ts +0 -67
  580. package/src/collapse/Collapse.a11y.test.ts +0 -53
  581. package/src/collapse/Collapse.kbd.test.ts +0 -89
  582. package/src/collapse/Collapse.svelte +0 -406
  583. package/src/collapse/CollapseA11yFixture.svelte +0 -27
  584. package/src/collapse/CollapseKbdFixture.svelte +0 -25
  585. package/src/collapse/CollapsePanel.svelte +0 -102
  586. package/src/collapse/context.ts +0 -54
  587. package/src/collapse/index.ts +0 -17
  588. package/src/collapse/meta.ts +0 -79
  589. package/src/collapse/types.ts +0 -5
  590. package/src/color-picker/ColorPicker.a11y.test.ts +0 -60
  591. package/src/color-picker/ColorPicker.kbd.test.ts +0 -73
  592. package/src/color-picker/ColorPicker.svelte +0 -985
  593. package/src/color-picker/ColorPickerKbdFixture.svelte +0 -25
  594. package/src/color-picker/index.ts +0 -2
  595. package/src/color-picker/meta.ts +0 -47
  596. package/src/config-provider/ConfigProvider.svelte +0 -227
  597. package/src/config-provider/context.ts +0 -29
  598. package/src/config-provider/index.ts +0 -48
  599. package/src/config-provider/meta.ts +0 -128
  600. package/src/date-picker/DatePicker.a11y.test.ts +0 -45
  601. package/src/date-picker/DatePicker.kbd.test.ts +0 -71
  602. package/src/date-picker/DatePicker.svelte +0 -1798
  603. package/src/date-picker/DatePickerKbdFixture.svelte +0 -26
  604. package/src/date-picker/RangePicker.kbd.test.ts +0 -69
  605. package/src/date-picker/RangePicker.svelte +0 -775
  606. package/src/date-picker/RangePickerKbdFixture.svelte +0 -30
  607. package/src/date-picker/index.ts +0 -4
  608. package/src/date-picker/meta.ts +0 -67
  609. package/src/date-picker/range-meta.ts +0 -44
  610. package/src/descriptions/Descriptions.a11y.test.ts +0 -33
  611. package/src/descriptions/Descriptions.svelte +0 -287
  612. package/src/descriptions/DescriptionsItem.svelte +0 -43
  613. package/src/descriptions/context.ts +0 -21
  614. package/src/descriptions/index.ts +0 -16
  615. package/src/descriptions/meta.ts +0 -45
  616. package/src/descriptions/types.ts +0 -6
  617. package/src/divider/Divider.a11y.test.ts +0 -23
  618. package/src/divider/Divider.svelte +0 -154
  619. package/src/divider/index.ts +0 -2
  620. package/src/divider/meta.ts +0 -23
  621. package/src/drawer/Drawer.a11y.test.ts +0 -41
  622. package/src/drawer/Drawer.kbd.test.ts +0 -67
  623. package/src/drawer/Drawer.svelte +0 -554
  624. package/src/drawer/DrawerKbdFixture.svelte +0 -28
  625. package/src/drawer/index.ts +0 -2
  626. package/src/drawer/meta.ts +0 -127
  627. package/src/dropdown/Dropdown.a11y.test.ts +0 -46
  628. package/src/dropdown/Dropdown.kbd.test.ts +0 -56
  629. package/src/dropdown/Dropdown.svelte +0 -573
  630. package/src/dropdown/DropdownA11yFixture.svelte +0 -24
  631. package/src/dropdown/DropdownDivider.svelte +0 -17
  632. package/src/dropdown/DropdownItem.svelte +0 -127
  633. package/src/dropdown/DropdownItemNode.svelte +0 -355
  634. package/src/dropdown/DropdownKbdFixture.svelte +0 -26
  635. package/src/dropdown/DropdownMenu.svelte +0 -24
  636. package/src/dropdown/DropdownSubMenu.svelte +0 -212
  637. package/src/dropdown/DropdownTitle.svelte +0 -34
  638. package/src/dropdown/context.ts +0 -13
  639. package/src/dropdown/index.ts +0 -36
  640. package/src/dropdown/meta.ts +0 -97
  641. package/src/dropdown/types.test.ts +0 -50
  642. package/src/dropdown/types.ts +0 -67
  643. package/src/empty/Empty.a11y.test.ts +0 -24
  644. package/src/empty/Empty.svelte +0 -304
  645. package/src/empty/index.ts +0 -2
  646. package/src/empty/meta.ts +0 -41
  647. package/src/form/Field.svelte +0 -492
  648. package/src/form/FieldArray.svelte +0 -75
  649. package/src/form/Form.a11y.test.ts +0 -39
  650. package/src/form/Form.svelte +0 -243
  651. package/src/form/FormA11yFixture.svelte +0 -31
  652. package/src/form/FormCascader.svelte +0 -82
  653. package/src/form/FormCheckbox.svelte +0 -83
  654. package/src/form/FormDatePicker.svelte +0 -80
  655. package/src/form/FormErrorMessage.svelte +0 -44
  656. package/src/form/FormInput.svelte +0 -95
  657. package/src/form/FormLabel.svelte +0 -46
  658. package/src/form/FormRadio.svelte +0 -83
  659. package/src/form/FormRating.svelte +0 -85
  660. package/src/form/FormSection.svelte +0 -45
  661. package/src/form/FormSelect.svelte +0 -96
  662. package/src/form/FormSlider.svelte +0 -95
  663. package/src/form/FormSlot.svelte +0 -51
  664. package/src/form/FormSwitch.svelte +0 -82
  665. package/src/form/FormTagInput.svelte +0 -79
  666. package/src/form/FormTreeSelect.svelte +0 -85
  667. package/src/form/FormUpload.svelte +0 -92
  668. package/src/form/context.ts +0 -47
  669. package/src/form/index.ts +0 -22
  670. package/src/form/meta.ts +0 -85
  671. package/src/grid/Col.svelte +0 -142
  672. package/src/grid/Grid.a11y.test.ts +0 -14
  673. package/src/grid/GridA11yFixture.svelte +0 -12
  674. package/src/grid/Row.svelte +0 -116
  675. package/src/grid/index.ts +0 -3
  676. package/src/grid/meta.ts +0 -72
  677. package/src/grid/use-breakpoint.svelte.ts +0 -48
  678. package/src/highlight/Highlight.a11y.test.ts +0 -25
  679. package/src/highlight/Highlight.svelte +0 -99
  680. package/src/highlight/index.ts +0 -2
  681. package/src/highlight/meta.ts +0 -80
  682. package/src/icon/Icon.svelte +0 -156
  683. package/src/icon/index.ts +0 -2
  684. package/src/icon/meta.ts +0 -41
  685. package/src/image/Image.a11y.test.ts +0 -30
  686. package/src/image/Image.svelte +0 -387
  687. package/src/image/ImagePreview.kbd.test.ts +0 -52
  688. package/src/image/ImagePreview.svelte +0 -309
  689. package/src/image/ImagePreviewGroup.svelte +0 -93
  690. package/src/image/ImagePreviewKbdFixture.svelte +0 -32
  691. package/src/image/context.ts +0 -26
  692. package/src/image/index.ts +0 -15
  693. package/src/image/meta.ts +0 -131
  694. package/src/index.ts +0 -208
  695. package/src/input/Input.a11y.test.ts +0 -58
  696. package/src/input/Input.svelte +0 -505
  697. package/src/input/index.ts +0 -2
  698. package/src/input/meta.ts +0 -40
  699. package/src/input-number/InputNumber.a11y.test.ts +0 -43
  700. package/src/input-number/InputNumber.kbd.test.ts +0 -41
  701. package/src/input-number/InputNumber.svelte +0 -674
  702. package/src/input-number/InputNumberKbdFixture.svelte +0 -15
  703. package/src/input-number/index.ts +0 -2
  704. package/src/input-number/meta.ts +0 -65
  705. package/src/layout/Content.svelte +0 -37
  706. package/src/layout/Footer.svelte +0 -49
  707. package/src/layout/Header.svelte +0 -46
  708. package/src/layout/Layout.a11y.test.ts +0 -34
  709. package/src/layout/Layout.svelte +0 -60
  710. package/src/layout/LayoutA11yFixture.svelte +0 -21
  711. package/src/layout/Sider.svelte +0 -207
  712. package/src/layout/index.ts +0 -26
  713. package/src/layout/meta.ts +0 -116
  714. package/src/list/List.a11y.test.ts +0 -69
  715. package/src/list/List.bench.ts +0 -26
  716. package/src/list/List.kbd.test.ts +0 -71
  717. package/src/list/List.svelte +0 -920
  718. package/src/list/ListA11yFixture.svelte +0 -38
  719. package/src/list/ListBenchFixture.svelte +0 -22
  720. package/src/list/ListItem.svelte +0 -175
  721. package/src/list/ListKbdFixture.svelte +0 -31
  722. package/src/list/ListMeta.svelte +0 -73
  723. package/src/list/context.ts +0 -39
  724. package/src/list/index.ts +0 -21
  725. package/src/list/meta.ts +0 -99
  726. package/src/locale-provider/LocaleProvider.svelte +0 -110
  727. package/src/locale-provider/context.ts +0 -22
  728. package/src/locale-provider/index.ts +0 -21
  729. package/src/locale-provider/meta.ts +0 -93
  730. package/src/locale-provider/use-locale.ts +0 -25
  731. package/src/lottie-icon/LottieIcon.svelte +0 -330
  732. package/src/lottie-icon/index.ts +0 -9
  733. package/src/lottie-icon/meta.ts +0 -162
  734. package/src/menu/Menu.a11y.test.ts +0 -54
  735. package/src/menu/Menu.kbd.test.ts +0 -69
  736. package/src/menu/Menu.svelte +0 -762
  737. package/src/menu/MenuKbdFixture.svelte +0 -22
  738. package/src/menu/MenuPopupNode.svelte +0 -525
  739. package/src/menu/index.ts +0 -4
  740. package/src/menu/meta.ts +0 -137
  741. package/src/menu/types.ts +0 -120
  742. package/src/meta.test.ts +0 -173
  743. package/src/modal/ConfirmModal.svelte +0 -173
  744. package/src/modal/Modal.a11y.test.ts +0 -46
  745. package/src/modal/Modal.kbd.test.ts +0 -65
  746. package/src/modal/Modal.svelte +0 -511
  747. package/src/modal/ModalKbdFixture.svelte +0 -24
  748. package/src/modal/command.svelte.ts +0 -103
  749. package/src/modal/index.ts +0 -30
  750. package/src/modal/meta.ts +0 -165
  751. package/src/modal/z-stack.ts +0 -26
  752. package/src/notification/NotificationContainer.svelte +0 -192
  753. package/src/notification/NotificationItem.a11y.test.ts +0 -73
  754. package/src/notification/NotificationItem.svelte +0 -368
  755. package/src/notification/index.ts +0 -9
  756. package/src/notification/meta.ts +0 -120
  757. package/src/notification/store.ts +0 -191
  758. package/src/overflow-list/OverflowList.a11y.test.ts +0 -46
  759. package/src/overflow-list/OverflowList.kbd.test.ts +0 -34
  760. package/src/overflow-list/OverflowList.svelte +0 -539
  761. package/src/overflow-list/OverflowListA11yFixture.svelte +0 -22
  762. package/src/overflow-list/OverflowListKbdFixture.svelte +0 -21
  763. package/src/overflow-list/index.ts +0 -2
  764. package/src/overflow-list/meta.ts +0 -138
  765. package/src/pagination/Pagination.a11y.test.ts +0 -62
  766. package/src/pagination/Pagination.kbd.test.ts +0 -66
  767. package/src/pagination/Pagination.svelte +0 -428
  768. package/src/pagination/PaginationKbdFixture.svelte +0 -15
  769. package/src/pagination/index.ts +0 -2
  770. package/src/pagination/meta.ts +0 -73
  771. package/src/popconfirm/Popconfirm.a11y.test.ts +0 -46
  772. package/src/popconfirm/Popconfirm.kbd.test.ts +0 -42
  773. package/src/popconfirm/Popconfirm.svelte +0 -724
  774. package/src/popconfirm/PopconfirmA11yFixture.svelte +0 -34
  775. package/src/popconfirm/PopconfirmKbdFixture.svelte +0 -17
  776. package/src/popconfirm/index.ts +0 -2
  777. package/src/popconfirm/meta.ts +0 -200
  778. package/src/popover/Popover.a11y.test.ts +0 -58
  779. package/src/popover/Popover.kbd.test.ts +0 -42
  780. package/src/popover/Popover.svelte +0 -643
  781. package/src/popover/PopoverA11yFixture.svelte +0 -35
  782. package/src/popover/PopoverKbdFixture.svelte +0 -18
  783. package/src/popover/index.ts +0 -2
  784. package/src/popover/meta.ts +0 -103
  785. package/src/progress/Progress.a11y.test.ts +0 -37
  786. package/src/progress/Progress.svelte +0 -423
  787. package/src/progress/index.ts +0 -3
  788. package/src/progress/meta.ts +0 -132
  789. package/src/radio/Radio.svelte +0 -330
  790. package/src/radio/RadioGroup.a11y.test.ts +0 -43
  791. package/src/radio/RadioGroup.kbd.test.ts +0 -75
  792. package/src/radio/RadioGroup.svelte +0 -199
  793. package/src/radio/RadioGroupKbdFixture.svelte +0 -21
  794. package/src/radio/context.ts +0 -42
  795. package/src/radio/index.ts +0 -4
  796. package/src/radio/meta.ts +0 -68
  797. package/src/rating/Rating.a11y.test.ts +0 -41
  798. package/src/rating/Rating.kbd.test.ts +0 -48
  799. package/src/rating/Rating.svelte +0 -407
  800. package/src/rating/RatingKbdFixture.svelte +0 -15
  801. package/src/rating/index.ts +0 -2
  802. package/src/rating/meta.ts +0 -40
  803. package/src/resize-observer/ResizeObserver.svelte +0 -169
  804. package/src/resize-observer/action.ts +0 -80
  805. package/src/resize-observer/index.ts +0 -9
  806. package/src/resize-observer/meta.ts +0 -102
  807. package/src/scroll-list/ScrollColumn.svelte +0 -592
  808. package/src/scroll-list/ScrollList.svelte +0 -257
  809. package/src/scroll-list/index.ts +0 -4
  810. package/src/scroll-list/meta.ts +0 -93
  811. package/src/scroll-list/types.ts +0 -18
  812. package/src/select/Select.a11y.test.ts +0 -59
  813. package/src/select/Select.kbd.test.ts +0 -59
  814. package/src/select/Select.svelte +0 -1155
  815. package/src/select/SelectKbdFixture.svelte +0 -29
  816. package/src/select/index.ts +0 -3
  817. package/src/select/meta.ts +0 -78
  818. package/src/select/types.ts +0 -2
  819. package/src/side-sheet/SideSheet.a11y.test.ts +0 -53
  820. package/src/side-sheet/SideSheet.kbd.test.ts +0 -63
  821. package/src/side-sheet/SideSheet.svelte +0 -659
  822. package/src/side-sheet/SideSheetKbdFixture.svelte +0 -30
  823. package/src/side-sheet/index.ts +0 -2
  824. package/src/side-sheet/meta.ts +0 -116
  825. package/src/skeleton/Skeleton.a11y.test.ts +0 -35
  826. package/src/skeleton/Skeleton.svelte +0 -131
  827. package/src/skeleton/SkeletonAvatar.svelte +0 -82
  828. package/src/skeleton/SkeletonButton.svelte +0 -90
  829. package/src/skeleton/SkeletonImage.svelte +0 -100
  830. package/src/skeleton/SkeletonParagraph.svelte +0 -103
  831. package/src/skeleton/SkeletonTitle.svelte +0 -74
  832. package/src/skeleton/context.ts +0 -11
  833. package/src/skeleton/index.ts +0 -8
  834. package/src/skeleton/meta.ts +0 -65
  835. package/src/slider/Slider.a11y.test.ts +0 -44
  836. package/src/slider/Slider.kbd.test.ts +0 -74
  837. package/src/slider/Slider.svelte +0 -716
  838. package/src/slider/SliderKbdFixture.svelte +0 -21
  839. package/src/slider/index.ts +0 -2
  840. package/src/slider/meta.ts +0 -55
  841. package/src/space/Space.a11y.test.ts +0 -22
  842. package/src/space/Space.svelte +0 -109
  843. package/src/space/SpaceA11yFixture.svelte +0 -17
  844. package/src/space/index.ts +0 -2
  845. package/src/space/meta.ts +0 -27
  846. package/src/spin/Spin.a11y.test.ts +0 -29
  847. package/src/spin/Spin.svelte +0 -293
  848. package/src/spin/SpinA11yFixture.svelte +0 -18
  849. package/src/spin/index.ts +0 -2
  850. package/src/spin/meta.ts +0 -72
  851. package/src/steps/Steps.a11y.test.ts +0 -39
  852. package/src/steps/Steps.kbd.test.ts +0 -73
  853. package/src/steps/Steps.svelte +0 -392
  854. package/src/steps/StepsKbdFixture.svelte +0 -21
  855. package/src/steps/index.ts +0 -3
  856. package/src/steps/meta.ts +0 -59
  857. package/src/steps/types.ts +0 -8
  858. package/src/switch/Switch.a11y.test.ts +0 -46
  859. package/src/switch/Switch.kbd.test.ts +0 -40
  860. package/src/switch/Switch.svelte +0 -310
  861. package/src/switch/SwitchKbdFixture.svelte +0 -22
  862. package/src/switch/index.ts +0 -2
  863. package/src/switch/meta.ts +0 -44
  864. package/src/table/Table.a11y.test.ts +0 -70
  865. package/src/table/Table.bench.ts +0 -51
  866. package/src/table/Table.kbd.test.ts +0 -94
  867. package/src/table/Table.svelte +0 -2327
  868. package/src/table/TableKbdFixture.svelte +0 -35
  869. package/src/table/grid-nav.test.ts +0 -173
  870. package/src/table/grid-nav.ts +0 -146
  871. package/src/table/index.ts +0 -13
  872. package/src/table/meta.ts +0 -121
  873. package/src/table/types.ts +0 -133
  874. package/src/tabs/TabPane.svelte +0 -92
  875. package/src/tabs/Tabs.a11y.test.ts +0 -47
  876. package/src/tabs/Tabs.kbd.test.ts +0 -74
  877. package/src/tabs/Tabs.svelte +0 -1128
  878. package/src/tabs/TabsA11yFixture.svelte +0 -20
  879. package/src/tabs/TabsKbdFixture.svelte +0 -25
  880. package/src/tabs/context.ts +0 -43
  881. package/src/tabs/index.ts +0 -14
  882. package/src/tabs/meta.ts +0 -152
  883. package/src/tabs/types.ts +0 -6
  884. package/src/tag/Tag.a11y.test.ts +0 -33
  885. package/src/tag/Tag.svelte +0 -366
  886. package/src/tag/TagA11yFixture.svelte +0 -18
  887. package/src/tag/index.ts +0 -2
  888. package/src/tag/meta.ts +0 -92
  889. package/src/tag-input/TagInput.a11y.test.ts +0 -41
  890. package/src/tag-input/TagInput.svelte +0 -544
  891. package/src/tag-input/index.ts +0 -2
  892. package/src/tag-input/meta.ts +0 -43
  893. package/src/tag-input/reorder.test.ts +0 -59
  894. package/src/tag-input/reorder.ts +0 -41
  895. package/src/test-utils/LocaleHarness.svelte +0 -29
  896. package/src/test-utils/a11y.ts +0 -108
  897. package/src/test-utils/kbd.ts +0 -52
  898. package/src/textarea/TextArea.a11y.test.ts +0 -44
  899. package/src/textarea/TextArea.svelte +0 -420
  900. package/src/textarea/index.ts +0 -2
  901. package/src/textarea/meta.ts +0 -104
  902. package/src/time-picker/TimePicker.a11y.test.ts +0 -45
  903. package/src/time-picker/TimePicker.kbd.test.ts +0 -70
  904. package/src/time-picker/TimePicker.svelte +0 -1023
  905. package/src/time-picker/TimePickerKbdFixture.svelte +0 -23
  906. package/src/time-picker/index.ts +0 -2
  907. package/src/time-picker/meta.ts +0 -64
  908. package/src/timeline/Timeline.a11y.test.ts +0 -54
  909. package/src/timeline/Timeline.svelte +0 -599
  910. package/src/timeline/TimelineItem.svelte +0 -164
  911. package/src/timeline/context.ts +0 -28
  912. package/src/timeline/index.ts +0 -16
  913. package/src/timeline/meta.ts +0 -129
  914. package/src/timeline/types.ts +0 -9
  915. package/src/toast/Toast.a11y.test.ts +0 -67
  916. package/src/toast/ToastContainer.svelte +0 -184
  917. package/src/toast/ToastItem.svelte +0 -247
  918. package/src/toast/index.ts +0 -9
  919. package/src/toast/live-region.ts +0 -78
  920. package/src/toast/meta.ts +0 -95
  921. package/src/toast/store.ts +0 -187
  922. package/src/tooltip/Tooltip.a11y.test.ts +0 -41
  923. package/src/tooltip/Tooltip.kbd.test.ts +0 -37
  924. package/src/tooltip/Tooltip.svelte +0 -416
  925. package/src/tooltip/TooltipA11yFixture.svelte +0 -31
  926. package/src/tooltip/TooltipKbdFixture.svelte +0 -16
  927. package/src/tooltip/index.ts +0 -2
  928. package/src/tooltip/meta.ts +0 -59
  929. package/src/tooltip/placement.ts +0 -6
  930. package/src/transfer/Transfer.a11y.test.ts +0 -63
  931. package/src/transfer/Transfer.kbd.test.ts +0 -75
  932. package/src/transfer/Transfer.svelte +0 -1451
  933. package/src/transfer/TransferKbdFixture.svelte +0 -23
  934. package/src/transfer/group.test.ts +0 -55
  935. package/src/transfer/group.ts +0 -61
  936. package/src/transfer/index.ts +0 -3
  937. package/src/transfer/meta.ts +0 -55
  938. package/src/transfer/reorder.test.ts +0 -52
  939. package/src/transfer/reorder.ts +0 -42
  940. package/src/transfer/tree.test.ts +0 -44
  941. package/src/transfer/tree.ts +0 -52
  942. package/src/transfer/types.ts +0 -32
  943. package/src/tree/Tree.a11y.test.ts +0 -63
  944. package/src/tree/Tree.kbd.test.ts +0 -91
  945. package/src/tree/Tree.svelte +0 -1500
  946. package/src/tree/TreeKbdFixture.svelte +0 -30
  947. package/src/tree/index.ts +0 -3
  948. package/src/tree/meta.ts +0 -152
  949. package/src/tree-select/TreeSelect.a11y.test.ts +0 -52
  950. package/src/tree-select/TreeSelect.kbd.test.ts +0 -53
  951. package/src/tree-select/TreeSelect.svelte +0 -1611
  952. package/src/tree-select/TreeSelectKbdFixture.svelte +0 -20
  953. package/src/tree-select/index.ts +0 -3
  954. package/src/tree-select/meta.ts +0 -73
  955. package/src/tree-select/types.ts +0 -11
  956. package/src/tree-select/virtual.test.ts +0 -104
  957. package/src/typography/Link.svelte +0 -120
  958. package/src/typography/Paragraph.svelte +0 -92
  959. package/src/typography/Text.svelte +0 -93
  960. package/src/typography/Title.svelte +0 -91
  961. package/src/typography/Typography.a11y.test.ts +0 -34
  962. package/src/typography/TypographyA11yFixture.svelte +0 -27
  963. package/src/typography/TypographyBase.svelte +0 -807
  964. package/src/typography/index.ts +0 -16
  965. package/src/typography/meta.ts +0 -158
  966. package/src/upload/Upload.a11y.test.ts +0 -58
  967. package/src/upload/Upload.svelte +0 -1094
  968. package/src/upload/UploadA11yFixture.svelte +0 -23
  969. package/src/upload/index.ts +0 -3
  970. package/src/upload/meta.ts +0 -64
  971. package/src/upload/types.ts +0 -16
  972. package/src/virtual-list/VirtualList.svelte +0 -401
  973. package/src/virtual-list/index.ts +0 -2
  974. package/src/virtual-list/meta.ts +0 -106
@@ -1,2327 +0,0 @@
1
- <!--
2
- Table — see specs/components/show/Table.spec.md
3
- 列定义驱动渲染:三态排序、客户端分页、行选择(含半选),受控/非受控双轨。
4
- 受控 sortState / rowSelection.selectedRowKeys / pagination.current 不回写,
5
- 仅通过 onSortChange / rowSelection.onChange / pagination.onChange 通知 (红线 #1)。
6
- 复用 @chenzy-design/core 纯函数算法与 Pagination 组件,不重复实现。
7
- 固定列:column.fixed='left'|'right',横滚时 sticky 锁定 + 逐列像素偏移 + 边界阴影。
8
- 列筛选:column.filters + onFilter,列头漏斗弹浮层多选过滤(复用 _floating + useDismiss)。
9
- 列宽拖拽:column.resizable,列头右侧拖拽手柄,指针几何命令式管理(红线 #3);
10
- 覆盖宽度存本地 SvelteMap 不写回 columns prop(红线 #1),进 cellStyle 宽度计算。
11
- 树形数据:tree=true 或 tree={{ childrenColumnName, indentSize, expandedRowKeys... }};
12
- 行含 children 自动嵌套,第一列内展开三角 + 逐级缩进;排序/分页/筛选作用于顶层行,
13
- 可见行经 core flattenTreeRows 纯函数扁平化驱动 tbody (红线 #2);受控展开 keys 不回写 (红线 #1)。
14
- 树形行选择父子联动:rowSelection.checkStrictly 默认 false=联动(勾父连带勾全部后代,
15
- 后代部分选中父行半选 indeterminate),true=父子独立(向后兼容)。联动 {checked,half} 经 core
16
- conductRows/toggleRowCheck 纯函数据整棵可见行树派生 (红线 #2);内部存叶子级 base,
17
- onChange 回传含父行的完整 checked 集;半选写 input.indeterminate 复用 attachment (红线 #3)。
18
- 行虚拟滚动:virtualized=true 时 .cd-table-wrap 自身纵向滚动(固定 height),thead sticky 固定顶部,
19
- tbody 仅渲染视口内行切片(复用 core fixedRange 算可见区间),首尾各一个 padding spacer tr 撑出
20
- 未渲染行总高(保持原生 <table>/<tr>/<td> 语义与 a11y)。scrollTop 命令式 scroll 回调 + rAF 节流写入
21
- 本地 $state,可见区间纯 $derived render 期只读(红线 #2/#3)。virtualized 与 pagination 互斥(虚拟时
22
- 忽略分页全量滚动);排序/筛选/行选择/树形/固定列均正常协同。假定行等高,不建议与 expandable 混用。
23
- -->
24
- <script lang="ts" generics="T extends Record<string, unknown>">
25
- import {
26
- toggleSort,
27
- applySort,
28
- paginate,
29
- selectAllState,
30
- toggleSelectAll,
31
- toggleRow,
32
- flattenTreeRows,
33
- conductRows,
34
- toggleRowCheck,
35
- fixedRange,
36
- useLiveAnnouncer,
37
- useId,
38
- type RowKey,
39
- type SortState,
40
- type FlatRow,
41
- } from '@chenzy-design/core';
42
- import { tick } from 'svelte';
43
- import type { Snippet } from 'svelte';
44
- import { SvelteMap } from 'svelte/reactivity';
45
- import { Pagination } from '../pagination/index.js';
46
- import { floating } from '../_floating/use-floating.js';
47
- import { useDismiss } from '@chenzy-design/core';
48
- import { useLocale } from '../locale-provider/index.js';
49
- import {
50
- buildGridCols,
51
- nextGridCoord,
52
- isFocusCell as isFocusCellPure,
53
- rovingTabindexAt,
54
- type GridCol,
55
- } from './grid-nav.js';
56
- import type {
57
- ColumnDef,
58
- RowSelection,
59
- Expandable,
60
- TreeTable,
61
- Align,
62
- TableSize,
63
- TableChangeInfo,
64
- TableChangeAction,
65
- TableScrollInfo,
66
- ScrollConfig,
67
- } from './types.js';
68
-
69
- // 泛型组件 props 用内联类型而非具名 interface Props:在 declaration:true 下,
70
- // 引用泛型参数 T 的具名 interface 会被当作私有名泄漏进生成的 .d.ts 公共签名而报错。
71
- let {
72
- columns = [],
73
- dataSource = [],
74
- rowKey = 'key',
75
- size = 'default',
76
- bordered = false,
77
- stripe = false,
78
- loading = false,
79
- sortState,
80
- defaultSortState = { key: null, order: null },
81
- onSortChange,
82
- pagination,
83
- rowSelection,
84
- expandable,
85
- tree,
86
- rowClassName,
87
- empty,
88
- ariaLabel,
89
- onRowClick,
90
- onChange,
91
- onFilterChange,
92
- onPaginationChange,
93
- onSelectChange,
94
- onExpandChange,
95
- onScroll,
96
- onReachBottom,
97
- reachBottomThreshold = 0,
98
- virtualized = false,
99
- height = 400,
100
- rowHeight = 48,
101
- gridNav,
102
- scroll,
103
- sticky = false,
104
- showHeader = true,
105
- defaultExpandAllRows = false,
106
- getPopupContainer,
107
- onRow,
108
- onHeaderRow,
109
- expandRowByClick = false,
110
- expandCellFixed,
111
- keepDOM = false,
112
- indentSize: indentSizeProp = 20,
113
- groupBy,
114
- renderGroupSection,
115
- titleSnippet,
116
- footerSnippet,
117
- }: {
118
- columns?: ColumnDef<T>[];
119
- dataSource?: T[];
120
- rowKey?: string | ((record: T) => RowKey);
121
- size?: TableSize;
122
- bordered?: boolean;
123
- stripe?: boolean;
124
- loading?: boolean;
125
- sortState?: SortState;
126
- defaultSortState?: SortState;
127
- onSortChange?: (state: SortState) => void;
128
- pagination?:
129
- | false
130
- | {
131
- pageSize?: number;
132
- current?: number;
133
- defaultCurrent?: number;
134
- onChange?: (page: number) => void;
135
- };
136
- rowSelection?: RowSelection<T>;
137
- expandable?: Expandable<T>;
138
- tree?: boolean | TreeTable;
139
- rowClassName?: (record: T, index: number) => string;
140
- empty?: string;
141
- ariaLabel?: string;
142
- onRowClick?: (info: { record: T; index: number }) => void;
143
- /** 聚合事件:排序/筛选/分页任一变化的主入口(受控数据回流)。spec §4 */
144
- onChange?: (info: TableChangeInfo) => void;
145
- /** 筛选状态变化(含重置)。spec §4 */
146
- onFilterChange?: (info: { dataIndex: string; values: (string | number)[] }) => void;
147
- /** 分页变化。spec §4 */
148
- onPaginationChange?: (info: { current: number; pageSize: number }) => void;
149
- /** 选择集变化(与 rowSelection.onChange 同时触发)。spec §4 */
150
- onSelectChange?: (info: { selectedRowKeys: RowKey[]; selectedRows: T[] }) => void;
151
- /** 行展开/收起(展开行与树形行均触发)。spec §4 */
152
- onExpandChange?: (info: {
153
- expanded: boolean;
154
- record: T;
155
- expandedRowKeys: RowKey[];
156
- }) => void;
157
- /** 滚动位置(含触底,用于无限加载)。命令式监听滚动容器。spec §4 */
158
- onScroll?: (info: TableScrollInfo) => void;
159
- /** 纵向触底(懒加载触发)。距底 reachBottomThreshold 像素内触发一次。spec §4 */
160
- onReachBottom?: () => void;
161
- /** onReachBottom 触发阈值(距底像素),默认 0(精确触底) */
162
- reachBottomThreshold?: number;
163
- /** 行虚拟滚动:仅渲染视口内行,适合大数据(1000+ 行)。默认 false(行为不变)。
164
- * 启用时忽略 pagination(全量滚动),表头 sticky 固定于滚动容器顶部。
165
- * 假定行等高(rowHeight);与 expandable 同用时展开内容行不计入高度,故不建议混用。 */
166
- virtualized?: boolean;
167
- /** 虚拟滚动视口高度(px)。virtualized 时生效,默认 400 */
168
- height?: number;
169
- /** 虚拟滚动行高(px)。virtualized 时生效,默认 48 */
170
- rowHeight?: number;
171
- /**
172
- * 交互态 WAI-ARIA Grid Pattern 开关(role=grid + 单元格二维方向键漫游 +
173
- * roving tabindex + 虚拟化焦点回收)。
174
- * - 缺省(undefined):当存在交互能力(排序/筛选/行选择/展开/树形/行点击)时自动启用 grid,
175
- * 纯展示表保持 role=table,省去漫游逻辑(spec §3 纯展示降级)。
176
- * - 显式 true/false:强制启用/关闭 grid 漫游。
177
- */
178
- gridNav?: boolean;
179
- /** 横/纵向滚动配置,x 设最小宽度并横向溢出,y 设最大高度并纵向溢出 */
180
- scroll?: ScrollConfig;
181
- /** 表头吸顶:true 时表头 sticky 定位;对象时可指定 offsetHeader(px) */
182
- sticky?: boolean | { offsetHeader?: number };
183
- /** 是否显示表头,默认 true */
184
- showHeader?: boolean;
185
- /** 默认展开全部行(包含树形行),默认 false */
186
- defaultExpandAllRows?: boolean;
187
- /** 筛选浮层挂载容器,默认跟随触发按钮 */
188
- getPopupContainer?: () => HTMLElement;
189
- /** 行级事件与属性(返回 onClick/onDoubleClick/className/style) */
190
- onRow?: (record: T, index: number) => { onClick?: (e: MouseEvent) => void; onDoubleClick?: (e: MouseEvent) => void; className?: string; style?: string };
191
- /** 表头行级事件与属性 */
192
- onHeaderRow?: (columns: ColumnDef<T>[], index: number) => { onClick?: (e: MouseEvent) => void; className?: string; style?: string };
193
- /** 点击行体时触发展开/收起,默认 false */
194
- expandRowByClick?: boolean;
195
- /** 展开图标列固定方向 */
196
- expandCellFixed?: boolean | 'left' | 'right';
197
- /** keepDOM=true 时保留已展开行 DOM 但隐藏(display:none),默认 false */
198
- keepDOM?: boolean;
199
- /** 树形缩进像素,默认 20(tree.indentSize 优先) */
200
- indentSize?: number;
201
- /** 按字段名或函数对数据行分组,插入分组标题行 */
202
- groupBy?: string | ((record: T) => string);
203
- /** 自定义分组标题渲染 */
204
- renderGroupSection?: Snippet<[{ groupKey: string; group: T[] }]>;
205
- /** 表格顶部标题区域 */
206
- titleSnippet?: Snippet;
207
- /** 表格底部内容区域(接收 currentData) */
208
- footerSnippet?: Snippet<[{ currentData: T[] }]>;
209
- } = $props();
210
-
211
- const loc = useLocale();
212
- // 单例 live region(polite):排序结果播报给屏幕阅读器(命令式写入在事件回调,红线 #3)。
213
- const announcer = useLiveAnnouncer();
214
-
215
- // --- 键解析 ---
216
- const getKey = (record: T): RowKey =>
217
- typeof rowKey === 'function' ? rowKey(record) : (record[rowKey] as RowKey);
218
-
219
- const colKeyOf = (col: ColumnDef<T>, index: number): string =>
220
- col.key ?? col.dataIndex ?? String(index);
221
-
222
- // --- 列宽拖拽:本地覆盖宽度 (colKey → px),不写回 columns prop (红线 #1) ---
223
- const MIN_COL_WIDTH = 40;
224
- const widthOverrides = new SvelteMap<string, number>();
225
- // 拖拽手柄所在列头引用(用于 pointerdown 读取起始几何)
226
- const resizeHandles: Record<string, HTMLElement | null> = $state({});
227
- // 当前正在拖拽的列 key(用于手柄高亮 / body class)
228
- let resizingKey = $state<string | null>(null);
229
-
230
- // 解析某列最终宽度:覆盖宽度优先,否则 col.width
231
- function resolveWidth(col: ColumnDef<T>, index: number): number | string | undefined {
232
- const ov = widthOverrides.get(colKeyOf(col, index));
233
- if (ov !== undefined) return ov;
234
- return col.width;
235
- }
236
-
237
- // 列头拖拽:命令式管理指针几何 (红线 #3)。
238
- // pointerdown 一次性把起始宽度 / clientX 存普通变量,document 上手动绑定
239
- // pointermove / pointerup,结束时解绑。绝不用响应式 attachment 读几何。
240
- function startResize(event: PointerEvent, col: ColumnDef<T>, index: number) {
241
- event.preventDefault();
242
- event.stopPropagation();
243
- const colKey = colKeyOf(col, index);
244
- const th = resizeHandles[colKey]?.closest('th') as HTMLElement | null;
245
- // 起始宽度:已有覆盖 > col.width 数值 > 实测列头宽度
246
- const ov = widthOverrides.get(colKey);
247
- const startWidth =
248
- ov ?? (typeof col.width === 'number' ? col.width : (th?.getBoundingClientRect().width ?? MIN_COL_WIDTH));
249
- const startX = event.clientX;
250
-
251
- resizingKey = colKey;
252
-
253
- const onMove = (e: PointerEvent) => {
254
- const next = Math.max(MIN_COL_WIDTH, Math.round(startWidth + (e.clientX - startX)));
255
- widthOverrides.set(colKey, next);
256
- };
257
- const onUp = () => {
258
- document.removeEventListener('pointermove', onMove);
259
- document.removeEventListener('pointerup', onUp);
260
- activeMove = null;
261
- activeUp = null;
262
- resizingKey = null;
263
- };
264
- activeMove = onMove;
265
- activeUp = onUp;
266
- document.addEventListener('pointermove', onMove);
267
- document.addEventListener('pointerup', onUp);
268
- }
269
-
270
- // 卸载兜底:若拖拽未结束就卸载,清掉可能遗留的全局监听 (红线 #3)。
271
- let activeMove: ((e: PointerEvent) => void) | null = null;
272
- let activeUp: (() => void) | null = null;
273
- $effect(() => () => {
274
- if (activeMove) document.removeEventListener('pointermove', activeMove);
275
- if (activeUp) document.removeEventListener('pointerup', activeUp);
276
- });
277
-
278
- // --- 排序:受控 sortState 不回写 (红线 #1) ---
279
- const isSortControlled = $derived(sortState !== undefined);
280
- let innerSort = $state<SortState>(initSort());
281
- const currentSort = $derived<SortState>(
282
- isSortControlled ? (sortState as SortState) : innerSort,
283
- );
284
- function initSort(): SortState {
285
- // Check for per-column defaultSortOrder
286
- for (let i = 0; i < columns.length; i++) {
287
- const col = columns[i] as ColumnDef<T>;
288
- if (col.defaultSortOrder != null) {
289
- return { key: colKeyOf(col, i), order: col.defaultSortOrder };
290
- }
291
- }
292
- return { ...defaultSortState };
293
- }
294
-
295
- // --- 列筛选:本地 state(colKey → 选中值集合),不写回 props (红线 #1) ---
296
- const filterState = new SvelteMap<string, Set<string | number>>();
297
- // 打开的筛选浮层列 key(同时只开一个)
298
- let openFilterKey = $state<string | null>(null);
299
- // 各列漏斗按钮引用(trigger)+ 当前浮层引用(dismiss extraTargets)
300
- const filterTriggers: Record<string, HTMLButtonElement | null> = $state({});
301
- let filterPanelEl = $state<HTMLDivElement | null>(null);
302
-
303
- // 浮层外点击/Esc 关闭(红线 #3:$effect 内 useDismiss,cleanup 解绑)
304
- $effect(() => {
305
- if (openFilterKey === null) return;
306
- const trigger = filterTriggers[openFilterKey];
307
- if (!trigger) return;
308
- return useDismiss(trigger, {
309
- onDismiss: () => (openFilterKey = null),
310
- escape: true,
311
- outsideClick: true,
312
- extraTargets: [filterPanelEl],
313
- });
314
- });
315
-
316
- function activeFilterValues(colKey: string): Set<string | number> {
317
- return filterState.get(colKey) ?? new Set();
318
- }
319
- function isFiltered(colKey: string): boolean {
320
- return (filterState.get(colKey)?.size ?? 0) > 0;
321
- }
322
- function toggleFilterValue(colKey: string, value: string | number) {
323
- const cur = new Set(filterState.get(colKey) ?? []);
324
- if (cur.has(value)) cur.delete(value);
325
- else cur.add(value);
326
- filterState.set(colKey, cur);
327
- emitFilterChange(colKey, [...cur]);
328
- }
329
- function resetFilter(colKey: string) {
330
- filterState.set(colKey, new Set());
331
- openFilterKey = null;
332
- emitFilterChange(colKey, []);
333
- }
334
- // 筛选变化:单列 onFilterChange + 聚合 onChange。dataIndex 优先列 dataIndex,回退 colKey。
335
- function emitFilterChange(colKey: string, values: (string | number)[]) {
336
- const col = columns.find((c, i) => colKeyOf(c, i) === colKey);
337
- onFilterChange?.({ dataIndex: col?.dataIndex ?? colKey, values });
338
- emitChange('filter');
339
- }
340
- // 行是否通过某列筛选:选中值任一 onFilter 命中(缺省按 dataIndex 全等)。
341
- function rowPassesColumn(col: ColumnDef<T>, colKey: string, record: T): boolean {
342
- const selected = filterState.get(colKey);
343
- if (!selected || selected.size === 0) return true;
344
- const test =
345
- col.onFilter ??
346
- ((value: string | number, rec: T): boolean =>
347
- col.dataIndex ? rec[col.dataIndex] === value : false);
348
- for (const v of selected) {
349
- if (test(v, record)) return true;
350
- }
351
- return false;
352
- }
353
-
354
- // 合并某列的有效筛选值:filteredValue(受控)优先,否则本地 filterState。
355
- function effectiveFilterValues(col: ColumnDef<T>, colKey: string): Set<string | number> {
356
- if (col.filteredValue !== undefined) {
357
- if (col.filteredValue === null) return new Set();
358
- return new Set(col.filteredValue);
359
- }
360
- return filterState.get(colKey) ?? new Set();
361
- }
362
- function isEffectivelyFiltered(col: ColumnDef<T>, colKey: string): boolean {
363
- return effectiveFilterValues(col, colKey).size > 0;
364
- }
365
-
366
- // --- 数据管道:列筛选 → 排序(客户端)。状态全来自 props / 本地 $state,派生安全 (红线 #2) ---
367
- const processed = $derived.by(() => {
368
- let data = [...dataSource];
369
- // 列筛选(多列 AND)
370
- for (let i = 0; i < columns.length; i++) {
371
- const col = columns[i] as ColumnDef<T>;
372
- const ck = colKeyOf(col, i);
373
- if (isEffectivelyFiltered(col, ck)) {
374
- const selected = effectiveFilterValues(col, ck);
375
- const test =
376
- col.onFilter ??
377
- ((value: string | number, rec: T): boolean =>
378
- col.dataIndex ? rec[col.dataIndex] === value : false);
379
- data = data.filter((rec) => {
380
- for (const v of selected) {
381
- if (test(v, rec)) return true;
382
- }
383
- return false;
384
- });
385
- }
386
- }
387
- const { key, order } = currentSort;
388
- if (key && order) {
389
- let target: ColumnDef<T> | undefined;
390
- columns.forEach((col, i) => {
391
- if (colKeyOf(col, i) === key) target = col;
392
- });
393
- if (target && target.sorter) {
394
- const dataIndex = target.dataIndex;
395
- const compare =
396
- typeof target.sorter === 'function'
397
- ? target.sorter
398
- : (a: T, b: T): number => {
399
- if (!dataIndex) return 0;
400
- const av = a[dataIndex];
401
- const bv = b[dataIndex];
402
- if (av == null && bv == null) return 0;
403
- if (av == null) return -1;
404
- if (bv == null) return 1;
405
- if (typeof av === 'number' && typeof bv === 'number') return av - bv;
406
- return String(av).localeCompare(String(bv));
407
- };
408
- data = applySort(data, order, compare);
409
- }
410
- }
411
- return data;
412
- });
413
-
414
- // --- 分页:受控 current 不回写 (红线 #1) ---
415
- // virtualized 与分页互斥:虚拟滚动时全量渲染滚动,忽略 pagination(取舍见 props 注释)。
416
- const paginationEnabled = $derived(!virtualized && pagination !== false);
417
- const pageSize = $derived(pagination ? (pagination.pageSize ?? 10) : 10);
418
- const isPageControlled = $derived(!!pagination && pagination.current !== undefined);
419
- let innerPage = $state(initPage());
420
- function initPage(): number {
421
- return pagination ? (pagination.defaultCurrent ?? 1) : 1;
422
- }
423
- const currentPage = $derived(
424
- pagination && pagination.current !== undefined ? pagination.current : innerPage,
425
- );
426
-
427
- const total = $derived(processed.length);
428
- const visibleRows = $derived(
429
- paginationEnabled ? paginate(processed, currentPage, pageSize) : processed,
430
- );
431
-
432
- // --- 行选择:受控 selectedRowKeys 不回写 (红线 #1) ---
433
- const isSelectionControlled = $derived(
434
- rowSelection?.selectedRowKeys !== undefined,
435
- );
436
- let innerSelected = $state<RowKey[]>(initSelected());
437
- function initSelected(): RowKey[] {
438
- return [...(rowSelection?.defaultSelectedRowKeys ?? [])];
439
- }
440
- const currentSelectedKeys = $derived<RowKey[]>(
441
- isSelectionControlled
442
- ? (rowSelection?.selectedRowKeys ?? [])
443
- : innerSelected,
444
- );
445
- const selectedSet = $derived(new Set(currentSelectedKeys));
446
-
447
- // --- 树形数据(嵌套行)---
448
- // tree 启用时:filter/sort/paginate 作用于顶层行(processed/visibleRows),
449
- // 然后据展开态把可见顶层行扁平化为带 level/hasChildren 的渲染行列表。
450
- // 受控 tree.expandedRowKeys 不回写,仅 onExpand 通知 (红线 #1)。
451
- const treeEnabled = $derived(tree !== undefined && tree !== false);
452
- const treeOpts = $derived<TreeTable>(typeof tree === 'object' ? tree : {});
453
- const childrenColumnName = $derived(treeOpts.childrenColumnName ?? 'children');
454
- const indentSize = $derived(treeOpts.indentSize ?? indentSizeProp);
455
-
456
- function getChildren(record: T): T[] | undefined {
457
- const kids = record[childrenColumnName];
458
- return Array.isArray(kids) ? (kids as T[]) : undefined;
459
- }
460
-
461
- // --- 树形行选择父子联动 ---
462
- // checkStrictly 默认 false=联动;true 时父子独立(与非树形逐行选择一致,向后兼容)。
463
- // 联动仅在树形 + 有行选择时生效。联动态下 base 选中集为叶子级,经纯函数
464
- // conductRows(顶层可见行树) 派生 {checked, half}(红线 #2:纯函数 + $derived)。
465
- const treeCheckable = $derived(
466
- treeEnabled && rowSelection !== undefined && rowSelection.checkStrictly !== true,
467
- );
468
- const rowDisabledFn = (record: T): boolean =>
469
- rowSelection?.getCheckboxProps?.(record)?.disabled ?? false;
470
- // 联动选择派生:覆盖整棵可见顶层行树(含未展开的子行)。
471
- const conducted = $derived.by(() => {
472
- if (!treeCheckable) return { checked: selectedSet, half: new Set<RowKey>() };
473
- return conductRows(visibleRows, selectedSet, getKey, getChildren, rowDisabledFn);
474
- });
475
-
476
- const isTreeExpandControlled = $derived(treeOpts.expandedRowKeys !== undefined);
477
- let innerTreeExpanded = $state<RowKey[]>(initTreeExpanded());
478
- function initTreeExpanded(): RowKey[] {
479
- if (typeof tree === 'object' && tree.defaultExpandedRowKeys) {
480
- return [...tree.defaultExpandedRowKeys];
481
- }
482
- if (defaultExpandAllRows) {
483
- // 递归收集所有含子行的行 key
484
- const keys: RowKey[] = [];
485
- const col = typeof tree === 'object' ? (tree.childrenColumnName ?? 'children') : 'children';
486
- const walk = (records: T[]): void => {
487
- for (const r of records) {
488
- const k = typeof rowKey === 'function' ? rowKey(r) : (r[rowKey as string] as RowKey);
489
- const kids = r[col];
490
- if (Array.isArray(kids) && kids.length > 0) {
491
- keys.push(k);
492
- walk(kids as T[]);
493
- }
494
- }
495
- };
496
- walk(dataSource);
497
- return keys;
498
- }
499
- return [];
500
- }
501
- const treeExpandedSet = $derived<Set<RowKey>>(
502
- new Set(isTreeExpandControlled ? (treeOpts.expandedRowKeys ?? []) : innerTreeExpanded),
503
- );
504
-
505
- function toggleTreeExpand(record: T) {
506
- const key = getKey(record);
507
- const next = new Set(treeExpandedSet);
508
- const willExpand = !next.has(key);
509
- if (willExpand) next.add(key);
510
- else next.delete(key);
511
- if (!isTreeExpandControlled) innerTreeExpanded = [...next];
512
- treeOpts.onExpand?.(willExpand, key);
513
- onExpandChange?.({ expanded: willExpand, record, expandedRowKeys: [...next] });
514
- }
515
-
516
- // 扁平化可见行:纯 $derived,不读 effect 写的状态 (红线 #2)。
517
- // 顶层行已是分页后的 visibleRows;树形时递归展开,否则等价 1:1 映射。
518
- const displayRows = $derived.by<FlatRow<T>[]>(() => {
519
- if (!treeEnabled) {
520
- return visibleRows.map((record, i) => ({
521
- record,
522
- key: getKey(record),
523
- level: 0,
524
- parentKey: null,
525
- hasChildren: false,
526
- topIndex: i,
527
- }));
528
- }
529
- return flattenTreeRows(visibleRows, treeExpandedSet, getKey, getChildren);
530
- });
531
-
532
- // --- 行虚拟滚动:仅渲染视口内行(复用 core fixedRange 纯函数)---
533
- // 视口容器自身滚动,scrollTop 由命令式 scroll 回调写入;可见区间纯 $derived
534
- // 仅依赖本地 $state,render 期只读不读 DOM(红线 #2)。
535
- const VIRTUAL_OVERSCAN = 4;
536
- let scrollEl = $state<HTMLDivElement | null>(null);
537
- // 仅由 scroll 回调写入的本地 scrollTop,render 期只读。
538
- let scrollTop = $state(0);
539
- // rAF 节流句柄(非响应式)。
540
- let rafId = 0;
541
- // onReachBottom 去抖:仅在「进入触底区」的那一帧触发一次,离开后复位(非响应式)。
542
- let reachedBottom = false;
543
-
544
- const vRowHeight = $derived(rowHeight > 0 ? rowHeight : 48);
545
- const vTotalHeight = $derived(displayRows.length * vRowHeight);
546
- const vRange = $derived(
547
- virtualized
548
- ? fixedRange(scrollTop, height, vRowHeight, displayRows.length, VIRTUAL_OVERSCAN)
549
- : { startIndex: 0, endIndex: displayRows.length },
550
- );
551
- // 实际喂给 #each 的行集合:virtualized 时只取视口内切片,否则全量。
552
- const renderRows = $derived(
553
- virtualized ? displayRows.slice(vRange.startIndex, vRange.endIndex) : displayRows,
554
- );
555
- // 上下 spacer 行高度:未渲染的上方/下方行总高,撑出正确总高(保持原生 table 语义)。
556
- const vTopPad = $derived(virtualized ? vRange.startIndex * vRowHeight : 0);
557
- const vBottomPad = $derived(
558
- virtualized ? Math.max(0, (displayRows.length - vRange.endIndex) * vRowHeight) : 0,
559
- );
560
-
561
- // 滚动监听需附着的容器是否需要纵向滚动能力:
562
- // 非虚拟化但提供了 onScroll/onReachBottom 时,约束高度并 overflow:auto,
563
- // 使表体可纵向滚动从而能上报位置/触底(虚拟化已自带固定高度滚动)。
564
- const scrollBody = $derived(!virtualized && (!!onScroll || !!onReachBottom));
565
-
566
- // 滚动监听(命令式 + rAF 节流 + cleanup)(红线 #3)。
567
- // 同时服务:① virtualized 视口区间计算(写 scrollTop)② onScroll 位置回调 ③ onReachBottom 触底。
568
- $effect(() => {
569
- const el = scrollEl;
570
- const needScroll = virtualized || !!onScroll || !!onReachBottom;
571
- if (!el || !needScroll) return;
572
- const handleScroll = () => {
573
- if (rafId) return;
574
- rafId = requestAnimationFrame(() => {
575
- rafId = 0;
576
- if (!el) return;
577
- if (virtualized) scrollTop = el.scrollTop;
578
- const { scrollLeft, scrollTop: sTop, scrollWidth, clientWidth, scrollHeight, clientHeight } = el;
579
- const atBottom = sTop + clientHeight >= scrollHeight - Math.max(0, reachBottomThreshold) - 1;
580
- if (onScroll) {
581
- onScroll({
582
- scrollLeft,
583
- scrollTop: sTop,
584
- atLeft: scrollLeft <= 0,
585
- atRight: scrollLeft + clientWidth >= scrollWidth - 1,
586
- atTop: sTop <= 0,
587
- atBottom,
588
- });
589
- }
590
- // 触底懒加载:仅在「刚进入触底区」触发一次,离开后复位(避免持续滚动重复触发)。
591
- if (onReachBottom) {
592
- if (atBottom && !reachedBottom) {
593
- reachedBottom = true;
594
- onReachBottom();
595
- } else if (!atBottom) {
596
- reachedBottom = false;
597
- }
598
- }
599
- });
600
- };
601
- el.addEventListener('scroll', handleScroll, { passive: true });
602
- return () => {
603
- el.removeEventListener('scroll', handleScroll);
604
- reachedBottom = false;
605
- if (rafId) {
606
- cancelAnimationFrame(rafId);
607
- rafId = 0;
608
- }
609
- };
610
- });
611
-
612
- // 全选范围 = 当前渲染行集(树形含已展开的子行);半选据可见行计算
613
- const visibleKeys = $derived(displayRows.map((r) => r.key));
614
- const disabledSet = $derived.by(() => {
615
- const set = new Set<RowKey>();
616
- const getProps = rowSelection?.getCheckboxProps;
617
- if (getProps) {
618
- for (const r of displayRows) {
619
- if (getProps(r.record).disabled) set.add(r.key);
620
- }
621
- }
622
- return set;
623
- });
624
- // 全选状态:联动态据「整棵可见行树」的顶层行 checked/half 计算
625
- // (顶层行全 checked → 全选;任一 half 或部分 checked → 半选),
626
- // 否则沿用扁平可见行的 selectAllState。
627
- const topKeys = $derived(visibleRows.map((r) => getKey(r)));
628
- const headerSelect = $derived.by(() => {
629
- if (!treeCheckable) return selectAllState(visibleKeys, selectedSet, disabledSet);
630
- const tops = topKeys.filter((k) => !disabledSet.has(k));
631
- if (tops.length === 0) return { checked: false, indeterminate: false };
632
- const allChecked = tops.every((k) => conducted.checked.has(k));
633
- const anyMarked = tops.some(
634
- (k) => conducted.checked.has(k) || conducted.half.has(k),
635
- );
636
- return { checked: allChecked, indeterminate: !allChecked && anyMarked };
637
- });
638
-
639
- const hasSelection = $derived(rowSelection !== undefined);
640
- const hasExpand = $derived(expandable !== undefined);
641
- const colSpan = $derived(
642
- columns.length + (hasSelection ? 1 : 0) + (hasExpand ? 1 : 0),
643
- );
644
-
645
- // --- 展开行:受控 expandedRowKeys 不回写 (红线 #1) ---
646
- const isExpandControlled = $derived(expandable?.expandedRowKeys !== undefined);
647
- let innerExpanded = $state<RowKey[]>(initExpanded());
648
- function initExpanded(): RowKey[] {
649
- if (expandable?.defaultExpandedRowKeys) {
650
- return [...expandable.defaultExpandedRowKeys];
651
- }
652
- if (defaultExpandAllRows && expandable) {
653
- return dataSource.map((r) =>
654
- typeof rowKey === 'function' ? rowKey(r) : (r[rowKey as string] as RowKey),
655
- );
656
- }
657
- return [];
658
- }
659
- const expandedSet = $derived<Set<RowKey>>(
660
- new Set(
661
- isExpandControlled
662
- ? (expandable?.expandedRowKeys ?? [])
663
- : innerExpanded,
664
- ),
665
- );
666
-
667
- function canExpand(record: T): boolean {
668
- return expandable?.rowExpandable ? expandable.rowExpandable(record) : true;
669
- }
670
-
671
- function toggleExpand(record: T) {
672
- const key = getKey(record);
673
- if (!canExpand(record)) return;
674
- const next = new Set(expandedSet);
675
- const willExpand = !next.has(key);
676
- if (willExpand) next.add(key);
677
- else next.delete(key);
678
- if (!isExpandControlled) innerExpanded = [...next];
679
- expandable?.onExpand?.(willExpand, record);
680
- onExpandChange?.({ expanded: willExpand, record, expandedRowKeys: [...next] });
681
- }
682
-
683
- // --- 选择变更:回调取对应行对象 ---
684
- // 联动树形需含未展开的子行,故据整棵可见行树建 key→record 映射;
685
- // 非树形/严格态沿用扁平 displayRows。
686
- const keyRecordMap = $derived.by(() => {
687
- const map = new Map<RowKey, T>();
688
- if (treeCheckable) {
689
- const walk = (record: T): void => {
690
- map.set(getKey(record), record);
691
- const kids = getChildren(record);
692
- if (kids) for (const c of kids) walk(c);
693
- };
694
- for (const r of visibleRows) walk(r);
695
- } else {
696
- for (const r of displayRows) map.set(r.key, r.record);
697
- }
698
- return map;
699
- });
700
- function rowsForKeys(keys: RowKey[]): T[] {
701
- const result: T[] = [];
702
- for (const k of keys) {
703
- const r = keyRecordMap.get(k);
704
- if (r !== undefined) result.push(r);
705
- }
706
- return result;
707
- }
708
-
709
- // next 是叶子级 base 集(联动态可经 conductRows round-trip)。
710
- // 内部态存 base;onChange 联动态回传含父行的完整 checked 集 + 行。
711
- function emitSelection(next: Set<RowKey>) {
712
- if (!isSelectionControlled) innerSelected = [...next];
713
- if (treeCheckable) {
714
- const { checked } = conductRows(visibleRows, next, getKey, getChildren, rowDisabledFn);
715
- const keys = [...checked];
716
- const rows = rowsForKeys(keys);
717
- rowSelection?.onChange?.(keys, rows);
718
- onSelectChange?.({ selectedRowKeys: keys, selectedRows: rows });
719
- } else {
720
- const keys = [...next];
721
- const rows = rowsForKeys(keys);
722
- rowSelection?.onChange?.(keys, rows);
723
- onSelectChange?.({ selectedRowKeys: keys, selectedRows: rows });
724
- }
725
- }
726
-
727
- function onToggleAll() {
728
- // radio 模式无全选
729
- if (rowSelection?.type === 'radio') return;
730
- if (treeCheckable) {
731
- // 全选:勾全部可见顶层行(连带后代叶子);已全选则清空。
732
- const tops = topKeys.filter((k) => !disabledSet.has(k));
733
- const allChecked = tops.length > 0 && tops.every((k) => conducted.checked.has(k));
734
- let next = new Set(selectedSet);
735
- for (const k of tops) {
736
- // 目标态:全选则要 off,否则要 on;与当前态不符才 toggle
737
- const isOn = conducted.checked.has(k);
738
- if (allChecked === isOn) {
739
- next = toggleRowCheck(visibleRows, next, k, getKey, getChildren, rowDisabledFn);
740
- }
741
- }
742
- const wasSelected = allChecked;
743
- emitSelection(next);
744
- // onSelectAll 回调
745
- if (rowSelection?.onSelectAll) {
746
- const { checked } = treeCheckable
747
- ? conductRows(visibleRows, next, getKey, getChildren, rowDisabledFn)
748
- : { checked: next };
749
- const selectedRows = rowsForKeys([...checked]);
750
- // changedRows: 非 disabled 的顶层行对应记录
751
- const changedRows = tops.map((k) => keyRecordMap.get(k)).filter((r): r is T => r !== undefined);
752
- rowSelection.onSelectAll(!wasSelected, selectedRows, changedRows);
753
- }
754
- return;
755
- }
756
- const prevKeys = [...selectedSet];
757
- const next = toggleSelectAll(visibleKeys, selectedSet, disabledSet);
758
- emitSelection(next);
759
- // onSelectAll 回调
760
- if (rowSelection?.onSelectAll) {
761
- const nextKeys = [...next];
762
- const isNowSelected = nextKeys.length > prevKeys.length;
763
- const selectedRows = rowsForKeys(nextKeys);
764
- const changedKeys = isNowSelected
765
- ? nextKeys.filter((k) => !selectedSet.has(k))
766
- : prevKeys.filter((k) => !next.has(k));
767
- const changedRows = rowsForKeys(changedKeys);
768
- rowSelection.onSelectAll(isNowSelected, selectedRows, changedRows);
769
- }
770
- }
771
-
772
- function onToggleRow(record: T) {
773
- const key = getKey(record);
774
- if (disabledSet.has(key)) return;
775
- const isRadio = rowSelection?.type === 'radio';
776
- if (isRadio) {
777
- // 单选:直接将选中集设为该行
778
- const next = new Set<RowKey>([key]);
779
- const wasSelected = selectedSet.has(key);
780
- emitSelection(next);
781
- rowSelection?.onSelect?.(record, !wasSelected, rowsForKeys([...next]));
782
- return;
783
- }
784
- const wasSelected = selectedSet.has(key);
785
- if (treeCheckable) {
786
- const next = toggleRowCheck(visibleRows, selectedSet, key, getKey, getChildren, rowDisabledFn);
787
- emitSelection(next);
788
- const { checked } = conductRows(visibleRows, next, getKey, getChildren, rowDisabledFn);
789
- rowSelection?.onSelect?.(record, !wasSelected, rowsForKeys([...checked]));
790
- return;
791
- }
792
- const next = toggleRow(selectedSet, key);
793
- emitSelection(next);
794
- rowSelection?.onSelect?.(record, !wasSelected, rowsForKeys([...next]));
795
- }
796
-
797
- // ===================================================================
798
- // 交互态 WAI-ARIA Grid Pattern:role=grid + 二维方向键漫游 + roving
799
- // tabindex + 虚拟化焦点回收。
800
- //
801
- // 焦点模型(红线 #2/#3):
802
- // - 焦点坐标 focusRow/focusCol 为「逻辑索引」存本地 $state:
803
- // focusRow = -1 表示表头行,0..displayRows.length-1 表示数据行(逻辑序,
804
- // 与虚拟化是否渲染无关);focusCol 索引进「网格列」扁平表
805
- // [expand?, selection?, ...dataColumns]。
806
- // - 每个渲染单元格的 tabindex 由纯派生函数 rovingTabindex(row,col) 计算:
807
- // 命中焦点坐标 → 0,否则 -1;整个 grid 只有一个 tabbable 入口(APG)。
808
- // - 方向键算下一坐标(纯函数 nextRovingIndex),命令式 focusCell() 聚焦:
809
- // 虚拟化下目标行未渲染先滚动进视口 + tick() 再 focus(render 期不写 $state)。
810
- // - 被虚拟化回收的焦点行:$effect 监测,焦点回退到 grid 容器并 announce,
811
- // 不让焦点掉到 <body>。
812
- // ===================================================================
813
-
814
- // grid 是否启用:缺省自动检测交互能力;显式 gridNav 覆盖。
815
- const isInteractive = $derived(
816
- hasSelection ||
817
- hasExpand ||
818
- treeEnabled ||
819
- !!onRowClick ||
820
- columns.some((c) => !!c.sorter || (!!c.filters && c.filters.length > 0)),
821
- );
822
- const gridEnabled = $derived(gridNav !== undefined ? gridNav : isInteractive);
823
-
824
- // grid 单元格 id 前缀(稳定、SSR 安全)。
825
- const gridId = useId('cd-table-grid');
826
- // 网格列扁平表:前置 expand/selection 占位列 + 数据列(纯函数 buildGridCols)。
827
- const gridCols = $derived<GridCol[]>(
828
- buildGridCols({ hasExpand, hasSelection, dataColumnCount: columns.length }),
829
- );
830
- const gridColCount = $derived(gridCols.length);
831
- // 总行数(含表头行)= aria-rowcount,虚拟化时为逻辑总数而非渲染数(spec §6)。
832
- const gridRowCount = $derived(displayRows.length + 1);
833
-
834
- // 焦点坐标(逻辑索引)。-1 行 = 表头;col 索引进 gridCols。
835
- // 初始未聚焦时为 null,首个 tab 停靠点回退到表头首格。
836
- let focusRow = $state(-1);
837
- let focusCol = $state(0);
838
- let hasFocused = $state(false);
839
-
840
- // 当前是否处于「单元格交互模式」(Enter/F2 进入,Esc 退出)。
841
- // 交互模式下单元格内可聚焦控件参与 Tab;导航模式下它们 tabindex=-1。
842
- let cellInteractive = $state(false);
843
-
844
- // 某 (row,col) 是否为当前 roving 焦点格(纯派生,render 期只读)。
845
- function isFocusCell(row: number, col: number): boolean {
846
- if (!gridEnabled) return false;
847
- return isFocusCellPure(row, col, { row: focusRow, col: focusCol, hasFocused });
848
- }
849
- // 单元格 roving tabindex:焦点格 0,其余 -1(仅 grid 启用时)。
850
- function rovingTabindex(row: number, col: number): 0 | -1 | undefined {
851
- if (!gridEnabled) return undefined;
852
- return rovingTabindexAt(row, col, { row: focusRow, col: focusCol, hasFocused });
853
- }
854
- // 单元格内交互控件的 tabindex:导航模式下 -1(不参与 Tab,靠 Enter/F2 进入),
855
- // 交互模式下当前焦点格内控件恢复 0。非 grid 时不接管(undefined)。
856
- function childTabindex(row: number, col: number): 0 | -1 | undefined {
857
- if (!gridEnabled) return undefined;
858
- if (cellInteractive && isFocusCell(row, col)) return 0;
859
- return -1;
860
- }
861
- // 单元格稳定 id(focusCell 命令式聚焦目标)。row=-1 表头记作 'h'。
862
- function cellId(row: number, col: number): string {
863
- return `${gridId}-r${row === -1 ? 'h' : row}-c${col}`;
864
- }
865
-
866
- // grid 容器(table 元素)引用 —— 焦点回收落点。
867
- let gridEl = $state<HTMLTableElement | null>(null);
868
-
869
- // 命令式聚焦某逻辑坐标的单元格:虚拟化下若行未渲染先滚动进视口 + tick 再聚焦。
870
- async function focusCell(row: number, col: number) {
871
- focusRow = row;
872
- focusCol = col;
873
- hasFocused = true;
874
- cellInteractive = false;
875
- // 数据行在虚拟化视口外:先滚动使其进入视口(render 期外,事件回调内,红线 #3)。
876
- if (virtualized && row >= 0 && scrollEl) {
877
- const inView = row >= vRange.startIndex && row < vRange.endIndex;
878
- if (!inView) {
879
- // 目标行顶部对齐到视口(留一行余量),写 scrollEl.scrollTop 触发 scroll 回调更新区间。
880
- const target = Math.max(0, row * vRowHeight);
881
- scrollEl.scrollTop = target;
882
- scrollTop = target;
883
- await tick();
884
- }
885
- }
886
- await tick();
887
- const el = gridEl?.querySelector<HTMLElement>(`#${cssEscape(cellId(row, col))}`);
888
- if (el) el.focus();
889
- else if (gridEl) gridEl.focus(); // 兜底:目标仍不可用,焦点回收到 grid 容器(不掉 body)。
890
- }
891
-
892
- // CSS.escape 兜底(id 仅含字母数字与 '-',本不需转义,留作健壮性)。
893
- function cssEscape(id: string): string {
894
- return typeof CSS !== 'undefined' && CSS.escape ? CSS.escape(id) : id;
895
- }
896
-
897
- // 二维方向键漫游 keydown(绑定在 grid table 上,事件委托冒泡)。
898
- function onGridKeydown(e: KeyboardEvent) {
899
- if (!gridEnabled) return;
900
- const key = e.key;
901
-
902
- // 交互模式:Esc 退出回导航模式并聚焦当前格;其余按键交给单元格内控件处理。
903
- if (cellInteractive) {
904
- if (key === 'Escape') {
905
- e.preventDefault();
906
- e.stopPropagation();
907
- cellInteractive = false;
908
- void focusCellSameCoord();
909
- }
910
- return;
911
- }
912
-
913
- // Enter/F2:进入交互模式(聚焦当前格内首个可聚焦控件,无则不拦截)。
914
- if (key === 'Enter' || key === 'F2') {
915
- const entered = enterCellInteractive();
916
- if (entered) {
917
- e.preventDefault();
918
- e.stopPropagation();
919
- }
920
- return;
921
- }
922
-
923
- // 导航模式:用纯函数算下一坐标(PageUp/Down 翻一屏行数)。
924
- const pageRows = Math.max(1, Math.floor(height / vRowHeight) || 10);
925
- const next = nextGridCoord(
926
- key,
927
- { ctrl: e.ctrlKey, meta: e.metaKey },
928
- {
929
- current: { row: focusRow, col: focusCol },
930
- rowCount: displayRows.length,
931
- colCount: gridColCount,
932
- pageRows,
933
- },
934
- );
935
- if (!next) return; // 非漫游键
936
- e.preventDefault();
937
- e.stopPropagation();
938
- if (next.row !== focusRow || next.col !== focusCol || !hasFocused) {
939
- void focusCell(next.row, next.col);
940
- }
941
- }
942
-
943
- // 重聚焦当前坐标(退出交互模式时用,避免改坐标)。
944
- async function focusCellSameCoord() {
945
- await tick();
946
- const el = gridEl?.querySelector<HTMLElement>(`#${cssEscape(cellId(focusRow, focusCol))}`);
947
- if (el) el.focus();
948
- }
949
-
950
- // 进入交互模式:聚焦当前焦点格内首个可聚焦元素。返回是否成功进入。
951
- function enterCellInteractive(): boolean {
952
- const cell = gridEl?.querySelector<HTMLElement>(`#${cssEscape(cellId(focusRow, focusCol))}`);
953
- if (!cell) return false;
954
- const focusable = cell.querySelector<HTMLElement>(
955
- 'button:not([disabled]),a[href],input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"]):not(.cd-table__cell)',
956
- );
957
- if (!focusable) return false;
958
- cellInteractive = true;
959
- // tabindex 由 childTabindex 派生切到 0;命令式聚焦控件。
960
- void tick().then(() => focusable.focus());
961
- return true;
962
- }
963
-
964
- // 单元格被点击/获得焦点时,同步焦点坐标(鼠标与键盘一致)。
965
- function syncFocusCoord(row: number, col: number) {
966
- if (!gridEnabled) return;
967
- focusRow = row;
968
- focusCol = col;
969
- hasFocused = true;
970
- }
971
-
972
- // --- 虚拟化焦点回收 ---
973
- // 当聚焦数据行被滚出渲染区间(虚拟化卸载),焦点会掉到 <body>。监测并回收:
974
- // 把焦点移到 grid 容器(table,tabindex=-1)并 announce,保证键盘用户不丢失上下文。
975
- $effect(() => {
976
- if (!gridEnabled || !virtualized || !hasFocused) return;
977
- // 仅当焦点落在数据行、且该行不在渲染区间时回收。
978
- const row = focusRow;
979
- if (row < 0) return;
980
- const inView = row >= vRange.startIndex && row < vRange.endIndex;
981
- if (inView) return;
982
- const active = typeof document !== 'undefined' ? document.activeElement : null;
983
- // 仅当焦点确实在本 grid 内(即将随卸载丢失)时回收。
984
- if (gridEl && active && gridEl.contains(active)) {
985
- gridEl.focus();
986
- announcer.announce(
987
- loc().t('Table.rowCount', { count: displayRows.length }),
988
- );
989
- }
990
- });
991
-
992
- // --- 聚合 onChange 载荷快照(读 render 期派生态,仅在事件回调内调用,红线 #2)---
993
- // 当前各列筛选选中值(colKey → values[]),仅含非空筛选列。
994
- function snapshotFilters(): Record<string, (string | number)[]> {
995
- const out: Record<string, (string | number)[]> = {};
996
- columns.forEach((col, i) => {
997
- const ck = colKeyOf(col, i);
998
- const vals = filterState.get(ck);
999
- if (vals && vals.size > 0) out[ck] = [...vals];
1000
- });
1001
- return out;
1002
- }
1003
- // 触发聚合 onChange:sorterOverride/pageOverride 让排序/分页变化时用「即将生效」的值,
1004
- // 因 $derived 在同步事件回调内尚未重算(受控时本就不回写)。
1005
- function emitChange(
1006
- action: TableChangeAction,
1007
- sorterOverride?: SortState,
1008
- pageOverride?: number,
1009
- ) {
1010
- onChange?.({
1011
- pagination: {
1012
- current: pageOverride ?? currentPage,
1013
- pageSize,
1014
- },
1015
- filters: snapshotFilters(),
1016
- sorter: sorterOverride ?? currentSort,
1017
- extra: { action },
1018
- });
1019
- }
1020
-
1021
- // --- 排序点击 ---
1022
- function onSort(col: ColumnDef<T>, index: number) {
1023
- const key = colKeyOf(col, index);
1024
- const next = toggleSort(currentSort, key);
1025
- if (!isSortControlled) innerSort = next;
1026
- onSortChange?.(next);
1027
- emitChange('sort', next);
1028
- announceSort(col, next);
1029
- }
1030
-
1031
- // 排序变化播报:升/降序播 sortedAnnounce(含列名 + 方向),三态循环到 null 播 sortClearedAnnounce。
1032
- function announceSort(col: ColumnDef<T>, next: SortState) {
1033
- const column = columnLabel(col);
1034
- if (next.order) {
1035
- const order = loc().t(
1036
- next.order === 'ascend' ? 'Table.sortOrderAscend' : 'Table.sortOrderDescend',
1037
- );
1038
- announcer.announce(loc().t('Table.sortedAnnounce', { column, order }));
1039
- } else {
1040
- announcer.announce(loc().t('Table.sortClearedAnnounce', { column }));
1041
- }
1042
- }
1043
-
1044
- // 列的可读名:title 为字符串时直接用,否则回退列 key(snippet/复杂 title 无文本可取)。
1045
- function columnLabel(col: ColumnDef<T>): string {
1046
- return typeof col.title === 'string' ? col.title : String(col.dataIndex ?? col.key ?? '');
1047
- }
1048
-
1049
- function ariaSortFor(col: ColumnDef<T>, index: number): 'ascending' | 'descending' | 'none' {
1050
- const order = col.sortOrder !== undefined
1051
- ? col.sortOrder
1052
- : (currentSort.key === colKeyOf(col, index) ? currentSort.order : null);
1053
- if (!order) return 'none';
1054
- return order === 'ascend' ? 'ascending' : 'descending';
1055
- }
1056
-
1057
- // --- 分页变更 ---
1058
- function onPageChange(page: number) {
1059
- if (!isPageControlled) innerPage = page;
1060
- if (pagination) pagination.onChange?.(page);
1061
- onPaginationChange?.({ current: page, pageSize });
1062
- emitChange('paginate', undefined, page);
1063
- }
1064
-
1065
- // --- 单元格取值 ---
1066
- function cellValue(col: ColumnDef<T>, record: T): unknown {
1067
- return col.dataIndex ? record[col.dataIndex] : undefined;
1068
- }
1069
- function cellText(value: unknown): string {
1070
- return value == null ? '' : String(value);
1071
- }
1072
-
1073
- function alignOf(col: ColumnDef<T>): Align {
1074
- return col.align ?? 'left';
1075
- }
1076
- function widthStyle(col: ColumnDef<T>, index: number): string | undefined {
1077
- const w = resolveWidth(col, index);
1078
- if (w === undefined) return undefined;
1079
- return typeof w === 'number' ? `width:${w}px` : `width:${w}`;
1080
- }
1081
-
1082
- // --- 固定列:纯 CSS sticky + 逐列像素偏移计算 ---
1083
- // selection / expand 前置列宽(与 CSS .cd-table__cell--selection/--expand 对齐)
1084
- const LEADING_W = 48;
1085
- // 前置 leading 列(expand + selection)的总宽,作为 left 固定列偏移基数
1086
- const leadingWidth = $derived((hasExpand ? LEADING_W : 0) + (hasSelection ? LEADING_W : 0));
1087
- const hasFixed = $derived(columns.some((c) => c.fixed));
1088
- // 固定列时 table 的最小总宽(列宽和 + 前置列),撑过容器以触发横滚
1089
- const totalMinWidth = $derived(
1090
- leadingWidth +
1091
- columns.reduce((sum, c, i) => {
1092
- const w = resolveWidth(c, i);
1093
- return sum + (typeof w === 'number' ? w : 120);
1094
- }, 0),
1095
- );
1096
- const tableStyle = $derived(hasFixed ? `min-inline-size:${totalMinWidth}px` : undefined);
1097
-
1098
- function colNumWidth(col: ColumnDef<T>, index: number): number {
1099
- const w = resolveWidth(col, index);
1100
- return typeof w === 'number' ? w : 0;
1101
- }
1102
-
1103
- // 每个数据列的 left 偏移(左固定列):前置宽 + 之前所有左固定列宽之和
1104
- const fixedLeftOffsets = $derived.by(() => {
1105
- const out: (number | null)[] = [];
1106
- let acc = leadingWidth;
1107
- for (let i = 0; i < columns.length; i++) {
1108
- const col = columns[i] as ColumnDef<T>;
1109
- if (col.fixed === 'left') {
1110
- out.push(acc);
1111
- acc += colNumWidth(col, i);
1112
- } else {
1113
- out.push(null);
1114
- }
1115
- }
1116
- return out;
1117
- });
1118
- // 每个数据列的 right 偏移(右固定列):之后所有右固定列宽之和
1119
- const fixedRightOffsets = $derived.by(() => {
1120
- const out: (number | null)[] = new Array(columns.length).fill(null);
1121
- let acc = 0;
1122
- for (let i = columns.length - 1; i >= 0; i--) {
1123
- const col = columns[i] as ColumnDef<T>;
1124
- if (col.fixed === 'right') {
1125
- out[i] = acc;
1126
- acc += colNumWidth(col, i);
1127
- }
1128
- }
1129
- return out;
1130
- });
1131
- // 最后一个左固定列 / 第一个右固定列索引(用于阴影边界)
1132
- const lastLeftFixed = $derived.by(() => {
1133
- let idx = -1;
1134
- columns.forEach((c, i) => {
1135
- if (c.fixed === 'left') idx = i;
1136
- });
1137
- return idx;
1138
- });
1139
- const firstRightFixed = $derived(columns.findIndex((c) => c.fixed === 'right'));
1140
-
1141
- // 组合某数据列的 sticky 行内样式(含宽度)
1142
- function cellStyle(col: ColumnDef<T>, i: number): string | undefined {
1143
- const parts: string[] = [];
1144
- const w = widthStyle(col, i);
1145
- if (w) parts.push(w);
1146
- const left = fixedLeftOffsets[i];
1147
- const right = fixedRightOffsets[i];
1148
- if (left != null) parts.push(`position:sticky`, `inset-inline-start:${left}px`);
1149
- else if (right != null) parts.push(`position:sticky`, `inset-inline-end:${right}px`);
1150
- return parts.length ? parts.join(';') : undefined;
1151
- }
1152
-
1153
- function fixedCellClass(i: number): string {
1154
- if (fixedLeftOffsets[i] != null) {
1155
- return `cd-table__cell--fixed cd-table__cell--fixed-left${i === lastLeftFixed ? ' cd-table__cell--fixed-left-last' : ''}`;
1156
- }
1157
- if (fixedRightOffsets[i] != null) {
1158
- return `cd-table__cell--fixed cd-table__cell--fixed-right${i === firstRightFixed ? ' cd-table__cell--fixed-right-first' : ''}`;
1159
- }
1160
- return '';
1161
- }
1162
-
1163
- // 前置 leading 列在存在左固定列时也需 sticky 锁定在最左
1164
- function leadingStyle(slot: 'expand' | 'selection'): string | undefined {
1165
- if (!hasFixed || lastLeftFixed < 0) return undefined;
1166
- const offset = slot === 'expand' ? 0 : hasExpand ? LEADING_W : 0;
1167
- return `position:sticky;inset-inline-start:${offset}px`;
1168
- }
1169
- const leadingFixedClass = $derived(hasFixed && lastLeftFixed >= 0 ? 'cd-table__cell--fixed cd-table__cell--fixed-left' : '');
1170
-
1171
- // --- 半选 indeterminate:用 attachment 命令式写具体 input 元素属性。
1172
- // 仅读派生布尔值并写 DOM,不读几何,写属性不触发响应式,无循环风险 (不违反红线 #3)。
1173
- function indeterminate(value: boolean) {
1174
- return (node: HTMLInputElement) => {
1175
- node.indeterminate = value;
1176
- };
1177
- }
1178
-
1179
- const cls = $derived(
1180
- [
1181
- 'cd-table',
1182
- `cd-table--${size}`,
1183
- bordered && 'cd-table--bordered',
1184
- stripe && 'cd-table--stripe',
1185
- hasFixed && 'cd-table--fixed',
1186
- ]
1187
- .filter(Boolean)
1188
- .join(' '),
1189
- );
1190
-
1191
- // --- scroll prop: wrapper container style ---
1192
- // scroll.y → max-height + overflow-y:auto; scroll.x → min-width on table
1193
- const scrollWrapStyle = $derived.by(() => {
1194
- const parts: string[] = [];
1195
- if (virtualized || scrollBody) {
1196
- parts.push(`block-size:${height}px`, 'overflow:auto');
1197
- }
1198
- if (scroll?.y != null) {
1199
- const yVal = typeof scroll.y === 'number' ? `${scroll.y}px` : scroll.y;
1200
- parts.push(`max-block-size:${yVal}`, 'overflow-y:auto');
1201
- }
1202
- if (scroll?.x != null) {
1203
- parts.push('overflow-x:auto');
1204
- }
1205
- return parts.length ? parts.join(';') : undefined;
1206
- });
1207
-
1208
- const scrollTableStyle = $derived.by(() => {
1209
- const parts: string[] = [];
1210
- if (tableStyle) parts.push(tableStyle);
1211
- if (scroll?.x != null) {
1212
- const xVal = typeof scroll.x === 'number' ? `${scroll.x}px` : scroll.x;
1213
- parts.push(`min-inline-size:${xVal}`);
1214
- }
1215
- return parts.length ? parts.join(';') : undefined;
1216
- });
1217
-
1218
- // --- sticky prop: thead top offset ---
1219
- const stickyOffset = $derived.by((): number => {
1220
- if (!sticky) return 0;
1221
- if (typeof sticky === 'object' && sticky.offsetHeader != null) return sticky.offsetHeader;
1222
- return 0;
1223
- });
1224
- const isStickyHead = $derived(!!sticky || virtualized || scrollBody || scroll?.y != null);
1225
-
1226
- // --- selection column width style ---
1227
- const selectionColStyle = $derived.by((): string | undefined => {
1228
- const parts: string[] = [];
1229
- if (rowSelection?.columnWidth != null) {
1230
- const w = rowSelection.columnWidth;
1231
- parts.push(`inline-size:${typeof w === 'number' ? `${w}px` : w}`);
1232
- }
1233
- if (rowSelection?.fixed) {
1234
- // fixed selection column — sticky at start of row
1235
- parts.push('position:sticky', 'inset-inline-start:0');
1236
- }
1237
- return parts.length ? parts.join(';') : undefined;
1238
- });
1239
- const selectionFixedClass = $derived(rowSelection?.fixed ? 'cd-table__cell--fixed cd-table__cell--fixed-left' : '');
1240
-
1241
- // --- groupBy: build grouped display rows ---
1242
- type GroupRow = { type: 'group'; groupKey: string; group: T[] };
1243
- type DataDisplayRow = FlatRow<T> & { type: 'data' };
1244
- type RenderRow = DataDisplayRow | GroupRow;
1245
-
1246
- const groupedDisplayRows = $derived.by<RenderRow[]>(() => {
1247
- if (!groupBy) {
1248
- return displayRows.map((r) => ({ ...r, type: 'data' as const }));
1249
- }
1250
- const getGroupKey = (record: T): string => {
1251
- if (typeof groupBy === 'function') return groupBy(record);
1252
- return String(record[groupBy as string] ?? '');
1253
- };
1254
- // Build ordered group buckets (only top-level rows are grouped)
1255
- const groupOrder: string[] = [];
1256
- const groupMap = new Map<string, T[]>();
1257
- for (const row of displayRows) {
1258
- if (row.level === 0) {
1259
- const gk = getGroupKey(row.record);
1260
- if (!groupMap.has(gk)) {
1261
- groupOrder.push(gk);
1262
- groupMap.set(gk, []);
1263
- }
1264
- groupMap.get(gk)!.push(row.record);
1265
- }
1266
- }
1267
- const result: RenderRow[] = [];
1268
- for (const gk of groupOrder) {
1269
- const group = groupMap.get(gk)!;
1270
- result.push({ type: 'group', groupKey: gk, group });
1271
- // Include all displayRows belonging to this group (incl. tree children)
1272
- let inGroup = false;
1273
- for (const row of displayRows) {
1274
- if (row.level === 0) {
1275
- inGroup = getGroupKey(row.record) === gk;
1276
- }
1277
- if (inGroup) result.push({ ...row, type: 'data' as const });
1278
- }
1279
- }
1280
- return result;
1281
- });
1282
-
1283
- // For render purposes when no groupBy: cast displayRows to RenderRow[]
1284
- const isGrouped = $derived(groupBy !== undefined);
1285
- </script>
1286
-
1287
- {#if titleSnippet}
1288
- <div class="cd-table__title-area">
1289
- {@render titleSnippet()}
1290
- </div>
1291
- {/if}
1292
- <div
1293
- class="cd-table-wrap"
1294
- class:cd-table-wrap--virtual={virtualized}
1295
- class:cd-table-wrap--scroll-body={scrollBody}
1296
- bind:this={scrollEl}
1297
- style={scrollWrapStyle}
1298
- >
1299
- <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
1300
- <!-- role=grid 是交互容器;tabindex=-1 仅作虚拟化焦点回收落点,不进 Tab 序列 -->
1301
- <table
1302
- bind:this={gridEl}
1303
- class={cls}
1304
- style={scrollTableStyle}
1305
- aria-label={ariaLabel}
1306
- role={gridEnabled ? 'grid' : undefined}
1307
- aria-rowcount={gridEnabled ? gridRowCount : undefined}
1308
- aria-colcount={gridEnabled ? gridColCount : undefined}
1309
- tabindex={gridEnabled ? -1 : undefined}
1310
- onkeydown={gridEnabled ? onGridKeydown : undefined}
1311
- >
1312
- {#if showHeader}
1313
- {@const headerRowProps = onHeaderRow ? onHeaderRow(columns, 0) : undefined}
1314
- <thead
1315
- class="cd-table__head"
1316
- class:cd-table__head--sticky={isStickyHead}
1317
- style={isStickyHead && stickyOffset > 0 ? `top:${stickyOffset}px` : undefined}
1318
- >
1319
- <tr
1320
- role={gridEnabled ? 'row' : undefined}
1321
- aria-rowindex={gridEnabled ? 1 : undefined}
1322
- class={headerRowProps?.className ?? undefined}
1323
- style={headerRowProps?.style ?? undefined}
1324
- onclick={headerRowProps?.onClick ?? undefined}
1325
- >
1326
- {#if hasExpand}
1327
- {@const gc = 0}
1328
- <th
1329
- class="cd-table__cell cd-table__cell--expand {leadingFixedClass}"
1330
- scope="col"
1331
- style={leadingStyle('expand')}
1332
- role={gridEnabled ? 'columnheader' : undefined}
1333
- id={gridEnabled ? cellId(-1, gc) : undefined}
1334
- tabindex={rovingTabindex(-1, gc)}
1335
- aria-colindex={gridEnabled ? gc + 1 : undefined}
1336
- onfocusin={gridEnabled ? () => syncFocusCoord(-1, gc) : undefined}
1337
- ></th>
1338
- {/if}
1339
- {#if hasSelection}
1340
- {@const gc = hasExpand ? 1 : 0}
1341
- {@const isRadio = rowSelection?.type === 'radio'}
1342
- {@const showSelectAll = !isRadio && !rowSelection?.hideSelectAll}
1343
- <th
1344
- class="cd-table__cell cd-table__cell--selection {selectionFixedClass || leadingFixedClass}"
1345
- scope="col"
1346
- style={selectionColStyle ?? leadingStyle('selection')}
1347
- role={gridEnabled ? 'columnheader' : undefined}
1348
- id={gridEnabled ? cellId(-1, gc) : undefined}
1349
- tabindex={rovingTabindex(-1, gc)}
1350
- aria-colindex={gridEnabled ? gc + 1 : undefined}
1351
- onfocusin={gridEnabled ? () => syncFocusCoord(-1, gc) : undefined}
1352
- >
1353
- {#if showSelectAll}
1354
- <input
1355
- type="checkbox"
1356
- class="cd-table__checkbox"
1357
- aria-label={loc().t('Table.selectAll')}
1358
- checked={headerSelect.checked}
1359
- tabindex={childTabindex(-1, gc)}
1360
- {@attach indeterminate(headerSelect.indeterminate)}
1361
- onchange={onToggleAll}
1362
- />
1363
- {/if}
1364
- </th>
1365
- {/if}
1366
- {#each columns as col, i (colKeyOf(col, i))}
1367
- {@const gc = (hasExpand ? 1 : 0) + (hasSelection ? 1 : 0) + i}
1368
- {@const sortable = !!col.sorter}
1369
- {@const colKey = colKeyOf(col, i)}
1370
- {@const hasFilter = !!col.filters && col.filters.length > 0}
1371
- {@const resizable = !!col.resizable}
1372
- <th
1373
- class="cd-table__cell cd-table__cell--head cd-table__cell--{alignOf(col)} {fixedCellClass(i)}"
1374
- class:cd-table__cell--ellipsis={col.ellipsis}
1375
- class:cd-table__cell--has-filter={hasFilter}
1376
- class:cd-table__cell--resizable={resizable}
1377
- class:cd-table__cell--resizing={resizingKey === colKey}
1378
- scope="col"
1379
- style={cellStyle(col, i)}
1380
- aria-sort={sortable ? ariaSortFor(col, i) : undefined}
1381
- role={gridEnabled ? 'columnheader' : undefined}
1382
- id={gridEnabled ? cellId(-1, gc) : undefined}
1383
- tabindex={rovingTabindex(-1, gc)}
1384
- aria-colindex={gridEnabled ? gc + 1 : undefined}
1385
- onfocusin={gridEnabled ? () => syncFocusCoord(-1, gc) : undefined}
1386
- >
1387
- {#if sortable}
1388
- {@const order = col.sortOrder !== undefined ? col.sortOrder : (currentSort.key === colKeyOf(col, i) ? currentSort.order : null)}
1389
- <button
1390
- type="button"
1391
- class="cd-table__sort-btn"
1392
- tabindex={childTabindex(-1, gc)}
1393
- onclick={() => onSort(col, i)}
1394
- >
1395
- <span class="cd-table__title">{col.title}</span>
1396
- <span class="cd-table__sort-icons" aria-hidden="true">
1397
- <svg
1398
- class="cd-table__sort-up"
1399
- class:cd-table__sort--active={order === 'ascend'}
1400
- viewBox="0 0 8 5"
1401
- width="8"
1402
- height="5"
1403
- focusable="false"
1404
- >
1405
- <path fill="currentColor" d="M4 0l4 5H0z" />
1406
- </svg>
1407
- <svg
1408
- class="cd-table__sort-down"
1409
- class:cd-table__sort--active={order === 'descend'}
1410
- viewBox="0 0 8 5"
1411
- width="8"
1412
- height="5"
1413
- focusable="false"
1414
- >
1415
- <path fill="currentColor" d="M4 5L0 0h8z" />
1416
- </svg>
1417
- </span>
1418
- </button>
1419
- {:else}
1420
- <span class="cd-table__title">{col.title}</span>
1421
- {/if}
1422
-
1423
- {#if hasFilter}
1424
- <button
1425
- type="button"
1426
- class="cd-table__filter-btn"
1427
- class:cd-table__filter-btn--active={isEffectivelyFiltered(col, colKey)}
1428
- aria-label={loc().t('Table.filter')}
1429
- aria-expanded={openFilterKey === colKey}
1430
- tabindex={childTabindex(-1, gc)}
1431
- bind:this={filterTriggers[colKey]}
1432
- onclick={(e) => {
1433
- e.stopPropagation();
1434
- openFilterKey = openFilterKey === colKey ? null : colKey;
1435
- }}
1436
- >
1437
- <svg viewBox="0 0 16 16" width="12" height="12" aria-hidden="true" focusable="false">
1438
- <path fill="currentColor" d="M2 3h12l-4.5 5.5V13L6.5 11V8.5L2 3Z" />
1439
- </svg>
1440
- </button>
1441
- {#if openFilterKey === colKey && filterTriggers[colKey]}
1442
- {@const filterMultiple = col.filterMultiple !== false}
1443
- <div
1444
- class="cd-table__filter-panel"
1445
- use:floating={{ trigger: filterTriggers[colKey], placement: 'bottomEnd', autoAdjust: true, offset: 4, getContainer: getPopupContainer }}
1446
- bind:this={filterPanelEl}
1447
- >
1448
- <ul class="cd-table__filter-list">
1449
- {#each col.filters ?? [] as f (f.value)}
1450
- <li class="cd-table__filter-option">
1451
- <label class="cd-table__filter-label">
1452
- {#if filterMultiple}
1453
- <input
1454
- type="checkbox"
1455
- checked={activeFilterValues(colKey).has(f.value)}
1456
- onchange={() => toggleFilterValue(colKey, f.value)}
1457
- />
1458
- {:else}
1459
- <input
1460
- type="radio"
1461
- name="cd-filter-{colKey}"
1462
- checked={activeFilterValues(colKey).has(f.value)}
1463
- onchange={() => {
1464
- filterState.set(colKey, new Set([f.value]));
1465
- emitFilterChange(colKey, [f.value]);
1466
- }}
1467
- />
1468
- {/if}
1469
- <span>{f.text}</span>
1470
- </label>
1471
- </li>
1472
- {/each}
1473
- </ul>
1474
- <div class="cd-table__filter-actions">
1475
- <button type="button" class="cd-table__filter-reset" onclick={() => resetFilter(colKey)}>
1476
- {loc().t('Table.filterReset')}
1477
- </button>
1478
- <button type="button" class="cd-table__filter-confirm" onclick={() => (openFilterKey = null)}>
1479
- {loc().t('Table.filterConfirm')}
1480
- </button>
1481
- </div>
1482
- </div>
1483
- {/if}
1484
- {/if}
1485
-
1486
- {#if resizable}
1487
- <span
1488
- class="cd-table__resize-handle"
1489
- role="separator"
1490
- aria-orientation="vertical"
1491
- aria-label={loc().t('Table.resizeColumn')}
1492
- bind:this={resizeHandles[colKey]}
1493
- onpointerdown={(e) => startResize(e, col, i)}
1494
- ></span>
1495
- {/if}
1496
- </th>
1497
- {/each}
1498
- </tr>
1499
- </thead>
1500
- {/if}
1501
- <tbody class="cd-table__body">
1502
- {#if visibleRows.length === 0}
1503
- <tr class="cd-table__row cd-table__row--empty" role={gridEnabled ? 'row' : undefined}>
1504
- <td
1505
- class="cd-table__cell cd-table__cell--empty"
1506
- colspan={colSpan}
1507
- role={gridEnabled ? 'gridcell' : undefined}
1508
- aria-colindex={gridEnabled ? 1 : undefined}
1509
- >
1510
- {empty ?? loc().t('Table.emptyText')}
1511
- </td>
1512
- </tr>
1513
- {:else}
1514
- {#if isGrouped}
1515
- {#each groupedDisplayRows as groupRow (groupRow.type === 'group' ? `__group__${(groupRow as GroupRow).groupKey}` : (groupRow as DataDisplayRow).key)}
1516
- {#if groupRow.type === 'group'}
1517
- {@const gRow = groupRow as GroupRow}
1518
- <tr class="cd-table__row cd-table__row--group-header" role={gridEnabled ? 'row' : undefined}>
1519
- <td class="cd-table__cell cd-table__cell--group-header" colspan={colSpan}>
1520
- {#if renderGroupSection}
1521
- {@render renderGroupSection({ groupKey: gRow.groupKey, group: gRow.group })}
1522
- {:else}
1523
- {gRow.groupKey}
1524
- {/if}
1525
- </td>
1526
- </tr>
1527
- {:else}
1528
- {@const row = groupRow as DataDisplayRow}
1529
- {@const record = row.record}
1530
- {@const key = row.key}
1531
- {@const index = row.topIndex}
1532
- {@const gridRow = index}
1533
- {@const selected = treeCheckable ? conducted.checked.has(key) : selectedSet.has(key)}
1534
- {@const rowHalf = treeCheckable && conducted.half.has(key)}
1535
- {@const rowDisabled = disabledSet.has(key)}
1536
- {@const extra = rowClassName ? rowClassName(record, index) : ''}
1537
- {@const clickable = !!onRowClick || expandRowByClick}
1538
- {@const rowProps = onRow ? onRow(record, index) : undefined}
1539
- <tr
1540
- class="cd-table__row {extra} {rowProps?.className ?? ''}"
1541
- class:cd-table__row--selected={selected}
1542
- class:cd-table__row--stripe={stripe && index % 2 === 1}
1543
- class:cd-table__row--clickable={clickable}
1544
- class:cd-table__row--child={treeEnabled && row.level > 0}
1545
- role={gridEnabled ? 'row' : undefined}
1546
- style={rowProps?.style ?? undefined}
1547
- onclick={(e) => {
1548
- if (expandRowByClick && hasExpand && canExpand(record)) toggleExpand(record);
1549
- if (expandRowByClick && treeEnabled && row.hasChildren) toggleTreeExpand(record);
1550
- if (onRowClick) onRowClick({ record, index });
1551
- if (rowProps?.onClick) rowProps.onClick(e);
1552
- }}
1553
- ondblclick={rowProps?.onDoubleClick ?? undefined}
1554
- >
1555
- {#if hasExpand}
1556
- {@const gc = 0}
1557
- <td
1558
- class="cd-table__cell cd-table__cell--expand {leadingFixedClass}"
1559
- style={leadingStyle('expand')}
1560
- role={gridEnabled ? 'gridcell' : undefined}
1561
- >
1562
- {#if canExpand(record)}
1563
- <button
1564
- type="button"
1565
- class="cd-table__expand-btn"
1566
- class:cd-table__expand-btn--open={expandedSet.has(key)}
1567
- aria-expanded={expandedSet.has(key)}
1568
- aria-label={expandedSet.has(key) ? loc().t('Table.collapseRow') : loc().t('Table.expandRow')}
1569
- onclick={(e) => { e.stopPropagation(); toggleExpand(record); }}
1570
- >
1571
- <svg viewBox="0 0 16 16" width="12" height="12" aria-hidden="true" focusable="false">
1572
- <path fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M6 4l4 4-4 4" />
1573
- </svg>
1574
- </button>
1575
- {/if}
1576
- </td>
1577
- {/if}
1578
- {#if hasSelection}
1579
- {@const isRadio = rowSelection?.type === 'radio'}
1580
- <td
1581
- class="cd-table__cell cd-table__cell--selection {selectionFixedClass || leadingFixedClass}"
1582
- style={selectionColStyle ?? leadingStyle('selection')}
1583
- role={gridEnabled ? 'gridcell' : undefined}
1584
- >
1585
- {#if isRadio}
1586
- <input
1587
- type="radio"
1588
- class="cd-table__checkbox"
1589
- aria-label={loc().t('Table.selectRow')}
1590
- checked={selected}
1591
- disabled={rowDisabled}
1592
- onclick={(e) => e.stopPropagation()}
1593
- onchange={() => onToggleRow(record)}
1594
- />
1595
- {:else}
1596
- <input
1597
- type="checkbox"
1598
- class="cd-table__checkbox"
1599
- aria-label={loc().t('Table.selectRow')}
1600
- checked={selected}
1601
- disabled={rowDisabled}
1602
- {@attach indeterminate(rowHalf)}
1603
- onclick={(e) => e.stopPropagation()}
1604
- onchange={() => onToggleRow(record)}
1605
- />
1606
- {/if}
1607
- </td>
1608
- {/if}
1609
- {#each columns as col, i (colKeyOf(col, i))}
1610
- {@const value = cellValue(col, record)}
1611
- <td
1612
- class="cd-table__cell cd-table__cell--{alignOf(col)} {fixedCellClass(i)}"
1613
- class:cd-table__cell--ellipsis={col.ellipsis}
1614
- style={cellStyle(col, i)}
1615
- >
1616
- {#if treeEnabled && i === 0}
1617
- <span class="cd-table__tree-indent" style="inline-size:{row.level * indentSize}px" aria-hidden="true"></span>
1618
- {#if row.hasChildren}
1619
- <button
1620
- type="button"
1621
- class="cd-table__tree-toggle"
1622
- class:cd-table__tree-toggle--open={treeExpandedSet.has(key)}
1623
- aria-expanded={treeExpandedSet.has(key)}
1624
- aria-label={treeExpandedSet.has(key) ? loc().t('Table.collapseRow') : loc().t('Table.expandRow')}
1625
- onclick={(e) => { e.stopPropagation(); toggleTreeExpand(record); }}
1626
- >
1627
- <svg viewBox="0 0 16 16" width="12" height="12" aria-hidden="true" focusable="false">
1628
- <path fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M6 4l4 4-4 4" />
1629
- </svg>
1630
- </button>
1631
- {:else}
1632
- <span class="cd-table__tree-toggle cd-table__tree-toggle--placeholder" aria-hidden="true"></span>
1633
- {/if}
1634
- {/if}
1635
- {#if col.render}
1636
- {@render col.render({ value, record, index })}
1637
- {:else}
1638
- {cellText(value)}
1639
- {/if}
1640
- </td>
1641
- {/each}
1642
- </tr>
1643
- {#if hasExpand && canExpand(record)}
1644
- {#if keepDOM}
1645
- <tr class="cd-table__row cd-table__row--expanded" role={gridEnabled ? 'row' : undefined} style={expandedSet.has(key) ? undefined : 'display:none'}>
1646
- <td class="cd-table__cell cd-table__cell--expanded-content" colspan={colSpan} role={gridEnabled ? 'gridcell' : undefined} aria-colindex={gridEnabled ? 1 : undefined}>
1647
- {@render expandable!.expandedRowRender({ record, index })}
1648
- </td>
1649
- </tr>
1650
- {:else if expandedSet.has(key)}
1651
- <tr class="cd-table__row cd-table__row--expanded" role={gridEnabled ? 'row' : undefined}>
1652
- <td class="cd-table__cell cd-table__cell--expanded-content" colspan={colSpan} role={gridEnabled ? 'gridcell' : undefined} aria-colindex={gridEnabled ? 1 : undefined}>
1653
- {@render expandable!.expandedRowRender({ record, index })}
1654
- </td>
1655
- </tr>
1656
- {/if}
1657
- {/if}
1658
- {/if}
1659
- {/each}
1660
- {:else}
1661
- {#if virtualized && vTopPad > 0}
1662
- <tr class="cd-table__row cd-table__row--spacer" aria-hidden="true">
1663
- <td colspan={colSpan} style="block-size:{vTopPad}px; padding:0; border:0"></td>
1664
- </tr>
1665
- {/if}
1666
- {#each renderRows as row, ri (row.key)}
1667
- {@const record = row.record}
1668
- {@const key = row.key}
1669
- {@const index = row.topIndex}
1670
- {@const gridRow = (virtualized ? vRange.startIndex : 0) + ri}
1671
- {@const selected = treeCheckable ? conducted.checked.has(key) : selectedSet.has(key)}
1672
- {@const rowHalf = treeCheckable && conducted.half.has(key)}
1673
- {@const rowDisabled = disabledSet.has(key)}
1674
- {@const extra = rowClassName ? rowClassName(record, index) : ''}
1675
- {@const clickable = !!onRowClick || expandRowByClick}
1676
- {@const rowProps = onRow ? onRow(record, index) : undefined}
1677
- <tr
1678
- class="cd-table__row {extra} {rowProps?.className ?? ''}"
1679
- class:cd-table__row--selected={selected}
1680
- class:cd-table__row--stripe={stripe && index % 2 === 1}
1681
- class:cd-table__row--clickable={clickable}
1682
- class:cd-table__row--child={treeEnabled && row.level > 0}
1683
- role={gridEnabled ? 'row' : undefined}
1684
- aria-rowindex={gridEnabled ? gridRow + 2 : undefined}
1685
- aria-selected={gridEnabled && hasSelection ? selected : undefined}
1686
- style={rowProps?.style ?? undefined}
1687
- onclick={(e) => {
1688
- if (expandRowByClick && hasExpand && canExpand(record)) toggleExpand(record);
1689
- if (expandRowByClick && treeEnabled && row.hasChildren) toggleTreeExpand(record);
1690
- if (onRowClick) onRowClick({ record, index });
1691
- if (rowProps?.onClick) rowProps.onClick(e);
1692
- }}
1693
- ondblclick={rowProps?.onDoubleClick ?? undefined}
1694
- >
1695
- {#if hasExpand}
1696
- {@const gc = 0}
1697
- <td
1698
- class="cd-table__cell cd-table__cell--expand {leadingFixedClass}"
1699
- style={leadingStyle('expand')}
1700
- role={gridEnabled ? 'gridcell' : undefined}
1701
- id={gridEnabled ? cellId(gridRow, gc) : undefined}
1702
- tabindex={rovingTabindex(gridRow, gc)}
1703
- aria-colindex={gridEnabled ? gc + 1 : undefined}
1704
- onfocusin={gridEnabled ? () => syncFocusCoord(gridRow, gc) : undefined}
1705
- >
1706
- {#if canExpand(record)}
1707
- <button
1708
- type="button"
1709
- class="cd-table__expand-btn"
1710
- class:cd-table__expand-btn--open={expandedSet.has(key)}
1711
- aria-expanded={expandedSet.has(key)}
1712
- aria-label={expandedSet.has(key) ? loc().t('Table.collapseRow') : loc().t('Table.expandRow')}
1713
- tabindex={childTabindex(gridRow, gc)}
1714
- onclick={(e) => {
1715
- e.stopPropagation();
1716
- toggleExpand(record);
1717
- }}
1718
- >
1719
- <svg viewBox="0 0 16 16" width="12" height="12" aria-hidden="true" focusable="false">
1720
- <path fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M6 4l4 4-4 4" />
1721
- </svg>
1722
- </button>
1723
- {/if}
1724
- </td>
1725
- {/if}
1726
- {#if hasSelection}
1727
- {@const gc = hasExpand ? 1 : 0}
1728
- {@const isRadio = rowSelection?.type === 'radio'}
1729
- <td
1730
- class="cd-table__cell cd-table__cell--selection {selectionFixedClass || leadingFixedClass}"
1731
- style={selectionColStyle ?? leadingStyle('selection')}
1732
- role={gridEnabled ? 'gridcell' : undefined}
1733
- id={gridEnabled ? cellId(gridRow, gc) : undefined}
1734
- tabindex={rovingTabindex(gridRow, gc)}
1735
- aria-colindex={gridEnabled ? gc + 1 : undefined}
1736
- onfocusin={gridEnabled ? () => syncFocusCoord(gridRow, gc) : undefined}
1737
- >
1738
- {#if isRadio}
1739
- <input
1740
- type="radio"
1741
- class="cd-table__checkbox"
1742
- aria-label={loc().t('Table.selectRow')}
1743
- checked={selected}
1744
- disabled={rowDisabled}
1745
- tabindex={childTabindex(gridRow, gc)}
1746
- onclick={(e) => e.stopPropagation()}
1747
- onchange={() => onToggleRow(record)}
1748
- />
1749
- {:else}
1750
- <input
1751
- type="checkbox"
1752
- class="cd-table__checkbox"
1753
- aria-label={loc().t('Table.selectRow')}
1754
- checked={selected}
1755
- disabled={rowDisabled}
1756
- tabindex={childTabindex(gridRow, gc)}
1757
- {@attach indeterminate(rowHalf)}
1758
- onclick={(e) => e.stopPropagation()}
1759
- onchange={() => onToggleRow(record)}
1760
- />
1761
- {/if}
1762
- </td>
1763
- {/if}
1764
- {#each columns as col, i (colKeyOf(col, i))}
1765
- {@const value = cellValue(col, record)}
1766
- {@const gc = (hasExpand ? 1 : 0) + (hasSelection ? 1 : 0) + i}
1767
- {@const isRowHeader = gridEnabled && i === 0 && !hasSelection && !hasExpand}
1768
- <td
1769
- class="cd-table__cell cd-table__cell--{alignOf(col)} {fixedCellClass(i)}"
1770
- class:cd-table__cell--ellipsis={col.ellipsis}
1771
- style={cellStyle(col, i)}
1772
- role={gridEnabled ? (isRowHeader ? 'rowheader' : 'gridcell') : undefined}
1773
- id={gridEnabled ? cellId(gridRow, gc) : undefined}
1774
- tabindex={rovingTabindex(gridRow, gc)}
1775
- aria-colindex={gridEnabled ? gc + 1 : undefined}
1776
- onfocusin={gridEnabled ? () => syncFocusCoord(gridRow, gc) : undefined}
1777
- >
1778
- {#if treeEnabled && i === 0}
1779
- <span class="cd-table__tree-indent" style="inline-size:{row.level * indentSize}px" aria-hidden="true"></span>
1780
- {#if row.hasChildren}
1781
- <button
1782
- type="button"
1783
- class="cd-table__tree-toggle"
1784
- class:cd-table__tree-toggle--open={treeExpandedSet.has(key)}
1785
- aria-expanded={treeExpandedSet.has(key)}
1786
- aria-label={treeExpandedSet.has(key) ? loc().t('Table.collapseRow') : loc().t('Table.expandRow')}
1787
- tabindex={childTabindex(gridRow, gc)}
1788
- onclick={(e) => {
1789
- e.stopPropagation();
1790
- toggleTreeExpand(record);
1791
- }}
1792
- >
1793
- <svg viewBox="0 0 16 16" width="12" height="12" aria-hidden="true" focusable="false">
1794
- <path fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M6 4l4 4-4 4" />
1795
- </svg>
1796
- </button>
1797
- {:else}
1798
- <span class="cd-table__tree-toggle cd-table__tree-toggle--placeholder" aria-hidden="true"></span>
1799
- {/if}
1800
- {/if}
1801
- {#if col.render}
1802
- {@render col.render({ value, record, index })}
1803
- {:else}
1804
- {cellText(value)}
1805
- {/if}
1806
- </td>
1807
- {/each}
1808
- </tr>
1809
- {#if hasExpand && canExpand(record)}
1810
- {#if keepDOM}
1811
- <tr
1812
- class="cd-table__row cd-table__row--expanded"
1813
- role={gridEnabled ? 'row' : undefined}
1814
- style={expandedSet.has(key) ? undefined : 'display:none'}
1815
- >
1816
- <td
1817
- class="cd-table__cell cd-table__cell--expanded-content"
1818
- colspan={colSpan}
1819
- role={gridEnabled ? 'gridcell' : undefined}
1820
- aria-colindex={gridEnabled ? 1 : undefined}
1821
- >
1822
- {@render expandable!.expandedRowRender({ record, index })}
1823
- </td>
1824
- </tr>
1825
- {:else if expandedSet.has(key)}
1826
- <tr class="cd-table__row cd-table__row--expanded" role={gridEnabled ? 'row' : undefined}>
1827
- <td
1828
- class="cd-table__cell cd-table__cell--expanded-content"
1829
- colspan={colSpan}
1830
- role={gridEnabled ? 'gridcell' : undefined}
1831
- aria-colindex={gridEnabled ? 1 : undefined}
1832
- >
1833
- {@render expandable!.expandedRowRender({ record, index })}
1834
- </td>
1835
- </tr>
1836
- {/if}
1837
- {/if}
1838
- {/each}
1839
- {#if virtualized && vBottomPad > 0}
1840
- <tr class="cd-table__row cd-table__row--spacer" aria-hidden="true">
1841
- <td colspan={colSpan} style="block-size:{vBottomPad}px; padding:0; border:0"></td>
1842
- </tr>
1843
- {/if}
1844
- {/if}
1845
- {/if}
1846
- </tbody>
1847
- </table>
1848
-
1849
- {#if paginationEnabled && total > 0}
1850
- <div class="cd-table__pagination">
1851
- <Pagination
1852
- {total}
1853
- currentPage={currentPage}
1854
- {pageSize}
1855
- size={size === 'large' ? 'default' : size}
1856
- onChange={onPageChange}
1857
- />
1858
- </div>
1859
- {/if}
1860
-
1861
- {#if loading}
1862
- <div class="cd-table__loading" aria-hidden="true">
1863
- <span class="cd-table__spinner"></span>
1864
- </div>
1865
- {/if}
1866
- </div>
1867
-
1868
- {#if footerSnippet}
1869
- <div class="cd-table__footer">
1870
- {@render footerSnippet({ currentData: visibleRows })}
1871
- </div>
1872
- {/if}
1873
-
1874
- <style>
1875
- .cd-table-wrap {
1876
- position: relative;
1877
- inline-size: 100%;
1878
- overflow-x: auto;
1879
- }
1880
-
1881
- /* 行虚拟滚动:容器自身纵向滚动,表头 sticky 固定于顶部 */
1882
- .cd-table-wrap--virtual {
1883
- overflow: auto;
1884
- }
1885
- /* 非虚拟化的可滚动表体(onScroll/onReachBottom):约束高度纵向滚动,表头 sticky */
1886
- .cd-table-wrap--scroll-body {
1887
- overflow: auto;
1888
- }
1889
- .cd-table__head--sticky th {
1890
- position: sticky;
1891
- inset-block-start: 0;
1892
- /* 高于固定列单元格(z-index:3),确保横向固定列表头不盖过纵向 sticky 表头 */
1893
- z-index: 5;
1894
- }
1895
- /* spacer 占位行无内容、无交互,仅撑高 */
1896
- .cd-table__row--spacer:hover {
1897
- background: transparent;
1898
- }
1899
-
1900
- .cd-table {
1901
- inline-size: 100%;
1902
- border-collapse: collapse;
1903
- background: var(--cd-table-bg);
1904
- color: var(--cd-table-cell-text);
1905
- border-radius: var(--cd-table-radius);
1906
- font-size: var(--cd-font-size-body);
1907
- }
1908
- /* 固定列:用 fixed 布局让列宽精确生效,min-width 撑过容器以触发横滚 */
1909
- .cd-table--fixed {
1910
- inline-size: auto;
1911
- min-inline-size: 100%;
1912
- table-layout: fixed;
1913
- }
1914
-
1915
- .cd-table__cell {
1916
- padding-block: var(--cd-table-cell-padding-y);
1917
- padding-inline: var(--cd-table-cell-padding-x);
1918
- text-align: left;
1919
- vertical-align: middle;
1920
- border-block-end: 1px solid var(--cd-table-border-color);
1921
- }
1922
- .cd-table--small .cd-table__cell {
1923
- padding-block: var(--cd-table-cell-padding-y-small);
1924
- }
1925
- .cd-table--large .cd-table__cell {
1926
- padding-block: var(--cd-table-cell-padding-y-large);
1927
- }
1928
-
1929
- .cd-table__cell--head {
1930
- color: var(--cd-table-header-text);
1931
- background: var(--cd-table-header-bg);
1932
- font-weight: 600;
1933
- }
1934
- .cd-table__head th {
1935
- background: var(--cd-table-header-bg);
1936
- color: var(--cd-table-header-text);
1937
- font-weight: 600;
1938
- }
1939
-
1940
- .cd-table__cell--center {
1941
- text-align: center;
1942
- }
1943
- .cd-table__cell--right {
1944
- text-align: right;
1945
- }
1946
- .cd-table__cell--selection {
1947
- inline-size: 48px;
1948
- text-align: center;
1949
- white-space: nowrap;
1950
- }
1951
- .cd-table__cell--expand {
1952
- inline-size: 48px;
1953
- white-space: nowrap;
1954
- text-align: center;
1955
- }
1956
- .cd-table__expand-btn {
1957
- display: inline-flex;
1958
- align-items: center;
1959
- justify-content: center;
1960
- padding: 0;
1961
- border: none;
1962
- background: transparent;
1963
- color: var(--cd-color-text-2);
1964
- cursor: pointer;
1965
- transition: transform var(--cd-motion-duration-fast) var(--cd-motion-ease-standard);
1966
- }
1967
- .cd-table__expand-btn:hover {
1968
- color: var(--cd-color-text-0);
1969
- }
1970
- .cd-table__expand-btn:focus-visible {
1971
- outline: none;
1972
- box-shadow: var(--cd-focus-ring);
1973
- border-radius: var(--cd-radius-1);
1974
- }
1975
- .cd-table__expand-btn--open {
1976
- transform: rotate(90deg);
1977
- }
1978
- .cd-table__cell--expanded-content {
1979
- padding: var(--cd-table-cell-padding, var(--cd-spacing-3));
1980
- background: var(--cd-color-fill-0);
1981
- }
1982
- @media (prefers-reduced-motion: reduce) {
1983
- .cd-table__expand-btn {
1984
- transition: none;
1985
- }
1986
- }
1987
- .cd-table__cell--ellipsis {
1988
- max-inline-size: 0;
1989
- overflow: hidden;
1990
- white-space: nowrap;
1991
- text-overflow: ellipsis;
1992
- }
1993
-
1994
- /* --- 树形数据:缩进 + 展开三角 --- */
1995
- .cd-table__tree-indent {
1996
- display: inline-block;
1997
- vertical-align: middle;
1998
- }
1999
- .cd-table__tree-toggle {
2000
- display: inline-flex;
2001
- align-items: center;
2002
- justify-content: center;
2003
- inline-size: 16px;
2004
- block-size: 16px;
2005
- margin-inline-end: var(--cd-spacing-1);
2006
- padding: 0;
2007
- border: none;
2008
- background: transparent;
2009
- color: var(--cd-color-text-2);
2010
- cursor: pointer;
2011
- vertical-align: middle;
2012
- transition: transform var(--cd-motion-duration-fast) var(--cd-motion-ease-standard);
2013
- }
2014
- .cd-table__tree-toggle:hover {
2015
- color: var(--cd-color-text-0);
2016
- }
2017
- .cd-table__tree-toggle:focus-visible {
2018
- outline: none;
2019
- box-shadow: var(--cd-focus-ring);
2020
- border-radius: var(--cd-radius-1);
2021
- }
2022
- .cd-table__tree-toggle--open {
2023
- transform: rotate(90deg);
2024
- }
2025
- .cd-table__tree-toggle--placeholder {
2026
- cursor: default;
2027
- }
2028
- @media (prefers-reduced-motion: reduce) {
2029
- .cd-table__tree-toggle {
2030
- transition: none;
2031
- }
2032
- }
2033
-
2034
- /* --- 固定列:sticky 单元格需不透明背景,避免透出横滚内容 --- */
2035
- .cd-table__cell--fixed {
2036
- z-index: 2;
2037
- background: var(--cd-table-bg);
2038
- }
2039
- .cd-table__head .cd-table__cell--fixed {
2040
- z-index: 3;
2041
- background: var(--cd-table-header-bg);
2042
- }
2043
- /* 固定列随行态变色:hover / stripe / selected 时同步背景 */
2044
- .cd-table__row:hover .cd-table__cell--fixed {
2045
- background: var(--cd-table-row-hover-bg);
2046
- }
2047
- .cd-table__row--stripe .cd-table__cell--fixed {
2048
- background: var(--cd-table-row-stripe-bg);
2049
- }
2050
- .cd-table__row--selected .cd-table__cell--fixed,
2051
- .cd-table__row--selected:hover .cd-table__cell--fixed {
2052
- background: var(--cd-table-row-selected-bg);
2053
- }
2054
- /* 边界阴影:最后一个左固定列右侧、第一个右固定列左侧 */
2055
- .cd-table__cell--fixed-left-last::after,
2056
- .cd-table__cell--fixed-right-first::after {
2057
- content: '';
2058
- position: absolute;
2059
- inset-block: 0;
2060
- inline-size: 6px;
2061
- pointer-events: none;
2062
- }
2063
- .cd-table__cell--fixed-left-last {
2064
- position: sticky;
2065
- }
2066
- .cd-table__cell--fixed-left-last::after {
2067
- inset-inline-end: -6px;
2068
- background: linear-gradient(
2069
- to right,
2070
- var(--cd-table-fixed-shadow, rgba(0, 0, 0, 0.12)),
2071
- transparent
2072
- );
2073
- }
2074
- .cd-table__cell--fixed-right-first::after {
2075
- inset-inline-start: -6px;
2076
- background: linear-gradient(
2077
- to left,
2078
- var(--cd-table-fixed-shadow, rgba(0, 0, 0, 0.12)),
2079
- transparent
2080
- );
2081
- }
2082
- /* sticky cell 需相对定位以承载 ::after 阴影 */
2083
- .cd-table__cell--fixed {
2084
- position: sticky;
2085
- }
2086
-
2087
- .cd-table--bordered .cd-table__cell {
2088
- border-inline-end: 1px solid var(--cd-table-border-color);
2089
- }
2090
- .cd-table--bordered .cd-table__cell:first-child {
2091
- border-inline-start: 1px solid var(--cd-table-border-color);
2092
- }
2093
- .cd-table--bordered .cd-table__head th {
2094
- border-block-start: 1px solid var(--cd-table-border-color);
2095
- }
2096
-
2097
- .cd-table__row--stripe {
2098
- background: var(--cd-table-row-stripe-bg);
2099
- }
2100
- .cd-table__row:hover {
2101
- background: var(--cd-table-row-hover-bg);
2102
- }
2103
- .cd-table__row--selected,
2104
- .cd-table__row--selected:hover {
2105
- background: var(--cd-table-row-selected-bg);
2106
- }
2107
- .cd-table__row--clickable {
2108
- cursor: pointer;
2109
- }
2110
-
2111
- .cd-table__cell--empty {
2112
- padding-block: var(--cd-spacing-6, 32px);
2113
- color: var(--cd-table-empty-color);
2114
- text-align: center;
2115
- }
2116
-
2117
- /* --- 列筛选 --- */
2118
- .cd-table__cell--has-filter {
2119
- position: relative;
2120
- }
2121
- .cd-table__filter-btn {
2122
- display: inline-flex;
2123
- align-items: center;
2124
- justify-content: center;
2125
- margin-inline-start: var(--cd-spacing-1);
2126
- padding: 2px;
2127
- border: none;
2128
- background: transparent;
2129
- color: var(--cd-table-sort-icon-color);
2130
- cursor: pointer;
2131
- border-radius: var(--cd-radius-1);
2132
- vertical-align: middle;
2133
- }
2134
- .cd-table__filter-btn:hover {
2135
- color: var(--cd-color-text-0);
2136
- }
2137
- .cd-table__filter-btn--active {
2138
- color: var(--cd-color-primary);
2139
- }
2140
- .cd-table__filter-btn:focus-visible {
2141
- outline: none;
2142
- box-shadow: var(--cd-focus-ring);
2143
- }
2144
- .cd-table__filter-panel {
2145
- z-index: var(--cd-select-dropdown-z, 1050);
2146
- min-inline-size: 10rem;
2147
- padding-block: var(--cd-spacing-1);
2148
- background: var(--cd-select-dropdown-bg, var(--cd-color-bg-0, #fff));
2149
- border-radius: var(--cd-select-dropdown-radius, 6px);
2150
- box-shadow: var(--cd-select-dropdown-shadow, 0 4px 12px rgba(0, 0, 0, 0.12));
2151
- font-weight: 400;
2152
- }
2153
- .cd-table__filter-list {
2154
- margin: 0;
2155
- padding: 0;
2156
- list-style: none;
2157
- max-block-size: 14rem;
2158
- overflow-y: auto;
2159
- }
2160
- .cd-table__filter-label {
2161
- display: flex;
2162
- align-items: center;
2163
- gap: var(--cd-spacing-2);
2164
- padding: var(--cd-spacing-1) var(--cd-spacing-3);
2165
- cursor: pointer;
2166
- }
2167
- .cd-table__filter-label:hover {
2168
- background: var(--cd-table-row-hover-bg);
2169
- }
2170
- .cd-table__filter-actions {
2171
- display: flex;
2172
- justify-content: space-between;
2173
- gap: var(--cd-spacing-2);
2174
- padding: var(--cd-spacing-1) var(--cd-spacing-3);
2175
- border-block-start: 1px solid var(--cd-table-border-color);
2176
- }
2177
- .cd-table__filter-reset,
2178
- .cd-table__filter-confirm {
2179
- padding: 0;
2180
- border: none;
2181
- background: transparent;
2182
- font: inherit;
2183
- font-size: var(--cd-font-size-1);
2184
- cursor: pointer;
2185
- }
2186
- .cd-table__filter-reset {
2187
- color: var(--cd-color-text-2);
2188
- }
2189
- .cd-table__filter-confirm {
2190
- color: var(--cd-color-primary);
2191
- }
2192
-
2193
- /* --- 列宽拖拽手柄 --- */
2194
- .cd-table__cell--resizable {
2195
- position: relative;
2196
- }
2197
- .cd-table__resize-handle {
2198
- position: absolute;
2199
- inset-block: 0;
2200
- inset-inline-end: 0;
2201
- inline-size: 8px;
2202
- cursor: col-resize;
2203
- /* 提到固定列阴影/内容之上,确保可命中 */
2204
- z-index: 4;
2205
- touch-action: none;
2206
- user-select: none;
2207
- }
2208
- .cd-table__resize-handle::after {
2209
- content: '';
2210
- position: absolute;
2211
- inset-block: 25%;
2212
- inset-inline-end: 3px;
2213
- inline-size: 2px;
2214
- background: transparent;
2215
- transition: background var(--cd-motion-duration-fast) var(--cd-motion-ease-standard);
2216
- }
2217
- .cd-table__resize-handle:hover::after,
2218
- .cd-table__cell--resizing .cd-table__resize-handle::after {
2219
- background: var(--cd-color-primary);
2220
- }
2221
- @media (prefers-reduced-motion: reduce) {
2222
- .cd-table__resize-handle::after {
2223
- transition: none;
2224
- }
2225
- }
2226
-
2227
- .cd-table__sort-btn {
2228
- display: inline-flex;
2229
- align-items: center;
2230
- gap: var(--cd-spacing-1);
2231
- padding: 0;
2232
- color: inherit;
2233
- font: inherit;
2234
- font-weight: 600;
2235
- background: none;
2236
- border: none;
2237
- cursor: pointer;
2238
- }
2239
- .cd-table__sort-btn:focus-visible {
2240
- outline: none;
2241
- box-shadow: var(--cd-focus-ring);
2242
- border-radius: var(--cd-radius-small, 4px);
2243
- }
2244
-
2245
- .cd-table__sort-icons {
2246
- display: inline-flex;
2247
- flex-direction: column;
2248
- gap: 1px;
2249
- color: var(--cd-table-sort-icon-color);
2250
- }
2251
- .cd-table__sort--active {
2252
- color: var(--cd-table-sort-active-color);
2253
- }
2254
-
2255
- .cd-table__checkbox {
2256
- cursor: pointer;
2257
- accent-color: var(--cd-color-primary);
2258
- }
2259
- .cd-table__checkbox:disabled {
2260
- cursor: not-allowed;
2261
- }
2262
- .cd-table__checkbox:focus-visible {
2263
- outline: none;
2264
- box-shadow: var(--cd-focus-ring);
2265
- }
2266
-
2267
- .cd-table__pagination {
2268
- display: flex;
2269
- justify-content: flex-end;
2270
- margin-block-start: var(--cd-spacing-3);
2271
- }
2272
-
2273
- .cd-table__loading {
2274
- position: absolute;
2275
- inset: 0;
2276
- display: flex;
2277
- align-items: center;
2278
- justify-content: center;
2279
- background: var(--cd-table-loading-mask);
2280
- opacity: 0.6;
2281
- }
2282
-
2283
- .cd-table__spinner {
2284
- inline-size: 28px;
2285
- block-size: 28px;
2286
- border: 3px solid var(--cd-color-fill-1, rgba(0, 0, 0, 0.1));
2287
- border-top-color: var(--cd-color-primary);
2288
- border-radius: 50%;
2289
- animation: cd-table-spin 0.8s linear infinite;
2290
- }
2291
-
2292
- @keyframes cd-table-spin {
2293
- to {
2294
- transform: rotate(360deg);
2295
- }
2296
- }
2297
-
2298
- @media (prefers-reduced-motion: reduce) {
2299
- .cd-table__spinner {
2300
- animation: none;
2301
- }
2302
- .cd-table__sort-up,
2303
- .cd-table__sort-down {
2304
- transition: none;
2305
- }
2306
- }
2307
-
2308
- /* --- 分组标题行 --- */
2309
- .cd-table__row--group-header {
2310
- background: var(--cd-table-header-bg);
2311
- }
2312
- .cd-table__cell--group-header {
2313
- padding-block: var(--cd-table-cell-padding-y);
2314
- padding-inline: var(--cd-table-cell-padding-x);
2315
- font-weight: 600;
2316
- color: var(--cd-table-header-text);
2317
- border-block-end: 1px solid var(--cd-table-border-color);
2318
- }
2319
-
2320
- /* --- 表格顶部标题/底部区域 --- */
2321
- .cd-table__title-area {
2322
- margin-block-end: var(--cd-spacing-2, 8px);
2323
- }
2324
- .cd-table__footer {
2325
- margin-block-start: var(--cd-spacing-3, 12px);
2326
- }
2327
- </style>