@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.
- package/dist/components.json +1 -1
- package/package.json +7 -8
- package/src/_floating/use-floating.ts +0 -208
- package/src/anchor/Anchor.a11y.test.ts +0 -49
- package/src/anchor/Anchor.kbd.test.ts +0 -70
- package/src/anchor/Anchor.svelte +0 -359
- package/src/anchor/AnchorKbdFixture.svelte +0 -24
- package/src/anchor/index.ts +0 -3
- package/src/anchor/meta.ts +0 -70
- package/src/anchor/types.ts +0 -8
- package/src/autocomplete/AutoComplete.a11y.test.ts +0 -49
- package/src/autocomplete/AutoComplete.kbd.test.ts +0 -69
- package/src/autocomplete/AutoComplete.svelte +0 -706
- package/src/autocomplete/AutoCompleteKbdFixture.svelte +0 -24
- package/src/autocomplete/index.ts +0 -2
- package/src/autocomplete/meta.ts +0 -41
- package/src/avatar/Avatar.a11y.test.ts +0 -37
- package/src/avatar/Avatar.svelte +0 -315
- package/src/avatar/AvatarGroup.svelte +0 -142
- package/src/avatar/context.ts +0 -21
- package/src/avatar/index.ts +0 -10
- package/src/avatar/meta.ts +0 -73
- package/src/back-top/BackTop.a11y.test.ts +0 -40
- package/src/back-top/BackTop.svelte +0 -314
- package/src/back-top/index.ts +0 -2
- package/src/back-top/meta.ts +0 -108
- package/src/badge/Badge.a11y.test.ts +0 -35
- package/src/badge/Badge.svelte +0 -328
- package/src/badge/BadgeA11yFixture.svelte +0 -18
- package/src/badge/index.ts +0 -2
- package/src/badge/meta.ts +0 -62
- package/src/banner/Banner.a11y.test.ts +0 -48
- package/src/banner/Banner.svelte +0 -368
- package/src/banner/index.ts +0 -3
- package/src/banner/meta.ts +0 -121
- package/src/breadcrumb/Breadcrumb.a11y.test.ts +0 -35
- package/src/breadcrumb/Breadcrumb.kbd.test.ts +0 -45
- package/src/breadcrumb/Breadcrumb.svelte +0 -414
- package/src/breadcrumb/BreadcrumbKbdFixture.svelte +0 -23
- package/src/breadcrumb/Item.svelte +0 -77
- package/src/breadcrumb/context.ts +0 -27
- package/src/breadcrumb/index.ts +0 -21
- package/src/breadcrumb/meta.ts +0 -128
- package/src/breadcrumb/types.ts +0 -4
- package/src/button/Button.a11y.test.ts +0 -54
- package/src/button/Button.svelte +0 -176
- package/src/button/index.ts +0 -2
- package/src/button/meta.ts +0 -28
- package/src/calendar/Calendar.a11y.test.ts +0 -51
- package/src/calendar/Calendar.kbd.test.ts +0 -59
- package/src/calendar/Calendar.svelte +0 -1344
- package/src/calendar/CalendarKbdFixture.svelte +0 -23
- package/src/calendar/index.ts +0 -3
- package/src/calendar/meta.ts +0 -117
- package/src/card/Card.a11y.test.ts +0 -38
- package/src/card/Card.svelte +0 -341
- package/src/card/CardMeta.svelte +0 -60
- package/src/card/index.ts +0 -8
- package/src/card/meta.ts +0 -83
- package/src/carousel/Carousel.a11y.test.ts +0 -53
- package/src/carousel/Carousel.kbd.test.ts +0 -67
- package/src/carousel/Carousel.svelte +0 -806
- package/src/carousel/CarouselA11yFixture.svelte +0 -25
- package/src/carousel/CarouselKbdFixture.svelte +0 -24
- package/src/carousel/index.ts +0 -2
- package/src/carousel/meta.ts +0 -74
- package/src/cascader/Cascader.a11y.test.ts +0 -59
- package/src/cascader/Cascader.kbd.test.ts +0 -56
- package/src/cascader/Cascader.svelte +0 -1570
- package/src/cascader/CascaderKbdFixture.svelte +0 -31
- package/src/cascader/index.ts +0 -3
- package/src/cascader/meta.ts +0 -57
- package/src/cascader/types.ts +0 -9
- package/src/checkbox/Checkbox.svelte +0 -281
- package/src/checkbox/CheckboxGroup.a11y.test.ts +0 -43
- package/src/checkbox/CheckboxGroup.kbd.test.ts +0 -40
- package/src/checkbox/CheckboxGroup.svelte +0 -122
- package/src/checkbox/CheckboxGroupKbdFixture.svelte +0 -20
- package/src/checkbox/context.ts +0 -31
- package/src/checkbox/index.ts +0 -4
- package/src/checkbox/meta.ts +0 -67
- package/src/collapse/Collapse.a11y.test.ts +0 -53
- package/src/collapse/Collapse.kbd.test.ts +0 -89
- package/src/collapse/Collapse.svelte +0 -406
- package/src/collapse/CollapseA11yFixture.svelte +0 -27
- package/src/collapse/CollapseKbdFixture.svelte +0 -25
- package/src/collapse/CollapsePanel.svelte +0 -102
- package/src/collapse/context.ts +0 -54
- package/src/collapse/index.ts +0 -17
- package/src/collapse/meta.ts +0 -79
- package/src/collapse/types.ts +0 -5
- package/src/color-picker/ColorPicker.a11y.test.ts +0 -60
- package/src/color-picker/ColorPicker.kbd.test.ts +0 -73
- package/src/color-picker/ColorPicker.svelte +0 -985
- package/src/color-picker/ColorPickerKbdFixture.svelte +0 -25
- package/src/color-picker/index.ts +0 -2
- package/src/color-picker/meta.ts +0 -47
- package/src/config-provider/ConfigProvider.svelte +0 -227
- package/src/config-provider/context.ts +0 -29
- package/src/config-provider/index.ts +0 -48
- package/src/config-provider/meta.ts +0 -128
- package/src/date-picker/DatePicker.a11y.test.ts +0 -45
- package/src/date-picker/DatePicker.kbd.test.ts +0 -71
- package/src/date-picker/DatePicker.svelte +0 -1798
- package/src/date-picker/DatePickerKbdFixture.svelte +0 -26
- package/src/date-picker/RangePicker.kbd.test.ts +0 -69
- package/src/date-picker/RangePicker.svelte +0 -775
- package/src/date-picker/RangePickerKbdFixture.svelte +0 -30
- package/src/date-picker/index.ts +0 -4
- package/src/date-picker/meta.ts +0 -67
- package/src/date-picker/range-meta.ts +0 -44
- package/src/descriptions/Descriptions.a11y.test.ts +0 -33
- package/src/descriptions/Descriptions.svelte +0 -287
- package/src/descriptions/DescriptionsItem.svelte +0 -43
- package/src/descriptions/context.ts +0 -21
- package/src/descriptions/index.ts +0 -16
- package/src/descriptions/meta.ts +0 -45
- package/src/descriptions/types.ts +0 -6
- package/src/divider/Divider.a11y.test.ts +0 -23
- package/src/divider/Divider.svelte +0 -154
- package/src/divider/index.ts +0 -2
- package/src/divider/meta.ts +0 -23
- package/src/drawer/Drawer.a11y.test.ts +0 -41
- package/src/drawer/Drawer.kbd.test.ts +0 -67
- package/src/drawer/Drawer.svelte +0 -554
- package/src/drawer/DrawerKbdFixture.svelte +0 -28
- package/src/drawer/index.ts +0 -2
- package/src/drawer/meta.ts +0 -127
- package/src/dropdown/Dropdown.a11y.test.ts +0 -46
- package/src/dropdown/Dropdown.kbd.test.ts +0 -56
- package/src/dropdown/Dropdown.svelte +0 -573
- package/src/dropdown/DropdownA11yFixture.svelte +0 -24
- package/src/dropdown/DropdownDivider.svelte +0 -17
- package/src/dropdown/DropdownItem.svelte +0 -127
- package/src/dropdown/DropdownItemNode.svelte +0 -355
- package/src/dropdown/DropdownKbdFixture.svelte +0 -26
- package/src/dropdown/DropdownMenu.svelte +0 -24
- package/src/dropdown/DropdownSubMenu.svelte +0 -212
- package/src/dropdown/DropdownTitle.svelte +0 -34
- package/src/dropdown/context.ts +0 -13
- package/src/dropdown/index.ts +0 -36
- package/src/dropdown/meta.ts +0 -97
- package/src/dropdown/types.test.ts +0 -50
- package/src/dropdown/types.ts +0 -67
- package/src/empty/Empty.a11y.test.ts +0 -24
- package/src/empty/Empty.svelte +0 -304
- package/src/empty/index.ts +0 -2
- package/src/empty/meta.ts +0 -41
- package/src/form/Field.svelte +0 -492
- package/src/form/FieldArray.svelte +0 -75
- package/src/form/Form.a11y.test.ts +0 -39
- package/src/form/Form.svelte +0 -243
- package/src/form/FormA11yFixture.svelte +0 -31
- package/src/form/FormCascader.svelte +0 -82
- package/src/form/FormCheckbox.svelte +0 -83
- package/src/form/FormDatePicker.svelte +0 -80
- package/src/form/FormErrorMessage.svelte +0 -44
- package/src/form/FormInput.svelte +0 -95
- package/src/form/FormLabel.svelte +0 -46
- package/src/form/FormRadio.svelte +0 -83
- package/src/form/FormRating.svelte +0 -85
- package/src/form/FormSection.svelte +0 -45
- package/src/form/FormSelect.svelte +0 -96
- package/src/form/FormSlider.svelte +0 -95
- package/src/form/FormSlot.svelte +0 -51
- package/src/form/FormSwitch.svelte +0 -82
- package/src/form/FormTagInput.svelte +0 -79
- package/src/form/FormTreeSelect.svelte +0 -85
- package/src/form/FormUpload.svelte +0 -92
- package/src/form/context.ts +0 -47
- package/src/form/index.ts +0 -22
- package/src/form/meta.ts +0 -85
- package/src/grid/Col.svelte +0 -142
- package/src/grid/Grid.a11y.test.ts +0 -14
- package/src/grid/GridA11yFixture.svelte +0 -12
- package/src/grid/Row.svelte +0 -116
- package/src/grid/index.ts +0 -3
- package/src/grid/meta.ts +0 -72
- package/src/grid/use-breakpoint.svelte.ts +0 -48
- package/src/highlight/Highlight.a11y.test.ts +0 -25
- package/src/highlight/Highlight.svelte +0 -99
- package/src/highlight/index.ts +0 -2
- package/src/highlight/meta.ts +0 -80
- package/src/icon/Icon.svelte +0 -156
- package/src/icon/index.ts +0 -2
- package/src/icon/meta.ts +0 -41
- package/src/image/Image.a11y.test.ts +0 -30
- package/src/image/Image.svelte +0 -387
- package/src/image/ImagePreview.kbd.test.ts +0 -52
- package/src/image/ImagePreview.svelte +0 -309
- package/src/image/ImagePreviewGroup.svelte +0 -93
- package/src/image/ImagePreviewKbdFixture.svelte +0 -32
- package/src/image/context.ts +0 -26
- package/src/image/index.ts +0 -15
- package/src/image/meta.ts +0 -131
- package/src/index.ts +0 -208
- package/src/input/Input.a11y.test.ts +0 -58
- package/src/input/Input.svelte +0 -505
- package/src/input/index.ts +0 -2
- package/src/input/meta.ts +0 -40
- package/src/input-number/InputNumber.a11y.test.ts +0 -43
- package/src/input-number/InputNumber.kbd.test.ts +0 -41
- package/src/input-number/InputNumber.svelte +0 -674
- package/src/input-number/InputNumberKbdFixture.svelte +0 -15
- package/src/input-number/index.ts +0 -2
- package/src/input-number/meta.ts +0 -65
- package/src/layout/Content.svelte +0 -37
- package/src/layout/Footer.svelte +0 -49
- package/src/layout/Header.svelte +0 -46
- package/src/layout/Layout.a11y.test.ts +0 -34
- package/src/layout/Layout.svelte +0 -60
- package/src/layout/LayoutA11yFixture.svelte +0 -21
- package/src/layout/Sider.svelte +0 -207
- package/src/layout/index.ts +0 -26
- package/src/layout/meta.ts +0 -116
- package/src/list/List.a11y.test.ts +0 -69
- package/src/list/List.bench.ts +0 -26
- package/src/list/List.kbd.test.ts +0 -71
- package/src/list/List.svelte +0 -920
- package/src/list/ListA11yFixture.svelte +0 -38
- package/src/list/ListBenchFixture.svelte +0 -22
- package/src/list/ListItem.svelte +0 -175
- package/src/list/ListKbdFixture.svelte +0 -31
- package/src/list/ListMeta.svelte +0 -73
- package/src/list/context.ts +0 -39
- package/src/list/index.ts +0 -21
- package/src/list/meta.ts +0 -99
- package/src/locale-provider/LocaleProvider.svelte +0 -110
- package/src/locale-provider/context.ts +0 -22
- package/src/locale-provider/index.ts +0 -21
- package/src/locale-provider/meta.ts +0 -93
- package/src/locale-provider/use-locale.ts +0 -25
- package/src/lottie-icon/LottieIcon.svelte +0 -330
- package/src/lottie-icon/index.ts +0 -9
- package/src/lottie-icon/meta.ts +0 -162
- package/src/menu/Menu.a11y.test.ts +0 -54
- package/src/menu/Menu.kbd.test.ts +0 -69
- package/src/menu/Menu.svelte +0 -762
- package/src/menu/MenuKbdFixture.svelte +0 -22
- package/src/menu/MenuPopupNode.svelte +0 -525
- package/src/menu/index.ts +0 -4
- package/src/menu/meta.ts +0 -137
- package/src/menu/types.ts +0 -120
- package/src/meta.test.ts +0 -173
- package/src/modal/ConfirmModal.svelte +0 -173
- package/src/modal/Modal.a11y.test.ts +0 -46
- package/src/modal/Modal.kbd.test.ts +0 -65
- package/src/modal/Modal.svelte +0 -511
- package/src/modal/ModalKbdFixture.svelte +0 -24
- package/src/modal/command.svelte.ts +0 -103
- package/src/modal/index.ts +0 -30
- package/src/modal/meta.ts +0 -165
- package/src/modal/z-stack.ts +0 -26
- package/src/notification/NotificationContainer.svelte +0 -192
- package/src/notification/NotificationItem.a11y.test.ts +0 -73
- package/src/notification/NotificationItem.svelte +0 -368
- package/src/notification/index.ts +0 -9
- package/src/notification/meta.ts +0 -120
- package/src/notification/store.ts +0 -191
- package/src/overflow-list/OverflowList.a11y.test.ts +0 -46
- package/src/overflow-list/OverflowList.kbd.test.ts +0 -34
- package/src/overflow-list/OverflowList.svelte +0 -539
- package/src/overflow-list/OverflowListA11yFixture.svelte +0 -22
- package/src/overflow-list/OverflowListKbdFixture.svelte +0 -21
- package/src/overflow-list/index.ts +0 -2
- package/src/overflow-list/meta.ts +0 -138
- package/src/pagination/Pagination.a11y.test.ts +0 -62
- package/src/pagination/Pagination.kbd.test.ts +0 -66
- package/src/pagination/Pagination.svelte +0 -428
- package/src/pagination/PaginationKbdFixture.svelte +0 -15
- package/src/pagination/index.ts +0 -2
- package/src/pagination/meta.ts +0 -73
- package/src/popconfirm/Popconfirm.a11y.test.ts +0 -46
- package/src/popconfirm/Popconfirm.kbd.test.ts +0 -42
- package/src/popconfirm/Popconfirm.svelte +0 -724
- package/src/popconfirm/PopconfirmA11yFixture.svelte +0 -34
- package/src/popconfirm/PopconfirmKbdFixture.svelte +0 -17
- package/src/popconfirm/index.ts +0 -2
- package/src/popconfirm/meta.ts +0 -200
- package/src/popover/Popover.a11y.test.ts +0 -58
- package/src/popover/Popover.kbd.test.ts +0 -42
- package/src/popover/Popover.svelte +0 -643
- package/src/popover/PopoverA11yFixture.svelte +0 -35
- package/src/popover/PopoverKbdFixture.svelte +0 -18
- package/src/popover/index.ts +0 -2
- package/src/popover/meta.ts +0 -103
- package/src/progress/Progress.a11y.test.ts +0 -37
- package/src/progress/Progress.svelte +0 -423
- package/src/progress/index.ts +0 -3
- package/src/progress/meta.ts +0 -132
- package/src/radio/Radio.svelte +0 -330
- package/src/radio/RadioGroup.a11y.test.ts +0 -43
- package/src/radio/RadioGroup.kbd.test.ts +0 -75
- package/src/radio/RadioGroup.svelte +0 -199
- package/src/radio/RadioGroupKbdFixture.svelte +0 -21
- package/src/radio/context.ts +0 -42
- package/src/radio/index.ts +0 -4
- package/src/radio/meta.ts +0 -68
- package/src/rating/Rating.a11y.test.ts +0 -41
- package/src/rating/Rating.kbd.test.ts +0 -48
- package/src/rating/Rating.svelte +0 -407
- package/src/rating/RatingKbdFixture.svelte +0 -15
- package/src/rating/index.ts +0 -2
- package/src/rating/meta.ts +0 -40
- package/src/resize-observer/ResizeObserver.svelte +0 -169
- package/src/resize-observer/action.ts +0 -80
- package/src/resize-observer/index.ts +0 -9
- package/src/resize-observer/meta.ts +0 -102
- package/src/scroll-list/ScrollColumn.svelte +0 -592
- package/src/scroll-list/ScrollList.svelte +0 -257
- package/src/scroll-list/index.ts +0 -4
- package/src/scroll-list/meta.ts +0 -93
- package/src/scroll-list/types.ts +0 -18
- package/src/select/Select.a11y.test.ts +0 -59
- package/src/select/Select.kbd.test.ts +0 -59
- package/src/select/Select.svelte +0 -1155
- package/src/select/SelectKbdFixture.svelte +0 -29
- package/src/select/index.ts +0 -3
- package/src/select/meta.ts +0 -78
- package/src/select/types.ts +0 -2
- package/src/side-sheet/SideSheet.a11y.test.ts +0 -53
- package/src/side-sheet/SideSheet.kbd.test.ts +0 -63
- package/src/side-sheet/SideSheet.svelte +0 -659
- package/src/side-sheet/SideSheetKbdFixture.svelte +0 -30
- package/src/side-sheet/index.ts +0 -2
- package/src/side-sheet/meta.ts +0 -116
- package/src/skeleton/Skeleton.a11y.test.ts +0 -35
- package/src/skeleton/Skeleton.svelte +0 -131
- package/src/skeleton/SkeletonAvatar.svelte +0 -82
- package/src/skeleton/SkeletonButton.svelte +0 -90
- package/src/skeleton/SkeletonImage.svelte +0 -100
- package/src/skeleton/SkeletonParagraph.svelte +0 -103
- package/src/skeleton/SkeletonTitle.svelte +0 -74
- package/src/skeleton/context.ts +0 -11
- package/src/skeleton/index.ts +0 -8
- package/src/skeleton/meta.ts +0 -65
- package/src/slider/Slider.a11y.test.ts +0 -44
- package/src/slider/Slider.kbd.test.ts +0 -74
- package/src/slider/Slider.svelte +0 -716
- package/src/slider/SliderKbdFixture.svelte +0 -21
- package/src/slider/index.ts +0 -2
- package/src/slider/meta.ts +0 -55
- package/src/space/Space.a11y.test.ts +0 -22
- package/src/space/Space.svelte +0 -109
- package/src/space/SpaceA11yFixture.svelte +0 -17
- package/src/space/index.ts +0 -2
- package/src/space/meta.ts +0 -27
- package/src/spin/Spin.a11y.test.ts +0 -29
- package/src/spin/Spin.svelte +0 -293
- package/src/spin/SpinA11yFixture.svelte +0 -18
- package/src/spin/index.ts +0 -2
- package/src/spin/meta.ts +0 -72
- package/src/steps/Steps.a11y.test.ts +0 -39
- package/src/steps/Steps.kbd.test.ts +0 -73
- package/src/steps/Steps.svelte +0 -392
- package/src/steps/StepsKbdFixture.svelte +0 -21
- package/src/steps/index.ts +0 -3
- package/src/steps/meta.ts +0 -59
- package/src/steps/types.ts +0 -8
- package/src/switch/Switch.a11y.test.ts +0 -46
- package/src/switch/Switch.kbd.test.ts +0 -40
- package/src/switch/Switch.svelte +0 -310
- package/src/switch/SwitchKbdFixture.svelte +0 -22
- package/src/switch/index.ts +0 -2
- package/src/switch/meta.ts +0 -44
- package/src/table/Table.a11y.test.ts +0 -70
- package/src/table/Table.bench.ts +0 -51
- package/src/table/Table.kbd.test.ts +0 -94
- package/src/table/Table.svelte +0 -2327
- package/src/table/TableKbdFixture.svelte +0 -35
- package/src/table/grid-nav.test.ts +0 -173
- package/src/table/grid-nav.ts +0 -146
- package/src/table/index.ts +0 -13
- package/src/table/meta.ts +0 -121
- package/src/table/types.ts +0 -133
- package/src/tabs/TabPane.svelte +0 -92
- package/src/tabs/Tabs.a11y.test.ts +0 -47
- package/src/tabs/Tabs.kbd.test.ts +0 -74
- package/src/tabs/Tabs.svelte +0 -1128
- package/src/tabs/TabsA11yFixture.svelte +0 -20
- package/src/tabs/TabsKbdFixture.svelte +0 -25
- package/src/tabs/context.ts +0 -43
- package/src/tabs/index.ts +0 -14
- package/src/tabs/meta.ts +0 -152
- package/src/tabs/types.ts +0 -6
- package/src/tag/Tag.a11y.test.ts +0 -33
- package/src/tag/Tag.svelte +0 -366
- package/src/tag/TagA11yFixture.svelte +0 -18
- package/src/tag/index.ts +0 -2
- package/src/tag/meta.ts +0 -92
- package/src/tag-input/TagInput.a11y.test.ts +0 -41
- package/src/tag-input/TagInput.svelte +0 -544
- package/src/tag-input/index.ts +0 -2
- package/src/tag-input/meta.ts +0 -43
- package/src/tag-input/reorder.test.ts +0 -59
- package/src/tag-input/reorder.ts +0 -41
- package/src/test-utils/LocaleHarness.svelte +0 -29
- package/src/test-utils/a11y.ts +0 -108
- package/src/test-utils/kbd.ts +0 -52
- package/src/textarea/TextArea.a11y.test.ts +0 -44
- package/src/textarea/TextArea.svelte +0 -420
- package/src/textarea/index.ts +0 -2
- package/src/textarea/meta.ts +0 -104
- package/src/time-picker/TimePicker.a11y.test.ts +0 -45
- package/src/time-picker/TimePicker.kbd.test.ts +0 -70
- package/src/time-picker/TimePicker.svelte +0 -1023
- package/src/time-picker/TimePickerKbdFixture.svelte +0 -23
- package/src/time-picker/index.ts +0 -2
- package/src/time-picker/meta.ts +0 -64
- package/src/timeline/Timeline.a11y.test.ts +0 -54
- package/src/timeline/Timeline.svelte +0 -599
- package/src/timeline/TimelineItem.svelte +0 -164
- package/src/timeline/context.ts +0 -28
- package/src/timeline/index.ts +0 -16
- package/src/timeline/meta.ts +0 -129
- package/src/timeline/types.ts +0 -9
- package/src/toast/Toast.a11y.test.ts +0 -67
- package/src/toast/ToastContainer.svelte +0 -184
- package/src/toast/ToastItem.svelte +0 -247
- package/src/toast/index.ts +0 -9
- package/src/toast/live-region.ts +0 -78
- package/src/toast/meta.ts +0 -95
- package/src/toast/store.ts +0 -187
- package/src/tooltip/Tooltip.a11y.test.ts +0 -41
- package/src/tooltip/Tooltip.kbd.test.ts +0 -37
- package/src/tooltip/Tooltip.svelte +0 -416
- package/src/tooltip/TooltipA11yFixture.svelte +0 -31
- package/src/tooltip/TooltipKbdFixture.svelte +0 -16
- package/src/tooltip/index.ts +0 -2
- package/src/tooltip/meta.ts +0 -59
- package/src/tooltip/placement.ts +0 -6
- package/src/transfer/Transfer.a11y.test.ts +0 -63
- package/src/transfer/Transfer.kbd.test.ts +0 -75
- package/src/transfer/Transfer.svelte +0 -1451
- package/src/transfer/TransferKbdFixture.svelte +0 -23
- package/src/transfer/group.test.ts +0 -55
- package/src/transfer/group.ts +0 -61
- package/src/transfer/index.ts +0 -3
- package/src/transfer/meta.ts +0 -55
- package/src/transfer/reorder.test.ts +0 -52
- package/src/transfer/reorder.ts +0 -42
- package/src/transfer/tree.test.ts +0 -44
- package/src/transfer/tree.ts +0 -52
- package/src/transfer/types.ts +0 -32
- package/src/tree/Tree.a11y.test.ts +0 -63
- package/src/tree/Tree.kbd.test.ts +0 -91
- package/src/tree/Tree.svelte +0 -1500
- package/src/tree/TreeKbdFixture.svelte +0 -30
- package/src/tree/index.ts +0 -3
- package/src/tree/meta.ts +0 -152
- package/src/tree-select/TreeSelect.a11y.test.ts +0 -52
- package/src/tree-select/TreeSelect.kbd.test.ts +0 -53
- package/src/tree-select/TreeSelect.svelte +0 -1611
- package/src/tree-select/TreeSelectKbdFixture.svelte +0 -20
- package/src/tree-select/index.ts +0 -3
- package/src/tree-select/meta.ts +0 -73
- package/src/tree-select/types.ts +0 -11
- package/src/tree-select/virtual.test.ts +0 -104
- package/src/typography/Link.svelte +0 -120
- package/src/typography/Paragraph.svelte +0 -92
- package/src/typography/Text.svelte +0 -93
- package/src/typography/Title.svelte +0 -91
- package/src/typography/Typography.a11y.test.ts +0 -34
- package/src/typography/TypographyA11yFixture.svelte +0 -27
- package/src/typography/TypographyBase.svelte +0 -807
- package/src/typography/index.ts +0 -16
- package/src/typography/meta.ts +0 -158
- package/src/upload/Upload.a11y.test.ts +0 -58
- package/src/upload/Upload.svelte +0 -1094
- package/src/upload/UploadA11yFixture.svelte +0 -23
- package/src/upload/index.ts +0 -3
- package/src/upload/meta.ts +0 -64
- package/src/upload/types.ts +0 -16
- package/src/virtual-list/VirtualList.svelte +0 -401
- package/src/virtual-list/index.ts +0 -2
- package/src/virtual-list/meta.ts +0 -106
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
仅供 Transfer.kbd.test.ts(browser project)使用的双 listbox roving 键盘 e2e 夹具。
|
|
3
|
-
受控 value + onChange 回写,使「移动到对侧」真实生效(红线 #1:组件不自改 value)。
|
|
4
|
-
左侧为 SOURCE(role=listbox),条目 role=option + data-transfer-key;
|
|
5
|
-
验证:列内 ↑↓ 真实移动焦点到相邻 option、Space 勾选、Enter 移动后焦点保留在源列合理位置。
|
|
6
|
-
-->
|
|
7
|
-
<script lang="ts">
|
|
8
|
-
import { LocaleProvider } from '../locale-provider/index.js';
|
|
9
|
-
import Transfer from './Transfer.svelte';
|
|
10
|
-
|
|
11
|
-
const dataSource = [
|
|
12
|
-
{ key: 'a', label: 'Apple' },
|
|
13
|
-
{ key: 'b', label: 'Banana' },
|
|
14
|
-
{ key: 'c', label: 'Cherry' },
|
|
15
|
-
{ key: 'd', label: 'Date' },
|
|
16
|
-
];
|
|
17
|
-
|
|
18
|
-
let value = $state<string[]>([]);
|
|
19
|
-
</script>
|
|
20
|
-
|
|
21
|
-
<LocaleProvider locale="en_US">
|
|
22
|
-
<Transfer {dataSource} {value} onChange={(next) => (value = next as string[])} />
|
|
23
|
-
</LocaleProvider>
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { buildGroups, hasGroups, isGrouped, normalizeData } from './group.js';
|
|
3
|
-
import type { TransferGroup, TransferItem } from './types.js';
|
|
4
|
-
|
|
5
|
-
describe('transfer/group', () => {
|
|
6
|
-
const flat: TransferItem[] = [
|
|
7
|
-
{ key: 'a', label: '北京' },
|
|
8
|
-
{ key: 'b', label: '上海' },
|
|
9
|
-
];
|
|
10
|
-
const grouped: TransferGroup[] = [
|
|
11
|
-
{ title: '华东', items: [{ key: 'hz', label: '杭州' }, { key: 'sh', label: '上海' }] },
|
|
12
|
-
{ title: '华南', items: [{ key: 'gz', label: '广州' }] },
|
|
13
|
-
];
|
|
14
|
-
|
|
15
|
-
it('isGrouped distinguishes flat vs grouped', () => {
|
|
16
|
-
expect(isGrouped(flat)).toBe(false);
|
|
17
|
-
expect(isGrouped(grouped)).toBe(true);
|
|
18
|
-
expect(isGrouped([])).toBe(false);
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it('normalizeData keeps flat data untouched', () => {
|
|
22
|
-
expect(normalizeData(flat)).toEqual(flat);
|
|
23
|
-
expect(hasGroups(normalizeData(flat))).toBe(false);
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it('normalizeData flattens grouped data and stamps group from title', () => {
|
|
27
|
-
const items = normalizeData(grouped);
|
|
28
|
-
expect(items.map((i) => i.key)).toEqual(['hz', 'sh', 'gz']);
|
|
29
|
-
expect(items.map((i) => i.group)).toEqual(['华东', '华东', '华南']);
|
|
30
|
-
expect(hasGroups(items)).toBe(true);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it('group title wins over a pre-set group on item', () => {
|
|
34
|
-
const src: TransferGroup[] = [
|
|
35
|
-
{ title: 'X', items: [{ key: '1', label: 'one', group: 'Y' }] },
|
|
36
|
-
];
|
|
37
|
-
expect(normalizeData(src)[0]!.group).toBe('X');
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('buildGroups preserves first-seen order and drops empty groups', () => {
|
|
41
|
-
const items = normalizeData(grouped);
|
|
42
|
-
// simulate a filter that removes all of 华南
|
|
43
|
-
const filtered = items.filter((i) => i.group === '华东');
|
|
44
|
-
const out = buildGroups(filtered, 'fallback');
|
|
45
|
-
expect(out.map((g) => g.title)).toEqual(['华东']);
|
|
46
|
-
expect(out[0]!.items.map((i) => i.key)).toEqual(['hz', 'sh']);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('buildGroups buckets ungrouped items under fallback title', () => {
|
|
50
|
-
const out = buildGroups(flat, '源');
|
|
51
|
-
expect(out).toHaveLength(1);
|
|
52
|
-
expect(out[0]!.title).toBe('源');
|
|
53
|
-
expect(out[0]!.items).toEqual(flat);
|
|
54
|
-
});
|
|
55
|
-
});
|
package/src/transfer/group.ts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import type { TransferGroup, TransferItem, TransferRenderGroup } from './types.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Normalize either a flat `TransferItem[]` or a grouped `TransferGroup[]` into a
|
|
5
|
-
* single flat list of items. Grouped input stamps `item.group` from the group
|
|
6
|
-
* title (the group title wins over any pre-set `group` on the item). Flat input
|
|
7
|
-
* is returned as-is so backward-compatible (ungrouped) behavior is untouched.
|
|
8
|
-
*/
|
|
9
|
-
export function normalizeData(
|
|
10
|
-
dataSource: TransferItem[] | TransferGroup[],
|
|
11
|
-
): TransferItem[] {
|
|
12
|
-
if (isGrouped(dataSource)) {
|
|
13
|
-
const out: TransferItem[] = [];
|
|
14
|
-
for (const grp of dataSource) {
|
|
15
|
-
for (const item of grp.items) out.push({ ...item, group: grp.title });
|
|
16
|
-
}
|
|
17
|
-
return out;
|
|
18
|
-
}
|
|
19
|
-
return dataSource;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/** A grouped data source is an array whose entries have `items` (not `key`). */
|
|
23
|
-
export function isGrouped(
|
|
24
|
-
dataSource: TransferItem[] | TransferGroup[],
|
|
25
|
-
): dataSource is TransferGroup[] {
|
|
26
|
-
return (
|
|
27
|
-
dataSource.length > 0 &&
|
|
28
|
-
Array.isArray((dataSource[0] as TransferGroup).items) &&
|
|
29
|
-
(dataSource[0] as TransferItem).key === undefined
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Build render groups from a list of (already-filtered) items, preserving the
|
|
35
|
-
* first-seen order of group names. Items without a `group` fall into a single
|
|
36
|
-
* ungrouped bucket keyed by `fallbackTitle`. Empty groups are naturally absent
|
|
37
|
-
* because the input is the post-filter item list.
|
|
38
|
-
*/
|
|
39
|
-
export function buildGroups(
|
|
40
|
-
items: TransferItem[],
|
|
41
|
-
fallbackTitle: string,
|
|
42
|
-
): TransferRenderGroup[] {
|
|
43
|
-
const order: string[] = [];
|
|
44
|
-
const map = new Map<string, TransferItem[]>();
|
|
45
|
-
for (const item of items) {
|
|
46
|
-
const title = item.group ?? fallbackTitle;
|
|
47
|
-
let bucket = map.get(title);
|
|
48
|
-
if (!bucket) {
|
|
49
|
-
bucket = [];
|
|
50
|
-
map.set(title, bucket);
|
|
51
|
-
order.push(title);
|
|
52
|
-
}
|
|
53
|
-
bucket.push(item);
|
|
54
|
-
}
|
|
55
|
-
return order.map((title) => ({ title, items: map.get(title)! }));
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/** True when any normalized item carries a `group` tag. */
|
|
59
|
-
export function hasGroups(items: TransferItem[]): boolean {
|
|
60
|
-
return items.some((i) => i.group !== undefined);
|
|
61
|
-
}
|
package/src/transfer/index.ts
DELETED
package/src/transfer/meta.ts
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Machine-readable component metadata for AI/docs consumption.
|
|
3
|
-
* See specs/00-foundation/ai-friendly.spec.md.
|
|
4
|
-
*/
|
|
5
|
-
export const meta = {
|
|
6
|
-
name: 'Transfer',
|
|
7
|
-
category: 'input',
|
|
8
|
-
description: '穿梭框,双栏列表间移动条目,支持多选、移动按钮、本地搜索过滤、分组(groupList)、树状源面板(treeList)、单向迁移(oneWay)、目标列拖拽重排(draggable)、虚拟化(virtualize)与远程搜索(onSearch)。',
|
|
9
|
-
props: [
|
|
10
|
-
{ name: 'value', type: '(string|number)[]', default: 'undefined', desc: '受控已选 key 数组;提供则为受控' },
|
|
11
|
-
{ name: 'defaultValue', type: '(string|number)[]', default: '[]', desc: '非受控初始已选 key' },
|
|
12
|
-
{ name: 'dataSource', type: 'TransferItem[] | TransferGroup[] | TransferTreeNode[]', default: '[]', desc: '平铺条目(key/label/disabled/group)、分组结构 {title, items}[],或树结构 {key,label,children}[](treeList);树模式下源面板按树渲染,仅叶子可迁移到平铺目标面板,已迁移叶子在源树置灰' },
|
|
13
|
-
{ name: 'filter', type: 'boolean', default: 'true', desc: '是否显示本地搜索框' },
|
|
14
|
-
{ name: 'searchPlaceholder', type: 'string', default: "'搜索'" },
|
|
15
|
-
{ name: 'size', type: "'small'|'default'|'large'", default: 'default' },
|
|
16
|
-
{ name: 'status', type: "'default'|'warning'|'error'", default: 'default' },
|
|
17
|
-
{ name: 'disabled', type: 'boolean', default: 'false' },
|
|
18
|
-
{ name: 'showPanelTitle', type: 'boolean', default: 'true', desc: '是否显示面板标题与计数' },
|
|
19
|
-
{ name: 'titles', type: '[string, string]', default: "['源', '已选']" },
|
|
20
|
-
{ name: 'oneWay', type: 'boolean', default: 'false', desc: '单向迁移:仅左→右;目标项各带「移除」按钮移回左侧,不显示右→左批量按钮' },
|
|
21
|
-
{ name: 'draggable', type: 'boolean', default: 'false', desc: '目标(已选)列项可鼠标拖拽重排(HTML5 DnD);新顺序经 reorder 纯函数算出仅通过 onChange 通知,受控 value 不回写' },
|
|
22
|
-
{ name: 'virtualize', type: 'boolean', default: 'false', desc: '虚拟化两侧平铺面板:大数据下仅渲染视口内项(复用 core fixedRange);分组/树源面板回退全量渲染' },
|
|
23
|
-
{ name: 'itemHeight', type: 'number', default: '32', desc: '虚拟化行高(px),需与实际行高一致' },
|
|
24
|
-
{ name: 'onSearch', type: "(query: string, direction: 'left'|'right') => void", default: 'undefined', desc: '远程搜索:提供后切换远程模式,输入防抖(searchDebounce ms)回调并由外部更新 dataSource,本地不再过滤' },
|
|
25
|
-
{ name: 'loading', type: 'boolean', default: 'false', desc: '远程加载中:每侧列表顶部显示 spinner 行' },
|
|
26
|
-
{ name: 'searchDebounce', type: 'number', default: '300', desc: 'onSearch 防抖毫秒' },
|
|
27
|
-
{ name: 'onChange', type: '(targetKeys: (string|number)[]) => void', default: 'undefined' },
|
|
28
|
-
{ name: 'type', type: "'list'|'groupList'|'treeList'", default: "'list'", desc: '数据形态:平铺/分组/树' },
|
|
29
|
-
{ name: 'emptyContent', type: '{ left?: Snippet|string; right?: Snippet|string; search?: Snippet|string }', default: 'undefined', desc: '自定义空态' },
|
|
30
|
-
{ name: 'inputProps', type: 'object', default: 'undefined', desc: '透传给搜索框 Input 的额外参数' },
|
|
31
|
-
{ name: 'treeProps', type: 'object', default: 'undefined', desc: 'type=treeList 时透传给左侧 Tree 组件的参数' },
|
|
32
|
-
{ name: 'showPath', type: 'boolean', default: 'false', desc: 'type=treeList 时右侧已选项显示完整路径' },
|
|
33
|
-
{ name: 'pagination', type: '{ pageSize?: number; currentPage?: number; defaultCurrentPage?: number; onPageChange?: (page) => void }', default: 'undefined', desc: '左侧面板分页(仅 list/groupList)' },
|
|
34
|
-
{ name: 'onSelect', type: '(item: TransferItem) => void', default: 'undefined', desc: '勾选单项时回调' },
|
|
35
|
-
{ name: 'onDeselect', type: '(item: TransferItem) => void', default: 'undefined', desc: '取消勾选单项时回调' },
|
|
36
|
-
{ name: 'renderSourceItem', type: 'Snippet<[{item, onChange, checked}]>', default: 'undefined', desc: '自定义左侧条目渲染' },
|
|
37
|
-
{ name: 'renderSelectedItem', type: 'Snippet<[{item, onRemove, sortableHandle}]>', default: 'undefined', desc: '自定义右侧条目渲染' },
|
|
38
|
-
{ name: 'renderSourceHeader', type: 'Snippet<[SourceHeaderProps]>', default: 'undefined', desc: '自定义左侧面板头部' },
|
|
39
|
-
{ name: 'renderSelectedHeader', type: 'Snippet<[SelectedHeaderProps]>', default: 'undefined', desc: '自定义右侧面板头部' },
|
|
40
|
-
{ name: 'renderSourcePanel', type: 'Snippet<[SourcePanelProps]>', default: 'undefined', desc: '完全自定义左侧面板' },
|
|
41
|
-
{ name: 'renderSelectedPanel', type: 'Snippet<[SelectedPanelProps]>', default: 'undefined', desc: '完全自定义右侧面板' },
|
|
42
|
-
],
|
|
43
|
-
a11y: {
|
|
44
|
-
role: 'group',
|
|
45
|
-
pattern: 'dual-listbox',
|
|
46
|
-
notes: [
|
|
47
|
-
'容器 role=group;每侧平铺列表 role=listbox + aria-multiselectable,aria-labelledby 指向栏标题',
|
|
48
|
-
'条目 role=option + aria-selected + aria-disabled,roving tabindex(每个 listbox 单一 Tab 停靠点)',
|
|
49
|
-
'列内键盘:↑↓ 漫游、Home/End 跳首末、Space 切换勾选、Shift+↑↓/Shift+Click 范围选择、Enter 移动到对侧',
|
|
50
|
-
'移动后焦点保留在源列表相邻 option;移动经 useLiveAnnouncer 播报',
|
|
51
|
-
'移动按钮有 aria-label;分组/树面板保留原 Checkbox 语义',
|
|
52
|
-
],
|
|
53
|
-
},
|
|
54
|
-
tokens: ['--cd-transfer-*', '--cd-focus-ring', '--cd-color-*', '--cd-spacing-*'],
|
|
55
|
-
} as const;
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { computeInsertSide, reorder } from './reorder.js';
|
|
3
|
-
|
|
4
|
-
describe('transfer/computeInsertSide', () => {
|
|
5
|
-
it('上半区 → before,下半区 → after,中线归 after', () => {
|
|
6
|
-
expect(computeInsertSide(0, 40)).toBe('before');
|
|
7
|
-
expect(computeInsertSide(19, 40)).toBe('before');
|
|
8
|
-
expect(computeInsertSide(20, 40)).toBe('after');
|
|
9
|
-
expect(computeInsertSide(39, 40)).toBe('after');
|
|
10
|
-
});
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
describe('transfer/reorder', () => {
|
|
14
|
-
const base = ['a', 'b', 'c', 'd'];
|
|
15
|
-
|
|
16
|
-
it('前移:把 c 放到 a 之前', () => {
|
|
17
|
-
expect(reorder(base, 2, 0, 'before')).toEqual(['c', 'a', 'b', 'd']);
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it('后移:把 a 放到 c 之后', () => {
|
|
21
|
-
expect(reorder(base, 0, 2, 'after')).toEqual(['b', 'c', 'a', 'd']);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('相邻互换:a 放到 b 之后', () => {
|
|
25
|
-
expect(reorder(base, 0, 1, 'after')).toEqual(['b', 'a', 'c', 'd']);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it('移动后位置不变 → 返回浅拷贝且等值', () => {
|
|
29
|
-
const out = reorder(base, 1, 1, 'before');
|
|
30
|
-
expect(out).toEqual(base);
|
|
31
|
-
expect(out).not.toBe(base);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it('放到自身之后等价于不动', () => {
|
|
35
|
-
expect(reorder(base, 1, 0, 'after')).toEqual(base);
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it('越界返回浅拷贝', () => {
|
|
39
|
-
expect(reorder(base, -1, 2, 'before')).toEqual(base);
|
|
40
|
-
expect(reorder(base, 0, 9, 'after')).toEqual(base);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it('不可变:不修改入参', () => {
|
|
44
|
-
const copy = base.slice();
|
|
45
|
-
reorder(base, 0, 3, 'after');
|
|
46
|
-
expect(base).toEqual(copy);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('末位拖到首位之前', () => {
|
|
50
|
-
expect(reorder(base, 3, 0, 'before')).toEqual(['d', 'a', 'b', 'c']);
|
|
51
|
-
});
|
|
52
|
-
});
|
package/src/transfer/reorder.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Transfer 目标列拖拽重排的纯函数 (红线 #2):不触碰组件状态,仅做数组计算,便于单测。
|
|
3
|
-
* 目标列为垂直列表,故插入侧以指针在目标项内的「垂直」位置判定。
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/** dragover 时根据指针在目标项内的垂直位置判断插入在其「前」或「后」。 */
|
|
7
|
-
export type InsertSide = 'before' | 'after';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* 以目标项中线为界:指针在上半区插入到目标之前,下半区插入到目标之后。
|
|
11
|
-
* @param offsetY 指针相对目标项上边缘的垂直偏移
|
|
12
|
-
* @param height 目标项高度
|
|
13
|
-
*/
|
|
14
|
-
export function computeInsertSide(offsetY: number, height: number): InsertSide {
|
|
15
|
-
return offsetY < height / 2 ? 'before' : 'after';
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* 把 `from` 处的元素移动到目标 `to` 的 `before`/`after` 侧,返回新数组(不可变)。
|
|
20
|
-
* 越界或目标即自身(移动后位置不变)时原样返回原数组的浅拷贝。
|
|
21
|
-
*/
|
|
22
|
-
export function reorder<T>(
|
|
23
|
-
list: readonly T[],
|
|
24
|
-
from: number,
|
|
25
|
-
to: number,
|
|
26
|
-
side: InsertSide,
|
|
27
|
-
): T[] {
|
|
28
|
-
const n = list.length;
|
|
29
|
-
if (from < 0 || from >= n || to < 0 || to >= n) return list.slice();
|
|
30
|
-
|
|
31
|
-
// 目标插入下标(在「移除 from 之前」的坐标系中)。
|
|
32
|
-
let insert = side === 'before' ? to : to + 1;
|
|
33
|
-
// 移除被拖项后,位于其右侧的插入点需左移一位。
|
|
34
|
-
if (from < insert) insert -= 1;
|
|
35
|
-
|
|
36
|
-
if (insert === from) return list.slice();
|
|
37
|
-
|
|
38
|
-
const next = list.slice();
|
|
39
|
-
const removed = next.splice(from, 1);
|
|
40
|
-
next.splice(insert, 0, ...removed);
|
|
41
|
-
return next;
|
|
42
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { collectLeafKeys, flattenLeaves, isTreeData } from './tree.js';
|
|
3
|
-
import type { TransferItem, TransferTreeNode } from './types.js';
|
|
4
|
-
|
|
5
|
-
describe('transfer/tree', () => {
|
|
6
|
-
const tree: TransferTreeNode[] = [
|
|
7
|
-
{
|
|
8
|
-
key: 'east',
|
|
9
|
-
label: '华东',
|
|
10
|
-
children: [
|
|
11
|
-
{ key: 'hz', label: '杭州' },
|
|
12
|
-
{ key: 'sh', label: '上海' },
|
|
13
|
-
],
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
key: 'south',
|
|
17
|
-
label: '华南',
|
|
18
|
-
disabled: true,
|
|
19
|
-
children: [{ key: 'gz', label: '广州' }],
|
|
20
|
-
},
|
|
21
|
-
{ key: 'solo', label: '独立项' },
|
|
22
|
-
];
|
|
23
|
-
const flat: TransferItem[] = [
|
|
24
|
-
{ key: 'a', label: '北京' },
|
|
25
|
-
{ key: 'b', label: '上海' },
|
|
26
|
-
];
|
|
27
|
-
|
|
28
|
-
it('isTreeData detects tree vs flat', () => {
|
|
29
|
-
expect(isTreeData(tree)).toBe(true);
|
|
30
|
-
expect(isTreeData(flat)).toBe(false);
|
|
31
|
-
expect(isTreeData([])).toBe(false);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it('collectLeafKeys returns only leaves in document order', () => {
|
|
35
|
-
expect(collectLeafKeys(tree)).toEqual(['hz', 'sh', 'gz', 'solo']);
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it('flattenLeaves returns leaf items and inherits parent disabled', () => {
|
|
39
|
-
const leaves = flattenLeaves(tree);
|
|
40
|
-
expect(leaves.map((l) => l.key)).toEqual(['hz', 'sh', 'gz', 'solo']);
|
|
41
|
-
expect(leaves.find((l) => l.key === 'gz')?.disabled).toBe(true);
|
|
42
|
-
expect(leaves.find((l) => l.key === 'hz')?.disabled).toBe(false);
|
|
43
|
-
});
|
|
44
|
-
});
|
package/src/transfer/tree.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import type { TransferItem, TransferTreeNode } from './types.js';
|
|
2
|
-
|
|
3
|
-
type Key = string | number;
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* A tree data source is an array whose entries carry `children` somewhere, or
|
|
7
|
-
* more precisely: entries that look like tree nodes (have `key`+`label`) AND at
|
|
8
|
-
* least one of them declares a `children` field. We accept a single root with
|
|
9
|
-
* children too. Flat `TransferItem[]` has no `children`, so this stays false and
|
|
10
|
-
* backward-compatible behavior is untouched.
|
|
11
|
-
*/
|
|
12
|
-
export function isTreeData(
|
|
13
|
-
dataSource: readonly unknown[],
|
|
14
|
-
): dataSource is TransferTreeNode[] {
|
|
15
|
-
return dataSource.some(
|
|
16
|
-
(n) =>
|
|
17
|
-
!!n &&
|
|
18
|
-
typeof n === 'object' &&
|
|
19
|
-
Array.isArray((n as TransferTreeNode).children),
|
|
20
|
-
);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/** Collect the keys of all leaf nodes (no children) under the tree, in order. */
|
|
24
|
-
export function collectLeafKeys(data: readonly TransferTreeNode[]): Key[] {
|
|
25
|
-
const out: Key[] = [];
|
|
26
|
-
function walk(nodes: readonly TransferTreeNode[]): void {
|
|
27
|
-
for (const node of nodes) {
|
|
28
|
-
if (node.children && node.children.length > 0) walk(node.children);
|
|
29
|
-
else out.push(node.key);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
walk(data);
|
|
33
|
-
return out;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Flatten the tree into a flat `TransferItem[]` of leaves only (the migratable
|
|
38
|
-
* units), preserving document order. Used to render the target panel and to map
|
|
39
|
-
* a leaf key back to its label.
|
|
40
|
-
*/
|
|
41
|
-
export function flattenLeaves(data: readonly TransferTreeNode[]): TransferItem[] {
|
|
42
|
-
const out: TransferItem[] = [];
|
|
43
|
-
function walk(nodes: readonly TransferTreeNode[], parentDisabled: boolean): void {
|
|
44
|
-
for (const node of nodes) {
|
|
45
|
-
const disabled = parentDisabled || !!node.disabled;
|
|
46
|
-
if (node.children && node.children.length > 0) walk(node.children, disabled);
|
|
47
|
-
else out.push({ key: node.key, label: node.label, disabled });
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
walk(data, false);
|
|
51
|
-
return out;
|
|
52
|
-
}
|
package/src/transfer/types.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
export interface TransferItem {
|
|
2
|
-
key: string | number;
|
|
3
|
-
label: string;
|
|
4
|
-
disabled?: boolean;
|
|
5
|
-
/** Optional group name; items sharing a group render under one group header. */
|
|
6
|
-
group?: string;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
/** Grouped data source: each group renders a header + its items. */
|
|
10
|
-
export interface TransferGroup {
|
|
11
|
-
/** Group title shown as the group header. */
|
|
12
|
-
title: string;
|
|
13
|
-
items: TransferItem[];
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/** A computed group used for rendering one panel side. */
|
|
17
|
-
export interface TransferRenderGroup {
|
|
18
|
-
title: string;
|
|
19
|
-
items: TransferItem[];
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Tree data source node (`treeList`): the source panel renders a tree. Checking a
|
|
24
|
-
* parent conducts to all enabled leaf descendants; only leaf keys are migrated to
|
|
25
|
-
* the target panel (which stays flat). A node with `children` is a parent.
|
|
26
|
-
*/
|
|
27
|
-
export interface TransferTreeNode {
|
|
28
|
-
key: string | number;
|
|
29
|
-
label: string;
|
|
30
|
-
disabled?: boolean;
|
|
31
|
-
children?: TransferTreeNode[];
|
|
32
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
// Tree a11y:层级树控件。
|
|
2
|
-
// 容器 role=tree(aria-multiselectable),每行 role=treeitem 含 aria-level/expanded/selected。
|
|
3
|
-
import { describe, it, expect } from 'vitest';
|
|
4
|
-
import { renderWithLocale, expectNoAxeViolations } from '../test-utils/a11y.js';
|
|
5
|
-
import Tree from './Tree.svelte';
|
|
6
|
-
|
|
7
|
-
const treeData = [
|
|
8
|
-
{
|
|
9
|
-
key: 'parent',
|
|
10
|
-
label: 'Parent',
|
|
11
|
-
children: [
|
|
12
|
-
{ key: 'child-1', label: 'Child 1' },
|
|
13
|
-
{ key: 'child-2', label: 'Child 2' },
|
|
14
|
-
],
|
|
15
|
-
},
|
|
16
|
-
{ key: 'leaf', label: 'Leaf' },
|
|
17
|
-
];
|
|
18
|
-
|
|
19
|
-
describe('Tree a11y', () => {
|
|
20
|
-
it('默认渲染:role=tree + treeitem,无 axe violations', async () => {
|
|
21
|
-
const { container } = renderWithLocale(Tree, {
|
|
22
|
-
props: { treeData, ariaLabel: 'File tree' },
|
|
23
|
-
});
|
|
24
|
-
const tree = container.querySelector('[role="tree"]');
|
|
25
|
-
expect(tree).not.toBeNull();
|
|
26
|
-
expect(tree?.getAttribute('aria-label')).toBe('File tree');
|
|
27
|
-
expect(container.querySelectorAll('[role="treeitem"]').length).toBeGreaterThanOrEqual(2);
|
|
28
|
-
await expectNoAxeViolations(container);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it('展开节点:aria-expanded 反映展开态 + aria-level', async () => {
|
|
32
|
-
const { container } = renderWithLocale(Tree, {
|
|
33
|
-
props: { treeData, ariaLabel: 'Tree', defaultExpandAll: true },
|
|
34
|
-
});
|
|
35
|
-
const expanded = container.querySelector('[role="treeitem"][aria-expanded="true"]');
|
|
36
|
-
expect(expanded?.textContent).toContain('Parent');
|
|
37
|
-
expect(expanded?.getAttribute('aria-level')).toBe('1');
|
|
38
|
-
// 展开后子节点可见,aria-level=2
|
|
39
|
-
const child = Array.from(container.querySelectorAll('[role="treeitem"]')).find((el) =>
|
|
40
|
-
el.textContent?.includes('Child 1'),
|
|
41
|
-
);
|
|
42
|
-
expect(child?.getAttribute('aria-level')).toBe('2');
|
|
43
|
-
await expectNoAxeViolations(container);
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('checkable:treeitem aria-checked + 容器 aria-multiselectable', async () => {
|
|
47
|
-
const { container } = renderWithLocale(Tree, {
|
|
48
|
-
props: { treeData, ariaLabel: 'Tree', checkable: true, defaultExpandAll: true },
|
|
49
|
-
});
|
|
50
|
-
expect(container.querySelector('[role="tree"]')?.getAttribute('aria-multiselectable')).toBe('true');
|
|
51
|
-
expect(container.querySelector('[role="treeitem"][aria-checked]')).not.toBeNull();
|
|
52
|
-
await expectNoAxeViolations(container);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('选中态:selectable 节点 aria-selected', async () => {
|
|
56
|
-
const { container } = renderWithLocale(Tree, {
|
|
57
|
-
props: { treeData, ariaLabel: 'Tree', defaultValue: 'leaf' },
|
|
58
|
-
});
|
|
59
|
-
const selected = container.querySelector('[role="treeitem"][aria-selected="true"]');
|
|
60
|
-
expect(selected?.textContent).toContain('Leaf');
|
|
61
|
-
await expectNoAxeViolations(container);
|
|
62
|
-
});
|
|
63
|
-
});
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
// Tree 键盘 e2e(browser project / 真实 chromium),aria-activedescendant 模型。
|
|
2
|
-
// Tree 遵循 WAI-ARIA APG Tree View:单一 tab stop(role=tree 容器 tabindex=0)+
|
|
3
|
-
// aria-activedescendant 漫游。焦点恒留在容器上,treeitem tabindex=-1 从不真实聚焦,
|
|
4
|
-
// 高亮由容器 aria-activedescendant 指向的 treeitem id 表达。故断言 activedescendant
|
|
5
|
-
// 指向的 treeitem 文本变化,而非 toHaveFocus(参照 TreeSelect 样板)。
|
|
6
|
-
// 1. 容器真实聚焦后首次 ↓ 高亮首项;↑↓ 相邻移动;Home/End 跳可见列表首/末。
|
|
7
|
-
// 2. typeahead:输入字符按 label 前缀跳到匹配节点(核心价值)。
|
|
8
|
-
// 3. `*` 展开当前层级全部可展开同级节点(这里仅 Date 可展开 → 其子节点变可见)。
|
|
9
|
-
import { describe, it, expect } from 'vitest';
|
|
10
|
-
import { page } from 'vitest/browser';
|
|
11
|
-
import { renderKbdFixture, userEvent } from '../test-utils/kbd.js';
|
|
12
|
-
import TreeKbdFixture from './TreeKbdFixture.svelte';
|
|
13
|
-
|
|
14
|
-
function loc(el: Element) {
|
|
15
|
-
return page.elementLocator(el);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// typeahead 缓冲超时为 600ms:连续按键在缓冲内累积为前缀(c+b → 'cb' 无匹配)。
|
|
19
|
-
// 测「单字符独立跳转」须在每次跳转间等待缓冲清空,故 sleep > 超时。
|
|
20
|
-
const TYPEAHEAD_TIMEOUT = 600;
|
|
21
|
-
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
|
|
22
|
-
|
|
23
|
-
// 读 role=tree 容器 aria-activedescendant 指向的 treeitem,断言其可见 label 文本。
|
|
24
|
-
function activeNodeText(tree: HTMLElement): string | null {
|
|
25
|
-
const id = tree.getAttribute('aria-activedescendant');
|
|
26
|
-
if (!id) return null;
|
|
27
|
-
const el = document.getElementById(id);
|
|
28
|
-
// label 在 .cd-tree__label 内(含 switcher/icon 等兄弟),只取 label 文本。
|
|
29
|
-
return el?.querySelector('.cd-tree__label')?.textContent?.trim() ?? null;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
describe('Tree 键盘 e2e(aria-activedescendant roving + typeahead)', () => {
|
|
33
|
-
it('容器聚焦 + ↑↓/Home/End 移高亮(activedescendant)', async () => {
|
|
34
|
-
const { baseElement } = renderKbdFixture(TreeKbdFixture);
|
|
35
|
-
|
|
36
|
-
const tree = baseElement.querySelector('[role="tree"]') as HTMLElement;
|
|
37
|
-
expect(tree).not.toBeNull();
|
|
38
|
-
expect(tree.tabIndex).toBe(0);
|
|
39
|
-
const items = Array.from(tree.querySelectorAll<HTMLElement>('[role="treeitem"]'));
|
|
40
|
-
// 顶层 4 项可见(Date 未展开)。
|
|
41
|
-
expect(items.length).toBe(4);
|
|
42
|
-
expect(items.every((n) => n.tabIndex === -1)).toBe(true);
|
|
43
|
-
|
|
44
|
-
// 容器真实聚焦(单一 tab stop)。
|
|
45
|
-
tree.focus();
|
|
46
|
-
await expect.element(loc(tree)).toHaveFocus();
|
|
47
|
-
|
|
48
|
-
// 1. 首次 ↓ 高亮首项 Apple。
|
|
49
|
-
await userEvent.keyboard('{ArrowDown}');
|
|
50
|
-
expect(activeNodeText(tree)).toBe('Apple');
|
|
51
|
-
await userEvent.keyboard('{ArrowDown}');
|
|
52
|
-
expect(activeNodeText(tree)).toBe('Banana');
|
|
53
|
-
await userEvent.keyboard('{ArrowUp}');
|
|
54
|
-
expect(activeNodeText(tree)).toBe('Apple');
|
|
55
|
-
|
|
56
|
-
// End 跳末项 Date;Home 回首项 Apple。焦点始终在容器上(activedescendant 模型)。
|
|
57
|
-
await userEvent.keyboard('{End}');
|
|
58
|
-
expect(activeNodeText(tree)).toBe('Date');
|
|
59
|
-
await userEvent.keyboard('{Home}');
|
|
60
|
-
expect(activeNodeText(tree)).toBe('Apple');
|
|
61
|
-
await expect.element(loc(tree)).toHaveFocus();
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it('typeahead 输入字符跳到首字母匹配节点 + `*` 展开同级', async () => {
|
|
65
|
-
const { baseElement } = renderKbdFixture(TreeKbdFixture);
|
|
66
|
-
|
|
67
|
-
const tree = baseElement.querySelector('[role="tree"]') as HTMLElement;
|
|
68
|
-
tree.focus();
|
|
69
|
-
await expect.element(loc(tree)).toHaveFocus();
|
|
70
|
-
|
|
71
|
-
// 2. typeahead:无活动项时输入 'c' → 跳到 Cherry。
|
|
72
|
-
await userEvent.keyboard('c');
|
|
73
|
-
expect(activeNodeText(tree)).toBe('Cherry');
|
|
74
|
-
// 等缓冲清空后输入 'b' → 跳到 Banana(否则 'c'+'b' 累积为前缀 'cb' 无匹配)。
|
|
75
|
-
await sleep(TYPEAHEAD_TIMEOUT + 100);
|
|
76
|
-
await userEvent.keyboard('b');
|
|
77
|
-
expect(activeNodeText(tree)).toBe('Banana');
|
|
78
|
-
// 等缓冲清空后输入 'd' → 跳到 Date。
|
|
79
|
-
await sleep(TYPEAHEAD_TIMEOUT + 100);
|
|
80
|
-
await userEvent.keyboard('d');
|
|
81
|
-
expect(activeNodeText(tree)).toBe('Date');
|
|
82
|
-
|
|
83
|
-
// 3. `*` 展开当前层级全部可展开同级:Date 展开 → 子节点 Deglet/Medjool 可见。
|
|
84
|
-
await userEvent.keyboard('*');
|
|
85
|
-
const labels = Array.from(
|
|
86
|
-
tree.querySelectorAll<HTMLElement>('.cd-tree__label'),
|
|
87
|
-
).map((n) => n.textContent?.trim());
|
|
88
|
-
expect(labels).toContain('Deglet');
|
|
89
|
-
expect(labels).toContain('Medjool');
|
|
90
|
-
});
|
|
91
|
-
});
|