style: vc-select2 to ts
							parent
							
								
									47e5df9103
								
							
						
					
					
						commit
						4b4fc9266c
					
				|  | @ -31,7 +31,8 @@ | |||
|         "@typescript-eslint/no-explicit-any": 0, | ||||
|         "@typescript-eslint/ban-types": 0, | ||||
|         "@typescript-eslint/explicit-module-boundary-types": 0, | ||||
|         "@typescript-eslint/no-empty-function": 0 | ||||
|         "@typescript-eslint/no-empty-function": 0, | ||||
|         "@typescript-eslint/no-non-null-assertion": 0 | ||||
|       } | ||||
|     } | ||||
|   ], | ||||
|  |  | |||
|  | @ -1,8 +0,0 @@ | |||
| function createRef() { | ||||
|   const func = function setRef(node) { | ||||
|     func.current = node; | ||||
|   }; | ||||
|   return func; | ||||
| } | ||||
| 
 | ||||
| export default createRef; | ||||
|  | @ -0,0 +1,12 @@ | |||
| interface RefObject extends Function { | ||||
|   current?: any; | ||||
| } | ||||
| 
 | ||||
| function createRef(): RefObject { | ||||
|   const func: RefObject = (node: any) => { | ||||
|     func.current = node; | ||||
|   }; | ||||
|   return func; | ||||
| } | ||||
| 
 | ||||
| export default createRef; | ||||
|  | @ -1,6 +1,10 @@ | |||
| export const responsiveArray = ['xxl', 'xl', 'lg', 'md', 'sm', 'xs']; | ||||
| export type Breakpoint = 'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs'; | ||||
| export type BreakpointMap = Partial<Record<Breakpoint, string>>; | ||||
| export type ScreenMap = Partial<Record<Breakpoint, boolean>>; | ||||
| 
 | ||||
