@qw-ui/core 0.3.0-next.40 → 0.3.0-next.43
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/README.md +21 -37
- package/dist/action-sheet/action-sheet.d.ts +110 -0
- package/dist/action-sheet/index.d.ts +2 -0
- package/dist/action-sheet/index.js +2 -0
- package/dist/action-sheet-Cvcr1S_m.js +183 -0
- package/dist/action-sheet-Cvcr1S_m.js.map +1 -0
- package/dist/area-picker/area-picker.d.ts +113 -0
- package/dist/area-picker/index.d.ts +1 -0
- package/dist/area-picker/index.js +348 -0
- package/dist/area-picker/index.js.map +1 -0
- package/dist/aria-description-CimD2M_C.js +13 -0
- package/dist/aria-description-CimD2M_C.js.map +1 -0
- package/dist/aria-description.d.ts +2 -0
- package/dist/avatar/avatar-load.d.ts +76 -0
- package/dist/avatar/avatar.d.ts +22 -5
- package/dist/avatar/index.d.ts +1 -0
- package/dist/avatar/index.js +57 -18
- package/dist/avatar/index.js.map +1 -1
- package/dist/avatar-load-w9dq05oV.js +139 -0
- package/dist/avatar-load-w9dq05oV.js.map +1 -0
- package/dist/back-top/back-top.d.ts +77 -0
- package/dist/back-top/index.d.ts +1 -0
- package/dist/back-top/index.js +189 -0
- package/dist/back-top/index.js.map +1 -0
- package/dist/badge/badge.d.ts +9 -0
- package/dist/badge/index.js +14 -1
- package/dist/badge/index.js.map +1 -1
- package/dist/button/button.d.ts +13 -0
- package/dist/button/index.js +3 -5
- package/dist/button/index.js.map +1 -1
- package/dist/calendar/calendar.d.ts +100 -0
- package/dist/calendar/index.d.ts +1 -0
- package/dist/calendar/index.js +2 -0
- package/dist/calendar-CmpK3stz.js +363 -0
- package/dist/calendar-CmpK3stz.js.map +1 -0
- package/dist/card/card.d.ts +68 -0
- package/dist/card/index.d.ts +2 -0
- package/dist/card/index.js +2 -0
- package/dist/card-DRtWa6Cr.js +107 -0
- package/dist/card-DRtWa6Cr.js.map +1 -0
- package/dist/cascader/cascader.d.ts +115 -0
- package/dist/cascader/index.d.ts +1 -0
- package/dist/cascader/index.js +2 -0
- package/dist/cascader-D-xMjs7P.js +333 -0
- package/dist/cascader-D-xMjs7P.js.map +1 -0
- package/dist/cell/cell.d.ts +41 -0
- package/dist/cell/index.d.ts +1 -0
- package/dist/cell/index.js +43 -0
- package/dist/cell/index.js.map +1 -0
- package/dist/check-list/check-list.d.ts +78 -0
- package/dist/check-list/index.d.ts +2 -0
- package/dist/check-list/index.js +2 -0
- package/dist/check-list-BvZHQt5w.js +60 -0
- package/dist/check-list-BvZHQt5w.js.map +1 -0
- package/dist/checkbox/checkbox.d.ts +59 -0
- package/dist/checkbox/index.d.ts +2 -0
- package/dist/checkbox/index.js +2 -0
- package/dist/checkbox-BlndJrz5.js +127 -0
- package/dist/checkbox-BlndJrz5.js.map +1 -0
- package/dist/checkbox-group/checkbox-group.d.ts +86 -0
- package/dist/checkbox-group/index.d.ts +3 -0
- package/dist/checkbox-group/index.js +2 -0
- package/dist/checkbox-group-gGfsTv-e.js +223 -0
- package/dist/checkbox-group-gGfsTv-e.js.map +1 -0
- package/dist/choice-group-C4c9m0qe.js +373 -0
- package/dist/choice-group-C4c9m0qe.js.map +1 -0
- package/dist/circle/circle.d.ts +97 -0
- package/dist/circle/index.d.ts +1 -0
- package/dist/circle/index.js +119 -0
- package/dist/circle/index.js.map +1 -0
- package/dist/collapse/collapse.d.ts +98 -0
- package/dist/collapse/index.d.ts +2 -0
- package/dist/collapse/index.js +2 -0
- package/dist/collapse-B969h7-H.js +226 -0
- package/dist/collapse-B969h7-H.js.map +1 -0
- package/dist/countdown/countdown.d.ts +114 -0
- package/dist/countdown/index.d.ts +1 -0
- package/dist/countdown/index.js +309 -0
- package/dist/countdown/index.js.map +1 -0
- package/dist/date-picker/date-picker.d.ts +168 -0
- package/dist/date-picker/index.d.ts +1 -0
- package/dist/date-picker/index.js +401 -0
- package/dist/date-picker/index.js.map +1 -0
- package/dist/descriptions/descriptions.d.ts +69 -0
- package/dist/descriptions/index.d.ts +1 -0
- package/dist/descriptions/index.js +86 -0
- package/dist/descriptions/index.js.map +1 -0
- package/dist/dialog/dialog.d.ts +32 -3
- package/dist/dialog/index.js +58 -3
- package/dist/dialog/index.js.map +1 -1
- package/dist/divider/divider.d.ts +18 -2
- package/dist/divider/index.js +20 -2
- package/dist/divider/index.js.map +1 -1
- package/dist/dropdown/dropdown.d.ts +172 -0
- package/dist/dropdown/index.d.ts +2 -0
- package/dist/dropdown/index.js +467 -0
- package/dist/dropdown/index.js.map +1 -0
- package/dist/ellipsis/ellipsis-layout.d.ts +34 -0
- package/dist/ellipsis/ellipsis.d.ts +88 -0
- package/dist/ellipsis/index.d.ts +2 -0
- package/dist/ellipsis/index.js +320 -0
- package/dist/ellipsis/index.js.map +1 -0
- package/dist/empty/empty-illustration.d.ts +3 -0
- package/dist/empty/empty.d.ts +43 -1
- package/dist/empty/index.js +2 -21
- package/dist/empty-CAgyvhUI.js +166 -0
- package/dist/empty-CAgyvhUI.js.map +1 -0
- package/dist/field/field.d.ts +95 -0
- package/dist/field/index.d.ts +2 -0
- package/dist/field/index.js +2 -0
- package/dist/field-DMHGIMZF.js +241 -0
- package/dist/field-DMHGIMZF.js.map +1 -0
- package/dist/floating-bubble/floating-bubble.d.ts +116 -0
- package/dist/floating-bubble/index.d.ts +1 -0
- package/dist/floating-bubble/index.js +333 -0
- package/dist/floating-bubble/index.js.map +1 -0
- package/dist/floating-panel/floating-panel.d.ts +80 -0
- package/dist/floating-panel/index.d.ts +2 -0
- package/dist/floating-panel/index.js +2 -0
- package/dist/floating-panel-Cbm5njBJ.js +363 -0
- package/dist/floating-panel-Cbm5njBJ.js.map +1 -0
- package/dist/footer/footer.d.ts +94 -0
- package/dist/footer/index.d.ts +1 -0
- package/dist/footer/index.js +154 -0
- package/dist/footer/index.js.map +1 -0
- package/dist/form/connect.d.ts +6 -0
- package/dist/form/form.d.ts +100 -0
- package/dist/form/ids.d.ts +14 -0
- package/dist/form/index.d.ts +13 -0
- package/dist/form/index.js +3 -0
- package/dist/form/methods.d.ts +5 -0
- package/dist/form/model.d.ts +24 -0
- package/dist/form/native.d.ts +25 -0
- package/dist/form/rules.d.ts +40 -0
- package/dist/form/ssr.d.ts +7 -0
- package/dist/form/types.d.ts +150 -0
- package/dist/form-BAGkIEMY.js +1354 -0
- package/dist/form-BAGkIEMY.js.map +1 -0
- package/dist/format-BDUY0C_c.js +89 -0
- package/dist/format-BDUY0C_c.js.map +1 -0
- package/dist/gesture-_SRHIvBm.js +30 -0
- package/dist/gesture-_SRHIvBm.js.map +1 -0
- package/dist/grid/grid-item.d.ts +22 -0
- package/dist/grid/grid.d.ts +42 -0
- package/dist/grid/index.d.ts +2 -0
- package/dist/grid/index.js +73 -0
- package/dist/grid/index.js.map +1 -0
- package/dist/icon/icon.d.ts +37 -1
- package/dist/icon/identity.d.ts +3 -0
- package/dist/icon/index.js +2 -20
- package/dist/icon-Cgdbnk1u.js +77 -0
- package/dist/icon-Cgdbnk1u.js.map +1 -0
- package/dist/image/image-load.d.ts +24 -0
- package/dist/image/image.d.ts +45 -8
- package/dist/image/index.d.ts +1 -0
- package/dist/image/index.js +116 -14
- package/dist/image/index.js.map +1 -1
- package/dist/image-preview/image-preview.d.ts +124 -0
- package/dist/image-preview/index.d.ts +1 -0
- package/dist/image-preview/index.js +450 -0
- package/dist/image-preview/index.js.map +1 -0
- package/dist/index-bar/index-bar.d.ts +121 -0
- package/dist/index-bar/index.d.ts +1 -0
- package/dist/index-bar/index.js +386 -0
- package/dist/index-bar/index.js.map +1 -0
- package/dist/index.d.ts +107 -14
- package/dist/index.js +148 -14
- package/dist/index.js.map +1 -0
- package/dist/infinite-scroll/index.d.ts +1 -0
- package/dist/infinite-scroll/index.js +248 -0
- package/dist/infinite-scroll/index.js.map +1 -0
- package/dist/infinite-scroll/infinite-scroll.d.ts +95 -0
- package/dist/input/index.js +181 -22
- package/dist/input/index.js.map +1 -1
- package/dist/input/input.d.ts +44 -1
- package/dist/layer-IpFrl5--.js +414 -0
- package/dist/layer-IpFrl5--.js.map +1 -0
- package/dist/layout-BRSqi4AQ.js +43 -0
- package/dist/layout-BRSqi4AQ.js.map +1 -0
- package/dist/layout.d.ts +13 -0
- package/dist/list/index.d.ts +2 -0
- package/dist/list/index.js +2 -0
- package/dist/list/list.d.ts +30 -0
- package/dist/list-6-iz-Irh.js +28 -0
- package/dist/list-6-iz-Irh.js.map +1 -0
- package/dist/loading/index.js +45 -2
- package/dist/loading/index.js.map +1 -1
- package/dist/loading/loading.d.ts +45 -2
- package/dist/modal-dialog-machine-CF9_z3Dm.js +487 -0
- package/dist/modal-dialog-machine-CF9_z3Dm.js.map +1 -0
- package/dist/modal-dialog-machine.d.ts +21 -0
- package/dist/modal-dismissable-lifetime.d.ts +21 -0
- package/dist/modal-registry.d.ts +24 -0
- package/dist/modal-render-hydration.d.ts +35 -0
- package/dist/modal-render-runtime.d.ts +19 -0
- package/dist/modal-render-scope.d.ts +63 -0
- package/dist/nav-bar/index.d.ts +1 -0
- package/dist/nav-bar/index.js +115 -0
- package/dist/nav-bar/index.js.map +1 -0
- package/dist/nav-bar/nav-bar.d.ts +76 -0
- package/dist/notice-bar/index.d.ts +2 -0
- package/dist/notice-bar/index.js +2 -0
- package/dist/notice-bar/notice-bar.d.ts +103 -0
- package/dist/notice-bar-DMpwLvRb.js +231 -0
- package/dist/notice-bar-DMpwLvRb.js.map +1 -0
- package/dist/notify/index.d.ts +1 -0
- package/dist/notify/index.js +251 -0
- package/dist/notify/index.js.map +1 -0
- package/dist/notify/notify.d.ts +123 -0
- package/dist/number-keyboard/index.d.ts +1 -0
- package/dist/number-keyboard/index.js +333 -0
- package/dist/number-keyboard/index.js.map +1 -0
- package/dist/number-keyboard/number-keyboard.d.ts +141 -0
- package/dist/page-indicator/index.d.ts +1 -0
- package/dist/page-indicator/index.js +138 -0
- package/dist/page-indicator/index.js.map +1 -0
- package/dist/page-indicator/page-indicator.d.ts +93 -0
- package/dist/pagination/index.d.ts +1 -0
- package/dist/pagination/index.js +198 -0
- package/dist/pagination/index.js.map +1 -0
- package/dist/pagination/pagination.d.ts +125 -0
- package/dist/password-input/index.d.ts +1 -0
- package/dist/password-input/index.js +317 -0
- package/dist/password-input/index.js.map +1 -0
- package/dist/password-input/password-input.d.ts +144 -0
- package/dist/picker/index.d.ts +8 -0
- package/dist/picker/index.js +2 -0
- package/dist/picker/picker-machine.d.ts +80 -0
- package/dist/picker/picker.d.ts +121 -0
- package/dist/picker/platform.d.ts +84 -0
- package/dist/picker/selection-connect.d.ts +90 -0
- package/dist/picker/selection-model.d.ts +211 -0
- package/dist/picker-BykFntQN.js +1675 -0
- package/dist/picker-BykFntQN.js.map +1 -0
- package/dist/popover/index.d.ts +3 -0
- package/dist/popover/index.js +253 -0
- package/dist/popover/index.js.map +1 -0
- package/dist/popover/layer.d.ts +44 -0
- package/dist/popover/popover.d.ts +104 -0
- package/dist/popover/positioning.d.ts +132 -0
- package/dist/popup/index.d.ts +2 -0
- package/dist/popup/index.js +2 -0
- package/dist/popup/popup.d.ts +60 -0
- package/dist/popup-z5d8IYCt.js +576 -0
- package/dist/popup-z5d8IYCt.js.map +1 -0
- package/dist/portal-BHCNTWhg.js +78 -0
- package/dist/portal-BHCNTWhg.js.map +1 -0
- package/dist/portal.d.ts +61 -0
- package/dist/price/format.d.ts +19 -0
- package/dist/price/index.d.ts +1 -0
- package/dist/price/index.js +154 -0
- package/dist/price/index.js.map +1 -0
- package/dist/price/price.d.ts +88 -0
- package/dist/progress/index.d.ts +1 -0
- package/dist/progress/index.js +2 -0
- package/dist/progress/progress.d.ts +32 -0
- package/dist/progress-f3iYEfdA.js +37 -0
- package/dist/progress-f3iYEfdA.js.map +1 -0
- package/dist/pull-refresh/index.d.ts +1 -0
- package/dist/pull-refresh/index.js +414 -0
- package/dist/pull-refresh/index.js.map +1 -0
- package/dist/pull-refresh/pull-refresh.d.ts +118 -0
- package/dist/radio-group/index.d.ts +3 -0
- package/dist/radio-group/index.js +2 -0
- package/dist/radio-group/radio-group.d.ts +78 -0
- package/dist/radio-group-BOIMuqnS.js +230 -0
- package/dist/radio-group-BOIMuqnS.js.map +1 -0
- package/dist/rate/index.d.ts +1 -0
- package/dist/rate/index.js +2 -0
- package/dist/rate/rate-form.d.ts +28 -0
- package/dist/rate/rate.d.ts +144 -0
- package/dist/rate-5XsU2QkY.js +631 -0
- package/dist/rate-5XsU2QkY.js.map +1 -0
- package/dist/reorder/index.d.ts +1 -0
- package/dist/reorder/index.js +720 -0
- package/dist/reorder/index.js.map +1 -0
- package/dist/reorder/reorder.d.ts +190 -0
- package/dist/result/index.d.ts +1 -0
- package/dist/result/index.js +123 -0
- package/dist/result/index.js.map +1 -0
- package/dist/result/result.d.ts +88 -0
- package/dist/safe-area/index.d.ts +1 -0
- package/dist/safe-area/index.js +42 -0
- package/dist/safe-area/index.js.map +1 -0
- package/dist/safe-area/safe-area.d.ts +28 -0
- package/dist/search-bar/index.js +3 -1
- package/dist/search-bar/index.js.map +1 -1
- package/dist/search-bar/search-bar.d.ts +4 -0
- package/dist/segmented/index.d.ts +2 -0
- package/dist/segmented/index.js +2 -0
- package/dist/segmented/segmented.d.ts +127 -0
- package/dist/segmented-BaU38_L4.js +367 -0
- package/dist/segmented-BaU38_L4.js.map +1 -0
- package/dist/selection-form-BOM_odUk.js +88 -0
- package/dist/selection-form-BOM_odUk.js.map +1 -0
- package/dist/selection-form.d.ts +27 -0
- package/dist/selection-ivXqO1eu.js +55 -0
- package/dist/selection-ivXqO1eu.js.map +1 -0
- package/dist/selection.d.ts +29 -0
- package/dist/selector/choice-group.d.ts +114 -0
- package/dist/selector/index.d.ts +2 -0
- package/dist/selector/index.js +2 -0
- package/dist/selector/selector.d.ts +90 -0
- package/dist/selector-BU2MMJ4N.js +93 -0
- package/dist/selector-BU2MMJ4N.js.map +1 -0
- package/dist/share-sheet/index.d.ts +1 -0
- package/dist/share-sheet/index.js +138 -0
- package/dist/share-sheet/index.js.map +1 -0
- package/dist/share-sheet/share-sheet.d.ts +139 -0
- package/dist/skeleton/index.js +51 -2
- package/dist/skeleton/index.js.map +1 -1
- package/dist/skeleton/skeleton.d.ts +34 -3
- package/dist/slider/index.d.ts +1 -0
- package/dist/slider/index.js +482 -0
- package/dist/slider/index.js.map +1 -0
- package/dist/slider/slider.d.ts +174 -0
- package/dist/space/index.d.ts +1 -0
- package/dist/space/index.js +52 -0
- package/dist/space/index.js.map +1 -0
- package/dist/space/space.d.ts +46 -0
- package/dist/statistic/index.d.ts +1 -0
- package/dist/statistic/index.js +152 -0
- package/dist/statistic/index.js.map +1 -0
- package/dist/statistic/statistic.d.ts +101 -0
- package/dist/stepper/index.js +62 -3
- package/dist/stepper/index.js.map +1 -1
- package/dist/stepper/stepper.d.ts +44 -4
- package/dist/steps/index.d.ts +1 -0
- package/dist/steps/index.js +72 -0
- package/dist/steps/index.js.map +1 -0
- package/dist/steps/steps.d.ts +67 -0
- package/dist/sticky/index.d.ts +1 -0
- package/dist/sticky/index.js +145 -0
- package/dist/sticky/index.js.map +1 -0
- package/dist/sticky/sticky.d.ts +70 -0
- package/dist/swipe-action/index.d.ts +1 -0
- package/dist/swipe-action/index.js +417 -0
- package/dist/swipe-action/index.js.map +1 -0
- package/dist/swipe-action/swipe-action.d.ts +148 -0
- package/dist/swiper/gesture.d.ts +32 -0
- package/dist/swiper/index.d.ts +1 -0
- package/dist/swiper/index.js +2 -0
- package/dist/swiper/swiper.d.ts +177 -0
- package/dist/swiper-BKivDkHp.js +550 -0
- package/dist/swiper-BKivDkHp.js.map +1 -0
- package/dist/switch/index.js +135 -10
- package/dist/switch/index.js.map +1 -1
- package/dist/switch/switch.d.ts +93 -6
- package/dist/tabbar/index.js +46 -1
- package/dist/tabbar/index.js.map +1 -1
- package/dist/tabbar/tabbar.d.ts +50 -0
- package/dist/tabs/index.js +22 -1
- package/dist/tabs/index.js.map +1 -1
- package/dist/tabs/tabs.d.ts +12 -8
- package/dist/tag/index.js +123 -2
- package/dist/tag/index.js.map +1 -1
- package/dist/tag/tag.d.ts +67 -1
- package/dist/textarea/index.d.ts +2 -0
- package/dist/textarea/index.js +2 -242
- package/dist/textarea/platform.d.ts +22 -0
- package/dist/textarea/textarea.d.ts +165 -46
- package/dist/textarea-qbnruDUG.js +775 -0
- package/dist/textarea-qbnruDUG.js.map +1 -0
- package/dist/time-picker/index.d.ts +1 -0
- package/dist/time-picker/index.js +228 -0
- package/dist/time-picker/index.js.map +1 -0
- package/dist/time-picker/time-picker.d.ts +83 -0
- package/dist/timeline/index.d.ts +1 -0
- package/dist/timeline/index.js +131 -0
- package/dist/timeline/index.js.map +1 -0
- package/dist/timeline/timeline.d.ts +79 -0
- package/dist/toast/index.js +47 -4
- package/dist/toast/index.js.map +1 -1
- package/dist/toast/toast.d.ts +26 -3
- package/dist/top-bar/index.js +16 -2
- package/dist/top-bar/index.js.map +1 -1
- package/dist/top-bar/top-bar.d.ts +13 -2
- package/dist/tree-select/index.d.ts +1 -0
- package/dist/tree-select/index.js +512 -0
- package/dist/tree-select/index.js.map +1 -0
- package/dist/tree-select/tree-select.d.ts +215 -0
- package/dist/typography/index.d.ts +1 -0
- package/dist/typography/index.js +82 -0
- package/dist/typography/index.js.map +1 -0
- package/dist/typography/typography.d.ts +54 -0
- package/dist/upload/index.d.ts +1 -0
- package/dist/upload/index.js +458 -0
- package/dist/upload/index.js.map +1 -0
- package/dist/upload/upload.d.ts +172 -0
- package/dist/virtual-list/index.d.ts +1 -0
- package/dist/virtual-list/index.js +445 -0
- package/dist/virtual-list/index.js.map +1 -0
- package/dist/virtual-list/virtual-list.d.ts +160 -0
- package/dist/visual-manifest.d.ts +6 -0
- package/dist/watermark/index.d.ts +1 -0
- package/dist/watermark/index.js +260 -0
- package/dist/watermark/index.js.map +1 -0
- package/dist/watermark/watermark.d.ts +106 -0
- package/package.json +399 -50
- package/dist/empty/index.js.map +0 -1
- package/dist/icon/index.js.map +0 -1
- package/dist/textarea/index.js.map +0 -1
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { type Machine, type Service } from "@zag-js/core";
|
|
2
|
+
import type { NormalizeProps, PropTypes } from "@zag-js/types";
|
|
3
|
+
/** Stable DOM parts shared by every adapter. */
|
|
4
|
+
export declare const UPLOAD_PARTS: readonly ["root", "input", "trigger", "list", "item", "preview", "name", "status", "retry", "cancel", "remove", "live"];
|
|
5
|
+
export declare const UPLOAD_STATUSES: readonly ["pending", "uploading", "done", "error"];
|
|
6
|
+
export type UploadStatus = (typeof UPLOAD_STATUSES)[number];
|
|
7
|
+
/** Serializable list entry. The File itself stays private to Core (used for retry and form sync). */
|
|
8
|
+
export interface UploadItem {
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
size: number;
|
|
12
|
+
type: string;
|
|
13
|
+
status: UploadStatus;
|
|
14
|
+
/** Remote or caller-provided URL; preferred over the Core-owned preview and never revoked by Core. */
|
|
15
|
+
url?: string;
|
|
16
|
+
error?: string;
|
|
17
|
+
/** 0–100, only when the caller reports progress through onProgress. */
|
|
18
|
+
progress?: number;
|
|
19
|
+
}
|
|
20
|
+
export type UploadRejectReason = "accept" | "max-size" | "max-count";
|
|
21
|
+
export interface UploadRejection {
|
|
22
|
+
file: File;
|
|
23
|
+
reason: UploadRejectReason;
|
|
24
|
+
}
|
|
25
|
+
export interface UploadRejectDetails {
|
|
26
|
+
rejections: UploadRejection[];
|
|
27
|
+
}
|
|
28
|
+
export interface UploadChangeDetails {
|
|
29
|
+
value: UploadItem[];
|
|
30
|
+
}
|
|
31
|
+
export interface UploadResult {
|
|
32
|
+
url?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface UploadRequestContext {
|
|
35
|
+
/** Aborted when the item is cancelled, removed, replaced out of the list or the component unmounts. */
|
|
36
|
+
signal: AbortSignal;
|
|
37
|
+
/** Optional real progress (0–100). Core never fabricates progress. */
|
|
38
|
+
onProgress(percent: number): void;
|
|
39
|
+
}
|
|
40
|
+
/** Caller-injected transport: resolve (optionally with { url }) on success, reject or throw on failure. */
|
|
41
|
+
export type UploadRequest = (file: File, context: UploadRequestContext) => Promise<UploadResult | void> | UploadResult | void;
|
|
42
|
+
export interface QwUploadProps {
|
|
43
|
+
id?: string;
|
|
44
|
+
/** Native form field name on the file input. */
|
|
45
|
+
name?: string;
|
|
46
|
+
/** Native accept list: extensions (.png), wildcards (image/*) or exact MIME types. */
|
|
47
|
+
accept?: string;
|
|
48
|
+
multiple?: boolean;
|
|
49
|
+
/** Maximum list length; invalid or ≤0 means unlimited. */
|
|
50
|
+
maxCount?: number;
|
|
51
|
+
/** Maximum file size in bytes; invalid or ≤0 means unlimited. */
|
|
52
|
+
maxSize?: number;
|
|
53
|
+
/** Controlled list; undefined lets Core own it (seeded by defaultValue). */
|
|
54
|
+
value?: readonly UploadItem[];
|
|
55
|
+
defaultValue?: readonly UploadItem[];
|
|
56
|
+
onChange?: (details: UploadChangeDetails) => void;
|
|
57
|
+
upload?: UploadRequest;
|
|
58
|
+
onReject?: (details: UploadRejectDetails) => void;
|
|
59
|
+
/** Create object-URL previews for image files; default true. */
|
|
60
|
+
preview?: boolean;
|
|
61
|
+
disabled?: boolean;
|
|
62
|
+
readOnly?: boolean;
|
|
63
|
+
triggerText?: string;
|
|
64
|
+
/** Remove button name with {name}; default 删除 {name}. */
|
|
65
|
+
removeLabel?: string;
|
|
66
|
+
retryText?: string;
|
|
67
|
+
cancelText?: string;
|
|
68
|
+
errorText?: string;
|
|
69
|
+
cancelledText?: string;
|
|
70
|
+
}
|
|
71
|
+
export interface ResolvedUploadState {
|
|
72
|
+
name: string | undefined;
|
|
73
|
+
accept: string;
|
|
74
|
+
multiple: boolean;
|
|
75
|
+
maxCount: number;
|
|
76
|
+
maxSize: number;
|
|
77
|
+
preview: boolean;
|
|
78
|
+
disabled: boolean;
|
|
79
|
+
readOnly: boolean;
|
|
80
|
+
triggerText: string;
|
|
81
|
+
removeLabel: string;
|
|
82
|
+
retryText: string;
|
|
83
|
+
cancelText: string;
|
|
84
|
+
errorText: string;
|
|
85
|
+
cancelledText: string;
|
|
86
|
+
}
|
|
87
|
+
export declare function resolveUploadState(props?: QwUploadProps): ResolvedUploadState;
|
|
88
|
+
/** Normalize caller items; unknown status becomes done, duplicate or empty ids are dropped. */
|
|
89
|
+
export declare function normalizeUploadItems(items: readonly UploadItem[] | undefined): UploadItem[];
|
|
90
|
+
/** Native accept semantics: case-insensitive extension, type/* prefix or exact MIME; empty accepts everything. */
|
|
91
|
+
export declare function matchesUploadAccept(file: {
|
|
92
|
+
name: string;
|
|
93
|
+
type: string;
|
|
94
|
+
}, accept: string): boolean;
|
|
95
|
+
export declare function createUploadProps(props?: QwUploadProps): QwUploadProps;
|
|
96
|
+
export interface QwUploadSchema {
|
|
97
|
+
props: QwUploadProps;
|
|
98
|
+
context: {
|
|
99
|
+
value: UploadItem[];
|
|
100
|
+
announcement: string;
|
|
101
|
+
};
|
|
102
|
+
refs: {
|
|
103
|
+
files: Map<string, File>;
|
|
104
|
+
controllers: Map<string, AbortController>;
|
|
105
|
+
urls: Map<string, string>;
|
|
106
|
+
seq: number;
|
|
107
|
+
active: boolean;
|
|
108
|
+
};
|
|
109
|
+
state: "ready";
|
|
110
|
+
action: "add" | "remove" | "retry" | "cancel" | "settle" | "sync";
|
|
111
|
+
effect: "lifecycle";
|
|
112
|
+
event: {
|
|
113
|
+
type: "FILES";
|
|
114
|
+
files: readonly File[];
|
|
115
|
+
} | {
|
|
116
|
+
type: "REMOVE";
|
|
117
|
+
id: string;
|
|
118
|
+
} | {
|
|
119
|
+
type: "RETRY";
|
|
120
|
+
id: string;
|
|
121
|
+
} | {
|
|
122
|
+
type: "CANCEL";
|
|
123
|
+
id: string;
|
|
124
|
+
} | {
|
|
125
|
+
type: "SETTLE";
|
|
126
|
+
id: string;
|
|
127
|
+
controller: AbortController;
|
|
128
|
+
patch: Partial<UploadItem>;
|
|
129
|
+
final: boolean;
|
|
130
|
+
} | {
|
|
131
|
+
type: "SYNC";
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
export type QwUploadMachine = Machine<QwUploadSchema>;
|
|
135
|
+
export type QwUploadService = Service<QwUploadSchema>;
|
|
136
|
+
/** Core owns validation, the list, caller-upload lifecycle with AbortSignal, object-URL ownership and announcements. */
|
|
137
|
+
export declare const uploadMachine: QwUploadMachine;
|
|
138
|
+
export interface UploadViewItem extends UploadItem {
|
|
139
|
+
/** item.url, else the Core-owned object URL for images, else undefined. */
|
|
140
|
+
previewUrl: string | undefined;
|
|
141
|
+
statusText: string;
|
|
142
|
+
removeLabel: string;
|
|
143
|
+
}
|
|
144
|
+
export interface UploadInputEvent {
|
|
145
|
+
readonly currentTarget: unknown;
|
|
146
|
+
}
|
|
147
|
+
export interface QwUploadApi<T extends PropTypes = PropTypes> {
|
|
148
|
+
items: UploadViewItem[];
|
|
149
|
+
announcement: string;
|
|
150
|
+
triggerText: string;
|
|
151
|
+
retryText: string;
|
|
152
|
+
cancelText: string;
|
|
153
|
+
/** False while disabled, read-only or at maxCount. */
|
|
154
|
+
canAdd: boolean;
|
|
155
|
+
addFiles(files: readonly File[]): void;
|
|
156
|
+
remove(id: string): void;
|
|
157
|
+
retry(id: string): void;
|
|
158
|
+
cancel(id: string): void;
|
|
159
|
+
getRootProps(): T["element"];
|
|
160
|
+
getInputProps(): T["input"];
|
|
161
|
+
getTriggerProps(): T["label"];
|
|
162
|
+
getListProps(): T["element"];
|
|
163
|
+
getItemProps(item: UploadViewItem): T["element"];
|
|
164
|
+
getPreviewProps(item: UploadViewItem): T["img"];
|
|
165
|
+
getNameProps(item: UploadViewItem): T["element"];
|
|
166
|
+
getStatusProps(item: UploadViewItem): T["element"];
|
|
167
|
+
getRetryProps(item: UploadViewItem): T["button"];
|
|
168
|
+
getCancelProps(item: UploadViewItem): T["button"];
|
|
169
|
+
getRemoveProps(item: UploadViewItem): T["button"];
|
|
170
|
+
getLiveProps(): T["element"];
|
|
171
|
+
}
|
|
172
|
+
export declare function connectUpload<T extends PropTypes>(service: QwUploadService, normalize: NormalizeProps<T>): QwUploadApi<T>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./virtual-list.js";
|
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
import { createMachine } from "@zag-js/core";
|
|
2
|
+
//#region src/virtual-list/virtual-list.ts
|
|
3
|
+
/** Stable DOM parts shared by every adapter. */
|
|
4
|
+
const VIRTUAL_LIST_PARTS = [
|
|
5
|
+
"root",
|
|
6
|
+
"list",
|
|
7
|
+
"item",
|
|
8
|
+
"empty"
|
|
9
|
+
];
|
|
10
|
+
/** scrollToIndex alignment vocabulary; any other value is treated as auto. */
|
|
11
|
+
const VIRTUAL_LIST_ALIGNS = [
|
|
12
|
+
"auto",
|
|
13
|
+
"start",
|
|
14
|
+
"center",
|
|
15
|
+
"end"
|
|
16
|
+
];
|
|
17
|
+
/** Fixed row height in CSS pixels used when itemHeight is missing or invalid. */
|
|
18
|
+
const VIRTUAL_LIST_DEFAULT_ITEM_HEIGHT = 48;
|
|
19
|
+
/** Rows rendered before and after the visible rows. */
|
|
20
|
+
const VIRTUAL_LIST_DEFAULT_OVERSCAN = 3;
|
|
21
|
+
/** Rows assumed visible before the viewport has been measured (SSR, hidden containers). */
|
|
22
|
+
const VIRTUAL_LIST_DEFAULT_INITIAL_COUNT = 10;
|
|
23
|
+
const text = (value, fallback) => typeof value === "string" && value.trim() ? value : fallback;
|
|
24
|
+
const positive = (value, fallback) => typeof value === "number" && Number.isFinite(value) && value > 0 ? value : fallback;
|
|
25
|
+
const whole = (value, fallback) => typeof value === "number" && Number.isFinite(value) && value >= 0 ? Math.floor(value) : fallback;
|
|
26
|
+
const clamp = (value, min, max) => Math.min(max, Math.max(min, value));
|
|
27
|
+
const field = (item, name) => item !== null && typeof item === "object" ? item[name] : void 0;
|
|
28
|
+
const accessor = (value) => typeof value === "function" || typeof value === "string" && value.trim() ? value : void 0;
|
|
29
|
+
/** O(1): items are referenced, never copied or scanned. */
|
|
30
|
+
function resolveVirtualListState(props = {}) {
|
|
31
|
+
const items = Array.isArray(props.items) ? props.items : [];
|
|
32
|
+
return {
|
|
33
|
+
items,
|
|
34
|
+
count: items.length,
|
|
35
|
+
itemHeight: positive(props.itemHeight, 48),
|
|
36
|
+
overscan: whole(props.overscan, 3),
|
|
37
|
+
initialVisibleCount: whole(props.initialVisibleCount, 10),
|
|
38
|
+
target: typeof props.target === "string" && props.target.trim() ? props.target : void 0,
|
|
39
|
+
label: text(props.label, "列表"),
|
|
40
|
+
emptyText: text(props.emptyText, "暂无数据"),
|
|
41
|
+
itemKey: accessor(props.itemKey),
|
|
42
|
+
itemText: accessor(props.itemText)
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/** Unique row identity. Missing, empty or non-finite keys throw: a silent fallback would break row identity. */
|
|
46
|
+
function resolveVirtualListKey(item, index, itemKey) {
|
|
47
|
+
const raw = itemKey === void 0 ? index : typeof itemKey === "function" ? itemKey(item, index) : field(item, itemKey);
|
|
48
|
+
if (typeof raw === "string" && raw.length) return raw;
|
|
49
|
+
if (typeof raw === "number" && Number.isFinite(raw)) return String(raw);
|
|
50
|
+
throw new TypeError(`VirtualList item ${index} requires a nonempty string or finite number key`);
|
|
51
|
+
}
|
|
52
|
+
/** Default text: never throws; anything other than a string or finite number renders as an empty string. */
|
|
53
|
+
function resolveVirtualListText(item, index, itemText) {
|
|
54
|
+
const raw = typeof itemText === "function" ? itemText(item, index) : typeof itemText === "string" ? field(item, itemText) : item;
|
|
55
|
+
return typeof raw === "string" ? raw : typeof raw === "number" && Number.isFinite(raw) ? String(raw) : "";
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Fixed-height window. scrollTop is the list-relative offset: an offset beyond the last full viewport is clamped
|
|
59
|
+
* (stale offsets stay valid after the data shrinks); a negative offset means the list starts below an external viewport's top.
|
|
60
|
+
*/
|
|
61
|
+
function getVirtualListRange(input) {
|
|
62
|
+
const count = Math.max(0, Math.floor(input.count) || 0), height = positive(input.itemHeight, 48);
|
|
63
|
+
const viewport = Number.isFinite(input.viewport) ? Math.max(0, input.viewport) : 0, overscan = whole(input.overscan, 0);
|
|
64
|
+
if (!count) return {
|
|
65
|
+
start: 0,
|
|
66
|
+
end: 0,
|
|
67
|
+
visibleStart: 0,
|
|
68
|
+
visibleEnd: 0,
|
|
69
|
+
count: 0
|
|
70
|
+
};
|
|
71
|
+
const top = Math.min(Number.isFinite(input.scrollTop) ? input.scrollTop : 0, Math.max(0, count * height - viewport));
|
|
72
|
+
const visibleStart = clamp(Math.floor(top / height), 0, count);
|
|
73
|
+
const visibleEnd = clamp(Math.ceil((top + viewport) / height), visibleStart, count);
|
|
74
|
+
return {
|
|
75
|
+
start: Math.max(0, visibleStart - overscan),
|
|
76
|
+
end: Math.min(count, visibleEnd + overscan),
|
|
77
|
+
visibleStart,
|
|
78
|
+
visibleEnd,
|
|
79
|
+
count
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/** Upper bound of windowed rows for any offset: ceil(viewport / itemHeight) + 1 partial row + 2 × overscan (a focused pinned row adds at most 1). */
|
|
83
|
+
function getVirtualListRenderLimit(viewport, itemHeight, overscan) {
|
|
84
|
+
return Math.ceil(Math.max(0, viewport) / positive(itemHeight, 48)) + 1 + 2 * whole(overscan, 0);
|
|
85
|
+
}
|
|
86
|
+
/** List-relative offset that brings index into view, or null when nothing should scroll. The index is clamped into [0, count - 1]. */
|
|
87
|
+
function getVirtualListScrollTop(input) {
|
|
88
|
+
const count = Math.max(0, Math.floor(input.count) || 0), height = positive(input.itemHeight, 48);
|
|
89
|
+
if (!count || !Number.isFinite(input.index)) return null;
|
|
90
|
+
const viewport = Number.isFinite(input.viewport) ? Math.max(0, input.viewport) : 0, current = Number.isFinite(input.scrollTop) ? input.scrollTop : 0;
|
|
91
|
+
const top = clamp(Math.floor(input.index), 0, count - 1) * height, bottom = top + height;
|
|
92
|
+
const align = VIRTUAL_LIST_ALIGNS.includes(input.align ?? "") ? input.align : "auto";
|
|
93
|
+
let next;
|
|
94
|
+
if (align === "start") next = top;
|
|
95
|
+
else if (align === "end") next = bottom - viewport;
|
|
96
|
+
else if (align === "center") next = top - (viewport - height) / 2;
|
|
97
|
+
else if (top >= current && bottom <= current + viewport) return null;
|
|
98
|
+
else next = top < current || height >= viewport ? top : bottom - viewport;
|
|
99
|
+
return clamp(next, 0, Math.max(0, count * height - viewport));
|
|
100
|
+
}
|
|
101
|
+
/** Row index currently holding focus: O(1) when unchanged, otherwise one scan by key; -1 when the row is gone. */
|
|
102
|
+
function findVirtualListFocus(state, focus) {
|
|
103
|
+
if (!focus) return -1;
|
|
104
|
+
const keyAt = (index) => {
|
|
105
|
+
try {
|
|
106
|
+
return resolveVirtualListKey(state.items[index], index, state.itemKey);
|
|
107
|
+
} catch {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
if (focus.index >= 0 && focus.index < state.count && keyAt(focus.index) === focus.key) return focus.index;
|
|
112
|
+
for (let index = 0; index < state.count; index++) if (keyAt(index) === focus.key) return index;
|
|
113
|
+
return -1;
|
|
114
|
+
}
|
|
115
|
+
function createVirtualListProps(props = {}) {
|
|
116
|
+
if (props.id !== void 0 && (typeof props.id !== "string" || !props.id.trim())) throw new TypeError("VirtualList requires a nonempty instance id when provided");
|
|
117
|
+
return { ...props };
|
|
118
|
+
}
|
|
119
|
+
const ids = (scope) => {
|
|
120
|
+
const base = `virtual-list:${scope.id}`;
|
|
121
|
+
return {
|
|
122
|
+
root: base,
|
|
123
|
+
list: `${base}:list`
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
const live = (service) => resolveVirtualListState({
|
|
127
|
+
items: service.prop("items"),
|
|
128
|
+
itemHeight: service.prop("itemHeight"),
|
|
129
|
+
itemKey: service.prop("itemKey"),
|
|
130
|
+
itemText: service.prop("itemText"),
|
|
131
|
+
overscan: service.prop("overscan"),
|
|
132
|
+
target: service.prop("target"),
|
|
133
|
+
initialVisibleCount: service.prop("initialVisibleCount"),
|
|
134
|
+
label: service.prop("label"),
|
|
135
|
+
emptyText: service.prop("emptyText")
|
|
136
|
+
});
|
|
137
|
+
/** A zero measurement (SSR, jsdom, display:none) keeps the initialVisibleCount fallback instead of collapsing the window. */
|
|
138
|
+
const viewportOf = (state, measured) => measured > 0 ? measured : state.initialVisibleCount * state.itemHeight;
|
|
139
|
+
const rangeOf = (state, context) => getVirtualListRange({
|
|
140
|
+
count: state.count,
|
|
141
|
+
itemHeight: state.itemHeight,
|
|
142
|
+
viewport: viewportOf(state, context.get("viewport")),
|
|
143
|
+
scrollTop: context.get("scrollTop"),
|
|
144
|
+
overscan: state.overscan
|
|
145
|
+
});
|
|
146
|
+
/** Primitive identity per items array: zag tracks primitives, and comparing 10k rows by value on every publish would be O(n). */
|
|
147
|
+
const identities = /* @__PURE__ */ new WeakMap();
|
|
148
|
+
let nextIdentity = 0;
|
|
149
|
+
function identityOf(value) {
|
|
150
|
+
if (!value || typeof value !== "object") return 0;
|
|
151
|
+
let identity = identities.get(value);
|
|
152
|
+
if (identity === void 0) {
|
|
153
|
+
identity = ++nextIdentity;
|
|
154
|
+
identities.set(value, identity);
|
|
155
|
+
}
|
|
156
|
+
return identity;
|
|
157
|
+
}
|
|
158
|
+
const rangeKey = (range) => `${range.start}:${range.end}:${range.visibleStart}:${range.visibleEnd}:${range.count}`;
|
|
159
|
+
/** Platform boundary: self, the target element in the root's own tree, or null for the page viewport. */
|
|
160
|
+
function resolveScroller(root, target) {
|
|
161
|
+
if (!target) return root;
|
|
162
|
+
return root.getRootNode().getElementById?.(target) ?? root.ownerDocument.getElementById(target);
|
|
163
|
+
}
|
|
164
|
+
/** List-relative offset and viewport size of the resolved scroller. */
|
|
165
|
+
function readViewport(root, list, scroller) {
|
|
166
|
+
if (scroller === root) return {
|
|
167
|
+
scrollTop: root.scrollTop,
|
|
168
|
+
viewport: root.clientHeight
|
|
169
|
+
};
|
|
170
|
+
const listTop = (list ?? root).getBoundingClientRect().top;
|
|
171
|
+
if (scroller) return {
|
|
172
|
+
scrollTop: scroller.getBoundingClientRect().top + scroller.clientTop - listTop,
|
|
173
|
+
viewport: scroller.clientHeight
|
|
174
|
+
};
|
|
175
|
+
return {
|
|
176
|
+
scrollTop: -listTop,
|
|
177
|
+
viewport: root.ownerDocument.defaultView?.innerHeight ?? 0
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
/** The row element of this list containing node; nested lists inside a row are ignored. */
|
|
181
|
+
function rowOf(root, list, node) {
|
|
182
|
+
for (let current = node; list && current && current !== root; current = current.parentNode) if (current.parentNode === list && current.getAttribute?.("data-part") === "item") return current;
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
/** Core owns measurement, windowing, the focused-row pin, scrollToIndex, range notifications and cleanup. */
|
|
186
|
+
const virtualListMachine = createMachine({
|
|
187
|
+
props: ({ props }) => createVirtualListProps(props),
|
|
188
|
+
initialState: () => "ready",
|
|
189
|
+
states: { ready: {} },
|
|
190
|
+
context: ({ bindable }) => ({
|
|
191
|
+
scrollTop: bindable(() => ({ defaultValue: 0 })),
|
|
192
|
+
viewport: bindable(() => ({ defaultValue: 0 })),
|
|
193
|
+
focus: bindable(() => ({
|
|
194
|
+
defaultValue: null,
|
|
195
|
+
hash: (value) => value ? `${value.index}\u0000${value.key}` : ""
|
|
196
|
+
}))
|
|
197
|
+
}),
|
|
198
|
+
refs: () => ({
|
|
199
|
+
rebind: null,
|
|
200
|
+
restore: null
|
|
201
|
+
}),
|
|
202
|
+
watch({ track, prop, context, action }) {
|
|
203
|
+
track([() => prop("target")], () => action(["rebind"]));
|
|
204
|
+
track([() => identityOf(prop("items")), () => prop("items")?.length], () => action(["reconcile"]));
|
|
205
|
+
track([() => rangeKey(rangeOf(live({ prop }), context))], () => action(["notifyRange"]));
|
|
206
|
+
},
|
|
207
|
+
on: {
|
|
208
|
+
MEASURE: { actions: ["measure"] },
|
|
209
|
+
"FOCUS.SET": { actions: ["setFocus"] },
|
|
210
|
+
"FOCUS.CLEAR": { actions: ["clearFocus"] },
|
|
211
|
+
"SCROLL.TO": { actions: ["scrollToIndex"] }
|
|
212
|
+
},
|
|
213
|
+
effects: ["trackViewport"],
|
|
214
|
+
implementations: {
|
|
215
|
+
actions: {
|
|
216
|
+
measure({ event, context }) {
|
|
217
|
+
if (event.type !== "MEASURE") return;
|
|
218
|
+
if (event.scrollTop !== context.get("scrollTop")) context.set("scrollTop", event.scrollTop);
|
|
219
|
+
if (event.viewport !== context.get("viewport")) context.set("viewport", event.viewport);
|
|
220
|
+
},
|
|
221
|
+
setFocus({ event, context }) {
|
|
222
|
+
if (event.type === "FOCUS.SET") context.set("focus", {
|
|
223
|
+
key: event.key,
|
|
224
|
+
index: event.index
|
|
225
|
+
});
|
|
226
|
+
},
|
|
227
|
+
clearFocus({ context }) {
|
|
228
|
+
if (context.get("focus")) context.set("focus", null);
|
|
229
|
+
},
|
|
230
|
+
rebind({ refs }) {
|
|
231
|
+
refs.get("rebind")?.();
|
|
232
|
+
},
|
|
233
|
+
reconcile({ context, prop, refs }) {
|
|
234
|
+
const focus = context.get("focus");
|
|
235
|
+
if (!focus) return;
|
|
236
|
+
const index = findVirtualListFocus(live({ prop }), focus);
|
|
237
|
+
if (index === -1) {
|
|
238
|
+
context.set("focus", null);
|
|
239
|
+
refs.get("restore")?.();
|
|
240
|
+
} else if (index !== focus.index) context.set("focus", {
|
|
241
|
+
key: focus.key,
|
|
242
|
+
index
|
|
243
|
+
});
|
|
244
|
+
},
|
|
245
|
+
notifyRange({ prop, context }) {
|
|
246
|
+
prop("onRangeChange")?.(rangeOf(live({ prop }), context));
|
|
247
|
+
},
|
|
248
|
+
scrollToIndex({ event, context, prop, scope }) {
|
|
249
|
+
if (event.type !== "SCROLL.TO") return;
|
|
250
|
+
const state = live({ prop }), id = ids(scope), root = scope.getById(id.root);
|
|
251
|
+
const scroller = root ? resolveScroller(root, state.target) : void 0;
|
|
252
|
+
const current = root ? readViewport(root, scope.getById(id.list), scroller ?? null) : {
|
|
253
|
+
scrollTop: context.get("scrollTop"),
|
|
254
|
+
viewport: context.get("viewport")
|
|
255
|
+
};
|
|
256
|
+
const next = getVirtualListScrollTop({
|
|
257
|
+
index: event.index,
|
|
258
|
+
align: event.align,
|
|
259
|
+
count: state.count,
|
|
260
|
+
itemHeight: state.itemHeight,
|
|
261
|
+
viewport: viewportOf(state, current.viewport),
|
|
262
|
+
scrollTop: current.scrollTop
|
|
263
|
+
});
|
|
264
|
+
if (next === null) return;
|
|
265
|
+
if (root) {
|
|
266
|
+
const win = root.ownerDocument.defaultView;
|
|
267
|
+
if (scroller === root) root.scrollTop = next;
|
|
268
|
+
else if (scroller) scroller.scrollTop += next - current.scrollTop;
|
|
269
|
+
else win?.scrollTo(win.scrollX, win.scrollY + next - current.scrollTop);
|
|
270
|
+
}
|
|
271
|
+
context.set("scrollTop", next);
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
effects: { trackViewport({ scope, prop, context, send, refs }) {
|
|
275
|
+
const id = ids(scope), root = scope.getById(id.root), doc = root?.ownerDocument, win = doc?.defaultView;
|
|
276
|
+
if (!root || !doc || !win) return;
|
|
277
|
+
let frame = 0, disposed = false, scroller = root, events = null, observer = null;
|
|
278
|
+
const pending = /* @__PURE__ */ new Set();
|
|
279
|
+
const measure = () => {
|
|
280
|
+
frame = 0;
|
|
281
|
+
if (disposed) return;
|
|
282
|
+
const next = readViewport(root, scope.getById(id.list), scroller);
|
|
283
|
+
if (next.scrollTop !== context.get("scrollTop") || next.viewport !== context.get("viewport")) send({
|
|
284
|
+
type: "MEASURE",
|
|
285
|
+
...next
|
|
286
|
+
});
|
|
287
|
+
};
|
|
288
|
+
const schedule = () => {
|
|
289
|
+
if (!disposed && !frame) frame = win.requestAnimationFrame(measure);
|
|
290
|
+
};
|
|
291
|
+
const later = (run) => {
|
|
292
|
+
const handle = win.requestAnimationFrame(() => {
|
|
293
|
+
pending.delete(handle);
|
|
294
|
+
if (!disposed) run();
|
|
295
|
+
});
|
|
296
|
+
pending.add(handle);
|
|
297
|
+
};
|
|
298
|
+
const bind = () => {
|
|
299
|
+
if (disposed) return;
|
|
300
|
+
events?.removeEventListener("scroll", schedule);
|
|
301
|
+
observer?.disconnect();
|
|
302
|
+
observer = null;
|
|
303
|
+
scroller = resolveScroller(root, live({ prop }).target);
|
|
304
|
+
events = scroller ?? win;
|
|
305
|
+
events.addEventListener("scroll", schedule, { passive: true });
|
|
306
|
+
const Observer = win.ResizeObserver;
|
|
307
|
+
if (Observer && scroller) {
|
|
308
|
+
observer = new Observer(schedule);
|
|
309
|
+
observer.observe(scroller);
|
|
310
|
+
}
|
|
311
|
+
measure();
|
|
312
|
+
};
|
|
313
|
+
const restore = () => later(() => {
|
|
314
|
+
const active = doc.activeElement;
|
|
315
|
+
if (!active || active === doc.body) root.focus({ preventScroll: true });
|
|
316
|
+
});
|
|
317
|
+
const onFocusIn = (event) => {
|
|
318
|
+
const row = rowOf(root, scope.getById(id.list), event.target), key = row?.getAttribute("data-key"), index = Number(row?.getAttribute("data-index"));
|
|
319
|
+
const current = context.get("focus");
|
|
320
|
+
if (row && key != null && Number.isInteger(index)) {
|
|
321
|
+
if (current?.key !== key || current.index !== index) send({
|
|
322
|
+
type: "FOCUS.SET",
|
|
323
|
+
key,
|
|
324
|
+
index
|
|
325
|
+
});
|
|
326
|
+
} else if (current) send({ type: "FOCUS.CLEAR" });
|
|
327
|
+
};
|
|
328
|
+
const onFocusOut = () => later(() => {
|
|
329
|
+
const active = doc.activeElement, focus = context.get("focus");
|
|
330
|
+
if (active && root.contains(active)) return;
|
|
331
|
+
if (focus && (!active || active === doc.body) && findVirtualListFocus(live({ prop }), focus) === -1) {
|
|
332
|
+
root.focus({ preventScroll: true });
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
send({ type: "FOCUS.CLEAR" });
|
|
336
|
+
});
|
|
337
|
+
refs.set("rebind", bind);
|
|
338
|
+
refs.set("restore", restore);
|
|
339
|
+
win.addEventListener("resize", schedule);
|
|
340
|
+
root.addEventListener("focusin", onFocusIn);
|
|
341
|
+
root.addEventListener("focusout", onFocusOut);
|
|
342
|
+
bind();
|
|
343
|
+
return () => {
|
|
344
|
+
disposed = true;
|
|
345
|
+
refs.set("rebind", null);
|
|
346
|
+
refs.set("restore", null);
|
|
347
|
+
if (frame) win.cancelAnimationFrame(frame);
|
|
348
|
+
for (const handle of pending) win.cancelAnimationFrame(handle);
|
|
349
|
+
pending.clear();
|
|
350
|
+
events?.removeEventListener("scroll", schedule);
|
|
351
|
+
observer?.disconnect();
|
|
352
|
+
win.removeEventListener("resize", schedule);
|
|
353
|
+
root.removeEventListener("focusin", onFocusIn);
|
|
354
|
+
root.removeEventListener("focusout", onFocusOut);
|
|
355
|
+
};
|
|
356
|
+
} }
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
function connectVirtualList(service, normalize) {
|
|
360
|
+
const base = live(service), state = base, id = ids(service.scope), range = rangeOf(base, service.context);
|
|
361
|
+
const row = (index, pinned) => {
|
|
362
|
+
const item = state.items[index];
|
|
363
|
+
return {
|
|
364
|
+
key: resolveVirtualListKey(item, index, state.itemKey),
|
|
365
|
+
index,
|
|
366
|
+
item,
|
|
367
|
+
text: resolveVirtualListText(item, index, state.itemText),
|
|
368
|
+
pinned
|
|
369
|
+
};
|
|
370
|
+
};
|
|
371
|
+
const rows = [];
|
|
372
|
+
for (let index = range.start; index < range.end; index++) rows.push(row(index, false));
|
|
373
|
+
const focused = findVirtualListFocus(base, service.context.get("focus"));
|
|
374
|
+
if (focused !== -1 && (focused < range.start || focused >= range.end)) if (focused < range.start) rows.unshift(row(focused, true));
|
|
375
|
+
else rows.push(row(focused, true));
|
|
376
|
+
const seen = /* @__PURE__ */ new Set();
|
|
377
|
+
for (const entry of rows) {
|
|
378
|
+
if (seen.has(entry.key)) throw new TypeError(`VirtualList item keys must be unique: ${entry.key}`);
|
|
379
|
+
seen.add(entry.key);
|
|
380
|
+
}
|
|
381
|
+
const empty = state.count === 0, self = state.target === void 0, totalHeight = state.count * state.itemHeight;
|
|
382
|
+
const part = (name) => ({
|
|
383
|
+
"data-scope": "virtual-list",
|
|
384
|
+
"data-part": name
|
|
385
|
+
});
|
|
386
|
+
return {
|
|
387
|
+
rows,
|
|
388
|
+
count: state.count,
|
|
389
|
+
empty,
|
|
390
|
+
range,
|
|
391
|
+
itemHeight: state.itemHeight,
|
|
392
|
+
totalHeight,
|
|
393
|
+
label: state.label,
|
|
394
|
+
emptyText: state.emptyText,
|
|
395
|
+
scrollToIndex: (index, align) => service.send({
|
|
396
|
+
type: "SCROLL.TO",
|
|
397
|
+
index,
|
|
398
|
+
align
|
|
399
|
+
}),
|
|
400
|
+
getRootProps: () => normalize.element({
|
|
401
|
+
...part("root"),
|
|
402
|
+
id: id.root,
|
|
403
|
+
role: "group",
|
|
404
|
+
"aria-label": state.label,
|
|
405
|
+
tabIndex: self ? 0 : -1,
|
|
406
|
+
"data-scroller": self ? "self" : "target",
|
|
407
|
+
"data-empty": empty ? "true" : void 0
|
|
408
|
+
}),
|
|
409
|
+
getListProps: () => normalize.element({
|
|
410
|
+
...part("list"),
|
|
411
|
+
id: id.list,
|
|
412
|
+
role: "list",
|
|
413
|
+
hidden: empty || void 0,
|
|
414
|
+
style: {
|
|
415
|
+
position: "relative",
|
|
416
|
+
blockSize: `${totalHeight}px`
|
|
417
|
+
}
|
|
418
|
+
}),
|
|
419
|
+
getItemProps: (entry) => normalize.element({
|
|
420
|
+
...part("item"),
|
|
421
|
+
role: "listitem",
|
|
422
|
+
"aria-setsize": state.count,
|
|
423
|
+
"aria-posinset": entry.index + 1,
|
|
424
|
+
"data-index": entry.index,
|
|
425
|
+
"data-key": entry.key,
|
|
426
|
+
"data-pinned": entry.pinned ? "true" : void 0,
|
|
427
|
+
style: {
|
|
428
|
+
position: "absolute",
|
|
429
|
+
insetInlineStart: "0",
|
|
430
|
+
insetInlineEnd: "0",
|
|
431
|
+
insetBlockStart: `${entry.index * state.itemHeight}px`,
|
|
432
|
+
blockSize: `${state.itemHeight}px`
|
|
433
|
+
}
|
|
434
|
+
}),
|
|
435
|
+
getEmptyProps: () => normalize.element({
|
|
436
|
+
...part("empty"),
|
|
437
|
+
role: "status",
|
|
438
|
+
hidden: !empty || void 0
|
|
439
|
+
})
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
//#endregion
|
|
443
|
+
export { VIRTUAL_LIST_ALIGNS, VIRTUAL_LIST_DEFAULT_INITIAL_COUNT, VIRTUAL_LIST_DEFAULT_ITEM_HEIGHT, VIRTUAL_LIST_DEFAULT_OVERSCAN, VIRTUAL_LIST_PARTS, connectVirtualList, createVirtualListProps, findVirtualListFocus, getVirtualListRange, getVirtualListRenderLimit, getVirtualListScrollTop, resolveVirtualListKey, resolveVirtualListState, resolveVirtualListText, virtualListMachine };
|
|
444
|
+
|
|
445
|
+
//# sourceMappingURL=index.js.map
|