@qw-ui/core 0.3.0-next.40 → 0.3.0-next.42
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 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/footer/footer.ts"],"sourcesContent":["import { createMachine, type Machine, type Service } from \"@zag-js/core\";\nimport type { NormalizeProps, PropTypes } from \"@zag-js/types\";\n\n/** Page/section closing area: separator label, links, content text and action chips. */\nexport const FOOTER_PARTS = [\"root\", \"label\", \"links\", \"link-item\", \"link\", \"content\", \"chips\", \"chip\", \"extra\"] as const;\nexport const FOOTER_CHIP_VARIANTS = [\"plain\", \"link\"] as const;\nexport type FooterPart = (typeof FOOTER_PARTS)[number];\nexport type FooterChipVariant = (typeof FOOTER_CHIP_VARIANTS)[number];\n\nexport interface FooterLink {\n id: string;\n text: string;\n href: string;\n disabled?: boolean;\n target?: string;\n rel?: string;\n}\nexport interface FooterChip {\n id: string;\n text: string;\n disabled?: boolean;\n /** plain: filled pill (default); link: text-style action. */\n variant?: FooterChipVariant;\n}\nexport interface FooterChipClickDetails { id: string; index: number }\nexport interface FooterLinkClickDetails { id: string; index: number; href?: string }\nexport interface QwFooterProps {\n /** Separator label text above the footer content. */\n label?: string;\n /** Plain footer text such as a copyright line. */\n content?: string;\n links?: readonly FooterLink[];\n chips?: readonly FooterChip[];\n /** Opt-in page-level contentinfo landmark; default is a plain region. */\n landmark?: boolean;\n /** Accessible name of the link list; default \"页脚链接\". */\n linksLabel?: string;\n onChipClick?: (details: FooterChipClickDetails) => void;\n /** Notification only; native navigation is never prevented. */\n onLinkClick?: (details: FooterLinkClickDetails) => void;\n}\nexport interface ResolvedFooterLink extends FooterLink { index: number; href: string; safeHref?: string; disabled: boolean }\nexport interface ResolvedFooterChip extends FooterChip { index: number; disabled: boolean; variant: FooterChipVariant }\n\nconst SAFE_SCHEMES = new Set([\"http\", \"https\", \"mailto\", \"tel\"]);\n/** Relative URLs and http(s)/mailto/tel are kept; other schemes (javascript:, data:, …) are dropped. */\nexport function sanitizeFooterHref(href: unknown): string | undefined {\n if (typeof href !== \"string\") return undefined;\n // eslint-disable-next-line no-control-regex -- C0/DEL characters can hide a scheme from naive checks.\n const value = href.trim().replace(/[\\x00-\\x1f\\x7f]/g, \"\");\n if (!value) return undefined;\n const scheme = /^([a-z][a-z0-9+.-]*):/i.exec(value)?.[1]?.toLowerCase();\n if (scheme) return SAFE_SCHEMES.has(scheme) ? href.trim() : undefined;\n return href.trim();\n}\nexport function resolveFooterLinks(links: readonly FooterLink[] | undefined): ResolvedFooterLink[] {\n return (links ?? []).map((link, index) => {\n const safeHref = sanitizeFooterHref(link.href);\n return { ...link, index, href: link.href, safeHref, disabled: link.disabled === true || safeHref === undefined };\n });\n}\nexport function resolveFooterChips(chips: readonly FooterChip[] | undefined): ResolvedFooterChip[] {\n return (chips ?? []).map((chip, index) => ({ ...chip, index, disabled: chip.disabled === true, variant: FOOTER_CHIP_VARIANTS.includes(chip.variant!) ? chip.variant! : \"plain\" }));\n}\n\nexport interface QwFooterSchema {\n props: QwFooterProps;\n context: Record<string, never>;\n state: \"idle\";\n action: \"notifyChip\" | \"notifyLink\";\n event: { type: \"CHIP.CLICK\"; index: number } | { type: \"LINK.CLICK\"; index: number };\n}\nexport type QwFooterMachine = Machine<QwFooterSchema>;\nexport type QwFooterService = Service<QwFooterSchema>;\n\n/** Stateless notification machine so every stack (including WC events) shares one activation path. */\nexport const footerMachine: QwFooterMachine = createMachine<QwFooterSchema>({\n initialState: () => \"idle\",\n on: { \"CHIP.CLICK\": { actions: [\"notifyChip\"] }, \"LINK.CLICK\": { actions: [\"notifyLink\"] } },\n states: { idle: {} },\n implementations: {\n actions: {\n notifyChip({ prop, event }) {\n if (event.type !== \"CHIP.CLICK\") return;\n const chip = resolveFooterChips(prop(\"chips\"))[event.index];\n if (chip && !chip.disabled) prop(\"onChipClick\")?.({ id: chip.id, index: chip.index });\n },\n notifyLink({ prop, event }) {\n if (event.type !== \"LINK.CLICK\") return;\n const link = resolveFooterLinks(prop(\"links\"))[event.index];\n if (link && !link.disabled) prop(\"onLinkClick\")?.({ id: link.id, index: link.index, href: link.safeHref });\n },\n },\n },\n});\n\nexport interface QwFooterApi<T extends PropTypes = PropTypes> {\n label?: string;\n content?: string;\n links: ResolvedFooterLink[];\n chips: ResolvedFooterChip[];\n getRootProps(): T[\"element\"];\n getLabelProps(): T[\"element\"];\n getLinksProps(): T[\"element\"];\n getLinkItemProps(link: ResolvedFooterLink): T[\"element\"];\n getLinkProps(link: ResolvedFooterLink): T[\"element\"];\n getContentProps(): T[\"element\"];\n getChipsProps(): T[\"element\"];\n getChipProps(chip: ResolvedFooterChip): T[\"button\"];\n getExtraProps(): T[\"element\"];\n}\nconst part = (name: FooterPart) => ({ \"data-scope\": \"footer\", \"data-part\": name });\nconst text = (value: unknown) => typeof value === \"string\" && value !== \"\" ? value : undefined;\n\nexport function connectFooter<T extends PropTypes>(service: QwFooterService, normalize: NormalizeProps<T>): QwFooterApi<T> {\n const label = text(service.prop(\"label\")), content = text(service.prop(\"content\"));\n const links = resolveFooterLinks(service.prop(\"links\")), chips = resolveFooterChips(service.prop(\"chips\"));\n return {\n label, content, links, chips,\n getRootProps: () => normalize.element({ ...part(\"root\"), ...(service.prop(\"landmark\") ? { role: \"contentinfo\" } : {}) }),\n getLabelProps: () => normalize.element({ ...part(\"label\"), hidden: label === undefined }),\n getLinksProps: () => normalize.element({ ...part(\"links\"), hidden: links.length === 0, \"aria-label\": links.length ? text(service.prop(\"linksLabel\")) ?? \"页脚链接\" : undefined }),\n getLinkItemProps: (link) => normalize.element({ ...part(\"link-item\"), \"data-value\": link.id }),\n getLinkProps: (link) => normalize.element({ ...part(\"link\"), \"data-value\": link.id,\n ...(link.disabled ? { \"aria-disabled\": \"true\", \"data-disabled\": \"true\" } : { href: link.safeHref, target: link.target, rel: link.rel ?? (link.target === \"_blank\" ? \"noopener noreferrer\" : undefined) }),\n onClick() { if (!link.disabled) service.send({ type: \"LINK.CLICK\", index: link.index }); } }),\n getContentProps: () => normalize.element({ ...part(\"content\"), hidden: content === undefined }),\n getChipsProps: () => normalize.element({ ...part(\"chips\"), hidden: chips.length === 0 }),\n getChipProps: (chip) => normalize.button({ ...part(\"chip\"), type: \"button\", disabled: chip.disabled, \"data-value\": chip.id, \"data-variant\": chip.variant,\n onClick() { service.send({ type: \"CHIP.CLICK\", index: chip.index }); } }),\n getExtraProps: () => normalize.element(part(\"extra\")),\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { NormalizeProps, PropTypes } from "@zag-js/types";
|
|
2
|
+
import { type QwFormService } from "./form.js";
|
|
3
|
+
import type { QwFormApi } from "./types.js";
|
|
4
|
+
export declare const FORM_PARTS: readonly ["root", "label", "content", "error-summary", "error-list", "error-item", "error-link", "footer"];
|
|
5
|
+
/** Public connect. Named connectForm so package barrels do not hide other connects. */
|
|
6
|
+
export declare function connectForm<T extends PropTypes>(service: QwFormService, normalize: NormalizeProps<T>): QwFormApi<T>;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { type Machine, type Service } from "@zag-js/core";
|
|
2
|
+
import { type FormNamePath, type QwFormValues, type QwNamePath, type QwFormValue } from "./model.js";
|
|
3
|
+
import { type FormValidationTrigger } from "./rules.js";
|
|
4
|
+
import type { FormCancelReason, FormErrorField, FormFieldState, FormInteractionSnapshot, FormSubmitResult, FormSubmitStatus, FormValidationResult, QwFormFieldDefinition, QwFormProps, QwFormState } from "./types.js";
|
|
5
|
+
interface Request {
|
|
6
|
+
ticket: number;
|
|
7
|
+
controller: AbortController;
|
|
8
|
+
}
|
|
9
|
+
type FeedbackKey = "errors" | "touched" | "validated" | "validating";
|
|
10
|
+
type FormFeedback = Pick<QwFormSchema["context"], FeedbackKey>;
|
|
11
|
+
interface KnownField {
|
|
12
|
+
name: FormNamePath;
|
|
13
|
+
preserve?: boolean;
|
|
14
|
+
}
|
|
15
|
+
interface FormRuntime {
|
|
16
|
+
feedback?: FormFeedback;
|
|
17
|
+
publishingFeedback?: boolean;
|
|
18
|
+
epoch: number;
|
|
19
|
+
next: number;
|
|
20
|
+
alive: boolean;
|
|
21
|
+
validations: Map<string, Request>;
|
|
22
|
+
submission?: Request;
|
|
23
|
+
reason: FormCancelReason;
|
|
24
|
+
valueHash: string;
|
|
25
|
+
functions: WeakMap<object, number>;
|
|
26
|
+
functionCount: number;
|
|
27
|
+
known: Map<string, KnownField>;
|
|
28
|
+
blurSeen: Set<string>;
|
|
29
|
+
suppressUser: boolean;
|
|
30
|
+
syncNative?: () => void;
|
|
31
|
+
userEcho?: {
|
|
32
|
+
key: string;
|
|
33
|
+
value: string;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export interface QwFormSchema {
|
|
37
|
+
props: QwFormProps & {
|
|
38
|
+
initialValues: QwFormValues;
|
|
39
|
+
initialErrors: FormErrorField[];
|
|
40
|
+
validateTrigger: FormValidationTrigger | FormValidationTrigger[];
|
|
41
|
+
initialInteraction?: FormInteractionSnapshot;
|
|
42
|
+
};
|
|
43
|
+
context: {
|
|
44
|
+
values: QwFormValues;
|
|
45
|
+
errors: FormErrorField[];
|
|
46
|
+
touched: string[];
|
|
47
|
+
validated: string[];
|
|
48
|
+
validating: string[];
|
|
49
|
+
submitStatus: FormSubmitStatus;
|
|
50
|
+
};
|
|
51
|
+
refs: {
|
|
52
|
+
runtime: FormRuntime;
|
|
53
|
+
};
|
|
54
|
+
state: "ready";
|
|
55
|
+
event: {
|
|
56
|
+
type: "VALUES.SET";
|
|
57
|
+
values: QwFormValues;
|
|
58
|
+
};
|
|
59
|
+
action: "setValues";
|
|
60
|
+
effect: "lifecycle" | "trackNative";
|
|
61
|
+
}
|
|
62
|
+
export type QwFormService = Service<QwFormSchema>;
|
|
63
|
+
export type QwFormMachine = Machine<QwFormSchema>;
|
|
64
|
+
/** Drop in-flight submit busy. Reconnect cannot resume the old promise. */
|
|
65
|
+
export declare function normalizeFormInteraction(snapshot: FormInteractionSnapshot | undefined): FormInteractionSnapshot | undefined;
|
|
66
|
+
export declare function normalizeFormFields(fields: QwFormFieldDefinition[]): QwFormFieldDefinition[];
|
|
67
|
+
export declare function createFormProps(props: QwFormProps & {
|
|
68
|
+
initialInteraction?: FormInteractionSnapshot;
|
|
69
|
+
}): QwFormSchema["props"];
|
|
70
|
+
export declare const formMachine: QwFormMachine;
|
|
71
|
+
/** Unknown and disabled choices stay stored but are not fabricated into the submit snapshot. */
|
|
72
|
+
export declare function submittedFieldValue(field: QwFormFieldDefinition, value: QwFormValue | undefined): {
|
|
73
|
+
include: boolean;
|
|
74
|
+
value?: QwFormValue;
|
|
75
|
+
};
|
|
76
|
+
/** Headless behavior API; DOM/getter transport is composed separately. */
|
|
77
|
+
export declare function connectFormBehavior(service: QwFormService): {
|
|
78
|
+
readonly values: QwFormValues;
|
|
79
|
+
readonly state: QwFormState;
|
|
80
|
+
getValues: () => QwFormValues;
|
|
81
|
+
getState: () => QwFormState;
|
|
82
|
+
getFieldState: (name: QwNamePath) => FormFieldState;
|
|
83
|
+
getInteractionSnapshot: () => FormInteractionSnapshot;
|
|
84
|
+
getFieldValue: (name: QwNamePath) => QwFormValue | undefined;
|
|
85
|
+
setFieldValue: (name: QwNamePath, value: QwFormValue | undefined) => void;
|
|
86
|
+
setFieldsValue: (patch: QwFormValues) => void;
|
|
87
|
+
setFieldErrors: (name: QwNamePath, errors: string[]) => void;
|
|
88
|
+
validateFields: (names?: QwNamePath[], options?: {
|
|
89
|
+
validateOnly?: boolean;
|
|
90
|
+
trigger?: FormValidationTrigger;
|
|
91
|
+
}) => Promise<FormValidationResult>;
|
|
92
|
+
resetFields: (names?: QwNamePath[]) => void;
|
|
93
|
+
submit: () => Promise<FormSubmitResult>;
|
|
94
|
+
cancelSubmit: () => void;
|
|
95
|
+
changeFieldFromUser: (name: QwNamePath, value: QwFormValue | undefined) => void;
|
|
96
|
+
blurField: (name: QwNamePath) => void;
|
|
97
|
+
focusField: (name: QwNamePath) => boolean;
|
|
98
|
+
initialFieldValue: (name: QwNamePath) => QwFormValue | undefined;
|
|
99
|
+
};
|
|
100
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type QwNamePath } from "./model.js";
|
|
2
|
+
/** HTML form id owned by one Core instance. */
|
|
3
|
+
export declare function formDomId(scopeId: string): string;
|
|
4
|
+
/** Accessible name target for the form landmark. */
|
|
5
|
+
export declare function formLabelId(scopeId: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* Stable field stem. `formFieldKey` is the injective NamePath encoding.
|
|
8
|
+
* Field root id is `field:` plus this stem.
|
|
9
|
+
*/
|
|
10
|
+
export declare function formFieldStem(scopeId: string, name: QwNamePath): string;
|
|
11
|
+
/** Actual control id shared by Input, selection and raw native inputs. */
|
|
12
|
+
export declare function formControlStem(scopeId: string, name: QwNamePath): string;
|
|
13
|
+
/** Field root id produced by `resolveFieldState`. */
|
|
14
|
+
export declare function formFieldRootId(scopeId: string, name: QwNamePath): string;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { FORM_PARTS, connectForm } from "./connect.js";
|
|
2
|
+
export { connectFormBehavior, createFormProps, formMachine, normalizeFormFields, normalizeFormInteraction, submittedFieldValue } from "./form.js";
|
|
3
|
+
export { trackFormNative } from "./native.js";
|
|
4
|
+
export type { FormNativePort } from "./native.js";
|
|
5
|
+
export type { QwFormMachine, QwFormSchema, QwFormService } from "./form.js";
|
|
6
|
+
export { formControlStem, formDomId, formFieldRootId, formFieldStem, formLabelId } from "./ids.js";
|
|
7
|
+
export { cloneFormValue, cloneFormValues, formFieldKey, formFieldNativeName, formValueFingerprint, formValuesEqual, freezeFormValues, getFormValue, hasFormValue, mergeFormValues, normalizeFormNamePath, setFormValue } from "./model.js";
|
|
8
|
+
export type { FormNamePath, QwFormValue, QwFormValues, QwNamePath } from "./model.js";
|
|
9
|
+
export { FORM_DEFAULT_MESSAGES, FORM_MESSAGES_EN, formErrorMessage, isFormEmpty, normalizeFormRule, validateFormRule } from "./rules.js";
|
|
10
|
+
export type { FormMessages, FormRule, FormRuleContext, FormRuleType, FormValidationTrigger } from "./rules.js";
|
|
11
|
+
export { assertFormMethodReady, invokeFormApi } from "./methods.js";
|
|
12
|
+
export { assertFormSsrProps } from "./ssr.js";
|
|
13
|
+
export type { FormCancelReason, FormControlKind, FormErrorField, FormFieldState, FormFieldValidationStatus, FormInputType, FormInteractionSnapshot, FormNormalizer, FormSubmitHandler, FormSubmitResult, FormSubmitStatus, FormValidationResult, QwFormApi, QwFormFieldDefinition, QwFormProps, QwFormState } from "./types.js";
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { C as setFormValue, S as normalizeFormNamePath, _ as formValuesEqual, b as hasFormValue, f as cloneFormValue, g as formValueFingerprint, h as formFieldNativeName, m as formFieldKey, p as cloneFormValues, v as freezeFormValues, x as mergeFormValues, y as getFormValue } from "../field-DMHGIMZF.js";
|
|
2
|
+
import { C as formLabelId, S as formFieldStem, _ as validateFormRule, a as connectForm, b as formDomId, c as formMachine, d as submittedFieldValue, f as FORM_DEFAULT_MESSAGES, g as normalizeFormRule, h as isFormEmpty, i as FORM_PARTS, l as normalizeFormFields, m as formErrorMessage, n as assertFormMethodReady, o as connectFormBehavior, p as FORM_MESSAGES_EN, r as invokeFormApi, s as createFormProps, t as assertFormSsrProps, u as normalizeFormInteraction, v as trackFormNative, x as formFieldRootId, y as formControlStem } from "../form-BAGkIEMY.js";
|
|
3
|
+
export { FORM_DEFAULT_MESSAGES, FORM_MESSAGES_EN, FORM_PARTS, assertFormMethodReady, assertFormSsrProps, cloneFormValue, cloneFormValues, connectForm, connectFormBehavior, createFormProps, formControlStem, formDomId, formErrorMessage, formFieldKey, formFieldNativeName, formFieldRootId, formFieldStem, formLabelId, formMachine, formValueFingerprint, formValuesEqual, freezeFormValues, getFormValue, hasFormValue, invokeFormApi, isFormEmpty, mergeFormValues, normalizeFormFields, normalizeFormInteraction, normalizeFormNamePath, normalizeFormRule, setFormValue, submittedFieldValue, trackFormNative, validateFormRule };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { QwFormApi } from "./types.js";
|
|
2
|
+
/** Live Core dispatch for a connected native method. Unknown names throw. */
|
|
3
|
+
export declare function invokeFormApi(api: QwFormApi, method: string, args?: readonly unknown[]): unknown;
|
|
4
|
+
/** Hosts call this before invoke. Disconnected or not-yet-ready calls throw. */
|
|
5
|
+
export declare function assertFormMethodReady(ready: boolean): void;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Finite JSON values form the public value/SSR boundary. */
|
|
2
|
+
export type QwFormValue = string | number | boolean | null | QwFormValue[] | {
|
|
3
|
+
[key: string]: QwFormValue;
|
|
4
|
+
};
|
|
5
|
+
export type QwFormValues = Record<string, QwFormValue>;
|
|
6
|
+
export type QwNamePath = string | readonly (string | number)[];
|
|
7
|
+
export type FormNamePath = (string | number)[];
|
|
8
|
+
/** Strings are literal single segments, never implicit dot/bracket parsing. */
|
|
9
|
+
export declare function normalizeFormNamePath(name: unknown): FormNamePath;
|
|
10
|
+
export declare function formFieldKey(name: QwNamePath): string;
|
|
11
|
+
export declare function formFieldNativeName(name: QwNamePath): string;
|
|
12
|
+
export declare function cloneFormValue(value: unknown): QwFormValue;
|
|
13
|
+
export declare function cloneFormValues(values?: unknown): QwFormValues;
|
|
14
|
+
/** Fresh recursively frozen validator snapshot; never freeze caller storage. */
|
|
15
|
+
export declare function freezeFormValues(values: QwFormValues): Readonly<QwFormValues>;
|
|
16
|
+
/** Canonical comparison keeps object key order from manufacturing dirty changes. */
|
|
17
|
+
export declare function formValueFingerprint(value: QwFormValue | undefined): string;
|
|
18
|
+
export declare function formValuesEqual(a: QwFormValues, b: QwFormValues | undefined): boolean;
|
|
19
|
+
export declare function getFormValue(values: QwFormValues, name: QwNamePath): QwFormValue | undefined;
|
|
20
|
+
export declare function hasFormValue(values: QwFormValues, name: QwNamePath): boolean;
|
|
21
|
+
/** Immutable path update. Dense arrays retain explicit JSON semantics. */
|
|
22
|
+
export declare function setFormValue(values: QwFormValues, name: QwNamePath, value: QwFormValue | undefined): QwFormValues;
|
|
23
|
+
/** Object recursion, array replacement; all inputs and outputs are independent. */
|
|
24
|
+
export declare function mergeFormValues(values: QwFormValues, patch: QwFormValues): QwFormValues;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { SelectionFormScope } from "../selection-form.js";
|
|
2
|
+
import { type QwFormValue, type QwNamePath } from "./model.js";
|
|
3
|
+
import type { QwFormFieldDefinition } from "./types.js";
|
|
4
|
+
/** DOM port implemented by the Form machine. Adapters do not keep a second controller. */
|
|
5
|
+
export interface FormNativePort {
|
|
6
|
+
scope: SelectionFormScope & {
|
|
7
|
+
id?: string;
|
|
8
|
+
};
|
|
9
|
+
fields(): readonly QwFormFieldDefinition[];
|
|
10
|
+
value(name: QwNamePath): QwFormValue | undefined;
|
|
11
|
+
change(name: QwNamePath, value: QwFormValue | undefined): void;
|
|
12
|
+
blur(name: QwNamePath): void;
|
|
13
|
+
reset(): void;
|
|
14
|
+
suppressUser(active: boolean): void;
|
|
15
|
+
bindSync(sync: (() => void) | undefined): void;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* One client lifecycle for raw inputs, supported native selection elements,
|
|
19
|
+
* composite blur, and a single deferred reset transaction.
|
|
20
|
+
* This listener is the only raw input/change transport. Getter props must not
|
|
21
|
+
* subscribe to the same event (Vue normalizes onChange into onInput).
|
|
22
|
+
* Selection controls keep their own reset listeners; user echoes are suppressed
|
|
23
|
+
* until this transaction finishes so they cannot overwrite the Form reset.
|
|
24
|
+
*/
|
|
25
|
+
export declare function trackFormNative(port: FormNativePort): () => void;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type FormNamePath, type QwFormValue, type QwFormValues } from "./model.js";
|
|
2
|
+
export type FormValidationTrigger = "change" | "blur" | "submit" | "manual";
|
|
3
|
+
export type FormRuleType = "string" | "number" | "boolean" | "array" | "email" | "url";
|
|
4
|
+
export interface FormRuleContext {
|
|
5
|
+
name: FormNamePath;
|
|
6
|
+
label: string;
|
|
7
|
+
values: Readonly<QwFormValues>;
|
|
8
|
+
signal: AbortSignal;
|
|
9
|
+
messages?: Partial<FormMessages>;
|
|
10
|
+
}
|
|
11
|
+
export interface FormRule {
|
|
12
|
+
required?: boolean;
|
|
13
|
+
type?: FormRuleType;
|
|
14
|
+
min?: number;
|
|
15
|
+
max?: number;
|
|
16
|
+
length?: number;
|
|
17
|
+
pattern?: string;
|
|
18
|
+
flags?: string;
|
|
19
|
+
enum?: QwFormValue[];
|
|
20
|
+
message?: string;
|
|
21
|
+
trigger?: FormValidationTrigger | FormValidationTrigger[];
|
|
22
|
+
validator?: (value: QwFormValue | undefined, context: FormRuleContext) => boolean | string | void | Promise<boolean | string | void>;
|
|
23
|
+
}
|
|
24
|
+
export interface FormMessages {
|
|
25
|
+
required: string;
|
|
26
|
+
type: string;
|
|
27
|
+
min: string;
|
|
28
|
+
max: string;
|
|
29
|
+
length: string;
|
|
30
|
+
pattern: string;
|
|
31
|
+
enum: string;
|
|
32
|
+
validator: string;
|
|
33
|
+
}
|
|
34
|
+
export declare const FORM_DEFAULT_MESSAGES: Readonly<FormMessages>;
|
|
35
|
+
export declare const FORM_MESSAGES_EN: Readonly<FormMessages>;
|
|
36
|
+
export declare function normalizeFormRule(rule: FormRule): FormRule;
|
|
37
|
+
export declare function isFormEmpty(value: QwFormValue | undefined): boolean;
|
|
38
|
+
export declare function formErrorMessage(error: unknown, fallback?: string): string;
|
|
39
|
+
/** One rule returns explicit errors; request ownership is checked by the Form engine. */
|
|
40
|
+
export declare function validateFormRule(input: FormRule, value: QwFormValue | undefined, context: FormRuleContext): Promise<string[]>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { QwFormProps } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* SSR accepts builtin JSON rules only.
|
|
4
|
+
* Custom validators and business handlers are runtime values: encountering one throws.
|
|
5
|
+
* Nothing is eval'd or silently dropped.
|
|
6
|
+
*/
|
|
7
|
+
export declare function assertFormSsrProps(props: QwFormProps): void;
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import type { QwInputProps } from "../input/index.js";
|
|
2
|
+
import type { QwCheckboxProps } from "../checkbox/index.js";
|
|
3
|
+
import type { QwRadioGroupProps } from "../radio-group/index.js";
|
|
4
|
+
import type { QwSegmentedProps, QwSegmentedItem, SegmentedSelectionMode } from "../segmented/index.js";
|
|
5
|
+
import type { QwFieldProps } from "../field/index.js";
|
|
6
|
+
import type { QwFormValue, QwFormValues, QwNamePath, FormNamePath } from "./model.js";
|
|
7
|
+
import type { FormMessages, FormRule, FormValidationTrigger } from "./rules.js";
|
|
8
|
+
import type { NormalizeProps, PropTypes } from "@zag-js/types";
|
|
9
|
+
export type FormControlKind = "native" | "input" | "checkbox" | "radio-group" | "segmented" | "custom";
|
|
10
|
+
export type FormInputType = "text" | "email" | "tel" | "url" | "password" | "search" | "number" | "checkbox";
|
|
11
|
+
export interface QwFormFieldDefinition {
|
|
12
|
+
name: QwNamePath;
|
|
13
|
+
label: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
controlDescription?: string;
|
|
16
|
+
nativeName?: string;
|
|
17
|
+
control?: FormControlKind;
|
|
18
|
+
inputType?: FormInputType;
|
|
19
|
+
items?: QwSegmentedItem[];
|
|
20
|
+
selectionMode?: SegmentedSelectionMode;
|
|
21
|
+
initialValue?: QwFormValue;
|
|
22
|
+
rules?: FormRule[];
|
|
23
|
+
dependencies?: QwNamePath[];
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
readOnly?: boolean;
|
|
26
|
+
required?: boolean;
|
|
27
|
+
preserve?: boolean;
|
|
28
|
+
validateTrigger?: FormValidationTrigger | FormValidationTrigger[];
|
|
29
|
+
}
|
|
30
|
+
export interface FormErrorField {
|
|
31
|
+
name: FormNamePath;
|
|
32
|
+
errors: string[];
|
|
33
|
+
}
|
|
34
|
+
export type FormFieldValidationStatus = "unvalidated" | "validating" | "valid" | "invalid";
|
|
35
|
+
export interface FormFieldState {
|
|
36
|
+
name: FormNamePath;
|
|
37
|
+
value: QwFormValue | undefined;
|
|
38
|
+
errors: string[];
|
|
39
|
+
touched: boolean;
|
|
40
|
+
dirty: boolean;
|
|
41
|
+
validationStatus: FormFieldValidationStatus;
|
|
42
|
+
disabled: boolean;
|
|
43
|
+
readOnly: boolean;
|
|
44
|
+
required: boolean;
|
|
45
|
+
}
|
|
46
|
+
export type FormSubmitStatus = "idle" | "validating" | "submitting" | "success" | "invalid" | "error" | "canceled";
|
|
47
|
+
/** Confirmed interaction restored after a native reconnect. In-flight validation is not included. */
|
|
48
|
+
export interface FormInteractionSnapshot {
|
|
49
|
+
readonly errors: readonly FormErrorField[];
|
|
50
|
+
readonly touched: readonly string[];
|
|
51
|
+
readonly validated: readonly string[];
|
|
52
|
+
readonly submitStatus: FormSubmitStatus;
|
|
53
|
+
}
|
|
54
|
+
export interface QwFormState {
|
|
55
|
+
values: QwFormValues;
|
|
56
|
+
fieldStates: FormFieldState[];
|
|
57
|
+
submitting: boolean;
|
|
58
|
+
submitStatus: FormSubmitStatus;
|
|
59
|
+
}
|
|
60
|
+
export type FormCancelReason = "superseded" | "values-change" | "reset" | "cancel" | "fields-change" | "unmount";
|
|
61
|
+
export interface FormValidationResult {
|
|
62
|
+
values: QwFormValues;
|
|
63
|
+
errorFields: FormErrorField[];
|
|
64
|
+
outOfDate: boolean;
|
|
65
|
+
canceled: boolean;
|
|
66
|
+
}
|
|
67
|
+
export interface FormSubmitResult {
|
|
68
|
+
status: "success" | "invalid" | "error" | "canceled";
|
|
69
|
+
values: QwFormValues;
|
|
70
|
+
errorFields: FormErrorField[];
|
|
71
|
+
error?: string;
|
|
72
|
+
reason?: FormCancelReason;
|
|
73
|
+
}
|
|
74
|
+
export type FormSubmitHandler = (values: QwFormValues, context: {
|
|
75
|
+
signal: AbortSignal;
|
|
76
|
+
}) => void | Promise<void>;
|
|
77
|
+
export interface QwFormProps {
|
|
78
|
+
id?: string;
|
|
79
|
+
label: string;
|
|
80
|
+
fields: QwFormFieldDefinition[];
|
|
81
|
+
values?: QwFormValues;
|
|
82
|
+
initialValues?: QwFormValues;
|
|
83
|
+
initialErrors?: FormErrorField[];
|
|
84
|
+
disabled?: boolean;
|
|
85
|
+
readOnly?: boolean;
|
|
86
|
+
validateTrigger?: FormValidationTrigger | FormValidationTrigger[];
|
|
87
|
+
validateFirst?: boolean;
|
|
88
|
+
focusFirstError?: boolean;
|
|
89
|
+
messages?: Partial<FormMessages>;
|
|
90
|
+
onValuesChange?: (details: {
|
|
91
|
+
values: QwFormValues;
|
|
92
|
+
}) => void;
|
|
93
|
+
onValidationChange?: (details: {
|
|
94
|
+
state: QwFormState;
|
|
95
|
+
}) => void;
|
|
96
|
+
onSubmit?: FormSubmitHandler;
|
|
97
|
+
onSubmitSuccess?: (details: {
|
|
98
|
+
values: QwFormValues;
|
|
99
|
+
}) => void;
|
|
100
|
+
onValidationFailed?: (details: {
|
|
101
|
+
values: QwFormValues;
|
|
102
|
+
errorFields: FormErrorField[];
|
|
103
|
+
}) => void;
|
|
104
|
+
onSubmitError?: (details: {
|
|
105
|
+
values: QwFormValues;
|
|
106
|
+
error: string;
|
|
107
|
+
}) => void;
|
|
108
|
+
onSubmitCancel?: (details: {
|
|
109
|
+
reason: FormCancelReason;
|
|
110
|
+
}) => void;
|
|
111
|
+
}
|
|
112
|
+
/** API methods always read live Core; returned state/values never expose internal storage. */
|
|
113
|
+
export interface QwFormApi<T extends PropTypes = PropTypes> {
|
|
114
|
+
readonly values: QwFormValues;
|
|
115
|
+
readonly state: QwFormState;
|
|
116
|
+
getValues(): QwFormValues;
|
|
117
|
+
getFieldValue(name: QwNamePath): QwFormValue | undefined;
|
|
118
|
+
getFieldState(name: QwNamePath): FormFieldState;
|
|
119
|
+
/** Live confirmed errors, touch, and submit status. Busy submit is settled only when a new machine applies it. */
|
|
120
|
+
getInteractionSnapshot(): FormInteractionSnapshot;
|
|
121
|
+
setFieldValue(name: QwNamePath, value: QwFormValue | undefined): void;
|
|
122
|
+
setFieldsValue(values: QwFormValues): void;
|
|
123
|
+
setFieldErrors(name: QwNamePath, errors: string[]): void;
|
|
124
|
+
validateFields(names?: QwNamePath[], options?: {
|
|
125
|
+
validateOnly?: boolean;
|
|
126
|
+
trigger?: FormValidationTrigger;
|
|
127
|
+
}): Promise<FormValidationResult>;
|
|
128
|
+
submit(): Promise<FormSubmitResult>;
|
|
129
|
+
cancelSubmit(): void;
|
|
130
|
+
resetFields(names?: QwNamePath[]): void;
|
|
131
|
+
focusField(name: QwNamePath): boolean;
|
|
132
|
+
getRootProps(): T["element"];
|
|
133
|
+
getLabelProps(): T["element"];
|
|
134
|
+
getContentProps(): T["element"];
|
|
135
|
+
getErrorSummaryProps(): T["element"];
|
|
136
|
+
getErrorListProps(): T["element"];
|
|
137
|
+
getErrorItemProps(name: QwNamePath): T["element"];
|
|
138
|
+
getErrorLinkProps(name: QwNamePath): T["element"];
|
|
139
|
+
getFooterProps(): T["element"];
|
|
140
|
+
getFieldProps(name: QwNamePath): QwFieldProps;
|
|
141
|
+
getInputProps(name: QwNamePath): QwInputProps;
|
|
142
|
+
getCheckboxProps(name: QwNamePath): QwCheckboxProps;
|
|
143
|
+
getRadioGroupProps(name: QwNamePath): QwRadioGroupProps;
|
|
144
|
+
getSegmentedProps(name: QwNamePath): QwSegmentedProps;
|
|
145
|
+
getNativeControlProps(name: QwNamePath): T["input"];
|
|
146
|
+
getNativeElementProps(name: QwNamePath): Record<string, unknown>;
|
|
147
|
+
/** Spreadable readonly text group. No tab stop and no htmlFor. */
|
|
148
|
+
getReadonlyProps(name: QwNamePath): T["element"];
|
|
149
|
+
}
|
|
150
|
+
export type FormNormalizer<T extends PropTypes> = NormalizeProps<T>;
|