@xihan-ui/vue 1.0.0-alpha.3 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2057 -0
- package/dist/backgrounds.d.ts.map +1 -1
- package/dist/backgrounds.js +1 -5
- package/dist/backgrounds.js.map +1 -1
- package/dist/behavior.d.ts +38 -0
- package/dist/behavior.d.ts.map +1 -0
- package/dist/behavior.js +74 -0
- package/dist/behavior.js.map +1 -0
- package/dist/components/accordion/accordion.d.ts +1 -1
- package/dist/components/accordion/context.js +2 -2
- package/dist/components/accordion/context.js.map +1 -1
- package/dist/components/affix/context.js +1 -1
- package/dist/components/affix/context.js.map +1 -1
- package/dist/components/alert/context.js +1 -1
- package/dist/components/alert/context.js.map +1 -1
- package/dist/components/anchor/anchor.d.ts +2 -2
- package/dist/components/anchor/context.js +1 -1
- package/dist/components/anchor/context.js.map +1 -1
- package/dist/components/avatar/context.js +1 -1
- package/dist/components/avatar/context.js.map +1 -1
- package/dist/components/avatar-group/context.js +1 -1
- package/dist/components/avatar-group/context.js.map +1 -1
- package/dist/components/back-top/back-top.d.ts +2 -2
- package/dist/components/back-top/context.js +1 -1
- package/dist/components/back-top/context.js.map +1 -1
- package/dist/components/badge/badge.d.ts +142 -50
- package/dist/components/badge/badge.d.ts.map +1 -1
- package/dist/components/badge/badge.js +67 -37
- package/dist/components/badge/badge.js.map +1 -1
- package/dist/components/badge/context.js +15 -0
- package/dist/components/badge/context.js.map +1 -0
- package/dist/components/breadcrumb/breadcrumb.d.ts +1 -1
- package/dist/components/breadcrumb/context.js +1 -1
- package/dist/components/breadcrumb/context.js.map +1 -1
- package/dist/components/button-group/button-group.d.ts +1 -1
- package/dist/components/calendar/context.js +2 -2
- package/dist/components/calendar/context.js.map +1 -1
- package/dist/components/card/card.d.ts +1 -1
- package/dist/components/card/context.js +1 -1
- package/dist/components/card/context.js.map +1 -1
- package/dist/components/carousel/context.js +1 -1
- package/dist/components/carousel/context.js.map +1 -1
- package/dist/components/cascader/cascader.d.ts +4 -4
- package/dist/components/cascader/cascader.d.ts.map +1 -1
- package/dist/components/cascader/cascader.js +14 -4
- package/dist/components/cascader/cascader.js.map +1 -1
- package/dist/components/cascader/context.js +2 -2
- package/dist/components/cascader/context.js.map +1 -1
- package/dist/components/cascader/use-cascader.js +1 -1
- package/dist/components/cascader/use-cascader.js.map +1 -1
- package/dist/components/checkbox-group/context.js +2 -2
- package/dist/components/checkbox-group/context.js.map +1 -1
- package/dist/components/clipboard/context.js +1 -1
- package/dist/components/clipboard/context.js.map +1 -1
- package/dist/components/collapsible/context.js +1 -1
- package/dist/components/collapsible/context.js.map +1 -1
- package/dist/components/color-picker/color-picker.d.ts +12 -3
- package/dist/components/color-picker/color-picker.d.ts.map +1 -1
- package/dist/components/color-picker/color-picker.js +7 -1
- package/dist/components/color-picker/color-picker.js.map +1 -1
- package/dist/components/color-picker/context.js +2 -2
- package/dist/components/color-picker/context.js.map +1 -1
- package/dist/components/color-picker/use-color-picker.js +1 -1
- package/dist/components/color-picker/use-color-picker.js.map +1 -1
- package/dist/components/combobox/combobox.d.ts +3 -3
- package/dist/components/combobox/combobox.d.ts.map +1 -1
- package/dist/components/combobox/combobox.js +10 -4
- package/dist/components/combobox/combobox.js.map +1 -1
- package/dist/components/combobox/context.js +3 -3
- package/dist/components/combobox/context.js.map +1 -1
- package/dist/components/combobox/use-combobox.js +1 -1
- package/dist/components/combobox/use-combobox.js.map +1 -1
- package/dist/components/composer/context.js +1 -1
- package/dist/components/composer/context.js.map +1 -1
- package/dist/components/context-menu/context-menu.d.ts +4 -4
- package/dist/components/context-menu/context-menu.d.ts.map +1 -1
- package/dist/components/context-menu/context-menu.js +3 -1
- package/dist/components/context-menu/context-menu.js.map +1 -1
- package/dist/components/context-menu/context.js +5 -5
- package/dist/components/context-menu/context.js.map +1 -1
- package/dist/components/context-menu/use-context-menu.js +1 -1
- package/dist/components/context-menu/use-context-menu.js.map +1 -1
- package/dist/components/date-field/context.js +1 -1
- package/dist/components/date-field/context.js.map +1 -1
- package/dist/components/date-field/date-field.d.ts +2 -2
- package/dist/components/date-picker/context.js +13 -4
- package/dist/components/date-picker/context.js.map +1 -1
- package/dist/components/date-picker/date-picker.d.ts +80 -44
- package/dist/components/date-picker/date-picker.d.ts.map +1 -1
- package/dist/components/date-picker/date-picker.js +68 -26
- package/dist/components/date-picker/date-picker.js.map +1 -1
- package/dist/components/date-picker/use-date-picker.js +1 -1
- package/dist/components/date-picker/use-date-picker.js.map +1 -1
- package/dist/components/descriptions/context.js +1 -1
- package/dist/components/descriptions/context.js.map +1 -1
- package/dist/components/dialog/context.js +1 -1
- package/dist/components/dialog/context.js.map +1 -1
- package/dist/components/dialog/dialog.d.ts +1 -1
- package/dist/components/drawer/context.js +1 -1
- package/dist/components/drawer/context.js.map +1 -1
- package/dist/components/drawer/drawer.d.ts +2 -2
- package/dist/components/dynamic-input/context.js +2 -2
- package/dist/components/dynamic-input/context.js.map +1 -1
- package/dist/components/editable/context.js +1 -1
- package/dist/components/editable/context.js.map +1 -1
- package/dist/components/empty-state/context.js +1 -1
- package/dist/components/empty-state/context.js.map +1 -1
- package/dist/components/field/context.d.ts +9 -0
- package/dist/components/field/context.d.ts.map +1 -0
- package/dist/components/field/context.js +6 -2
- package/dist/components/field/context.js.map +1 -1
- package/dist/components/field/field.d.ts +26 -2
- package/dist/components/field/field.d.ts.map +1 -1
- package/dist/components/field/field.js +15 -4
- package/dist/components/field/field.js.map +1 -1
- package/dist/components/field/use-field-control.d.ts +41 -0
- package/dist/components/field/use-field-control.d.ts.map +1 -0
- package/dist/components/field/use-field-control.js +77 -0
- package/dist/components/field/use-field-control.js.map +1 -0
- package/dist/components/fieldset/context.js +1 -1
- package/dist/components/fieldset/context.js.map +1 -1
- package/dist/components/file-upload/context.js +2 -2
- package/dist/components/file-upload/context.js.map +1 -1
- package/dist/components/flex/flex.d.ts +9 -0
- package/dist/components/flex/flex.d.ts.map +1 -1
- package/dist/components/flex/flex.js +4 -0
- package/dist/components/flex/flex.js.map +1 -1
- package/dist/components/float-button/context.js +1 -1
- package/dist/components/float-button/context.js.map +1 -1
- package/dist/components/float-button/float-button.d.ts +2 -2
- package/dist/components/floating-panel/context.js +1 -1
- package/dist/components/floating-panel/context.js.map +1 -1
- package/dist/components/floating-panel/floating-panel.d.ts +1 -1
- package/dist/components/form/context.js +2 -2
- package/dist/components/form/context.js.map +1 -1
- package/dist/components/grid/context.js +1 -1
- package/dist/components/grid/context.js.map +1 -1
- package/dist/components/heatmap/context.js +3 -3
- package/dist/components/heatmap/context.js.map +1 -1
- package/dist/components/heatmap/heatmap.d.ts +1 -1
- package/dist/components/hotkeys/hotkeys.d.ts +3 -1
- package/dist/components/hotkeys/hotkeys.d.ts.map +1 -1
- package/dist/components/hotkeys/hotkeys.js +7 -25
- package/dist/components/hotkeys/hotkeys.js.map +1 -1
- package/dist/components/hotkeys/use-hotkeys.d.ts +31 -0
- package/dist/components/hotkeys/use-hotkeys.d.ts.map +1 -0
- package/dist/components/hotkeys/use-hotkeys.js +60 -0
- package/dist/components/hotkeys/use-hotkeys.js.map +1 -0
- package/dist/components/hover-card/context.js +1 -1
- package/dist/components/hover-card/context.js.map +1 -1
- package/dist/components/hover-card/hover-card.d.ts +2 -2
- package/dist/components/hover-card/hover-card.d.ts.map +1 -1
- package/dist/components/hover-card/hover-card.js +3 -1
- package/dist/components/hover-card/hover-card.js.map +1 -1
- package/dist/components/hover-card/use-hover-card.js +1 -1
- package/dist/components/hover-card/use-hover-card.js.map +1 -1
- package/dist/components/icon/icon.d.ts +1 -1
- package/dist/components/icon-wrapper/icon-wrapper.d.ts +1 -1
- package/dist/components/image/context.js +1 -1
- package/dist/components/image/context.js.map +1 -1
- package/dist/components/image-cropper/context.js +1 -1
- package/dist/components/image-cropper/context.js.map +1 -1
- package/dist/components/image-cropper/image-cropper.d.ts +1 -1
- package/dist/components/image-viewer/context.js +1 -1
- package/dist/components/image-viewer/context.js.map +1 -1
- package/dist/components/image-viewer/image-viewer.d.ts +2 -2
- package/dist/components/infinite-scroll/context.js +1 -1
- package/dist/components/infinite-scroll/context.js.map +1 -1
- package/dist/components/infinite-scroll/infinite-scroll.d.ts +1 -1
- package/dist/components/json-viewer/json-viewer.d.ts +12 -3
- package/dist/components/json-viewer/json-viewer.d.ts.map +1 -1
- package/dist/components/json-viewer/json-viewer.js +23 -2
- package/dist/components/json-viewer/json-viewer.js.map +1 -1
- package/dist/components/layout/context.js +1 -1
- package/dist/components/layout/context.js.map +1 -1
- package/dist/components/list/context.js +1 -1
- package/dist/components/list/context.js.map +1 -1
- package/dist/components/list/list.d.ts +1 -1
- package/dist/components/listbox/context.js +3 -3
- package/dist/components/listbox/context.js.map +1 -1
- package/dist/components/loading-bar/context.js +1 -1
- package/dist/components/loading-bar/context.js.map +1 -1
- package/dist/components/log/context.js +1 -1
- package/dist/components/log/context.js.map +1 -1
- package/dist/components/marquee/context.js +1 -1
- package/dist/components/marquee/context.js.map +1 -1
- package/dist/components/mention/context.js +2 -2
- package/dist/components/mention/context.js.map +1 -1
- package/dist/components/mention/mention.d.ts +2 -2
- package/dist/components/mention/mention.d.ts.map +1 -1
- package/dist/components/mention/mention.js +10 -4
- package/dist/components/mention/mention.js.map +1 -1
- package/dist/components/mention/use-mention.js +1 -1
- package/dist/components/mention/use-mention.js.map +1 -1
- package/dist/components/menu/context.js +4 -4
- package/dist/components/menu/context.js.map +1 -1
- package/dist/components/menu/menu.d.ts +3 -3
- package/dist/components/menu/menu.d.ts.map +1 -1
- package/dist/components/menu/menu.js +3 -1
- package/dist/components/menu/menu.js.map +1 -1
- package/dist/components/menu/use-menu.js +1 -1
- package/dist/components/menu/use-menu.js.map +1 -1
- package/dist/components/menubar/context.js +6 -6
- package/dist/components/menubar/context.js.map +1 -1
- package/dist/components/menubar/menubar.d.ts +2 -2
- package/dist/components/menubar/menubar.js.map +1 -1
- package/dist/components/navigation-menu/context.js +1 -1
- package/dist/components/navigation-menu/context.js.map +1 -1
- package/dist/components/navigation-menu/navigation-menu.d.ts +1 -1
- package/dist/components/notification/context.d.ts +23 -0
- package/dist/components/notification/context.d.ts.map +1 -0
- package/dist/components/notification/context.js +28 -0
- package/dist/components/notification/context.js.map +1 -0
- package/dist/components/notification/notification.d.ts +249 -0
- package/dist/components/notification/notification.d.ts.map +1 -0
- package/dist/components/notification/notification.js +179 -0
- package/dist/components/notification/notification.js.map +1 -0
- package/dist/components/notification/use-notification.d.ts +14 -0
- package/dist/components/notification/use-notification.d.ts.map +1 -0
- package/dist/components/notification/use-notification.js +42 -0
- package/dist/components/notification/use-notification.js.map +1 -0
- package/dist/components/number-animation/number-animation.d.ts +1 -1
- package/dist/components/number-field/context.js +1 -1
- package/dist/components/number-field/context.js.map +1 -1
- package/dist/components/number-field/number-field.d.ts +3 -3
- package/dist/components/number-field/number-field.d.ts.map +1 -1
- package/dist/components/number-field/number-field.js +7 -1
- package/dist/components/number-field/number-field.js.map +1 -1
- package/dist/components/page-header/context.js +1 -1
- package/dist/components/page-header/context.js.map +1 -1
- package/dist/components/pagination/context.js +1 -1
- package/dist/components/pagination/context.js.map +1 -1
- package/dist/components/pagination/pagination.d.ts +60 -6
- package/dist/components/pagination/pagination.d.ts.map +1 -1
- package/dist/components/pagination/pagination.js +85 -5
- package/dist/components/pagination/pagination.js.map +1 -1
- package/dist/components/pagination/use-pagination.d.ts +12 -2
- package/dist/components/pagination/use-pagination.d.ts.map +1 -1
- package/dist/components/pagination/use-pagination.js +50 -5
- package/dist/components/pagination/use-pagination.js.map +1 -1
- package/dist/components/password-input/context.js +1 -1
- package/dist/components/password-input/context.js.map +1 -1
- package/dist/components/password-input/password-input.d.ts +2 -2
- package/dist/components/password-input/password-input.d.ts.map +1 -1
- package/dist/components/password-input/password-input.js +7 -1
- package/dist/components/password-input/password-input.js.map +1 -1
- package/dist/components/pin-input/context.js +1 -1
- package/dist/components/pin-input/context.js.map +1 -1
- package/dist/components/pin-input/pin-input.d.ts +1 -1
- package/dist/components/popconfirm/context.js +1 -1
- package/dist/components/popconfirm/context.js.map +1 -1
- package/dist/components/popconfirm/popconfirm.d.ts +1 -1
- package/dist/components/popover/context.js +1 -1
- package/dist/components/popover/context.js.map +1 -1
- package/dist/components/popover/popover.d.ts +2 -2
- package/dist/components/popover/popover.d.ts.map +1 -1
- package/dist/components/popover/popover.js +3 -1
- package/dist/components/popover/popover.js.map +1 -1
- package/dist/components/popover/use-popover.js +1 -1
- package/dist/components/popover/use-popover.js.map +1 -1
- package/dist/components/popselect/context.js +2 -2
- package/dist/components/popselect/context.js.map +1 -1
- package/dist/components/popselect/popselect.d.ts +3 -3
- package/dist/components/popselect/popselect.d.ts.map +1 -1
- package/dist/components/popselect/popselect.js +3 -1
- package/dist/components/popselect/popselect.js.map +1 -1
- package/dist/components/popselect/use-popselect.js +1 -1
- package/dist/components/popselect/use-popselect.js.map +1 -1
- package/dist/components/progress/progress.d.ts +1 -1
- package/dist/components/qr-code/context.js +1 -1
- package/dist/components/qr-code/context.js.map +1 -1
- package/dist/components/radio-group/context.js +2 -2
- package/dist/components/radio-group/context.js.map +1 -1
- package/dist/components/radio-group/radio-group.d.ts +1 -1
- package/dist/components/rating/context.js +1 -1
- package/dist/components/rating/context.js.map +1 -1
- package/dist/components/rating/rating.d.ts +2 -2
- package/dist/components/result/context.js +1 -1
- package/dist/components/result/context.js.map +1 -1
- package/dist/components/scroll-area/context.js +2 -2
- package/dist/components/scroll-area/context.js.map +1 -1
- package/dist/components/scroll-area/scroll-area.d.ts +1 -1
- package/dist/components/scrollbar/context.js +1 -1
- package/dist/components/scrollbar/context.js.map +1 -1
- package/dist/components/scrollbar/scrollbar.d.ts +1 -1
- package/dist/components/segmented/context.js +2 -2
- package/dist/components/segmented/context.js.map +1 -1
- package/dist/components/segmented/segmented.d.ts +1 -1
- package/dist/components/select/context.js +3 -3
- package/dist/components/select/context.js.map +1 -1
- package/dist/components/select/select.d.ts +3 -3
- package/dist/components/select/select.d.ts.map +1 -1
- package/dist/components/select/select.js +7 -3
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/side-nav/context.js +2 -2
- package/dist/components/side-nav/context.js.map +1 -1
- package/dist/components/side-nav/side-nav.d.ts +1 -1
- package/dist/components/signature-pad/context.js +1 -1
- package/dist/components/signature-pad/context.js.map +1 -1
- package/dist/components/skeleton/context.js +1 -1
- package/dist/components/skeleton/context.js.map +1 -1
- package/dist/components/slider/context.js +2 -2
- package/dist/components/slider/context.js.map +1 -1
- package/dist/components/slider/slider.d.ts +1 -1
- package/dist/components/space/context.js +1 -1
- package/dist/components/space/context.js.map +1 -1
- package/dist/components/space/space.d.ts +9 -0
- package/dist/components/space/space.d.ts.map +1 -1
- package/dist/components/space/space.js +4 -0
- package/dist/components/space/space.js.map +1 -1
- package/dist/components/spinner/context.js +1 -1
- package/dist/components/spinner/context.js.map +1 -1
- package/dist/components/spinner/spinner.d.ts +1 -1
- package/dist/components/splitter/context.js +1 -1
- package/dist/components/splitter/context.js.map +1 -1
- package/dist/components/statistic/context.js +1 -1
- package/dist/components/statistic/context.js.map +1 -1
- package/dist/components/statistic/statistic.d.ts +1 -1
- package/dist/components/steps/context.js +2 -2
- package/dist/components/steps/context.js.map +1 -1
- package/dist/components/steps/steps.d.ts +2 -2
- package/dist/components/table/context.js +4 -4
- package/dist/components/table/context.js.map +1 -1
- package/dist/components/table/table.d.ts +62 -3
- package/dist/components/table/table.d.ts.map +1 -1
- package/dist/components/table/table.js +37 -1
- package/dist/components/table/table.js.map +1 -1
- package/dist/components/table/use-table.d.ts +1 -1
- package/dist/components/table/use-table.d.ts.map +1 -1
- package/dist/components/table/use-table.js +3 -2
- package/dist/components/table/use-table.js.map +1 -1
- package/dist/components/tabs/context.js +1 -1
- package/dist/components/tabs/context.js.map +1 -1
- package/dist/components/tabs/tabs.d.ts +1 -1
- package/dist/components/tag/context.js +1 -1
- package/dist/components/tag/context.js.map +1 -1
- package/dist/components/tag/use-tag.js +14 -2
- package/dist/components/tag/use-tag.js.map +1 -1
- package/dist/components/tags-input/context.js +2 -2
- package/dist/components/tags-input/context.js.map +1 -1
- package/dist/components/tags-input/tags-input.d.ts +3 -3
- package/dist/components/tags-input/tags-input.d.ts.map +1 -1
- package/dist/components/tags-input/tags-input.js +7 -1
- package/dist/components/tags-input/tags-input.js.map +1 -1
- package/dist/components/text-field/context.js +1 -1
- package/dist/components/text-field/context.js.map +1 -1
- package/dist/components/text-field/text-field.d.ts +1 -1
- package/dist/components/text-field/text-field.d.ts.map +1 -1
- package/dist/components/text-field/text-field.js +7 -3
- package/dist/components/text-field/text-field.js.map +1 -1
- package/dist/components/thread/context.d.ts +7 -0
- package/dist/components/thread/context.d.ts.map +1 -0
- package/dist/components/thread/context.js +1 -1
- package/dist/components/thread/context.js.map +1 -1
- package/dist/components/time-field/context.js +1 -1
- package/dist/components/time-field/context.js.map +1 -1
- package/dist/components/time-field/time-field.d.ts +2 -2
- package/dist/components/time-picker/context.js +2 -2
- package/dist/components/time-picker/context.js.map +1 -1
- package/dist/components/time-picker/time-picker.d.ts +5 -5
- package/dist/components/time-picker/time-picker.d.ts.map +1 -1
- package/dist/components/time-picker/time-picker.js +10 -1
- package/dist/components/time-picker/time-picker.js.map +1 -1
- package/dist/components/time-picker/use-time-picker.d.ts +1 -0
- package/dist/components/time-picker/use-time-picker.d.ts.map +1 -1
- package/dist/components/time-picker/use-time-picker.js +3 -0
- package/dist/components/time-picker/use-time-picker.js.map +1 -1
- package/dist/components/timeline/context.js +2 -2
- package/dist/components/timeline/context.js.map +1 -1
- package/dist/components/timeline/timeline.d.ts +1 -1
- package/dist/components/timer/context.js +1 -1
- package/dist/components/timer/context.js.map +1 -1
- package/dist/components/toast/context.js +1 -1
- package/dist/components/toast/context.js.map +1 -1
- package/dist/components/toast/toast.d.ts +3 -15
- package/dist/components/toast/toast.d.ts.map +1 -1
- package/dist/components/toast/toast.js +1 -12
- package/dist/components/toast/toast.js.map +1 -1
- package/dist/components/toast/use-toast.d.ts.map +1 -1
- package/dist/components/toast/use-toast.js +1 -7
- package/dist/components/toast/use-toast.js.map +1 -1
- package/dist/components/toggle-group/context.js +1 -1
- package/dist/components/toggle-group/context.js.map +1 -1
- package/dist/components/toggle-group/toggle-group.d.ts +10 -1
- package/dist/components/toggle-group/toggle-group.d.ts.map +1 -1
- package/dist/components/toggle-group/toggle-group.js +4 -0
- package/dist/components/toggle-group/toggle-group.js.map +1 -1
- package/dist/components/toolbar/context.js +1 -1
- package/dist/components/toolbar/context.js.map +1 -1
- package/dist/components/toolbar/toolbar.d.ts +1 -1
- package/dist/components/tooltip/context.js +1 -1
- package/dist/components/tooltip/context.js.map +1 -1
- package/dist/components/tooltip/tooltip.d.ts +2 -2
- package/dist/components/tour/context.js +1 -1
- package/dist/components/tour/context.js.map +1 -1
- package/dist/components/tour/tour.d.ts +2 -2
- package/dist/components/transfer/context.js +3 -3
- package/dist/components/transfer/context.js.map +1 -1
- package/dist/components/tree/context.js +2 -2
- package/dist/components/tree/context.js.map +1 -1
- package/dist/components/tree/tree.d.ts +20 -0
- package/dist/components/tree/tree.d.ts.map +1 -1
- package/dist/components/tree/tree.js +9 -0
- package/dist/components/tree/tree.js.map +1 -1
- package/dist/components/tree-select/context.js +2 -2
- package/dist/components/tree-select/context.js.map +1 -1
- package/dist/components/tree-select/tree-select.d.ts +3 -3
- package/dist/components/tree-select/tree-select.d.ts.map +1 -1
- package/dist/components/tree-select/tree-select.js +14 -4
- package/dist/components/tree-select/tree-select.js.map +1 -1
- package/dist/components/tree-select/use-tree-select.js +1 -1
- package/dist/components/tree-select/use-tree-select.js.map +1 -1
- package/dist/components/typography/context.js +1 -1
- package/dist/components/typography/context.js.map +1 -1
- package/dist/components/virtualizer/context.js +1 -1
- package/dist/components/virtualizer/context.js.map +1 -1
- package/dist/components/watermark/context.js +1 -1
- package/dist/components/watermark/context.js.map +1 -1
- package/dist/config/config.js +1 -1
- package/dist/config/config.js.map +1 -1
- package/dist/index.d.ts +16 -9
- package/dist/index.js +15 -8
- package/dist/package.js +1 -1
- package/dist/runtime/use-scrollbars.js +66 -0
- package/dist/runtime/use-scrollbars.js.map +1 -0
- package/dist/services/dialog-service.d.ts +33 -8
- package/dist/services/dialog-service.d.ts.map +1 -1
- package/dist/services/dialog-service.js +44 -20
- package/dist/services/dialog-service.js.map +1 -1
- package/dist/services/glyph.js +41 -1
- package/dist/services/glyph.js.map +1 -1
- package/dist/services/loading-bar-service.d.ts +46 -0
- package/dist/services/loading-bar-service.d.ts.map +1 -0
- package/dist/services/loading-bar-service.js +70 -0
- package/dist/services/loading-bar-service.js.map +1 -0
- package/dist/services/mount-host.js +35 -0
- package/dist/services/mount-host.js.map +1 -0
- package/dist/services/notification-service.d.ts +46 -0
- package/dist/services/notification-service.d.ts.map +1 -0
- package/dist/services/notification-service.js +91 -0
- package/dist/services/notification-service.js.map +1 -0
- package/dist/services/service-config.js +16 -0
- package/dist/services/service-config.js.map +1 -0
- package/dist/services/toast-service.d.ts +20 -12
- package/dist/services/toast-service.d.ts.map +1 -1
- package/dist/services/toast-service.js +103 -50
- package/dist/services/toast-service.js.map +1 -1
- package/package.json +18 -14
- package/dist/components/toaster/context.js +0 -19
- package/dist/components/toaster/context.js.map +0 -1
- package/dist/components/toaster/toaster.d.ts +0 -135
- package/dist/components/toaster/toaster.d.ts.map +0 -1
- package/dist/components/toaster/toaster.js +0 -91
- package/dist/components/toaster/toaster.js.map +0 -1
- package/dist/components/toaster/use-toaster.d.ts +0 -15
- package/dist/components/toaster/use-toaster.d.ts.map +0 -1
- package/dist/components/toaster/use-toaster.js +0 -23
- package/dist/components/toaster/use-toaster.js.map +0 -1
package/dist/services/glyph.js
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import { h } from "vue";
|
|
2
2
|
import { resolveMotionPreference } from "@xihan-ui/motion";
|
|
3
3
|
//#region src/services/glyph.ts
|
|
4
|
+
/** 裸字形跟着宿主声明的图标尺寸走;宿主没声明时退回控件指示符那一档。 */
|
|
5
|
+
const GLYPH_SIZE = "var(--xh-icon-size, var(--xh-control-indicator-size))";
|
|
6
|
+
const GLYPH_STYLE = {
|
|
7
|
+
display: "grid",
|
|
8
|
+
placeItems: "center",
|
|
9
|
+
flex: "none",
|
|
10
|
+
inlineSize: GLYPH_SIZE,
|
|
11
|
+
blockSize: GLYPH_SIZE,
|
|
12
|
+
color: "var(--xh-_tone-fg, var(--xh-fg-default))"
|
|
13
|
+
};
|
|
4
14
|
/** 徽记的圆底取中号字形尺寸;里面的字形四边各让出一个 space-1。 */
|
|
5
15
|
const BADGE_SIZE = "var(--xh-glyph-size-md)";
|
|
6
16
|
const MARK_SIZE = "calc(var(--xh-glyph-size-md) - 2 * var(--xh-space-1))";
|
|
@@ -73,10 +83,39 @@ function spin(el) {
|
|
|
73
83
|
easing: "linear"
|
|
74
84
|
});
|
|
75
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* 状态字形:不带圆底的一枚字形,尺寸随宿主的 --xh-icon-size,颜色随语气。
|
|
88
|
+
*
|
|
89
|
+
* 与 typeBadge 的分工是体量:圆底徽记是给对话框那种有余裕的版面用的(眼下只剩它在用),
|
|
90
|
+
* 排在一行短消息里会把行高顶起来,也让一句话的反馈看着像一则公告。
|
|
91
|
+
*/
|
|
92
|
+
function typeGlyph(type) {
|
|
93
|
+
if (!type) return null;
|
|
94
|
+
if (type === "loading") return h("span", {
|
|
95
|
+
"key": "spin",
|
|
96
|
+
"style": GLYPH_STYLE,
|
|
97
|
+
"aria-hidden": "true",
|
|
98
|
+
"onVnodeMounted": (vnode) => spin(vnode.el)
|
|
99
|
+
}, [spinArc("100%")]);
|
|
100
|
+
const mark = GLYPH_MARK[type];
|
|
101
|
+
if (!mark) return null;
|
|
102
|
+
const image = `var(${mark})`;
|
|
103
|
+
return h("span", {
|
|
104
|
+
"key": "mark",
|
|
105
|
+
"style": {
|
|
106
|
+
...GLYPH_STYLE,
|
|
107
|
+
backgroundColor: "currentColor",
|
|
108
|
+
WebkitMask: `${image} center / contain no-repeat`,
|
|
109
|
+
mask: `${image} center / contain no-repeat`
|
|
110
|
+
},
|
|
111
|
+
"aria-hidden": "true"
|
|
112
|
+
});
|
|
113
|
+
}
|
|
76
114
|
/** 类型徽记:圆底 + 字形;loading 给转圈弧线。 */
|
|
77
115
|
function typeBadge(type) {
|
|
78
116
|
if (!type) return null;
|
|
79
117
|
if (type === "loading") return h("span", {
|
|
118
|
+
"key": "spin",
|
|
80
119
|
"style": BADGE_STYLE,
|
|
81
120
|
"aria-hidden": "true",
|
|
82
121
|
"onVnodeMounted": (vnode) => spin(vnode.el)
|
|
@@ -84,11 +123,12 @@ function typeBadge(type) {
|
|
|
84
123
|
const mark = GLYPH_MARK[type];
|
|
85
124
|
if (!mark) return null;
|
|
86
125
|
return h("span", {
|
|
126
|
+
"key": "mark",
|
|
87
127
|
"style": BADGE_STYLE,
|
|
88
128
|
"aria-hidden": "true"
|
|
89
129
|
}, [h("span", { style: markStyle(mark) })]);
|
|
90
130
|
}
|
|
91
131
|
//#endregion
|
|
92
|
-
export { spinArc, typeBadge };
|
|
132
|
+
export { spinArc, typeBadge, typeGlyph };
|
|
93
133
|
|
|
94
134
|
//# sourceMappingURL=glyph.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"glyph.js","names":[],"sources":["../../src/services/glyph.ts"],"sourcesContent":["//
|
|
1
|
+
{"version":3,"file":"glyph.js","names":[],"sources":["../../src/services/glyph.ts"],"sourcesContent":["// 反馈服务默认模板用的装饰图形:裸字形(typeGlyph)、圆底徽记(typeBadge)与加载弧线。\n// 纯装饰(aria-hidden),读屏内容由标题与描述承担;配色取语气层继承下来的私有槽,\n// 随宿主 data-tone 自动换族。徽记里的图形取 --xh-glyph-mark-* 令牌,与皮肤的兜底字形同一套。\nimport type { VNode } from 'vue'\nimport { resolveMotionPreference } from '@xihan-ui/motion'\nimport { h } from 'vue'\n\n/** 裸字形跟着宿主声明的图标尺寸走;宿主没声明时退回控件指示符那一档。 */\nconst GLYPH_SIZE = 'var(--xh-icon-size, var(--xh-control-indicator-size))'\n\nconst GLYPH_STYLE = {\n display: 'grid',\n placeItems: 'center',\n flex: 'none',\n inlineSize: GLYPH_SIZE,\n blockSize: GLYPH_SIZE,\n /* 字形压的是同族淡底,不是白底:主色 600 档兑上去只剩 2.1–2.7(浅色 success / warning、\n 深色 neutral),够不到图形该有的 3:1。-fg 档在同一批底上最低 4.08,与 alert 的图标同档 */\n color: 'var(--xh-_tone-fg, var(--xh-fg-default))',\n} as const\n\n/** 徽记的圆底取中号字形尺寸;里面的字形四边各让出一个 space-1。 */\nconst BADGE_SIZE = 'var(--xh-glyph-size-md)'\nconst MARK_SIZE = 'calc(var(--xh-glyph-size-md) - 2 * var(--xh-space-1))'\n\nconst BADGE_STYLE = {\n display: 'grid',\n placeItems: 'center',\n flex: 'none',\n inlineSize: BADGE_SIZE,\n blockSize: BADGE_SIZE,\n borderRadius: 'var(--xh-shape-pill)',\n background: 'var(--xh-_tone-subtle, var(--xh-bg-muted))',\n color: 'var(--xh-_tone-fg, var(--xh-fg-default))',\n} as const\n\n/** 四种类型各取哪枚字形令牌;图形经 mask 着色,跟着徽记的前景色走。 */\nconst GLYPH_MARK: Record<string, string> = {\n info: '--xh-glyph-mark-info',\n success: '--xh-glyph-mark-check',\n warning: '--xh-glyph-mark-warning',\n error: '--xh-glyph-mark-close',\n}\n\nfunction markStyle(token: string): Record<string, string> {\n const image = `var(${token})`\n return {\n display: 'block',\n inlineSize: MARK_SIZE,\n blockSize: MARK_SIZE,\n backgroundColor: 'currentColor',\n WebkitMask: `${image} center / contain no-repeat`,\n mask: `${image} center / contain no-repeat`,\n }\n}\n\n/** 旋转的加载弧线;转动动画由外层容器(如 XhButtonIndicator)或自带样式提供。 */\nexport function spinArc(size = '1em'): VNode {\n return h('svg', {\n 'viewBox': '0 0 16 16',\n 'width': size,\n 'height': size,\n 'aria-hidden': 'true',\n 'style': { display: 'block' },\n }, [\n h('circle', {\n 'cx': 8,\n 'cy': 8,\n 'r': 6.5,\n 'fill': 'none',\n 'stroke': 'currentColor',\n 'stroke-width': 2,\n 'stroke-linecap': 'round',\n 'stroke-dasharray': '30',\n 'stroke-dashoffset': '22',\n }),\n ])\n}\n\n/** 解析 CSS 时长(\"640ms\" / \"0.8s\")为毫秒,解析不出来给 0。 */\nfunction parseDuration(value: string): number {\n const n = Number.parseFloat(value)\n if (!Number.isFinite(n))\n return 0\n return /s\\s*$/.test(value) && !/ms\\s*$/.test(value) ? n * 1000 : n\n}\n\n/**\n * 让徽记转起来。动画用 Web Animations 而不是 CSS 动画名:模板是内联样式渲染的,\n * 不归任何一份皮肤管,引用皮肤里的 @keyframes 名字时那份皮肤不一定在场。\n * 时长读 --xh-spin-duration 令牌;减弱动效时不转,静止的弧线仍读得出「还没好」。\n */\nfunction spin(el: HTMLElement): void {\n if (typeof el.animate !== 'function' || resolveMotionPreference(el.ownerDocument?.defaultView ?? undefined) === 'reduce')\n return\n const duration = parseDuration(getComputedStyle(el).getPropertyValue('--xh-spin-duration'))\n if (duration <= 0)\n return\n el.animate([{ rotate: '0deg' }, { rotate: '360deg' }], { duration, iterations: Number.POSITIVE_INFINITY, easing: 'linear' })\n}\n\n/**\n * 状态字形:不带圆底的一枚字形,尺寸随宿主的 --xh-icon-size,颜色随语气。\n *\n * 与 typeBadge 的分工是体量:圆底徽记是给对话框那种有余裕的版面用的(眼下只剩它在用),\n * 排在一行短消息里会把行高顶起来,也让一句话的反馈看着像一则公告。\n */\nexport function typeGlyph(type: string | undefined): VNode | null {\n if (!type)\n return null\n if (type === 'loading') {\n // key 必须与下面那支不同:同为无 key 的 span 会被判成同一个节点就地复用,\n // 而转圈是 Web Animations 挂在元素上的,样式补丁不会把它收走——\n // loading 改写成 success 之后那枚勾号会一直转\n return h('span', {\n 'key': 'spin',\n 'style': GLYPH_STYLE,\n 'aria-hidden': 'true',\n 'onVnodeMounted': vnode => spin(vnode.el as HTMLElement),\n }, [spinArc('100%')])\n }\n const mark = GLYPH_MARK[type]\n if (!mark)\n return null\n const image = `var(${mark})`\n // 图案经 mask 着色,取的就是本元素的 color,不必再套一层内节点\n return h('span', {\n 'key': 'mark',\n 'style': {\n ...GLYPH_STYLE,\n backgroundColor: 'currentColor',\n WebkitMask: `${image} center / contain no-repeat`,\n mask: `${image} center / contain no-repeat`,\n },\n 'aria-hidden': 'true',\n })\n}\n\n/** 类型徽记:圆底 + 字形;loading 给转圈弧线。 */\nexport function typeBadge(type: string | undefined): VNode | null {\n if (!type)\n return null\n if (type === 'loading') {\n // 两支的 key 必须不同,理由同 typeGlyph\n return h('span', {\n 'key': 'spin',\n 'style': BADGE_STYLE,\n 'aria-hidden': 'true',\n 'onVnodeMounted': vnode => spin(vnode.el as HTMLElement),\n }, [spinArc(MARK_SIZE)])\n }\n const mark = GLYPH_MARK[type]\n if (!mark)\n return null\n return h('span', { 'key': 'mark', 'style': BADGE_STYLE, 'aria-hidden': 'true' }, [h('span', { style: markStyle(mark) })])\n}\n"],"mappings":";;;;AAQA,MAAM,aAAa;AAEnB,MAAM,cAAc;CAClB,SAAS;CACT,YAAY;CACZ,MAAM;CACN,YAAY;CACZ,WAAW;CAGX,OAAO;AACT;;AAGA,MAAM,aAAa;AACnB,MAAM,YAAY;AAElB,MAAM,cAAc;CAClB,SAAS;CACT,YAAY;CACZ,MAAM;CACN,YAAY;CACZ,WAAW;CACX,cAAc;CACd,YAAY;CACZ,OAAO;AACT;;AAGA,MAAM,aAAqC;CACzC,MAAM;CACN,SAAS;CACT,SAAS;CACT,OAAO;AACT;AAEA,SAAS,UAAU,OAAuC;CACxD,MAAM,QAAQ,OAAO,MAAM;CAC3B,OAAO;EACL,SAAS;EACT,YAAY;EACZ,WAAW;EACX,iBAAiB;EACjB,YAAY,GAAG,MAAM;EACrB,MAAM,GAAG,MAAM;CACjB;AACF;;AAGA,SAAgB,QAAQ,OAAO,OAAc;CAC3C,OAAO,EAAE,OAAO;EACd,WAAW;EACX,SAAS;EACT,UAAU;EACV,eAAe;EACf,SAAS,EAAE,SAAS,QAAQ;CAC9B,GAAG,CACD,EAAE,UAAU;EACV,MAAM;EACN,MAAM;EACN,KAAK;EACL,QAAQ;EACR,UAAU;EACV,gBAAgB;EAChB,kBAAkB;EAClB,oBAAoB;EACpB,qBAAqB;CACvB,CAAC,CACH,CAAC;AACH;;AAGA,SAAS,cAAc,OAAuB;CAC5C,MAAM,IAAI,OAAO,WAAW,KAAK;CACjC,IAAI,CAAC,OAAO,SAAS,CAAC,GACpB,OAAO;CACT,OAAO,QAAQ,KAAK,KAAK,KAAK,CAAC,SAAS,KAAK,KAAK,IAAI,IAAI,MAAO;AACnE;;;;;;AAOA,SAAS,KAAK,IAAuB;CACnC,IAAI,OAAO,GAAG,YAAY,cAAc,wBAAwB,GAAG,eAAe,eAAe,KAAA,CAAS,MAAM,UAC9G;CACF,MAAM,WAAW,cAAc,iBAAiB,EAAE,CAAC,CAAC,iBAAiB,oBAAoB,CAAC;CAC1F,IAAI,YAAY,GACd;CACF,GAAG,QAAQ,CAAC,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,SAAS,CAAC,GAAG;EAAE;EAAU,YAAY,OAAO;EAAmB,QAAQ;CAAS,CAAC;AAC7H;;;;;;;AAQA,SAAgB,UAAU,MAAwC;CAChE,IAAI,CAAC,MACH,OAAO;CACT,IAAI,SAAS,WAIX,OAAO,EAAE,QAAQ;EACf,OAAO;EACP,SAAS;EACT,eAAe;EACf,mBAAkB,UAAS,KAAK,MAAM,EAAiB;CACzD,GAAG,CAAC,QAAQ,MAAM,CAAC,CAAC;CAEtB,MAAM,OAAO,WAAW;CACxB,IAAI,CAAC,MACH,OAAO;CACT,MAAM,QAAQ,OAAO,KAAK;CAE1B,OAAO,EAAE,QAAQ;EACf,OAAO;EACP,SAAS;GACP,GAAG;GACH,iBAAiB;GACjB,YAAY,GAAG,MAAM;GACrB,MAAM,GAAG,MAAM;EACjB;EACA,eAAe;CACjB,CAAC;AACH;;AAGA,SAAgB,UAAU,MAAwC;CAChE,IAAI,CAAC,MACH,OAAO;CACT,IAAI,SAAS,WAEX,OAAO,EAAE,QAAQ;EACf,OAAO;EACP,SAAS;EACT,eAAe;EACf,mBAAkB,UAAS,KAAK,MAAM,EAAiB;CACzD,GAAG,CAAC,QAAQ,SAAS,CAAC,CAAC;CAEzB,MAAM,OAAO,WAAW;CACxB,IAAI,CAAC,MACH,OAAO;CACT,OAAO,EAAE,QAAQ;EAAE,OAAO;EAAQ,SAAS;EAAa,eAAe;CAAO,GAAG,CAAC,EAAE,QAAQ,EAAE,OAAO,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC;AAC1H"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { XhConfig } from "../config/config.js";
|
|
2
|
+
import { MaybeRefOrGetter } from "vue";
|
|
3
|
+
import { LoadingBarTranslations } from "@xihan-ui/headless";
|
|
4
|
+
import { Tone } from "@xihan-ui/kernel";
|
|
5
|
+
//#region src/services/loading-bar-service.d.ts
|
|
6
|
+
interface LoadingBarServiceOptions {
|
|
7
|
+
/** 正常收尾的语气,缺省 brand。 */
|
|
8
|
+
tone?: Tone;
|
|
9
|
+
/** error() 收尾用的语气,缺省 danger:出错的收尾要与正常收尾区分得开。 */
|
|
10
|
+
errorTone?: Tone;
|
|
11
|
+
height?: string | number;
|
|
12
|
+
color?: string;
|
|
13
|
+
trickle?: boolean;
|
|
14
|
+
trickleSpeed?: number;
|
|
15
|
+
minimum?: number;
|
|
16
|
+
fadeDuration?: number;
|
|
17
|
+
translations?: MaybeRefOrGetter<Partial<LoadingBarTranslations>>;
|
|
18
|
+
/**
|
|
19
|
+
* 喂给进度条子树的全局配置。
|
|
20
|
+
* 本服务自带宿主应用,接不到组件树里的 provideXhConfig,要让它跟应用同语言就从这里给;
|
|
21
|
+
* 传 ref/getter 即可运行期跟着切语言,也可以之后用 setConfig 推。
|
|
22
|
+
*/
|
|
23
|
+
config?: MaybeRefOrGetter<XhConfig>;
|
|
24
|
+
/** 宿主容器;不给就在 body 下新建一个。 */
|
|
25
|
+
target?: HTMLElement;
|
|
26
|
+
}
|
|
27
|
+
interface LoadingBarService {
|
|
28
|
+
/** 在途计数 +1;从 0 起跳即开始爬升。 */
|
|
29
|
+
start: () => void;
|
|
30
|
+
/** 在途计数 -1(夹到 0,多调不会变负);归零才收。 */
|
|
31
|
+
finish: () => void;
|
|
32
|
+
/** 强制归零并以 errorTone 收。 */
|
|
33
|
+
error: () => void;
|
|
34
|
+
/** 不管还剩几笔在途一律收掉(路由跳走时用)。 */
|
|
35
|
+
finishAll: () => void;
|
|
36
|
+
/** 切成确定进度:给了值就照它显示,内部爬升停止;再 start() 回到不确定。 */
|
|
37
|
+
set: (value: number) => void;
|
|
38
|
+
/** 换一份全局配置源。 */
|
|
39
|
+
setConfig: (next: MaybeRefOrGetter<XhConfig> | undefined) => void;
|
|
40
|
+
/** 卸载宿主应用并移除容器。 */
|
|
41
|
+
dispose: () => void;
|
|
42
|
+
}
|
|
43
|
+
declare function createLoadingBarService(options?: LoadingBarServiceOptions): LoadingBarService;
|
|
44
|
+
//#endregion
|
|
45
|
+
export { LoadingBarService, LoadingBarServiceOptions, createLoadingBarService };
|
|
46
|
+
//# sourceMappingURL=loading-bar-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loading-bar-service.d.ts","names":[],"sources":["../../src/services/loading-bar-service.ts"],"mappings":";;;;;UAeiB;;EAEf,OAAO;;EAEP,YAAY;EACZ;EACA;EACA;EACA;EACA;EACA;EACA,eAAe,iBAAiB,QAAQ;;;;;;EAMxC,SAAS,iBAAiB;;EAE1B,SAAS;;UAGM;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA,MAAM;;EAEN,YAAY,MAAM,iBAAiB;;EAEnC;;iBAGc,wBAAwB,UAAS,2BAAgC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { vueNormalize } from "../runtime/normalize-props.js";
|
|
2
|
+
import { useMachine } from "../runtime/use-machine.js";
|
|
3
|
+
import { mountServiceHost } from "./mount-host.js";
|
|
4
|
+
import { createServiceConfig } from "./service-config.js";
|
|
5
|
+
import { computed, createApp, defineComponent, h, reactive, toValue } from "vue";
|
|
6
|
+
import { connectLoadingBar, loadingBarMachine } from "@xihan-ui/headless";
|
|
7
|
+
import { ensurePortalRoot } from "@xihan-ui/kernel";
|
|
8
|
+
//#region src/services/loading-bar-service.ts
|
|
9
|
+
function createLoadingBarService(options = {}) {
|
|
10
|
+
if (typeof document === "undefined") throw new Error("createLoadingBarService 需要 document;SSR 里请等到客户端再创建");
|
|
11
|
+
const { target, config, tone = "brand", errorTone = "danger", translations, ...barProps } = options;
|
|
12
|
+
const holder = target ?? document.createElement("div");
|
|
13
|
+
if (!target) ensurePortalRoot(document).appendChild(holder);
|
|
14
|
+
const configSource = createServiceConfig(config);
|
|
15
|
+
const state = reactive({
|
|
16
|
+
pending: 0,
|
|
17
|
+
tone,
|
|
18
|
+
value: void 0
|
|
19
|
+
});
|
|
20
|
+
const app = createApp(defineComponent({
|
|
21
|
+
name: "XhLoadingBarServiceHost",
|
|
22
|
+
setup() {
|
|
23
|
+
configSource.provide();
|
|
24
|
+
const service = useMachine(loadingBarMachine, () => ({
|
|
25
|
+
...barProps,
|
|
26
|
+
loading: state.pending > 0,
|
|
27
|
+
tone: state.tone,
|
|
28
|
+
value: state.value,
|
|
29
|
+
translations: toValue(translations)
|
|
30
|
+
}));
|
|
31
|
+
const api = computed(() => connectLoadingBar(service, vueNormalize));
|
|
32
|
+
return () => h("div", api.value.getRootProps(), [h("div", api.value.getTrackProps(), [h("div", api.value.getRangeProps())])]);
|
|
33
|
+
}
|
|
34
|
+
}));
|
|
35
|
+
const mounted = mountServiceHost(app, holder, "loading-bar");
|
|
36
|
+
const settle = (nextTone) => {
|
|
37
|
+
if (!mounted) return;
|
|
38
|
+
state.pending = 0;
|
|
39
|
+
state.tone = nextTone;
|
|
40
|
+
state.value = void 0;
|
|
41
|
+
};
|
|
42
|
+
return {
|
|
43
|
+
start: () => {
|
|
44
|
+
if (!mounted) return;
|
|
45
|
+
state.tone = tone;
|
|
46
|
+
state.value = void 0;
|
|
47
|
+
state.pending += 1;
|
|
48
|
+
},
|
|
49
|
+
finish: () => {
|
|
50
|
+
if (!mounted) return;
|
|
51
|
+
state.pending = Math.max(0, state.pending - 1);
|
|
52
|
+
if (state.pending === 0) state.value = void 0;
|
|
53
|
+
},
|
|
54
|
+
error: () => settle(errorTone),
|
|
55
|
+
finishAll: () => settle(tone),
|
|
56
|
+
set: (value) => {
|
|
57
|
+
if (!mounted) return;
|
|
58
|
+
state.value = value;
|
|
59
|
+
},
|
|
60
|
+
setConfig: (next) => configSource.set(next),
|
|
61
|
+
dispose: () => {
|
|
62
|
+
if (mounted) app.unmount();
|
|
63
|
+
if (!target) holder.remove();
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
//#endregion
|
|
68
|
+
export { createLoadingBarService };
|
|
69
|
+
|
|
70
|
+
//# sourceMappingURL=loading-bar-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loading-bar-service.js","names":[],"sources":["../../src/services/loading-bar-service.ts"],"sourcesContent":["// 全局命令式顶部进度条:自带一个挂到 body 的宿主应用,\n// start/finish 在任意模块作用域可调(路由守卫、请求拦截器),不要求调用点在组件树内。\n// 组件树内的组合用法仍走 XhLoadingBarRoot。\nimport type { LoadingBarTranslations } from '@xihan-ui/headless'\nimport type { Tone } from '@xihan-ui/kernel'\nimport type { App, MaybeRefOrGetter } from 'vue'\nimport type { XhConfig } from '../config/config'\nimport { connectLoadingBar, loadingBarMachine } from '@xihan-ui/headless'\nimport { ensurePortalRoot } from '@xihan-ui/kernel'\nimport { computed, createApp, defineComponent, h, reactive, toValue } from 'vue'\nimport { vueNormalize } from '../runtime/normalize-props'\nimport { useMachine } from '../runtime/use-machine'\nimport { mountServiceHost } from './mount-host'\nimport { createServiceConfig } from './service-config'\n\nexport interface LoadingBarServiceOptions {\n /** 正常收尾的语气,缺省 brand。 */\n tone?: Tone\n /** error() 收尾用的语气,缺省 danger:出错的收尾要与正常收尾区分得开。 */\n errorTone?: Tone\n height?: string | number\n color?: string\n trickle?: boolean\n trickleSpeed?: number\n minimum?: number\n fadeDuration?: number\n translations?: MaybeRefOrGetter<Partial<LoadingBarTranslations>>\n /**\n * 喂给进度条子树的全局配置。\n * 本服务自带宿主应用,接不到组件树里的 provideXhConfig,要让它跟应用同语言就从这里给;\n * 传 ref/getter 即可运行期跟着切语言,也可以之后用 setConfig 推。\n */\n config?: MaybeRefOrGetter<XhConfig>\n /** 宿主容器;不给就在 body 下新建一个。 */\n target?: HTMLElement\n}\n\nexport interface LoadingBarService {\n /** 在途计数 +1;从 0 起跳即开始爬升。 */\n start: () => void\n /** 在途计数 -1(夹到 0,多调不会变负);归零才收。 */\n finish: () => void\n /** 强制归零并以 errorTone 收。 */\n error: () => void\n /** 不管还剩几笔在途一律收掉(路由跳走时用)。 */\n finishAll: () => void\n /** 切成确定进度:给了值就照它显示,内部爬升停止;再 start() 回到不确定。 */\n set: (value: number) => void\n /** 换一份全局配置源。 */\n setConfig: (next: MaybeRefOrGetter<XhConfig> | undefined) => void\n /** 卸载宿主应用并移除容器。 */\n dispose: () => void\n}\n\nexport function createLoadingBarService(options: LoadingBarServiceOptions = {}): LoadingBarService {\n if (typeof document === 'undefined')\n throw new Error('createLoadingBarService 需要 document;SSR 里请等到客户端再创建')\n\n const { target, config, tone = 'brand', errorTone = 'danger', translations, ...barProps } = options\n const holder = target ?? document.createElement('div')\n if (!target)\n ensurePortalRoot(document).appendChild(holder)\n\n const configSource = createServiceConfig(config)\n\n // 在途计数而不是布尔开关:并发请求里第一个回来时其余还在跑,\n // 布尔开关会把条子提前收掉。\n const state = reactive<{ pending: number, tone: Tone, value: number | undefined }>({\n pending: 0,\n tone,\n value: undefined,\n })\n\n const Host = defineComponent({\n name: 'XhLoadingBarServiceHost',\n setup() {\n configSource.provide()\n // 直接从 api 渲染那三层,不走部件组件:这棵子树固定且全归服务自己拥有,\n // 经上下文传 api 什么也没换来,却把「跨模块 provide/inject 必须对得上」\n // 加成了一条本可以没有的前提\n const service = useMachine(loadingBarMachine, () => ({\n ...barProps,\n loading: state.pending > 0,\n tone: state.tone,\n value: state.value,\n translations: toValue(translations),\n }))\n const api = computed(() => connectLoadingBar(service, vueNormalize))\n return () => h('div', api.value.getRootProps() as Record<string, unknown>, [\n h('div', api.value.getTrackProps() as Record<string, unknown>, [\n h('div', api.value.getRangeProps() as Record<string, unknown>),\n ]),\n ])\n },\n })\n\n const app: App = createApp(Host)\n const mounted = mountServiceHost(app, holder, 'loading-bar')\n\n const settle = (nextTone: Tone): void => {\n if (!mounted)\n return\n state.pending = 0\n state.tone = nextTone\n state.value = undefined\n }\n\n return {\n // 宿主没挂起来时整体惰化:状态一动不动,残骸也就不会被叫醒\n start: () => {\n if (!mounted)\n return\n state.tone = tone\n state.value = undefined\n state.pending += 1\n },\n finish: () => {\n if (!mounted)\n return\n state.pending = Math.max(0, state.pending - 1)\n if (state.pending === 0)\n state.value = undefined\n },\n error: () => settle(errorTone),\n finishAll: () => settle(tone),\n set: (value) => {\n if (!mounted)\n return\n state.value = value\n },\n setConfig: next => configSource.set(next),\n dispose: () => {\n if (mounted)\n app.unmount()\n if (!target)\n holder.remove()\n },\n }\n}\n"],"mappings":";;;;;;;;AAsDA,SAAgB,wBAAwB,UAAoC,CAAC,GAAsB;CACjG,IAAI,OAAO,aAAa,aACtB,MAAM,IAAI,MAAM,oDAAoD;CAEtE,MAAM,EAAE,QAAQ,QAAQ,OAAO,SAAS,YAAY,UAAU,cAAc,GAAG,aAAa;CAC5F,MAAM,SAAS,UAAU,SAAS,cAAc,KAAK;CACrD,IAAI,CAAC,QACH,iBAAiB,QAAQ,CAAC,CAAC,YAAY,MAAM;CAE/C,MAAM,eAAe,oBAAoB,MAAM;CAI/C,MAAM,QAAQ,SAAqE;EACjF,SAAS;EACT;EACA,OAAO,KAAA;CACT,CAAC;CAyBD,MAAM,MAAW,UAvBJ,gBAAgB;EAC3B,MAAM;EACN,QAAQ;GACN,aAAa,QAAQ;GAIrB,MAAM,UAAU,WAAW,0BAA0B;IACnD,GAAG;IACH,SAAS,MAAM,UAAU;IACzB,MAAM,MAAM;IACZ,OAAO,MAAM;IACb,cAAc,QAAQ,YAAY;GACpC,EAAE;GACF,MAAM,MAAM,eAAe,kBAAkB,SAAS,YAAY,CAAC;GACnE,aAAa,EAAE,OAAO,IAAI,MAAM,aAAa,GAA8B,CACzE,EAAE,OAAO,IAAI,MAAM,cAAc,GAA8B,CAC7D,EAAE,OAAO,IAAI,MAAM,cAAc,CAA4B,CAC/D,CAAC,CACH,CAAC;EACH;CACF,CAE8B,CAAC;CAC/B,MAAM,UAAU,iBAAiB,KAAK,QAAQ,aAAa;CAE3D,MAAM,UAAU,aAAyB;EACvC,IAAI,CAAC,SACH;EACF,MAAM,UAAU;EAChB,MAAM,OAAO;EACb,MAAM,QAAQ,KAAA;CAChB;CAEA,OAAO;EAEL,aAAa;GACX,IAAI,CAAC,SACH;GACF,MAAM,OAAO;GACb,MAAM,QAAQ,KAAA;GACd,MAAM,WAAW;EACnB;EACA,cAAc;GACZ,IAAI,CAAC,SACH;GACF,MAAM,UAAU,KAAK,IAAI,GAAG,MAAM,UAAU,CAAC;GAC7C,IAAI,MAAM,YAAY,GACpB,MAAM,QAAQ,KAAA;EAClB;EACA,aAAa,OAAO,SAAS;EAC7B,iBAAiB,OAAO,IAAI;EAC5B,MAAM,UAAU;GACd,IAAI,CAAC,SACH;GACF,MAAM,QAAQ;EAChB;EACA,YAAW,SAAQ,aAAa,IAAI,IAAI;EACxC,eAAe;GACb,IAAI,SACF,IAAI,QAAQ;GACd,IAAI,CAAC,QACH,OAAO,OAAO;EAClB;CACF;AACF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { DIAGNOSTIC_CODES, reportDiagnostic } from "@xihan-ui/kernel";
|
|
2
|
+
//#region src/services/mount-host.ts
|
|
3
|
+
/**
|
|
4
|
+
* 把命令式服务的宿主应用挂上去,挂不起来也不连累调用方。
|
|
5
|
+
*
|
|
6
|
+
* 这几个服务是从路由守卫、请求拦截器这类地方懒建的——那些位置抛异常,
|
|
7
|
+
* 后果不是「提示没弹出来」而是整次导航失败、整站白屏,而报错指向的是浮层部件,
|
|
8
|
+
* 与真正的原因隔着十万八千里。一条轻提示、一根进度条都不该有这个权力。
|
|
9
|
+
*
|
|
10
|
+
* 挂不起来时发一条诊断并交回 false,由调用方整体惰化:状态一律不再改动。
|
|
11
|
+
* 半挂载的树仍订阅着响应式状态,继续写它只会让那棵残骸一遍遍重渲,
|
|
12
|
+
* 每次都吐一串「slot invoked outside of the render function」,把控制台淹掉。
|
|
13
|
+
*/
|
|
14
|
+
function mountServiceHost(app, holder, service) {
|
|
15
|
+
try {
|
|
16
|
+
app.mount(holder);
|
|
17
|
+
return true;
|
|
18
|
+
} catch (error) {
|
|
19
|
+
reportDiagnostic({
|
|
20
|
+
code: DIAGNOSTIC_CODES.warn,
|
|
21
|
+
level: "warn",
|
|
22
|
+
message: `[xh] ${service} 的宿主没挂起来,这个服务本次退化成空操作。常见原因是同一份组件模块被加载成了两份(链到工作区的库重建产物后,dev server 的模块图会新旧混杂),清掉 node_modules/.vite 再重启即可。`,
|
|
23
|
+
detail: {
|
|
24
|
+
service,
|
|
25
|
+
error
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
holder.remove();
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
export { mountServiceHost };
|
|
34
|
+
|
|
35
|
+
//# sourceMappingURL=mount-host.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mount-host.js","names":[],"sources":["../../src/services/mount-host.ts"],"sourcesContent":["import type { App } from 'vue'\nimport { DIAGNOSTIC_CODES, reportDiagnostic } from '@xihan-ui/kernel'\n\n/**\n * 把命令式服务的宿主应用挂上去,挂不起来也不连累调用方。\n *\n * 这几个服务是从路由守卫、请求拦截器这类地方懒建的——那些位置抛异常,\n * 后果不是「提示没弹出来」而是整次导航失败、整站白屏,而报错指向的是浮层部件,\n * 与真正的原因隔着十万八千里。一条轻提示、一根进度条都不该有这个权力。\n *\n * 挂不起来时发一条诊断并交回 false,由调用方整体惰化:状态一律不再改动。\n * 半挂载的树仍订阅着响应式状态,继续写它只会让那棵残骸一遍遍重渲,\n * 每次都吐一串「slot invoked outside of the render function」,把控制台淹掉。\n */\nexport function mountServiceHost(app: App, holder: HTMLElement, service: string): boolean {\n try {\n app.mount(holder)\n return true\n }\n catch (error) {\n reportDiagnostic({\n code: DIAGNOSTIC_CODES.warn,\n level: 'warn',\n message:\n `[xh] ${service} 的宿主没挂起来,这个服务本次退化成空操作。`\n + '常见原因是同一份组件模块被加载成了两份(链到工作区的库重建产物后,'\n + 'dev server 的模块图会新旧混杂),清掉 node_modules/.vite 再重启即可。',\n detail: { service, error },\n })\n // 不调 app.unmount():mount 抛出时 Vue 并没把 isMounted 置真,\n // 这时卸载只会再吐一条「Cannot unmount an app that is not mounted」\n holder.remove()\n return false\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAcA,SAAgB,iBAAiB,KAAU,QAAqB,SAA0B;CACxF,IAAI;EACF,IAAI,MAAM,MAAM;EAChB,OAAO;CACT,SACO,OAAO;EACZ,iBAAiB;GACf,MAAM,iBAAiB;GACvB,OAAO;GACP,SACE,QAAQ,QAAQ;GAGlB,QAAQ;IAAE;IAAS;GAAM;EAC3B,CAAC;EAGD,OAAO,OAAO;EACd,OAAO;CACT;AACF"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { XhConfig } from "../config/config.js";
|
|
2
|
+
import { MaybeRefOrGetter } from "vue";
|
|
3
|
+
import { NotificationOptions, NotificationPlacement, NotificationTranslations } from "@xihan-ui/headless";
|
|
4
|
+
//#region src/services/notification-service.d.ts
|
|
5
|
+
interface NotificationServiceOptions {
|
|
6
|
+
/** 默认落位,默认 bottom-end;单条可用 options.placement 覆盖。 */
|
|
7
|
+
placement?: NotificationPlacement;
|
|
8
|
+
/** 每个位置最多同时留几条,超出挤掉最旧的。不给即不限。 */
|
|
9
|
+
max?: number;
|
|
10
|
+
/** 同一摞内的间距(px),默认 16。 */
|
|
11
|
+
gap?: number;
|
|
12
|
+
duration?: number;
|
|
13
|
+
removeDelay?: number;
|
|
14
|
+
pauseOnPageIdle?: boolean;
|
|
15
|
+
/** 通知的文案:那一摞的读屏名与卡片上那颗叉的读屏名,一个桶装完。 */
|
|
16
|
+
translations?: MaybeRefOrGetter<Partial<NotificationTranslations>>;
|
|
17
|
+
/**
|
|
18
|
+
* 喂给通知子树的全局配置(locale / translations / size / portalContainer)。
|
|
19
|
+
* 本服务自带宿主应用,接不到组件树里的 provideXhConfig,要让它跟应用同语言就从这里给;
|
|
20
|
+
* 传 ref/getter 即可运行期跟着切语言,也可以之后用 setConfig 推。
|
|
21
|
+
*/
|
|
22
|
+
config?: MaybeRefOrGetter<XhConfig>;
|
|
23
|
+
/** 宿主容器;不给就在 body 下新建一个。 */
|
|
24
|
+
target?: HTMLElement;
|
|
25
|
+
}
|
|
26
|
+
/** 类型糖的入参:只差 type 与 title,其余同 create。 */
|
|
27
|
+
type NotificationMessageOptions = Omit<NotificationOptions, 'type' | 'title'>;
|
|
28
|
+
interface NotificationService {
|
|
29
|
+
/** 入队并返回 id;同 id 已存在则就地改写,位置不动。 */
|
|
30
|
+
create: (options?: NotificationOptions) => string;
|
|
31
|
+
update: (id: string, options: Partial<NotificationOptions>) => void;
|
|
32
|
+
dismiss: (id: string) => void;
|
|
33
|
+
dismissAll: () => void;
|
|
34
|
+
info: (title: string, options?: NotificationMessageOptions) => string;
|
|
35
|
+
success: (title: string, options?: NotificationMessageOptions) => string;
|
|
36
|
+
warning: (title: string, options?: NotificationMessageOptions) => string;
|
|
37
|
+
error: (title: string, options?: NotificationMessageOptions) => string;
|
|
38
|
+
/** 换一份全局配置源。 */
|
|
39
|
+
setConfig: (next: MaybeRefOrGetter<XhConfig> | undefined) => void;
|
|
40
|
+
/** 卸载宿主应用并移除容器。 */
|
|
41
|
+
dispose: () => void;
|
|
42
|
+
}
|
|
43
|
+
declare function createNotificationService(options?: NotificationServiceOptions): NotificationService;
|
|
44
|
+
//#endregion
|
|
45
|
+
export { NotificationMessageOptions, NotificationService, NotificationServiceOptions, createNotificationService };
|
|
46
|
+
//# sourceMappingURL=notification-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notification-service.d.ts","names":[],"sources":["../../src/services/notification-service.ts"],"mappings":";;;;UA8BiB;;EAEf,YAAY;;EAEZ;;EAEA;EACA;EACA;EACA;;EAEA,eAAe,iBAAiB,QAAQ;;;;;;EAMxC,SAAS,iBAAiB;;EAE1B,SAAS;;;KAIC,6BAA6B,KAAK;UAE7B;;EAEf,SAAS,UAAU;EACnB,SAAS,YAAY,SAAS,QAAQ;EACtC,UAAU;EACV;EACA,OAAO,eAAe,UAAU;EAChC,UAAU,eAAe,UAAU;EACnC,UAAU,eAAe,UAAU;EACnC,QAAQ,eAAe,UAAU;;EAEjC,YAAY,MAAM,iBAAiB;;EAEnC;;iBAiCc,0BAA0B,UAAS,6BAAkC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { useNotification } from "../components/notification/use-notification.js";
|
|
2
|
+
import { XhNotificationItem, XhNotificationItemCloseTrigger, XhNotificationItemDescription, XhNotificationItemIndicator, XhNotificationItemTitle } from "../components/notification/notification.js";
|
|
3
|
+
import { mountServiceHost } from "./mount-host.js";
|
|
4
|
+
import { createServiceConfig } from "./service-config.js";
|
|
5
|
+
import { Fragment, computed, createApp, defineComponent, h, toValue } from "vue";
|
|
6
|
+
import { ensurePortalRoot } from "@xihan-ui/kernel";
|
|
7
|
+
//#region src/services/notification-service.ts
|
|
8
|
+
function defaultCard(item, translations, onUnmounted) {
|
|
9
|
+
return h(XhNotificationItem, {
|
|
10
|
+
id: item.id,
|
|
11
|
+
title: item.title,
|
|
12
|
+
description: item.description,
|
|
13
|
+
type: item.type,
|
|
14
|
+
duration: item.duration,
|
|
15
|
+
removeDelay: item.removeDelay,
|
|
16
|
+
closable: item.closable,
|
|
17
|
+
pauseOnPageIdle: item.pauseOnPageIdle,
|
|
18
|
+
translations,
|
|
19
|
+
onStatusChange: ({ id, status }) => {
|
|
20
|
+
if (status === "unmounted") onUnmounted(id);
|
|
21
|
+
}
|
|
22
|
+
}, () => [
|
|
23
|
+
h(XhNotificationItemIndicator),
|
|
24
|
+
h(XhNotificationItemTitle),
|
|
25
|
+
h(XhNotificationItemDescription),
|
|
26
|
+
item.closable !== false ? h(XhNotificationItemCloseTrigger) : null
|
|
27
|
+
]);
|
|
28
|
+
}
|
|
29
|
+
function createNotificationService(options = {}) {
|
|
30
|
+
if (typeof document === "undefined") throw new Error("createNotificationService 需要 document;SSR 里请等到客户端再创建");
|
|
31
|
+
const { target, config, ...queueProps } = options;
|
|
32
|
+
const configSource = createServiceConfig(config);
|
|
33
|
+
const holder = target ?? document.createElement("div");
|
|
34
|
+
if (!target) ensurePortalRoot(document).appendChild(holder);
|
|
35
|
+
let ctx = null;
|
|
36
|
+
const app = createApp(defineComponent({
|
|
37
|
+
name: "XhNotificationServiceHost",
|
|
38
|
+
setup() {
|
|
39
|
+
configSource.provide();
|
|
40
|
+
const inner = useNotification(() => ({
|
|
41
|
+
...queueProps,
|
|
42
|
+
translations: toValue(queueProps.translations)
|
|
43
|
+
}));
|
|
44
|
+
ctx = inner;
|
|
45
|
+
const api = computed(() => inner.api.value);
|
|
46
|
+
return () => {
|
|
47
|
+
const value = api.value;
|
|
48
|
+
return h("div", value.getRootProps(), value.placements.map((placement) => h("div", {
|
|
49
|
+
key: placement,
|
|
50
|
+
...value.getGroupProps({ placement })
|
|
51
|
+
}, value.getItemsByPlacement(placement).map((item) => h(Fragment, { key: item.id }, [defaultCard(item, toValue(queueProps.translations), inner.dismiss)])))));
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}));
|
|
55
|
+
const mounted = mountServiceHost(app, holder, "notification");
|
|
56
|
+
let disposed = false;
|
|
57
|
+
/**
|
|
58
|
+
* 宿主没挂起来时命令一律空转:把消息丢掉好过让调用点(推送回调、拦截器)连锁崩掉。
|
|
59
|
+
* 已卸载则是另一回事——那是调用方拿着一个死服务在用,明说好过静默吞掉。
|
|
60
|
+
*/
|
|
61
|
+
const use = () => {
|
|
62
|
+
if (disposed) throw new Error("notification 服务已卸载");
|
|
63
|
+
return mounted ? ctx : null;
|
|
64
|
+
};
|
|
65
|
+
const sugar = (type) => (title, opts = {}) => use()?.create({
|
|
66
|
+
...opts,
|
|
67
|
+
type,
|
|
68
|
+
title
|
|
69
|
+
}) ?? "";
|
|
70
|
+
return {
|
|
71
|
+
create: (opts) => use()?.create(opts) ?? "",
|
|
72
|
+
update: (id, opts) => use()?.update(id, opts),
|
|
73
|
+
dismiss: (id) => use()?.dismiss(id),
|
|
74
|
+
dismissAll: () => use()?.dismissAll(),
|
|
75
|
+
info: sugar("info"),
|
|
76
|
+
success: sugar("success"),
|
|
77
|
+
warning: sugar("warning"),
|
|
78
|
+
error: sugar("error"),
|
|
79
|
+
setConfig: (next) => configSource.set(next),
|
|
80
|
+
dispose: () => {
|
|
81
|
+
if (mounted) app.unmount();
|
|
82
|
+
disposed = true;
|
|
83
|
+
ctx = null;
|
|
84
|
+
if (!target) holder.remove();
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
89
|
+
export { createNotificationService };
|
|
90
|
+
|
|
91
|
+
//# sourceMappingURL=notification-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notification-service.js","names":[],"sources":["../../src/services/notification-service.ts"],"sourcesContent":["// 全局命令式通知服务:自带一个挂到 body 的宿主应用与默认渲染模板。\n//\n// 通知常常不是从组件树里发出来的——推送连接的回调、后台任务的收尾、拦截器里的\n// 一条系统消息,调用点都在组件之外。要它们各自去找一份队列上下文并不现实,\n// 所以队列由本服务持有,业务代码只管发。\n//\n// 队列要长在页面结构里(比如通知中心那一栏自己排版)时,用组件形态的\n// XhNotificationRoot,那是另一条路,两者不共享队列。\nimport type {\n NotificationOptions,\n NotificationPlacement,\n NotificationTranslations,\n ResolvedNotification,\n} from '@xihan-ui/headless'\nimport type { App, MaybeRefOrGetter, VNode } from 'vue'\nimport type { NotificationContext } from '../components/notification/context'\nimport type { XhConfig } from '../config/config'\nimport { ensurePortalRoot } from '@xihan-ui/kernel'\nimport { computed, createApp, defineComponent, Fragment, h, toValue } from 'vue'\nimport {\n XhNotificationItem,\n XhNotificationItemCloseTrigger,\n XhNotificationItemDescription,\n XhNotificationItemIndicator,\n XhNotificationItemTitle,\n} from '../components/notification/notification'\nimport { useNotification } from '../components/notification/use-notification'\nimport { mountServiceHost } from './mount-host'\nimport { createServiceConfig } from './service-config'\n\nexport interface NotificationServiceOptions {\n /** 默认落位,默认 bottom-end;单条可用 options.placement 覆盖。 */\n placement?: NotificationPlacement\n /** 每个位置最多同时留几条,超出挤掉最旧的。不给即不限。 */\n max?: number\n /** 同一摞内的间距(px),默认 16。 */\n gap?: number\n duration?: number\n removeDelay?: number\n pauseOnPageIdle?: boolean\n /** 通知的文案:那一摞的读屏名与卡片上那颗叉的读屏名,一个桶装完。 */\n translations?: MaybeRefOrGetter<Partial<NotificationTranslations>>\n /**\n * 喂给通知子树的全局配置(locale / translations / size / portalContainer)。\n * 本服务自带宿主应用,接不到组件树里的 provideXhConfig,要让它跟应用同语言就从这里给;\n * 传 ref/getter 即可运行期跟着切语言,也可以之后用 setConfig 推。\n */\n config?: MaybeRefOrGetter<XhConfig>\n /** 宿主容器;不给就在 body 下新建一个。 */\n target?: HTMLElement\n}\n\n/** 类型糖的入参:只差 type 与 title,其余同 create。 */\nexport type NotificationMessageOptions = Omit<NotificationOptions, 'type' | 'title'>\n\nexport interface NotificationService {\n /** 入队并返回 id;同 id 已存在则就地改写,位置不动。 */\n create: (options?: NotificationOptions) => string\n update: (id: string, options: Partial<NotificationOptions>) => void\n dismiss: (id: string) => void\n dismissAll: () => void\n info: (title: string, options?: NotificationMessageOptions) => string\n success: (title: string, options?: NotificationMessageOptions) => string\n warning: (title: string, options?: NotificationMessageOptions) => string\n error: (title: string, options?: NotificationMessageOptions) => string\n /** 换一份全局配置源。 */\n setConfig: (next: MaybeRefOrGetter<XhConfig> | undefined) => void\n /** 卸载宿主应用并移除容器。 */\n dispose: () => void\n}\n\nfunction defaultCard(\n item: ResolvedNotification,\n translations: Partial<NotificationTranslations> | undefined,\n onUnmounted: (id: string) => void,\n): VNode {\n return h(XhNotificationItem, {\n id: item.id,\n title: item.title,\n description: item.description,\n type: item.type,\n duration: item.duration,\n removeDelay: item.removeDelay,\n closable: item.closable,\n pauseOnPageIdle: item.pauseOnPageIdle,\n translations,\n onStatusChange: ({ id, status }: { id: string, status: string }) => {\n if (status === 'unmounted')\n onUnmounted(id)\n },\n }, () => [\n // 四个节点平铺:两列网格与右上角那颗叉都归皮肤,模板套一层行容器只会与它打架。\n // 指示符与说明都恒渲染——皮肤的 :empty 规则负责把空盒收走,\n // 而 aria-describedby 无条件指着说明那一个,节点缺席就成了悬空引用\n h(XhNotificationItemIndicator),\n h(XhNotificationItemTitle),\n h(XhNotificationItemDescription),\n item.closable !== false ? h(XhNotificationItemCloseTrigger) : null,\n ])\n}\n\nexport function createNotificationService(options: NotificationServiceOptions = {}): NotificationService {\n if (typeof document === 'undefined')\n throw new Error('createNotificationService 需要 document;SSR 里请等到客户端再创建')\n\n const { target, config, ...queueProps } = options\n const configSource = createServiceConfig(config)\n const holder = target ?? document.createElement('div')\n if (!target)\n ensurePortalRoot(document).appendChild(holder)\n\n let ctx: NotificationContext | null = null\n\n const Host = defineComponent({\n name: 'XhNotificationServiceHost',\n setup() {\n configSource.provide()\n // props 每帧现展开:文案是 getter 时才跟得上运行期切语言\n const inner = useNotification(() => ({ ...queueProps, translations: toValue(queueProps.translations) }))\n ctx = inner\n // 部件不经 provide/inject 取队列:本服务自己收 status-change 把走完退场的那条删掉,\n // 卡片与队列之间因此没有第二条隐式链路\n const api = computed(() => inner.api.value)\n return () => {\n const value = api.value\n return h('div', value.getRootProps() as Record<string, unknown>, value.placements.map(placement =>\n h(\n 'div',\n { key: placement, ...value.getGroupProps({ placement }) as Record<string, unknown> },\n // 按队列身份 id 给 key,避免节点被就地复用\n value.getItemsByPlacement(placement).map(item => h(Fragment, { key: item.id }, [\n defaultCard(item, toValue(queueProps.translations), inner.dismiss),\n ])),\n )))\n }\n },\n })\n\n const app: App = createApp(Host)\n const mounted = mountServiceHost(app, holder, 'notification')\n let disposed = false\n\n /**\n * 宿主没挂起来时命令一律空转:把消息丢掉好过让调用点(推送回调、拦截器)连锁崩掉。\n * 已卸载则是另一回事——那是调用方拿着一个死服务在用,明说好过静默吞掉。\n */\n const use = (): NotificationContext | null => {\n if (disposed)\n throw new Error('notification 服务已卸载')\n return mounted ? ctx : null\n }\n const sugar = (type: NotificationOptions['type']) =>\n (title: string, opts: NotificationMessageOptions = {}): string =>\n use()?.create({ ...opts, type, title }) ?? ''\n\n return {\n create: opts => use()?.create(opts) ?? '',\n update: (id, opts) => use()?.update(id, opts),\n dismiss: id => use()?.dismiss(id),\n dismissAll: () => use()?.dismissAll(),\n info: sugar('info'),\n success: sugar('success'),\n warning: sugar('warning'),\n error: sugar('error'),\n setConfig: next => configSource.set(next),\n dispose: () => {\n if (mounted)\n app.unmount()\n disposed = true\n ctx = null\n if (!target)\n holder.remove()\n },\n }\n}\n"],"mappings":";;;;;;;AAuEA,SAAS,YACP,MACA,cACA,aACO;CACP,OAAO,EAAE,oBAAoB;EAC3B,IAAI,KAAK;EACT,OAAO,KAAK;EACZ,aAAa,KAAK;EAClB,MAAM,KAAK;EACX,UAAU,KAAK;EACf,aAAa,KAAK;EAClB,UAAU,KAAK;EACf,iBAAiB,KAAK;EACtB;EACA,iBAAiB,EAAE,IAAI,aAA6C;GAClE,IAAI,WAAW,aACb,YAAY,EAAE;EAClB;CACF,SAAS;EAIP,EAAE,2BAA2B;EAC7B,EAAE,uBAAuB;EACzB,EAAE,6BAA6B;EAC/B,KAAK,aAAa,QAAQ,EAAE,8BAA8B,IAAI;CAChE,CAAC;AACH;AAEA,SAAgB,0BAA0B,UAAsC,CAAC,GAAwB;CACvG,IAAI,OAAO,aAAa,aACtB,MAAM,IAAI,MAAM,sDAAsD;CAExE,MAAM,EAAE,QAAQ,QAAQ,GAAG,eAAe;CAC1C,MAAM,eAAe,oBAAoB,MAAM;CAC/C,MAAM,SAAS,UAAU,SAAS,cAAc,KAAK;CACrD,IAAI,CAAC,QACH,iBAAiB,QAAQ,CAAC,CAAC,YAAY,MAAM;CAE/C,IAAI,MAAkC;CA2BtC,MAAM,MAAW,UAzBJ,gBAAgB;EAC3B,MAAM;EACN,QAAQ;GACN,aAAa,QAAQ;GAErB,MAAM,QAAQ,uBAAuB;IAAE,GAAG;IAAY,cAAc,QAAQ,WAAW,YAAY;GAAE,EAAE;GACvG,MAAM;GAGN,MAAM,MAAM,eAAe,MAAM,IAAI,KAAK;GAC1C,aAAa;IACX,MAAM,QAAQ,IAAI;IAClB,OAAO,EAAE,OAAO,MAAM,aAAa,GAA8B,MAAM,WAAW,KAAI,cACpF,EACE,OACA;KAAE,KAAK;KAAW,GAAG,MAAM,cAAc,EAAE,UAAU,CAAC;IAA6B,GAEnF,MAAM,oBAAoB,SAAS,CAAC,CAAC,KAAI,SAAQ,EAAE,UAAU,EAAE,KAAK,KAAK,GAAG,GAAG,CAC7E,YAAY,MAAM,QAAQ,WAAW,YAAY,GAAG,MAAM,OAAO,CACnE,CAAC,CAAC,CACJ,CAAC,CAAC;GACN;EACF;CACF,CAE8B,CAAC;CAC/B,MAAM,UAAU,iBAAiB,KAAK,QAAQ,cAAc;CAC5D,IAAI,WAAW;;;;;CAMf,MAAM,YAAwC;EAC5C,IAAI,UACF,MAAM,IAAI,MAAM,oBAAoB;EACtC,OAAO,UAAU,MAAM;CACzB;CACA,MAAM,SAAS,UACZ,OAAe,OAAmC,CAAC,MAClD,IAAI,CAAC,EAAE,OAAO;EAAE,GAAG;EAAM;EAAM;CAAM,CAAC,KAAK;CAE/C,OAAO;EACL,SAAQ,SAAQ,IAAI,CAAC,EAAE,OAAO,IAAI,KAAK;EACvC,SAAS,IAAI,SAAS,IAAI,CAAC,EAAE,OAAO,IAAI,IAAI;EAC5C,UAAS,OAAM,IAAI,CAAC,EAAE,QAAQ,EAAE;EAChC,kBAAkB,IAAI,CAAC,EAAE,WAAW;EACpC,MAAM,MAAM,MAAM;EAClB,SAAS,MAAM,SAAS;EACxB,SAAS,MAAM,SAAS;EACxB,OAAO,MAAM,OAAO;EACpB,YAAW,SAAQ,aAAa,IAAI,IAAI;EACxC,eAAe;GACb,IAAI,SACF,IAAI,QAAQ;GACd,WAAW;GACX,MAAM;GACN,IAAI,CAAC,QACH,OAAO,OAAO;EAClB;CACF;AACF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { provideXhConfig } from "../config/config.js";
|
|
2
|
+
import { shallowRef, toValue } from "vue";
|
|
3
|
+
//#region src/services/service-config.ts
|
|
4
|
+
function createServiceConfig(initial) {
|
|
5
|
+
const box = shallowRef({ src: initial });
|
|
6
|
+
return {
|
|
7
|
+
provide: () => provideXhConfig(() => toValue(box.value.src) ?? {}),
|
|
8
|
+
set: (next) => {
|
|
9
|
+
box.value = { src: next };
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { createServiceConfig };
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=service-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-config.js","names":[],"sources":["../../src/services/service-config.ts"],"sourcesContent":["// 命令式服务共用的配置源。三个服务各自 createApp 到自建容器,接不到组件树里的\n// provideXhConfig,只能自己往宿主里 provide 一份;这里把那段收在一处。\n// 源收成 shallowRef 是为了运行期能换:传 ref/getter 的跟着应用切语言,\n// 没有响应式源的用句柄上的 setConfig 命令式推。\nimport type { MaybeRefOrGetter } from 'vue'\nimport type { XhConfig } from '../config/config'\nimport { shallowRef, toValue } from 'vue'\nimport { provideXhConfig } from '../config/config'\n\nexport interface ServiceConfigSource {\n /** 在宿主组件的 setup 里调一次。 */\n provide: () => void\n /** 换一份配置源;下一帧起服务子树读新值。 */\n set: (next: MaybeRefOrGetter<XhConfig> | undefined) => void\n}\n\nexport function createServiceConfig(initial?: MaybeRefOrGetter<XhConfig>): ServiceConfigSource {\n // 源本身可能就是个 ref,直接放进 shallowRef 会被解包成只读,故套一层盒子\n const box = shallowRef<{ src: MaybeRefOrGetter<XhConfig> | undefined }>({ src: initial })\n return {\n provide: () => provideXhConfig(() => toValue(box.value.src) ?? {}),\n set: (next) => {\n box.value = { src: next }\n },\n }\n}\n"],"mappings":";;;AAgBA,SAAgB,oBAAoB,SAA2D;CAE7F,MAAM,MAAM,WAA4D,EAAE,KAAK,QAAQ,CAAC;CACxF,OAAO;EACL,eAAe,sBAAsB,QAAQ,IAAI,MAAM,GAAG,KAAK,CAAC,CAAC;EACjE,MAAM,SAAS;GACb,IAAI,QAAQ,EAAE,KAAK,KAAK;EAC1B;CACF;AACF"}
|
|
@@ -1,23 +1,28 @@
|
|
|
1
1
|
import { XhConfig } from "../config/config.js";
|
|
2
|
-
import {
|
|
2
|
+
import { MaybeRefOrGetter } from "vue";
|
|
3
|
+
import { ToastOptions, ToastPlacement, ToastTranslations } from "@xihan-ui/headless";
|
|
3
4
|
//#region src/services/toast-service.d.ts
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
placement?: ToastPlacement;
|
|
7
|
-
/** 每个位置最多同时留几条,默认 5。 */
|
|
8
|
-
max?: number;
|
|
9
|
-
gap?: number;
|
|
5
|
+
/** 单条没写时的兜底:服务档一次定好,逐条渲染时补进去。 */
|
|
6
|
+
interface ToastDefaults {
|
|
10
7
|
duration?: number;
|
|
11
8
|
removeDelay?: number;
|
|
12
9
|
pauseOnPageIdle?: boolean;
|
|
13
|
-
|
|
10
|
+
}
|
|
11
|
+
interface ToastServiceOptions extends ToastDefaults {
|
|
12
|
+
/** 那一摞落在哪儿,默认 'top':视线正好在刚才操作的地方上方。 */
|
|
13
|
+
placement?: ToastPlacement;
|
|
14
|
+
/** 最多同时留几条,超出挤掉最旧的,默认 5。 */
|
|
15
|
+
max?: number;
|
|
16
|
+
/** 摞内间距(px),默认 16。 */
|
|
17
|
+
gap?: number;
|
|
14
18
|
/** toast 部件的文案(关闭钮的读屏名等)。 */
|
|
15
|
-
toastTranslations?: Partial<ToastTranslations
|
|
19
|
+
toastTranslations?: MaybeRefOrGetter<Partial<ToastTranslations>>;
|
|
16
20
|
/**
|
|
17
|
-
*
|
|
18
|
-
* 本服务自带宿主应用,接不到组件树里的 provideXhConfig
|
|
21
|
+
* 喂给轻提示子树的全局配置(locale / translations / size / portalContainer)。
|
|
22
|
+
* 本服务自带宿主应用,接不到组件树里的 provideXhConfig,要让它跟应用同语言就从这里给;
|
|
23
|
+
* 传 ref/getter 即可运行期跟着切语言,也可以之后用 setConfig 推。
|
|
19
24
|
*/
|
|
20
|
-
config?: XhConfig
|
|
25
|
+
config?: MaybeRefOrGetter<XhConfig>;
|
|
21
26
|
/** 宿主容器;不给就在 body 下新建一个。 */
|
|
22
27
|
target?: HTMLElement;
|
|
23
28
|
}
|
|
@@ -27,6 +32,7 @@ interface ToastService {
|
|
|
27
32
|
/** 入队并返回 id;同 id 已存在则就地改写。 */
|
|
28
33
|
create: (options?: ToastOptions) => string;
|
|
29
34
|
update: (id: string, options: Partial<ToastOptions>) => void;
|
|
35
|
+
/** 立刻从队列里删掉。条子自己的关闭按钮走的是退场窗口,有退场动画。 */
|
|
30
36
|
dismiss: (id: string) => void;
|
|
31
37
|
dismissAll: () => void;
|
|
32
38
|
info: (message: string, options?: ToastMessageOptions) => string;
|
|
@@ -35,6 +41,8 @@ interface ToastService {
|
|
|
35
41
|
error: (message: string, options?: ToastMessageOptions) => string;
|
|
36
42
|
/** 返回 id,之后用 update(id, { type: 'success', title: … }) 收尾。 */
|
|
37
43
|
loading: (message: string, options?: ToastMessageOptions) => string;
|
|
44
|
+
/** 换一份全局配置源。 */
|
|
45
|
+
setConfig: (next: MaybeRefOrGetter<XhConfig> | undefined) => void;
|
|
38
46
|
/** 卸载宿主应用并移除容器。 */
|
|
39
47
|
dispose: () => void;
|
|
40
48
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toast-service.d.ts","names":[],"sources":["../../src/services/toast-service.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"toast-service.d.ts","names":[],"sources":["../../src/services/toast-service.ts"],"mappings":";;;;;UAoBU;EACR;EACA;EACA;;UAGe,4BAA4B;;EAE3C,YAAY;;EAEZ;;EAEA;;EAEA,oBAAoB,iBAAiB,QAAQ;;;;;;EAM7C,SAAS,iBAAiB;;EAE1B,SAAS;;;KAIC,sBAAsB,KAAK;UAEtB;;EAEf,SAAS,UAAU;EACnB,SAAS,YAAY,SAAS,QAAQ;;EAEtC,UAAU;EACV;EACA,OAAO,iBAAiB,UAAU;EAClC,UAAU,iBAAiB,UAAU;EACrC,UAAU,iBAAiB,UAAU;EACrC,QAAQ,iBAAiB,UAAU;;EAEnC,UAAU,iBAAiB,UAAU;;EAErC,YAAY,MAAM,iBAAiB;;EAEnC;;iBAgDc,mBAAmB,UAAS,sBAA2B"}
|