| export const responsiveMap = { | ||||
| export const responsiveArray: Breakpoint[] = ['xxl', 'xl', 'lg', 'md', 'sm', 'xs']; | ||||
| 
 | ||||
| export const responsiveMap: BreakpointMap = { | ||||
|   xs: '(max-width: 575px)', | ||||
|   sm: '(min-width: 576px)', | ||||
|   md: '(min-width: 768px)', | ||||
|  | @ -9,40 +13,46 @@ export const responsiveMap = { | |||
|   xxl: '(min-width: 1600px)', | ||||
| }; | ||||
| 
 | ||||
| const subscribers = new Map(); | ||||
| type SubscribeFunc = (screens: ScreenMap) => void; | ||||
| const subscribers = new Map<Number, SubscribeFunc>(); | ||||
| let subUid = -1; | ||||
| let screens = {}; | ||||
| 
 | ||||
| const responsiveObserve = { | ||||
|   matchHandlers: {}, | ||||
|   dispatch(pointMap) { | ||||
|   matchHandlers: {} as { | ||||
|     [prop: string]: { | ||||
|       mql: MediaQueryList; | ||||
|       listener: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | null; | ||||
|     }; | ||||
|   }, | ||||
|   dispatch(pointMap: ScreenMap) { | ||||
|     screens = pointMap; | ||||
|     subscribers.forEach(func => func(screens)); | ||||
|     return subscribers.size >= 1; | ||||
|   }, | ||||
|   subscribe(func) { | ||||
|   subscribe(func: SubscribeFunc): number { | ||||
|     if (!subscribers.size) this.register(); | ||||
|     subUid += 1; | ||||
|     subscribers.set(subUid, func); | ||||
|     func(screens); | ||||
|     return subUid; | ||||
|   }, | ||||
|   unsubscribe(token) { | ||||
|   unsubscribe(token: number) { | ||||
|     subscribers.delete(token); | ||||
|     if (!subscribers.size) this.unregister(); | ||||
|   }, | ||||
|   unregister() { | ||||
|     Object.keys(responsiveMap).forEach(screen => { | ||||
|       const matchMediaQuery = responsiveMap[screen]; | ||||
|     Object.keys(responsiveMap).forEach((screen: Breakpoint) => { | ||||
|       const matchMediaQuery = responsiveMap[screen]!; | ||||
|       const handler = this.matchHandlers[matchMediaQuery]; | ||||
|       handler?.mql.removeListener(handler?.listener); | ||||
|     }); | ||||
|     subscribers.clear(); | ||||
|   }, | ||||
|   register() { | ||||
|     Object.keys(responsiveMap).forEach(screen => { | ||||
|       const matchMediaQuery = responsiveMap[screen]; | ||||
|       const listener = ({ matches }) => { | ||||
|     Object.keys(responsiveMap).forEach((screen: Breakpoint) => { | ||||
|       const matchMediaQuery = responsiveMap[screen]!; | ||||
|       const listener = ({ matches }: { matches: boolean }) => { | ||||
|         this.dispatch({ | ||||
|           ...screens, | ||||
|           [screen]: matches, | ||||
|  | @ -1,10 +1,11 @@ | |||
| // based on rc-resize-observer 0.1.3 | ||||
| import ResizeObserver from 'resize-observer-polyfill'; | ||||
| import { defineComponent } from 'vue'; | ||||
| import BaseMixin from '../_util/BaseMixin'; | ||||
| import { findDOMNode } from '../_util/props-util'; | ||||
| 
 | ||||
| // Still need to be compatible with React 15, we use class component here | ||||
| const VueResizeObserver = { | ||||
| const VueResizeObserver = defineComponent({ | ||||
|   name: 'ResizeObserver', | ||||
|   mixins: [BaseMixin], | ||||
|   props: { | ||||
|  | @ -84,6 +85,6 @@ const VueResizeObserver = { | |||
|   render() { | ||||
|     return this.$slots.default && this.$slots.default()[0]; | ||||
|   }, | ||||
| }; | ||||
| }); | ||||
| 
 | ||||
| export default VueResizeObserver; | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ import classNames from '../_util/classNames'; | |||
| import pickAttrs from '../_util/pickAttrs'; | ||||
| import { isValidElement } from '../_util/props-util'; | ||||
| import createRef from '../_util/createRef'; | ||||
| import { computed, reactive, watch } from 'vue'; | ||||
| import { computed, defineComponent, reactive, watch } from 'vue'; | ||||
| import List from '../vc-virtual-list/List'; | ||||
| 
 | ||||
| const OptionListProps = { | ||||
|  | @ -39,7 +39,7 @@ const OptionListProps = { | |||
|  * Using virtual list of option display. | ||||
|  * Will fallback to dom if use customize render. | ||||
|  */ | ||||
| const OptionList = { | ||||
| const OptionList = defineComponent({ | ||||
|   props: OptionListProps, | ||||
|   name: 'OptionList', | ||||
|   inheritAttrs: false, | ||||
|  | @ -138,7 +138,7 @@ const OptionList = { | |||
|       const mergedLabel = props.childrenAsData ? children : label; | ||||
|       return item ? ( | ||||
|         <div | ||||
|           aria-label={typeof mergedLabel === 'string' ? mergedLabel : null} | ||||
|           aria-label={typeof mergedLabel === 'string' ? mergedLabel : undefined} | ||||
|           {...attrs} | ||||
|           key={index} | ||||
|           role="option" | ||||
|  | @ -343,6 +343,6 @@ const OptionList = { | |||
|       </> | ||||
|     ); | ||||
|   }, | ||||
| }; | ||||
| }); | ||||
| 
 | ||||
| export default OptionList; | ||||
|  | @ -3,8 +3,10 @@ import PropTypes from '../_util/vue-types'; | |||
| import { getSlot } from '../_util/props-util'; | ||||
| import classNames from '../_util/classNames'; | ||||
| import createRef from '../_util/createRef'; | ||||
| import { CSSProperties, defineComponent, VNodeChild } from 'vue'; | ||||
| import { RenderDOMFunc } from './interface'; | ||||
| 
 | ||||
| const getBuiltInPlacements = dropdownMatchSelectWidth => { | ||||
| const getBuiltInPlacements = (dropdownMatchSelectWidth: number | boolean) => { | ||||
|   // Enable horizontal overflow auto-adjustment when a custom dropdown width is provided
 | ||||
|   const adjustX = typeof dropdownMatchSelectWidth !== 'number' ? 0 : 1; | ||||
| 
 | ||||
|  | @ -43,33 +45,27 @@ const getBuiltInPlacements = dropdownMatchSelectWidth => { | |||
|     }, | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| export default { | ||||
| export interface SelectTriggerProps { | ||||
|   prefixCls: string; | ||||
|   disabled: boolean; | ||||
|   visible: boolean; | ||||
|   popupElement: VNodeChild; | ||||
|   animation?: string; | ||||
|   transitionName?: string; | ||||
|   containerWidth: number; | ||||
|   dropdownStyle: CSSProperties; | ||||
|   dropdownClassName: string; | ||||
|   direction: string; | ||||
|   dropdownMatchSelectWidth?: boolean | number; | ||||
|   dropdownRender?: (menu: VNodeChild) => VNodeChild; | ||||
|   getPopupContainer?: RenderDOMFunc; | ||||
|   dropdownAlign: object; | ||||
|   empty: boolean; | ||||
|   getTriggerDOMNode: () => HTMLElement; | ||||
| } | ||||
| const SelectTrigger = defineComponent<SelectTriggerProps>({ | ||||
|   name: 'SelectTrigger', | ||||
|   inheritAttrs: false, | ||||
|   props: { | ||||
|     // onPopupFocus: PropTypes.func,
 | ||||
|     // onPopupScroll: PropTypes.func,
 | ||||
|     dropdownAlign: PropTypes.object, | ||||
|     visible: PropTypes.bool, | ||||
|     disabled: PropTypes.bool, | ||||
|     dropdownClassName: PropTypes.string, | ||||
|     dropdownStyle: PropTypes.object, | ||||
|     empty: PropTypes.bool, | ||||
|     prefixCls: PropTypes.string, | ||||
|     popupClassName: PropTypes.string, | ||||
|     // children: PropTypes.any,
 | ||||
|     animation: PropTypes.string, | ||||
|     transitionName: PropTypes.string, | ||||
|     getPopupContainer: PropTypes.func, | ||||
|     dropdownRender: PropTypes.func, | ||||
|     containerWidth: PropTypes.number, | ||||
|     dropdownMatchSelectWidth: PropTypes.oneOfType([Number, Boolean]).def(true), | ||||
|     popupElement: PropTypes.any, | ||||
|     direction: PropTypes.string, | ||||
|     getTriggerDOMNode: PropTypes.func, | ||||
|   }, | ||||
| 
 | ||||
|   created() { | ||||
|     this.popupRef = createRef(); | ||||
|   }, | ||||
|  | @ -89,7 +85,7 @@ export default { | |||
|   }, | ||||
| 
 | ||||
|   render() { | ||||
|     const { empty, ...props } = { ...this.$props, ...this.$attrs }; | ||||
|     const { empty = false, ...props } = { ...this.$props, ...this.$attrs }; | ||||
|     const { | ||||
|       visible, | ||||
|       dropdownAlign, | ||||
|  | @ -122,7 +118,6 @@ export default { | |||
|         showAction={[]} | ||||
|         hideAction={[]} | ||||
|         popupPlacement={this.direction === 'rtl' ? 'bottomRight' : 'bottomLeft'} | ||||
|         popupPlacement="bottomLeft" | ||||
|         builtinPlacements={builtInPlacements} | ||||
|         prefixCls={dropdownPrefixCls} | ||||
|         popupTransitionName={this.getDropdownTransitionName()} | ||||
|  | @ -141,4 +136,24 @@ export default { | |||
|       </Trigger> | ||||
|     ); | ||||
|   }, | ||||
| }); | ||||
| SelectTrigger.props = { | ||||
|   dropdownAlign: PropTypes.object, | ||||
|   visible: PropTypes.bool, | ||||
|   disabled: PropTypes.bool, | ||||
|   dropdownClassName: PropTypes.string, | ||||
|   dropdownStyle: PropTypes.object, | ||||
|   empty: PropTypes.bool, | ||||
|   prefixCls: PropTypes.string, | ||||
|   popupClassName: PropTypes.string, | ||||
|   animation: PropTypes.string, | ||||
|   transitionName: PropTypes.string, | ||||
|   getPopupContainer: PropTypes.func, | ||||
|   dropdownRender: PropTypes.func, | ||||
|   containerWidth: PropTypes.number, | ||||
|   dropdownMatchSelectWidth: PropTypes.oneOfType([Number, Boolean]).def(true), | ||||
|   popupElement: PropTypes.any, | ||||
|   direction: PropTypes.string, | ||||
|   getTriggerDOMNode: PropTypes.func, | ||||
| }; | ||||
| export default SelectTrigger; | ||||
|  | @ -1,41 +0,0 @@ | |||
| const TransBtn = ( | ||||
|   _, | ||||
|   { attrs: { class: className, customizeIcon, customizeIconProps, onMousedown, onClick }, slots }, | ||||
| ) => { | ||||
|   let icon; | ||||
| 
 | ||||
|   if (typeof customizeIcon === 'function') { | ||||
|     icon = customizeIcon(customizeIconProps); | ||||
|   } else { | ||||
|     icon = customizeIcon; | ||||
|   } | ||||
| 
 | ||||
|   return ( | ||||
|     <span | ||||
|       class={className} | ||||
|       onMousedown={event => { | ||||
|         event.preventDefault(); | ||||
|         if (onMousedown) { | ||||
|           onMousedown(event); | ||||
|         } | ||||
|       }} | ||||
|       style={{ | ||||
|         userSelect: 'none', | ||||
|         WebkitUserSelect: 'none', | ||||
|       }} | ||||
|       unselectable="on" | ||||
|       onClick={onClick} | ||||
|       aria-hidden | ||||
|     > | ||||
|       {icon !== undefined ? ( | ||||
|         icon | ||||
|       ) : ( | ||||
|         <span class={className.split(/\s+/).map(cls => `${cls}-icon`)}>{slots?.default()}</span> | ||||
|       )} | ||||
|     </span> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| TransBtn.inheritAttrs = false; | ||||
| 
 | ||||
| export default TransBtn; | ||||
|  | @ -0,0 +1,59 @@ | |||
| import { SetupContext, VNodeChild } from 'vue'; | ||||
| import PropTypes from '../_util/vue-types'; | ||||
| 
 | ||||
| export interface TransBtnProps { | ||||
|   class: string; | ||||
|   customizeIcon: VNodeChild | ((props?: any) => VNodeChild); | ||||
|   customizeIconProps?: any; | ||||
|   onMousedown?: (payload: MouseEvent) => void; | ||||
|   onClick?: (payload: MouseEvent) => void; | ||||
| } | ||||
| 
 | ||||
| const TransBtn = (props: TransBtnProps, { slots }: SetupContext) => { | ||||
|   const { class: className, customizeIcon, customizeIconProps, onMousedown, onClick } = props; | ||||
|   let icon: VNodeChild; | ||||
| 
 | ||||
|   if (typeof customizeIcon === 'function') { | ||||
|     icon = customizeIcon(customizeIconProps); | ||||
|   } else { | ||||
|     icon = customizeIcon; | ||||
|   } | ||||
| 
 | ||||
|   return ( | ||||
|     <span | ||||
|       class={className} | ||||
|       onMousedown={event => { | ||||
|         event.preventDefault(); | ||||
|         if (onMousedown) { | ||||
|           onMousedown(event); | ||||
|         } | ||||
|       }} | ||||
|       style={{ | ||||
|         userSelect: 'none', | ||||
|         WebkitUserSelect: 'none', | ||||
|       }} | ||||
|       unselectable="on" | ||||
|       onClick={onClick} | ||||
|       aria-hidden | ||||
|     > | ||||
|       {icon !== undefined ? ( | ||||
|         icon | ||||
|       ) : ( | ||||
|         <span class={className.split(/\s+/).map((cls: any) => `${cls}-icon`)}> | ||||
|           {slots.default && slots.default()} | ||||
|         </span> | ||||
|       )} | ||||
|     </span> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| TransBtn.inheritAttrs = false; | ||||
| TransBtn.props = { | ||||
|   class: PropTypes.string, | ||||
|   customizeIcon: PropTypes.any, | ||||
|   customizeIconProps: PropTypes.any, | ||||
|   onMousedown: PropTypes.func, | ||||
|   onClick: PropTypes.func, | ||||
| }; | ||||
| 
 | ||||
| export default TransBtn; | ||||
|  | @ -0,0 +1,64 @@ | |||
| import * as Vue from 'vue'; | ||||
| import { SelectProps, RefSelectProps } from '../generate'; | ||||
| 
 | ||||
| export type SelectSource = 'option' | 'selection' | 'input'; | ||||
| 
 | ||||
| export const INTERNAL_PROPS_MARK = 'RC_SELECT_INTERNAL_PROPS_MARK'; | ||||
| 
 | ||||
| // =================================== Shared Type ===================================
 | ||||
| export type Key = string | number; | ||||
| 
 | ||||
| export type RawValueType = string | number; | ||||
| 
 | ||||
| export interface LabelValueType { | ||||
|   key?: Key; | ||||
|   value?: RawValueType; | ||||
|   label?: Vue.VNodeChild; | ||||
| } | ||||
| export type DefaultValueType = RawValueType | RawValueType[] | LabelValueType | LabelValueType[]; | ||||
| 
 | ||||
| export interface DisplayLabelValueType extends LabelValueType { | ||||
|   disabled?: boolean; | ||||
| } | ||||
| 
 | ||||
| export type SingleType<MixType> = MixType extends (infer Single)[] ? Single : MixType; | ||||
| 
 | ||||
| export type OnClear = () => void; | ||||
| 
 | ||||
| export type CustomTagProps = { | ||||
|   label: DefaultValueType; | ||||
|   value: DefaultValueType; | ||||
|   disabled: boolean; | ||||
|   onClose: (event?: MouseEvent) => void; | ||||
|   closable: boolean; | ||||
| }; | ||||
| 
 | ||||
| // ==================================== Generator ====================================
 | ||||
| export type GetLabeledValue<FOT extends FlattenOptionsType> = ( | ||||
|   value: RawValueType, | ||||
|   config: { | ||||
|     options: FOT; | ||||
|     prevValue: DefaultValueType; | ||||
|     labelInValue: boolean; | ||||
|     optionLabelProp: string; | ||||
|   }, | ||||
| ) => LabelValueType; | ||||
| 
 | ||||
| export type FilterOptions<OptionsType extends object[]> = ( | ||||
|   searchValue: string, | ||||
|   options: OptionsType, | ||||
|   /** Component props, since Select & TreeSelect use different prop name, use any here */ | ||||
|   config: { | ||||
|     optionFilterProp: string; | ||||
|     filterOption: boolean | FilterFunc<OptionsType[number]>; | ||||
|   }, | ||||
| ) => OptionsType; | ||||
| 
 | ||||
| export type FilterFunc<OptionType> = (inputValue: string, option?: OptionType) => boolean; | ||||
| 
 | ||||
| export type FlattenOptionsType<OptionsType extends object[] = object[]> = { | ||||
|   key: Key; | ||||
|   data: OptionsType[number]; | ||||
|   /** Used for customize data */ | ||||
|   [name: string]: any; // eslint-disable-line @typescript-eslint/no-explicit-any
 | ||||
| }[]; | ||||
|  | @ -0,0 +1,54 @@ | |||
| import * as Vue from 'vue'; | ||||
| import { Key, RawValueType } from './generator'; | ||||
| 
 | ||||
| export type RenderDOMFunc = (props: any) => HTMLElement; | ||||
| 
 | ||||
| export type RenderNode = Vue.VNodeChild | ((props: any) => Vue.VNodeChild); | ||||
| 
 | ||||
| export type Mode = 'multiple' | 'tags' | 'combobox'; | ||||
| 
 | ||||
| // ======================== Option ========================
 | ||||
| export type OnActiveValue = ( | ||||
|   active: RawValueType, | ||||
|   index: number, | ||||
|   info?: { source?: 'keyboard' | 'mouse' }, | ||||
| ) => void; | ||||
| 
 | ||||
| export interface OptionCoreData { | ||||
|   key?: Key; | ||||
|   disabled?: boolean; | ||||
|   value: Key; | ||||
|   title?: string; | ||||
|   className?: string; | ||||
|   class?: string; | ||||
|   style?: Vue.CSSProperties; | ||||
|   label?: Vue.VNodeChild; | ||||
|   /** @deprecated Only works when use `children` as option data */ | ||||
|   children?: Vue.VNodeChild; | ||||
| } | ||||
| 
 | ||||
| export interface OptionData extends OptionCoreData { | ||||
|   /** Save for customize data */ | ||||
|   [prop: string]: any; // eslint-disable-line @typescript-eslint/no-explicit-any
 | ||||
| } | ||||
| 
 | ||||
| export interface OptionGroupData { | ||||
|   key?: Key; | ||||
|   label?: Vue.VNodeChild; | ||||
|   options: OptionData[]; | ||||
|   className?: string; | ||||
|   class?: string; | ||||
|   style?: Vue.CSSProperties; | ||||
| 
 | ||||
|   /** Save for customize data */ | ||||
|   [prop: string]: any; // eslint-disable-line @typescript-eslint/no-explicit-any
 | ||||
| } | ||||
| 
 | ||||
| export type OptionsType = (OptionData | OptionGroupData)[]; | ||||
| 
 | ||||
| export interface FlattenOptionData { | ||||
|   group?: boolean; | ||||
|   groupOption?: boolean; | ||||
|   key: string | number; | ||||
|   data: OptionData | OptionGroupData; | ||||
| } | ||||
|  | @ -1,4 +1,4 @@ | |||
| import { inject, provide } from 'vue'; | ||||
| import { defineComponent, inject, provide } from 'vue'; | ||||
| import PropTypes from '../_util/vue-types'; | ||||
| import contains from '../vc-util/Dom/contains'; | ||||
| import { | ||||
|  | @ -37,7 +37,7 @@ const ALL_HANDLERS = [ | |||
|   'onContextmenu', | ||||
| ]; | ||||
| 
 | ||||
| export default { | ||||
| export default defineComponent({ | ||||
|   name: 'Trigger', | ||||
|   mixins: [BaseMixin], | ||||
|   inheritAttrs: false, | ||||
|  | @ -653,4 +653,4 @@ export default { | |||
|     } | ||||
|     return [portal, trigger]; | ||||
|   }, | ||||
| }; | ||||
| }); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 tangjinzhou
						tangjinzhou