chore: refactor with ts

pull/2926/head
Amour1688 2020-09-28 11:47:15 +08:00
parent f96895c17c
commit 22cad37729
12 changed files with 149 additions and 195 deletions

View File

@ -425,13 +425,13 @@ const KeyCode = {
* WIN_IME * WIN_IME
*/ */
WIN_IME: 229, WIN_IME: 229,
};
/* // ======================== Function ========================
whether text and modified key is entered at the same time. /**
* whether text and modified key is entered at the same time.
*/ */
KeyCode.isTextModifyingKeyEvent = function isTextModifyingKeyEvent(e) { isTextModifyingKeyEvent: function isTextModifyingKeyEvent(e: KeyboardEvent) {
const keyCode = e.keyCode; const { keyCode } = e;
if ( if (
(e.altKey && !e.ctrlKey) || (e.altKey && !e.ctrlKey) ||
e.metaKey || e.metaKey ||
@ -471,12 +471,12 @@ KeyCode.isTextModifyingKeyEvent = function isTextModifyingKeyEvent(e) {
default: default:
return true; return true;
} }
}; },
/* /**
whether character is entered. * whether character is entered.
*/ */
KeyCode.isCharacterKey = function isCharacterKey(keyCode) { isCharacterKey: function isCharacterKey(keyCode: number) {
if (keyCode >= KeyCode.ZERO && keyCode <= KeyCode.NINE) { if (keyCode >= KeyCode.ZERO && keyCode <= KeyCode.NINE) {
return true; return true;
} }
@ -490,7 +490,7 @@ KeyCode.isCharacterKey = function isCharacterKey(keyCode) {
} }
// Safari sends zero key code for non-latin characters. // Safari sends zero key code for non-latin characters.
if (window.navigation.userAgent.indexOf('WebKit') !== -1 && keyCode === 0) { if (window.navigator.userAgent.indexOf('WebKit') !== -1 && keyCode === 0) {
return true; return true;
} }
@ -516,6 +516,7 @@ KeyCode.isCharacterKey = function isCharacterKey(keyCode) {
default: default:
return false; return false;
} }
},
}; };
export default KeyCode; export default KeyCode;

View File

@ -1,10 +1,13 @@
import PropTypes from './vue-types'; import PropTypes from './vue-types';
import { Teleport } from 'vue'; import { Teleport, defineComponent, PropType } from 'vue';
export default { export default defineComponent({
name: 'Portal', name: 'Portal',
props: { props: {
getContainer: PropTypes.func.isRequired, getContainer: {
type: Function as PropType<(triggerNode: HTMLElement) => HTMLElement>,
required: true,
},
children: PropTypes.any.isRequired, children: PropTypes.any.isRequired,
didUpdate: PropTypes.func, didUpdate: PropTypes.func,
}, },
@ -45,4 +48,4 @@ export default {
} }
return null; return null;
}, },
}; });

View File

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

View File

@ -1,17 +1,25 @@
export default function getScroll(target, top) { 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') { if (typeof window === 'undefined') {
return 0; return 0;
} }
const prop = top ? 'pageYOffset' : 'pageXOffset';
const method = top ? 'scrollTop' : 'scrollLeft'; const method = top ? 'scrollTop' : 'scrollLeft';
const isWindow = target === window; let result = 0;
if (isWindow(target)) {
let ret = isWindow ? target[prop] : target[method]; result = (target as Window)[top ? 'pageYOffset' : 'pageXOffset'];
// ie6,7,8 standard mode } else if (target instanceof Document) {
if (isWindow && typeof ret !== 'number') { result = target.documentElement[method];
ret = window.document.documentElement[method]; } else if (target) {
result = (target as HTMLElement)[method];
} }
if (target && !isWindow(target) && typeof result !== 'number') {
return ret; result = ((target as HTMLElement).ownerDocument || (target as Document)).documentElement[
method
];
}
return result;
} }

View File

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

View File

@ -1,63 +0,0 @@
export const responsiveArray = ['xxl', 'xl', 'lg', 'md', 'sm', 'xs'];
export const responsiveMap = {
xs: '(max-width: 575px)',
sm: '(min-width: 576px)',
md: '(min-width: 768px)',
lg: '(min-width: 992px)',
xl: '(min-width: 1200px)',
xxl: '(min-width: 1600px)',
};
const subscribers = new Map();
let subUid = -1;
let screens = {};
const responsiveObserve = {
matchHandlers: {},
dispatch(pointMap) {
screens = pointMap;
subscribers.forEach(func => func(screens));
return subscribers.size >= 1;
},
subscribe(func) {
if (!subscribers.size) this.register();
subUid += 1;
subscribers.set(subUid, func);
func(screens);
return subUid;
},
unsubscribe(token) {
subscribers.delete(token);
if (!subscribers.size) this.unregister();
},
unregister() {
Object.keys(responsiveMap).forEach(screen => {
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 }) => {
this.dispatch({
...screens,
[screen]: matches,
});
};
const mql = window.matchMedia(matchMediaQuery);
mql.addListener(listener);
this.matchHandlers[matchMediaQuery] = {
mql,
listener,
};
listener(mql);
});
},
};
export default responsiveObserve;

View File

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

View File

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

View File

@ -53,8 +53,8 @@ function resolvePropValue(options, props, key, value) {
return value; return value;
} }
export function getDataAndAriaProps(props) { export function getDataAndAriaProps(props: Record<string, unknown>) {
return Object.keys(props).reduce((memo, key) => { return Object.keys(props).reduce((memo: Record<string, unknown>, key: string) => {
if (key.substr(0, 5) === 'data-' || key.substr(0, 5) === 'aria-') { if (key.substr(0, 5) === 'data-' || key.substr(0, 5) === 'aria-') {
memo[key] = props[key]; memo[key] = props[key];
} }

View File

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

View File

@ -1,5 +1,5 @@
import { inject, defineComponent, HTMLAttributes, CSSProperties } from 'vue'; import { inject, defineComponent, HTMLAttributes, CSSProperties } from 'vue';
import classNames from 'classnames'; import classNames from '../_util/classNames';
import { ConfigConsumerProps } from '../config-provider'; import { ConfigConsumerProps } from '../config-provider';
import { rowContextState } from './Row'; import { rowContextState } from './Row';

View File

@ -82,6 +82,8 @@
"@commitlint/cli": "^8.0.0", "@commitlint/cli": "^8.0.0",
"@commitlint/config-conventional": "^8.0.0", "@commitlint/config-conventional": "^8.0.0",
"@octokit/rest": "^16.0.0", "@octokit/rest": "^16.0.0",
"@types/lodash-es": "^4.17.3",
"@types/raf": "^3.4.0",
"@typescript-eslint/eslint-plugin": "^4.1.0", "@typescript-eslint/eslint-plugin": "^4.1.0",
"@typescript-eslint/parser": "^4.1.0", "@typescript-eslint/parser": "^4.1.0",
"@vue/babel-plugin-jsx": "^1.0.0-rc.2", "@vue/babel-plugin-jsx": "^1.0.0-rc.2",