chore: rever util to js

pull/2935/head
undefined 2020-10-02 15:44:10 +08:00
parent 609de24f19
commit b7db5b31ba
60 changed files with 492 additions and 543 deletions

View File

@ -2,7 +2,7 @@ import { getOptionProps } from './props-util';
export default {
methods: {
setState(state = {}, callback: () => void) {
setState(state = {}, callback) {
let newState = typeof state === 'function' ? state(this.$data, this.$props) : state;
if (this.getDerivedStateFromProps) {
const s = this.getDerivedStateFromProps(getOptionProps(this), {
@ -25,7 +25,6 @@ export default {
},
__emit() {
// 直接调用事件底层组件不需要vueTool记录events
// eslint-disable-next-line prefer-rest-params
const args = [].slice.call(arguments, 0);
let eventName = args[0];
eventName = `on${eventName[0].toUpperCase()}${eventName.substring(1)}`;

View File

@ -2,7 +2,7 @@ import { getOptionProps } from './props-util';
export default {
methods: {
setState(state = {}, callback: () => any) {
setState(state = {}, callback) {
let newState = typeof state === 'function' ? state(this, this.$props) : state;
if (this.getDerivedStateFromProps) {
const s = this.getDerivedStateFromProps(getOptionProps(this), {
@ -25,7 +25,6 @@ export default {
},
__emit() {
// 直接调用事件底层组件不需要vueTool记录events
// eslint-disable-next-line prefer-rest-params
const args = [].slice.call(arguments, 0);
let eventName = args[0];
eventName = `on${eventName[0].toUpperCase()}${eventName.substring(1)}`;

View File

@ -0,0 +1,98 @@
import PropTypes from './vue-types';
export default {
props: {
autoMount: PropTypes.bool.def(true),
autoDestroy: PropTypes.bool.def(true),
visible: PropTypes.bool,
forceRender: PropTypes.bool.def(false),
parent: PropTypes.any,
getComponent: PropTypes.func.isRequired,
getContainer: PropTypes.func.isRequired,
children: PropTypes.func.isRequired,
},
mounted() {
if (this.autoMount) {
this.renderComponent();
}
},
updated() {
if (this.autoMount) {
this.renderComponent();
}
},
beforeUnmount() {
if (this.autoDestroy) {
this.removeContainer();
}
},
methods: {
removeContainer() {
if (this.container) {
this._component && this._component.$destroy();
this.container.parentNode.removeChild(this.container);
this.container = null;
this._component = null;
}
},
renderComponent(props = {}, ready) {
const { visible, forceRender, getContainer, parent } = this;
const self = this;
if (visible || parent._component || parent.$refs._component || forceRender) {
let el = this.componentEl;
if (!this.container) {
this.container = getContainer();
el = document.createElement('div');
this.componentEl = el;
this.container.appendChild(el);
}
// self.getComponent render render
const com = { component: self.getComponent(props) };
if (!this._component) {
this._component = new this.$root.constructor({
el,
parent: self,
data: {
_com: com,
},
mounted() {
this.$nextTick(() => {
if (ready) {
ready.call(self);
}
});
},
updated() {
this.$nextTick(() => {
if (ready) {
ready.call(self);
}
});
},
methods: {
setComponent(_com) {
this.$data._com = _com;
},
},
render() {
return this.$data._com.component;
},
});
} else {
this._component.setComponent(com);
}
}
},
},
render() {
return this.children({
renderComponent: this.renderComponent,
removeContainer: this.removeContainer,
});
},
};

View File

@ -1,10 +0,0 @@
export function antDecorator(Vue) {
return Vue.directive('decorator', {});
}
export default {
// just for tag
install: Vue => {
antDecorator(Vue);
},
};

View File

@ -425,98 +425,97 @@ const KeyCode = {
* WIN_IME
*/
WIN_IME: 229,
};
// ======================== Function ========================
/**
* whether text and modified key is entered at the same time.
*/
isTextModifyingKeyEvent: function isTextModifyingKeyEvent(e: KeyboardEvent) {
const { keyCode } = e;
if (
(e.altKey && !e.ctrlKey) ||
e.metaKey ||
// Function keys don't generate text
(keyCode >= KeyCode.F1 && keyCode <= KeyCode.F12)
) {
/*
whether text and modified key is entered at the same time.
*/
KeyCode.isTextModifyingKeyEvent = function isTextModifyingKeyEvent(e) {
const keyCode = e.keyCode;
if (
(e.altKey && !e.ctrlKey) ||
e.metaKey ||
// Function keys don't generate text
(keyCode >= KeyCode.F1 && keyCode <= KeyCode.F12)
) {
return false;
}
// The following keys are quite harmless, even in combination with
// CTRL, ALT or SHIFT.
switch (keyCode) {
case KeyCode.ALT:
case KeyCode.CAPS_LOCK:
case KeyCode.CONTEXT_MENU:
case KeyCode.CTRL:
case KeyCode.DOWN:
case KeyCode.END:
case KeyCode.ESC:
case KeyCode.HOME:
case KeyCode.INSERT:
case KeyCode.LEFT:
case KeyCode.MAC_FF_META:
case KeyCode.META:
case KeyCode.NUMLOCK:
case KeyCode.NUM_CENTER:
case KeyCode.PAGE_DOWN:
case KeyCode.PAGE_UP:
case KeyCode.PAUSE:
case KeyCode.PRINT_SCREEN:
case KeyCode.RIGHT:
case KeyCode.SHIFT:
case KeyCode.UP:
case KeyCode.WIN_KEY:
case KeyCode.WIN_KEY_RIGHT:
return false;
}
// The following keys are quite harmless, even in combination with
// CTRL, ALT or SHIFT.
switch (keyCode) {
case KeyCode.ALT:
case KeyCode.CAPS_LOCK:
case KeyCode.CONTEXT_MENU:
case KeyCode.CTRL:
case KeyCode.DOWN:
case KeyCode.END:
case KeyCode.ESC:
case KeyCode.HOME:
case KeyCode.INSERT:
case KeyCode.LEFT:
case KeyCode.MAC_FF_META:
case KeyCode.META:
case KeyCode.NUMLOCK:
case KeyCode.NUM_CENTER:
case KeyCode.PAGE_DOWN:
case KeyCode.PAGE_UP:
case KeyCode.PAUSE:
case KeyCode.PRINT_SCREEN:
case KeyCode.RIGHT:
case KeyCode.SHIFT:
case KeyCode.UP:
case KeyCode.WIN_KEY:
case KeyCode.WIN_KEY_RIGHT:
return false;
default:
return true;
}
},
/**
* whether character is entered.
*/
isCharacterKey: function isCharacterKey(keyCode: number) {
if (keyCode >= KeyCode.ZERO && keyCode <= KeyCode.NINE) {
default:
return true;
}
}
};
if (keyCode >= KeyCode.NUM_ZERO && keyCode <= KeyCode.NUM_MULTIPLY) {
/*
whether character is entered.
*/
KeyCode.isCharacterKey = function isCharacterKey(keyCode) {
if (keyCode >= KeyCode.ZERO && keyCode <= KeyCode.NINE) {
return true;
}
if (keyCode >= KeyCode.NUM_ZERO && keyCode <= KeyCode.NUM_MULTIPLY) {
return true;
}
if (keyCode >= KeyCode.A && keyCode <= KeyCode.Z) {
return true;
}
// Safari sends zero key code for non-latin characters.
if (window.navigation.userAgent.indexOf('WebKit') !== -1 && keyCode === 0) {
return true;
}
switch (keyCode) {
case KeyCode.SPACE:
case KeyCode.QUESTION_MARK:
case KeyCode.NUM_PLUS:
case KeyCode.NUM_MINUS:
case KeyCode.NUM_PERIOD:
case KeyCode.NUM_DIVISION:
case KeyCode.SEMICOLON:
case KeyCode.DASH:
case KeyCode.EQUALS:
case KeyCode.COMMA:
case KeyCode.PERIOD:
case KeyCode.SLASH:
case KeyCode.APOSTROPHE:
case KeyCode.SINGLE_QUOTE:
case KeyCode.OPEN_SQUARE_BRACKET:
case KeyCode.BACKSLASH:
case KeyCode.CLOSE_SQUARE_BRACKET:
return true;
}
if (keyCode >= KeyCode.A && keyCode <= KeyCode.Z) {
return true;
}
// Safari sends zero key code for non-latin characters.
if (window.navigator.userAgent.indexOf('WebKit') !== -1 && keyCode === 0) {
return true;
}
switch (keyCode) {
case KeyCode.SPACE:
case KeyCode.QUESTION_MARK:
case KeyCode.NUM_PLUS:
case KeyCode.NUM_MINUS:
case KeyCode.NUM_PERIOD:
case KeyCode.NUM_DIVISION:
case KeyCode.SEMICOLON:
case KeyCode.DASH:
case KeyCode.EQUALS:
case KeyCode.COMMA:
case KeyCode.PERIOD:
case KeyCode.SLASH:
case KeyCode.APOSTROPHE:
case KeyCode.SINGLE_QUOTE:
case KeyCode.OPEN_SQUARE_BRACKET:
case KeyCode.BACKSLASH:
case KeyCode.CLOSE_SQUARE_BRACKET:
return true;
default:
return false;
}
},
default:
return false;
}
};
export default KeyCode;

View File

@ -1,18 +1,16 @@
import PropTypes from './vue-types';
import { Teleport, defineComponent, PropType } from 'vue';
import { Teleport } from 'vue';
export default defineComponent({
export default {
name: 'Portal',
props: {
getContainer: {
type: Function as PropType<(triggerNode: HTMLElement) => HTMLElement>,
required: true,
},
getContainer: PropTypes.func.isRequired,
children: PropTypes.any.isRequired,
didUpdate: PropTypes.func,
},
beforeCreate() {
data() {
this._container = null;
return {};
},
mounted() {
this.createContainer();
@ -47,4 +45,4 @@ export default defineComponent({
}
return null;
},
});
};

View File

@ -1,31 +1,25 @@
function onCompositionStart(e: Event) {
(e.target as any).composing = true;
function onCompositionStart(e) {
e.target.composing = true;
}
function onCompositionEnd(e: Event) {
const target = e.target as any;
if (target.composing) {
target.composing = false;
trigger(target, 'input');
}
function onCompositionEnd(e) {
// prevent triggering an input event for no reason
if (!e.target.composing) return;
e.target.composing = false;
trigger(e.target, 'input');
}
function trigger(el: HTMLElement, type: string) {
function trigger(el, type) {
const e = document.createEvent('HTMLEvents');
e.initEvent(type, true, true);
el.dispatchEvent(e);
}
export function addEventListener(
el: Element,
event: string,
handler: EventListener,
options?: EventListenerOptions,
) {
export function addEventListener(el, event, handler, options) {
el.addEventListener(event, handler, options);
}
const antInput = {
created(el: Element, binding: { modifiers: { lazy: any } }) {
created(el, binding) {
if (!binding.modifiers || !binding.modifiers.lazy) {
addEventListener(el, 'compositionstart', onCompositionStart);
addEventListener(el, 'compositionend', onCompositionEnd);

View File

@ -1,27 +1,9 @@
import { isArray, isString, isObject } from './util';
export type ClassArray = ClassValue[];
export interface ClassDictionary {
[id: string]: any;
}
export type ClassValue =
| string
| number
| ClassDictionary
| ClassArray
| undefined
| null
| boolean;
function classNames(...args: ClassValue[]): string {
const classes: string[] = [];
for (let i = 0; i < args.length; i++) {
const value = args[i];
if (!value) {
continue;
}
function classNames() {
let classes = [];
for (let i = 0; i < arguments.length; i++) {
const value = arguments[i];
if (!value) continue;
if (isString(value)) {
classes.push(value);
} else if (isArray(value)) {

View File

@ -0,0 +1,17 @@
import { tuple } from './type';
export const PresetColorTypes = tuple(
'pink',
'red',
'yellow',
'orange',
'cyan',
'green',
'blue',
'purple',
'geekblue',
'magenta',
'volcano',
'gold',
'lime',
);

View File

@ -1,22 +0,0 @@
import { ElementOf, tuple } from './type';
export const PresetStatusColorTypes = tuple('success', 'processing', 'error', 'default', 'warning');
export const PresetColorTypes = tuple(
'pink',
'red',
'yellow',
'orange',
'cyan',
'green',
'blue',
'purple',
'geekblue',
'magenta',
'volcano',
'gold',
'lime',
);
export type PresetColorType = ElementOf<typeof PresetColorTypes>;
export type PresetStatusColorType = ElementOf<typeof PresetStatusColorTypes>;

View File

@ -0,0 +1,8 @@
function createRef() {
const func = function setRef(node) {
func.current = node;
};
return func;
}
export default createRef;

View File

@ -1,12 +0,0 @@
interface RefObject<T> extends Function {
current?: T | null;
}
function createRef<T>(): RefObject<T> {
const func: RefObject<T> = (node: T | null) => {
func.current = node;
};
return func;
}
export default createRef;

View File

@ -1,4 +1,4 @@
const START_EVENT_NAME_MAP: Record<string, Record<string, string>> = {
const START_EVENT_NAME_MAP = {
transitionstart: {
transition: 'transitionstart',
WebkitTransition: 'webkitTransitionStart',
@ -16,7 +16,7 @@ const START_EVENT_NAME_MAP: Record<string, Record<string, string>> = {
},
};
const END_EVENT_NAME_MAP: Record<string, Record<string, string>> = {
const END_EVENT_NAME_MAP = {
transitionend: {
transition: 'transitionend',
WebkitTransition: 'webkitTransitionEnd',
@ -34,8 +34,8 @@ const END_EVENT_NAME_MAP: Record<string, Record<string, string>> = {
},
};
const startEvents: any[] = [];
const endEvents: any[] = [];
const startEvents = [];
const endEvents = [];
function detectEvents() {
const testEl = document.createElement('div');
@ -51,7 +51,7 @@ function detectEvents() {
delete END_EVENT_NAME_MAP.transitionend.transition;
}
function process(EVENT_NAME_MAP: Record<string, Record<string, string>>, events: any[]) {
function process(EVENT_NAME_MAP, events) {
for (const baseEventName in EVENT_NAME_MAP) {
if (EVENT_NAME_MAP.hasOwnProperty(baseEventName)) {
const baseEvents = EVENT_NAME_MAP[baseEventName];
@ -73,11 +73,11 @@ if (typeof window !== 'undefined' && typeof document !== 'undefined') {
detectEvents();
}
function addEventListener(node: Element, eventName: string, eventListener: any) {
function addEventListener(node, eventName, eventListener) {
node.addEventListener(eventName, eventListener, false);
}
function removeEventListener(node: Element, eventName: string, eventListener: any) {
function removeEventListener(node, eventName, eventListener) {
node.removeEventListener(eventName, eventListener, false);
}
@ -85,7 +85,7 @@ const TransitionEvents = {
// Start events
startEvents,
addStartEventListener(node: Element, eventListener: any) {
addStartEventListener(node, eventListener) {
if (startEvents.length === 0) {
window.setTimeout(eventListener, 0);
return;
@ -95,7 +95,7 @@ const TransitionEvents = {
});
},
removeStartEventListener(node: Element, eventListener: any) {
removeStartEventListener(node, eventListener) {
if (startEvents.length === 0) {
return;
}
@ -107,7 +107,7 @@ const TransitionEvents = {
// End events
endEvents,
addEndEventListener(node: Element, eventListener: any) {
addEndEventListener(node, eventListener) {
if (endEvents.length === 0) {
window.setTimeout(eventListener, 0);
return;
@ -117,7 +117,7 @@ const TransitionEvents = {
});
},
removeEndEventListener(node: Element, eventListener: any) {
removeEndEventListener(node, eventListener) {
if (endEvents.length === 0) {
return;
}

View File

@ -14,13 +14,7 @@ const capitalPrefixes = [
];
const prefixes = ['-webkit-', '-moz-', '-o-', 'ms-', ''];
interface CustomHTMLElement extends HTMLElement {
rcEndAnimTimeout?: any;
rcAnimTimeout?: any;
rcEndListener?: Function | null;
}
function getStyleProperty(node: HTMLElement, name: string) {
function getStyleProperty(node, name) {
// old ff need null, https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle
const style = window.getComputedStyle(node, null);
let ret = '';
@ -33,7 +27,7 @@ function getStyleProperty(node: HTMLElement, name: string) {
return ret;
}
function fixBrowserByTimeout(node: CustomHTMLElement) {
function fixBrowserByTimeout(node) {
if (isCssAnimationSupported) {
const transitionDelay = parseFloat(getStyleProperty(node, 'transition-delay')) || 0;
const transitionDuration = parseFloat(getStyleProperty(node, 'transition-duration')) || 0;
@ -50,29 +44,20 @@ function fixBrowserByTimeout(node: CustomHTMLElement) {
}
}
function clearBrowserBugTimeout(node: CustomHTMLElement) {
function clearBrowserBugTimeout(node) {
if (node.rcEndAnimTimeout) {
clearTimeout(node.rcEndAnimTimeout);
node.rcEndAnimTimeout = null;
}
}
interface TransitionName {
name?: string;
active?: string;
}
const cssAnimation = (
node: CustomHTMLElement,
transitionName: string | TransitionName,
endCallback?: any,
) => {
const cssAnimation = (node, transitionName, endCallback) => {
const nameIsObj = typeof transitionName === 'object';
const className = nameIsObj ? (transitionName as TransitionName).name : transitionName;
const activeClassName = nameIsObj
? (transitionName as TransitionName).active
: `${transitionName}-active`;
const className = nameIsObj ? transitionName.name : transitionName;
const activeClassName = nameIsObj ? transitionName.active : `${transitionName}-active`;
let end = endCallback;
let start;
let active: any;
let active;
const nodeClasses = classes(node);
if (endCallback && Object.prototype.toString.call(endCallback) === '[object Object]') {
@ -85,7 +70,7 @@ const cssAnimation = (
node.rcEndListener();
}
node.rcEndListener = (e: Event) => {
node.rcEndListener = e => {
if (e && e.target !== node) {
return;
}
@ -139,12 +124,12 @@ const cssAnimation = (
};
};
cssAnimation.style = (node: CustomHTMLElement, style: Record<string, any>, callback?: Function) => {
cssAnimation.style = (node, style, callback) => {
if (node.rcEndListener) {
node.rcEndListener();
}
node.rcEndListener = (e: Event) => {
node.rcEndListener = e => {
if (e && e.target !== node) {
return;
}
@ -171,7 +156,7 @@ cssAnimation.style = (node: CustomHTMLElement, style: Record<string, any>, callb
node.rcAnimTimeout = requestAnimationTimeout(() => {
for (const s in style) {
if (style.hasOwnProperty(s)) {
node.style[s as any] = style[s];
node.style[s] = style[s];
}
}
node.rcAnimTimeout = null;
@ -179,7 +164,7 @@ cssAnimation.style = (node: CustomHTMLElement, style: Record<string, any>, callb
}, 0);
};
cssAnimation.setTransition = (node: HTMLElement, p?: any, value?: any) => {
cssAnimation.setTransition = (node, p, value) => {
let property = p;
let v = value;
if (value === undefined) {
@ -188,7 +173,7 @@ cssAnimation.setTransition = (node: HTMLElement, p?: any, value?: any) => {
}
property = property || '';
capitalPrefixes.forEach(prefix => {
node.style[`${prefix}Transition${property}` as any] = v;
node.style[`${prefix}Transition${property}`] = v;
});
};

View File

@ -1,9 +1,8 @@
export function easeInOutCubic(t: number, b: number, c: number, d: number) {
export function easeInOutCubic(t, b, c, d) {
const cc = c - b;
t /= d / 2;
if (t < 1) {
return (cc / 2) * t * t * t + b;
}
// eslint-disable-next-line no-return-assign
return (cc / 2) * ((t -= 2) * t * t + 2) + b;
}

View File

@ -0,0 +1,17 @@
export default function getScroll(target, top) {
if (typeof window === 'undefined') {
return 0;
}
const prop = top ? 'pageYOffset' : 'pageXOffset';
const method = top ? 'scrollTop' : 'scrollLeft';
const isWindow = target === window;
let ret = isWindow ? target[prop] : target[method];
// ie6,7,8 standard mode
if (isWindow && typeof ret !== 'number') {
ret = window.document.documentElement[method];
}
return ret;
}

View File

@ -1,25 +0,0 @@
export function isWindow(obj: any) {
return obj !== null && obj !== undefined && obj === obj.window;
}
export default function getScroll(target: HTMLElement | Window | Document | null, top: Boolean) {
if (typeof window === 'undefined') {
return 0;
}
const method = top ? 'scrollTop' : 'scrollLeft';
let result = 0;
if (isWindow(target)) {
result = (target as Window)[top ? 'pageYOffset' : 'pageXOffset'];
} else if (target instanceof Document) {
result = target.documentElement[method];
} else if (target) {
result = (target as HTMLElement)[method];
}
if (target && !isWindow(target) && typeof result !== 'number') {
result = ((target as HTMLElement).ownerDocument || (target as Document)).documentElement[
method
];
}
return result;
}

View File

@ -1,6 +1,6 @@
let cached: number | undefined;
let cached;
export default function getScrollBarSize(fresh?: boolean) {
export default function getScrollBarSize(fresh) {
if (fresh || cached === undefined) {
const inner = document.createElement('div');
inner.style.width = '100%';
@ -10,8 +10,8 @@ export default function getScrollBarSize(fresh?: boolean) {
const outerStyle = outer.style;
outerStyle.position = 'absolute';
outerStyle.top = '0';
outerStyle.left = '0';
outerStyle.top = 0;
outerStyle.left = 0;
outerStyle.pointerEvents = 'none';
outerStyle.visibility = 'hidden';
outerStyle.width = '200px';

View File

@ -1,5 +1,4 @@
const isNumeric = (value: any): boolean => {
const isNumeric = value => {
return !isNaN(parseFloat(value)) && isFinite(value);
};
export default isNumeric;

View File

@ -1,5 +1,4 @@
const isValid = (value: unknown) => {
const isValid = value => {
return value !== undefined && value !== null && value !== '';
};
export default isValid;

View File

@ -2,10 +2,10 @@ import cssAnimation from './css-animation';
import raf from 'raf';
import { nextTick } from 'vue';
function animate(node: HTMLElement, show: boolean, done: () => void) {
let height: number;
let requestAnimationFrameId: number;
let appearRequestAnimationFrameId: number;
function animate(node, show, done) {
let height;
let requestAnimationFrameId;
let appearRequestAnimationFrameId;
return cssAnimation(node, 'ant-motion-collapse-legacy', {
start() {
if (appearRequestAnimationFrameId) {
@ -54,12 +54,12 @@ function animate(node: HTMLElement, show: boolean, done: () => void) {
}
const animation = {
onEnter(node: HTMLElement, done: () => void) {
onEnter(node, done) {
nextTick(() => {
animate(node, true, done);
});
},
onLeave(node: HTMLElement, done: () => void) {
onLeave(node, done) {
return animate(node, false, done);
},
};

View File

@ -11,13 +11,13 @@ const attributes = `accept acceptCharset accessKey action allowFullScreen allowT
shape size sizes span spellCheck src srcDoc srcLang srcSet start step style
summary tabIndex target title type useMap value width wmode wrap`;
const eventsName = `onCopy onCut onPaste onCompositionend onCompositionstart onCompositionupdate onKeydown
onKeypress onKeyup onFocus onBlur onChange onInput onSubmit onClick onContextmenu onDoubleclick onDblclick
onDrag onDragend onDragenter onDragexit onDragleave onDragover onDragstart onDrop onMousedown
onMouseenter onMouseleave onMousemove onMouseout onMouseover onMouseup onSelect onTouchcancel
onTouchend onTouchmove onTouchstart onScroll onWheel onAbort onCanplay onCanplaythrough
onDurationchange onEmptied onEncrypted onEnded onError onLoadedsata onLoadedmetadata
onLoadstart onPause onPlay onPlaying onProgress onRatechange onSeeked onSeeking onStalled onSuspend onTimeupdate onVolumechange onWaiting onLoad onError`;
const eventsName = `onCopy onCut onPaste onCompositionEnd onCompositionStart onCompositionUpdate onKeyDown
onKeyPress onKeyUp onFocus onBlur onChange onInput onSubmit onClick onContextMenu onDoubleClick
onDrag onDragEnd onDragEnter onDragExit onDragLeave onDragOver onDragStart onDrop onMouseDown
onMouseEnter onMouseLeave onMouseMove onMouseOut onMouseOver onMouseUp onSelect onTouchCancel
onTouchEnd onTouchMove onTouchStart onScroll onWheel onAbort onCanPlay onCanPlayThrough
onDurationChange onEmptied onEncrypted onEnded onError onLoadedData onLoadedMetadata
onLoadStart onPause onPlay onPlaying onProgress onRateChange onSeeked onSeeking onStalled onSuspend onTimeUpdate onVolumeChange onWaiting onLoad onError`;
const propList = `${attributes} ${eventsName}`.split(/[\s\n]+/);
@ -25,23 +25,17 @@ const propList = `${attributes} ${eventsName}`.split(/[\s\n]+/);
const ariaPrefix = 'aria-';
const dataPrefix = 'data-';
function match(key: string, prefix: string) {
function match(key, prefix) {
return key.indexOf(prefix) === 0;
}
export interface PickConfig {
aria?: boolean;
data?: boolean;
attr?: boolean;
}
/**
* Picker props from exist props with filter
* @param props Passed props
* @param ariaOnly boolean | { aria?: boolean; data?: boolean; attr?: boolean; } filter config
*/
export default function pickAttrs(props: object, ariaOnly: boolean | PickConfig = false) {
let mergedConfig: PickConfig;
export default function pickAttrs(props, ariaOnly = false) {
let mergedConfig;
if (ariaOnly === false) {
mergedConfig = {
aria: true,

View File

@ -1,18 +1,18 @@
import { isVNode, Fragment, Comment, Text, h, VNode, ComponentPublicInstance, Slots } from 'vue';
import isPlainObject from 'lodash-es/isPlainObject';
import classNames from './classNames';
import { isVNode, Fragment, Comment, Text, h } from 'vue';
import { camelize, hyphenate, isOn, resolvePropValue } from './util';
import isValid from './isValid';
import { Data, PropOptions } from './type';
// function getType(fn) {
// const match = fn && fn.toString().match(/^\s*function (\w+)/);
// return match ? match[1] : '';
// }
const splitAttrs = (attrs: Data) => {
const splitAttrs = attrs => {
const allAttrs = Object.keys(attrs);
const eventAttrs: Data = {};
const onEvents: Data = {};
const extraAttrs: Data = {};
const eventAttrs = {};
const onEvents = {};
const extraAttrs = {};
for (let i = 0, l = allAttrs.length; i < l; i++) {
const key = allAttrs[i];
if (isOn(key)) {
@ -24,8 +24,8 @@ const splitAttrs = (attrs: Data) => {
}
return { onEvents, events: eventAttrs, extraAttrs };
};
const parseStyleText = (cssText = '', camel: boolean) => {
const res: Record<string, string> = {};
const parseStyleText = (cssText = '', camel) => {
const res = {};
const listDelimiter = /;(?![^(]*\))/g;
const propertyDelimiter = /:(.+)/;
cssText.split(listDelimiter).forEach(function(item) {
@ -40,7 +40,11 @@ const parseStyleText = (cssText = '', camel: boolean) => {
return res;
};
const hasProp = (instance: ComponentPublicInstance, prop: string) => {
const getComponentFromSetup = (props, slots, name, options) => {
return props[name] ? props[name] : slots[name]?.(options);
};
const hasProp = (instance, prop) => {
return prop in getOptionProps(instance);
};
// 重构后直接使用 hasProp 替换
@ -100,7 +104,7 @@ const getSlot = (self, name = 'default', options = {}) => {
return [];
}
} else {
const res = self.$slots[name] && self.$slots[name](options);
let res = self.$slots[name] && self.$slots[name](options);
return flattenChildren(res);
}
};
@ -115,14 +119,14 @@ const getAllChildren = ele => {
const getSlotOptions = () => {
throw Error('使用 .type 直接取值');
};
const findDOMNode = (instance: ComponentPublicInstance) => {
const findDOMNode = instance => {
let node = instance && (instance.$el || instance);
while (node && !node.tagName) {
node = node.nextSibling;
}
return node;
};
const getOptionProps = (instance: ComponentPublicInstance) => {
const getOptionProps = instance => {
const res = {};
if (instance.$ && instance.$.vnode) {
const props = instance.$.vnode.props || {};
@ -149,22 +153,7 @@ const getOptionProps = (instance: ComponentPublicInstance) => {
}
return res;
};
const getComponentFromSetup = (
props: Record<string, unknown>,
slots: Slots,
name: string,
options?: unknown,
) => {
return props[name] ? props[name] : slots[name]?.(options);
};
const getComponent = (
instance: ComponentPublicInstance,
prop = 'default',
options = instance,
execute = true,
) => {
const getComponent = (instance, prop = 'default', options = instance, execute = true) => {
let com = undefined;
if (instance.$) {
const temp = instance[prop];
@ -243,7 +232,7 @@ const getAllProps = ele => {
return props;
};
const getPropsData = (ins: ComponentPublicInstance) => {
const getPropsData = ins => {
const vnode = ins.$ ? ins.$ : ins;
const res = {};
const originProps = vnode.props || {};
@ -275,7 +264,7 @@ const getAttrs = ele => {
};
const getKey = ele => {
const key = ele.key;
let key = ele.key;
return key;
};
@ -289,7 +278,7 @@ export function getEvents(ele = {}, on = true) {
return splitAttrs(props)[on ? 'onEvents' : 'events'];
}
export function getEvent(child: VNode, event: string) {
export function getEvent(child, event) {
return child.props && child.props[event];
}
@ -309,7 +298,7 @@ export function getListeners(context) {
}
export function getClass(ele) {
const props = (isVNode(ele) ? ele.props : ele.$attrs) || {};
const tempCls = props.class || {};
let tempCls = props.class || {};
let cls = {};
if (typeof tempCls === 'string') {
tempCls.split(' ').forEach(c => {
@ -348,7 +337,7 @@ export function isFragment(c) {
return c.length === 1 && c[0].type === Fragment;
}
export function isEmptyElement(c: VNode) {
export function isEmptyElement(c) {
return (
c.type === Comment ||
(c.type === Fragment && c.children.length === 0) ||
@ -356,12 +345,12 @@ export function isEmptyElement(c: VNode) {
);
}
export function isStringElement(c: VNode): boolean {
export function isStringElement(c) {
return c && c.type === Text;
}
export function filterEmpty(children: VNode[] = []) {
const res: VNode[] = [];
export function filterEmpty(children = []) {
const res = [];
children.forEach(child => {
if (Array.isArray(child)) {
res.push(...child);
@ -373,14 +362,10 @@ export function filterEmpty(children: VNode[] = []) {
});
return res.filter(c => !isEmptyElement(c));
}
const initDefaultProps = <T>(
propTypes: T,
defaultProps: { [K in Extract<keyof T, string>]?: T[K] },
): T => {
Object.keys(defaultProps).forEach((k: Extract<keyof T, string>) => {
const prop = propTypes[k] as PropOptions;
if (prop) {
prop.default = defaultProps[k];
const initDefaultProps = (propTypes, defaultProps) => {
Object.keys(defaultProps).forEach(k => {
if (propTypes[k]) {
propTypes[k].def && (propTypes[k] = propTypes[k].def(defaultProps[k]));
} else {
throw new Error(`not have ${k} prop`);
}
@ -388,11 +373,28 @@ const initDefaultProps = <T>(
return propTypes;
};
export function mergeProps() {
const args = [].slice.call(arguments, 0);
const props = {};
args.forEach((p = {}) => {
for (const [k, v] of Object.entries(p)) {
props[k] = props[k] || {};
if (isPlainObject(v)) {
Object.assign(props[k], v);
} else {
props[k] = v;
}
}
});
return props;
}
function isValidElement(element) {
return element && element.__v_isVNode && typeof element.type !== 'symbol'; // remove text node
}
export {
getComponentFromSetup,
splitAttrs,
hasProp,
getOptionProps,
@ -414,6 +416,5 @@ export {
getAllChildren,
findDOMNode,
flattenChildren,
getComponentFromSetup,
};
export default hasProp;

View File

@ -1,14 +1,10 @@
import raf from 'raf';
interface RafMap {
[id: number]: number;
}
let id = 0;
const ids: RafMap = {};
const ids = {};
// Support call raf with delay specified frame
export default function wrapperRaf(callback: () => void, delayFrames = 1): number {
export default function wrapperRaf(callback, delayFrames = 1) {
const myId = id++;
let restFrames = delayFrames;
@ -28,10 +24,9 @@ export default function wrapperRaf(callback: () => void, delayFrames = 1): numbe
return myId;
}
wrapperRaf.cancel = function(pid?: number) {
wrapperRaf.cancel = function(pid) {
if (pid === undefined) return;
raf.cancel(ids[pid]);
delete ids[pid];
};
wrapperRaf.ids = ids; // export this for test usage

View File

@ -1,10 +1,6 @@
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 responsiveArray = ['xxl', 'xl', 'lg', 'md', 'sm', 'xs'];
export const responsiveArray: Breakpoint[] = ['xxl', 'xl', 'lg', 'md', 'sm', 'xs'];
export const responsiveMap: BreakpointMap = {
export const responsiveMap = {
xs: '(max-width: 575px)',
sm: '(min-width: 576px)',
md: '(min-width: 768px)',
@ -13,36 +9,30 @@ export const responsiveMap: BreakpointMap = {
xxl: '(min-width: 1600px)',
};
type SubscribeFunc = (screens: ScreenMap) => void;
const subscribers = new Map<Number, SubscribeFunc>();
const subscribers = new Map();
let subUid = -1;
let screens = {};
const responsiveObserve = {
matchHandlers: {} as {
[prop: string]: {
mql: MediaQueryList;
listener: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | null;
};
},
dispatch(pointMap: ScreenMap) {
matchHandlers: {},
dispatch(pointMap) {
screens = pointMap;
subscribers.forEach(func => func(screens));
return subscribers.size >= 1;
},
subscribe(func: SubscribeFunc): number {
subscribe(func) {
if (!subscribers.size) this.register();
subUid += 1;
subscribers.set(subUid, func);
func(screens);
return subUid;
},
unsubscribe(token: number) {
unsubscribe(token) {
subscribers.delete(token);
if (!subscribers.size) this.unregister();
},
unregister() {
Object.keys(responsiveMap).forEach((screen: Breakpoint) => {
Object.keys(responsiveMap).forEach(screen => {
const matchMediaQuery = responsiveMap[screen];
const handler = this.matchHandlers[matchMediaQuery];
handler?.mql.removeListener(handler?.listener);
@ -50,9 +40,9 @@ const responsiveObserve = {
subscribers.clear();
},
register() {
Object.keys(responsiveMap).forEach((screen: Breakpoint) => {
Object.keys(responsiveMap).forEach(screen => {
const matchMediaQuery = responsiveMap[screen];
const listener = ({ matches }: { matches: boolean }) => {
const listener = ({ matches }) => {
this.dispatch({
...screens,
[screen]: matches,

View File

@ -0,0 +1,37 @@
import raf from 'raf';
import getScroll from './getScroll';
import { easeInOutCubic } from './easings';
// interface ScrollToOptions {
// /** Scroll container, default as window */
// getContainer?: () => HTMLElement | Window;
// /** Scroll end callback */
// callback?: () => any;
// /** Animation duration, default as 450 */
// duration?: number;
// }
export default function scrollTo(y, options = {}) {
const { getContainer = () => window, callback, duration = 450 } = options;
const container = getContainer();
const scrollTop = getScroll(container, true);
const startTime = Date.now();
const frameFunc = () => {
const timestamp = Date.now();
const time = timestamp - startTime;
const nextScrollTop = easeInOutCubic(time > duration ? duration : time, scrollTop, y, duration);
if (container === window) {
window.scrollTo(window.pageXOffset, nextScrollTop);
} else {
container.scrollTop = nextScrollTop;
}
if (time < duration) {
raf(frameFunc);
} else if (typeof callback === 'function') {
callback();
}
};
raf(frameFunc);
}

View File

@ -1,38 +0,0 @@
import raf from 'raf';
import getScroll, { isWindow } from './getScroll';
import { easeInOutCubic } from './easings';
interface ScrollToOptions {
/** Scroll container, default as window */
getContainer?: () => HTMLElement | Window | Document;
/** Scroll end callback */
callback?: () => any;
/** Animation duration, default as 450 */
duration?: number;
}
export default function scrollTo(y: number, options: ScrollToOptions = {}) {
const { getContainer = () => window, callback, duration = 450 } = options;
const container = getContainer();
const scrollTop = getScroll(container, true);
const startTime = Date.now();
const frameFunc = () => {
const timestamp = Date.now();
const time = timestamp - startTime;
const nextScrollTop = easeInOutCubic(time > duration ? duration : time, scrollTop, y, duration);
if (isWindow(container)) {
(container as Window).scrollTo(window.pageXOffset, nextScrollTop);
} else if (container instanceof HTMLDocument || container.constructor.name === 'HTMLDocument') {
(container as HTMLDocument).documentElement.scrollTop = nextScrollTop;
} else {
(container as HTMLElement).scrollTop = nextScrollTop;
}
if (time < duration) {
raf(frameFunc);
} else if (typeof callback === 'function') {
callback();
}
};
raf(frameFunc);
}

View File

@ -1,4 +1,4 @@
const isStyleSupport = (styleName: string | string[]): boolean => {
const isStyleSupport = styleName => {
if (typeof window !== 'undefined' && window.document && window.document.documentElement) {
const styleNameList = Array.isArray(styleName) ? styleName : [styleName];
const { documentElement } = window.document;

View File

@ -1,6 +1,6 @@
import getScrollBarSize from './getScrollBarSize';
export default (close?: boolean) => {
export default close => {
const bodyIsOverflowing =
document.body.scrollHeight > (window.innerHeight || document.documentElement.clientHeight) &&
window.innerWidth > document.body.offsetWidth;

View File

@ -2,8 +2,8 @@
* Wrap of sub component which need use as Button capacity (like Icon component).
* This helps accessibility reader to tread as a interactive button to operation.
*/
import { defineComponent, PropType } from 'vue';
import KeyCode from './KeyCode';
import PropTypes from './vue-types';
const inlineStyle = {
border: 0,
@ -13,30 +13,30 @@ const inlineStyle = {
display: 'inline-block',
};
const TransButton = defineComponent({
const TransButton = {
name: 'TransButton',
inheritAttrs: false,
props: {
noStyle: Boolean,
onClick: Function as PropType<(e: MouseEvent) => void>,
noStyle: PropTypes.bool,
onClick: PropTypes.func,
},
methods: {
onKeyDown(event: KeyboardEvent) {
onKeyDown(event) {
const { keyCode } = event;
if (keyCode === KeyCode.ENTER) {
event.preventDefault();
}
},
onKeyUp(event: KeyboardEvent) {
onKeyUp(event) {
const { keyCode } = event;
if (keyCode === KeyCode.ENTER) {
this.$emit('click', event);
}
},
setRef(btn: HTMLDivElement) {
setRef(btn) {
this.$refs.div = btn;
},
@ -67,10 +67,10 @@ const TransButton = defineComponent({
onKeyup={this.onKeyUp}
style={{ ...(!noStyle ? inlineStyle : null) }}
>
{this.$slots.default?.()}
{this.$slots.default && this.$slots.default()}
</div>
);
},
});
};
export default TransButton;

View File

@ -1,4 +1,4 @@
export default function triggerEvent(el: HTMLElement, type: string) {
export default function triggerEvent(el, type) {
if ('createEvent' in document) {
// modern browsers, IE9+
const e = document.createEvent('HTMLEvents');

4
components/_util/type.js Normal file
View File

@ -0,0 +1,4 @@
// https://stackoverflow.com/questions/46176165/ways-to-get-string-literal-type-of-array-values-without-enum-overhead
export const tuple = (...args) => args;
export const tupleNum = (...args) => args;

View File

@ -1,36 +0,0 @@
import { PropType, VNodeProps } from 'vue';
export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
// https://stackoverflow.com/questions/46176165/ways-to-get-string-literal-type-of-array-values-without-enum-overhead
export const tuple = <T extends string[]>(...args: T) => args;
export const tupleNum = <T extends number[]>(...args: T) => args;
/**
* https://stackoverflow.com/a/59187769
* Extract the type of an element of an array/tuple without performing indexing
*/
export type ElementOf<T> = T extends (infer E)[] ? E : T extends readonly (infer E)[] ? E : never;
/**
* https://github.com/Microsoft/TypeScript/issues/29729
*/
export type LiteralUnion<T extends U, U> = T | (U & {});
export type StringKeyOf<T> = Extract<keyof T, string>;
export type EventHandlers<E> = {
[K in StringKeyOf<E>]?: E[K] extends Function ? E[K] : (payload: E[K]) => void;
};
export type Data = Record<string, unknown>;
export type Key = string | number;
export declare type DefaultFactory<T> = (props: Data) => T | null | undefined;
export declare interface PropOptions<T = any, D = T> {
type?: PropType<T> | true | null;
required?: boolean;
default?: D | DefaultFactory<D> | null | undefined | object;
validator?(value: unknown): boolean;
}

View File

@ -1,35 +1,35 @@
export const isFunction = (val: unknown): val is Function => typeof val === 'function';
export const isFunction = val => typeof val === 'function';
export const isArray = Array.isArray;
export const isString = (val: unknown): val is string => typeof val === 'string';
export const isSymbol = (val: unknown): val is symbol => typeof val === 'symbol';
export const isObject = (val: unknown): val is object => val !== null && typeof val === 'object';
export const isString = val => typeof val === 'string';
export const isSymbol = val => typeof val === 'symbol';
export const isObject = val => val !== null && typeof val === 'object';
const onRE = /^on[^a-z]/;
const isOn = (key: string) => onRE.test(key);
const isOn = key => onRE.test(key);
const cacheStringFunction = (fn: (str: string) => string) => {
const cacheStringFunction = fn => {
const cache = Object.create(null);
return (str: string) => {
return str => {
const hit = cache[str];
return hit || (cache[str] = fn(str));
};
};
const camelizeRE = /-(\w)/g;
const camelize = cacheStringFunction((str: string) => {
const camelize = cacheStringFunction(str => {
return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));
});
const hyphenateRE = /\B([A-Z])/g;
const hyphenate = cacheStringFunction((str: string) =>
str.replace(hyphenateRE, '-$1').toLowerCase(),
);
const hyphenate = cacheStringFunction(str => {
return str.replace(hyphenateRE, '-$1').toLowerCase();
});
const capitalize = cacheStringFunction((str: string) => {
const capitalize = cacheStringFunction(str => {
return str.charAt(0).toUpperCase() + str.slice(1);
});
const hasOwnProperty = Object.prototype.hasOwnProperty;
const hasOwn = (val: object, key: string) => hasOwnProperty.call(val, key);
const hasOwn = (val, key) => hasOwnProperty.call(val, key);
// change from vue sourcecode
function resolvePropValue(options, props, key, value) {
@ -53,8 +53,8 @@ function resolvePropValue(options, props, key, value) {
return value;
}
export function getDataAndAriaProps(props: Record<string, unknown>) {
return Object.keys(props).reduce((memo: Record<string, unknown>, key: string) => {
export function getDataAndAriaProps(props) {
return Object.keys(props).reduce((memo, key) => {
if (key.substr(0, 5) === 'data-' || key.substr(0, 5) === 'aria-') {
memo[key] = props[key];
}

View File

@ -1,8 +1,8 @@
import { filterEmpty } from './props-util';
import { cloneVNode, VNode } from 'vue';
import { cloneVNode } from 'vue';
import warning from './warning';
export function cloneElement(vnode: VNode, nodeProps = {}, override = true) {
export function cloneElement(vnode, nodeProps = {}, override = true) {
let ele = vnode;
if (Array.isArray(vnode)) {
ele = filterEmpty(vnode)[0];
@ -14,10 +14,10 @@ export function cloneElement(vnode: VNode, nodeProps = {}, override = true) {
// cloneVNode内部是合并属性这里改成覆盖属性
node.props = override ? { ...node.props, ...nodeProps } : node.props;
warning(typeof node.props!.class !== 'object', 'class must be string');
warning(typeof node.props.class !== 'object', 'class must be string');
return node;
}
export function cloneVNodes(vnodes: VNode[], nodeProps = {}, override = true) {
export function cloneVNodes(vnodes, nodeProps = {}, override = true) {
return vnodes.map(vnode => cloneElement(vnode, nodeProps, override));
}

View File

@ -1,13 +1,6 @@
import { PropType } from 'vue';
import isPlainObject from 'lodash-es/isPlainObject';
import { toType, getType, isFunction, validateType, isInteger, isArray, warn } from './utils';
// interface BaseTypes {
// type: any;
// def: Function;
// validator: Function;
// }
const PropTypes = {
get any() {
return toType('any', {
@ -16,66 +9,66 @@ const PropTypes = {
},
get func() {
return {
return toType('function', {
type: Function,
};
}).def(currentDefaults.func);
},
get bool() {
return {
return toType('boolean', {
type: Boolean,
};
}).def(currentDefaults.bool);
},
get string() {
return {
return toType('string', {
type: String,
};
}).def(currentDefaults.string);
},
get number() {
return {
return toType('number', {
type: Number,
};
}).def(currentDefaults.number);
},
get array() {
return {
return toType('array', {
type: Array,
};
}).def(currentDefaults.array);
},
get object() {
return {
return toType('object', {
type: Object,
};
}).def(currentDefaults.object);
},
get integer() {
return {
return toType('integer', {
type: Number,
validator(value: number) {
validator(value) {
return isInteger(value);
},
};
}).def(currentDefaults.integer);
},
get symbol() {
return {
return toType('symbol', {
type: null,
validator(value: Symbol) {
validator(value) {
return typeof value === 'symbol';
},
};
});
},
custom(validatorFn: Function, warnMsg = 'custom validation failed') {
custom(validatorFn, warnMsg = 'custom validation failed') {
if (typeof validatorFn !== 'function') {
throw new TypeError('[VueTypes error]: You must provide a function as argument');
}
return toType(validatorFn.name || '<<anonymous function>>', {
validator(...args: any[]) {
validator(...args) {
const valid = validatorFn(...args);
if (!valid) warn(`${this._vueTypes_name} - ${warnMsg}`);
return valid;
@ -83,28 +76,21 @@ const PropTypes = {
});
},
tuple<T>() {
return {
type: (String as unknown) as PropType<T>,
};
},
oneOf<T extends readonly any[]>(arr: T) {
oneOf(arr) {
if (!isArray(arr)) {
throw new TypeError('[VueTypes error]: You must provide an array as argument');
}
const msg = `oneOf - value should be one of "${arr.join('", "')}"`;
const allowedTypes = arr.reduce((ret, v) => {
if (v !== null && v !== undefined) {
const constr = (v as any).constructor;
ret.indexOf(constr) === -1 && ret.push(constr);
ret.indexOf(v.constructor) === -1 && ret.push(v.constructor);
}
return ret;
}, []);
return toType('oneOf', {
type: allowedTypes.length > 0 ? allowedTypes : null,
validator(value: unknown) {
validator(value) {
const valid = arr.indexOf(value) !== -1;
if (!valid) warn(msg);
return valid;
@ -112,13 +98,13 @@ const PropTypes = {
});
},
instanceOf<T>(instanceConstructor: T) {
return {
instanceOf(instanceConstructor) {
return toType('instanceOf', {
type: instanceConstructor,
};
});
},
oneOfType(arr: any[]) {
oneOfType(arr) {
if (!isArray(arr)) {
throw new TypeError('[VueTypes error]: You must provide an array as argument');
}
@ -160,7 +146,7 @@ const PropTypes = {
.reduce((ret, type) => ret.concat(isArray(type) ? type : [type]), [])
.join('", "');
return this.custom(function oneOfType(value: any) {
return this.custom(function oneOfType(value) {
const valid = arr.some(type => {
if (type._vueTypes_name === 'oneOf') {
return type.type ? validateType(type.type, value, true) : true;
@ -172,10 +158,10 @@ const PropTypes = {
}).def(undefined);
},
arrayOf<T extends object>(type: T) {
arrayOf(type) {
return toType('arrayOf', {
type: Array as PropType<T[]>,
validator(values: T[]) {
type: Array,
validator(values) {
const valid = values.every(value => validateType(type, value));
if (!valid) warn(`arrayOf - value must be an array of "${getType(type)}"`);
return valid;
@ -183,10 +169,10 @@ const PropTypes = {
});
},
objectOf(type: any) {
objectOf(type) {
return toType('objectOf', {
type: Object,
validator(obj: { [x: string]: any }) {
validator(obj) {
const valid = Object.keys(obj).every(key => validateType(type, obj[key]));
if (!valid) warn(`objectOf - value must be an object of "${getType(type)}"`);
return valid;
@ -194,13 +180,13 @@ const PropTypes = {
});
},
shape(obj: { [x: string]: any; subscribe?: any; setState?: any; getState?: any }) {
shape(obj) {
const keys = Object.keys(obj);
const requiredKeys = keys.filter(key => obj[key] && obj[key].required === true);
const type = toType('shape', {
type: Object,
validator(value: { [x: string]: any }) {
validator(value) {
if (!isPlainObject(value)) {
return false;
}
@ -246,7 +232,7 @@ const PropTypes = {
},
};
const typeDefaults = (): object => ({
const typeDefaults = () => ({
func: undefined,
bool: undefined,
string: undefined,

View File

@ -7,15 +7,13 @@ export const hasOwn = ObjProto.hasOwnProperty;
const FN_MATCH_REGEXP = /^\s*function (\w+)/;
// https://github.com/vuejs/vue/blob/dev/src/core/util/props.js#L159
export const getType = (fn: any) => {
export const getType = fn => {
const type = fn !== null && fn !== undefined ? (fn.type ? fn.type : fn) : null;
const match = type && type.toString().match(FN_MATCH_REGEXP);
return match && match[1];
};
export const getNativeType = (
value: { constructor: { toString: () => string } } | null | undefined,
) => {
export const getNativeType = value => {
if (value === null || value === undefined) return null;
const match = value.constructor.toString().match(FN_MATCH_REGEXP);
return match && match[1];
@ -24,7 +22,6 @@ export const getNativeType = (
/**
* No-op function
*/
// eslint-disable-next-line @typescript-eslint/no-empty-function
export const noop = () => {};
/**
@ -33,7 +30,7 @@ export const noop = () => {};
* @param {object} obj - Object
* @param {string} prop - Property to check
*/
export const has = (obj: object, prop: string) => hasOwn.call(obj, prop);
export const has = (obj, prop) => hasOwn.call(obj, prop);
/**
* Determines whether the passed value is an integer. Uses `Number.isInteger` if available
@ -66,17 +63,16 @@ export const isArray =
* @param {any} value - Value to check
* @returns {boolean}
*/
export const isFunction = (value: unknown): value is Function =>
toString.call(value) === '[object Function]';
export const isFunction = value => toString.call(value) === '[object Function]';
/**
* Adds a `def` method to the object returning a new object with passed in argument as `default` property
*
* @param {object} type - Object to enhance
*/
export const withDefault = function(type: any) {
export const withDefault = function(type) {
Object.defineProperty(type, 'def', {
value(def: undefined) {
value(def) {
if (def === undefined && this.default === undefined) {
this.default = undefined;
return this;
@ -104,7 +100,7 @@ export const withDefault = function(type: any) {
*
* @param {object} type - Object to enhance
*/
export const withRequired = function(type: any) {
export const withRequired = function(type) {
Object.defineProperty(type, 'isRequired', {
get() {
this.required = true;
@ -121,7 +117,7 @@ export const withRequired = function(type: any) {
* @param {object} obj - Object to enhance
* @returns {object}
*/
export const toType = (name: string, obj: { type?: any; validator?: any; def?: any }) => {
export const toType = (name, obj) => {
Object.defineProperty(obj, '_vueTypes_name', {
enumerable: false,
writable: false,
@ -144,11 +140,7 @@ export const toType = (name: string, obj: { type?: any; validator?: any; def?: a
* @param {boolean} silent - Silence warnings
* @returns {boolean}
*/
export const validateType = (
type: any,
value: { constructor: { toString: () => string } } | null | undefined,
silent = false,
) => {
export const validateType = (type, value, silent = false) => {
let typeToCheck = type;
let valid = true;
let expectedType;
@ -159,8 +151,8 @@ export const validateType = (
if (hasOwn.call(typeToCheck, 'type') && typeToCheck.type !== null) {
if (isArray(typeToCheck.type)) {
valid = typeToCheck.type.some((type: any) => validateType(type, value, true));
expectedType = typeToCheck.type.map((type: any) => getType(type)).join(' or ');
valid = typeToCheck.type.some(type => validateType(type, value, true));
expectedType = typeToCheck.type.map(type => getType(type)).join(' or ');
} else {
expectedType = getType(typeToCheck);
@ -194,11 +186,11 @@ export const validateType = (
return valid;
};
let warn: any = noop;
let warn = noop;
if (process.env.NODE_ENV !== 'production') {
const hasConsole = typeof console !== 'undefined';
warn = (msg: string) => {
warn = msg => {
if (hasConsole) {
console.warn(`[VueTypes warn]: ${msg}`);
}

View File

@ -1,18 +1,18 @@
import { nextTick, inject, defineComponent } from 'vue';
import { nextTick, inject } from 'vue';
import TransitionEvents from './css-animation/Event';
import raf from './raf';
import { defaultConfigProvider } from '../config-provider';
import { ConfigConsumerProps } from '../config-provider';
import { findDOMNode } from './props-util';
let styleForPesudo: HTMLStyleElement | null;
let styleForPesudo;
// Where el is the DOM element you'd like to test for visibility
function isHidden(element: HTMLElement) {
function isHidden(element) {
if (process.env.NODE_ENV === 'test') {
return false;
}
return !element || element.offsetParent === null;
}
function isNotGrey(color: string) {
function isNotGrey(color) {
// eslint-disable-next-line no-useless-escape
const match = (color || '').match(/rgba?\((\d*), (\d*), (\d*)(, [\.\d]*)?\)/);
if (match && match[1] && match[2] && match[3]) {
@ -20,7 +20,7 @@ function isNotGrey(color: string) {
}
return true;
}
export default defineComponent({
export default {
name: 'Wave',
props: ['insertExtraNode'],
mounted() {
@ -33,7 +33,7 @@ export default defineComponent({
});
},
setup() {
const configProvider = inject('configProvider', defaultConfigProvider);
const configProvider = inject('configProvider', ConfigConsumerProps);
return {
configProvider,
};
@ -47,7 +47,7 @@ export default defineComponent({
}
},
methods: {
onClick(node: HTMLElement, waveColor: string) {
onClick(node, waveColor) {
if (!node || isHidden(node) || node.className.indexOf('-leave') >= 0) {
return;
}
@ -87,7 +87,7 @@ export default defineComponent({
TransitionEvents.addStartEventListener(node, this.onTransitionStart);
TransitionEvents.addEndEventListener(node, this.onTransitionEnd);
},
onTransitionStart(e: AnimationEvent) {
onTransitionStart(e) {
if (this._.isUnmounted) return;
const node = findDOMNode(this);
@ -99,7 +99,7 @@ export default defineComponent({
this.resetEffect(node);
}
},
onTransitionEnd(e: AnimationEvent) {
onTransitionEnd(e) {
if (!e || e.animationName !== 'fadeEffect') {
return;
}
@ -109,7 +109,7 @@ export default defineComponent({
const { insertExtraNode } = this.$props;
return insertExtraNode ? 'ant-click-animating' : 'ant-click-animating-without-extra-node';
},
bindAnimationEvent(node: HTMLElement) {
bindAnimationEvent(node) {
if (
!node ||
!node.getAttribute ||
@ -118,9 +118,9 @@ export default defineComponent({
) {
return;
}
const onClick = (e: MouseEvent) => {
const onClick = e => {
// Fix radio button click twice
if ((e.target as HTMLElement).tagName === 'INPUT' || isHidden(e.target as HTMLElement)) {
if (e.target.tagName === 'INPUT' || isHidden(e.target)) {
return;
}
this.resetEffect(node);
@ -146,7 +146,7 @@ export default defineComponent({
};
},
resetEffect(node: HTMLElement) {
resetEffect(node) {
if (!node || node === this.extraNode || !(node instanceof Element)) {
return;
}
@ -171,4 +171,4 @@ export default defineComponent({
}
return this.$slots.default && this.$slots.default()[0];
},
});
};