@kine-design/core 0.0.1-beta.1 → 0.0.1-beta.10
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/.vlaude/last-session-id +1 -0
- package/.vlaude/session-switch.signal +1 -0
- package/assets/style/global.css +1 -0
- package/assets/style/var/Wuxing.css +71 -0
- package/assets/style/var.css +23 -0
- package/components/base/affix/api.ts +16 -0
- package/components/base/affix/index.ts +17 -0
- package/components/base/affix/props.d.ts +34 -0
- package/components/base/affix/useAffix.ts +124 -0
- package/components/base/alert/api.ts +18 -0
- package/components/base/alert/index.ts +15 -0
- package/components/base/alert/props.d.ts +50 -0
- package/components/base/anchor/api.ts +20 -0
- package/components/base/anchor/index.ts +18 -0
- package/components/base/anchor/props.d.ts +46 -0
- package/components/base/anchor/useAnchor.ts +84 -0
- package/components/base/autoComplete/api.ts +24 -0
- package/components/base/autoComplete/index.ts +17 -0
- package/components/base/autoComplete/props.d.ts +75 -0
- package/components/base/autoComplete/useAutoComplete.ts +157 -0
- package/components/base/avatar/api.ts +17 -0
- package/components/base/avatar/avatar.css +61 -0
- package/components/base/avatar/index.ts +15 -0
- package/components/base/avatar/props.d.ts +37 -0
- package/components/base/backTop/api.ts +17 -0
- package/components/base/backTop/index.ts +17 -0
- package/components/base/backTop/props.d.ts +38 -0
- package/components/base/backTop/useBackTop.ts +62 -0
- package/components/base/badge/api.ts +22 -0
- package/components/base/badge/index.ts +15 -0
- package/components/base/badge/props.d.ts +50 -0
- package/components/base/button/api.ts +28 -0
- package/components/base/button/button.css +34 -0
- package/components/base/button/index.ts +17 -0
- package/components/base/button/props.d.ts +66 -0
- package/components/base/button/useButton.ts +37 -0
- package/components/base/card/api.ts +17 -0
- package/components/base/card/index.ts +15 -0
- package/components/base/card/props.d.ts +37 -0
- package/components/base/carousel/api.ts +28 -0
- package/components/base/carousel/index.ts +17 -0
- package/components/base/carousel/props.d.ts +72 -0
- package/components/base/carousel/useCarousel.ts +150 -0
- package/components/base/cascader/api.ts +23 -0
- package/components/base/cascader/index.ts +18 -0
- package/components/base/cascader/props.d.ts +103 -0
- package/components/base/cascader/useCascader.ts +335 -0
- package/components/base/checkbox/api.ts +24 -0
- package/components/base/checkbox/checkbox.css +0 -0
- package/components/base/checkbox/index.ts +17 -0
- package/components/base/checkbox/props.d.ts +77 -0
- package/components/base/checkbox/useCheckbox.ts +43 -0
- package/components/base/collapse/api.ts +21 -0
- package/components/base/collapse/index.ts +18 -0
- package/components/base/collapse/props.d.ts +45 -0
- package/components/base/collapse/useCollapse.ts +81 -0
- package/components/base/datePicker/__tests__/useDatePicker.test.ts +244 -0
- package/components/base/datePicker/api.ts +22 -0
- package/components/base/datePicker/index.ts +19 -0
- package/components/base/datePicker/props.d.ts +86 -0
- package/components/base/datePicker/useDatePicker.ts +392 -0
- package/components/base/divider/api.ts +15 -0
- package/components/base/divider/divider.css +11 -0
- package/components/base/divider/index.ts +15 -0
- package/components/base/divider/props.d.ts +30 -0
- package/components/base/dropdown/api.ts +33 -0
- package/components/base/dropdown/index.ts +18 -0
- package/components/base/dropdown/props.d.ts +60 -0
- package/components/base/dropdown/useDropdown.ts +124 -0
- package/components/base/empty/api.ts +15 -0
- package/components/base/empty/index.ts +15 -0
- package/components/base/empty/props.d.ts +26 -0
- package/components/base/image/__tests__/useImage.test.ts +176 -0
- package/components/base/image/api.ts +25 -0
- package/components/base/image/index.ts +18 -0
- package/components/base/image/props.d.ts +67 -0
- package/components/base/image/useImage.ts +119 -0
- package/components/base/input/api.ts +23 -0
- package/components/base/input/index.ts +17 -0
- package/components/base/input/input.css +19 -0
- package/components/base/input/props.d.ts +85 -0
- package/components/base/input/useInput.ts +63 -0
- package/components/base/inputNumber/__tests__/useInputNumber.test.ts +189 -0
- package/components/base/inputNumber/api.ts +23 -0
- package/components/base/inputNumber/index.ts +17 -0
- package/components/base/inputNumber/props.d.ts +78 -0
- package/components/base/inputNumber/useInputNumber.ts +182 -0
- package/components/base/li/api.ts +15 -0
- package/components/base/li/index.ts +15 -0
- package/components/base/li/props.d.ts +30 -0
- package/components/base/list/api.ts +16 -0
- package/components/base/list/index.ts +17 -0
- package/components/base/list/props.d.ts +33 -0
- package/components/base/list/useList.ts +36 -0
- package/components/base/loading/api.ts +17 -0
- package/components/base/loading/index.ts +15 -0
- package/components/base/loading/props.d.ts +40 -0
- package/components/base/popover/api.ts +28 -0
- package/components/base/popover/index.ts +17 -0
- package/components/base/popover/props.d.ts +73 -0
- package/components/base/popover/usePopover.ts +193 -0
- package/components/base/progress/api.ts +20 -0
- package/components/base/progress/index.ts +17 -0
- package/components/base/progress/props.d.ts +68 -0
- package/components/base/progress/useProgress.ts +28 -0
- package/components/base/radio/api.ts +19 -0
- package/components/base/radio/index.ts +19 -0
- package/components/base/radio/props.d.ts +59 -0
- package/components/base/radio/useRadio.ts +11 -0
- package/components/base/rate/api.ts +18 -0
- package/components/base/rate/index.ts +17 -0
- package/components/base/rate/props.d.ts +49 -0
- package/components/base/rate/useRate.ts +76 -0
- package/components/base/result/api.ts +20 -0
- package/components/base/result/index.ts +15 -0
- package/components/base/result/props.d.ts +36 -0
- package/components/base/select/api.ts +34 -0
- package/components/base/select/index.ts +18 -0
- package/components/base/select/props.d.ts +152 -0
- package/components/base/select/select.css +7 -0
- package/components/base/select/useSelect.ts +281 -0
- package/components/base/select/useSelectTools.ts +60 -0
- package/components/base/skeleton/api.ts +18 -0
- package/components/base/skeleton/index.ts +15 -0
- package/components/base/skeleton/props.d.ts +41 -0
- package/components/base/slider/api.ts +22 -0
- package/components/base/slider/index.ts +17 -0
- package/components/base/slider/props.d.ts +79 -0
- package/components/base/slider/useSlider.ts +87 -0
- package/components/base/space/api.ts +17 -0
- package/components/base/space/index.ts +15 -0
- package/components/base/space/props.d.ts +39 -0
- package/components/base/steps/__tests__/useSteps.test.ts +46 -0
- package/components/base/steps/api.ts +30 -0
- package/components/base/steps/index.ts +22 -0
- package/components/base/steps/props.d.ts +88 -0
- package/components/base/steps/useSteps.ts +101 -0
- package/components/base/switch/api.ts +22 -0
- package/components/base/switch/index.ts +19 -0
- package/components/base/switch/props.d.ts +66 -0
- package/components/base/switch/useSwitch.tsx +80 -0
- package/components/base/tabs/api.ts +23 -0
- package/components/base/tabs/index.ts +18 -0
- package/components/base/tabs/props.d.ts +41 -0
- package/components/base/tabs/useTabs.ts +67 -0
- package/components/base/tag/api.ts +17 -0
- package/components/base/tag/index.ts +15 -0
- package/components/base/tag/props.d.ts +51 -0
- package/components/base/timePicker/__tests__/useTimePicker.test.ts +124 -0
- package/components/base/timePicker/api.ts +24 -0
- package/components/base/timePicker/index.ts +18 -0
- package/components/base/timePicker/props.d.ts +86 -0
- package/components/base/timePicker/useTimePicker.ts +161 -0
- package/components/base/timeline/api.ts +24 -0
- package/components/base/timeline/index.ts +16 -0
- package/components/base/timeline/props.d.ts +60 -0
- package/components/base/tooltip/api.ts +21 -0
- package/components/base/tooltip/index.ts +18 -0
- package/components/base/tooltip/props.d.ts +46 -0
- package/components/base/tooltip/useTooltip.ts +208 -0
- package/components/base/transfer/api.ts +18 -0
- package/components/base/transfer/index.ts +17 -0
- package/components/base/transfer/props.d.ts +63 -0
- package/components/base/transfer/useTransfer.ts +208 -0
- package/components/base/tree/__tests__/tree.test.ts +223 -0
- package/components/base/tree/api.ts +47 -0
- package/components/base/tree/index.ts +29 -0
- package/components/base/tree/props.d.ts +108 -0
- package/components/base/tree/tree.ts +263 -0
- package/components/base/tree/useTree.ts +114 -0
- package/components/message/confirm/api.ts +21 -0
- package/components/message/confirm/index.ts +15 -0
- package/components/message/confirm/props.d.ts +69 -0
- package/components/message/dialog/api.ts +20 -0
- package/components/message/dialog/index.ts +15 -0
- package/components/message/dialog/props.d.ts +62 -0
- package/components/message/drawer/api.ts +33 -0
- package/components/message/drawer/index.ts +15 -0
- package/components/message/drawer/props.d.ts +80 -0
- package/components/message/message/api.ts +27 -0
- package/components/message/message/index.ts +20 -0
- package/components/message/message/props.d.ts +54 -0
- package/components/message/message/useMessage.ts +61 -0
- package/components/message/notification/__tests__/useNotification.test.ts +129 -0
- package/components/message/notification/api.ts +23 -0
- package/components/message/notification/index.ts +19 -0
- package/components/message/notification/props.d.ts +64 -0
- package/components/message/notification/useNotification.ts +79 -0
- package/components/message/popover/MPopover.tsx +94 -0
- package/components/message/popover/api.ts +54 -0
- package/components/message/popover/index.ts +17 -0
- package/components/message/popover/popover.css +21 -0
- package/components/message/popover/props.d.ts +76 -0
- package/components/message/popover/usePopover.ts +234 -0
- package/components/other/darkMode/api.ts +17 -0
- package/components/other/darkMode/index.ts +17 -0
- package/components/other/darkMode/props.d.ts +37 -0
- package/components/other/darkMode/useDarkMode.ts +129 -0
- package/components/template/border/api.ts +18 -0
- package/components/template/border/index.ts +15 -0
- package/components/template/border/props.d.ts +41 -0
- package/components/template/breadcrumb/api.ts +15 -0
- package/components/template/breadcrumb/index.ts +15 -0
- package/components/template/breadcrumb/props.d.ts +45 -0
- package/components/template/descriptions/api.ts +23 -0
- package/components/template/descriptions/index.ts +16 -0
- package/components/template/descriptions/props.d.ts +54 -0
- package/components/template/form/api.ts +23 -0
- package/components/template/form/index.ts +20 -0
- package/components/template/form/props.d.ts +60 -0
- package/components/template/grid/api.ts +20 -0
- package/components/template/grid/index.ts +15 -0
- package/components/template/grid/props.d.ts +48 -0
- package/components/template/menu/__tests__/useMenu.test.ts +157 -0
- package/components/template/menu/api.ts +26 -0
- package/components/template/menu/index.ts +18 -0
- package/components/template/menu/props.d.ts +93 -0
- package/components/template/menu/useMenu.ts +155 -0
- package/components/template/pagination/__tests__/usePagination.test.ts +138 -0
- package/components/template/pagination/api.ts +22 -0
- package/components/template/pagination/index.ts +19 -0
- package/components/template/pagination/props.d.ts +65 -0
- package/components/template/pagination/usePagination.ts +186 -0
- package/components/template/table/__tests__/useTable.test.ts +138 -0
- package/components/template/table/api.ts +18 -0
- package/components/template/table/index.ts +18 -0
- package/components/template/table/props.d.ts +36 -0
- package/components/template/table/useTable.ts +136 -0
- package/components/template/tableColumn/api.ts +17 -0
- package/components/template/tableColumn/index.ts +15 -0
- package/components/template/tableColumn/props.d.ts +32 -0
- package/components/template/virtualList/api.ts +16 -0
- package/components/template/virtualList/index.ts +17 -0
- package/components/template/virtualList/props.d.ts +25 -0
- package/components/template/virtualList/useVirtualList.ts +237 -0
- package/components/types/hook.d.ts +24 -0
- package/components/types/props.d.ts +57 -0
- package/components/types/template.d.ts +59 -0
- package/compositions/commandPalette/index.ts +11 -0
- package/compositions/commandPalette/types.ts +29 -0
- package/compositions/commandPalette/useCommandPalette.ts +135 -0
- package/compositions/common/__tests__/useDebounceFn.test.ts +62 -0
- package/compositions/common/__tests__/useEventListener.test.ts +98 -0
- package/compositions/common/__tests__/usePopover.test.ts +43 -0
- package/compositions/common/__tests__/useTeleport.test.ts +32 -0
- package/compositions/common/defineCore.ts +55 -0
- package/compositions/common/testAnchor.ts +211 -0
- package/compositions/common/useComponentSize.ts +17 -0
- package/compositions/common/useDebounceFn.ts +27 -0
- package/compositions/common/useDrag.ts +65 -0
- package/compositions/common/useElementSize.ts +37 -0
- package/compositions/common/useEventListener.ts +48 -0
- package/compositions/common/usePopover.ts +45 -0
- package/compositions/common/useResizeObserver.ts +47 -0
- package/compositions/common/useTeleport.ts +24 -0
- package/compositions/contextMenu/index.ts +10 -0
- package/compositions/contextMenu/types.ts +21 -0
- package/compositions/contextMenu/useContextMenu.ts +101 -0
- package/compositions/editor/index.ts +18 -0
- package/compositions/editor/types.ts +147 -0
- package/compositions/editor/useEditor.ts +224 -0
- package/compositions/index.ts +15 -0
- package/compositions/input/__tests__/useBooleanInput.test.ts +73 -0
- package/compositions/input/useBooleanInput.ts +52 -0
- package/compositions/modal/__tests__/useModal.test.ts +110 -0
- package/compositions/modal/useModal.ts +72 -0
- package/compositions/overlay/index.ts +14 -0
- package/compositions/overlay/useOverlayStack.ts +146 -0
- package/compositions/peekView/index.ts +10 -0
- package/compositions/peekView/usePeekView.ts +99 -0
- package/compositions/popper/useClickAway.ts +41 -0
- package/compositions/popper/usePopper.ts +63 -0
- package/compositions/theme/index.ts +17 -0
- package/compositions/theme/presets/compact.ts +117 -0
- package/compositions/theme/presets/dark.ts +113 -0
- package/compositions/theme/presets/index.ts +11 -0
- package/compositions/theme/presets/light.ts +113 -0
- package/compositions/theme/types.ts +46 -0
- package/compositions/theme/useTheme.ts +269 -0
- package/compositions/toast/index.ts +10 -0
- package/compositions/toast/useToast.ts +176 -0
- package/compositions/tooltip/index.ts +9 -0
- package/compositions/tooltip/useTooltip.ts +10 -0
- package/compositions/utils/__tests__/filters.test.ts +136 -0
- package/compositions/utils/filters.ts +135 -0
- package/compositions/virtualList/__tests__/useHeightCache.test.ts +97 -0
- package/compositions/virtualList/enums.ts +52 -0
- package/compositions/virtualList/useContainerObserver.ts +89 -0
- package/compositions/virtualList/useEntries.ts +248 -0
- package/compositions/virtualList/useHeightCache.ts +83 -0
- package/compositions/virtualList/useSentinelObserver.ts +81 -0
- package/dist/components/base/affix/index.d.ts +2 -1
- package/dist/components/base/affix/useAffix.d.ts +7 -5
- package/dist/components/base/anchor/index.d.ts +2 -1
- package/dist/components/base/anchor/useAnchor.d.ts +3 -2
- package/dist/components/base/autoComplete/useAutoComplete.d.ts +14 -5
- package/dist/components/base/avatar/index.d.ts +1 -0
- package/dist/components/base/backTop/index.d.ts +2 -1
- package/dist/components/base/backTop/useBackTop.d.ts +2 -2
- package/dist/components/base/button/index.d.ts +3 -21
- package/dist/components/base/button/useButton.d.ts +5 -2
- package/dist/components/base/carousel/useCarousel.d.ts +7 -3
- package/dist/components/base/cascader/useCascader.d.ts +25 -12
- package/dist/components/base/checkbox/index.d.ts +2 -1
- package/dist/components/base/checkbox/useCheckbox.d.ts +5 -3
- package/dist/components/base/collapse/index.d.ts +2 -1
- package/dist/components/base/collapse/useCollapse.d.ts +4 -3
- package/dist/components/base/datePicker/__tests__/useDatePicker.test.d.ts +1 -0
- package/dist/components/base/datePicker/useDatePicker.d.ts +140 -8
- package/dist/components/base/dropdown/index.d.ts +2 -1
- package/dist/components/base/dropdown/useDropdown.d.ts +13 -6
- package/dist/components/base/image/__tests__/useImage.test.d.ts +1 -0
- package/dist/components/base/image/useImage.d.ts +5 -5
- package/dist/components/base/input/index.d.ts +2 -1
- package/dist/components/base/input/useInput.d.ts +4 -2
- package/dist/components/base/inputNumber/__tests__/useInputNumber.test.d.ts +1 -0
- package/dist/components/base/inputNumber/index.d.ts +2 -1
- package/dist/components/base/inputNumber/useInputNumber.d.ts +4 -3
- package/dist/components/base/li/index.d.ts +1 -0
- package/dist/components/base/list/index.d.ts +2 -1
- package/dist/components/base/list/useList.d.ts +1 -1
- package/dist/components/base/popover/index.d.ts +2 -1
- package/dist/components/base/popover/usePopover.d.ts +10 -9
- package/dist/components/base/progress/index.d.ts +2 -1
- package/dist/components/base/progress/useProgress.d.ts +2 -2
- package/dist/components/base/rate/index.d.ts +2 -1
- package/dist/components/base/rate/useRate.d.ts +3 -2
- package/dist/components/base/select/useSelect.d.ts +10 -9
- package/dist/components/base/slider/index.d.ts +2 -1
- package/dist/components/base/slider/useSlider.d.ts +5 -4
- package/dist/components/base/steps/__tests__/useSteps.test.d.ts +1 -0
- package/dist/components/base/steps/index.d.ts +1 -1
- package/dist/components/base/steps/useSteps.d.ts +5 -5
- package/dist/components/base/switch/index.d.ts +2 -1
- package/dist/components/base/switch/useSwitch.d.ts +9 -3
- package/dist/components/base/tabs/index.d.ts +1 -1
- package/dist/components/base/tabs/useTabs.d.ts +4 -3
- package/dist/components/base/tag/index.d.ts +1 -0
- package/dist/components/base/timePicker/__tests__/useTimePicker.test.d.ts +1 -0
- package/dist/components/base/timePicker/useTimePicker.d.ts +14 -6
- package/dist/components/base/tooltip/index.d.ts +2 -1
- package/dist/components/base/tooltip/useTooltip.d.ts +24 -11
- package/dist/components/base/transfer/useTransfer.d.ts +17 -16
- package/dist/components/base/tree/__tests__/tree.test.d.ts +1 -0
- package/dist/components/base/tree/index.d.ts +1 -1
- package/dist/components/base/tree/useTree.d.ts +2 -1
- package/dist/components/message/drawer/index.d.ts +2 -2
- package/dist/components/message/message/useMessage.d.ts +11 -1
- package/dist/components/message/notification/__tests__/useNotification.test.d.ts +1 -0
- package/dist/components/message/notification/useNotification.d.ts +17 -1
- package/dist/components/message/popover/MPopover.d.ts +6 -1
- package/dist/components/message/popover/index.d.ts +1 -1
- package/dist/components/message/popover/usePopover.d.ts +7 -7
- package/dist/components/other/darkMode/useDarkMode.d.ts +3 -4
- package/dist/components/template/menu/__tests__/useMenu.test.d.ts +1 -0
- package/dist/components/template/menu/index.d.ts +0 -1
- package/dist/components/template/menu/useMenu.d.ts +2 -1
- package/dist/components/template/pagination/__tests__/usePagination.test.d.ts +1 -0
- package/dist/components/template/pagination/index.d.ts +2 -1
- package/dist/components/template/table/__tests__/useTable.test.d.ts +1 -0
- package/dist/components/template/virtualList/index.d.ts +0 -1
- package/dist/components/template/virtualList/useVirtualList.d.ts +10 -7
- package/dist/compositions/commandPalette/index.d.ts +11 -0
- package/dist/compositions/commandPalette/types.d.ts +20 -0
- package/dist/compositions/commandPalette/useCommandPalette.d.ts +32 -0
- package/dist/compositions/common/__tests__/useDebounceFn.test.d.ts +1 -0
- package/dist/compositions/common/__tests__/useEventListener.test.d.ts +1 -0
- package/dist/compositions/common/__tests__/usePopover.test.d.ts +1 -0
- package/dist/compositions/common/__tests__/useTeleport.test.d.ts +1 -0
- package/dist/compositions/common/testAnchor.d.ts +40 -0
- package/dist/compositions/common/useComponentSize.d.ts +6 -0
- package/dist/compositions/common/useDrag.d.ts +1 -1
- package/dist/compositions/common/useElementSize.d.ts +2 -2
- package/dist/compositions/common/useEventListener.d.ts +2 -2
- package/dist/compositions/common/useTeleport.d.ts +4 -2
- package/dist/compositions/contextMenu/index.d.ts +10 -0
- package/dist/compositions/contextMenu/types.d.ts +12 -0
- package/dist/compositions/contextMenu/useContextMenu.d.ts +52 -0
- package/dist/compositions/editor/index.d.ts +10 -0
- package/dist/compositions/editor/types.d.ts +132 -0
- package/dist/compositions/editor/useEditor.d.ts +13 -0
- package/dist/compositions/index.d.ts +15 -0
- package/dist/compositions/input/__tests__/useBooleanInput.test.d.ts +1 -0
- package/dist/compositions/modal/__tests__/useModal.test.d.ts +1 -0
- package/dist/compositions/modal/useModal.d.ts +3 -2
- package/dist/compositions/overlay/index.d.ts +10 -0
- package/dist/compositions/overlay/useOverlayStack.d.ts +188 -0
- package/dist/compositions/peekView/index.d.ts +10 -0
- package/dist/compositions/peekView/usePeekView.d.ts +16 -0
- package/dist/compositions/popper/useClickAway.d.ts +3 -3
- package/dist/compositions/theme/index.d.ts +11 -0
- package/dist/compositions/theme/presets/compact.d.ts +6 -0
- package/dist/compositions/theme/presets/dark.d.ts +2 -0
- package/dist/compositions/theme/presets/index.d.ts +11 -0
- package/dist/compositions/theme/presets/light.d.ts +2 -0
- package/dist/compositions/theme/types.d.ts +41 -0
- package/dist/compositions/theme/useTheme.d.ts +167 -0
- package/dist/compositions/toast/index.d.ts +10 -0
- package/dist/compositions/toast/useToast.d.ts +71 -0
- package/dist/compositions/tooltip/index.d.ts +9 -0
- package/dist/compositions/tooltip/useTooltip.d.ts +10 -0
- package/dist/compositions/utils/__tests__/filters.test.d.ts +1 -0
- package/dist/compositions/virtualList/__tests__/useHeightCache.test.d.ts +1 -0
- package/dist/core.js +7050 -4188
- package/dist/index.d.ts +1 -0
- package/dist/runtime/defineHook.d.ts +1 -1
- package/dist/tools/__tests__/empty.test.d.ts +1 -0
- package/dist/tools/empty.d.ts +2 -2
- package/dist/tools/types.d.ts +1 -1
- package/dist/vitest.config.d.ts +10 -0
- package/index.css +1 -0
- package/index.ts +73 -0
- package/package.json +41 -22
- package/runtime/defineHook.ts +21 -0
- package/tools/__tests__/empty.test.ts +91 -0
- package/tools/empty.ts +81 -0
- package/tools/index.ts +15 -0
- package/tools/types.ts +11 -0
- package/tsconfig.json +8 -0
- package/types/common/common.d.ts +25 -0
- package/types/common/model.d.ts +25 -0
- package/types/index.d.ts +11 -0
- package/types/props.d.ts +13 -0
- package/vite.config.build.ts +41 -0
- package/vitest.config.ts +17 -0
- package/dist/vite.config.build.d.ts +0 -2
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description rate hook
|
|
3
|
+
* @author 阿怪
|
|
4
|
+
* @date 2026/2/26
|
|
5
|
+
* @version v1.0.0
|
|
6
|
+
*
|
|
7
|
+
* 江湖的业务千篇一律,复杂的代码好几百行。
|
|
8
|
+
*/
|
|
9
|
+
import { ref } from 'vue';
|
|
10
|
+
import { type HookContext } from '../../types/hook';
|
|
11
|
+
import { RateProps } from './props';
|
|
12
|
+
|
|
13
|
+
export function useRate(props: Required<RateProps>, emit: HookContext['emit']) {
|
|
14
|
+
// 悬停预览值,null 表示未悬停
|
|
15
|
+
const hoverValue = ref<number | null>(null);
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* 计算鼠标在星星内的位置,返回实际值(支持半星)
|
|
19
|
+
*/
|
|
20
|
+
const getValueFromEvent = (e: MouseEvent, index: number): number => {
|
|
21
|
+
if (!props.allowHalf) {
|
|
22
|
+
return index + 1;
|
|
23
|
+
}
|
|
24
|
+
const target = e.currentTarget as HTMLElement;
|
|
25
|
+
const { left, width } = target.getBoundingClientRect();
|
|
26
|
+
const isHalf = (e.clientX - left) / width <= 0.5;
|
|
27
|
+
return isHalf ? index + 0.5 : index + 1;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const onMouseEnter = (e: MouseEvent, index: number) => {
|
|
31
|
+
if (props.disabled || props.readonly) { return; }
|
|
32
|
+
hoverValue.value = getValueFromEvent(e, index);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const onMouseMove = (e: MouseEvent, index: number) => {
|
|
36
|
+
if (props.disabled || props.readonly) { return; }
|
|
37
|
+
hoverValue.value = getValueFromEvent(e, index);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const onMouseLeave = () => {
|
|
41
|
+
if (props.disabled || props.readonly) { return; }
|
|
42
|
+
hoverValue.value = null;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const onClick = (e: MouseEvent, index: number) => {
|
|
46
|
+
if (props.disabled || props.readonly) { return; }
|
|
47
|
+
const value = getValueFromEvent(e, index);
|
|
48
|
+
emit('update:modelValue', value);
|
|
49
|
+
emit('change', value);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* 计算第 index 颗星(0 起始)的填充状态
|
|
54
|
+
* @returns 'full' | 'half' | 'empty'
|
|
55
|
+
*/
|
|
56
|
+
const getStarState = (index: number): 'full' | 'half' | 'empty' => {
|
|
57
|
+
const current = hoverValue.value ?? props.modelValue;
|
|
58
|
+
const starValue = index + 1;
|
|
59
|
+
if (current >= starValue) {
|
|
60
|
+
return 'full';
|
|
61
|
+
}
|
|
62
|
+
if (props.allowHalf && current >= starValue - 0.5) {
|
|
63
|
+
return 'half';
|
|
64
|
+
}
|
|
65
|
+
return 'empty';
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
hoverValue,
|
|
70
|
+
getStarState,
|
|
71
|
+
onMouseEnter,
|
|
72
|
+
onMouseMove,
|
|
73
|
+
onMouseLeave,
|
|
74
|
+
onClick,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description result api
|
|
3
|
+
* @author 阿怪
|
|
4
|
+
* @date 2026/2/26
|
|
5
|
+
* @version v1.0.0
|
|
6
|
+
*
|
|
7
|
+
* 江湖的业务千篇一律,复杂的代码好几百行。
|
|
8
|
+
*/
|
|
9
|
+
import { MCOPO, MPropType } from '../../types/props';
|
|
10
|
+
import { ResultProps, ResultStatus } from './props';
|
|
11
|
+
|
|
12
|
+
export const props: MCOPO<ResultProps> = {
|
|
13
|
+
status: {
|
|
14
|
+
type: String as MPropType<ResultStatus>,
|
|
15
|
+
default: 'info',
|
|
16
|
+
enum: ['success', 'warning', 'error', 'info', '404'],
|
|
17
|
+
},
|
|
18
|
+
title: { type: String, default: '' },
|
|
19
|
+
subTitle: { type: String, default: '' },
|
|
20
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description result core 导出
|
|
3
|
+
* @author 阿怪
|
|
4
|
+
* @date 2026/2/26
|
|
5
|
+
* @version v1.0.0
|
|
6
|
+
*
|
|
7
|
+
* 江湖的业务千篇一律,复杂的代码好几百行。
|
|
8
|
+
*/
|
|
9
|
+
import { props } from './api';
|
|
10
|
+
|
|
11
|
+
export const ResultCore = {
|
|
12
|
+
props,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type { ResultProps, ResultStatus } from './props';
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description result props type
|
|
3
|
+
* @author 阿怪
|
|
4
|
+
* @date 2026/2/26
|
|
5
|
+
* @version v1.0.0
|
|
6
|
+
*
|
|
7
|
+
* @name m-result
|
|
8
|
+
* @docDescription Result page component for displaying operation results.
|
|
9
|
+
* 结果页组件,用于展示操作结果或页面状态。
|
|
10
|
+
*
|
|
11
|
+
* 江湖的业务千篇一律,复杂的代码好几百行。
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export declare type ResultStatus = 'success' | 'warning' | 'error' | 'info' | '404';
|
|
15
|
+
|
|
16
|
+
export declare type ResultProps = {
|
|
17
|
+
/**
|
|
18
|
+
* @description 结果状态,决定默认图标和配色
|
|
19
|
+
* @type string
|
|
20
|
+
* @default 'info'
|
|
21
|
+
* @enum success|warning|error|info|404
|
|
22
|
+
*/
|
|
23
|
+
status?: ResultStatus,
|
|
24
|
+
/**
|
|
25
|
+
* @description 主标题
|
|
26
|
+
* @type string
|
|
27
|
+
* @default ''
|
|
28
|
+
*/
|
|
29
|
+
title?: string,
|
|
30
|
+
/**
|
|
31
|
+
* @description 副标题
|
|
32
|
+
* @type string
|
|
33
|
+
* @default ''
|
|
34
|
+
*/
|
|
35
|
+
subTitle?: string,
|
|
36
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description select api
|
|
3
|
+
* @author 阿怪
|
|
4
|
+
* @date 2023/4/23 11:46
|
|
5
|
+
* @version v1.0.1
|
|
6
|
+
*
|
|
7
|
+
* 江湖的业务千篇一律,复杂的代码好几百行。
|
|
8
|
+
*
|
|
9
|
+
* v1.0.1 新增 filterable prop 阿怪 2026/2/27
|
|
10
|
+
*/
|
|
11
|
+
import { MCOPO, MPropType } from '../../types/props';
|
|
12
|
+
import { SelectProps } from './props';
|
|
13
|
+
|
|
14
|
+
export const props: MCOPO<SelectProps> = {
|
|
15
|
+
modelValue: { type: undefined, default: '' },
|
|
16
|
+
options: { type: Array, default: () => [] },
|
|
17
|
+
inputParam: { type: String, default: undefined },
|
|
18
|
+
optionParam: { type: String, default: undefined },
|
|
19
|
+
valueParam: { type: String, default: undefined },
|
|
20
|
+
readonly: { type: Boolean, default: true },
|
|
21
|
+
disabled: { type: Boolean, default: false },
|
|
22
|
+
placeholder: { type: String, default: '请选择...' },
|
|
23
|
+
toMatch: { type: Function as MPropType<(option: any, value: any) => boolean>, default: undefined },
|
|
24
|
+
multiple: { type: Boolean, default: false },
|
|
25
|
+
checkbox: { type: Boolean, default: true },
|
|
26
|
+
filterable: { type: Boolean, default: false },
|
|
27
|
+
filter: { type: Function as MPropType<(option: any, inputValue: string) => boolean>, default: undefined },
|
|
28
|
+
optionsH: { type: [Number, String], default: undefined },
|
|
29
|
+
needFetch: { type: Boolean, default: false },
|
|
30
|
+
fetch: { type: Function as MPropType<() => Promise<void>>, default: undefined },
|
|
31
|
+
clearable: { type: Boolean, default: false },
|
|
32
|
+
size: { type: String as unknown as MPropType<NonNullable<SelectProps['size']>>, default: undefined },
|
|
33
|
+
loading: { type: Boolean, default: false },
|
|
34
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description select core 导出
|
|
3
|
+
* @author 阿怪
|
|
4
|
+
* @date 2026/2/25 14:50
|
|
5
|
+
* @version v2.0.0
|
|
6
|
+
*
|
|
7
|
+
* 江湖的业务千篇一律,复杂的代码好几百行。
|
|
8
|
+
*/
|
|
9
|
+
import { props } from './api';
|
|
10
|
+
import { useSelect } from './useSelect';
|
|
11
|
+
|
|
12
|
+
export const SelectCore = {
|
|
13
|
+
props,
|
|
14
|
+
useSelect,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export type { SelectProps } from './props';
|
|
18
|
+
export type { SelectOptionItem } from './useSelect';
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description select api type
|
|
3
|
+
* @author 阿怪
|
|
4
|
+
* @date 2022/4/16 21:10
|
|
5
|
+
* @version v1.0.2
|
|
6
|
+
*
|
|
7
|
+
* @name m-select
|
|
8
|
+
* @docDescription Select component with shuimo-ui style.
|
|
9
|
+
* 水墨组件的选择组件。
|
|
10
|
+
* @docUrl https://shuimo.design/select
|
|
11
|
+
*
|
|
12
|
+
* 江湖的业务千篇一律,复杂的代码好几百行。
|
|
13
|
+
*
|
|
14
|
+
* v1.0.1 新增多选和filter配置 Jimmy
|
|
15
|
+
* v1.0.2 新增 filterable prop,支持内置搜索过滤 阿怪
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { KineSize } from '../../types/props';
|
|
19
|
+
|
|
20
|
+
export declare type SelectProps = {
|
|
21
|
+
/**
|
|
22
|
+
* @description select value
|
|
23
|
+
* 选择框的值
|
|
24
|
+
* @type any | any[]
|
|
25
|
+
* @default ''
|
|
26
|
+
*/
|
|
27
|
+
modelValue?: any | any[],
|
|
28
|
+
/**
|
|
29
|
+
* @description select options
|
|
30
|
+
* 选择框的数组
|
|
31
|
+
* @type any[]
|
|
32
|
+
* @default []
|
|
33
|
+
*/
|
|
34
|
+
options?: Array<any>,
|
|
35
|
+
/**
|
|
36
|
+
* @description support for which key value to display in 'input'
|
|
37
|
+
* 选择后使用option中的哪个key的值去更新modelValue
|
|
38
|
+
* @type string
|
|
39
|
+
* @default undefined
|
|
40
|
+
*/
|
|
41
|
+
inputParam?: string,
|
|
42
|
+
/**
|
|
43
|
+
* @description select dropdown display info key
|
|
44
|
+
* 选择下拉框中显示内容的key
|
|
45
|
+
* @type string
|
|
46
|
+
* @default undefined
|
|
47
|
+
*/
|
|
48
|
+
optionParam?: string,
|
|
49
|
+
/**
|
|
50
|
+
* @description modelValue's key
|
|
51
|
+
* 参数的key
|
|
52
|
+
* @type string
|
|
53
|
+
* @default undefined
|
|
54
|
+
*/
|
|
55
|
+
valueParam?: string,
|
|
56
|
+
/**
|
|
57
|
+
* @description used to disable input event
|
|
58
|
+
* 用于禁止输入事件
|
|
59
|
+
* @type boolean
|
|
60
|
+
* @default true
|
|
61
|
+
*/
|
|
62
|
+
readonly?: boolean,
|
|
63
|
+
/**
|
|
64
|
+
* @description used to disable select
|
|
65
|
+
* 是否禁用
|
|
66
|
+
* @type boolean
|
|
67
|
+
* @default false
|
|
68
|
+
*/
|
|
69
|
+
disabled?: boolean,
|
|
70
|
+
/**
|
|
71
|
+
* @description input placeholder. 提示语
|
|
72
|
+
* @type string
|
|
73
|
+
* @default '请选择...'
|
|
74
|
+
*/
|
|
75
|
+
placeholder?: string,
|
|
76
|
+
/**
|
|
77
|
+
* @description modelValue match function
|
|
78
|
+
* 用于比较参数和modelValue是否相等的方法,常用于modelValue为对象的场景
|
|
79
|
+
* option: 列表数据
|
|
80
|
+
* value: modelValue
|
|
81
|
+
* @type function
|
|
82
|
+
* @default undefined
|
|
83
|
+
*/
|
|
84
|
+
toMatch?: (option: any, value: any) => boolean,
|
|
85
|
+
/**
|
|
86
|
+
* @description multiple choice
|
|
87
|
+
* 是否为多选
|
|
88
|
+
* @type boolean
|
|
89
|
+
* @default false
|
|
90
|
+
*/
|
|
91
|
+
multiple?: boolean,
|
|
92
|
+
/**
|
|
93
|
+
* @description in multiple, whether to show checkbox
|
|
94
|
+
* 多选模式下是否启用checkbox
|
|
95
|
+
* @type boolean
|
|
96
|
+
* @default true
|
|
97
|
+
*/
|
|
98
|
+
checkbox?: boolean,
|
|
99
|
+
/**
|
|
100
|
+
* @description whether to enable built-in search filtering
|
|
101
|
+
* 是否开启内置搜索过滤,开启后输入框变为可编辑状态
|
|
102
|
+
* @type boolean
|
|
103
|
+
* @default false
|
|
104
|
+
*/
|
|
105
|
+
filterable?: boolean,
|
|
106
|
+
/**
|
|
107
|
+
* @description defined input box filter query method
|
|
108
|
+
* 自定义输入框filter查询方法,filterable 为 true 时生效;未传则使用默认标签匹配
|
|
109
|
+
* @type function (options:any, inputValue: string) =>boolean
|
|
110
|
+
* @default undefined
|
|
111
|
+
*/
|
|
112
|
+
filter?: (options: any, inputValue: string) => boolean,
|
|
113
|
+
/**
|
|
114
|
+
* @description The height of the options dom
|
|
115
|
+
* 下拉框的高度
|
|
116
|
+
* @type number | string
|
|
117
|
+
* @default undefined
|
|
118
|
+
*/
|
|
119
|
+
optionsH?: number | string,
|
|
120
|
+
/**
|
|
121
|
+
* @description Whether to fetch
|
|
122
|
+
* 是否fetch
|
|
123
|
+
* @type boolean
|
|
124
|
+
* @default false
|
|
125
|
+
*/
|
|
126
|
+
needFetch?: boolean,
|
|
127
|
+
/**
|
|
128
|
+
* @description beta version autoComplete fetch func, should return an end flag
|
|
129
|
+
* beta版本的自动补全,需要返回一个是否停止标志
|
|
130
|
+
* @type Function
|
|
131
|
+
* @default undefined
|
|
132
|
+
*/
|
|
133
|
+
fetch?: () => Promise<void>,
|
|
134
|
+
/**
|
|
135
|
+
* @description whether to show clear button. 是否可清空
|
|
136
|
+
* @type boolean
|
|
137
|
+
* @default false
|
|
138
|
+
*/
|
|
139
|
+
clearable?: boolean,
|
|
140
|
+
/**
|
|
141
|
+
* @description select size. 选择框尺寸
|
|
142
|
+
* @type KineSize
|
|
143
|
+
* @default undefined
|
|
144
|
+
*/
|
|
145
|
+
size?: KineSize,
|
|
146
|
+
/**
|
|
147
|
+
* @description whether to show loading indicator. 是否显示加载中状态
|
|
148
|
+
* @type boolean
|
|
149
|
+
* @default false
|
|
150
|
+
*/
|
|
151
|
+
loading?: boolean,
|
|
152
|
+
};
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description select 核心 composable
|
|
3
|
+
* @author 阿怪
|
|
4
|
+
* @date 2026/2/25 14:40
|
|
5
|
+
* @version v1.0.1
|
|
6
|
+
*
|
|
7
|
+
* 江湖的业务千篇一律,复杂的代码好几百行。
|
|
8
|
+
*
|
|
9
|
+
* 用 computed + ref 替代原 class 继承方案
|
|
10
|
+
* 单选/多选通过 props.multiple 分支处理
|
|
11
|
+
* fetch 通过 IntersectionObserver 观察最后一个选项实现
|
|
12
|
+
* v1.0.1 新增 filterable 支持:开启后 inputReadonly 为 false,可输入过滤 阿怪 2026/2/27
|
|
13
|
+
*/
|
|
14
|
+
import { computed, ref, watch, toRef, onBeforeUnmount } from 'vue';
|
|
15
|
+
import { SelectProps } from './props';
|
|
16
|
+
import { useSelectTools } from './useSelectTools';
|
|
17
|
+
import { type HookContext } from '../../types/hook';
|
|
18
|
+
|
|
19
|
+
export interface SelectOptionItem {
|
|
20
|
+
/** 原始值 */
|
|
21
|
+
value: any;
|
|
22
|
+
/** 在 options 数组中的索引 */
|
|
23
|
+
index: number;
|
|
24
|
+
/** 是否选中 */
|
|
25
|
+
isSelected: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function useSelect(props: SelectProps, ctx: HookContext) {
|
|
29
|
+
const tools = useSelectTools(props);
|
|
30
|
+
const optionsRef = toRef(() => props.options ?? []);
|
|
31
|
+
const modelValueRef = toRef(() => props.modelValue);
|
|
32
|
+
const multipleRef = toRef(() => props.multiple ?? false);
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* 输入框是否只读:
|
|
36
|
+
* - filterable=true 时强制可编辑(忽略 readonly prop)
|
|
37
|
+
* - 否则沿用 props.readonly(默认 true)
|
|
38
|
+
*/
|
|
39
|
+
const inputReadonly = toRef(() => props.filterable ? false : (props.readonly ?? true));
|
|
40
|
+
|
|
41
|
+
// --- 状态 ---
|
|
42
|
+
const inputValue = ref('');
|
|
43
|
+
const isOpen = ref(false);
|
|
44
|
+
const fetchLoading = ref(false);
|
|
45
|
+
|
|
46
|
+
// --- 选中状态 ---
|
|
47
|
+
/** 多选时记录选中的索引集合 */
|
|
48
|
+
const selectedIndices = ref<Set<number>>(new Set());
|
|
49
|
+
|
|
50
|
+
/** 判断某个 option 是否选中 */
|
|
51
|
+
const isSelected = (option: any, index: number): boolean => {
|
|
52
|
+
if (multipleRef.value) {
|
|
53
|
+
return selectedIndices.value.has(index);
|
|
54
|
+
}
|
|
55
|
+
if (props.toMatch) {
|
|
56
|
+
return props.toMatch(option, modelValueRef.value);
|
|
57
|
+
}
|
|
58
|
+
return modelValueRef.value === tools.getModelValue(option);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// --- 选项列表 ---
|
|
62
|
+
/** 全量选项(带 isSelected 标记) */
|
|
63
|
+
const allOptions = computed<SelectOptionItem[]>(() => {
|
|
64
|
+
return optionsRef.value.map((o, i) => ({
|
|
65
|
+
value: o,
|
|
66
|
+
index: i,
|
|
67
|
+
isSelected: isSelected(o, i),
|
|
68
|
+
}));
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
/** 过滤后的显示选项 */
|
|
72
|
+
const displayOptions = computed<SelectOptionItem[]>(() => {
|
|
73
|
+
return allOptions.value.filter(o => {
|
|
74
|
+
// 只读模式(非 filterable 且 readonly)直接不过滤
|
|
75
|
+
if (inputReadonly.value) return true;
|
|
76
|
+
// 没有输入值时不过滤
|
|
77
|
+
if (!inputValue.value) return true;
|
|
78
|
+
// 优先使用自定义过滤函数(filterable 或 readonly=false 场景均生效)
|
|
79
|
+
if (props.filter) {
|
|
80
|
+
return props.filter(o.value, inputValue.value);
|
|
81
|
+
}
|
|
82
|
+
// 默认:输入值包含在 optionParam 显示值中(大小写不敏感)
|
|
83
|
+
return tools.getOptionValue(o.value).toLowerCase().includes(inputValue.value.toLowerCase());
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
/** 多选已选标签 */
|
|
88
|
+
const selectedTags = computed<SelectOptionItem[]>(() => {
|
|
89
|
+
if (!multipleRef.value) return [];
|
|
90
|
+
return allOptions.value.filter(o => o.isSelected);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// --- 初始化 inputValue ---
|
|
94
|
+
const syncInputFromModelValue = () => {
|
|
95
|
+
if (multipleRef.value) {
|
|
96
|
+
inputValue.value = '';
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const mv = modelValueRef.value;
|
|
100
|
+
if (mv == null || mv === '') {
|
|
101
|
+
inputValue.value = '';
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const found = optionsRef.value.find(o => {
|
|
105
|
+
if (props.toMatch) return props.toMatch(o, mv);
|
|
106
|
+
return tools.getModelValue(o) === mv;
|
|
107
|
+
});
|
|
108
|
+
inputValue.value = found ? tools.getInputValue(found) : '';
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
/** 初始化多选选中状态 */
|
|
112
|
+
const syncSelectedFromModelValue = () => {
|
|
113
|
+
if (!multipleRef.value) return;
|
|
114
|
+
const mv = modelValueRef.value;
|
|
115
|
+
const newSet = new Set<number>();
|
|
116
|
+
if (Array.isArray(mv)) {
|
|
117
|
+
optionsRef.value.forEach((o, i) => {
|
|
118
|
+
const val = tools.getModelValue(o);
|
|
119
|
+
if (mv.includes(val)) {
|
|
120
|
+
newSet.add(i);
|
|
121
|
+
}
|
|
122
|
+
if (props.toMatch && mv.some((v: any) => props.toMatch!(o, v))) {
|
|
123
|
+
newSet.add(i);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
selectedIndices.value = newSet;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// 初始同步
|
|
131
|
+
syncSelectedFromModelValue();
|
|
132
|
+
syncInputFromModelValue();
|
|
133
|
+
|
|
134
|
+
// --- 事件处理 ---
|
|
135
|
+
|
|
136
|
+
/** 点击选项 */
|
|
137
|
+
const onSelect = (index: number) => {
|
|
138
|
+
const option = optionsRef.value[index];
|
|
139
|
+
if (!option) return;
|
|
140
|
+
if (option.disabled) return;
|
|
141
|
+
|
|
142
|
+
if (multipleRef.value) {
|
|
143
|
+
// 多选:切换选中
|
|
144
|
+
const newSet = new Set(selectedIndices.value);
|
|
145
|
+
if (newSet.has(index)) {
|
|
146
|
+
newSet.delete(index);
|
|
147
|
+
} else {
|
|
148
|
+
newSet.add(index);
|
|
149
|
+
}
|
|
150
|
+
selectedIndices.value = newSet;
|
|
151
|
+
inputValue.value = '';
|
|
152
|
+
|
|
153
|
+
const newModelValue = optionsRef.value
|
|
154
|
+
.filter((_, i) => newSet.has(i))
|
|
155
|
+
.map(o => tools.getModelValue(o));
|
|
156
|
+
ctx.emit('update:modelValue', newModelValue);
|
|
157
|
+
ctx.emit('select', option);
|
|
158
|
+
} else {
|
|
159
|
+
// 单选:选中并关闭
|
|
160
|
+
inputValue.value = tools.getInputValue(option);
|
|
161
|
+
ctx.emit('update:modelValue', tools.getModelValue(option));
|
|
162
|
+
ctx.emit('select', option);
|
|
163
|
+
isOpen.value = false;
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
/** 删除多选标签 */
|
|
168
|
+
const onDeleteTag = (index: number) => {
|
|
169
|
+
const newSet = new Set(selectedIndices.value);
|
|
170
|
+
newSet.delete(index);
|
|
171
|
+
selectedIndices.value = newSet;
|
|
172
|
+
|
|
173
|
+
const newModelValue = optionsRef.value
|
|
174
|
+
.filter((_, i) => newSet.has(i))
|
|
175
|
+
.map(o => tools.getModelValue(o));
|
|
176
|
+
ctx.emit('update:modelValue', newModelValue);
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
/** 输入事件 */
|
|
180
|
+
const onInput = () => {
|
|
181
|
+
ctx.emit('input', inputValue.value);
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
/** 聚焦 */
|
|
185
|
+
const onFocus = (e: FocusEvent) => {
|
|
186
|
+
if (inputReadonly.value) return;
|
|
187
|
+
ctx.emit('focus', e, inputValue.value);
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
/** 失焦 */
|
|
191
|
+
const onBlur = (e: FocusEvent) => {
|
|
192
|
+
if (inputReadonly.value) return;
|
|
193
|
+
ctx.emit('blur', e, inputValue.value);
|
|
194
|
+
|
|
195
|
+
// 单选失焦时,如果输入值不匹配任何选项,清空
|
|
196
|
+
if (!multipleRef.value) {
|
|
197
|
+
const matched = displayOptions.value.find(o => o.isSelected);
|
|
198
|
+
if (matched && inputValue.value === tools.getInputValue(matched.value)) return;
|
|
199
|
+
if (!inputValue.value) {
|
|
200
|
+
ctx.emit('update:modelValue', undefined);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
// --- Fetch(IntersectionObserver 观察最后一个选项) ---
|
|
206
|
+
const lastOptionRef = ref<HTMLElement | null>(null);
|
|
207
|
+
const optionsContainerRef = ref<HTMLElement | null>(null);
|
|
208
|
+
let fetchObserver: IntersectionObserver | undefined;
|
|
209
|
+
|
|
210
|
+
const cleanupFetchObserver = () => {
|
|
211
|
+
if (fetchObserver) {
|
|
212
|
+
fetchObserver.disconnect();
|
|
213
|
+
fetchObserver = undefined;
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
/** 更新 fetch observer:观察最后一个选项元素 */
|
|
218
|
+
const updateFetchObserver = () => {
|
|
219
|
+
cleanupFetchObserver();
|
|
220
|
+
if (!props.needFetch || !lastOptionRef.value || !optionsContainerRef.value) return;
|
|
221
|
+
|
|
222
|
+
fetchObserver = new IntersectionObserver(
|
|
223
|
+
async (entries) => {
|
|
224
|
+
const entry = entries[0];
|
|
225
|
+
if (entry?.isIntersecting && props.needFetch) {
|
|
226
|
+
fetchLoading.value = true;
|
|
227
|
+
await props.fetch?.();
|
|
228
|
+
fetchLoading.value = false;
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
{ root: optionsContainerRef.value, threshold: 1 },
|
|
232
|
+
);
|
|
233
|
+
fetchObserver.observe(lastOptionRef.value);
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
// --- Watch ---
|
|
237
|
+
|
|
238
|
+
// modelValue 变化时同步输入框和选中状态
|
|
239
|
+
watch(modelValueRef, () => {
|
|
240
|
+
syncSelectedFromModelValue();
|
|
241
|
+
syncInputFromModelValue();
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
// options 变化时重新同步
|
|
245
|
+
watch(optionsRef, () => {
|
|
246
|
+
syncSelectedFromModelValue();
|
|
247
|
+
syncInputFromModelValue();
|
|
248
|
+
}, { deep: true });
|
|
249
|
+
|
|
250
|
+
// lastOptionRef 变化时更新 fetch observer
|
|
251
|
+
watch(lastOptionRef, () => {
|
|
252
|
+
updateFetchObserver();
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
onBeforeUnmount(cleanupFetchObserver);
|
|
256
|
+
|
|
257
|
+
return {
|
|
258
|
+
// 状态
|
|
259
|
+
inputValue,
|
|
260
|
+
isOpen,
|
|
261
|
+
fetchLoading,
|
|
262
|
+
// 输入框是否只读(filterable=true 时为 false)
|
|
263
|
+
inputReadonly,
|
|
264
|
+
// 列表
|
|
265
|
+
displayOptions,
|
|
266
|
+
selectedTags,
|
|
267
|
+
// DOM refs(fetch 用)
|
|
268
|
+
lastOptionRef,
|
|
269
|
+
optionsContainerRef,
|
|
270
|
+
// 事件
|
|
271
|
+
onSelect,
|
|
272
|
+
onDeleteTag,
|
|
273
|
+
onInput,
|
|
274
|
+
onFocus,
|
|
275
|
+
onBlur,
|
|
276
|
+
// 工具
|
|
277
|
+
tools,
|
|
278
|
+
// fetch
|
|
279
|
+
updateFetchObserver,
|
|
280
|
+
};
|
|
281
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description select 参数映射工具
|
|
3
|
+
* @author 阿怪
|
|
4
|
+
* @date 2026/2/25 14:40
|
|
5
|
+
* @version v1.0.0
|
|
6
|
+
*
|
|
7
|
+
* 江湖的业务千篇一律,复杂的代码好几百行。
|
|
8
|
+
*
|
|
9
|
+
* 处理 options 中对象数据的 key 映射
|
|
10
|
+
* inputParam: 选中后输入框显示哪个字段
|
|
11
|
+
* optionParam: 下拉列表中显示哪个字段
|
|
12
|
+
* valueParam: modelValue 绑定哪个字段
|
|
13
|
+
*/
|
|
14
|
+
import { SelectProps } from './props';
|
|
15
|
+
|
|
16
|
+
export type SelectParamKeys = 'optionParam' | 'valueParam' | 'inputParam';
|
|
17
|
+
|
|
18
|
+
export function useSelectTools(props: SelectProps) {
|
|
19
|
+
|
|
20
|
+
/** 从 option 中取指定 key 的值 */
|
|
21
|
+
const getInfoWithKey = (option: any, key: SelectParamKeys): any => {
|
|
22
|
+
const paramKey = props[key];
|
|
23
|
+
if (!paramKey) {
|
|
24
|
+
if (option && typeof option === 'object') {
|
|
25
|
+
if ('label' in option) return option.label;
|
|
26
|
+
if ('name' in option) return option.name;
|
|
27
|
+
if ('text' in option) return option.text;
|
|
28
|
+
}
|
|
29
|
+
return option;
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
return option[paramKey];
|
|
33
|
+
} catch {
|
|
34
|
+
return option;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/** 输入框显示值 */
|
|
39
|
+
const getInputValue = (option: any): string => {
|
|
40
|
+
return String(getInfoWithKey(option, 'inputParam') ?? '');
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/** 下拉列表显示值 */
|
|
44
|
+
const getOptionValue = (option: any): string => {
|
|
45
|
+
return String(getInfoWithKey(option, 'optionParam') ?? '');
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/** modelValue 绑定值 */
|
|
49
|
+
const getModelValue = (option: any): any => {
|
|
50
|
+
if (props.valueParam) {
|
|
51
|
+
return getInfoWithKey(option, 'valueParam');
|
|
52
|
+
}
|
|
53
|
+
if (option && typeof option === 'object' && 'value' in option) {
|
|
54
|
+
return option.value;
|
|
55
|
+
}
|
|
56
|
+
return option;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
return { getInfoWithKey, getInputValue, getOptionValue, getModelValue };
|
|
60
|
+
}
|