@chenzy-design/svelte 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (476) hide show
  1. package/dist/components.json +1 -1
  2. package/package.json +7 -8
  3. package/src/_floating/use-floating.ts +0 -208
  4. package/src/anchor/Anchor.a11y.test.ts +0 -49
  5. package/src/anchor/Anchor.kbd.test.ts +0 -70
  6. package/src/anchor/Anchor.svelte +0 -359
  7. package/src/anchor/AnchorKbdFixture.svelte +0 -24
  8. package/src/anchor/index.ts +0 -3
  9. package/src/anchor/meta.ts +0 -70
  10. package/src/anchor/types.ts +0 -8
  11. package/src/autocomplete/AutoComplete.a11y.test.ts +0 -49
  12. package/src/autocomplete/AutoComplete.kbd.test.ts +0 -69
  13. package/src/autocomplete/AutoComplete.svelte +0 -706
  14. package/src/autocomplete/AutoCompleteKbdFixture.svelte +0 -24
  15. package/src/autocomplete/index.ts +0 -2
  16. package/src/autocomplete/meta.ts +0 -41
  17. package/src/avatar/Avatar.a11y.test.ts +0 -37
  18. package/src/avatar/Avatar.svelte +0 -315
  19. package/src/avatar/AvatarGroup.svelte +0 -142
  20. package/src/avatar/context.ts +0 -21
  21. package/src/avatar/index.ts +0 -10
  22. package/src/avatar/meta.ts +0 -73
  23. package/src/back-top/BackTop.a11y.test.ts +0 -40
  24. package/src/back-top/BackTop.svelte +0 -314
  25. package/src/back-top/index.ts +0 -2
  26. package/src/back-top/meta.ts +0 -108
  27. package/src/badge/Badge.a11y.test.ts +0 -35
  28. package/src/badge/Badge.svelte +0 -328
  29. package/src/badge/BadgeA11yFixture.svelte +0 -18
  30. package/src/badge/index.ts +0 -2
  31. package/src/badge/meta.ts +0 -62
  32. package/src/banner/Banner.a11y.test.ts +0 -48
  33. package/src/banner/Banner.svelte +0 -368
  34. package/src/banner/index.ts +0 -3
  35. package/src/banner/meta.ts +0 -121
  36. package/src/breadcrumb/Breadcrumb.a11y.test.ts +0 -35
  37. package/src/breadcrumb/Breadcrumb.kbd.test.ts +0 -45
  38. package/src/breadcrumb/Breadcrumb.svelte +0 -414
  39. package/src/breadcrumb/BreadcrumbKbdFixture.svelte +0 -23
  40. package/src/breadcrumb/Item.svelte +0 -77
  41. package/src/breadcrumb/context.ts +0 -27
  42. package/src/breadcrumb/index.ts +0 -21
  43. package/src/breadcrumb/meta.ts +0 -128
  44. package/src/breadcrumb/types.ts +0 -4
  45. package/src/button/Button.a11y.test.ts +0 -54
  46. package/src/button/Button.svelte +0 -176
  47. package/src/button/index.ts +0 -2
  48. package/src/button/meta.ts +0 -28
  49. package/src/calendar/Calendar.a11y.test.ts +0 -51
  50. package/src/calendar/Calendar.kbd.test.ts +0 -59
  51. package/src/calendar/Calendar.svelte +0 -1344
  52. package/src/calendar/CalendarKbdFixture.svelte +0 -23
  53. package/src/calendar/index.ts +0 -3
  54. package/src/calendar/meta.ts +0 -117
  55. package/src/card/Card.a11y.test.ts +0 -38
  56. package/src/card/Card.svelte +0 -341
  57. package/src/card/CardMeta.svelte +0 -60
  58. package/src/card/index.ts +0 -8
  59. package/src/card/meta.ts +0 -83
  60. package/src/carousel/Carousel.a11y.test.ts +0 -53
  61. package/src/carousel/Carousel.kbd.test.ts +0 -67
  62. package/src/carousel/Carousel.svelte +0 -806
  63. package/src/carousel/CarouselA11yFixture.svelte +0 -25
  64. package/src/carousel/CarouselKbdFixture.svelte +0 -24
  65. package/src/carousel/index.ts +0 -2
  66. package/src/carousel/meta.ts +0 -74
  67. package/src/cascader/Cascader.a11y.test.ts +0 -59
  68. package/src/cascader/Cascader.kbd.test.ts +0 -56
  69. package/src/cascader/Cascader.svelte +0 -1570
  70. package/src/cascader/CascaderKbdFixture.svelte +0 -31
  71. package/src/cascader/index.ts +0 -3
  72. package/src/cascader/meta.ts +0 -57
  73. package/src/cascader/types.ts +0 -9
  74. package/src/checkbox/Checkbox.svelte +0 -281
  75. package/src/checkbox/CheckboxGroup.a11y.test.ts +0 -43
  76. package/src/checkbox/CheckboxGroup.kbd.test.ts +0 -40
  77. package/src/checkbox/CheckboxGroup.svelte +0 -122
  78. package/src/checkbox/CheckboxGroupKbdFixture.svelte +0 -20
  79. package/src/checkbox/context.ts +0 -31
  80. package/src/checkbox/index.ts +0 -4
  81. package/src/checkbox/meta.ts +0 -67
  82. package/src/collapse/Collapse.a11y.test.ts +0 -53
  83. package/src/collapse/Collapse.kbd.test.ts +0 -89
  84. package/src/collapse/Collapse.svelte +0 -406
  85. package/src/collapse/CollapseA11yFixture.svelte +0 -27
  86. package/src/collapse/CollapseKbdFixture.svelte +0 -25
  87. package/src/collapse/CollapsePanel.svelte +0 -102
  88. package/src/collapse/context.ts +0 -54
  89. package/src/collapse/index.ts +0 -17
  90. package/src/collapse/meta.ts +0 -79
  91. package/src/collapse/types.ts +0 -5
  92. package/src/color-picker/ColorPicker.a11y.test.ts +0 -60
  93. package/src/color-picker/ColorPicker.kbd.test.ts +0 -73
  94. package/src/color-picker/ColorPicker.svelte +0 -985
  95. package/src/color-picker/ColorPickerKbdFixture.svelte +0 -25
  96. package/src/color-picker/index.ts +0 -2
  97. package/src/color-picker/meta.ts +0 -47
  98. package/src/config-provider/ConfigProvider.svelte +0 -227
  99. package/src/config-provider/context.ts +0 -29
  100. package/src/config-provider/index.ts +0 -48
  101. package/src/config-provider/meta.ts +0 -128
  102. package/src/date-picker/DatePicker.a11y.test.ts +0 -45
  103. package/src/date-picker/DatePicker.kbd.test.ts +0 -71
  104. package/src/date-picker/DatePicker.svelte +0 -1798
  105. package/src/date-picker/DatePickerKbdFixture.svelte +0 -26
  106. package/src/date-picker/RangePicker.kbd.test.ts +0 -69
  107. package/src/date-picker/RangePicker.svelte +0 -775
  108. package/src/date-picker/RangePickerKbdFixture.svelte +0 -30
  109. package/src/date-picker/index.ts +0 -4
  110. package/src/date-picker/meta.ts +0 -67
  111. package/src/date-picker/range-meta.ts +0 -44
  112. package/src/descriptions/Descriptions.a11y.test.ts +0 -33
  113. package/src/descriptions/Descriptions.svelte +0 -287
  114. package/src/descriptions/DescriptionsItem.svelte +0 -43
  115. package/src/descriptions/context.ts +0 -21
  116. package/src/descriptions/index.ts +0 -16
  117. package/src/descriptions/meta.ts +0 -45
  118. package/src/descriptions/types.ts +0 -6
  119. package/src/divider/Divider.a11y.test.ts +0 -23
  120. package/src/divider/Divider.svelte +0 -154
  121. package/src/divider/index.ts +0 -2
  122. package/src/divider/meta.ts +0 -23
  123. package/src/drawer/Drawer.a11y.test.ts +0 -41
  124. package/src/drawer/Drawer.kbd.test.ts +0 -67
  125. package/src/drawer/Drawer.svelte +0 -554
  126. package/src/drawer/DrawerKbdFixture.svelte +0 -28
  127. package/src/drawer/index.ts +0 -2
  128. package/src/drawer/meta.ts +0 -127
  129. package/src/dropdown/Dropdown.a11y.test.ts +0 -46
  130. package/src/dropdown/Dropdown.kbd.test.ts +0 -56
  131. package/src/dropdown/Dropdown.svelte +0 -573
  132. package/src/dropdown/DropdownA11yFixture.svelte +0 -24
  133. package/src/dropdown/DropdownDivider.svelte +0 -17
  134. package/src/dropdown/DropdownItem.svelte +0 -127
  135. package/src/dropdown/DropdownItemNode.svelte +0 -355
  136. package/src/dropdown/DropdownKbdFixture.svelte +0 -26
  137. package/src/dropdown/DropdownMenu.svelte +0 -24
  138. package/src/dropdown/DropdownSubMenu.svelte +0 -212
  139. package/src/dropdown/DropdownTitle.svelte +0 -34
  140. package/src/dropdown/context.ts +0 -13
  141. package/src/dropdown/index.ts +0 -36
  142. package/src/dropdown/meta.ts +0 -97
  143. package/src/dropdown/types.test.ts +0 -50
  144. package/src/dropdown/types.ts +0 -67
  145. package/src/empty/Empty.a11y.test.ts +0 -24
  146. package/src/empty/Empty.svelte +0 -304
  147. package/src/empty/index.ts +0 -2
  148. package/src/empty/meta.ts +0 -41
  149. package/src/form/Field.svelte +0 -492
  150. package/src/form/FieldArray.svelte +0 -75
  151. package/src/form/Form.a11y.test.ts +0 -39
  152. package/src/form/Form.svelte +0 -243
  153. package/src/form/FormA11yFixture.svelte +0 -31
  154. package/src/form/FormCascader.svelte +0 -82
  155. package/src/form/FormCheckbox.svelte +0 -83
  156. package/src/form/FormDatePicker.svelte +0 -80
  157. package/src/form/FormErrorMessage.svelte +0 -44
  158. package/src/form/FormInput.svelte +0 -95
  159. package/src/form/FormLabel.svelte +0 -46
  160. package/src/form/FormRadio.svelte +0 -83
  161. package/src/form/FormRating.svelte +0 -85
  162. package/src/form/FormSection.svelte +0 -45
  163. package/src/form/FormSelect.svelte +0 -96
  164. package/src/form/FormSlider.svelte +0 -95
  165. package/src/form/FormSlot.svelte +0 -51
  166. package/src/form/FormSwitch.svelte +0 -82
  167. package/src/form/FormTagInput.svelte +0 -79
  168. package/src/form/FormTreeSelect.svelte +0 -85
  169. package/src/form/FormUpload.svelte +0 -92
  170. package/src/form/context.ts +0 -47
  171. package/src/form/index.ts +0 -22
  172. package/src/form/meta.ts +0 -85
  173. package/src/grid/Col.svelte +0 -142
  174. package/src/grid/Grid.a11y.test.ts +0 -14
  175. package/src/grid/GridA11yFixture.svelte +0 -12
  176. package/src/grid/Row.svelte +0 -116
  177. package/src/grid/index.ts +0 -3
  178. package/src/grid/meta.ts +0 -72
  179. package/src/grid/use-breakpoint.svelte.ts +0 -48
  180. package/src/highlight/Highlight.a11y.test.ts +0 -25
  181. package/src/highlight/Highlight.svelte +0 -99
  182. package/src/highlight/index.ts +0 -2
  183. package/src/highlight/meta.ts +0 -80
  184. package/src/icon/Icon.svelte +0 -156
  185. package/src/icon/index.ts +0 -2
  186. package/src/icon/meta.ts +0 -41
  187. package/src/image/Image.a11y.test.ts +0 -30
  188. package/src/image/Image.svelte +0 -387
  189. package/src/image/ImagePreview.kbd.test.ts +0 -52
  190. package/src/image/ImagePreview.svelte +0 -309
  191. package/src/image/ImagePreviewGroup.svelte +0 -93
  192. package/src/image/ImagePreviewKbdFixture.svelte +0 -32
  193. package/src/image/context.ts +0 -26
  194. package/src/image/index.ts +0 -15
  195. package/src/image/meta.ts +0 -131
  196. package/src/index.ts +0 -208
  197. package/src/input/Input.a11y.test.ts +0 -58
  198. package/src/input/Input.svelte +0 -505
  199. package/src/input/index.ts +0 -2
  200. package/src/input/meta.ts +0 -40
  201. package/src/input-number/InputNumber.a11y.test.ts +0 -43
  202. package/src/input-number/InputNumber.kbd.test.ts +0 -41
  203. package/src/input-number/InputNumber.svelte +0 -674
  204. package/src/input-number/InputNumberKbdFixture.svelte +0 -15
  205. package/src/input-number/index.ts +0 -2
  206. package/src/input-number/meta.ts +0 -65
  207. package/src/layout/Content.svelte +0 -37
  208. package/src/layout/Footer.svelte +0 -49
  209. package/src/layout/Header.svelte +0 -46
  210. package/src/layout/Layout.a11y.test.ts +0 -34
  211. package/src/layout/Layout.svelte +0 -60
  212. package/src/layout/LayoutA11yFixture.svelte +0 -21
  213. package/src/layout/Sider.svelte +0 -207
  214. package/src/layout/index.ts +0 -26
  215. package/src/layout/meta.ts +0 -116
  216. package/src/list/List.a11y.test.ts +0 -69
  217. package/src/list/List.bench.ts +0 -26
  218. package/src/list/List.kbd.test.ts +0 -71
  219. package/src/list/List.svelte +0 -920
  220. package/src/list/ListA11yFixture.svelte +0 -38
  221. package/src/list/ListBenchFixture.svelte +0 -22
  222. package/src/list/ListItem.svelte +0 -175
  223. package/src/list/ListKbdFixture.svelte +0 -31
  224. package/src/list/ListMeta.svelte +0 -73
  225. package/src/list/context.ts +0 -39
  226. package/src/list/index.ts +0 -21
  227. package/src/list/meta.ts +0 -99
  228. package/src/locale-provider/LocaleProvider.svelte +0 -110
  229. package/src/locale-provider/context.ts +0 -22
  230. package/src/locale-provider/index.ts +0 -21
  231. package/src/locale-provider/meta.ts +0 -93
  232. package/src/locale-provider/use-locale.ts +0 -25
  233. package/src/lottie-icon/LottieIcon.svelte +0 -330
  234. package/src/lottie-icon/index.ts +0 -9
  235. package/src/lottie-icon/meta.ts +0 -162
  236. package/src/menu/Menu.a11y.test.ts +0 -54
  237. package/src/menu/Menu.kbd.test.ts +0 -69
  238. package/src/menu/Menu.svelte +0 -762
  239. package/src/menu/MenuKbdFixture.svelte +0 -22
  240. package/src/menu/MenuPopupNode.svelte +0 -525
  241. package/src/menu/index.ts +0 -4
  242. package/src/menu/meta.ts +0 -137
  243. package/src/menu/types.ts +0 -120
  244. package/src/meta.test.ts +0 -173
  245. package/src/modal/ConfirmModal.svelte +0 -173
  246. package/src/modal/Modal.a11y.test.ts +0 -46
  247. package/src/modal/Modal.kbd.test.ts +0 -65
  248. package/src/modal/Modal.svelte +0 -511
  249. package/src/modal/ModalKbdFixture.svelte +0 -24
  250. package/src/modal/command.svelte.ts +0 -103
  251. package/src/modal/index.ts +0 -30
  252. package/src/modal/meta.ts +0 -165
  253. package/src/modal/z-stack.ts +0 -26
  254. package/src/notification/NotificationContainer.svelte +0 -192
  255. package/src/notification/NotificationItem.a11y.test.ts +0 -73
  256. package/src/notification/NotificationItem.svelte +0 -368
  257. package/src/notification/index.ts +0 -9
  258. package/src/notification/meta.ts +0 -120
  259. package/src/notification/store.ts +0 -191
  260. package/src/overflow-list/OverflowList.a11y.test.ts +0 -46
  261. package/src/overflow-list/OverflowList.kbd.test.ts +0 -34
  262. package/src/overflow-list/OverflowList.svelte +0 -539
  263. package/src/overflow-list/OverflowListA11yFixture.svelte +0 -22
  264. package/src/overflow-list/OverflowListKbdFixture.svelte +0 -21
  265. package/src/overflow-list/index.ts +0 -2
  266. package/src/overflow-list/meta.ts +0 -138
  267. package/src/pagination/Pagination.a11y.test.ts +0 -62
  268. package/src/pagination/Pagination.kbd.test.ts +0 -66
  269. package/src/pagination/Pagination.svelte +0 -428
  270. package/src/pagination/PaginationKbdFixture.svelte +0 -15
  271. package/src/pagination/index.ts +0 -2
  272. package/src/pagination/meta.ts +0 -73
  273. package/src/popconfirm/Popconfirm.a11y.test.ts +0 -46
  274. package/src/popconfirm/Popconfirm.kbd.test.ts +0 -42
  275. package/src/popconfirm/Popconfirm.svelte +0 -724
  276. package/src/popconfirm/PopconfirmA11yFixture.svelte +0 -34
  277. package/src/popconfirm/PopconfirmKbdFixture.svelte +0 -17
  278. package/src/popconfirm/index.ts +0 -2
  279. package/src/popconfirm/meta.ts +0 -200
  280. package/src/popover/Popover.a11y.test.ts +0 -58
  281. package/src/popover/Popover.kbd.test.ts +0 -42
  282. package/src/popover/Popover.svelte +0 -643
  283. package/src/popover/PopoverA11yFixture.svelte +0 -35
  284. package/src/popover/PopoverKbdFixture.svelte +0 -18
  285. package/src/popover/index.ts +0 -2
  286. package/src/popover/meta.ts +0 -103
  287. package/src/progress/Progress.a11y.test.ts +0 -37
  288. package/src/progress/Progress.svelte +0 -423
  289. package/src/progress/index.ts +0 -3
  290. package/src/progress/meta.ts +0 -132
  291. package/src/radio/Radio.svelte +0 -330
  292. package/src/radio/RadioGroup.a11y.test.ts +0 -43
  293. package/src/radio/RadioGroup.kbd.test.ts +0 -75
  294. package/src/radio/RadioGroup.svelte +0 -199
  295. package/src/radio/RadioGroupKbdFixture.svelte +0 -21
  296. package/src/radio/context.ts +0 -42
  297. package/src/radio/index.ts +0 -4
  298. package/src/radio/meta.ts +0 -68
  299. package/src/rating/Rating.a11y.test.ts +0 -41
  300. package/src/rating/Rating.kbd.test.ts +0 -48
  301. package/src/rating/Rating.svelte +0 -407
  302. package/src/rating/RatingKbdFixture.svelte +0 -15
  303. package/src/rating/index.ts +0 -2
  304. package/src/rating/meta.ts +0 -40
  305. package/src/resize-observer/ResizeObserver.svelte +0 -169
  306. package/src/resize-observer/action.ts +0 -80
  307. package/src/resize-observer/index.ts +0 -9
  308. package/src/resize-observer/meta.ts +0 -102
  309. package/src/scroll-list/ScrollColumn.svelte +0 -592
  310. package/src/scroll-list/ScrollList.svelte +0 -257
  311. package/src/scroll-list/index.ts +0 -4
  312. package/src/scroll-list/meta.ts +0 -93
  313. package/src/scroll-list/types.ts +0 -18
  314. package/src/select/Select.a11y.test.ts +0 -59
  315. package/src/select/Select.kbd.test.ts +0 -59
  316. package/src/select/Select.svelte +0 -1155
  317. package/src/select/SelectKbdFixture.svelte +0 -29
  318. package/src/select/index.ts +0 -3
  319. package/src/select/meta.ts +0 -78
  320. package/src/select/types.ts +0 -2
  321. package/src/side-sheet/SideSheet.a11y.test.ts +0 -53
  322. package/src/side-sheet/SideSheet.kbd.test.ts +0 -63
  323. package/src/side-sheet/SideSheet.svelte +0 -659
  324. package/src/side-sheet/SideSheetKbdFixture.svelte +0 -30
  325. package/src/side-sheet/index.ts +0 -2
  326. package/src/side-sheet/meta.ts +0 -116
  327. package/src/skeleton/Skeleton.a11y.test.ts +0 -35
  328. package/src/skeleton/Skeleton.svelte +0 -131
  329. package/src/skeleton/SkeletonAvatar.svelte +0 -82
  330. package/src/skeleton/SkeletonButton.svelte +0 -90
  331. package/src/skeleton/SkeletonImage.svelte +0 -100
  332. package/src/skeleton/SkeletonParagraph.svelte +0 -103
  333. package/src/skeleton/SkeletonTitle.svelte +0 -74
  334. package/src/skeleton/context.ts +0 -11
  335. package/src/skeleton/index.ts +0 -8
  336. package/src/skeleton/meta.ts +0 -65
  337. package/src/slider/Slider.a11y.test.ts +0 -44
  338. package/src/slider/Slider.kbd.test.ts +0 -74
  339. package/src/slider/Slider.svelte +0 -716
  340. package/src/slider/SliderKbdFixture.svelte +0 -21
  341. package/src/slider/index.ts +0 -2
  342. package/src/slider/meta.ts +0 -55
  343. package/src/space/Space.a11y.test.ts +0 -22
  344. package/src/space/Space.svelte +0 -109
  345. package/src/space/SpaceA11yFixture.svelte +0 -17
  346. package/src/space/index.ts +0 -2
  347. package/src/space/meta.ts +0 -27
  348. package/src/spin/Spin.a11y.test.ts +0 -29
  349. package/src/spin/Spin.svelte +0 -293
  350. package/src/spin/SpinA11yFixture.svelte +0 -18
  351. package/src/spin/index.ts +0 -2
  352. package/src/spin/meta.ts +0 -72
  353. package/src/steps/Steps.a11y.test.ts +0 -39
  354. package/src/steps/Steps.kbd.test.ts +0 -73
  355. package/src/steps/Steps.svelte +0 -392
  356. package/src/steps/StepsKbdFixture.svelte +0 -21
  357. package/src/steps/index.ts +0 -3
  358. package/src/steps/meta.ts +0 -59
  359. package/src/steps/types.ts +0 -8
  360. package/src/switch/Switch.a11y.test.ts +0 -46
  361. package/src/switch/Switch.kbd.test.ts +0 -40
  362. package/src/switch/Switch.svelte +0 -310
  363. package/src/switch/SwitchKbdFixture.svelte +0 -22
  364. package/src/switch/index.ts +0 -2
  365. package/src/switch/meta.ts +0 -44
  366. package/src/table/Table.a11y.test.ts +0 -70
  367. package/src/table/Table.bench.ts +0 -51
  368. package/src/table/Table.kbd.test.ts +0 -94
  369. package/src/table/Table.svelte +0 -2327
  370. package/src/table/TableKbdFixture.svelte +0 -35
  371. package/src/table/grid-nav.test.ts +0 -173
  372. package/src/table/grid-nav.ts +0 -146
  373. package/src/table/index.ts +0 -13
  374. package/src/table/meta.ts +0 -121
  375. package/src/table/types.ts +0 -133
  376. package/src/tabs/TabPane.svelte +0 -92
  377. package/src/tabs/Tabs.a11y.test.ts +0 -47
  378. package/src/tabs/Tabs.kbd.test.ts +0 -74
  379. package/src/tabs/Tabs.svelte +0 -1128
  380. package/src/tabs/TabsA11yFixture.svelte +0 -20
  381. package/src/tabs/TabsKbdFixture.svelte +0 -25
  382. package/src/tabs/context.ts +0 -43
  383. package/src/tabs/index.ts +0 -14
  384. package/src/tabs/meta.ts +0 -152
  385. package/src/tabs/types.ts +0 -6
  386. package/src/tag/Tag.a11y.test.ts +0 -33
  387. package/src/tag/Tag.svelte +0 -366
  388. package/src/tag/TagA11yFixture.svelte +0 -18
  389. package/src/tag/index.ts +0 -2
  390. package/src/tag/meta.ts +0 -92
  391. package/src/tag-input/TagInput.a11y.test.ts +0 -41
  392. package/src/tag-input/TagInput.svelte +0 -544
  393. package/src/tag-input/index.ts +0 -2
  394. package/src/tag-input/meta.ts +0 -43
  395. package/src/tag-input/reorder.test.ts +0 -59
  396. package/src/tag-input/reorder.ts +0 -41
  397. package/src/test-utils/LocaleHarness.svelte +0 -29
  398. package/src/test-utils/a11y.ts +0 -108
  399. package/src/test-utils/kbd.ts +0 -52
  400. package/src/textarea/TextArea.a11y.test.ts +0 -44
  401. package/src/textarea/TextArea.svelte +0 -420
  402. package/src/textarea/index.ts +0 -2
  403. package/src/textarea/meta.ts +0 -104
  404. package/src/time-picker/TimePicker.a11y.test.ts +0 -45
  405. package/src/time-picker/TimePicker.kbd.test.ts +0 -70
  406. package/src/time-picker/TimePicker.svelte +0 -1023
  407. package/src/time-picker/TimePickerKbdFixture.svelte +0 -23
  408. package/src/time-picker/index.ts +0 -2
  409. package/src/time-picker/meta.ts +0 -64
  410. package/src/timeline/Timeline.a11y.test.ts +0 -54
  411. package/src/timeline/Timeline.svelte +0 -599
  412. package/src/timeline/TimelineItem.svelte +0 -164
  413. package/src/timeline/context.ts +0 -28
  414. package/src/timeline/index.ts +0 -16
  415. package/src/timeline/meta.ts +0 -129
  416. package/src/timeline/types.ts +0 -9
  417. package/src/toast/Toast.a11y.test.ts +0 -67
  418. package/src/toast/ToastContainer.svelte +0 -184
  419. package/src/toast/ToastItem.svelte +0 -247
  420. package/src/toast/index.ts +0 -9
  421. package/src/toast/live-region.ts +0 -78
  422. package/src/toast/meta.ts +0 -95
  423. package/src/toast/store.ts +0 -187
  424. package/src/tooltip/Tooltip.a11y.test.ts +0 -41
  425. package/src/tooltip/Tooltip.kbd.test.ts +0 -37
  426. package/src/tooltip/Tooltip.svelte +0 -416
  427. package/src/tooltip/TooltipA11yFixture.svelte +0 -31
  428. package/src/tooltip/TooltipKbdFixture.svelte +0 -16
  429. package/src/tooltip/index.ts +0 -2
  430. package/src/tooltip/meta.ts +0 -59
  431. package/src/tooltip/placement.ts +0 -6
  432. package/src/transfer/Transfer.a11y.test.ts +0 -63
  433. package/src/transfer/Transfer.kbd.test.ts +0 -75
  434. package/src/transfer/Transfer.svelte +0 -1451
  435. package/src/transfer/TransferKbdFixture.svelte +0 -23
  436. package/src/transfer/group.test.ts +0 -55
  437. package/src/transfer/group.ts +0 -61
  438. package/src/transfer/index.ts +0 -3
  439. package/src/transfer/meta.ts +0 -55
  440. package/src/transfer/reorder.test.ts +0 -52
  441. package/src/transfer/reorder.ts +0 -42
  442. package/src/transfer/tree.test.ts +0 -44
  443. package/src/transfer/tree.ts +0 -52
  444. package/src/transfer/types.ts +0 -32
  445. package/src/tree/Tree.a11y.test.ts +0 -63
  446. package/src/tree/Tree.kbd.test.ts +0 -91
  447. package/src/tree/Tree.svelte +0 -1500
  448. package/src/tree/TreeKbdFixture.svelte +0 -30
  449. package/src/tree/index.ts +0 -3
  450. package/src/tree/meta.ts +0 -152
  451. package/src/tree-select/TreeSelect.a11y.test.ts +0 -52
  452. package/src/tree-select/TreeSelect.kbd.test.ts +0 -53
  453. package/src/tree-select/TreeSelect.svelte +0 -1611
  454. package/src/tree-select/TreeSelectKbdFixture.svelte +0 -20
  455. package/src/tree-select/index.ts +0 -3
  456. package/src/tree-select/meta.ts +0 -73
  457. package/src/tree-select/types.ts +0 -11
  458. package/src/tree-select/virtual.test.ts +0 -104
  459. package/src/typography/Link.svelte +0 -120
  460. package/src/typography/Paragraph.svelte +0 -92
  461. package/src/typography/Text.svelte +0 -93
  462. package/src/typography/Title.svelte +0 -91
  463. package/src/typography/Typography.a11y.test.ts +0 -34
  464. package/src/typography/TypographyA11yFixture.svelte +0 -27
  465. package/src/typography/TypographyBase.svelte +0 -807
  466. package/src/typography/index.ts +0 -16
  467. package/src/typography/meta.ts +0 -158
  468. package/src/upload/Upload.a11y.test.ts +0 -58
  469. package/src/upload/Upload.svelte +0 -1094
  470. package/src/upload/UploadA11yFixture.svelte +0 -23
  471. package/src/upload/index.ts +0 -3
  472. package/src/upload/meta.ts +0 -64
  473. package/src/upload/types.ts +0 -16
  474. package/src/virtual-list/VirtualList.svelte +0 -401
  475. package/src/virtual-list/index.ts +0 -2
  476. package/src/virtual-list/meta.ts +0 -106
