chore: update util
parent
37c6293ede
commit
92dcc1b90d
|
@ -1,5 +1,5 @@
|
|||
module.exports = {
|
||||
dev: {
|
||||
componentName: 'tree', // dev components
|
||||
componentName: 'affix', // dev components
|
||||
},
|
||||
};
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import { easeInOutCubic } from '../easings';
|
||||
|
||||
describe('Test easings', () => {
|
||||
it('easeInOutCubic return value', () => {
|
||||
const nums = [];
|
||||
// eslint-disable-next-line no-plusplus
|
||||
for (let index = 0; index < 5; index++) {
|
||||
nums.push(easeInOutCubic(index, 1, 5, 4));
|
||||
}
|
||||
|
||||
expect(nums).toEqual([1, 1.25, 3, 4.75, 5]);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,56 @@
|
|||
import scrollTo from '../scrollTo';
|
||||
|
||||
describe('Test ScrollTo function', () => {
|
||||
let dateNowMock;
|
||||
|
||||
beforeAll(() => {
|
||||
jest.useFakeTimers();
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
dateNowMock = jest
|
||||
.spyOn(Date, 'now')
|
||||
.mockImplementationOnce(() => 0)
|
||||
.mockImplementationOnce(() => 1000);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
dateNowMock.mockRestore();
|
||||
});
|
||||
|
||||
it('test scrollTo', async () => {
|
||||
const scrollToSpy = jest.spyOn(window, 'scrollTo').mockImplementation((x, y) => {
|
||||
window.scrollY = y;
|
||||
window.pageYOffset = y;
|
||||
});
|
||||
|
||||
scrollTo(1000);
|
||||
|
||||
jest.runAllTimers();
|
||||
expect(window.pageYOffset).toBe(1000);
|
||||
|
||||
scrollToSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('test callback - option', async () => {
|
||||
const cbMock = jest.fn();
|
||||
scrollTo(1000, {
|
||||
callback: cbMock,
|
||||
});
|
||||
jest.runAllTimers();
|
||||
expect(cbMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('test getContainer - option', async () => {
|
||||
const div = document.createElement('div');
|
||||
scrollTo(1000, {
|
||||
getContainer: () => div,
|
||||
});
|
||||
jest.runAllTimers();
|
||||
expect(div.scrollTop).toBe(1000);
|
||||
});
|
||||
});
|
|
@ -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',
|
||||
);
|
|
@ -0,0 +1,8 @@
|
|||
export function easeInOutCubic(t, b, c, d) {
|
||||
const cc = c - b;
|
||||
t /= d / 2;
|
||||
if (t < 1) {
|
||||
return (cc / 2) * t * t * t + b;
|
||||
}
|
||||
return (cc / 2) * ((t -= 2) * t * t + 2) + b;
|
||||
}
|
|
@ -6,7 +6,7 @@ function animate(node, show, done) {
|
|||
let height;
|
||||
let requestAnimationFrameId;
|
||||
let appearRequestAnimationFrameId;
|
||||
return cssAnimation(node, 'ant-motion-collapse', {
|
||||
return cssAnimation(node, 'ant-motion-collapse-legacy', {
|
||||
start() {
|
||||
if (appearRequestAnimationFrameId) {
|
||||
raf.cancel(appearRequestAnimationFrameId);
|
||||
|
|
|
@ -13,18 +13,20 @@ export default function wrapperRaf(callback, delayFrames = 1) {
|
|||
|
||||
if (restFrames <= 0) {
|
||||
callback();
|
||||
delete ids[id];
|
||||
delete ids[myId];
|
||||
} else {
|
||||
ids[id] = raf(internalCallback);
|
||||
ids[myId] = raf(internalCallback);
|
||||
}
|
||||
}
|
||||
|
||||
ids[id] = raf(internalCallback);
|
||||
ids[myId] = raf(internalCallback);
|
||||
|
||||
return myId;
|
||||
}
|
||||
|
||||
wrapperRaf.cancel = function(pid) {
|
||||
if (pid === undefined) return;
|
||||
raf.cancel(ids[pid]);
|
||||
delete ids[pid];
|
||||
};
|
||||
wrapperRaf.ids = ids; // export this for test usage
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
function isStyleSupport(styleName) {
|
||||
const isStyleSupport = styleName => {
|
||||
if (typeof window !== 'undefined' && window.document && window.document.documentElement) {
|
||||
const styleNameList = Array.isArray(styleName) ? styleName : [styleName];
|
||||
const { documentElement } = window.document;
|
||||
|
@ -6,7 +6,7 @@ function isStyleSupport(styleName) {
|
|||
return styleNameList.some(name => name in documentElement.style);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
export const isFlexSupported = isStyleSupport(['flex', 'webkitFlex', 'Flex', 'msFlex']);
|
||||
|
||||
|
|
|
@ -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;
|
|
@ -1,38 +1,7 @@
|
|||
/* eslint-disable no-console */
|
||||
let warned = {};
|
||||
import warning, { resetWarned } from '../vc-util/warning';
|
||||
|
||||
export function warning(valid, message) {
|
||||
// Support uglify
|
||||
if (process.env.NODE_ENV !== 'production' && !valid && console !== undefined) {
|
||||
console.error(`Warning: ${message}`);
|
||||
}
|
||||
}
|
||||
export { resetWarned };
|
||||
|
||||
export function note(valid, message) {
|
||||
// Support uglify
|
||||
if (process.env.NODE_ENV !== 'production' && !valid && console !== undefined) {
|
||||
console.warn(`Note: ${message}`);
|
||||
}
|
||||
}
|
||||
|
||||
export function resetWarned() {
|
||||
warned = {};
|
||||
}
|
||||
|
||||
export function call(method, valid, message) {
|
||||
if (!valid && !warned[message]) {
|
||||
method(false, message);
|
||||
warned[message] = true;
|
||||
}
|
||||
}
|
||||
|
||||
export function warningOnce(valid, message) {
|
||||
call(warning, valid, message);
|
||||
}
|
||||
|
||||
export function noteOnce(valid, message) {
|
||||
call(note, valid, message);
|
||||
}
|
||||
|
||||
export default warningOnce;
|
||||
/* eslint-enable */
|
||||
export default (valid, component, message) => {
|
||||
warning(valid, `[antdv: ${component}] ${message}`);
|
||||
};
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import TransitionEvents from './css-animation/Event';
|
||||
import raf from '../_util/raf';
|
||||
import raf from './raf';
|
||||
import { ConfigConsumerProps } from '../config-provider';
|
||||
let styleForPesudo;
|
||||
|
||||
// Where el is the DOM element you'd like to test for visibility
|
||||
|
@ -9,7 +10,14 @@ function isHidden(element) {
|
|||
}
|
||||
return !element || element.offsetParent === null;
|
||||
}
|
||||
|
||||
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]) {
|
||||
return !(match[1] === match[2] && match[2] === match[3]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
export default {
|
||||
name: 'Wave',
|
||||
props: ['insertExtraNode'],
|
||||
|
@ -22,7 +30,9 @@ export default {
|
|||
this.instance = this.bindAnimationEvent(node);
|
||||
});
|
||||
},
|
||||
|
||||
inject: {
|
||||
configProvider: { default: () => ConfigConsumerProps },
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.instance) {
|
||||
this.instance.cancel();
|
||||
|
@ -33,19 +43,10 @@ export default {
|
|||
this.destroy = true;
|
||||
},
|
||||
methods: {
|
||||
isNotGrey(color) {
|
||||
const match = (color || '').match(/rgba?\((\d*), (\d*), (\d*)(, [\.\d]*)?\)/);
|
||||
if (match && match[1] && match[2] && match[3]) {
|
||||
return !(match[1] === match[2] && match[2] === match[3]);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
onClick(node, waveColor) {
|
||||
if (!node || isHidden(node) || node.className.indexOf('-leave') >= 0) {
|
||||
return;
|
||||
}
|
||||
this.removeExtraStyleNode();
|
||||
const { insertExtraNode } = this.$props;
|
||||
this.extraNode = document.createElement('div');
|
||||
const extraNode = this.extraNode;
|
||||
|
@ -59,13 +60,19 @@ export default {
|
|||
waveColor &&
|
||||
waveColor !== '#ffffff' &&
|
||||
waveColor !== 'rgb(255, 255, 255)' &&
|
||||
this.isNotGrey(waveColor) &&
|
||||
isNotGrey(waveColor) &&
|
||||
!/rgba\(\d*, \d*, \d*, 0\)/.test(waveColor) && // any transparent rgba color
|
||||
waveColor !== 'transparent'
|
||||
) {
|
||||
// Add nonce if CSP exist
|
||||
if (this.csp && this.csp.nonce) {
|
||||
styleForPesudo.nonce = this.csp.nonce;
|
||||
}
|
||||
extraNode.style.borderColor = waveColor;
|
||||
|
||||
styleForPesudo.innerHTML = `[ant-click-animating-without-extra-node]:after { border-color: ${waveColor}; }`;
|
||||
styleForPesudo.innerHTML = `
|
||||
[ant-click-animating-without-extra-node='true']::after, .ant-click-animating-node {
|
||||
--antd-wave-shadow-color: ${waveColor};
|
||||
}`;
|
||||
if (!document.body.contains(styleForPesudo)) {
|
||||
document.body.appendChild(styleForPesudo);
|
||||
}
|
||||
|
@ -76,7 +83,28 @@ export default {
|
|||
TransitionEvents.addStartEventListener(node, this.onTransitionStart);
|
||||
TransitionEvents.addEndEventListener(node, this.onTransitionEnd);
|
||||
},
|
||||
onTransitionStart(e) {
|
||||
if (this.destroy) return;
|
||||
|
||||
const node = this.$el;
|
||||
if (!e || e.target !== node) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.animationStart) {
|
||||
this.resetEffect(node);
|
||||
}
|
||||
},
|
||||
onTransitionEnd(e) {
|
||||
if (!e || e.animationName !== 'fadeEffect') {
|
||||
return;
|
||||
}
|
||||
this.resetEffect(e.target);
|
||||
},
|
||||
getAttributeName() {
|
||||
const { insertExtraNode } = this.$props;
|
||||
return insertExtraNode ? 'ant-click-animating' : 'ant-click-animating-without-extra-node';
|
||||
},
|
||||
bindAnimationEvent(node) {
|
||||
if (
|
||||
!node ||
|
||||
|
@ -113,10 +141,6 @@ export default {
|
|||
},
|
||||
};
|
||||
},
|
||||
getAttributeName() {
|
||||
const { insertExtraNode } = this.$props;
|
||||
return insertExtraNode ? 'ant-click-animating' : 'ant-click-animating-without-extra-node';
|
||||
},
|
||||
|
||||
resetEffect(node) {
|
||||
if (!node || node === this.extraNode || !(node instanceof Element)) {
|
||||
|
@ -124,40 +148,22 @@ export default {
|
|||
}
|
||||
const { insertExtraNode } = this.$props;
|
||||
const attributeName = this.getAttributeName();
|
||||
node.removeAttribute(attributeName);
|
||||
this.removeExtraStyleNode();
|
||||
node.setAttribute(attributeName, 'false'); // edge has bug on `removeAttribute` #14466
|
||||
if (styleForPesudo) {
|
||||
styleForPesudo.innerHTML = '';
|
||||
}
|
||||
if (insertExtraNode && this.extraNode && node.contains(this.extraNode)) {
|
||||
node.removeChild(this.extraNode);
|
||||
}
|
||||
TransitionEvents.removeStartEventListener(node, this.onTransitionStart);
|
||||
TransitionEvents.removeEndEventListener(node, this.onTransitionEnd);
|
||||
},
|
||||
onTransitionStart(e) {
|
||||
if (this.destroy) return;
|
||||
|
||||
const node = this.$el;
|
||||
if (!e || e.target !== node) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.animationStart) {
|
||||
this.resetEffect(node);
|
||||
}
|
||||
},
|
||||
onTransitionEnd(e) {
|
||||
if (!e || e.animationName !== 'fadeEffect') {
|
||||
return;
|
||||
}
|
||||
this.resetEffect(e.target);
|
||||
},
|
||||
removeExtraStyleNode() {
|
||||
if (styleForPesudo) {
|
||||
styleForPesudo.innerHTML = '';
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
if (this.configProvider.csp) {
|
||||
this.csp = csp;
|
||||
}
|
||||
return this.$slots.default && this.$slots.default[0];
|
||||
},
|
||||
};
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/* eslint-disable no-console */
|
||||
let warned = {};
|
||||
|
||||
export function warning(valid, message) {
|
||||
// Support uglify
|
||||
if (process.env.NODE_ENV !== 'production' && !valid && console !== undefined) {
|
||||
console.error(`Warning: ${message}`);
|
||||
}
|
||||
}
|
||||
|
||||
export function note(valid, message) {
|
||||
// Support uglify
|
||||
if (process.env.NODE_ENV !== 'production' && !valid && console !== undefined) {
|
||||
console.warn(`Note: ${message}`);
|
||||
}
|
||||
}
|
||||
|
||||
export function resetWarned() {
|
||||
warned = {};
|
||||
}
|
||||
|
||||
export function call(method, valid, message) {
|
||||
if (!valid && !warned[message]) {
|
||||
method(false, message);
|
||||
warned[message] = true;
|
||||
}
|
||||
}
|
||||
|
||||
export function warningOnce(valid, message) {
|
||||
call(warning, valid, message);
|
||||
}
|
||||
|
||||
export function noteOnce(valid, message) {
|
||||
call(note, valid, message);
|
||||
}
|
||||
|
||||
export default warningOnce;
|
||||
/* eslint-enable */
|
Loading…
Reference in New Issue