@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,1344 +0,0 @@
1
- <!--
2
- Calendar — see specs/components/show/Calendar.spec.md
3
- 月/周/日视图日历:日格网格 + 事件展示与 +N 折叠,today/selected/outside/weekend/disabled 态。
4
- mode='month'(6×7) | 'week'(1×7) | 'day'(单日时间轴,纵向小时段);selectionMode='single'(选中日) | 'range'(范围选择,起止+区间高亮+hover 预览)。
5
- day 模式:dayStartHour~dayEndHour 逐小时一行,带时间事件按起始小时入对应时段、全天/跨天延续事件入顶部「全天」区(纯派生 timelineForDay,纯 CSS 布局)。
6
- 受控 value(锚点)/selectedDate/rangeValue 不回写,仅 onChange/onSelect/onRangeChange/onDateClick/onMoreClick 通知。
7
- 复用 @chenzy-design/core 的纯日期/分组算法(getMonthGrid/getWeekGrid/getDayHours/addMonths/addWeeks/addDays/timelineForDay/gridFocusMove…),不重复实现。
8
- roving 键盘焦点:网格内仅活动格 tabindex=0,方向键(←→天/↑↓周/PageUp-Down月/Home-End周首末)移动焦点,跨月/周自动翻页并落焦,Enter/Space 选中(纯 gridFocusMove 派生 + 命令式 focus)。
9
- popup 弹层模式:渲染 trigger,日历门户浮出(复用 _floating),外部点击/Esc 关闭(useDismiss)并归还焦点。
10
- 虚拟化:day 视图小时时间轴按阈值用 core fixedRange 视口渲染(滚动监听命令式 + cleanup,红线 #3)。
11
- -->
12
- <script lang="ts">
13
- import { untrack, tick, type Snippet } from 'svelte';
14
- import {
15
- getMonthGrid,
16
- getWeekGrid,
17
- getDayHours,
18
- weekdayOrder,
19
- isSameDay,
20
- startOfDay,
21
- addMonths,
22
- addWeeks,
23
- addDays,
24
- groupEventsByDays,
25
- timelineForDay,
26
- dayKey,
27
- isPastDay,
28
- gridFocusMove,
29
- fixedRange,
30
- useDismiss,
31
- useLiveAnnouncer,
32
- type GridFocusKey,
33
- type CalendarEvent,
34
- type Placement,
35
- } from '@chenzy-design/core';
36
- import { floating } from '../_floating/use-floating.js';
37
- import { useLocale } from '../locale-provider/index.js';
38
-
39
- type WeekStart = 0 | 1 | 2 | 3 | 4 | 5 | 6;
40
- type Mode = 'month' | 'week' | 'day';
41
- type SelectionMode = 'single' | 'range';
42
- type RangeValue = [Date, Date];
43
-
44
- interface Props {
45
- value?: Date;
46
- defaultValue?: Date;
47
- mode?: Mode;
48
- selectionMode?: SelectionMode;
49
- events?: CalendarEvent[];
50
- weekStartsOn?: WeekStart;
51
- maxEventsPerDay?: number;
52
- dayStartHour?: number;
53
- dayEndHour?: number;
54
- weekendDays?: number[];
55
- markWeekend?: boolean;
56
- disabledDate?: (date: Date) => boolean;
57
- selectedDate?: Date;
58
- defaultSelectedDate?: Date;
59
- rangeValue?: RangeValue | null;
60
- defaultRangeValue?: RangeValue | null;
61
- locale?: string;
62
- onChange?: (info: { value: Date }) => void;
63
- onSelect?: (info: { date: Date }) => void;
64
- onRangeChange?: (info: { range: RangeValue }) => void;
65
- onDateClick?: (info: { date: Date }) => void;
66
- onMoreClick?: (info: { date: Date; events: CalendarEvent[] }) => void;
67
- /** 点击/键盘激活事件块(spec §a11y:事件块 role=button + Enter/Space 触发)。 */
68
- onEventClick?: (info: { event: CalendarEvent; nativeEvent: Event }) => void;
69
- /** 关闭回调(popup 模式) */
70
- onClose?: () => void;
71
- dateCell?: Snippet<
72
- [{ date: Date; events: CalendarEvent[]; isToday: boolean; isOutside: boolean; disabled: boolean }]
73
- >;
74
- event?: Snippet<[{ event: CalendarEvent }]>;
75
- /** 自定义头部内容,替换默认头部 */
76
- header?: Snippet;
77
- /** 自定义单元格额外内容 (dateString: 'YYYY-MM-DD', date: Date) */
78
- dateGridRender?: (dateString: string, date: Date) => Snippet | null | undefined;
79
- /** 自定义全天事件区域渲染 */
80
- allDayEventsRender?: (events: CalendarEvent[]) => Snippet | null | undefined;
81
- /** 自定义时间文案 (hour: 0-23) */
82
- renderTimeDisplay?: (hour: number) => string;
83
- /** 自定义日期文案 */
84
- renderDateDisplay?: (date: Date) => string;
85
- /** 是否显示当前时间红线(day/week 视图,默认 true) */
86
- showCurrTime?: boolean;
87
- /** day/week 视图默认滚动高度(px,默认 400) */
88
- scrollTop?: number;
89
- /** 事件块最小高度(px) */
90
- minEventHeight?: number;
91
- /** 日历整体宽度 */
92
- width?: number | string;
93
- /** 日历整体高度 */
94
- height?: number | string;
95
- /** 范围选择的日期区间(mode='range' 时用于初始化,同 rangeValue) */
96
- range?: [Date, Date] | null;
97
- /** 受控展示锚点(Semi API: displayValue,等同于 value) */
98
- displayValue?: Date;
99
- ariaLabel?: string;
100
- // --- 弹层模式 (popup) ---
101
- /** 弹层模式:渲染 trigger,日历作为浮层弹出(复用 _floating 门户定位) */
102
- popup?: boolean;
103
- /** 受控展开态(popup 模式),受控时不回写仅 onOpenChange (红线 #1) */
104
- open?: boolean;
105
- /** 非受控初始展开态 */
106
- defaultOpen?: boolean;
107
- /** 展开态变化回调 */
108
- onOpenChange?: (info: { open: boolean }) => void;
109
- /** 浮层相对 trigger 的位置 */
110
- placement?: Placement;
111
- /** 浮层门户挂载容器(默认 document.body) */
112
- getContainer?: () => HTMLElement | null | undefined;
113
- /** trigger 自定义内容(popup 模式);不传则渲染默认按钮显示标题 */
114
- trigger?: Snippet<[{ open: boolean; toggle: () => void }]>;
115
- // --- 虚拟化 (day 视图时间轴) ---
116
- /**
117
- * day 视图小时时间轴虚拟化:当行数 ≥ virtualizeThreshold 时仅渲染视口行。
118
- * 'auto'(默认)按阈值自动;true 强制;false 关闭。
119
- */
120
- virtualizeDay?: boolean | 'auto';
121
- /** 触发虚拟化的最少行数(virtualizeDay='auto' 时生效) */
122
- virtualizeThreshold?: number;
123
- /** day 视图时间轴视口高度(px,虚拟化时滚动容器高度) */
124
- timelineViewportHeight?: number;
125
- }
126
-
127
- let {
128
- value,
129
- defaultValue,
130
- displayValue,
131
- mode = 'month',
132
- selectionMode = 'single',
133
- events = [],
134
- weekStartsOn = 0,
135
- maxEventsPerDay = 3,
136
- dayStartHour = 0,
137
- dayEndHour = 23,
138
- weekendDays = [0, 6],
139
- markWeekend = true,
140
- disabledDate,
141
- selectedDate,
142
- defaultSelectedDate,
143
- rangeValue,
144
- defaultRangeValue,
145
- range,
146
- locale = 'zh-CN',
147
- onChange,
148
- onSelect,
149
- onRangeChange,
150
- onDateClick,
151
- onMoreClick,
152
- onEventClick,
153
- onClose,
154
- dateCell,
155
- event,
156
- header,
157
- dateGridRender,
158
- allDayEventsRender,
159
- renderTimeDisplay,
160
- renderDateDisplay,
161
- showCurrTime = true,
162
- scrollTop = 400,
163
- minEventHeight,
164
- width,
165
- height,
166
- ariaLabel,
167
- popup = false,
168
- open,
169
- defaultOpen = false,
170
- onOpenChange,
171
- placement = 'bottomStart',
172
- getContainer,
173
- trigger,
174
- virtualizeDay = 'auto',
175
- virtualizeThreshold = 18,
176
- timelineViewportHeight = 360,
177
- }: Props = $props();
178
-
179
- // displayValue 作为 value 的别名(Semi API),优先级低于 value
180
- const resolvedValue = $derived(value ?? displayValue);
181
-
182
- // range 作为 rangeValue 的别名(Semi API),优先级低于 rangeValue
183
- const resolvedRangeValue = $derived(rangeValue ?? range);
184
-
185
- const loc = useLocale();
186
- // 单例 live region(polite):切月/年、移动焦点、选中日期时播报可读文本(红线 #3:命令式)。
187
- const announcer = useLiveAnnouncer();
188
-
189
- // 一次性常量:今天(render 用于派生 today/past 态,不放 $state 反复 new)
190
- const today = new Date();
191
-
192
- // --- 锚点 value:受控不回写 (红线 #1) ---
193
- // resolvedValue = value ?? displayValue(displayValue 是 Semi API 的别名)
194
- function initValue(): Date {
195
- return defaultValue ?? new Date();
196
- }
197
- const isValueControlled = $derived(resolvedValue !== undefined);
198
- let innerValue = $state<Date>(initValue());
199
- const currentValue = $derived(isValueControlled ? (resolvedValue as Date) : innerValue);
200
-
201
- // --- 选中日 selectedDate:受控不回写 (红线 #1) ---
202
- function initSelected(): Date | null {
203
- return defaultSelectedDate ?? null;
204
- }
205
- const isSelectedControlled = $derived(selectedDate !== undefined);
206
- let innerSelected = $state<Date | null>(initSelected());
207
- const currentSelected = $derived(
208
- isSelectedControlled ? (selectedDate as Date) : innerSelected,
209
- );
210
-
211
- // --- 选中范围 rangeValue:受控不回写 (红线 #1) ---
212
- function normRange(r: RangeValue | null | undefined): RangeValue | null {
213
- if (!r) return null;
214
- const a = startOfDay(r[0]);
215
- const b = startOfDay(r[1]);
216
- return a.getTime() <= b.getTime() ? [a, b] : [b, a];
217
- }
218
- // resolvedRangeValue = rangeValue ?? range(range 是 Semi API 的别名)
219
- const isRangeControlled = $derived(resolvedRangeValue !== undefined);
220
- let innerRange = $state<RangeValue | null>(untrack(() => normRange(defaultRangeValue)));
221
- const currentRange = $derived(
222
- isRangeControlled ? normRange(resolvedRangeValue) : innerRange,
223
- );
224
-
225
- // --- range 选择状态机:'start'=待选起点;'end'=已选起点待选终点 ---
226
- let phase = $state<'start' | 'end'>('start');
227
- let pendingStart = $state<Date | null>(null);
228
- let previewEnd = $state<Date | null>(null);
229
-
230
- // --- 弹层展开态:受控不回写仅 onOpenChange (红线 #1) ---
231
- const isOpenControlled = $derived(open !== undefined);
232
- let innerOpen = $state(untrack(() => defaultOpen));
233
- const isOpen = $derived(isOpenControlled ? (open as boolean) : innerOpen);
234
- function setOpen(next: boolean) {
235
- if (next === isOpen) return;
236
- if (!isOpenControlled) innerOpen = next;
237
- onOpenChange?.({ open: next });
238
- }
239
- function toggleOpen() {
240
- setOpen(!isOpen);
241
- }
242
-
243
- // --- roving 焦点:被聚焦的日期(纯 $state,网格只有一个 tabindex=0 的格) ---
244
- // 初值跟随锚点;用户方向键移动时更新,跨月/周则锚点随动重渲染网格。
245
- let focusedDate = $state<Date | null>(null);
246
- // 标记下一次重渲染后需把 DOM 焦点落到 focusedDate 对应的格上
247
- let pendingFocus = $state(false);
248
-
249
- let rootEl = $state<HTMLElement | null>(null);
250
- let triggerEl = $state<HTMLElement | null>(null);
251
- let panelEl = $state<HTMLElement | null>(null);
252
-
253
- // --- 网格与分组:全部从 props/本地 $state 派生 (红线 #2) ---
254
- // day 模式不需要日格网格;给出空数组避免下游再分支
255
- const cells = $derived(
256
- mode === 'day'
257
- ? []
258
- : mode === 'week'
259
- ? getWeekGrid(currentValue, weekStartsOn)
260
- : getMonthGrid(currentValue, weekStartsOn),
261
- );
262
- const weeks = $derived(
263
- mode === 'week'
264
- ? [cells]
265
- : mode === 'day'
266
- ? []
267
- : Array.from({ length: 6 }, (_, i) => cells.slice(i * 7, (i + 1) * 7)),
268
- );
269
- const dayMap = $derived(
270
- groupEventsByDays(
271
- events,
272
- cells.map((c) => c.date),
273
- maxEventsPerDay,
274
- ),
275
- );
276
-
277
- // --- day 视图:单日时间轴(纯派生,红线 #2/#3) ---
278
- const hourSlots = $derived(
279
- mode === 'day' ? getDayHours(currentValue, dayStartHour, dayEndHour) : [],
280
- );
281
- const dayTimeline = $derived(
282
- mode === 'day'
283
- ? timelineForDay(events, currentValue, dayStartHour, dayEndHour)
284
- : { allDay: [], byHour: new Map<number, CalendarEvent[]>() },
285
- );
286
-
287
- // --- day 时间轴虚拟化(复用 core fixedRange,红线 #2 派生 / #3 滚动监听命令式)---
288
- const ROW_H = 40; // 与 --cd-calendar-hour-min-h 默认值对齐(固定行高视口渲染)
289
- const useVirtual = $derived(
290
- mode === 'day' &&
291
- (virtualizeDay === true ||
292
- (virtualizeDay === 'auto' && hourSlots.length >= virtualizeThreshold)),
293
- );
294
- let timelineScrollTop = $state(0);
295
- // 视口可见行区间(含 overscan),仅虚拟化时计算
296
- const visibleRange = $derived(
297
- useVirtual
298
- ? fixedRange(timelineScrollTop, timelineViewportHeight, ROW_H, hourSlots.length, 3)
299
- : { startIndex: 0, endIndex: hourSlots.length },
300
- );
301
- const visibleSlots = $derived(
302
- useVirtual ? hourSlots.slice(visibleRange.startIndex, visibleRange.endIndex) : hourSlots,
303
- );
304
- // 上/下空白撑高,保证滚动条与 hour 行绝对位置正确
305
- const padTop = $derived(useVirtual ? visibleRange.startIndex * ROW_H : 0);
306
- const totalHeight = $derived(useVirtual ? hourSlots.length * ROW_H : 0);
307
-
308
- // 命令式滚动监听 + cleanup(红线 #3):只在虚拟化时绑定
309
- let timelineEl = $state<HTMLElement | null>(null);
310
-
311
- // scrollTop:day 视图初始滚动位置(命令式,红线 #3)
312
- $effect(() => {
313
- if (mode !== 'day' || !timelineEl) return;
314
- // 使用 untrack 避免把 scrollTop prop 加入 effect 依赖,只在 timelineEl mount 时执行一次
315
- const top = scrollTop;
316
- timelineEl.scrollTop = top;
317
- });
318
-
319
- // showCurrTime:当前时间红线,每分钟更新一次(命令式定时器,红线 #3)
320
- let currTimePercent = $state<number | null>(null);
321
- $effect(() => {
322
- if (mode !== 'day' || !showCurrTime) {
323
- currTimePercent = null;
324
- return;
325
- }
326
- const compute = () => {
327
- const now = new Date();
328
- const h = now.getHours();
329
- const m = now.getMinutes();
330
- const totalHours = dayEndHour - dayStartHour + 1;
331
- if (h < dayStartHour || h > dayEndHour) {
332
- currTimePercent = null;
333
- return;
334
- }
335
- currTimePercent = ((h - dayStartHour + m / 60) / totalHours) * 100;
336
- };
337
- compute();
338
- // 剩余秒数到下一分钟
339
- const now = new Date();
340
- const msToNextMin = (60 - now.getSeconds()) * 1000 - now.getMilliseconds();
341
- let timer: ReturnType<typeof setTimeout>;
342
- let interval: ReturnType<typeof setInterval>;
343
- timer = setTimeout(() => {
344
- compute();
345
- interval = setInterval(compute, 60_000);
346
- }, msToNextMin);
347
- return () => {
348
- clearTimeout(timer);
349
- clearInterval(interval);
350
- };
351
- });
352
- $effect(() => {
353
- if (!useVirtual || !timelineEl) return;
354
- const el = timelineEl;
355
- let frame = 0;
356
- const onScroll = () => {
357
- if (frame) return;
358
- frame = requestAnimationFrame(() => {
359
- frame = 0;
360
- timelineScrollTop = el.scrollTop;
361
- });
362
- };
363
- el.addEventListener('scroll', onScroll, { passive: true });
364
- timelineScrollTop = el.scrollTop;
365
- return () => {
366
- if (frame) cancelAnimationFrame(frame);
367
- el.removeEventListener('scroll', onScroll);
368
- };
369
- });
370
-
371
- // --- Intl 格式化 ---
372
- const titleFormatter = $derived(
373
- new Intl.DateTimeFormat(locale, { year: 'numeric', month: 'long' }),
374
- );
375
- const weekdayFormatter = $derived(new Intl.DateTimeFormat(locale, { weekday: 'short' }));
376
- // week 模式标题:本周首日 ~ 末日(同月则只展示一次月份)
377
- const rangeTitleFormatter = $derived(
378
- new Intl.DateTimeFormat(locale, { year: 'numeric', month: 'long', day: 'numeric' }),
379
- );
380
- const dayTitleFormatter = $derived(new Intl.DateTimeFormat(locale, { day: 'numeric' }));
381
- const weekTitle = $derived.by(() => {
382
- const first = cells[0]?.date;
383
- const last = cells[cells.length - 1]?.date;
384
- if (!first || !last) return '';
385
- const startText = rangeTitleFormatter.format(first);
386
- const endText =
387
- first.getMonth() === last.getMonth() && first.getFullYear() === last.getFullYear()
388
- ? dayTitleFormatter.format(last)
389
- : rangeTitleFormatter.format(last);
390
- return `${startText} – ${endText}`;
391
- });
392
- // day 模式标题:完整日期(含星期)
393
- const dayTitleFullFormatter = $derived(
394
- new Intl.DateTimeFormat(locale, {
395
- year: 'numeric',
396
- month: 'long',
397
- day: 'numeric',
398
- weekday: 'long',
399
- }),
400
- );
401
- // 时间轴每行的小时标签(如 09:00)
402
- const hourLabelFormatter = $derived(
403
- new Intl.DateTimeFormat(locale, { hour: '2-digit', minute: '2-digit', hour12: false }),
404
- );
405
- const title = $derived(
406
- mode === 'week'
407
- ? weekTitle
408
- : mode === 'day'
409
- ? dayTitleFullFormatter.format(currentValue)
410
- : titleFormatter.format(currentValue),
411
- );
412
-
413
- // 星期表头:用首周 7 格的 date 生成名称(顺序与 weekStartsOn 一致)
414
- const weekdayOrderList = $derived(weekdayOrder(weekStartsOn));
415
- const weekdayNames = $derived(
416
- cells.slice(0, 7).map((c) => weekdayFormatter.format(c.date)),
417
- );
418
-
419
- // --- roving 焦点目标(纯派生,红线 #2)---
420
- // 网格里唯一获得 tabindex=0 的「活动格」:优先用户已聚焦日期,否则选中日/今天/锚点。
421
- // 若 focusedDate 不在当前网格(跨月翻页后),仍以 focusedDate 为准——它就是要落焦的格。
422
- const activeDate = $derived.by<Date>(() => {
423
- if (focusedDate) return focusedDate;
424
- if (selectionMode === 'single' && currentSelected) return currentSelected;
425
- const inGridToday = cells.some((c) => isSameDay(c.date, today));
426
- if (inGridToday) return today;
427
- // 月视图回退到当月 1 号所在的格,周/日回退到锚点
428
- return mode === 'month' ? startOfDay(new Date(currentValue.getFullYear(), currentValue.getMonth(), 1)) : currentValue;
429
- });
430
- function isActiveCell(date: Date): boolean {
431
- return isSameDay(date, activeDate);
432
- }
433
-
434
- // --- 状态写入:仅非受控写 inner,受控只回调 (红线 #1) ---
435
- function setAnchor(next: Date) {
436
- if (!isValueControlled) innerValue = next;
437
- onChange?.({ value: next });
438
- }
439
-
440
- function step(delta: number): Date {
441
- if (mode === 'day') return addDays(currentValue, delta);
442
- if (mode === 'week') return addWeeks(currentValue, delta);
443
- return addMonths(currentValue, delta);
444
- }
445
- // 切月/年/今日:把焦点带到新锚点并 polite 播报其可读全文(formatter 仅依赖 locale,可安全用于任意日期)。
446
- function announceFocusDate(date: Date) {
447
- announcer.announce(dayTitleFullFormatter.format(date));
448
- }
449
- function goPrev() {
450
- const next = step(-1);
451
- setAnchor(next);
452
- announceFocusDate(next);
453
- }
454
- function goNext() {
455
- const next = step(1);
456
- setAnchor(next);
457
- announceFocusDate(next);
458
- }
459
- function goToday() {
460
- const next = new Date();
461
- setAnchor(next);
462
- announceFocusDate(next);
463
- }
464
-
465
- function setSelected(date: Date) {
466
- if (!isSelectedControlled) innerSelected = date;
467
- onSelect?.({ date });
468
- // 选中日期 polite 播报可读全文。
469
- announcer.announce(
470
- loc().t('Calendar.selectedDateAnnounce', { date: dayTitleFullFormatter.format(date) }),
471
- );
472
- }
473
-
474
- function setRange(next: RangeValue) {
475
- if (!isRangeControlled) innerRange = next;
476
- onRangeChange?.({ range: next });
477
- }
478
-
479
- function isDisabled(date: Date): boolean {
480
- return disabledDate?.(date) ?? false;
481
- }
482
-
483
- // range 选择:点第一天设起、第二天设止(排序后提交)
484
- function onRangeActivate(date: Date) {
485
- const day = startOfDay(date);
486
- if (phase === 'start') {
487
- pendingStart = day;
488
- previewEnd = day;
489
- phase = 'end';
490
- return;
491
- }
492
- const a = pendingStart ?? day;
493
- const next: RangeValue =
494
- a.getTime() <= day.getTime() ? [a, day] : [day, a];
495
- setRange(next);
496
- phase = 'start';
497
- pendingStart = null;
498
- previewEnd = null;
499
- }
500
-
501
- function onCellActivate(date: Date) {
502
- if (isDisabled(date)) return;
503
- onDateClick?.({ date });
504
- if (selectionMode === 'range') {
505
- onRangeActivate(date);
506
- } else {
507
- setSelected(date);
508
- }
509
- }
510
-
511
- function onCellHover(date: Date) {
512
- if (selectionMode === 'range' && phase === 'end' && !isDisabled(date)) {
513
- previewEnd = startOfDay(date);
514
- }
515
- }
516
-
517
- const NAV_KEYS = new Set<string>([
518
- 'ArrowLeft',
519
- 'ArrowRight',
520
- 'ArrowUp',
521
- 'ArrowDown',
522
- 'PageUp',
523
- 'PageDown',
524
- 'Home',
525
- 'End',
526
- ]);
527
-
528
- // 将 DOM 焦点落到 activeDate 对应的格(重渲染后调用,命令式 + 无监听需 cleanup)
529
- async function focusActiveCell() {
530
- await tick();
531
- const host = rootEl ?? panelEl;
532
- if (!host) return;
533
- const el = host.querySelector<HTMLElement>('.cd-calendar__cell--active');
534
- el?.focus();
535
- }
536
-
537
- // 网格级 roving 键盘导航(WAI-ARIA grid 模式,红线 #2 派生用纯 gridFocusMove)
538
- function onGridKeydown(e: KeyboardEvent) {
539
- const key = e.key;
540
- if (key === 'Enter' || key === ' ') {
541
- e.preventDefault();
542
- onCellActivate(activeDate);
543
- return;
544
- }
545
- // Shift+PageUp/Down:切年(gridFocusMove 不含年级,组件层 ±12 月)
546
- if (e.shiftKey && (key === 'PageUp' || key === 'PageDown')) {
547
- e.preventDefault();
548
- const nextYearDate = addMonths(activeDate, key === 'PageUp' ? -12 : 12);
549
- focusedDate = nextYearDate;
550
- const stillVisible = cells.some((c) => isSameDay(c.date, nextYearDate));
551
- if (!stillVisible) setAnchor(nextYearDate);
552
- pendingFocus = true;
553
- announceFocusDate(nextYearDate);
554
- return;
555
- }
556
- if (!NAV_KEYS.has(key)) return;
557
- e.preventDefault();
558
- const next = gridFocusMove(
559
- activeDate,
560
- key as GridFocusKey,
561
- mode === 'week' ? 'week' : 'month',
562
- weekStartsOn,
563
- );
564
- if (!next) return;
565
- focusedDate = next;
566
- // 跨出当前展示月/周:锚点随动,触发网格重渲染(受控锚点只回调,红线 #1)
567
- const stillVisible = cells.some((c) => isSameDay(c.date, next));
568
- if (!stillVisible) setAnchor(next);
569
- pendingFocus = true;
570
- announceFocusDate(next);
571
- }
572
-
573
- // 焦点落格:activeDate / 网格内容变化后,若有待定焦点则把 DOM 焦点移到活动格
574
- $effect(() => {
575
- // 依赖 activeDate + cells 确保翻页重渲染后再落焦
576
- void activeDate;
577
- void cells;
578
- if (pendingFocus) {
579
- pendingFocus = false;
580
- void focusActiveCell();
581
- }
582
- });
583
-
584
- // --- range 区间端点 / 区间内判定(纯派生,红线 #2) ---
585
- const rangeStart = $derived(phase === 'end' ? pendingStart : (currentRange?.[0] ?? null));
586
- const rangeEnd = $derived(phase === 'end' ? previewEnd : (currentRange?.[1] ?? null));
587
- const span = $derived.by<[number, number] | null>(() => {
588
- if (!rangeStart || !rangeEnd) return null;
589
- const ta = rangeStart.getTime();
590
- const tb = rangeEnd.getTime();
591
- return ta <= tb ? [ta, tb] : [tb, ta];
592
- });
593
-
594
- function isRangeEdge(date: Date): boolean {
595
- if (selectionMode !== 'range') return false;
596
- return isSameDay(date, rangeStart) || isSameDay(date, rangeEnd);
597
- }
598
- function isInRange(date: Date): boolean {
599
- if (selectionMode !== 'range' || !span) return false;
600
- const t = startOfDay(date).getTime();
601
- return t > span[0] && t < span[1];
602
- }
603
-
604
- function onMore(date: Date, total: CalendarEvent[]) {
605
- onMoreClick?.({ date, events: total });
606
- }
607
-
608
- // 事件块激活(点击或 Enter/Space)。阻止冒泡避免连带触发日格选择。
609
- function activateEvent(ev: CalendarEvent, e: Event) {
610
- e.stopPropagation();
611
- if (ev.disabled) return;
612
- onEventClick?.({ event: ev, nativeEvent: e });
613
- }
614
- function onEventKeydown(ev: CalendarEvent, e: KeyboardEvent) {
615
- if (e.key === 'Enter' || e.key === ' ') {
616
- e.preventDefault();
617
- activateEvent(ev, e);
618
- }
619
- }
620
-
621
- // --- popup 外部点击 / Esc 关闭(红线 #3:open 时绑、cleanup 解绑)---
622
- $effect(() => {
623
- if (!popup || !isOpen || !triggerEl) return;
624
- return useDismiss(triggerEl, {
625
- onDismiss: (reason) => {
626
- setOpen(false);
627
- onClose?.();
628
- // 仅 Esc 归还焦点到 trigger(外部点击焦点应留在点击处)
629
- if (reason === 'esc') {
630
- const btn = triggerEl?.querySelector<HTMLElement>(
631
- '.cd-calendar-popup__trigger, [data-calendar-trigger]',
632
- );
633
- (btn ?? triggerEl)?.focus();
634
- }
635
- },
636
- escape: true,
637
- outsideClick: true,
638
- // 浮层门户到 body,点击浮层内部不算外部
639
- extraTargets: [panelEl],
640
- });
641
- });
642
-
643
- // popup 打开后把焦点落到活动格,关闭后归还 trigger(命令式)
644
- $effect(() => {
645
- if (!popup) return;
646
- if (isOpen) {
647
- pendingFocus = true;
648
- void focusActiveCell();
649
- }
650
- });
651
-
652
- function dayNumber(date: Date): number {
653
- return date.getDate();
654
- }
655
-
656
- function isWeekendDay(date: Date): boolean {
657
- return markWeekend && weekendDays.includes(date.getDay());
658
- }
659
-
660
- function isTodayDay(date: Date): boolean {
661
- return isSameDay(date, today);
662
- }
663
-
664
- function isSelectedDay(date: Date): boolean {
665
- if (selectionMode === 'range') return false;
666
- return isSameDay(date, currentSelected);
667
- }
668
- </script>
669
-
670
- {#snippet calendarBody()}
671
- {#if header}
672
- {@render header()}
673
- {:else}
674
- <div class="cd-calendar__toolbar">
675
- <button
676
- type="button"
677
- class="cd-calendar__nav"
678
- aria-label={loc().t('Calendar.prev')}
679
- onclick={goPrev}
680
- >
681
- <svg viewBox="0 0 16 16" width="14" height="14" aria-hidden="true" focusable="false">
682
- <path
683
- fill="none"
684
- stroke="currentColor"
685
- stroke-width="2"
686
- stroke-linecap="round"
687
- stroke-linejoin="round"
688
- d="M10 3L5 8l5 5"
689
- />
690
- </svg>
691
- </button>
692
- <button type="button" class="cd-calendar__today" onclick={goToday}>{loc().t('Calendar.today')}</button>
693
- <div class="cd-calendar__title">{renderDateDisplay ? renderDateDisplay(currentValue) : title}</div>
694
- <button
695
- type="button"
696
- class="cd-calendar__nav"
697
- aria-label={loc().t('Calendar.next')}
698
- onclick={goNext}
699
- >
700
- <svg viewBox="0 0 16 16" width="14" height="14" aria-hidden="true" focusable="false">
701
- <path
702
- fill="none"
703
- stroke="currentColor"
704
- stroke-width="2"
705
- stroke-linecap="round"
706
- stroke-linejoin="round"
707
- d="M6 3l5 5-5 5"
708
- />
709
- </svg>
710
- </button>
711
- </div>
712
- {/if}
713
-
714
- {#if mode === 'day'}
715
- <div class="cd-calendar__timeline" aria-label={ariaLabel ?? title}>
716
- {#if dayTimeline.allDay.length > 0}
717
- <div class="cd-calendar__allday">
718
- <div class="cd-calendar__allday-label">{loc().t('Calendar.allDay')}</div>
719
- {#if allDayEventsRender}
720
- {@render allDayEventsRender(dayTimeline.allDay)?.()}
721
- {:else}
722
- <div class="cd-calendar__allday-events">
723
- {#each dayTimeline.allDay as ev (ev.key)}
724
- {#if event}
725
- {@render event({ event: ev })}
726
- {:else}
727
- <div
728
- class="cd-calendar__event"
729
- class:cd-calendar__event--disabled={ev.disabled}
730
- style:--cd-calendar-event-accent={ev.color ?? 'var(--cd-calendar-event-default-bg)'}
731
- role="button"
732
- tabindex={ev.disabled ? -1 : 0}
733
- aria-disabled={ev.disabled || undefined}
734
- aria-label={ev.title}
735
- title={ev.title}
736
- onclick={(e) => activateEvent(ev, e)}
737
- onkeydown={(e) => onEventKeydown(ev, e)}
738
- >
739
- <span class="cd-calendar__event-bar" aria-hidden="true"></span>
740
- <span class="cd-calendar__event-title">{ev.title}</span>
741
- </div>
742
- {/if}
743
- {/each}
744
- </div>
745
- {/if}
746
- </div>
747
- {/if}
748
- <div
749
- class="cd-calendar__hours"
750
- class:cd-calendar__hours--virtual={useVirtual}
751
- role="list"
752
- bind:this={timelineEl}
753
- style:max-block-size={useVirtual ? `${timelineViewportHeight}px` : undefined}
754
- style:position="relative"
755
- >
756
- <!-- showCurrTime 红线:绝对定位,top% 由派生纯函数算出(红线 #2) -->
757
- {#if showCurrTime && currTimePercent !== null}
758
- <div
759
- class="cd-calendar__curr-time"
760
- aria-hidden="true"
761
- style:top={`${currTimePercent}%`}
762
- ></div>
763
- {/if}
764
- {#if useVirtual}
765
- <!-- 撑高占位 + 上空白 padding,仅渲染视口行(复用 core fixedRange)-->
766
- <div class="cd-calendar__hours-spacer" style:block-size={`${totalHeight}px`}>
767
- <div style:transform={`translateY(${padTop}px)`}>
768
- {#each visibleSlots as slot (slot.hour)}
769
- {@const hourEvents = dayTimeline.byHour.get(slot.hour) ?? []}
770
- <div class="cd-calendar__hour" role="listitem" style:min-block-size={`${ROW_H}px`}>
771
- <div class="cd-calendar__hour-label" aria-hidden="true">
772
- {renderTimeDisplay ? renderTimeDisplay(slot.hour) : hourLabelFormatter.format(slot.date)}
773
- </div>
774
- <div class="cd-calendar__hour-slot">
775
- {#each hourEvents as ev (ev.key)}
776
- {#if event}
777
- {@render event({ event: ev })}
778
- {:else}
779
- <div
780
- class="cd-calendar__event cd-calendar__event--timed"
781
- class:cd-calendar__event--disabled={ev.disabled}
782
- style:--cd-calendar-event-accent={ev.color ?? 'var(--cd-calendar-event-default-bg)'}
783
- style:min-block-size={minEventHeight ? `${minEventHeight}px` : undefined}
784
- role="button"
785
- tabindex={ev.disabled ? -1 : 0}
786
- aria-disabled={ev.disabled || undefined}
787
- aria-label={`${hourLabelFormatter.format(ev.start)} ${ev.title}`}
788
- title={ev.title}
789
- onclick={(e) => activateEvent(ev, e)}
790
- onkeydown={(e) => onEventKeydown(ev, e)}
791
- >
792
- <span class="cd-calendar__event-bar" aria-hidden="true"></span>
793
- <span class="cd-calendar__event-time">{hourLabelFormatter.format(ev.start)}</span>
794
- <span class="cd-calendar__event-title">{ev.title}</span>
795
- </div>
796
- {/if}
797
- {/each}
798
- </div>
799
- </div>
800
- {/each}
801
- </div>
802
- </div>
803
- {:else}
804
- {#each hourSlots as slot (slot.hour)}
805
- {@const hourEvents = dayTimeline.byHour.get(slot.hour) ?? []}
806
- <div class="cd-calendar__hour" role="listitem">
807
- <div class="cd-calendar__hour-label" aria-hidden="true">
808
- {renderTimeDisplay ? renderTimeDisplay(slot.hour) : hourLabelFormatter.format(slot.date)}
809
- </div>
810
- <div class="cd-calendar__hour-slot">
811
- {#each hourEvents as ev (ev.key)}
812
- {#if event}
813
- {@render event({ event: ev })}
814
- {:else}
815
- <div
816
- class="cd-calendar__event cd-calendar__event--timed"
817
- class:cd-calendar__event--disabled={ev.disabled}
818
- style:--cd-calendar-event-accent={ev.color ?? 'var(--cd-calendar-event-default-bg)'}
819
- style:min-block-size={minEventHeight ? `${minEventHeight}px` : undefined}
820
- title={ev.title}
821
- >
822
- <span class="cd-calendar__event-bar" aria-hidden="true"></span>
823
- <span class="cd-calendar__event-time">{hourLabelFormatter.format(ev.start)}</span>
824
- <span class="cd-calendar__event-title">{ev.title}</span>
825
- </div>
826
- {/if}
827
- {/each}
828
- </div>
829
- </div>
830
- {/each}
831
- {/if}
832
- </div>
833
- </div>
834
- {:else}
835
- <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
836
- <div
837
- class="cd-calendar__grid"
838
- role="grid"
839
- aria-label={ariaLabel ?? title}
840
- tabindex="-1"
841
- onkeydown={onGridKeydown}
842
- >
843
- <div class="cd-calendar__row cd-calendar__row--head" role="row">
844
- {#each weekdayNames as name, i (weekdayOrderList[i])}
845
- {@const weekend = markWeekend && weekendDays.includes(weekdayOrderList[i] as number)}
846
- <div
847
- class="cd-calendar__weekday"
848
- class:cd-calendar__weekday--weekend={weekend}
849
- role="columnheader"
850
- >
851
- {name}
852
- </div>
853
- {/each}
854
- </div>
855
-
856
- {#each weeks as week, wi (wi)}
857
- <div class="cd-calendar__row" role="row">
858
- {#each week as cell (dayKey(cell.date))}
859
- {@const date = cell.date}
860
- {@const outside = !cell.inMonth}
861
- {@const disabled = isDisabled(date)}
862
- {@const isToday = isTodayDay(date)}
863
- {@const selected = isSelectedDay(date)}
864
- {@const weekend = isWeekendDay(date)}
865
- {@const past = isPastDay(date, today)}
866
- {@const rangeEdgeCell = isRangeEdge(date)}
867
- {@const inRangeCell = isInRange(date)}
868
- {@const active = isActiveCell(date)}
869
- {@const dayData = dayMap.get(dayKey(date))}
870
- {@const visible = dayData?.visible ?? []}
871
- {@const total = dayData?.total ?? []}
872
- {@const overflow = dayData?.overflow ?? 0}
873
- <!-- 键盘交互由网格容器统一处理(roving + Enter/Space),格本身只响应点击 -->
874
- <!-- svelte-ignore a11y_click_events_have_key_events -->
875
- <div
876
- class="cd-calendar__cell"
877
- class:cd-calendar__cell--week={mode === 'week'}
878
- class:cd-calendar__cell--today={isToday}
879
- class:cd-calendar__cell--selected={selected}
880
- class:cd-calendar__cell--range-edge={rangeEdgeCell}
881
- class:cd-calendar__cell--in-range={inRangeCell}
882
- class:cd-calendar__cell--outside={outside}
883
- class:cd-calendar__cell--weekend={weekend}
884
- class:cd-calendar__cell--disabled={disabled}
885
- class:cd-calendar__cell--past={past}
886
- class:cd-calendar__cell--active={active}
887
- role="gridcell"
888
- tabindex={disabled ? undefined : active ? 0 : -1}
889
- aria-selected={selected || rangeEdgeCell || undefined}
890
- aria-disabled={disabled || undefined}
891
- aria-current={isToday ? 'date' : undefined}
892
- onclick={() => onCellActivate(date)}
893
- onpointerenter={() => onCellHover(date)}
894
- >
895
- {#if dateCell}
896
- {@render dateCell({ date, events: total, isToday, isOutside: outside, disabled })}
897
- {:else}
898
- <div class="cd-calendar__date">{dayNumber(date)}</div>
899
- {#if dateGridRender}
900
- {@const extraSnippet = dateGridRender(dayKey(date), date)}
901
- {#if extraSnippet}{@render extraSnippet()}{/if}
902
- {/if}
903
- <div class="cd-calendar__events">
904
- {#each visible as ev (ev.key)}
905
- {#if event}
906
- {@render event({ event: ev })}
907
- {:else}
908
- <div
909
- class="cd-calendar__event"
910
- class:cd-calendar__event--disabled={ev.disabled}
911
- style:--cd-calendar-event-accent={ev.color ?? 'var(--cd-calendar-event-default-bg)'}
912
- role="button"
913
- tabindex={ev.disabled ? -1 : 0}
914
- aria-disabled={ev.disabled || undefined}
915
- aria-label={ev.title}
916
- title={ev.title}
917
- onclick={(e) => activateEvent(ev, e)}
918
- onkeydown={(e) => onEventKeydown(ev, e)}
919
- >
920
- <span class="cd-calendar__event-bar" aria-hidden="true"></span>
921
- <span class="cd-calendar__event-title">{ev.title}</span>
922
- </div>
923
- {/if}
924
- {/each}
925
- {#if overflow > 0}
926
- <button
927
- type="button"
928
- class="cd-calendar__more"
929
- onclick={(e) => {
930
- e.stopPropagation();
931
- onMore(date, total);
932
- }}
933
- >
934
- {loc().t('Calendar.moreCount', { count: overflow })}
935
- </button>
936
- {/if}
937
- </div>
938
- {/if}
939
- </div>
940
- {/each}
941
- </div>
942
- {/each}
943
- </div>
944
- {/if}
945
- {/snippet}
946
-
947
- {#if popup}
948
- <div class="cd-calendar-popup" bind:this={triggerEl}>
949
- {#if trigger}
950
- {@render trigger({ open: isOpen, toggle: toggleOpen })}
951
- {:else}
952
- <button
953
- type="button"
954
- class="cd-calendar-popup__trigger"
955
- aria-haspopup="dialog"
956
- aria-expanded={isOpen}
957
- onclick={toggleOpen}
958
- >
959
- <span>{title}</span>
960
- <svg viewBox="0 0 16 16" width="14" height="14" aria-hidden="true" focusable="false">
961
- <path fill="currentColor" d="M5 1v1H3.5A1.5 1.5 0 0 0 2 3.5v9A1.5 1.5 0 0 0 3.5 14h9a1.5 1.5 0 0 0 1.5-1.5v-9A1.5 1.5 0 0 0 12.5 2H11V1h-1v1H6V1H5Zm7.5 4.5v7h-9v-7h9Z" />
962
- </svg>
963
- </button>
964
- {/if}
965
- {#if isOpen}
966
- <div
967
- bind:this={panelEl}
968
- class="cd-calendar cd-calendar--popup"
969
- role="dialog"
970
- aria-label={ariaLabel ?? title}
971
- use:floating={{ trigger: triggerEl, placement, offset: 8, autoAdjust: true, getContainer }}
972
- style:inline-size={width ? (typeof width === 'number' ? `${width}px` : width) : undefined}
973
- style:block-size={height ? (typeof height === 'number' ? `${height}px` : height) : undefined}
974
- >
975
- {@render calendarBody()}
976
- </div>
977
- {/if}
978
- </div>
979
- {:else}
980
- <div
981
- class="cd-calendar"
982
- bind:this={rootEl}
983
- style:inline-size={width ? (typeof width === 'number' ? `${width}px` : width) : undefined}
984
- style:block-size={height ? (typeof height === 'number' ? `${height}px` : height) : undefined}
985
- >
986
- {@render calendarBody()}
987
- </div>
988
- {/if}
989
-
990
- <style>
991
- .cd-calendar {
992
- display: flex;
993
- flex-direction: column;
994
- gap: var(--cd-spacing-2);
995
- color: var(--cd-calendar-text);
996
- background: var(--cd-calendar-bg);
997
- border: 1px solid var(--cd-calendar-border);
998
- border-radius: var(--cd-calendar-radius);
999
- font-size: var(--cd-font-size-body);
1000
- }
1001
-
1002
- .cd-calendar__toolbar {
1003
- display: flex;
1004
- align-items: center;
1005
- gap: var(--cd-spacing-2);
1006
- padding: var(--cd-spacing-2) var(--cd-spacing-3);
1007
- background: var(--cd-calendar-header-bg);
1008
- border-bottom: 1px solid var(--cd-calendar-border);
1009
- border-start-start-radius: var(--cd-calendar-radius);
1010
- border-start-end-radius: var(--cd-calendar-radius);
1011
- }
1012
-
1013
- .cd-calendar__title {
1014
- flex: 1 1 auto;
1015
- font-weight: 600;
1016
- }
1017
-
1018
- .cd-calendar__nav,
1019
- .cd-calendar__today {
1020
- display: inline-flex;
1021
- align-items: center;
1022
- justify-content: center;
1023
- padding: var(--cd-spacing-1) var(--cd-spacing-2);
1024
- color: inherit;
1025
- background: transparent;
1026
- border: 1px solid var(--cd-calendar-border);
1027
- border-radius: var(--cd-calendar-radius);
1028
- cursor: pointer;
1029
- font: inherit;
1030
- transition: background-color var(--cd-motion-duration-fast) var(--cd-motion-ease-standard);
1031
- }
1032
- .cd-calendar__nav:hover,
1033
- .cd-calendar__today:hover {
1034
- background: var(--cd-calendar-cell-bg-hover);
1035
- }
1036
- .cd-calendar__nav:focus-visible,
1037
- .cd-calendar__today:focus-visible {
1038
- outline: none;
1039
- box-shadow: 0 0 0 2px var(--cd-focus-ring);
1040
- }
1041
-
1042
- .cd-calendar__grid {
1043
- display: flex;
1044
- flex-direction: column;
1045
- }
1046
-
1047
- .cd-calendar__row {
1048
- display: grid;
1049
- grid-template-columns: repeat(7, 1fr);
1050
- }
1051
-
1052
- .cd-calendar__weekday {
1053
- padding: var(--cd-spacing-1);
1054
- color: var(--cd-calendar-text-secondary);
1055
- text-align: center;
1056
- font-weight: 500;
1057
- border-block-end: 1px solid var(--cd-calendar-border);
1058
- }
1059
- .cd-calendar__weekday--weekend {
1060
- background: var(--cd-calendar-weekend-bg);
1061
- }
1062
-
1063
- .cd-calendar__cell {
1064
- display: flex;
1065
- flex-direction: column;
1066
- gap: var(--cd-spacing-1);
1067
- min-block-size: var(--cd-calendar-cell-min-h);
1068
- padding: var(--cd-spacing-1);
1069
- border-inline-end: 1px solid var(--cd-calendar-border);
1070
- border-block-end: 1px solid var(--cd-calendar-border);
1071
- cursor: pointer;
1072
- outline: none;
1073
- transition: background-color var(--cd-motion-duration-fast) var(--cd-motion-ease-standard);
1074
- }
1075
- .cd-calendar__cell:hover {
1076
- background: var(--cd-calendar-cell-bg-hover);
1077
- }
1078
- .cd-calendar__cell:focus-visible {
1079
- box-shadow: inset 0 0 0 2px var(--cd-focus-ring);
1080
- }
1081
- /* grid roving 焦点容器自身不需可见焦点环(焦点落在活动格) */
1082
- .cd-calendar__grid:focus {
1083
- outline: none;
1084
- }
1085
-
1086
- .cd-calendar__cell--weekend {
1087
- background: var(--cd-calendar-weekend-bg);
1088
- }
1089
- .cd-calendar__cell--today {
1090
- background: var(--cd-calendar-today-bg);
1091
- }
1092
- .cd-calendar__cell--today .cd-calendar__date {
1093
- color: var(--cd-calendar-today-fg);
1094
- font-weight: 700;
1095
- }
1096
- .cd-calendar__cell--selected {
1097
- box-shadow: inset 0 0 0 2px var(--cd-calendar-selected-border);
1098
- }
1099
- /* range 区间内:浅底连续填充 */
1100
- .cd-calendar__cell--in-range {
1101
- background: var(--cd-calendar-range-bg, var(--cd-calendar-today-bg));
1102
- }
1103
- /* range 端点:实心边框高亮(起止) */
1104
- .cd-calendar__cell--range-edge {
1105
- background: var(--cd-calendar-range-edge-bg, var(--cd-calendar-today-bg));
1106
- box-shadow: inset 0 0 0 2px var(--cd-calendar-selected-border);
1107
- }
1108
- /* week 模式:单行更高,事件区有更多展示空间 */
1109
- .cd-calendar__cell--week {
1110
- min-block-size: var(--cd-calendar-week-cell-min-h, calc(var(--cd-calendar-cell-min-h) * 3));
1111
- }
1112
- .cd-calendar__cell--outside .cd-calendar__date {
1113
- color: var(--cd-calendar-text-secondary);
1114
- }
1115
- .cd-calendar__cell--past .cd-calendar__date {
1116
- opacity: 0.6;
1117
- }
1118
- .cd-calendar__cell--disabled {
1119
- background: var(--cd-calendar-disabled-bg);
1120
- cursor: not-allowed;
1121
- background-image: repeating-linear-gradient(
1122
- 45deg,
1123
- transparent,
1124
- transparent 4px,
1125
- var(--cd-calendar-disabled-bg) 4px,
1126
- var(--cd-calendar-disabled-bg) 8px
1127
- );
1128
- }
1129
- .cd-calendar__cell--disabled:hover {
1130
- background-color: var(--cd-calendar-disabled-bg);
1131
- }
1132
-
1133
- .cd-calendar__date {
1134
- align-self: flex-end;
1135
- font-size: var(--cd-font-size-body);
1136
- line-height: 1.2;
1137
- }
1138
-
1139
- .cd-calendar__events {
1140
- display: flex;
1141
- flex-direction: column;
1142
- gap: 2px;
1143
- min-inline-size: 0;
1144
- }
1145
-
1146
- .cd-calendar__event {
1147
- display: flex;
1148
- align-items: center;
1149
- gap: var(--cd-spacing-1);
1150
- min-inline-size: 0;
1151
- padding-block: 1px;
1152
- padding-inline: var(--cd-spacing-1);
1153
- color: var(--cd-calendar-text);
1154
- background: var(--cd-calendar-cell-bg-hover);
1155
- border-radius: var(--cd-calendar-radius);
1156
- font-size: 0.75rem;
1157
- line-height: 1.4;
1158
- }
1159
- .cd-calendar__event--disabled {
1160
- opacity: 0.5;
1161
- }
1162
- /* 事件块作为 role=button:键盘焦点环可见 */
1163
- .cd-calendar__event[role='button'] {
1164
- cursor: pointer;
1165
- text-align: start;
1166
- }
1167
- .cd-calendar__event[role='button']:focus-visible {
1168
- outline: none;
1169
- box-shadow: 0 0 0 2px var(--cd-focus-ring);
1170
- }
1171
- .cd-calendar__event--disabled[role='button'] {
1172
- cursor: not-allowed;
1173
- }
1174
- .cd-calendar__event-bar {
1175
- flex: 0 0 auto;
1176
- inline-size: 3px;
1177
- align-self: stretch;
1178
- min-block-size: 0.9em;
1179
- background: var(--cd-calendar-event-accent, var(--cd-calendar-event-default-bg));
1180
- border-radius: 2px;
1181
- }
1182
- .cd-calendar__event-title {
1183
- overflow: hidden;
1184
- white-space: nowrap;
1185
- text-overflow: ellipsis;
1186
- }
1187
-
1188
- .cd-calendar__more {
1189
- align-self: flex-start;
1190
- padding: 0;
1191
- color: var(--cd-calendar-more-color);
1192
- background: transparent;
1193
- border: none;
1194
- cursor: pointer;
1195
- font: inherit;
1196
- font-size: var(--cd-font-size-caption, 0.85em);
1197
- }
1198
- .cd-calendar__more:hover {
1199
- text-decoration: underline;
1200
- }
1201
- .cd-calendar__more:focus-visible {
1202
- outline: none;
1203
- box-shadow: 0 0 0 2px var(--cd-focus-ring);
1204
- border-radius: var(--cd-calendar-radius);
1205
- }
1206
-
1207
- /* --- day 视图:单日时间轴 --- */
1208
- .cd-calendar__timeline {
1209
- display: flex;
1210
- flex-direction: column;
1211
- }
1212
-
1213
- .cd-calendar__allday {
1214
- display: flex;
1215
- align-items: flex-start;
1216
- gap: var(--cd-spacing-2);
1217
- padding: var(--cd-spacing-1) var(--cd-spacing-2);
1218
- border-block-end: 1px solid var(--cd-calendar-border);
1219
- background: var(--cd-calendar-header-bg);
1220
- }
1221
- .cd-calendar__allday-label {
1222
- flex: 0 0 var(--cd-calendar-hour-label-w, 56px);
1223
- color: var(--cd-calendar-text-secondary);
1224
- font-weight: 500;
1225
- text-align: end;
1226
- }
1227
- .cd-calendar__allday-events {
1228
- display: flex;
1229
- flex-direction: column;
1230
- gap: 2px;
1231
- min-inline-size: 0;
1232
- flex: 1 1 auto;
1233
- }
1234
-
1235
- .cd-calendar__hours {
1236
- display: flex;
1237
- flex-direction: column;
1238
- }
1239
- .cd-calendar__hour {
1240
- display: flex;
1241
- align-items: stretch;
1242
- gap: var(--cd-spacing-2);
1243
- min-block-size: var(--cd-calendar-hour-min-h, 40px);
1244
- border-block-end: 1px solid var(--cd-calendar-border);
1245
- }
1246
- .cd-calendar__hour:last-child {
1247
- border-block-end: none;
1248
- }
1249
- .cd-calendar__hour-label {
1250
- flex: 0 0 var(--cd-calendar-hour-label-w, 56px);
1251
- padding: var(--cd-spacing-1) var(--cd-spacing-2);
1252
- color: var(--cd-calendar-text-secondary);
1253
- text-align: end;
1254
- font-variant-numeric: tabular-nums;
1255
- border-inline-end: 1px solid var(--cd-calendar-border);
1256
- }
1257
- .cd-calendar__hour-slot {
1258
- display: flex;
1259
- flex-direction: column;
1260
- gap: 2px;
1261
- flex: 1 1 auto;
1262
- min-inline-size: 0;
1263
- padding: var(--cd-spacing-1);
1264
- }
1265
- .cd-calendar__event--timed {
1266
- padding-block: 2px;
1267
- }
1268
- .cd-calendar__event-time {
1269
- flex: 0 0 auto;
1270
- color: var(--cd-calendar-text-secondary);
1271
- font-variant-numeric: tabular-nums;
1272
- font-size: 0.75rem;
1273
- }
1274
-
1275
- /* --- 虚拟化时间轴:滚动视口(block 布局,避免 flex 压缩撑高占位)--- */
1276
- .cd-calendar__hours--virtual {
1277
- display: block;
1278
- overflow-y: auto;
1279
- position: relative;
1280
- }
1281
- .cd-calendar__hours-spacer {
1282
- position: relative;
1283
- flex: none;
1284
- }
1285
-
1286
- /* --- 弹层模式 --- */
1287
- .cd-calendar-popup {
1288
- position: relative;
1289
- display: inline-block;
1290
- }
1291
- .cd-calendar-popup__trigger {
1292
- display: inline-flex;
1293
- align-items: center;
1294
- gap: var(--cd-spacing-2);
1295
- padding: var(--cd-spacing-1) var(--cd-spacing-3);
1296
- color: var(--cd-calendar-text);
1297
- background: var(--cd-calendar-bg);
1298
- border: 1px solid var(--cd-calendar-border);
1299
- border-radius: var(--cd-calendar-radius);
1300
- cursor: pointer;
1301
- font: inherit;
1302
- }
1303
- .cd-calendar-popup__trigger:hover {
1304
- background: var(--cd-calendar-cell-bg-hover);
1305
- }
1306
- .cd-calendar-popup__trigger:focus-visible {
1307
- outline: none;
1308
- box-shadow: 0 0 0 2px var(--cd-focus-ring);
1309
- }
1310
- .cd-calendar--popup {
1311
- z-index: var(--cd-z-popover, 1050);
1312
- inline-size: max-content;
1313
- box-shadow: var(--cd-shadow-elevated, 0 4px 16px rgb(0 0 0 / 0.12));
1314
- }
1315
-
1316
- /* showCurrTime 当前时间红线:绝对定位,跨越整个小时列区域 */
1317
- .cd-calendar__curr-time {
1318
- position: absolute;
1319
- inset-inline: 0;
1320
- block-size: 2px;
1321
- background: var(--cd-calendar-curr-time-color, var(--cd-color-danger, #f5222d));
1322
- z-index: 1;
1323
- pointer-events: none;
1324
- }
1325
- .cd-calendar__curr-time::before {
1326
- content: '';
1327
- position: absolute;
1328
- inset-block-start: 50%;
1329
- inset-inline-start: var(--cd-calendar-hour-label-w, 56px);
1330
- transform: translateY(-50%);
1331
- inline-size: 8px;
1332
- block-size: 8px;
1333
- border-radius: 50%;
1334
- background: var(--cd-calendar-curr-time-color, var(--cd-color-danger, #f5222d));
1335
- }
1336
-
1337
- @media (prefers-reduced-motion: reduce) {
1338
- .cd-calendar__cell,
1339
- .cd-calendar__nav,
1340
- .cd-calendar__today {
1341
- transition: none;
1342
- }
1343
- }
1344
- </style>