@@ -1,67 +0,0 @@
1
- /**
2
- * Machine-readable component metadata for AI/docs consumption.
3
- * See specs/00-foundation/ai-friendly.spec.md.
4
- */
5
- export const meta = {
6
- name: 'Checkbox',
7
- category: 'input',
8
- description: '多选框,可独立使用或置于 CheckboxGroup 中管理一组选项,支持半选态。',
9
- props: [
10
- { name: 'checked', type: 'boolean', default: 'undefined', desc: '受控选中;提供则为受控' },
11
- { name: 'defaultChecked', type: 'boolean', default: 'false', desc: '非受控初始选中' },
12
- { name: 'indeterminate', type: 'boolean', default: 'false', desc: '半选态(视觉横线)' },
13
- { name: 'value', type: 'string | number', default: 'undefined', desc: 'Group 内的标识值' },
14
- { name: 'disabled', type: 'boolean', default: 'false' },
15
- { name: 'size', type: "'small'|'default'|'large'", default: 'default' },
16
- { name: 'status', type: "'default'|'warning'|'error'", default: 'default' },
17
- {
18
- name: 'type',
19
- type: "'default'|'card'|'pureCard'",
20
- default: 'default',
21
- desc: '展示形态;card 带边框背景且整卡为命中区,pureCard 无边框。Group 透传,单项可覆盖',
22
- },
23
- { name: 'name', type: 'string', default: 'undefined' },
24
- { name: 'extra', type: 'string', default: 'undefined', desc: '辅助说明,aria-describedby 关联' },
25
- { name: 'id', type: 'string', default: 'useId()' },
26
- { name: 'onChange', type: '(checked: boolean) => void', default: 'undefined' },
27
- { name: 'children', type: 'Snippet', default: 'undefined', desc: '标签内容' },
28
- ],
29
- group: {
30
- name: 'CheckboxGroup',
31
- props: [
32
- { name: 'value', type: '(string|number)[]', default: 'undefined', desc: '受控选中集合' },
33
- { name: 'defaultValue', type: '(string|number)[]', default: '[]' },
34
- {
35
- name: 'options',
36
- type: 'Array<string|number|{label,value,disabled?,extra?}>',
37
- default: 'undefined',
38
- },
39
- { name: 'disabled', type: 'boolean', default: 'false' },
40
- { name: 'size', type: "'small'|'default'|'large'", default: 'default' },
41
- {
42
- name: 'status',
43
- type: "'default'|'warning'|'error'",
44
- default: 'default',
45
- desc: '统一校验态透传子项,单项可覆盖',
46
- },
47
- {
48
- name: 'type',
49
- type: "'default'|'card'|'pureCard'",
50
- default: 'default',
51
- desc: '统一展示形态透传子项',
52
- },
53
- { name: 'name', type: 'string', default: 'undefined' },
54
- { name: 'direction', type: "'horizontal'|'vertical'", default: 'horizontal' },
55
- { name: 'onChange', type: '(v: (string|number)[]) => void', default: 'undefined' },
56
- { name: 'children', type: 'Snippet', default: 'undefined' },
57
- { name: 'ariaLabel', type: 'string', default: 'undefined', desc: '无可见标题时的可访问名(role=group)' },
58
- { name: 'ariaLabelledby', type: 'string', default: 'undefined', desc: '关联组可见标题 id(优先于 ariaLabel)' },
59
- ],
60
- },
61
- a11y: {
62
- role: 'checkbox',
63
- keyboard: ['Space'],
64
- notes: ['隐藏原生 input', 'indeterminate 用 DOM 属性', 'extra 经 aria-describedby 关联'],
65
- },
66
- tokens: ['--cd-checkbox-*', '--cd-focus-ring', '--cd-motion-*', '--cd-spacing-*'],
67
- } as const;
@@ -1,53 +0,0 @@
1
- // Collapse a11y:折叠面板(APG Accordion)。
2
- // Header 外层 role=heading + aria-level;触发器为原生 button + aria-expanded;
3
- // button aria-controls 指向内容 region,region aria-labelledby 指回 header。
4
- // 用数据驱动夹具(CollapseA11yFixture)渲染真实 region,使 aria-controls 不悬空。
5
- import { describe, it, expect } from 'vitest';
6
- import { renderWithLocale, expectNoAxeViolations } from '../test-utils/a11y.js';
7
- import CollapseFixture from './CollapseA11yFixture.svelte';
8
-
9
- describe('Collapse a11y', () => {
10
- it('默认渲染:role=heading + button aria-expanded + region 关联,无 axe violations', async () => {
11
- const { container } = renderWithLocale(CollapseFixture, {});
12
-
13
- // 每个 panel 的 Header 外层为 role=heading + aria-level。
14
- const headings = container.querySelectorAll('[role="heading"]');
15
- expect(headings.length).toBe(3);
16
- expect(headings[0]?.getAttribute('aria-level')).toBe('3');
17
-
18
- // 触发器为原生 button,aria-expanded 标记展开态(默认全收起)。
19
- const headerBtns = container.querySelectorAll('button.cd-collapse__header');
20
- expect(headerBtns.length).toBe(3);
21
- expect(headerBtns[0]?.getAttribute('aria-expanded')).toBe('false');
22
-
23
- // aria-controls 指向真实存在的 region,region aria-labelledby 指回 header。
24
- const controls = headerBtns[0]?.getAttribute('aria-controls');
25
- expect(controls).toBeTruthy();
26
- const region = controls ? container.ownerDocument.getElementById(controls!) : null;
27
- expect(region?.getAttribute('role')).toBe('region');
28
- expect(region?.getAttribute('aria-labelledby')).toBe(headerBtns[0]?.id);
29
-
30
- await expectNoAxeViolations(container);
31
- });
32
-
33
- it('defaultActiveKey 展开:对应 header aria-expanded=true,region 非 hidden', async () => {
34
- const { container } = renderWithLocale(CollapseFixture, {
35
- props: { defaultActiveKey: 'a' },
36
- });
37
- const headerBtns = container.querySelectorAll('button.cd-collapse__header');
38
- expect(headerBtns[0]?.getAttribute('aria-expanded')).toBe('true');
39
- const controls = headerBtns[0]?.getAttribute('aria-controls');
40
- const region = controls ? container.ownerDocument.getElementById(controls!) : null;
41
- expect(region?.hasAttribute('hidden')).toBe(false);
42
- await expectNoAxeViolations(container);
43
- });
44
-
45
- it('roving tabindex:仅一个 Header 为 Tab 停靠点(tabindex=0),其余 -1', async () => {
46
- const { container } = renderWithLocale(CollapseFixture, {});
47
- const headerBtns = [...container.querySelectorAll('button.cd-collapse__header')];
48
- const zero = headerBtns.filter((b) => b.getAttribute('tabindex') === '0');
49
- // 首个未禁用 Header 为停靠点;禁用项(第三个)从 roving 中排除。
50
- expect(zero.length).toBe(1);
51
- await expectNoAxeViolations(container);
52
- });
53
- });
@@ -1,89 +0,0 @@
1
- // Collapse 键盘 e2e(browser project / 真实 chromium)。
2
- // APG Accordion:Header 组为单一 Tab 停靠点,roving(真实焦点)。
3
- // 测真实焦点移动 + Enter/Space 展开——jsdom 测不了(命令式 focus() 不可靠):
4
- // 1. roving 单停靠点:Tab 进入只停在一个 Header(其余 tabindex=-1,默认首个)。
5
- // 2. ↑↓ 真实移动焦点到相邻 Header(无 wrap:clamp,源码 nextRovingIndex(...,false))。
6
- // 3. Home/End 跳首/末 Header。
7
- // 4. Enter / Space 展开当前焦点 Header(aria-expanded=true)。
8
- //
9
- // 真实焦点断言用 page locator 的 .toHaveFocus()。
10
- import { describe, it, expect } from 'vitest';
11
- import { page } from 'vitest/browser';
12
- import { renderKbdFixture, userEvent } from '../test-utils/kbd.js';
13
- import CollapseKbdFixture from './CollapseKbdFixture.svelte';
14
-
15
- function loc(el: Element) {
16
- return page.elementLocator(el);
17
- }
18
-
19
- describe('Collapse 键盘 e2e(accordion header roving,真实焦点)', () => {
20
- it('Tab 单停靠点 + ↑↓ 移动焦点(clamp)+ Home/End', async () => {
21
- const { baseElement } = renderKbdFixture(CollapseKbdFixture);
22
-
23
- const headers = Array.from(
24
- baseElement.querySelectorAll<HTMLElement>('.cd-collapse__header[data-collapse-key]'),
25
- );
26
- expect(headers.length).toBe(3);
27
- const [h1, h2, h3] = headers as [HTMLElement, HTMLElement, HTMLElement];
28
-
29
- // 1. roving 单停靠点:默认首个 Header 为 tabindex=0,其余 -1。
30
- expect(headers.filter((el) => el.tabIndex === 0).length).toBe(1);
31
- expect(h1.tabIndex).toBe(0);
32
-
33
- const before = baseElement.querySelector('[data-testid="before"]') as HTMLElement;
34
- before.focus();
35
- await expect.element(loc(before)).toHaveFocus();
36
- await userEvent.tab();
37
- await expect.element(loc(h1)).toHaveFocus();
38
-
39
- // 2. ↓ 移动焦点到下一 Header(真实焦点 + 停靠点同步)。
40
- await userEvent.keyboard('{ArrowDown}');
41
- await expect.element(loc(h2)).toHaveFocus();
42
- expect(h2.tabIndex).toBe(0);
43
- expect(h1.tabIndex).toBe(-1);
44
-
45
- await userEvent.keyboard('{ArrowDown}');
46
- await expect.element(loc(h3)).toHaveFocus();
47
-
48
- // 无 wrap:末项再 ↓ 停在末项(clamp)。
49
- await userEvent.keyboard('{ArrowDown}');
50
- await expect.element(loc(h3)).toHaveFocus();
51
-
52
- // ↑ 回退;首项再 ↑ 停在首项(clamp)。
53
- await userEvent.keyboard('{ArrowUp}');
54
- await expect.element(loc(h2)).toHaveFocus();
55
- await userEvent.keyboard('{ArrowUp}');
56
- await expect.element(loc(h1)).toHaveFocus();
57
- await userEvent.keyboard('{ArrowUp}');
58
- await expect.element(loc(h1)).toHaveFocus();
59
-
60
- // 3. Home/End 跳首/末。
61
- await userEvent.keyboard('{End}');
62
- await expect.element(loc(h3)).toHaveFocus();
63
- await userEvent.keyboard('{Home}');
64
- await expect.element(loc(h1)).toHaveFocus();
65
- });
66
-
67
- it('Enter / Space 展开当前焦点 Header(aria-expanded)', async () => {
68
- const { baseElement } = renderKbdFixture(CollapseKbdFixture);
69
-
70
- const headers = Array.from(
71
- baseElement.querySelectorAll<HTMLElement>('.cd-collapse__header[data-collapse-key]'),
72
- );
73
- const [h1, h2] = headers as [HTMLElement, HTMLElement];
74
-
75
- h1.focus();
76
- await expect.element(loc(h1)).toHaveFocus();
77
- expect(h1.getAttribute('aria-expanded')).toBe('false');
78
-
79
- // Enter 展开当前 Header(原生 button 触发 onclick → toggle)。
80
- await userEvent.keyboard('{Enter}');
81
- await expect.element(loc(h1)).toHaveAttribute('aria-expanded', 'true');
82
-
83
- // 移到下一 Header,Space 展开(非 accordion,可同时展开)。
84
- await userEvent.keyboard('{ArrowDown}');
85
- await expect.element(loc(h2)).toHaveFocus();
86
- await userEvent.keyboard(' ');
87
- await expect.element(loc(h2)).toHaveAttribute('aria-expanded', 'true');
88
- });
89
- });
@@ -1,406 +0,0 @@
1
- <!--
2
- Collapse — see specs/components/show/Collapse.spec.md
3
- 两种用法择一(与 Timeline / Form 复合组件同模式):
4
- - 数据驱动:传 panels 数组(向后兼容,行为完全不变)。
5
- - 声明式:不传 panels,改在 children 内写 <Collapse.Panel itemKey header>...</Collapse.Panel>。
6
- 父子状态经 context.ts 传递:父提供展开态派生函数 + toggle 回调,子 Panel 消费判断自身
7
- 展开/渲染与点击切换。两模式渲染同一套 .cd-collapse__item 结构,故声明式复用父级全部
8
- grid 动画 / 箭头 / 边框样式(样式用 .cd-collapse :global(.cd-collapse__*) 跨子组件作用域)。
9
-
10
- 红线遵守:
11
- #1 受控 activeKey 不回写 prop:isControlled = $derived(prop !== undefined),
12
- 内部 SvelteSet $state 兜底,current = $derived(...),变更只 onChange(声明式同样经 toggle 落实)。
13
- #2 展开状态用本地 SvelteSet $state,不依赖挂载 registry,render 期不读 effect 写入的数组;
14
- isActive/shouldRender 为纯派生函数,经 context 传给子 Panel 只读。
15
- #3 展开动画用 CSS grid-template-rows 0fr↔1fr 过渡,不 JS 测量 DOM 几何。
16
- -->
17
- <script lang="ts">
18
- import type { Snippet } from 'svelte';
19
- import { SvelteSet } from 'svelte/reactivity';
20
- import { useId, nextRovingIndex, rovingKeyFromEvent } from '@chenzy-design/core';
21
- import type { CollapsePanel } from './types.js';
22
- import { setCollapseContext } from './context.js';
23
-
24
- type Size = 'small' | 'default' | 'large';
25
- type IconPosition = 'left' | 'right';
26
-
27
- interface Props {
28
- panels?: CollapsePanel[];
29
- activeKey?: string | string[];
30
- defaultActiveKey?: string | string[];
31
- accordion?: boolean;
32
- size?: Size;
33
- expandIconPosition?: IconPosition;
34
- bordered?: boolean;
35
- disabled?: boolean;
36
- motion?: boolean;
37
- /** Header 包裹元素的 aria-level(role=heading),默认 3。 */
38
- headingLevel?: number;
39
- /** 首次展开后才渲染面板内容 */
40
- lazyRender?: boolean;
41
- /** 展开过的面板内容保留 DOM(收起后不卸载),与 lazyRender 配合 */
42
- keepDOM?: boolean;
43
- onChange?: (keys: string[]) => void;
44
- /** 某面板被展开后触发(spec §4:on:expand)。 */
45
- onExpand?: (detail: { key: string }) => void;
46
- /** 某面板被收起后触发(spec §4:on:collapse)。 */
47
- onCollapse?: (detail: { key: string }) => void;
48
- /** Header 被点击时触发(spec §4:on:headerClick,在 disabled 拦截前发出,可用于埋点)。 */
49
- onHeaderClick?: (detail: { key: string; event: MouseEvent }) => void;
50
- /** 自定义展开图标,替换默认箭头 SVG;参数为 {isExpanded: boolean}。 */
51
- expandIcon?: Snippet<[{ isExpanded: boolean }]>;
52
- /**
53
- * 数据驱动模式:按 key 渲染面板内容 Snippet<[{ key }]>。
54
- * 声明式模式(不传 panels):内嵌 <Collapse.Panel> 列表,普通 Snippet。
55
- */
56
- children?: Snippet<[{ key: string }]> | Snippet;
57
- }
58
-
59
- let {
60
- panels = [],
61
- activeKey,
62
- defaultActiveKey,
63
- accordion = false,
64
- size = 'default',
65
- expandIconPosition = 'right',
66
- bordered = true,
67
- disabled = false,
68
- motion = true,
69
- headingLevel = 3,
70
- lazyRender = false,
71
- keepDOM = true,
72
- onChange,
73
- onExpand,
74
- onCollapse,
75
- onHeaderClick,
76
- expandIcon,
77
- children,
78
- }: Props = $props();
79
-
80
- const idBase = useId('cd-collapse');
81
-
82
- function normalize(value: string | string[] | undefined): string[] {
83
- if (value === undefined) return [];
84
- return Array.isArray(value) ? value : [value];
85
- }
86
-
87
- function getInitialKeys(): SvelteSet<string> {
88
- return new SvelteSet(normalize(defaultActiveKey));
89
- }
90
-
91
- // 红线 #1: 受控判定 + 内部 SvelteSet 兜底
92
- const isControlled = $derived(activeKey !== undefined);
93
- // 红线 #2: 本地 SvelteSet $state,不依赖挂载 registry
94
- const innerKeys = $state<SvelteSet<string>>(getInitialKeys());
95
-
96
- // 受控时读 prop(归一化),非受控读本地 set
97
- const currentKeys = $derived<string[]>(
98
- isControlled ? normalize(activeKey) : [...innerKeys],
99
- );
100
-
101
- // 记录曾展开过的面板(lazyRender + keepDOM 用)。初值为初始展开集。
102
- const everExpanded = $state<SvelteSet<string>>(getInitialEverExpanded());
103
- function getInitialEverExpanded(): SvelteSet<string> {
104
- return new SvelteSet(normalize(defaultActiveKey ?? activeKey));
105
- }
106
- // 当前激活的也并入「曾展开」(受控场景:active 推进 everExpanded,effect 内写不在 render 期)。
107
- $effect(() => {
108
- for (const k of currentKeys) everExpanded.add(k);
109
- });
110
-
111
- function isActive(key: string): boolean {
112
- return currentKeys.includes(key);
113
- }
114
-
115
- // 渲染策略:
116
- // - 非 lazyRender:始终渲染(内容常驻,配合 grid 动画)。
117
- // - lazyRender + keepDOM:首次展开才渲染,之后保留 DOM。
118
- // - lazyRender 非 keepDOM:仅当前展开渲染(收起卸载)。
119
- function shouldRender(key: string): boolean {
120
- if (!lazyRender) return true;
121
- return keepDOM ? everExpanded.has(key) : isActive(key);
122
- }
123
-
124
- function toggle(key: string, panelDisabled?: boolean) {
125
- if (disabled || panelDisabled) return;
126
-
127
- const isOpen = currentKeys.includes(key);
128
- let nextArr: string[];
129
- if (isOpen) {
130
- nextArr = currentKeys.filter((k) => k !== key);
131
- } else if (accordion) {
132
- nextArr = [key];
133
- } else {
134
- nextArr = [...currentKeys, key];
135
- }
136
-
137
- // 红线 #1: 受控不回写 prop,仅 onChange;非受控更新本地 set
138
- if (!isControlled) {
139
- innerKeys.clear();
140
- for (const k of nextArr) innerKeys.add(k);
141
- }
142
- onChange?.(nextArr);
143
- // spec §4:展开/收起后分别发出 on:expand / on:collapse(key 级语义事件)。
144
- if (isOpen) onCollapse?.({ key });
145
- else onExpand?.({ key });
146
- }
147
-
148
- // spec §4 on:headerClick:Header 被点击即发出(在 disabled 拦截前,可用于埋点),
149
- // 随后再走 toggle(disabled / panelDisabled 在 toggle 内拦截,不影响本事件发出)。
150
- function headerClick(event: MouseEvent, key: string, panelDisabled?: boolean) {
151
- onHeaderClick?.({ key, event });
152
- toggle(key, panelDisabled);
153
- }
154
-
155
- const cls = $derived(
156
- [
157
- 'cd-collapse',
158
- `cd-collapse--${size}`,
159
- `cd-collapse--icon-${expandIconPosition}`,
160
- bordered && 'cd-collapse--bordered',
161
- disabled && 'cd-collapse--disabled',
162
- motion && 'cd-collapse--motion',
163
- ]
164
- .filter(Boolean)
165
- .join(' '),
166
- );
167
-
168
- // 声明式优先级低于 panels:仅在未传 panels 时渲染 children 内的 <Collapse.Panel>。
169
- const useDeclarative = $derived(panels.length === 0 && children != null);
170
-
171
- // --- roving tabindex(a11y §6 / APG Accordion):Header 组为单一 Tab 停靠点。 ---
172
- // rootEl 普通引用(bind:this),命令式 focus() 用,非 render 期读 DOM;
173
- // 声明式 <Collapse.Panel> 也渲染进同一 rootEl,故按 DOM 顺序统一漫游(红线 #2:
174
- // 不用 $state 数组收集子项,避免 effect 自循环)。
175
- let rootEl = $state<HTMLElement | null>(null);
176
- // 当前焦点 Header 的 key;null = 尚无焦点 -> 首个未禁用 Header 作为 Tab 停靠点。
177
- let focusedKey = $state<string | null>(null);
178
-
179
- // 查询 rootEl 下所有未禁用的 Header 按钮(DOM 顺序),roving 在其中漫游。
180
- function focusableHeaders(): HTMLButtonElement[] {
181
- if (!rootEl) return [];
182
- return [
183
- ...rootEl.querySelectorAll<HTMLButtonElement>(
184
- '.cd-collapse__header[data-collapse-key]:not([disabled])',
185
- ),
186
- ];
187
- }
188
-
189
- // 纯派生 tabindex:焦点 Header(或无焦点时首个未禁用 Header)为 0,其余 -1。
190
- // 不在 render 期写 $state(红线 #2)。整体 disabled 时所有 Header tabindex=-1。
191
- function headerTabindex(key: string, panelDisabled?: boolean): 0 | -1 {
192
- if (disabled || panelDisabled) return -1;
193
- if (focusedKey != null) return focusedKey === key ? 0 : -1;
194
- // 无焦点:首个未禁用 Header 为停靠点。数据驱动模式下用 panels 推断首个可聚焦项。
195
- const firstKey = firstFocusableKey();
196
- return firstKey === key ? 0 : -1;
197
- }
198
-
199
- // 首个未禁用 Header 的 key:数据驱动用 panels 派生;声明式回退到 DOM 查询。
200
- function firstFocusableKey(): string | undefined {
201
- if (panels.length > 0) {
202
- return panels.find((p) => !(disabled || p.disabled))?.key;
203
- }
204
- return focusableHeaders()[0]?.dataset.collapseKey;
205
- }
206
-
207
- function focusHeaderByKey(key: string): void {
208
- rootEl
209
- ?.querySelector<HTMLElement>(
210
- `.cd-collapse__header[data-collapse-key="${CSS.escape(key)}"]`,
211
- )
212
- ?.focus();
213
- }
214
-
215
- // Header keydown:↑↓ roving(纯函数 nextRovingIndex 派生,跳过禁用项)、Home/End 跳首尾。
216
- // Enter/Space 交给原生 <button>(向后兼容 toggle)。
217
- function onHeaderKeydown(e: KeyboardEvent, key: string): void {
218
- const intent = rovingKeyFromEvent(e.key);
219
- if (!intent) return;
220
- const headers = focusableHeaders();
221
- if (headers.length === 0) return;
222
- e.preventDefault();
223
- const keys = headers.map((h) => h.dataset.collapseKey ?? '');
224
- const cur = keys.indexOf(key);
225
- const next = nextRovingIndex(cur, keys.length, intent, false);
226
- const nextKey = keys[next];
227
- if (nextKey) {
228
- focusedKey = nextKey;
229
- focusHeaderByKey(nextKey);
230
- }
231
- }
232
-
233
- function onHeaderFocus(key: string): void {
234
- focusedKey = key;
235
- }
236
-
237
- // 经 context 暴露给子 Panel:全部 getter / 纯派生函数,红线 #1#2 落实在父级。
238
- setCollapseContext({
239
- isActive,
240
- shouldRender,
241
- toggle,
242
- headerClick,
243
- getDisabled: () => disabled,
244
- getSize: () => size,
245
- getIconPosition: () => expandIconPosition,
246
- getIdBase: () => idBase,
247
- getHeadingLevel: () => headingLevel,
248
- headerTabindex,
249
- onHeaderKeydown,
250
- onHeaderFocus,
251
- getExpandIcon: () => expandIcon,
252
- });
253
- </script>
254
-
255
- <div class={cls} bind:this={rootEl}>
256
- {#if useDeclarative}
257
- {@render (children as Snippet)?.()}
258
- {:else}
259
- {#each panels as panel (panel.key)}
260
- {@const active = isActive(panel.key)}
261
- {@const itemDisabled = disabled || panel.disabled}
262
- {@const headerId = `${idBase}-h-${panel.key}`}
263
- {@const regionId = `${idBase}-r-${panel.key}`}
264
- <div class="cd-collapse__item" class:cd-collapse__item--active={active}>
265
- <!-- APG Accordion:Header 触发器外层 role=heading + aria-level。 -->
266
- <span role="heading" aria-level={headingLevel} class="cd-collapse__heading">
267
- <button
268
- type="button"
269
- id={headerId}
270
- class="cd-collapse__header"
271
- data-collapse-key={panel.key}
272
- aria-expanded={active}
273
- aria-controls={regionId}
274
- aria-disabled={itemDisabled || undefined}
275
- disabled={itemDisabled || undefined}
276
- tabindex={headerTabindex(panel.key, panel.disabled)}
277
- onclick={(e) => headerClick(e, panel.key, panel.disabled)}
278
- onkeydown={(e) => onHeaderKeydown(e, panel.key)}
279
- onfocus={() => onHeaderFocus(panel.key)}
280
- >
281
- {#if expandIcon}
282
- <span class="cd-collapse__arrow" class:cd-collapse__arrow--open={active} aria-hidden="true">
283
- {@render expandIcon({ isExpanded: active })}
284
- </span>
285
- {:else}
286
- <span class="cd-collapse__arrow" class:cd-collapse__arrow--open={active} aria-hidden="true">
287
- <svg viewBox="0 0 16 16" width="12" height="12" focusable="false">
288
- <path fill="currentColor" d="M6 4l4 4-4 4V4Z" />
289
- </svg>
290
- </span>
291
- {/if}
292
- <span class="cd-collapse__title">{panel.header}</span>
293
- </button>
294
- </span>
295
- <div
296
- id={regionId}
297
- class="cd-collapse__region"
298
- role="region"
299
- aria-labelledby={headerId}
300
- hidden={!active}
301
- >
302
- <div class="cd-collapse__region-inner">
303
- <div class="cd-collapse__content">
304
- {#if shouldRender(panel.key)}
305
- {@render (children as Snippet<[{ key: string }]>)?.({ key: panel.key })}
306
- {/if}
307
- </div>
308
- </div>
309
- </div>
310
- </div>
311
- {/each}
312
- {/if}
313
- </div>
314
-
315
- <style>
316
- /*
317
- .cd-collapse 根(<div>)保留组件作用域哈希;其下各 .cd-collapse__* 后代用 :global 包裹,
318
- 使同一套结构样式既覆盖本组件 panels 渲染的 .cd-collapse__item,也覆盖 <Collapse.Panel>
319
- 在子组件作用域内渲染的相同结构(参考 Timeline)。
320
- */
321
- .cd-collapse {
322
- inline-size: 100%;
323
- }
324
- .cd-collapse--bordered {
325
- border: 1px solid var(--cd-collapse-border);
326
- border-radius: var(--cd-radius-1);
327
- }
328
- .cd-collapse :global(.cd-collapse__item + .cd-collapse__item) {
329
- border-block-start: 1px solid var(--cd-collapse-border);
330
- }
331
- /* role=heading 包裹元素:消除 inline 默认行为,让内部 button 占满宽度。 */
332
- .cd-collapse :global(.cd-collapse__heading) {
333
- display: block;
334
- margin: 0;
335
- font: inherit;
336
- }
337
- .cd-collapse :global(.cd-collapse__header) {
338
- display: flex;
339
- align-items: center;
340
- gap: var(--cd-spacing-2);
341
- inline-size: 100%;
342
- padding: var(--cd-collapse-header-padding);
343
- border: none;
344
- background: transparent;
345
- color: var(--cd-collapse-header-color);
346
- font: inherit;
347
- text-align: start;
348
- cursor: pointer;
349
- }
350
- .cd-collapse :global(.cd-collapse__header:hover:not(:disabled)) {
351
- background: var(--cd-collapse-header-bg-hover);
352
- }
353
- .cd-collapse :global(.cd-collapse__header:focus-visible) {
354
- outline: none;
355
- box-shadow: var(--cd-focus-ring);
356
- }
357
- .cd-collapse :global(.cd-collapse__header:disabled) {
358
- color: var(--cd-color-text-3);
359
- cursor: not-allowed;
360
- }
361
- .cd-collapse--icon-right :global(.cd-collapse__header) {
362
- flex-direction: row-reverse;
363
- }
364
- .cd-collapse--icon-right :global(.cd-collapse__title) {
365
- flex: 1 1 auto;
366
- }
367
- .cd-collapse :global(.cd-collapse__arrow) {
368
- display: inline-flex;
369
- align-items: center;
370
- justify-content: center;
371
- flex: 0 0 auto;
372
- color: var(--cd-collapse-arrow-color);
373
- transition: transform var(--cd-collapse-motion-duration) var(--cd-motion-ease-standard);
374
- }
375
- .cd-collapse :global(.cd-collapse__arrow--open) {
376
- transform: rotate(90deg);
377
- }
378
-
379
- /* 红线 #3: CSS grid-template-rows 0fr↔1fr 过渡,不 JS 测高 */
380
- .cd-collapse :global(.cd-collapse__region) {
381
- display: grid;
382
- grid-template-rows: 1fr;
383
- }
384
- .cd-collapse :global(.cd-collapse__region[hidden]) {
385
- display: grid;
386
- grid-template-rows: 0fr;
387
- }
388
- .cd-collapse--motion :global(.cd-collapse__region) {
389
- transition: grid-template-rows var(--cd-collapse-motion-duration) var(--cd-motion-ease-standard);
390
- }
391
- .cd-collapse :global(.cd-collapse__region-inner) {
392
- overflow: hidden;
393
- min-block-size: 0;
394
- }
395
- .cd-collapse :global(.cd-collapse__content) {
396
- padding: var(--cd-collapse-content-padding);
397
- color: var(--cd-collapse-content-color);
398
- }
399
-
400
- @media (prefers-reduced-motion: reduce) {
401
- .cd-collapse--motion :global(.cd-collapse__region),
402
- .cd-collapse :global(.cd-collapse__arrow) {
403
- transition: none;
404
- }
405
- }
406
- </style>
@@ -1,27 +0,0 @@
1
- <!--
2
- 仅供 Collapse.a11y.test.ts 使用的测试夹具:数据驱动 panels + children Snippet 渲染面板内容,
3
- 使 header button 的 aria-controls 指向真实存在的 region(axe aria-valid-attr-value 通过)。
4
- -->
5
- <script lang="ts">
6
- import { Collapse } from './index.js';
7
- import type { CollapsePanel } from './types.js';
8
-
9
- interface Props {
10
- accordion?: boolean;
11
- disabled?: boolean;
12
- defaultActiveKey?: string | string[];
13
- }
14
- let { accordion = false, disabled = false, defaultActiveKey = [] }: Props = $props();
15
-
16
- const panels: CollapsePanel[] = [
17
- { key: 'a', header: 'Section A' },
18
- { key: 'b', header: 'Section B' },
19
- { key: 'c', header: 'Section C', disabled: true },
20
- ];
21
- </script>
22
-
23
- <Collapse {panels} {accordion} {disabled} {defaultActiveKey}>
24
- {#snippet children({ key })}
25
- <p>Content for {key}</p>
26
- {/snippet}
27
- </Collapse>
@@ -1,25 +0,0 @@
1
- <!--
2
- 仅供 Collapse.kbd.test.ts(browser project)使用的键盘 e2e 夹具。
3
- 数据驱动 panels;Header 组为单一 Tab 停靠点(roving,真实焦点)。
4
- 前后各放按钮验证 Tab 进入只停靠单个 Header、Tab 出去落到 after。
5
- -->
6
- <script lang="ts">
7
- import { LocaleProvider } from '../locale-provider/index.js';
8
- import Collapse from './Collapse.svelte';
9
-
10
- const panels = [
11
- { key: 'p1', header: 'Panel One' },
12
- { key: 'p2', header: 'Panel Two' },
13
- { key: 'p3', header: 'Panel Three' },
14
- ];
15
- </script>
16
-
17
- <LocaleProvider locale="en_US">
18
- <button type="button" data-testid="before">before</button>
19
- <Collapse {panels}>
20
- {#snippet children({ key }: { key: string })}
21
- <p>content {key}</p>
22
- {/snippet}
23
- </Collapse>
24
- <button type="button" data-testid="after">after</button>
25
- </LocaleProvider>