@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,1023 +0,0 @@
1
- <!--
2
- TimePicker — see specs/components/input/TimePicker.spec.md
3
- 单选 type='time',HH:mm:ss 三列滚动选择 (+ 12h 制 AM/PM 列)。受控/非受控。
4
- type='timeRange' (或 range):选起止两个时间,值为 [start, end] (双面板)。
5
- value/defaultValue 支持 Date | string (如 '12:30:45'),字符串经 core parseTimeString 解析。
6
- format 字符串 (如 'HH:mm' / 'hh:mm A'):经 core parseFormatSpec 决定显示哪些列 + 12h,
7
- 显示经 core formatTime 序列化 (有 format 时),否则走 Intl.DateTimeFormat (不手拼时间串)。
8
- scrollIntoView 命令式调用 (非响应式 attachment)。
9
- 列项/禁用集生成 + 格式解析/序列化走 @chenzy-design/core 纯函数 (红线 #2)。
10
- -->
11
- <script lang="ts">
12
- import { tick, type Snippet } from 'svelte';
13
- import {
14
- useId,
15
- useDismiss,
16
- buildHourOptions,
17
- buildMinuteOptions,
18
- buildSecondOptions,
19
- applyHideDisabled,
20
- to12Hour,
21
- meridiemOf,
22
- from12Hour,
23
- parseFormatSpec,
24
- formatTime,
25
- parseTimeString,
26
- type Meridiem,
27
- type TimeOption,
28
- } from '@chenzy-design/core';
29
- import { useLocale } from '../locale-provider/index.js';
30
-
31
- type Size = 'small' | 'default' | 'large';
32
- type Status = 'default' | 'warning' | 'error';
33
-
34
- /** 单选入参:Date 或时间字符串 (如 '12:30:45')。 */
35
- type TimeInput = Date | string | null;
36
-
37
- interface Props {
38
- /** 单选时 Date|string;范围时 [start, end] (各自 Date|string)。 */
39
- value?: TimeInput | [TimeInput, TimeInput] | null;
40
- defaultValue?: TimeInput | [TimeInput, TimeInput] | null;
41
- /** 'time' 单选 (默认) / 'timeRange' 范围选择 (等价 range=true)。 */
42
- type?: 'time' | 'timeRange';
43
- /** range=true 等价 type='timeRange'。 */
44
- range?: boolean;
45
- open?: boolean;
46
- defaultOpen?: boolean;
47
- placeholder?: string;
48
- size?: Size;
49
- status?: Status;
50
- disabled?: boolean;
51
- clearable?: boolean;
52
- hourStep?: number;
53
- minuteStep?: number;
54
- secondStep?: number;
55
- showSecond?: boolean;
56
- use12Hours?: boolean;
57
- /** 格式串 (如 'HH:mm' / 'hh:mm A' / 'HH:mm:ss'):决定显示列与 12h,并作为展示/字符串值序列化格式。 */
58
- format?: string;
59
- disabledHours?: () => number[];
60
- disabledMinutes?: (hour: number) => number[];
61
- disabledSeconds?: (hour: number, minute: number) => number[];
62
- hideDisabledOptions?: boolean;
63
- locale?: string;
64
- /** 单选回调 Date|null;范围回调 [Date|null, Date|null]。 */
65
- onChange?: (v: (Date | null) | [Date | null, Date | null]) => void;
66
- onOpenChange?: (open: boolean) => void;
67
- ariaLabel?: string;
68
- /** 浮层溢出自动调整(默认 true)。 */
69
- autoAdjustOverflow?: boolean;
70
- /** 挂载时自动聚焦触发器。 */
71
- autoFocus?: boolean;
72
- /** 自定义清除按钮图标。 */
73
- clearIcon?: Snippet;
74
- /** 是否显示清除按钮(clearable 别名)。 */
75
- showClear?: boolean;
76
- /** 浮层 className。 */
77
- dropdownClassName?: string;
78
- /** 浮层溢出冗余。 */
79
- dropdownMargin?: number | { x?: number; y?: number };
80
- /** 浮层内联样式。 */
81
- dropdownStyle?: string | Record<string, string>;
82
- /** 打开面板时自动聚焦第一列(默认 true)。 */
83
- focusOnOpen?: boolean;
84
- /** 浮层挂载容器。 */
85
- getPopupContainer?: () => HTMLElement;
86
- /** 面板展开动画(默认 true)。 */
87
- motion?: boolean;
88
- /** 面板顶部自定义内容。 */
89
- panelHeader?: string | Snippet;
90
- /** 浮层弹出位置(默认 'bottomLeft')。 */
91
- position?: string;
92
- /** 触发器前缀内容。 */
93
- prefix?: string | Snippet;
94
- /** 范围模式分隔符(默认 '~')。 */
95
- rangeSeparator?: string;
96
- /** 滚动列 item 属性透传。 */
97
- scrollItemProps?: Record<string, unknown>;
98
- /** 阻止浮层点击事件冒泡(默认 true)。 */
99
- stopPropagation?: boolean;
100
- /** 浮层 z-index(默认 1030)。 */
101
- zIndex?: number;
102
- /** 触发器失焦。 */
103
- onBlur?: (e: FocusEvent) => void;
104
- /** 触发器聚焦。 */
105
- onFocus?: (e: FocusEvent) => void;
106
- /** onChange 参数 dateFirst 模式。 */
107
- onChangeWithDateFirst?: boolean;
108
- /** 点击外部触发。 */
109
- onClickOutSide?: (e: MouseEvent) => void;
110
- /** 范围模式禁用函数。 */
111
- disabledTime?: (date: Date) => { disabledHours?: () => number[]; disabledMinutes?: (h: number) => number[]; disabledSeconds?: (h: number, m: number) => number[] };
112
- /** 面板底部自定义内容(在"此刻"/"确定"按钮上方插入)。 */
113
- panelFooter?: string | Snippet;
114
- /** 输入框样式(透传到触发器 button)。 */
115
- inputStyle?: string | Record<string, string>;
116
- /** 输入框 readonly 属性(仅允许通过面板选择,不可键盘输入触发器文本)。 */
117
- inputReadOnly?: boolean;
118
- /** 完全自定义触发器渲染(替换默认 input + 图标区域)。 */
119
- triggerRender?: Snippet<[{ value: Date | null; placeholder: string; open: boolean; disabled: boolean }]>;
120
- /** 无边框模式。 */
121
- borderless?: boolean;
122
- /** focus 时阻止滚动(传给 focus({ preventScroll }) 调用)。 */
123
- preventScroll?: boolean;
124
- }
125
-
126
- let {
127
- value,
128
- defaultValue = null,
129
- type = 'time',
130
- range = false,
131
- open,
132
- defaultOpen = false,
133
- placeholder,
134
- size = 'default',
135
- status = 'default',
136
- disabled = false,
137
- clearable = true,
138
- hourStep = 1,
139
- minuteStep = 1,
140
- secondStep = 1,
141
- showSecond = true,
142
- use12Hours = false,
143
- format,
144
- disabledHours,
145
- disabledMinutes,
146
- disabledSeconds,
147
- hideDisabledOptions = false,
148
- locale = 'zh-CN',
149
- onChange,
150
- onOpenChange,
151
- ariaLabel,
152
- autoAdjustOverflow = true,
153
- autoFocus = false,
154
- clearIcon,
155
- showClear,
156
- dropdownClassName,
157
- dropdownMargin,
158
- dropdownStyle,
159
- focusOnOpen = true,
160
- getPopupContainer,
161
- motion = true,
162
- panelHeader,
163
- position = 'bottomLeft',
164
- prefix,
165
- rangeSeparator = '~',
166
- scrollItemProps,
167
- stopPropagation = true,
168
- zIndex = 1030,
169
- onBlur,
170
- onFocus,
171
- onChangeWithDateFirst = false,
172
- onClickOutSide,
173
- disabledTime,
174
- panelFooter,
175
- inputStyle,
176
- inputReadOnly = false,
177
- triggerRender,
178
- borderless = false,
179
- preventScroll = false,
180
- }: Props = $props();
181
-
182
- const isRange = $derived(range || type === 'timeRange');
183
-
184
- // showClear 是 clearable 别名
185
- const effClearable = $derived(clearable ?? showClear ?? true);
186
-
187
- // --- format 串解析 (红线 #2 经 core 纯函数):决定列与 12h;无 format 时回退 props ---
188
- const formatSpec = $derived(format ? parseFormatSpec(format) : null);
189
- const effShowSecond = $derived(formatSpec ? formatSpec.showSecond : showSecond);
190
- const effUse12Hours = $derived(formatSpec ? formatSpec.use12Hours : use12Hours);
191
-
192
- // --- 字符串/Date 入参归一化为 Date|null (字符串经 core parseTimeString) ---
193
- function toDate(input: TimeInput): Date | null {
194
- if (input == null) return null;
195
- if (input instanceof Date) return input;
196
- const parts = parseTimeString(input);
197
- if (!parts) return null;
198
- const d = new Date();
199
- d.setHours(parts.hour, parts.minute, parts.second, 0);
200
- return d;
201
- }
202
-
203
- const loc = useLocale();
204
-
205
- const baseId = useId('cd-time-picker-panel');
206
-
207
- // --- 受控 value (红线 #1): 不无条件回写 value,仅 onChange ---
208
- // 内部统一用 [start, end] 元组表示 (单选只用 [0]),避免双分支。
209
- type Pair = [Date | null, Date | null];
210
-
211
- function toPair(input: Props['value']): Pair {
212
- if (Array.isArray(input)) return [toDate(input[0] ?? null), toDate(input[1] ?? null)];
213
- return [toDate((input ?? null) as TimeInput), null];
214
- }
215
-
216
- const isValueControlled = $derived(value !== undefined);
217
- // eslint-disable-next-line svelte/no-state-referencing-locally -- 仅捕获初始 defaultValue (非受控初值)
218
- let innerValue = $state<Pair>(getInitialPair());
219
-
220
- function getInitialPair(): Pair {
221
- return toPair(defaultValue);
222
- }
223
- const currentPair = $derived<Pair>(isValueControlled ? toPair(value) : innerValue);
224
-
225
- // 单选视图:始终读 [0]
226
- const current = $derived<Date | null>(currentPair[0]);
227
-
228
- // 范围当前正在编辑的一端 (0=start, 1=end);打开时重置为 start
229
- let activeIndex = $state<0 | 1>(0);
230
- const activeDate = $derived<Date | null>(isRange ? currentPair[activeIndex] : currentPair[0]);
231
-
232
- function emit(next: Pair) {
233
- if (!isValueControlled) innerValue = next;
234
- onChange?.(isRange ? next : next[0]);
235
- }
236
-
237
- // 单选 setValue:写 [0]
238
- function setValue(next: Date | null) {
239
- emit([next, currentPair[1]]);
240
- }
241
-
242
- // 范围 setValue:写当前 activeIndex 端
243
- function setRangeValue(next: Date | null) {
244
- const pair: Pair = [...currentPair];
245
- pair[activeIndex] = next;
246
- emit(pair);
247
- }
248
-
249
- // --- 受控 open (红线 #1): 不无条件回写 open,仅 onOpenChange ---
250
- const isOpenControlled = $derived(open !== undefined);
251
- let innerOpen = $state(getInitialOpen());
252
- const isOpen = $derived(isOpenControlled ? !!open : innerOpen);
253
-
254
- function getInitialOpen(): boolean {
255
- return defaultOpen;
256
- }
257
-
258
- function setOpen(next: boolean) {
259
- if (next === isOpen) return;
260
- if (!isOpenControlled) innerOpen = next;
261
- onOpenChange?.(next);
262
- }
263
-
264
- function toggleOpen() {
265
- if (disabled) return;
266
- setOpen(!isOpen);
267
- }
268
-
269
- // --- 选中的 h/m/s 派生 (24h 内部表示);从当前编辑端 activeDate 读取 ---
270
- const selectedHour = $derived(activeDate ? activeDate.getHours() : 0);
271
- const selectedMinute = $derived(activeDate ? activeDate.getMinutes() : 0);
272
- const selectedSecond = $derived(activeDate ? activeDate.getSeconds() : 0);
273
-
274
- // --- 12h 制派生:当前 meridiem + 小时列显示值 (红线 #2 经 core 纯函数) ---
275
- const selectedMeridiem = $derived<Meridiem>(meridiemOf(selectedHour));
276
- const selectedHourDisplay = $derived(effUse12Hours ? to12Hour(selectedHour) : selectedHour);
277
-
278
- // --- 列项 + 禁用集生成 (红线 #2: 派生纯函数) ---
279
- const hours = $derived(
280
- applyHideDisabled(
281
- buildHourOptions(hourStep, effUse12Hours, selectedMeridiem, disabledHours),
282
- hideDisabledOptions,
283
- ),
284
- );
285
- const minutes = $derived(
286
- applyHideDisabled(
287
- buildMinuteOptions(minuteStep, selectedHour, disabledMinutes),
288
- hideDisabledOptions,
289
- ),
290
- );
291
- const seconds = $derived(
292
- applyHideDisabled(
293
- buildSecondOptions(secondStep, selectedHour, selectedMinute, disabledSeconds),
294
- hideDisabledOptions,
295
- ),
296
- );
297
-
298
- function pad2(n: number): string {
299
- return n < 10 ? `0${n}` : `${n}`;
300
- }
301
-
302
- // --- Intl 本地化展示 (无 format 时;不手拼时间串);12h 制由 hour12 驱动 AM/PM ---
303
- const triggerFormat = $derived(
304
- new Intl.DateTimeFormat(locale, {
305
- hour: '2-digit',
306
- minute: '2-digit',
307
- second: effShowSecond ? '2-digit' : undefined,
308
- hour12: effUse12Hours,
309
- }),
310
- );
311
-
312
- // 单个 Date 的展示串:有 format 走 core formatTime (红线 #2),否则 Intl 本地化
313
- function displayOne(d: Date): string {
314
- if (format) {
315
- return formatTime({ hour: d.getHours(), minute: d.getMinutes(), second: d.getSeconds() }, format);
316
- }
317
- return triggerFormat.format(d);
318
- }
319
-
320
- const placeholderText = $derived(placeholder ?? loc().t('TimePicker.placeholder'));
321
-
322
- const displayText = $derived.by(() => {
323
- if (isRange) {
324
- const [s, e] = currentPair;
325
- if (!s && !e) return placeholderText;
326
- const sep = ' ~ ';
327
- return `${s ? displayOne(s) : ''}${sep}${e ? displayOne(e) : ''}`;
328
- }
329
- return current ? displayOne(current) : placeholderText;
330
- });
331
-
332
- const hasValue = $derived(isRange ? currentPair[0] !== null || currentPair[1] !== null : current !== null);
333
- const showClearBtn = $derived(effClearable && !disabled && hasValue);
334
-
335
- // 合成 Date: 基于当前编辑端或今天,写入 h/m/s;按模式写单选/范围端
336
- function commit(h: number, m: number, s: number) {
337
- const base = activeDate ? new Date(activeDate) : new Date();
338
- base.setHours(h, m, s, 0);
339
- if (isRange) setRangeValue(base);
340
- else setValue(base);
341
- }
342
-
343
- // 12h 制下小时列的值是显示小时 (1-12),按当前 meridiem 转回 24h 内部表示
344
- function pickHour(h: number) {
345
- const hour24 = effUse12Hours ? from12Hour(h, selectedMeridiem) : h;
346
- commit(hour24, selectedMinute, selectedSecond);
347
- }
348
- function pickMinute(m: number) {
349
- commit(selectedHour, m, selectedSecond);
350
- }
351
- function pickSecond(s: number) {
352
- commit(selectedHour, selectedMinute, s);
353
- }
354
- // 切换 AM/PM:保持当前显示小时,重算 24h 表示
355
- function pickMeridiem(m: Meridiem) {
356
- if (m === selectedMeridiem) return;
357
- commit(from12Hour(selectedHourDisplay, m), selectedMinute, selectedSecond);
358
- }
359
-
360
- function setNow() {
361
- const now = new Date();
362
- commit(now.getHours(), now.getMinutes(), now.getSeconds());
363
- }
364
-
365
- function confirm() {
366
- // 范围:在 start 端确认后切到 end 端继续选;end 端确认后关闭
367
- if (isRange && activeIndex === 0) {
368
- activeIndex = 1;
369
- return;
370
- }
371
- setOpen(false);
372
- }
373
-
374
- function clear(e: MouseEvent) {
375
- e.stopPropagation();
376
- if (disabled) return;
377
- if (isRange) emit([null, null]);
378
- else setValue(null);
379
- }
380
-
381
- function onTriggerKeydown(e: KeyboardEvent) {
382
- if (disabled) return;
383
- switch (e.key) {
384
- case 'Enter':
385
- case ' ':
386
- e.preventDefault();
387
- setOpen(true);
388
- break;
389
- case 'ArrowDown':
390
- e.preventDefault();
391
- if (!isOpen) setOpen(true);
392
- break;
393
- case 'Escape':
394
- if (isOpen) {
395
- e.preventDefault();
396
- setOpen(false);
397
- }
398
- break;
399
- default:
400
- break;
401
- }
402
- }
403
-
404
- // --- 列容器引用 (红线 #3: 普通 bind:this,scrollIntoView 命令式调用) ---
405
- let hourCol = $state<HTMLUListElement | null>(null);
406
- let minuteCol = $state<HTMLUListElement | null>(null);
407
- let secondCol = $state<HTMLUListElement | null>(null);
408
- let meridiemCol = $state<HTMLUListElement | null>(null);
409
-
410
- function scrollColToSelected(col: HTMLUListElement | null) {
411
- if (!col) return;
412
- const target = col.querySelector<HTMLElement>('[aria-selected="true"]');
413
- target?.scrollIntoView({ block: 'center' });
414
- }
415
-
416
- // --- 列内 roving 键盘导航(a11y §6 / WAI-ARIA APG listbox)---
417
- // 每列单一 Tab 停靠点:选中项(或首个可选项)tabindex=0,其余 -1。
418
- // 列间用 Tab/Shift+Tab(原生焦点序,停靠点即为各列入口)。
419
-
420
- // 列内可聚焦(非 disabled)选项,按 DOM 顺序漫游。
421
- function colOptions(col: HTMLUListElement | null): HTMLElement[] {
422
- if (!col) return [];
423
- return [...col.querySelectorAll<HTMLElement>('[role="option"]')].filter(
424
- (el) => el.getAttribute('aria-disabled') !== 'true',
425
- );
426
- }
427
-
428
- // 纯派生 tabindex:列内选中项(无选中时首个可选项)为停靠点 0,其余 -1(红线 #2:render 期只读)。
429
- // selected 为该列当前选中值的 option(传 isSelected 布尔),col 标识用于「无选中回退首项」。
430
- function colItemTabindex(isSelectedOpt: boolean, isFirst: boolean, anySelected: boolean): 0 | -1 {
431
- if (anySelected) return isSelectedOpt ? 0 : -1;
432
- return isFirst ? 0 : -1;
433
- }
434
-
435
- // 各列是否存在可聚焦的选中项(决定 roving 停靠点是选中项还是回退首项;红线 #2:纯派生)。
436
- const hourSelected = $derived(hours.some((h) => h.value === selectedHourDisplay && !h.disabled));
437
- const minuteSelected = $derived(minutes.some((m) => m.value === selectedMinute && !m.disabled));
438
-
439
- // 列内 keydown:↑↓ 漫游(循环)、Home/End 跳首末、Enter/Space 选中。
440
- function onColKeydown(e: KeyboardEvent, col: HTMLUListElement | null, pick: (v: number) => void, value: number) {
441
- if (e.key === 'Enter' || e.key === ' ') {
442
- e.preventDefault();
443
- pick(value);
444
- return;
445
- }
446
- if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp' && e.key !== 'Home' && e.key !== 'End') return;
447
- const opts = colOptions(col);
448
- if (opts.length === 0) return;
449
- const cur = opts.findIndex((el) => el === document.activeElement);
450
- e.preventDefault();
451
- let next = cur;
452
- if (e.key === 'ArrowDown') next = cur < 0 ? 0 : (cur + 1) % opts.length;
453
- else if (e.key === 'ArrowUp') next = cur < 0 ? opts.length - 1 : (cur - 1 + opts.length) % opts.length;
454
- else if (e.key === 'Home') next = 0;
455
- else if (e.key === 'End') next = opts.length - 1;
456
- const target = opts[next];
457
- if (!target) return;
458
- // 收敛 roving 停靠点到目标项(命令式写 DOM,非 render 期;红线 #2)。
459
- for (const el of opts) el.tabIndex = el === target ? 0 : -1;
460
- target.focus();
461
- }
462
-
463
- // meridiem 列(值为 'am'/'pm' 字符串)的 keydown:导航同 onColKeydown,激活走 pickMeridiem。
464
- function onMeridiemKeydown(e: KeyboardEvent, mer: Meridiem) {
465
- if (e.key === 'Enter' || e.key === ' ') {
466
- e.preventDefault();
467
- pickMeridiem(mer);
468
- return;
469
- }
470
- if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp' && e.key !== 'Home' && e.key !== 'End') return;
471
- const opts = colOptions(meridiemCol);
472
- if (opts.length === 0) return;
473
- const cur = opts.findIndex((el) => el === document.activeElement);
474
- e.preventDefault();
475
- let next = cur;
476
- if (e.key === 'ArrowDown') next = cur < 0 ? 0 : (cur + 1) % opts.length;
477
- else if (e.key === 'ArrowUp') next = cur < 0 ? opts.length - 1 : (cur - 1 + opts.length) % opts.length;
478
- else if (e.key === 'Home') next = 0;
479
- else if (e.key === 'End') next = opts.length - 1;
480
- const target = opts[next];
481
- if (!target) return;
482
- for (const el of opts) el.tabIndex = el === target ? 0 : -1;
483
- target.focus();
484
- }
485
-
486
- // 打开后把焦点送进当前小时列的选中项(APG:打开浮层并聚焦当前小时列)。
487
- $effect(() => {
488
- if (!isOpen) return;
489
- void activeIndex;
490
- void tick().then(() => {
491
- const target =
492
- hourCol?.querySelector<HTMLElement>('[aria-selected="true"]') ??
493
- colOptions(hourCol)[0] ??
494
- null;
495
- target?.focus({ preventScroll });
496
- });
497
- });
498
-
499
- // 打开时重置范围编辑端为 start
500
- $effect(() => {
501
- if (isOpen) activeIndex = 0;
502
- });
503
-
504
- // 打开 / 切换编辑端时把列各自滚到选中项 (命令式,不放响应式 attachment)
505
- $effect(() => {
506
- if (!isOpen) return;
507
- void activeIndex; // 切端时重滚
508
- void tick().then(() => {
509
- scrollColToSelected(hourCol);
510
- scrollColToSelected(minuteCol);
511
- if (effShowSecond) scrollColToSelected(secondCol);
512
- });
513
- });
514
-
515
- // --- useDismiss (红线 #3): 绑定放进 $effect,open 时绑、cleanup 解绑 ---
516
- let rootEl = $state<HTMLDivElement | null>(null);
517
- let triggerEl = $state<HTMLButtonElement | null>(null);
518
-
519
- $effect(() => {
520
- if (!isOpen || !rootEl) return;
521
- return useDismiss(rootEl, {
522
- onDismiss: () => setOpen(false),
523
- escape: true,
524
- outsideClick: true,
525
- });
526
- });
527
-
528
- // autoFocus: 挂载时自动聚焦触发器
529
- $effect(() => {
530
- if (autoFocus && triggerEl) {
531
- triggerEl.focus({ preventScroll: true });
532
- }
533
- });
534
-
535
- // onClickOutSide: 监听 document mousedown,点击不在 rootEl 内时触发
536
- $effect(() => {
537
- if (!onClickOutSide) return;
538
- function handler(e: MouseEvent) {
539
- if (rootEl && !rootEl.contains(e.target as Node)) {
540
- onClickOutSide!(e);
541
- }
542
- }
543
- document.addEventListener('mousedown', handler);
544
- return () => document.removeEventListener('mousedown', handler);
545
- });
546
-
547
- function isSnippet(v: unknown): v is Snippet {
548
- return typeof v === 'function';
549
- }
550
-
551
- const inputStyleStr = $derived.by(() => {
552
- if (!inputStyle) return undefined;
553
- if (typeof inputStyle === 'string') return inputStyle;
554
- return Object.entries(inputStyle)
555
- .map(([k, v]) => `${k}:${v}`)
556
- .join(';');
557
- });
558
-
559
- const cls = $derived(
560
- [
561
- 'cd-time-picker',
562
- `cd-time-picker--${size}`,
563
- `cd-time-picker--${status}`,
564
- disabled && 'cd-time-picker--disabled',
565
- isOpen && 'cd-time-picker--open',
566
- !motion && 'cd-time-picker--no-motion',
567
- borderless && 'cd-time-picker--borderless',
568
- ]
569
- .filter(Boolean)
570
- .join(' '),
571
- );
572
- </script>
573
-
574
- <div class={cls} bind:this={rootEl} aria-invalid={status === 'error' || undefined} data-position={position}>
575
- {#if triggerRender}
576
- <!-- 自定义触发器:完全替换默认 input + 图标区域 -->
577
- <div class="cd-time-picker__control" onclick={toggleOpen} onkeydown={onTriggerKeydown} role="button" tabindex={disabled ? -1 : 0} aria-haspopup="dialog" aria-expanded={isOpen}>
578
- {@render triggerRender({ value: current, placeholder: placeholderText, open: isOpen, disabled })}
579
- </div>
580
- {:else}
581
- <div class="cd-time-picker__control">
582
- <button
583
- type="button"
584
- class="cd-time-picker__trigger"
585
- aria-haspopup="dialog"
586
- aria-expanded={isOpen}
587
- aria-controls={baseId}
588
- aria-label={ariaLabel}
589
- {disabled}
590
- readonly={inputReadOnly || undefined}
591
- style={inputStyleStr}
592
- bind:this={triggerEl}
593
- onclick={toggleOpen}
594
- onkeydown={onTriggerKeydown}
595
- onfocus={onFocus}
596
- onblur={onBlur}
597
- >
598
- {#if prefix}
599
- <span class="cd-time-picker__prefix">
600
- {#if typeof prefix === 'string'}
601
- {prefix}
602
- {:else}
603
- {@render prefix()}
604
- {/if}
605
- </span>
606
- {/if}
607
- <span class="cd-time-picker__value" class:cd-time-picker__value--placeholder={current === null}>
608
- {displayText}
609
- </span>
610
- </button>
611
-
612
- {#if showClearBtn}
613
- <button type="button" class="cd-time-picker__clear" aria-label={loc().t('TimePicker.clear')} onclick={clear}>
614
- {#if clearIcon}
615
- {@render clearIcon()}
616
- {:else}
617
- <svg viewBox="0 0 16 16" width="14" height="14" aria-hidden="true" focusable="false">
618
- <path
619
- fill="currentColor"
620
- d="M8 1a7 7 0 1 0 0 14A7 7 0 0 0 8 1Zm2.5 9.1-1.4 1.4L8 9.4 6.5 11l-1.4-1.4L6.6 8 5.1 6.5 6.5 5.1 8 6.6 9.5 5.1l1.4 1.4L9.4 8l1.1 1.1Z"
621
- />
622
- </svg>
623
- {/if}
624
- </button>
625
- {/if}
626
-
627
- <span class="cd-time-picker__icon" aria-hidden="true">
628
- <svg viewBox="0 0 16 16" width="14" height="14" focusable="false">
629
- <path
630
- fill="currentColor"
631
- d="M8 1.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13Zm0 12a5.5 5.5 0 1 1 0-11 5.5 5.5 0 0 1 0 11ZM8.5 4.5h-1v4l3 1.8.5-.85L8.5 8V4.5Z"
632
- />
633
- </svg>
634
- </span>
635
- </div>
636
- {/if}
637
-
638
- {#if isOpen}
639
- <div
640
- class="cd-time-picker__panel"
641
- id={baseId}
642
- role="dialog"
643
- aria-label={loc().t('TimePicker.triggerLabel')}
644
- tabindex="-1"
645
- >
646
- {#if panelHeader}
647
- <div class="cd-time-picker__panel-header">
648
- {#if typeof panelHeader === 'string'}
649
- {panelHeader}
650
- {:else}
651
- {@render panelHeader()}
652
- {/if}
653
- </div>
654
- {/if}
655
- {#if isRange}
656
- <div class="cd-time-picker__range-tabs" role="tablist" aria-label={loc().t('TimePicker.triggerLabel')}>
657
- <button
658
- type="button"
659
- role="tab"
660
- class="cd-time-picker__range-tab"
661
- class:cd-time-picker__range-tab--active={activeIndex === 0}
662
- aria-selected={activeIndex === 0}
663
- onclick={() => (activeIndex = 0)}
664
- >
665
- {loc().t('TimePicker.rangeStart')}
666
- <span class="cd-time-picker__range-preview">{currentPair[0] ? displayOne(currentPair[0]) : '--'}</span>
667
- </button>
668
- <button
669
- type="button"
670
- role="tab"
671
- class="cd-time-picker__range-tab"
672
- class:cd-time-picker__range-tab--active={activeIndex === 1}
673
- aria-selected={activeIndex === 1}
674
- onclick={() => (activeIndex = 1)}
675
- >
676
- {loc().t('TimePicker.rangeEnd')}
677
- <span class="cd-time-picker__range-preview">{currentPair[1] ? displayOne(currentPair[1]) : '--'}</span>
678
- </button>
679
- </div>
680
- {/if}
681
-
682
- <div class="cd-time-picker__columns">
683
- <ul class="cd-time-picker__col" role="listbox" aria-label={loc().t('TimePicker.hour')} bind:this={hourCol}>
684
- {#each hours as h, hi (h.value)}
685
- <li
686
- class="cd-time-picker__item"
687
- class:cd-time-picker__item--selected={h.value === selectedHourDisplay}
688
- class:cd-time-picker__item--disabled={h.disabled}
689
- role="option"
690
- aria-selected={h.value === selectedHourDisplay}
691
- aria-disabled={h.disabled || undefined}
692
- tabindex={h.disabled ? -1 : colItemTabindex(h.value === selectedHourDisplay, hi === 0, hourSelected)}
693
- onclick={() => !h.disabled && pickHour(h.value)}
694
- onkeydown={(e) => !h.disabled && onColKeydown(e, hourCol, pickHour, h.value)}
695
- >
696
- {pad2(h.value)}
697
- </li>
698
- {/each}
699
- </ul>
700
-
701
- <ul class="cd-time-picker__col" role="listbox" aria-label={loc().t('TimePicker.minute')} bind:this={minuteCol}>
702
- {#each minutes as m, mi (m.value)}
703
- <li
704
- class="cd-time-picker__item"
705
- class:cd-time-picker__item--selected={m.value === selectedMinute}
706
- class:cd-time-picker__item--disabled={m.disabled}
707
- role="option"
708
- aria-selected={m.value === selectedMinute}
709
- aria-disabled={m.disabled || undefined}
710
- tabindex={m.disabled ? -1 : colItemTabindex(m.value === selectedMinute, mi === 0, minuteSelected)}
711
- onclick={() => !m.disabled && pickMinute(m.value)}
712
- onkeydown={(e) => !m.disabled && onColKeydown(e, minuteCol, pickMinute, m.value)}
713
- >
714
- {pad2(m.value)}
715
- </li>
716
- {/each}
717
- </ul>
718
-
719
- {#if effShowSecond}
720
- {@const secondSelected = seconds.some((s) => s.value === selectedSecond && !s.disabled)}
721
- <ul class="cd-time-picker__col" role="listbox" aria-label={loc().t('TimePicker.second')} bind:this={secondCol}>
722
- {#each seconds as s, si (s.value)}
723
- <li
724
- class="cd-time-picker__item"
725
- class:cd-time-picker__item--selected={s.value === selectedSecond}
726
- class:cd-time-picker__item--disabled={s.disabled}
727
- role="option"
728
- aria-selected={s.value === selectedSecond}
729
- aria-disabled={s.disabled || undefined}
730
- tabindex={s.disabled ? -1 : colItemTabindex(s.value === selectedSecond, si === 0, secondSelected)}
731
- onclick={() => !s.disabled && pickSecond(s.value)}
732
- onkeydown={(e) => !s.disabled && onColKeydown(e, secondCol, pickSecond, s.value)}
733
- >
734
- {pad2(s.value)}
735
- </li>
736
- {/each}
737
- </ul>
738
- {/if}
739
-
740
- {#if effUse12Hours}
741
- <ul class="cd-time-picker__col" role="listbox" aria-label={loc().t('TimePicker.triggerLabel')} bind:this={meridiemCol}>
742
- {#each ['am', 'pm'] as const as mer, meri (mer)}
743
- <li
744
- class="cd-time-picker__item"
745
- class:cd-time-picker__item--selected={mer === selectedMeridiem}
746
- role="option"
747
- aria-selected={mer === selectedMeridiem}
748
- tabindex={colItemTabindex(mer === selectedMeridiem, meri === 0, true)}
749
- onclick={() => pickMeridiem(mer)}
750
- onkeydown={(e) => onMeridiemKeydown(e, mer)}
751
- >
752
- {loc().t(`TimePicker.${mer}`)}
753
- </li>
754
- {/each}
755
- </ul>
756
- {/if}
757
- </div>
758
-
759
- {#if panelFooter !== undefined}
760
- <div class="cd-time-picker__panel-footer-extra">
761
- {#if isSnippet(panelFooter)}{@render panelFooter()}{:else}{panelFooter}{/if}
762
- </div>
763
- {/if}
764
- <div class="cd-time-picker__footer">
765
- <button type="button" class="cd-time-picker__now" onclick={setNow}>{loc().t('TimePicker.now')}</button>
766
- <button type="button" class="cd-time-picker__ok" onclick={confirm}>{loc().t('TimePicker.confirm')}</button>
767
- </div>
768
- </div>
769
- {/if}
770
- </div>
771
-
772
- <style>
773
- .cd-time-picker {
774
- position: relative;
775
- display: inline-flex;
776
- inline-size: 100%;
777
- font-size: var(--cd-input-font-size);
778
- }
779
- .cd-time-picker__control {
780
- position: relative;
781
- inline-size: 100%;
782
- }
783
- .cd-time-picker__trigger {
784
- display: flex;
785
- align-items: center;
786
- gap: var(--cd-spacing-2);
787
- inline-size: 100%;
788
- block-size: var(--cd-input-height-default);
789
- padding-inline-start: var(--cd-input-padding-x);
790
- padding-inline-end: calc(var(--cd-input-padding-x) + 1.25rem);
791
- background: var(--cd-input-color-bg);
792
- color: var(--cd-input-color-text);
793
- border: 1px solid var(--cd-input-border);
794
- border-radius: var(--cd-input-radius);
795
- font: inherit;
796
- text-align: start;
797
- cursor: pointer;
798
- transition: border-color var(--cd-motion-duration-fast) var(--cd-motion-ease-standard);
799
- }
800
- .cd-time-picker--small .cd-time-picker__trigger {
801
- block-size: var(--cd-input-height-small);
802
- font-size: var(--cd-font-size-1);
803
- }
804
- .cd-time-picker--large .cd-time-picker__trigger {
805
- block-size: var(--cd-input-height-large);
806
- font-size: var(--cd-font-size-3);
807
- }
808
- .cd-time-picker__trigger:focus-visible {
809
- outline: none;
810
- border-color: var(--cd-input-border-active);
811
- box-shadow: var(--cd-focus-ring);
812
- }
813
- .cd-time-picker--open .cd-time-picker__trigger {
814
- border-color: var(--cd-input-border-active);
815
- }
816
- .cd-time-picker--warning .cd-time-picker__trigger {
817
- border-color: var(--cd-input-border-warning);
818
- }
819
- .cd-time-picker--error .cd-time-picker__trigger {
820
- border-color: var(--cd-input-border-error);
821
- }
822
- .cd-time-picker--disabled .cd-time-picker__trigger {
823
- background: var(--cd-color-fill-0);
824
- color: var(--cd-color-text-3);
825
- cursor: not-allowed;
826
- }
827
- /* 无边框模式 */
828
- .cd-time-picker--borderless .cd-time-picker__trigger {
829
- border-color: transparent;
830
- background: transparent;
831
- }
832
- .cd-time-picker--borderless .cd-time-picker__trigger:focus-visible {
833
- border-color: var(--cd-input-border-active);
834
- background: var(--cd-input-color-bg);
835
- }
836
- .cd-time-picker__value {
837
- flex: 1 1 auto;
838
- overflow: hidden;
839
- white-space: nowrap;
840
- text-overflow: ellipsis;
841
- }
842
- .cd-time-picker__value--placeholder {
843
- color: var(--cd-input-color-placeholder);
844
- }
845
- .cd-time-picker__clear,
846
- .cd-time-picker__icon {
847
- position: absolute;
848
- inset-block-start: 50%;
849
- inset-inline-end: var(--cd-input-padding-x);
850
- transform: translateY(-50%);
851
- display: inline-flex;
852
- align-items: center;
853
- justify-content: center;
854
- color: var(--cd-color-text-2);
855
- pointer-events: none;
856
- }
857
- .cd-time-picker__clear {
858
- padding: 0;
859
- border: none;
860
- background: var(--cd-input-color-bg);
861
- cursor: pointer;
862
- opacity: 0;
863
- pointer-events: auto;
864
- transition: opacity var(--cd-motion-duration-fast) var(--cd-motion-ease-standard);
865
- }
866
- .cd-time-picker__control:hover .cd-time-picker__clear,
867
- .cd-time-picker__clear:focus-visible {
868
- opacity: 1;
869
- }
870
- .cd-time-picker__clear:focus-visible {
871
- outline: none;
872
- box-shadow: var(--cd-focus-ring);
873
- border-radius: var(--cd-radius-1);
874
- }
875
- .cd-time-picker__clear:hover {
876
- color: var(--cd-color-text-0);
877
- }
878
- .cd-time-picker__panel {
879
- position: absolute;
880
- inset-block-start: calc(100% + var(--cd-spacing-1));
881
- inset-inline-start: 0;
882
- z-index: var(--cd-date-picker-panel-z);
883
- background: var(--cd-date-picker-panel-bg);
884
- border-radius: var(--cd-date-picker-panel-radius);
885
- box-shadow: var(--cd-date-picker-panel-shadow);
886
- }
887
- .cd-time-picker__panel:focus-visible {
888
- outline: none;
889
- }
890
- .cd-time-picker__panel-header {
891
- padding: var(--cd-spacing-2) var(--cd-spacing-2);
892
- border-block-end: 1px solid var(--cd-color-border);
893
- color: var(--cd-color-text-0);
894
- font-size: var(--cd-font-size-1);
895
- }
896
- .cd-time-picker__prefix {
897
- flex: 0 0 auto;
898
- color: var(--cd-color-text-2);
899
- }
900
- .cd-time-picker--no-motion .cd-time-picker__panel {
901
- transition: none;
902
- }
903
- .cd-time-picker__range-tabs {
904
- display: flex;
905
- border-block-end: 1px solid var(--cd-color-border);
906
- }
907
- .cd-time-picker__range-tab {
908
- flex: 1 1 0;
909
- display: flex;
910
- flex-direction: column;
911
- align-items: flex-start;
912
- gap: 2px;
913
- border: none;
914
- background: transparent;
915
- font: inherit;
916
- cursor: pointer;
917
- padding: var(--cd-spacing-2);
918
- color: var(--cd-color-text-2);
919
- border-block-end: 2px solid transparent;
920
- }
921
- .cd-time-picker__range-tab--active {
922
- color: var(--cd-color-primary);
923
- border-block-end-color: var(--cd-color-primary);
924
- }
925
- .cd-time-picker__range-tab:focus-visible {
926
- outline: none;
927
- box-shadow: var(--cd-focus-ring);
928
- }
929
- .cd-time-picker__range-preview {
930
- font-size: var(--cd-font-size-1);
931
- color: var(--cd-color-text-0);
932
- font-variant-numeric: tabular-nums;
933
- }
934
- .cd-time-picker__columns {
935
- display: flex;
936
- }
937
- .cd-time-picker__col {
938
- inline-size: var(--cd-time-picker-time-col-width);
939
- block-size: calc(var(--cd-time-picker-time-item-height) * 7);
940
- margin: 0;
941
- padding: 0;
942
- overflow-y: auto;
943
- list-style: none;
944
- scrollbar-width: thin;
945
- }
946
- .cd-time-picker__col + .cd-time-picker__col {
947
- border-inline-start: 1px solid var(--cd-color-border);
948
- }
949
- .cd-time-picker__item {
950
- display: flex;
951
- align-items: center;
952
- justify-content: center;
953
- block-size: var(--cd-time-picker-time-item-height);
954
- color: var(--cd-color-text-0);
955
- cursor: pointer;
956
- transition: background var(--cd-motion-duration-fast) var(--cd-motion-ease-standard);
957
- }
958
- .cd-time-picker__item:hover {
959
- background: var(--cd-date-picker-cell-bg-hover);
960
- }
961
- .cd-time-picker__item:focus-visible {
962
- outline: none;
963
- box-shadow: var(--cd-focus-ring);
964
- }
965
- .cd-time-picker__item--selected,
966
- .cd-time-picker__item--selected:hover {
967
- background: var(--cd-date-picker-cell-bg-selected);
968
- color: var(--cd-date-picker-cell-color-selected);
969
- }
970
- .cd-time-picker__item--disabled,
971
- .cd-time-picker__item--disabled:hover {
972
- color: var(--cd-color-text-3);
973
- background: transparent;
974
- cursor: not-allowed;
975
- }
976
- .cd-time-picker__panel-footer-extra {
977
- padding: var(--cd-spacing-2);
978
- border-block-start: 1px solid var(--cd-color-border);
979
- }
980
- .cd-time-picker__footer {
981
- display: flex;
982
- align-items: center;
983
- justify-content: space-between;
984
- gap: var(--cd-spacing-2);
985
- padding: var(--cd-spacing-2);
986
- border-block-start: 1px solid var(--cd-color-border);
987
- }
988
- .cd-time-picker__now,
989
- .cd-time-picker__ok {
990
- border: none;
991
- background: transparent;
992
- font: inherit;
993
- cursor: pointer;
994
- border-radius: var(--cd-radius-1);
995
- padding-inline: var(--cd-spacing-2);
996
- padding-block: var(--cd-spacing-1);
997
- }
998
- .cd-time-picker__now {
999
- color: var(--cd-color-primary);
1000
- }
1001
- .cd-time-picker__now:hover {
1002
- text-decoration: underline;
1003
- }
1004
- .cd-time-picker__ok {
1005
- color: var(--cd-color-white, #fff);
1006
- background: var(--cd-color-primary);
1007
- }
1008
- .cd-time-picker__ok:hover {
1009
- background: var(--cd-color-primary-hover, var(--cd-color-primary));
1010
- }
1011
- .cd-time-picker__now:focus-visible,
1012
- .cd-time-picker__ok:focus-visible {
1013
- outline: none;
1014
- box-shadow: var(--cd-focus-ring);
1015
- }
1016
- @media (prefers-reduced-motion: reduce) {
1017
- .cd-time-picker__trigger,
1018
- .cd-time-picker__clear,
1019
- .cd-time-picker__item {
1020
- transition: none;
1021
- }
1022
- }
1023
- </style>