From 23515f8c3b71f0e00d6ae476150376514a012059 Mon Sep 17 00:00:00 2001 From: xrkffgg Date: Wed, 19 Aug 2020 21:06:38 +0800 Subject: [PATCH 01/31] chore: use father --- .eslintrc.js | 24 ++ .fatherrc.js | 9 + .gitignore | 4 +- .prettierrc | 6 + examples/ant-design.html | 0 examples/ant-design.tsx | 370 ++++++++++++++---------------- examples/bootstrap.html | 0 examples/bootstrap.tsx | 247 ++++++++++---------- examples/multiple-Portal.html | 0 examples/multiple-Portal.tsx | 13 +- jest.config.js | 4 + now.json | 11 + package.json | 72 +++--- src/Dialog.tsx | 118 +++++----- src/DialogWrap.tsx | 3 +- src/IDialogPropTypes.tsx | 4 +- src/LazyRenderBox.tsx | 1 + tests/{index.js => index.spec.js} | 0 tests/setup.js | 6 + typings/custom.d.ts | 6 +- typings/index.d.ts | 1 + 21 files changed, 447 insertions(+), 452 deletions(-) create mode 100644 .eslintrc.js create mode 100644 .fatherrc.js create mode 100644 .prettierrc delete mode 100644 examples/ant-design.html delete mode 100644 examples/bootstrap.html delete mode 100644 examples/multiple-Portal.html create mode 100644 jest.config.js create mode 100644 now.json rename tests/{index.js => index.spec.js} (100%) create mode 100644 tests/setup.js diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000..65b14552 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,24 @@ +const base = require("@umijs/fabric/dist/eslint"); + +module.exports = { + ...base, + rules: { + ...base.rules, + "arrow-parens": 0, + "react/no-array-index-key": 0, + "react/sort-comp": 0, + "@typescript-eslint/no-explicit-any": 0, + "@typescript-eslint/no-empty-interface": 0, + "@typescript-eslint/no-inferrable-types": 0, + "react/no-find-dom-node": 0, + "react/require-default-props": 0, + "no-confusing-arrow": 0, + "import/no-named-as-default-member": 0, + "jsx-a11y/label-has-for": 0, + "jsx-a11y/label-has-associated-control": 0, + "import/no-extraneous-dependencies": 0, + "react/button-has-type": 0, + "jsx-a11y/no-noninteractive-tabindex": 0, + "jsx-a11y/no-autofocus": 0, + }, +}; diff --git a/.fatherrc.js b/.fatherrc.js new file mode 100644 index 00000000..9d8c16b0 --- /dev/null +++ b/.fatherrc.js @@ -0,0 +1,9 @@ +export default { + cjs: "babel", + esm: { type: "babel", importLibToEs: true }, + preCommit: { + eslint: true, + prettier: true, + }, + runtimeHelpers: true, +}; diff --git a/.gitignore b/.gitignore index 27e6a383..ffe384fb 100644 --- a/.gitignore +++ b/.gitignore @@ -25,11 +25,11 @@ build lib es coverage -*.js *.jsx *.map !tests/index.js !/index*.js /ios/ /android/ -yarn.lock \ No newline at end of file +yarn.lock +.storybook diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..895b8bdc --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "singleQuote": true, + "trailingComma": "all", + "proseWrap": "never", + "printWidth": 100 +} diff --git a/examples/ant-design.html b/examples/ant-design.html deleted file mode 100644 index e69de29b..00000000 diff --git a/examples/ant-design.tsx b/examples/ant-design.tsx index c74dd3a7..f8ca15e5 100644 --- a/examples/ant-design.tsx +++ b/examples/ant-design.tsx @@ -1,8 +1,6 @@ /* eslint no-console:0 */ -import 'rc-dialog/assets/index.less'; +import '../assets/index.less'; import * as React from 'react'; -import * as ReactDOM from 'react-dom'; -// use import Dialog from 'rc-dialog' import Dialog from '../src/DialogWrap'; const clearPath = 'M793 242H366v-74c0-6.7-7.7-10.4-12.9' + @@ -27,224 +25,188 @@ const getSvg = (path: string, props = {}, align = false) => { ); }; -class MyControl extends React.Component { - state = { - visible: false, - visible2: false, - visible3: true, - width: 600, - destroyOnClose: false, - center: false, - mousePosition: undefined, - useIcon: false, - forceRender: false, - }; - - onClick = (e: React.MouseEvent) => { - this.setState({ - mousePosition: { - x: e.pageX, - y: e.pageY, - }, - visible: true, +const MyControl = () => { + const [visible, setVisible] = React.useState(false); + const [visible2, setVisible2] = React.useState(false); + const [visible3, setVisible3] = React.useState(false); + const [width, setWidth] = React.useState(600); + const [destroyOnClose, setDestroyOnClose] = React.useState(false); + const [center, setCenter] = React.useState(false); + const [mousePosition, setMousePosition] = React.useState({}); + const [useIcon, setUseIcon] = React.useState(false); + const [forceRender, setForceRender] = React.useState(false); + + const onClick = (e: React.MouseEvent) => { + setMousePosition({ + x: e.pageX, + y: e.pageY, }); + setVisible(true); } - onClose = (e: React.SyntheticEvent) => { - this.setState({ - visible: false, - }); + const onClose = () => { + setVisible(false); } - onClose2 = (e: React.SyntheticEvent) => { - this.setState({ - visible: false, - visible2: false, - }); + const onClose2 = () => { + setVisible(false); + setVisible2(false); } - onClose3 = (e: React.SyntheticEvent) => { - this.setState({ visible3: false }); + const onClose3 = () => { + setVisible3(false); } - onDestroyOnCloseChange = (e: React.ChangeEvent) => { - this.setState({ - destroyOnClose: e.target.checked, - }); + const onDestroyOnCloseChange = (e: React.ChangeEvent) => { + setDestroyOnClose(e.target.checked); } - onForceRenderChange = (e: React.ChangeEvent) => { - this.setState({ - forceRender: e.target.checked, - }); + const onForceRenderChange = (e: React.ChangeEvent) => { + setForceRender(e.target.checked); } - changeWidth = () => { - this.setState({ - width: this.state.width === 600 ? 800 : 600, - }); + const changeWidth = () => { + setWidth(width === 600 ? 800 : 600); } - center = (e: React.ChangeEvent) => { - this.setState({ - center: e.target.checked, - }); + const centerEvent = (e: React.ChangeEvent) => { + setCenter(e.target.checked); } - toggleCloseIcon = () => { - this.setState({ - useIcon: !this.state.useIcon, - }); + const toggleCloseIcon = () => { + setUseIcon(!useIcon); } - render() { - const style = { - width: this.state.width, - }; - let wrapClassName = ''; - if (this.state.center) { - wrapClassName = 'center'; - } - const dialog = ( - - -

basic modal

- - - - -
-
- ); - - const dialog2 = ( - - -

basic modal

- - - - - -
-
- ); - - const dialog3 = ( - -

initialized with forceRender and visbile true

- - - - -
-
- ); - - return ( -
- -

- -   - -   - -   - -

- {dialog} - {dialog2} - {dialog3} -
- ); + const style = { width }; + + let wrapClassName = ''; + if (center) { + wrapClassName = 'center'; } -} - -ReactDOM.render( -
-

ant-design dialog

- -
, - document.getElementById('__react-content'), -); + + const dialog = ( + + +

basic modal

+ + + + +
+
+ ); + + const dialog2 = ( + + +

basic modal

+ + + + + +
+
+ ); + + const dialog3 = ( + +

initialized with forceRender and visbile true

+ + + + +
+
+ ); + + return ( +
+ +

+ +   + +   + +   + +

+ {dialog} + {dialog2} + {dialog3} +
+ ); +}; + +export default MyControl; diff --git a/examples/bootstrap.html b/examples/bootstrap.html deleted file mode 100644 index e69de29b..00000000 diff --git a/examples/bootstrap.tsx b/examples/bootstrap.tsx index 23513b10..c4a52948 100644 --- a/examples/bootstrap.tsx +++ b/examples/bootstrap.tsx @@ -1,144 +1,133 @@ import 'bootstrap/dist/css/bootstrap.css'; -import 'rc-dialog/assets/bootstrap.less'; +import '../assets/bootstrap.less'; import * as React from 'react'; -import * as ReactDOM from 'react-dom'; import Dialog from '../src/DialogWrap'; -class MyControl extends React.Component { - state = { - visible: false, - destroyOnClose: false, - }; - onClick = () => { - this.setState({ - visible: true, - }); +const MyControl = () => { + const [visible, setVisible] = React.useState(false); + const [destroyOnClose, setDestroyOnClose] = React.useState(false); + + const onClick = () => { + setVisible(true); } - onClose = () => { - this.setState({ - visible: false, - }); + + const onClose = () => { + setVisible(false); } - onDestroyOnCloseChange = (e: React.ChangeEvent) => { - this.setState({ - destroyOnClose: e.target.checked, - }); + + const onDestroyOnCloseChange = (e: React.ChangeEvent) => { + setDestroyOnClose(e.target.checked); } - render() { - let dialog; - if (this.state.visible || !this.state.destroyOnClose) { - dialog = ( - 第二个弹框} - footer={ - [ - , - , - ] - } - >

Text in a modal

-

Duis mollis, est non commodo luctus, nisi erat porttitor ligula.

-
-

Overflowing text to show scroll behavior

+ + let dialog; + + if (visible || !destroyOnClose) { + dialog = ( + 第二个弹框} + footer={ + [ + , + , + ] + } + >

Text in a modal

+

Duis mollis, est non commodo luctus, nisi erat porttitor ligula.

+
+

Overflowing text to show scroll behavior

+

Cras mattis consectetur purus sit amet fermentum. + Cras justo odio, dapibus ac facilisis in, + egestas eget quam. Morbi leo risus, porta ac consectetur ac, + vestibulum at eros. +

+

+ {' '} + {' '} + {' '} + {' '} + {' '} + {' '} +

+

Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus + sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. +

+
+

Aenean lacinia bibendum nulla sed + consectetur. Praesent commodo cursus magna, + vel scelerisque nisl consectetur et. Donec sed odio dui. + Donec + ullamcorper nulla non metus auctor fringilla. +

+

Cras mattis consectetur purus sit amet fermentum. + Cras justo odio, dapibus ac facilisis in, egestas + eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. +

+

Praesent commodo cursus + magna, vel scelerisque nisl consectetur et. + Vivamus sagittis lacus vel augue laoreet rutrum faucibus + dolor auctor. +

+

Aenean lacinia bibendum nulla sed consectetur. + Praesent commodo cursus magna, vel + scelerisque nisl consectetur et. Donec sed odio dui. + Donec ullamcorper nulla non metus auctor + fringilla. +

Cras mattis consectetur purus sit amet fermentum. - Cras justo odio, dapibus ac facilisis in, - egestas eget quam. Morbi leo risus, porta ac consectetur ac, - vestibulum at eros. + Cras justo odio, dapibus ac + facilisis in, egestas eget quam. Morbi leo risus, + porta ac consectetur ac, vestibulum at eros.

- {' '} - {' '} - {' '} - {' '} - {' '} - {' '} + Praesent commodo cursus magna, vel scelerisque nisl consectetur et. + Vivamus sagittis lacus vel augue + laoreet rutrum faucibus dolor auctor.

-

Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus - sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. +

Aenean lacinia bibendum nulla sed consectetur. Praesent + commodo cursus magna, vel scelerisque nisl consectetur et. + Donec sed odio dui. Donec ullamcorper nulla + non metus auctor fringilla.

-
-

Aenean lacinia bibendum nulla sed - consectetur. Praesent commodo cursus magna, - vel scelerisque nisl consectetur et. Donec sed odio dui. - Donec - ullamcorper nulla non metus auctor fringilla. -

-

Cras mattis consectetur purus sit amet fermentum. - Cras justo odio, dapibus ac facilisis in, egestas - eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. -

-

Praesent commodo cursus - magna, vel scelerisque nisl consectetur et. - Vivamus sagittis lacus vel augue laoreet rutrum faucibus - dolor auctor. -

-

Aenean lacinia bibendum nulla sed consectetur. - Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. - Donec ullamcorper nulla non metus auctor - fringilla. -

-

Cras mattis consectetur purus sit amet fermentum. - Cras justo odio, dapibus ac - facilisis in, egestas eget quam. Morbi leo risus, - porta ac consectetur ac, vestibulum at eros. -

-

- Praesent commodo cursus magna, vel scelerisque nisl consectetur et. - Vivamus sagittis lacus vel augue - laoreet rutrum faucibus dolor auctor. -

-

Aenean lacinia bibendum nulla sed consectetur. Praesent - commodo cursus magna, vel scelerisque nisl consectetur et. - Donec sed odio dui. Donec ullamcorper nulla - non metus auctor fringilla. -

-
-
- ); - } - return ( -
-

- -   - -

- {dialog} -
+ +
); } -} -ReactDOM.render( -
-

ant-design dialog

- -
, - document.getElementById('__react-content'), -); + return ( +
+

+ +   + +

+ {dialog} +
+ ); +}; + +export default MyControl; diff --git a/examples/multiple-Portal.html b/examples/multiple-Portal.html deleted file mode 100644 index e69de29b..00000000 diff --git a/examples/multiple-Portal.tsx b/examples/multiple-Portal.tsx index 9aa0bc5a..a9843d99 100644 --- a/examples/multiple-Portal.tsx +++ b/examples/multiple-Portal.tsx @@ -1,9 +1,8 @@ import * as React from 'react'; -import * as ReactDOM from 'react-dom'; -import Dialog from '../src/DialogWrap'; import Drawer from 'rc-drawer'; +import Dialog from '../src/DialogWrap'; import 'rc-drawer/assets/index.css'; -import 'rc-dialog/assets/index.less'; +import '../assets/index.less'; const { useState } = React; @@ -51,10 +50,4 @@ const Demo = () => { ); }; -ReactDOM.render( -
-

multiple dialog

- -
, - document.getElementById('__react-content'), -); +export default Demo; diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 00000000..0a096396 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,4 @@ +module.exports = { + setupFiles: ["./tests/setup.js"], + snapshotSerializers: [require.resolve("enzyme-to-json/serializer")], +}; diff --git a/now.json b/now.json new file mode 100644 index 00000000..1d18e2a0 --- /dev/null +++ b/now.json @@ -0,0 +1,11 @@ +{ + "version": 2, + "name": "rc-dialog", + "builds": [ + { + "src": "package.json", + "use": "@now/static-build", + "config": { "distDir": ".doc" } + } + ] +} diff --git a/package.json b/package.json index 6f10cef9..1f2ad6c6 100644 --- a/package.json +++ b/package.json @@ -27,59 +27,45 @@ ], "main": "./lib/DialogWrap", "module": "./es/DialogWrap", - "config": { - "port": 8007, - "entry": { - "rc-dialog": [ - "./index.js", - "./assets/index.less" - ], - "rc-dialog-bootstrap": [ - "./index.js", - "./assets/bootstrap.less" - ] - } - }, "scripts": { - "watch-tsc": "rc-tools run watch-tsc", - "build": "rc-tools run build", - "dist": "rc-tools run dist", - "gh-pages": "rc-tools run gh-pages", - "start": "rc-tools run server", - "compile": "rc-tools run compile", - "pub": "rc-tools run pub", - "lint": "rc-tools run lint --no-js-lint", - "lint:ts": "tsc", - "karma": "rc-test run karma", - "saucelabs": "rc-test run saucelabs", - "test": "rc-test run test", - "chrome-test": "rc-test run chrome-test", - "coverage": "rc-test run coverage", - "prepublish": "rc-tools run guard" + "start": "cross-env NODE_ENV=development father doc dev --storybook", + "build": "father doc build --storybook", + "compile": "father build && lessc assets/index.less assets/index.css && lessc assets/bootstrap.less assets/bootstrap.css", + "gh-pages": "npm run build && father doc deploy", + "prepublishOnly": "npm run compile && np --yolo --no-publish", + "lint": "eslint src/ --ext .ts,.tsx,.jsx,.js,.md", + "prettier": "prettier --write \"**/*.{ts,tsx,js,jsx,json,md}\"", + "test": "father test", + "coverage": "father test --coverage" + }, + "peerDependencies": { + "react": "^16.0.0", + "react-dom": "^16.0.0" + }, + "dependencies": { + "rc-animate": "3.x", + "rc-util": "^5.0.1" }, "devDependencies": { "@types/mocha": "~8.0.0", - "@types/react": "^16.0.19", - "@types/react-dom": "^16.0.2", + "@types/react": "^16.9.2", + "@types/react-dom": "^16.9.0", + "@umijs/fabric": "^2.0.0", "async": "^0.9.0", "bluebird": "~3.7.2", "bootstrap": "^4.3.1", "core-js": "^2.5.1", + "cross-env": "^7.0.0", + "enzyme": "^3.1.1", + "enzyme-adapter-react-16": "^1.0.1", + "enzyme-to-json": "^3.1.2", + "eslint": "^7.1.0", "expect.js": "~0.3.1", + "father": "^2.29.6", "jquery": "^3.3.1", - "pre-commit": "1.x", "rc-drawer": "4.1.0", - "rc-test": "^6.0.1", - "rc-tools": "7.x", - "react": "^16.0.0", - "react-dom": "^16.0.0" + "react": "^16.9.0", + "react-dom": "^16.9.0" }, - "pre-commit": [ - "lint" - ], - "typings": "./lib/DialogWrap.d.ts", - "dependencies": { - "rc-animate": "3.x", - "rc-util": "^5.0.1" - } + "typings": "./lib/DialogWrap.d.ts" } diff --git a/src/Dialog.tsx b/src/Dialog.tsx index f3611ec3..59e58bc7 100644 --- a/src/Dialog.tsx +++ b/src/Dialog.tsx @@ -24,11 +24,11 @@ function getScroll(w: any, top?: boolean) { } function setTransformOrigin(node: any, value: string) { - const style = node.style; + const { style } = node; ['Webkit', 'Moz', 'Ms', 'ms'].forEach((prefix: string) => { style[`${prefix}TransformOrigin`] = value; }); - style[`transformOrigin`] = value; + style.transformOrigin = value; } function offset(el: any) { @@ -63,20 +63,30 @@ export default class Dialog extends React.Component { }; private inTransition: boolean = false; + private titleId: string; + private openTime: number; + private lastOutSideFocusNode: HTMLElement | null; + private wrap: HTMLElement; + private dialog: any; + private sentinelStart: HTMLElement; + private sentinelEnd: HTMLElement; + private dialogMouseDown: boolean; + private timeoutId: number; + private switchScrollingEffect: () => void; constructor(props: IDialogChildProps) { super(props); - this.titleId = `rcDialogTitle${uuid++}`; + this.titleId = `rcDialogTitle${uuid += 1}`; this.switchScrollingEffect = props.switchScrollingEffect || (() => {}); } @@ -96,7 +106,7 @@ export default class Dialog extends React.Component { componentDidUpdate(prevProps: IDialogPropTypes) { const {visible, mask, focusTriggerAfterClose} = this.props; - const mousePosition = this.props.mousePosition; + const { mousePosition } = this.props; if (visible) { // first show if (!prevProps.visible) { @@ -183,55 +193,52 @@ export default class Dialog extends React.Component { } onKeyDown = (e: React.KeyboardEvent) => { - const props = this.props; - if (props.keyboard && e.keyCode === KeyCode.ESC) { + const { keyboard, visible } = this.props; + if (keyboard && e.keyCode === KeyCode.ESC) { e.stopPropagation(); this.close(e); return; } // keep focus inside dialog - if (props.visible) { + if (visible) { if (e.keyCode === KeyCode.TAB) { - const activeElement = document.activeElement; - const sentinelStart = this.sentinelStart; + const { activeElement } = document; if (e.shiftKey) { - if (activeElement === sentinelStart) { + if (activeElement === this.sentinelStart) { this.sentinelEnd.focus(); } } else if (activeElement === this.sentinelEnd) { - sentinelStart.focus(); + this.sentinelStart.focus(); } } } } getDialogElement = () => { - const props = this.props; - const closable = props.closable; - const prefixCls = props.prefixCls; + const { closable, prefixCls, width, height, footer, title, closeIcon, style, className, visible, forceRender, bodyStyle, bodyProps, children, destroyOnClose } = this.props; const dest: any = {}; - if (props.width !== undefined) { - dest.width = props.width; + if (width !== undefined) { + dest.width = width; } - if (props.height !== undefined) { - dest.height = props.height; + if (height !== undefined) { + dest.height = height; } - let footer; - if (props.footer) { - footer = ( + let footerNode; + if (footer) { + footerNode = (
- {props.footer} + {footer}
); } - let header; - if (props.title) { - header = ( + let headerNode; + if (title) { + headerNode = (
- {props.title} + {title}
); @@ -246,12 +253,12 @@ export default class Dialog extends React.Component { aria-label="Close" className={`${prefixCls}-close`} > - {props.closeIcon || } + {closeIcon || } ); } - const style = { ...props.style, ...dest }; + const styleBox = { ...style, ...dest }; const sentinelStyle = { width: 0, height: 0, overflow: 'hidden', outline: 'none' }; const transitionName = this.getTransitionName(); const dialogElement = ( @@ -259,10 +266,10 @@ export default class Dialog extends React.Component { key="dialog-element" role="document" ref={this.saveRef('dialog')} - style={style} - className={`${prefixCls} ${props.className || ''}`} - visible={props.visible} - forceRender={props.forceRender} + style={styleBox} + className={`${prefixCls} ${className || ''}`} + visible={visible} + forceRender={forceRender} onMouseDown={this.onDialogMouseDown} >
{ />
{closer} - {header} + {headerNode}
- {props.children} + {children}
- {footer} + {footerNode}
{ component="" transitionAppear > - {props.visible || !props.destroyOnClose ? dialogElement : null} + {visible || !destroyOnClose ? dialogElement : null} ); } getZIndexStyle = () => { const style: any = {}; - const props = this.props; - if (props.zIndex !== undefined) { - style.zIndex = props.zIndex; + const { zIndex } = this.props; + if (zIndex !== undefined) { + style.zIndex = zIndex; } return style; } @@ -325,18 +332,18 @@ export default class Dialog extends React.Component { } getMaskElement = () => { - const props = this.props; + const { mask, prefixCls, visible, maskProps } = this.props; let maskElement; - if (props.mask) { + if (mask) { const maskTransition = this.getMaskTransitionName(); maskElement = ( ); if (maskTransition) { @@ -357,24 +364,23 @@ export default class Dialog extends React.Component { } getMaskTransitionName = () => { - const props = this.props; - let transitionName = props.maskTransitionName; - const animation = props.maskAnimation; + const { maskTransitionName, maskAnimation, prefixCls } = this.props; + let transitionName = maskTransitionName; + const animation = maskAnimation; if (!transitionName && animation) { - transitionName = `${props.prefixCls}-${animation}`; + transitionName = `${prefixCls}-${animation}`; } return transitionName; } getTransitionName = () => { - const props = this.props; - let transitionName = props.transitionName; - const animation = props.animation; + const { transitionName, animation, prefixCls } = this.props; + let transitionNameResult = transitionName; if (!transitionName && animation) { - transitionName = `${props.prefixCls}-${animation}`; + transitionNameResult = `${prefixCls}-${animation}`; } - return transitionName; + return transitionNameResult; } close = (e: any) => { diff --git a/src/DialogWrap.tsx b/src/DialogWrap.tsx index 0f89ba6c..de493ca9 100644 --- a/src/DialogWrap.tsx +++ b/src/DialogWrap.tsx @@ -1,8 +1,7 @@ import * as React from 'react'; -import Dialog from './Dialog'; import Portal from 'rc-util/lib/PortalWrapper'; +import Dialog, { IDialogChildProps } from './Dialog'; import IDialogPropTypes from './IDialogPropTypes'; -import { IDialogChildProps } from './Dialog'; // fix issue #10656 /* diff --git a/src/IDialogPropTypes.tsx b/src/IDialogPropTypes.tsx index 984cceab..ed6bac2d 100644 --- a/src/IDialogPropTypes.tsx +++ b/src/IDialogPropTypes.tsx @@ -2,7 +2,7 @@ import { ReactNode, CSSProperties, SyntheticEvent } from 'react'; type IStringOrHtmlElement = string | HTMLElement; -interface IDialogPropTypes { +export interface IDialogPropTypes { className?: string; keyboard?: boolean; style?: CSSProperties; @@ -42,5 +42,3 @@ interface IDialogPropTypes { // https://github.com/react-component/dialog/issues/95 focusTriggerAfterClose?: boolean; } - -export default IDialogPropTypes; diff --git a/src/LazyRenderBox.tsx b/src/LazyRenderBox.tsx index b2204313..ca08f7d3 100644 --- a/src/LazyRenderBox.tsx +++ b/src/LazyRenderBox.tsx @@ -17,6 +17,7 @@ export default class LazyRenderBox extends React.Component setTimeout(cb, 0); + +const Enzyme = require('enzyme'); +const Adapter = require('enzyme-adapter-react-16'); + +Enzyme.configure({ adapter: new Adapter() }); diff --git a/typings/custom.d.ts b/typings/custom.d.ts index 455b131f..1998f6f4 100644 --- a/typings/custom.d.ts +++ b/typings/custom.d.ts @@ -1,14 +1,14 @@ declare module "rc-util/lib/KeyCode" { - var Ret: {ESC:any;TAB:any;}; + const Ret: {ESC:any;TAB:any;}; export default Ret; } declare module "rc-util/lib/*" { - var Ret: any; + const Ret: any; export default Ret; } declare module "rc-animate" { - var Ret: any; + const Ret: any; export default Ret; } \ No newline at end of file diff --git a/typings/index.d.ts b/typings/index.d.ts index 09e70c53..cf3494a8 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -1 +1,2 @@ +// eslint-disable-next-line spaced-comment /// From c10fdab5fcf4e0743f03023ea942ce835d020aa6 Mon Sep 17 00:00:00 2001 From: xrkffgg Date: Thu, 20 Aug 2020 09:50:34 +0800 Subject: [PATCH 02/31] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index ffe384fb..d7e68431 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ coverage /android/ yarn.lock .storybook +.doc From 9aac8dc5a06c48daff20c64d28c0d765f664b556 Mon Sep 17 00:00:00 2001 From: xrkffgg Date: Thu, 20 Aug 2020 14:14:50 +0800 Subject: [PATCH 03/31] chore: update --- package.json | 8 +++++--- tests/index.spec.js | 35 +++++++++++++++++++++-------------- typings/custom.d.ts | 8 ++++---- typings/index.d.ts | 1 - 4 files changed, 30 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index 1f2ad6c6..13f613da 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,8 @@ }, "devDependencies": { "@types/mocha": "~8.0.0", + "@types/enzyme": "^3.1.15", + "@types/jest": "^26.0.0", "@types/react": "^16.9.2", "@types/react-dom": "^16.9.0", "@umijs/fabric": "^2.0.0", @@ -65,7 +67,7 @@ "jquery": "^3.3.1", "rc-drawer": "4.1.0", "react": "^16.9.0", - "react-dom": "^16.9.0" - }, - "typings": "./lib/DialogWrap.d.ts" + "react-dom": "^16.9.0", + "typescript": "^3.9.3" + } } diff --git a/tests/index.spec.js b/tests/index.spec.js index 8f115c3e..f8aa056f 100644 --- a/tests/index.spec.js +++ b/tests/index.spec.js @@ -1,17 +1,21 @@ +/* eslint-disable react/no-render-return-value */ /* eslint-disable func-names */ import 'core-js/es6/map'; import 'core-js/es6/set'; import expect from 'expect.js'; -import Dialog from '../index'; -import '../assets/bootstrap.less'; import $ from 'jquery'; import React from 'react'; import ReactDOM from 'react-dom'; import TestUtils from 'react-dom/test-utils'; -const Simulate = TestUtils.Simulate; + import async from 'async'; import KeyCode from 'rc-util/lib/KeyCode'; +import Dialog from '../index'; +import '../assets/bootstrap.less'; + +const {Simulate} = TestUtils; + describe('dialog', () => { const title = '第一个title'; let dialog; @@ -27,6 +31,7 @@ describe('dialog', () => { visible: false, maskClosable: true, }; + render() { return ( { style={{ width: 600 }} title={title} onClose={onClose} - closeIcon={'test-text'} + closeIcon="test-text" >

第一个dialog

), container); @@ -113,7 +118,7 @@ describe('dialog', () => { setTimeout(done, 10); }, (done) => { const btn = $('.rc-dialog-close')[0]; - expect(btn.innerText).to.be('test-text'); + expect(btn.textContent).to.be('test-text'); Simulate.click(btn); setTimeout(done, 10); }, (done) => { @@ -229,7 +234,7 @@ describe('dialog', () => { it('render footer padding correctly', () => { async.series([() => { - ReactDOM.render(, container) + ReactDOM.render(, container) }, () => { expect($('.rc-dialog-footer').css('padding')).to.be('10px 20px'); }]); @@ -263,7 +268,7 @@ describe('dialog', () => { }); it('sets transform-origin when property mousePosition is set', () => { - const d = ReactDOM.render(( + ReactDOM.render(( { }); it('can get dom element before dialog first show when forceRender is set true ',()=>{ - const d = ReactDOM.render(( + ReactDOM.render(( @@ -341,6 +346,7 @@ describe('dialog', () => { visible: false, visible2: false, }; + render() { return (
@@ -402,7 +408,7 @@ describe('dialog', () => { }) it('afterClose', (done) => { - const dialog = ReactDOM.render(( + ReactDOM.render(( @@ -418,7 +424,7 @@ describe('dialog', () => { }); it('zIndex', () => { - const dialog = ReactDOM.render(( + ReactDOM.render(( @@ -434,11 +440,12 @@ describe('dialog', () => { }); it('should show dialog when initialize dialog, given forceRender and visible is true', () => { - class DialogWrap extends React.Component { + class DialogWrapTest extends React.Component { state = { visible: true, forceRender: true, }; + render() { return ( { ); } } + ReactDOM.render(( -
Show dialog with forceRender and visible is true
-
+ ),container); setTimeout(() => { expect($('.rc-dialog-wrap').css('display')) .to.be('block'); - done(); }, 10); }); }); diff --git a/typings/custom.d.ts b/typings/custom.d.ts index 1998f6f4..591383a4 100644 --- a/typings/custom.d.ts +++ b/typings/custom.d.ts @@ -1,14 +1,14 @@ declare module "rc-util/lib/KeyCode" { - const Ret: {ESC:any;TAB:any;}; + var Ret: {ESC:any;TAB:any;}; export default Ret; } declare module "rc-util/lib/*" { - const Ret: any; + var Ret: any; export default Ret; } declare module "rc-animate" { - const Ret: any; + var Ret: any; export default Ret; -} \ No newline at end of file +} diff --git a/typings/index.d.ts b/typings/index.d.ts index cf3494a8..09e70c53 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -1,2 +1 @@ -// eslint-disable-next-line spaced-comment /// From 75920a8fc5c772a72f5c476f51e3c1ab22931eeb Mon Sep 17 00:00:00 2001 From: xrkffgg Date: Thu, 20 Aug 2020 14:24:28 +0800 Subject: [PATCH 04/31] update travis --- .travis.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 313a4cbc..b1684f3c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,16 +17,15 @@ before_install: echo "Only docs were updated, stopping build process." exit fi - phantomjs --version script: - | if [ "$TEST_TYPE" = test ]; then - npm test + npm test -- --coverage && \ + bash <(curl -s https://codecov.io/bash) else npm run $TEST_TYPE fi env: matrix: - TEST_TYPE=lint - - TEST_TYPE=test - - TEST_TYPE=coverage + - TEST_TYPE=test \ No newline at end of file From e08fc8d5540cdbec3cbb846ba27adc0f2f10091b Mon Sep 17 00:00:00 2001 From: xrkffgg Date: Thu, 20 Aug 2020 14:35:30 +0800 Subject: [PATCH 05/31] update --- .travis.yml | 6 +++--- package.json | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index b1684f3c..617358e7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,15 +17,15 @@ before_install: echo "Only docs were updated, stopping build process." exit fi + phantomjs --version script: - | if [ "$TEST_TYPE" = test ]; then - npm test -- --coverage && \ - bash <(curl -s https://codecov.io/bash) + npm test else npm run $TEST_TYPE fi env: matrix: - TEST_TYPE=lint - - TEST_TYPE=test \ No newline at end of file + - TEST_TYPE=test diff --git a/package.json b/package.json index 13f613da..979bc08d 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "jquery": "^3.3.1", "rc-drawer": "4.1.0", "react": "^16.9.0", - "react-dom": "^16.9.0", - "typescript": "^3.9.3" - } + "react-dom": "^16.9.0" + }, + "typings": "./lib/DialogWrap.d.ts" } From 80190bb86e1189caac1b228de6e00c12d9b67881 Mon Sep 17 00:00:00 2001 From: xrkffgg Date: Thu, 20 Aug 2020 14:42:02 +0800 Subject: [PATCH 06/31] modified: package.json --- package.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/package.json b/package.json index 979bc08d..1f2ad6c6 100644 --- a/package.json +++ b/package.json @@ -48,8 +48,6 @@ }, "devDependencies": { "@types/mocha": "~8.0.0", - "@types/enzyme": "^3.1.15", - "@types/jest": "^26.0.0", "@types/react": "^16.9.2", "@types/react-dom": "^16.9.0", "@umijs/fabric": "^2.0.0", From d4d5d3e42af268029002f0147d646eb1d63b7879 Mon Sep 17 00:00:00 2001 From: xrkffgg Date: Thu, 20 Aug 2020 14:52:59 +0800 Subject: [PATCH 07/31] fix typings --- typings/custom.d.ts | 6 +++--- typings/index.d.ts | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/typings/custom.d.ts b/typings/custom.d.ts index 591383a4..d4a32db3 100644 --- a/typings/custom.d.ts +++ b/typings/custom.d.ts @@ -1,14 +1,14 @@ declare module "rc-util/lib/KeyCode" { - var Ret: {ESC:any;TAB:any;}; + const Ret: {ESC:any;TAB:any;}; export default Ret; } declare module "rc-util/lib/*" { - var Ret: any; + const Ret: any; export default Ret; } declare module "rc-animate" { - var Ret: any; + const Ret: any; export default Ret; } diff --git a/typings/index.d.ts b/typings/index.d.ts index 09e70c53..cf3494a8 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -1 +1,2 @@ +// eslint-disable-next-line spaced-comment /// From 4876eecd30727254f0e3520d3f5dfdb5cc7593b2 Mon Sep 17 00:00:00 2001 From: xrkffgg Date: Thu, 20 Aug 2020 15:01:15 +0800 Subject: [PATCH 08/31] modified: package.json --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 1f2ad6c6..cd9c6236 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "react-dom": "^16.0.0" }, "dependencies": { + "eslint-config-airbnb": "^18.2.0", "rc-animate": "3.x", "rc-util": "^5.0.1" }, From 2337edffa06d5aaec82dc88e8b1aea15dbdc22db Mon Sep 17 00:00:00 2001 From: xrkffgg Date: Thu, 20 Aug 2020 15:21:28 +0800 Subject: [PATCH 09/31] modified: package.json --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index cd9c6236..dc05bb0e 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,8 @@ "jquery": "^3.3.1", "rc-drawer": "4.1.0", "react": "^16.9.0", - "react-dom": "^16.9.0" + "react-dom": "^16.9.0", + "typescript": "^3.7.2" }, "typings": "./lib/DialogWrap.d.ts" } From cd838956e0d5e9ac210ee747e85b4ae229fb1144 Mon Sep 17 00:00:00 2001 From: xrkffgg Date: Thu, 20 Aug 2020 15:33:56 +0800 Subject: [PATCH 10/31] modified: package.json --- package.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package.json b/package.json index dc05bb0e..9c1dc08a 100644 --- a/package.json +++ b/package.json @@ -44,10 +44,12 @@ }, "dependencies": { "eslint-config-airbnb": "^18.2.0", + "eslint-plugin-react": "^7.20.6", "rc-animate": "3.x", "rc-util": "^5.0.1" }, "devDependencies": { + "@types/jest": "^26.0.0", "@types/mocha": "~8.0.0", "@types/react": "^16.9.2", "@types/react-dom": "^16.9.0", From a78cd66033cefbf95a5832a8c145c4c216c69c47 Mon Sep 17 00:00:00 2001 From: xrkffgg Date: Thu, 20 Aug 2020 15:44:56 +0800 Subject: [PATCH 11/31] modified: package.json --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 9c1dc08a..78193235 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,8 @@ "eslint-config-airbnb": "^18.2.0", "eslint-plugin-react": "^7.20.6", "rc-animate": "3.x", - "rc-util": "^5.0.1" + "rc-util": "^5.0.1", + "request": "^2.88.2" }, "devDependencies": { "@types/jest": "^26.0.0", From fadaed00e0f90715bc0f67f41f8a2be0bbb73eae Mon Sep 17 00:00:00 2001 From: xrkffgg Date: Thu, 20 Aug 2020 16:45:07 +0800 Subject: [PATCH 12/31] add coverage --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 617358e7..313a4cbc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,3 +29,4 @@ env: matrix: - TEST_TYPE=lint - TEST_TYPE=test + - TEST_TYPE=coverage From 936c67556fc4add1f74a960a5b65940da05890bb Mon Sep 17 00:00:00 2001 From: xrkffgg Date: Thu, 20 Aug 2020 17:54:10 +0800 Subject: [PATCH 13/31] update expect --- package.json | 1 - src/Dialog.tsx | 3 +- tests/index.spec.js | 107 ++++++++++++++++++++++---------------------- typings/index.d.ts | 2 - 4 files changed, 56 insertions(+), 57 deletions(-) delete mode 100644 typings/index.d.ts diff --git a/package.json b/package.json index 78193235..d1ff5f6b 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,6 @@ "enzyme-adapter-react-16": "^1.0.1", "enzyme-to-json": "^3.1.2", "eslint": "^7.1.0", - "expect.js": "~0.3.1", "father": "^2.29.6", "jquery": "^3.3.1", "rc-drawer": "4.1.0", diff --git a/src/Dialog.tsx b/src/Dialog.tsx index 59e58bc7..3608da87 100644 --- a/src/Dialog.tsx +++ b/src/Dialog.tsx @@ -86,7 +86,8 @@ export default class Dialog extends React.Component { constructor(props: IDialogChildProps) { super(props); - this.titleId = `rcDialogTitle${uuid += 1}`; + this.titleId = `rcDialogTitle${uuid}`; + uuid += 1; this.switchScrollingEffect = props.switchScrollingEffect || (() => {}); } diff --git a/tests/index.spec.js b/tests/index.spec.js index f8aa056f..f5509830 100644 --- a/tests/index.spec.js +++ b/tests/index.spec.js @@ -2,7 +2,6 @@ /* eslint-disable func-names */ import 'core-js/es6/map'; import 'core-js/es6/set'; -import expect from 'expect.js'; import $ from 'jquery'; import React from 'react'; import ReactDOM from 'react-dom'; @@ -73,7 +72,7 @@ describe('dialog', () => { }); setTimeout(() => { expect($('.rc-dialog-wrap').css('display')) - .to.be('block'); + .toBe('block'); done(); }, 10); }); @@ -87,27 +86,27 @@ describe('dialog', () => { }); setTimeout(() => { expect($('.rc-dialog-wrap').css('display')) - .to.be('none'); + .toBe('none'); done(); }, 10); }); it('create', () => { - expect($('.rc-dialog').length).to.be(0); + expect($('.rc-dialog').length).toBe(0); }); it('mask', () => { dialog.setState({ visible: true, }); - expect($('.rc-dialog-mask').length).to.be(1); + expect($('.rc-dialog-mask').length).toBe(1); }); it('root', () => { dialog.setState({ visible: true, }); - expect($('.rc-dialog-root').length).to.be(1); + expect($('.rc-dialog-root').length).toBe(1); }); it('click close', (finish) => { @@ -118,13 +117,13 @@ describe('dialog', () => { setTimeout(done, 10); }, (done) => { const btn = $('.rc-dialog-close')[0]; - expect(btn.textContent).to.be('test-text'); + expect(btn.textContent).toBe('test-text'); Simulate.click(btn); setTimeout(done, 10); }, (done) => { - expect(callback1).to.be(1); + expect(callback1).toBe(1); expect($('.rc-dialog-wrap').css('display')) - .to.be('none'); + .toBe('none'); done(); }], finish); }); @@ -137,14 +136,14 @@ describe('dialog', () => { visible: true, }); $(".inputElem").val("test"); - expect($(".inputElem").val()).to.be("test") + expect($(".inputElem").val()).toBe("test") wrapper.setState({ visible: false, }); wrapper.setState({ visible: true, }); - expect($(".inputElem").val()).to.be("") + expect($(".inputElem").val()).toBe("") }) it('esc to close', (finish) => { @@ -159,9 +158,9 @@ describe('dialog', () => { }); setTimeout(done, 10); }, (done) => { - expect(callback1).to.be(1); + expect(callback1).toBe(1); expect($('.rc-dialog-wrap').css('display')) - .to.be('none'); + .toBe('none'); done(); }], finish); }); @@ -178,9 +177,9 @@ describe('dialog', () => { setTimeout(done, 10); }, (done) => { // dialog should closed after mask click - expect(callback1).to.be(1); + expect(callback1).toBe(1); expect($('.rc-dialog-wrap').css('display')) - .to.be('none'); + .toBe('none'); done(); }, (done) => { dialog.setState({ @@ -191,9 +190,9 @@ describe('dialog', () => { setTimeout(done, 10); }, (done) => { // dialog should stay on visible after mask click if set maskClosable to false - // expect(callback1).to.be(0); + // expect(callback1).toBe(0); expect($('.rc-dialog-wrap').css('display')) - .to.be('block'); + .toBe('block'); done(); }], finish); }); @@ -202,17 +201,17 @@ describe('dialog', () => { const d = ReactDOM.render(

1

, container); - expect($('.renderToBody').length).to.be(0); - expect($('.rc-dialog-wrap').length).to.be(0); + expect($('.renderToBody').length).toBe(0); + expect($('.rc-dialog-wrap').length).toBe(0); d.setState({ visible: true, }); - expect($('.rc-dialog-wrap').length).to.be(1); - expect($('.renderToBody').length).to.be(1); - expect($('.rc-dialog-wrap')[0].parentNode.parentNode).not.to.be(container); + expect($('.rc-dialog-wrap').length).toBe(1); + expect($('.renderToBody').length).toBe(1); + expect($('.rc-dialog-wrap')[0].parentNode.parentNode).not.toBe(container); ReactDOM.unmountComponentAtNode(container); - expect($('.renderToBody').length).to.be(0); - expect($('.rc-dialog-wrap').length).to.be(0); + expect($('.renderToBody').length).toBe(0); + expect($('.rc-dialog-wrap').length).toBe(0); }); it('getContainer', () => { @@ -228,15 +227,15 @@ describe('dialog', () => { visible: true, }); // fix issue #10656, must change this test - // expect($('.rc-dialog-wrap')[0].parentNode.parentNode).to.be(returnedContainer); - expect($('.rc-dialog-wrap')[0].parentNode.parentNode.parentNode).to.be(returnedContainer); + // expect($('.rc-dialog-wrap')[0].parentNode.parentNode).toBe(returnedContainer); + expect($('.rc-dialog-wrap')[0].parentNode.parentNode.parentNode).toBe(returnedContainer); }); it('render footer padding correctly', () => { async.series([() => { ReactDOM.render(, container) }, () => { - expect($('.rc-dialog-footer').css('padding')).to.be('10px 20px'); + expect($('.rc-dialog-footer').css('padding')).toBe('10px 20px'); }]); }); @@ -248,7 +247,7 @@ describe('dialog', () => { d.setState({ visible: true }); - expect(document.activeElement).to.be(document.querySelector('input')); + expect(document.activeElement).toBe(document.querySelector('input')); }); it('trap focus after shift-tabbing', () => { @@ -264,7 +263,7 @@ describe('dialog', () => { } Simulate.keyDown(dialogEl, shiftTabbingDescriptor); const sentinelEnd = $('.rc-dialog-content + div')[0]; - expect(document.activeElement).to.be(sentinelEnd); + expect(document.activeElement).toBe(sentinelEnd); }); it('sets transform-origin when property mousePosition is set', () => { @@ -277,7 +276,7 @@ describe('dialog', () => { >

the dialog

), container); - expect($('.rc-dialog').css('transform-origin')).to.not.be.empty(); + expect($('.rc-dialog').css('transform-origin')).not.toBeNull(); }); it('can get dom element before dialog first show when forceRender is set true ',()=>{ @@ -288,7 +287,7 @@ describe('dialog', () => {
forceRender element
),container); - expect($('.rc-dialog-body > div').text()).to.be('forceRender element'); + expect($('.rc-dialog-body > div').text()).toBe('forceRender element'); }); it('should not close if mouse down in dialog', () => { @@ -299,8 +298,9 @@ describe('dialog', () => { Simulate.mouseDown(dialogBody); const wrapper = $('.rc-dialog-wrap')[0]; Simulate.mouseUp(wrapper); - expect(dialog.state.visible).to.be(true); + expect(dialog.state.visible).toBe(true); }); + it('getContainer is false', () => { ReactDOM.render(( {
forceRender element
),container); - expect($('.rc-dialog-body > div').text()).to.be('forceRender element'); - expect($('.rc-dialog-wrap')[0].style.display).to.be('none'); + expect($('.rc-dialog-body > div').text()).toBe('forceRender element'); + expect($('.rc-dialog-wrap')[0].style.display).toBe('none'); }); + it('getContainer is false and visible is true', () => { ReactDOM.render(( {
forceRender element
),container); - expect($('.rc-dialog-body > div').text()).to.be('forceRender element'); - expect($('.rc-dialog-wrap')[0].style.display).to.be(''); - }) + expect($('.rc-dialog-body > div').text()).toBe('forceRender element'); + expect($('.rc-dialog-wrap')[0].style.display).toBe(''); + }); + it('Single Dialog body overflow set correctly', () => { document.body.style.overflow = "scroll" dialog.setState({ visible: true }); - expect(document.body.style.overflow).to.be('hidden'); + expect(document.body.style.overflow).toBe('hidden'); dialog.setState({ visible: false }); - expect(document.body.style.overflow).to.be('scroll'); - }) + expect(document.body.style.overflow).toBe('scroll'); + }); it('Multiple Dialog body overflow set correctly', () => { document.body.style.overflow = "scroll" @@ -369,43 +371,43 @@ describe('dialog', () => { ),container); - expect($('.rc-dialog').length).to.be(0); + expect($('.rc-dialog').length).toBe(0); d.setState({ visible: true, }) - expect($('.rc-dialog').length).to.be(1); - expect(document.body.style.overflow).to.be('hidden'); + expect($('.rc-dialog').length).toBe(1); + expect(document.body.style.overflow).toBe('hidden'); d.setState({ visible2: true, }) - expect($('.rc-dialog').length).to.be(2); - expect(document.body.style.overflow).to.be('hidden'); + expect($('.rc-dialog').length).toBe(2); + expect(document.body.style.overflow).toBe('hidden'); d.setState({ visible: false, visible2: false, }) - expect(document.body.style.overflow).to.be('scroll'); + expect(document.body.style.overflow).toBe('scroll'); d.setState({ visible: true, }) - expect(document.body.style.overflow).to.be('hidden'); + expect(document.body.style.overflow).toBe('hidden'); d.setState({ visible: false, visible2: true, }) - expect(document.body.style.overflow).to.be('hidden'); + expect(document.body.style.overflow).toBe('hidden'); d.setState({ visible: false, visible2: false, }) - expect(document.body.style.overflow).to.be('scroll'); - }) + expect(document.body.style.overflow).toBe('scroll'); + }); it('afterClose', (done) => { ReactDOM.render(( @@ -435,8 +437,7 @@ describe('dialog', () => { visible: true, }); - expect($('.rc-dialog-wrap').css("zIndex")).to.be('1000'); - + expect($('.rc-dialog-wrap').css("zIndex")).toBe('1000'); }); it('should show dialog when initialize dialog, given forceRender and visible is true', () => { @@ -466,7 +467,7 @@ describe('dialog', () => { ),container); setTimeout(() => { expect($('.rc-dialog-wrap').css('display')) - .to.be('block'); + .toBe('block'); }, 10); }); }); diff --git a/typings/index.d.ts b/typings/index.d.ts deleted file mode 100644 index cf3494a8..00000000 --- a/typings/index.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -// eslint-disable-next-line spaced-comment -/// From 23b450c1e644f088f15e413dc7d0c6f23cf12559 Mon Sep 17 00:00:00 2001 From: xrkffgg Date: Fri, 21 Aug 2020 15:51:53 +0800 Subject: [PATCH 14/31] test --- package.json | 1 - tests/index.spec.js | 833 +++++++++++++++++++++----------------------- 2 files changed, 397 insertions(+), 437 deletions(-) diff --git a/package.json b/package.json index d1ff5f6b..96e4c5a8 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,6 @@ "async": "^0.9.0", "bluebird": "~3.7.2", "bootstrap": "^4.3.1", - "core-js": "^2.5.1", "cross-env": "^7.0.0", "enzyme": "^3.1.1", "enzyme-adapter-react-16": "^1.0.1", diff --git a/tests/index.spec.js b/tests/index.spec.js index f5509830..b91c289b 100644 --- a/tests/index.spec.js +++ b/tests/index.spec.js @@ -1,11 +1,7 @@ /* eslint-disable react/no-render-return-value */ /* eslint-disable func-names */ -import 'core-js/es6/map'; -import 'core-js/es6/set'; -import $ from 'jquery'; import React from 'react'; -import ReactDOM from 'react-dom'; -import TestUtils from 'react-dom/test-utils'; +import { mount } from 'enzyme'; import async from 'async'; import KeyCode from 'rc-util/lib/KeyCode'; @@ -13,18 +9,7 @@ import KeyCode from 'rc-util/lib/KeyCode'; import Dialog from '../index'; import '../assets/bootstrap.less'; -const {Simulate} = TestUtils; - describe('dialog', () => { - const title = '第一个title'; - let dialog; - - const container = document.createElement('div'); - container.id = 't1'; - document.body.appendChild(container); - - let callback1; - class DialogWrap extends React.Component { state = { visible: false, @@ -43,431 +28,407 @@ describe('dialog', () => { } beforeEach(() => { - function onClose() { - callback1 = 1; - dialog.setState({ - visible: false, - }); - } - - callback1 = 0; - dialog = ReactDOM.render(( - -

第一个dialog

-
), container); + jest.useFakeTimers(); }); afterEach(() => { - ReactDOM.unmountComponentAtNode(container); - }); - - it('show', (done) => { - dialog.setState({ - visible: true, - }); - setTimeout(() => { - expect($('.rc-dialog-wrap').css('display')) - .toBe('block'); - done(); - }, 10); - }); - - it('close', (done) => { - dialog.setState({ - visible: true, - }); - dialog.setState({ - visible: false, - }); - setTimeout(() => { - expect($('.rc-dialog-wrap').css('display')) - .toBe('none'); - done(); - }, 10); - }); - - it('create', () => { - expect($('.rc-dialog').length).toBe(0); - }); - - it('mask', () => { - dialog.setState({ - visible: true, - }); - expect($('.rc-dialog-mask').length).toBe(1); - }); - - it('root', () => { - dialog.setState({ - visible: true, - }); - expect($('.rc-dialog-root').length).toBe(1); - }); - - it('click close', (finish) => { - async.series([(done) => { - dialog.setState({ - visible: true, - }); - setTimeout(done, 10); - }, (done) => { - const btn = $('.rc-dialog-close')[0]; - expect(btn.textContent).toBe('test-text'); - Simulate.click(btn); - setTimeout(done, 10); - }, (done) => { - expect(callback1).toBe(1); - expect($('.rc-dialog-wrap').css('display')) - .toBe('none'); - done(); - }], finish); - }); - - it("destroy on hide should unmount child components on close", () => { - const wrapper = ReactDOM.render( - - , container); - wrapper.setState({ - visible: true, - }); - $(".inputElem").val("test"); - expect($(".inputElem").val()).toBe("test") - wrapper.setState({ - visible: false, - }); - wrapper.setState({ - visible: true, - }); - expect($(".inputElem").val()).toBe("") - }) - - it('esc to close', (finish) => { - async.series([(done) => { - dialog.setState({ - visible: true, - }); - setTimeout(done, 10); - }, (done) => { - Simulate.keyDown($('.rc-dialog')[0], { - keyCode: KeyCode.ESC, - }); - setTimeout(done, 10); - }, (done) => { - expect(callback1).toBe(1); - expect($('.rc-dialog-wrap').css('display')) - .toBe('none'); - done(); - }], finish); - }); - - it('mask to close', (finish) => { - async.series([(done) => { - dialog.setState({ - visible: true, - }); - setTimeout(done, 500); - }, (done) => { - const mask = $('.rc-dialog-wrap')[0]; - Simulate.click(mask); - setTimeout(done, 10); - }, (done) => { - // dialog should closed after mask click - expect(callback1).toBe(1); - expect($('.rc-dialog-wrap').css('display')) - .toBe('none'); - done(); - }, (done) => { - dialog.setState({ - visible: true, - maskClosable: false, - }); - - setTimeout(done, 10); - }, (done) => { - // dialog should stay on visible after mask click if set maskClosable to false - // expect(callback1).toBe(0); - expect($('.rc-dialog-wrap').css('display')) - .toBe('block'); - done(); - }], finish); - }); - - it('renderToBody', () => { - const d = ReactDOM.render( -

1

-
, container); - expect($('.renderToBody').length).toBe(0); - expect($('.rc-dialog-wrap').length).toBe(0); - d.setState({ - visible: true, - }); - expect($('.rc-dialog-wrap').length).toBe(1); - expect($('.renderToBody').length).toBe(1); - expect($('.rc-dialog-wrap')[0].parentNode.parentNode).not.toBe(container); - ReactDOM.unmountComponentAtNode(container); - expect($('.renderToBody').length).toBe(0); - expect($('.rc-dialog-wrap').length).toBe(0); - }); - - it('getContainer', () => { - const returnedContainer = document.createElement('div'); - document.body.appendChild(returnedContainer); - const d = ReactDOM.render( - returnedContainer}> -

Hello world!

-
, - container - ); - d.setState({ - visible: true, - }); - // fix issue #10656, must change this test - // expect($('.rc-dialog-wrap')[0].parentNode.parentNode).toBe(returnedContainer); - expect($('.rc-dialog-wrap')[0].parentNode.parentNode.parentNode).toBe(returnedContainer); - }); - - it('render footer padding correctly', () => { - async.series([() => { - ReactDOM.render(, container) - }, () => { - expect($('.rc-dialog-footer').css('padding')).toBe('10px 20px'); - }]); - }); - - it('support input autoFocus', () => { - const d = ReactDOM.render( - , - container - ); - d.setState({ - visible: true - }); - expect(document.activeElement).toBe(document.querySelector('input')); - }); - - it('trap focus after shift-tabbing', () => { - dialog.setState({ - visible: true - }); - const dialogEl = $('.rc-dialog-wrap')[0]; - const shiftTabbingDescriptor = { - key: 'TAB', - keyCode: 9, - which: 9, - shiftKey: true - } - Simulate.keyDown(dialogEl, shiftTabbingDescriptor); - const sentinelEnd = $('.rc-dialog-content + div')[0]; - expect(document.activeElement).toBe(sentinelEnd); + jest.useRealTimers(); }); - it('sets transform-origin when property mousePosition is set', () => { - ReactDOM.render(( - -

the dialog

-
), container); - expect($('.rc-dialog').css('transform-origin')).not.toBeNull(); + it('show', () => { + const dialog = mount(); + dialog.setState({ visible: true }); + jest.runAllTimers(); + dialog.update(); + expect(dialog.find('.rc-dialog-wrap').props().style.display).toEqual('block'); }); - it('can get dom element before dialog first show when forceRender is set true ',()=>{ - ReactDOM.render(( - -
forceRender element
-
- ),container); - expect($('.rc-dialog-body > div').text()).toBe('forceRender element'); - }); - - it('should not close if mouse down in dialog', () => { - dialog.setState({ - visible: true, - }); - const dialogBody = $('.rc-dialog-body')[0]; - Simulate.mouseDown(dialogBody); - const wrapper = $('.rc-dialog-wrap')[0]; - Simulate.mouseUp(wrapper); - expect(dialog.state.visible).toBe(true); - }); - - it('getContainer is false', () => { - ReactDOM.render(( - -
forceRender element
-
- ),container); - expect($('.rc-dialog-body > div').text()).toBe('forceRender element'); - expect($('.rc-dialog-wrap')[0].style.display).toBe('none'); - }); - - it('getContainer is false and visible is true', () => { - ReactDOM.render(( - -
forceRender element
-
- ),container); - expect($('.rc-dialog-body > div').text()).toBe('forceRender element'); - expect($('.rc-dialog-wrap')[0].style.display).toBe(''); - }); - - it('Single Dialog body overflow set correctly', () => { - document.body.style.overflow = "scroll" - - dialog.setState({ - visible: true - }); - expect(document.body.style.overflow).toBe('hidden'); - - dialog.setState({ - visible: false - }); - expect(document.body.style.overflow).toBe('scroll'); - }); - - it('Multiple Dialog body overflow set correctly', () => { - document.body.style.overflow = "scroll" - - class MultipleDialogWrap extends React.Component { - state = { - visible: false, - visible2: false, - }; - - render() { - return ( -
- - -
- ); - } - } - - const d = ReactDOM.render(( - -
forceRender element
-
- ),container); - - expect($('.rc-dialog').length).toBe(0); - - d.setState({ - visible: true, - }) - expect($('.rc-dialog').length).toBe(1); - expect(document.body.style.overflow).toBe('hidden'); - - d.setState({ - visible2: true, - }) - expect($('.rc-dialog').length).toBe(2); - expect(document.body.style.overflow).toBe('hidden'); - - d.setState({ - visible: false, - visible2: false, - }) - expect(document.body.style.overflow).toBe('scroll'); - - d.setState({ - visible: true, - }) - expect(document.body.style.overflow).toBe('hidden'); - - d.setState({ - visible: false, - visible2: true, - }) - expect(document.body.style.overflow).toBe('hidden'); - - d.setState({ - visible: false, - visible2: false, - }) - expect(document.body.style.overflow).toBe('scroll'); - }); - - it('afterClose', (done) => { - ReactDOM.render(( - -
afterClose
-
- ),container); - dialog.setState({ - visible: true, - }); - dialog.setState({ - visible: false, - }); - }); - - it('zIndex', () => { - ReactDOM.render(( - -
afterClose
-
- ),container); - dialog.setState({ - visible: true, - }); - - expect($('.rc-dialog-wrap').css("zIndex")).toBe('1000'); - }); - - it('should show dialog when initialize dialog, given forceRender and visible is true', () => { - class DialogWrapTest extends React.Component { - state = { - visible: true, - forceRender: true, - }; - - render() { - return ( - - ); - } - } - - ReactDOM.render(( - -
Show dialog with forceRender and visible is true
-
- ),container); - setTimeout(() => { - expect($('.rc-dialog-wrap').css('display')) - .toBe('block'); - }, 10); - }); + // it('close', () => { + // const dialog = mount(); + // dialog.setState({ + // visible: true, + // }); + // dialog.setState({ + // visible: false, + // }); + // // jest.runAllTimers(); + // expect(dialog.find('.rc-dialog-wrap').props().style.display).toEqual('none'); + // // setTimeout(() => { + + // // }, 10); + // }); + + // it('create', () => { + // const dialog = mount(); + // expect(dialog.find('.rc-dialog').length) + // expect($('.rc-dialog').length).toBe(0); + // }); + + // it('mask', () => { + // dialog.setState({ + // visible: true, + // }); + // expect($('.rc-dialog-mask').length).toBe(1); + // }); + + // it('root', () => { + // dialog.setState({ + // visible: true, + // }); + // expect($('.rc-dialog-root').length).toBe(1); + // }); + + // it('click close', (finish) => { + // async.series([(done) => { + // dialog.setState({ + // visible: true, + // }); + // setTimeout(done, 10); + // }, (done) => { + // const btn = dialog.find('.rc-dialog-close'); + // expect(btn.textContent).toBe('test-text'); + // btn.simulate('click'); + // setTimeout(done, 10); + // }, (done) => { + // expect(callback1).toBe(1); + // expect($('.rc-dialog-wrap').css('display')) + // .toBe('none'); + // done(); + // }], finish); + // }); + + // it("destroy on hide should unmount child components on close", () => { + // const wrapper = ReactDOM.render( + // + // , container); + // wrapper.setState({ + // visible: true, + // }); + // $(".inputElem").val("test"); + // expect($(".inputElem").val()).toBe("test") + // wrapper.setState({ + // visible: false, + // }); + // wrapper.setState({ + // visible: true, + // }); + // expect($(".inputElem").val()).toBe("") + // }) + + // it('esc to close', (finish) => { + // async.series([(done) => { + // dialog.setState({ + // visible: true, + // }); + // setTimeout(done, 10); + // }, (done) => { + // $('.rc-dialog')[0].simulate('keyDown', { keyCode: KeyCode.ESC }); + // setTimeout(done, 10); + // }, (done) => { + // expect(callback1).toBe(1); + // expect($('.rc-dialog-wrap').css('display')) + // .toBe('none'); + // done(); + // }], finish); + // }); + + // it('mask to close', (finish) => { + // async.series([(done) => { + // dialog.setState({ + // visible: true, + // }); + // setTimeout(done, 500); + // }, (done) => { + // const mask = $('.rc-dialog-wrap')[0]; + // mask.simulate('click'); + // setTimeout(done, 10); + // }, (done) => { + // // dialog should closed after mask click + // expect(callback1).toBe(1); + // expect($('.rc-dialog-wrap').css('display')) + // .toBe('none'); + // done(); + // }, (done) => { + // dialog.setState({ + // visible: true, + // maskClosable: false, + // }); + + // setTimeout(done, 10); + // }, (done) => { + // // dialog should stay on visible after mask click if set maskClosable to false + // // expect(callback1).toBe(0); + // expect($('.rc-dialog-wrap').css('display')) + // .toBe('block'); + // done(); + // }], finish); + // }); + + // it('renderToBody', () => { + // const d = ReactDOM.render( + //

1

+ //
, container); + // expect($('.renderToBody').length).toBe(0); + // expect($('.rc-dialog-wrap').length).toBe(0); + // d.setState({ + // visible: true, + // }); + // expect($('.rc-dialog-wrap').length).toBe(1); + // expect($('.renderToBody').length).toBe(1); + // expect($('.rc-dialog-wrap')[0].parentNode.parentNode).not.toBe(container); + // ReactDOM.unmountComponentAtNode(container); + // expect($('.renderToBody').length).toBe(0); + // expect($('.rc-dialog-wrap').length).toBe(0); + // }); + + // it('getContainer', () => { + // const returnedContainer = document.createElement('div'); + // document.body.appendChild(returnedContainer); + // const d = ReactDOM.render( + // returnedContainer}> + //

Hello world!

+ //
, + // container + // ); + // d.setState({ + // visible: true, + // }); + // // fix issue #10656, must change this test + // // expect($('.rc-dialog-wrap')[0].parentNode.parentNode).toBe(returnedContainer); + // expect($('.rc-dialog-wrap')[0].parentNode.parentNode.parentNode).toBe(returnedContainer); + // }); + + // it('render footer padding correctly', () => { + // async.series([() => { + // ReactDOM.render(, container) + // }, () => { + // expect($('.rc-dialog-footer').css('padding')).toBe('10px 20px'); + // }]); + // }); + + // it('support input autoFocus', () => { + // const d = ReactDOM.render( + // , + // container + // ); + // d.setState({ + // visible: true + // }); + // expect(document.activeElement).toBe(document.querySelector('input')); + // }); + + // it('trap focus after shift-tabbing', () => { + // dialog.setState({ + // visible: true + // }); + // const dialogEl = $('.rc-dialog-wrap')[0]; + // dialogEl.simulate('keyDown', { keyCode: 9 }); + // const sentinelEnd = $('.rc-dialog-content + div')[0]; + // expect(document.activeElement).toBe(sentinelEnd); + // }); + + // it('sets transform-origin when property mousePosition is set', () => { + // ReactDOM.render(( + // + //

the dialog

+ //
), container); + // expect($('.rc-dialog').css('transform-origin')).not.toBeNull(); + // }); + + // it('can get dom element before dialog first show when forceRender is set true ',()=>{ + // ReactDOM.render(( + // + //
forceRender element
+ //
+ // ),container); + // expect($('.rc-dialog-body > div').text()).toBe('forceRender element'); + // }); + + // it('should not close if mouse down in dialog', () => { + // dialog.setState({ + // visible: true, + // }); + // const dialogBody = $('.rc-dialog-body')[0]; + // dialogBody.simulate('mousedown'); + // const wrapper = $('.rc-dialog-wrap')[0]; + // wrapper.simulate('mouseup'); + // expect(dialog.state.visible).toBe(true); + // }); + + // it('getContainer is false', () => { + // ReactDOM.render(( + // + //
forceRender element
+ //
+ // ),container); + // expect($('.rc-dialog-body > div').text()).toBe('forceRender element'); + // expect($('.rc-dialog-wrap')[0].style.display).toBe('none'); + // }); + + // it('getContainer is false and visible is true', () => { + // ReactDOM.render(( + // + //
forceRender element
+ //
+ // ),container); + // expect($('.rc-dialog-body > div').text()).toBe('forceRender element'); + // expect($('.rc-dialog-wrap')[0].style.display).toBe(''); + // }); + + // it('Single Dialog body overflow set correctly', () => { + // document.body.style.overflow = "scroll" + + // dialog.setState({ + // visible: true + // }); + // expect(document.body.style.overflow).toBe('hidden'); + + // dialog.setState({ + // visible: false + // }); + // expect(document.body.style.overflow).toBe('scroll'); + // }); + + // it('Multiple Dialog body overflow set correctly', () => { + // document.body.style.overflow = "scroll" + + // class MultipleDialogWrap extends React.Component { + // state = { + // visible: false, + // visible2: false, + // }; + + // render() { + // return ( + //
+ // + // + //
+ // ); + // } + // } + + // const d = ReactDOM.render(( + // + //
forceRender element
+ //
+ // ),container); + + // expect($('.rc-dialog').length).toBe(0); + + // d.setState({ + // visible: true, + // }) + // expect($('.rc-dialog').length).toBe(1); + // expect(document.body.style.overflow).toBe('hidden'); + + // d.setState({ + // visible2: true, + // }) + // expect($('.rc-dialog').length).toBe(2); + // expect(document.body.style.overflow).toBe('hidden'); + + // d.setState({ + // visible: false, + // visible2: false, + // }) + // expect(document.body.style.overflow).toBe('scroll'); + + // d.setState({ + // visible: true, + // }) + // expect(document.body.style.overflow).toBe('hidden'); + + // d.setState({ + // visible: false, + // visible2: true, + // }) + // expect(document.body.style.overflow).toBe('hidden'); + + // d.setState({ + // visible: false, + // visible2: false, + // }) + // expect(document.body.style.overflow).toBe('scroll'); + // }); + + // it('afterClose', (done) => { + // ReactDOM.render(( + // + //
afterClose
+ //
+ // ),container); + // dialog.setState({ + // visible: true, + // }); + // dialog.setState({ + // visible: false, + // }); + // }); + + // it('zIndex', () => { + // ReactDOM.render(( + // + //
afterClose
+ //
+ // ),container); + // dialog.setState({ + // visible: true, + // }); + + // expect($('.rc-dialog-wrap').css("zIndex")).toBe('1000'); + // }); + + // it('should show dialog when initialize dialog, given forceRender and visible is true', () => { + // class DialogWrapTest extends React.Component { + // state = { + // visible: true, + // forceRender: true, + // }; + + // render() { + // return ( + // + // ); + // } + // } + + // ReactDOM.render(( + // + //
Show dialog with forceRender and visible is true
+ //
+ // ),container); + // setTimeout(() => { + // expect($('.rc-dialog-wrap').css('display')) + // .toBe('block'); + // }, 10); + // }); }); From d9604fa6ad40e949999456d8c020e47593e48f0d Mon Sep 17 00:00:00 2001 From: zombiej Date: Fri, 21 Aug 2020 16:05:25 +0800 Subject: [PATCH 15/31] fix one test --- index.js | 3 --- src/Dialog.tsx | 52 +++++++++++++++++++++++++++++---------------- src/index.ts | 5 +++++ tests/index.spec.js | 6 +++--- 4 files changed, 42 insertions(+), 24 deletions(-) delete mode 100644 index.js create mode 100644 src/index.ts diff --git a/index.js b/index.js deleted file mode 100644 index 083513eb..00000000 --- a/index.js +++ /dev/null @@ -1,3 +0,0 @@ -'use strict'; - -module.exports = require('./src/DialogWrap'); diff --git a/src/Dialog.tsx b/src/Dialog.tsx index 3608da87..50b3c5b9 100644 --- a/src/Dialog.tsx +++ b/src/Dialog.tsx @@ -4,7 +4,7 @@ import KeyCode from 'rc-util/lib/KeyCode'; import contains from 'rc-util/lib/Dom/contains'; import Animate from 'rc-animate'; import LazyRenderBox from './LazyRenderBox'; -import IDialogPropTypes from './IDialogPropTypes'; +import { IDialogPropTypes } from './IDialogPropTypes'; let uuid = 0; @@ -80,7 +80,7 @@ export default class Dialog extends React.Component { private dialogMouseDown: boolean; - private timeoutId: number; + private timeoutId: any; private switchScrollingEffect: () => void; @@ -106,7 +106,7 @@ export default class Dialog extends React.Component { } componentDidUpdate(prevProps: IDialogPropTypes) { - const {visible, mask, focusTriggerAfterClose} = this.props; + const { visible, mask, focusTriggerAfterClose } = this.props; const { mousePosition } = this.props; if (visible) { // first show @@ -169,11 +169,11 @@ export default class Dialog extends React.Component { if (afterClose) { afterClose(); } - } + }; onDialogMouseDown = () => { this.dialogMouseDown = true; - } + }; onMaskMouseUp: React.MouseEventHandler = () => { if (this.dialogMouseDown) { @@ -181,7 +181,7 @@ export default class Dialog extends React.Component { this.dialogMouseDown = false; }, 0); } - } + }; onMaskClick = (e: React.MouseEvent) => { // android trigger click on open (fastclick??) @@ -191,7 +191,7 @@ export default class Dialog extends React.Component { if (e.target === e.currentTarget && !this.dialogMouseDown) { this.close(e); } - } + }; onKeyDown = (e: React.KeyboardEvent) => { const { keyboard, visible } = this.props; @@ -213,10 +213,26 @@ export default class Dialog extends React.Component { } } } - } + }; getDialogElement = () => { - const { closable, prefixCls, width, height, footer, title, closeIcon, style, className, visible, forceRender, bodyStyle, bodyProps, children, destroyOnClose } = this.props; + const { + closable, + prefixCls, + width, + height, + footer, + title, + closeIcon, + style, + className, + visible, + forceRender, + bodyStyle, + bodyProps, + children, + destroyOnClose, + } = this.props; const dest: any = {}; if (width !== undefined) { dest.width = width; @@ -313,7 +329,7 @@ export default class Dialog extends React.Component { {visible || !destroyOnClose ? dialogElement : null} ); - } + }; getZIndexStyle = () => { const style: any = {}; @@ -322,15 +338,15 @@ export default class Dialog extends React.Component { style.zIndex = zIndex; } return style; - } + }; getWrapStyle = (): any => { return { ...this.getZIndexStyle(), ...this.props.wrapStyle }; - } + }; getMaskStyle = () => { return { ...this.getZIndexStyle(), ...this.props.maskStyle }; - } + }; getMaskElement = () => { const { mask, prefixCls, visible, maskProps } = this.props; @@ -362,7 +378,7 @@ export default class Dialog extends React.Component { } } return maskElement; - } + }; getMaskTransitionName = () => { const { maskTransitionName, maskAnimation, prefixCls } = this.props; @@ -373,7 +389,7 @@ export default class Dialog extends React.Component { } return transitionName; - } + }; getTransitionName = () => { const { transitionName, animation, prefixCls } = this.props; @@ -382,18 +398,18 @@ export default class Dialog extends React.Component { transitionNameResult = `${prefixCls}-${animation}`; } return transitionNameResult; - } + }; close = (e: any) => { const { onClose } = this.props; if (onClose) { onClose(e); } - } + }; saveRef = (name: string) => (node: any) => { (this as any)[name] = node; - } + }; render() { const { props } = this; diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 00000000..23018ffa --- /dev/null +++ b/src/index.ts @@ -0,0 +1,5 @@ +import Dialog, { IDialogChildProps as DialogProps } from './Dialog'; + +export { DialogProps }; + +export default Dialog; diff --git a/tests/index.spec.js b/tests/index.spec.js index b91c289b..b9d6259a 100644 --- a/tests/index.spec.js +++ b/tests/index.spec.js @@ -6,7 +6,7 @@ import { mount } from 'enzyme'; import async from 'async'; import KeyCode from 'rc-util/lib/KeyCode'; -import Dialog from '../index'; +import Dialog from '../src'; import '../assets/bootstrap.less'; describe('dialog', () => { @@ -40,7 +40,7 @@ describe('dialog', () => { dialog.setState({ visible: true }); jest.runAllTimers(); dialog.update(); - expect(dialog.find('.rc-dialog-wrap').props().style.display).toEqual('block'); + expect(dialog.find('.rc-dialog-wrap').props().style.display).toEqual(null); }); // it('close', () => { @@ -54,7 +54,7 @@ describe('dialog', () => { // // jest.runAllTimers(); // expect(dialog.find('.rc-dialog-wrap').props().style.display).toEqual('none'); // // setTimeout(() => { - + // // }, 10); // }); From ec3ec2752634c2c68b926ba98c8d4bcff3874832 Mon Sep 17 00:00:00 2001 From: zombiej Date: Fri, 21 Aug 2020 16:08:58 +0800 Subject: [PATCH 16/31] update ref --- package.json | 4 ++-- src/DialogWrap.tsx | 27 +++++++++------------------ src/index.ts | 5 +++-- 3 files changed, 14 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index 96e4c5a8..0fbde5e2 100644 --- a/package.json +++ b/package.json @@ -25,8 +25,8 @@ "assets/*.css", "dist" ], - "main": "./lib/DialogWrap", - "module": "./es/DialogWrap", + "main": "./lib/index", + "module": "./es/index", "scripts": { "start": "cross-env NODE_ENV=development father doc dev --storybook", "build": "father doc build --storybook", diff --git a/src/DialogWrap.tsx b/src/DialogWrap.tsx index de493ca9..97e8c4bc 100644 --- a/src/DialogWrap.tsx +++ b/src/DialogWrap.tsx @@ -1,16 +1,16 @@ import * as React from 'react'; import Portal from 'rc-util/lib/PortalWrapper'; import Dialog, { IDialogChildProps } from './Dialog'; -import IDialogPropTypes from './IDialogPropTypes'; +import { IDialogPropTypes } from './IDialogPropTypes'; // fix issue #10656 /* -* getContainer remarks -* Custom container should not be return, because in the Portal component, it will remove the -* return container element here, if the custom container is the only child of it's component, -* like issue #10656, It will has a conflict with removeChild method in react-dom. -* So here should add a child (div element) to custom container. -* */ + * getContainer remarks + * Custom container should not be return, because in the Portal component, it will remove the + * return container element here, if the custom container is the only child of it's component, + * like issue #10656, It will has a conflict with removeChild method in react-dom. + * So here should add a child (div element) to custom container. + * */ export default (props: IDialogPropTypes) => { const { visible, getContainer, forceRender } = props; @@ -25,17 +25,8 @@ export default (props: IDialogPropTypes) => { } return ( - - {(childProps: IDialogChildProps) => ( - - )} + + {(childProps: IDialogChildProps) => } ); }; diff --git a/src/index.ts b/src/index.ts index 23018ffa..2f72a1e0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,6 @@ -import Dialog, { IDialogChildProps as DialogProps } from './Dialog'; +import DialogWrap from './DialogWrap'; +import { IDialogPropTypes as DialogProps } from './IDialogPropTypes'; export { DialogProps }; -export default Dialog; +export default DialogWrap; From b2ee866a59e45433ac3a1806e260beb27113aa09 Mon Sep 17 00:00:00 2001 From: xrkffgg Date: Fri, 21 Aug 2020 18:03:37 +0800 Subject: [PATCH 17/31] update --- package.json | 6 +- tests/index.spec.js | 152 +++++++++++++++++++------------------------- tsconfig.json | 9 --- 3 files changed, 70 insertions(+), 97 deletions(-) delete mode 100644 tsconfig.json diff --git a/package.json b/package.json index 0fbde5e2..c690b3a2 100644 --- a/package.json +++ b/package.json @@ -43,8 +43,7 @@ "react-dom": "^16.0.0" }, "dependencies": { - "eslint-config-airbnb": "^18.2.0", - "eslint-plugin-react": "^7.20.6", + "@babel/runtime": "^7.10.1", "rc-animate": "3.x", "rc-util": "^5.0.1", "request": "^2.88.2" @@ -55,7 +54,6 @@ "@types/react": "^16.9.2", "@types/react-dom": "^16.9.0", "@umijs/fabric": "^2.0.0", - "async": "^0.9.0", "bluebird": "~3.7.2", "bootstrap": "^4.3.1", "cross-env": "^7.0.0", @@ -63,6 +61,8 @@ "enzyme-adapter-react-16": "^1.0.1", "enzyme-to-json": "^3.1.2", "eslint": "^7.1.0", + "eslint-config-airbnb": "^18.2.0", + "eslint-plugin-react": "^7.20.6", "father": "^2.29.6", "jquery": "^3.3.1", "rc-drawer": "4.1.0", diff --git a/tests/index.spec.js b/tests/index.spec.js index b9d6259a..f5196a22 100644 --- a/tests/index.spec.js +++ b/tests/index.spec.js @@ -3,7 +3,6 @@ import React from 'react'; import { mount } from 'enzyme'; -import async from 'async'; import KeyCode from 'rc-util/lib/KeyCode'; import Dialog from '../src'; @@ -43,94 +42,77 @@ describe('dialog', () => { expect(dialog.find('.rc-dialog-wrap').props().style.display).toEqual(null); }); - // it('close', () => { - // const dialog = mount(); - // dialog.setState({ - // visible: true, - // }); - // dialog.setState({ - // visible: false, - // }); - // // jest.runAllTimers(); - // expect(dialog.find('.rc-dialog-wrap').props().style.display).toEqual('none'); - // // setTimeout(() => { - - // // }, 10); - // }); - - // it('create', () => { - // const dialog = mount(); - // expect(dialog.find('.rc-dialog').length) - // expect($('.rc-dialog').length).toBe(0); - // }); - - // it('mask', () => { - // dialog.setState({ - // visible: true, - // }); - // expect($('.rc-dialog-mask').length).toBe(1); - // }); + it('close', () => { + const dialog = mount(); + dialog.setState({ visible: true }); + dialog.setState({ visible: false }); + jest.runAllTimers(); + dialog.update(); + expect(dialog.find('.rc-dialog-wrap').props().style).toEqual({}); + }); - // it('root', () => { - // dialog.setState({ - // visible: true, - // }); - // expect($('.rc-dialog-root').length).toBe(1); - // }); + it('create & root & mask', () => { + const dialog = mount(); + expect(dialog.find('.rc-dialog').length).toBe(0); + dialog.setState({ visible: true }); + jest.runAllTimers(); + dialog.update(); + expect(dialog.find('.rc-dialog-root').length).toBe(1); + expect(dialog.find('.rc-dialog-mask').length).toBe(1); + }); - // it('click close', (finish) => { - // async.series([(done) => { - // dialog.setState({ - // visible: true, - // }); - // setTimeout(done, 10); - // }, (done) => { - // const btn = dialog.find('.rc-dialog-close'); - // expect(btn.textContent).toBe('test-text'); - // btn.simulate('click'); - // setTimeout(done, 10); - // }, (done) => { - // expect(callback1).toBe(1); - // expect($('.rc-dialog-wrap').css('display')) - // .toBe('none'); - // done(); - // }], finish); - // }); + it('click close', () => { + let callback = 0; + const onClose = () =>{ + callback = 1; + } + const dialog = mount( + + ); + dialog.setState({ visible: true }); + jest.runAllTimers(); + dialog.update(); + const btn = dialog.find('.rc-dialog-close'); + expect(btn.props().children).toBe('test'); + btn.simulate('click'); + jest.runAllTimers(); + dialog.update(); + expect(callback).toBe(1); + }); - // it("destroy on hide should unmount child components on close", () => { - // const wrapper = ReactDOM.render( - // - // , container); - // wrapper.setState({ - // visible: true, - // }); - // $(".inputElem").val("test"); - // expect($(".inputElem").val()).toBe("test") - // wrapper.setState({ - // visible: false, - // }); - // wrapper.setState({ - // visible: true, - // }); - // expect($(".inputElem").val()).toBe("") - // }) + it("destroy on hide should unmount child components on close", () => { + const dialog = mount( + + + + ); + dialog.setState({ visible: true }); + jest.runAllTimers(); + dialog.update(); + const input = dialog.find('input'); + input.simulate('change', { target: { value: '111' } }); + expect(input.prop('value')).toEqual('111'); + + dialog.setState({ visible: false }); + dialog.setState({ visible: true }); + jest.runAllTimers(); + dialog.update(); + expect(input.prop('value')).toEqual(''); + }) - // it('esc to close', (finish) => { - // async.series([(done) => { - // dialog.setState({ - // visible: true, - // }); - // setTimeout(done, 10); - // }, (done) => { - // $('.rc-dialog')[0].simulate('keyDown', { keyCode: KeyCode.ESC }); - // setTimeout(done, 10); - // }, (done) => { - // expect(callback1).toBe(1); - // expect($('.rc-dialog-wrap').css('display')) - // .toBe('none'); - // done(); - // }], finish); - // }); + it('esc to close', () => { + const dialog = mount(); + dialog.setState({ visible: true }); + jest.runAllTimers(); + dialog.update(); + dialog.find('.rc-dialog').at(0).simulate('keyDown', { keyCode: KeyCode.ESC }); + jest.runAllTimers(); + dialog.update(); + expect(dialog.find('.rc-dialog-wrap').props().style).toEqual({}); + }); // it('mask to close', (finish) => { // async.series([(done) => { diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index 9727789e..00000000 --- a/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "compilerOptions": { - "strictNullChecks": true, - "moduleResolution": "node", - "jsx": "react", - "target": "es6", - "noImplicitAny": true - } -} From c52992c7568c184c350e0d972e31370132a489bd Mon Sep 17 00:00:00 2001 From: xrkffgg Date: Mon, 24 Aug 2020 15:09:46 +0800 Subject: [PATCH 18/31] update test --- .travis.yml | 1 + examples/ant-design.tsx | 38 ++++++++++++--------- tests/index.spec.js | 74 ++++++++++++++++++++++------------------- 3 files changed, 64 insertions(+), 49 deletions(-) diff --git a/.travis.yml b/.travis.yml index 313a4cbc..76e37e47 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,3 +30,4 @@ env: - TEST_TYPE=lint - TEST_TYPE=test - TEST_TYPE=coverage + - TEST_TYPE=compile diff --git a/examples/ant-design.tsx b/examples/ant-design.tsx index f8ca15e5..ae7de28e 100644 --- a/examples/ant-design.tsx +++ b/examples/ant-design.tsx @@ -26,13 +26,16 @@ const getSvg = (path: string, props = {}, align = false) => { }; const MyControl = () => { - const [visible, setVisible] = React.useState(false); + const [visible1, setVisible1] = React.useState(false); const [visible2, setVisible2] = React.useState(false); - const [visible3, setVisible3] = React.useState(false); + const [visible3, setVisible3] = React.useState(true); const [width, setWidth] = React.useState(600); const [destroyOnClose, setDestroyOnClose] = React.useState(false); const [center, setCenter] = React.useState(false); - const [mousePosition, setMousePosition] = React.useState({}); + const [mousePosition, setMousePosition] = React.useState({ + x: null, + y: null + }); const [useIcon, setUseIcon] = React.useState(false); const [forceRender, setForceRender] = React.useState(false); @@ -41,15 +44,14 @@ const MyControl = () => { x: e.pageX, y: e.pageY, }); - setVisible(true); + setVisible1(true); } const onClose = () => { - setVisible(false); + setVisible1(false); } const onClose2 = () => { - setVisible(false); setVisible2(false); } @@ -57,6 +59,12 @@ const MyControl = () => { setVisible3(false); } + const closeAll = () => { + setVisible1(false); + setVisible2(false); + setVisible3(false); + } + const onDestroyOnCloseChange = (e: React.ChangeEvent) => { setDestroyOnClose(e.target.checked); } @@ -86,12 +94,13 @@ const MyControl = () => { const dialog = ( {

basic modal

@@ -119,19 +127,18 @@ const MyControl = () => { const dialog2 = (

basic modal

- + - +

the dialog

', + ); }); - it('can get dom element before dialog first show when forceRender is set true ',()=>{ + it('can get dom element before dialog first show when forceRender is set true ', () => { const d = mount( - +
forceRender element
-
+
, ); expect(d.find('.rc-dialog-body > div').props().children).toEqual('forceRender element'); }); it('getContainer is false', () => { const d = mount( - +
forceRender element
-
+
, ); expect(d.find('.rc-dialog-body > div').props().children).toEqual('forceRender element'); - expect(d.find('.rc-dialog-wrap').at(0).props().style).toEqual({}); + expect( + d + .find('.rc-dialog-wrap') + .at(0) + .props().style, + ).toEqual({}); }); it('getContainer is false and visible is true', () => { const d = mount( - +
forceRender element
-
+
, ); expect(d.find('.rc-dialog-body > div').props().children).toEqual('forceRender element'); expect(d.find('.rc-dialog-wrap').props().style.display).toEqual(null); @@ -280,12 +279,12 @@ describe('dialog', () => { // 感觉是没有渲染到 body 上,所以没有改变 overflow it('Single Dialog body overflow set correctly', () => { - document.body.style.overflow = "scroll" + document.body.style.overflow = 'scroll'; dialog.setState({ visible: true }); jest.runAllTimers(); dialog.update(); - console.log(document.body.style.overflow) + console.log(document.body.style.overflow); dialog.setState({ visible: false }); jest.runAllTimers(); @@ -364,11 +363,9 @@ describe('dialog', () => { it('afterClose', () => { const afterCloseMock = jest.fn(); const d = mount( - +
afterClose
-
+
, ); d.setState({ visible: true }); jest.runAllTimers(); @@ -380,11 +377,7 @@ describe('dialog', () => { }); it('zIndex', () => { - const d = mount( - - ) + const d = mount(); d.setState({ visible: true }); jest.runAllTimers(); d.update(); @@ -399,22 +392,14 @@ describe('dialog', () => { }; render() { - return ( - - ); + return ; } } const d = mount( - +
Show dialog with forceRender and visible is true
-
+
, ); jest.runAllTimers(); d.update(); From ee3dd73132ab6eb4ccd397c48867ea88a5c9493b Mon Sep 17 00:00:00 2001 From: xrkffgg Date: Wed, 26 Aug 2020 09:49:23 +0800 Subject: [PATCH 24/31] fix input --- tests/index.spec.js | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/tests/index.spec.js b/tests/index.spec.js index 96a83d9d..18e9bc68 100644 --- a/tests/index.spec.js +++ b/tests/index.spec.js @@ -87,24 +87,26 @@ describe('dialog', () => { expect(callback).toBe(1); }); - // failed input 输入没成功 - // it("destroy on hide should unmount child components on close", () => { - // const wrapper = mount( - // - // - // - // ); - // wrapper.setState({ visible: true }); - // jest.runAllTimers(); - // wrapper.update(); - // wrapper.find('input').simulate('change', { target: { value: '111' } }); - // expect(wrapper.find('input').getDOMNode().value).toEqual('111'); - // wrapper.setState({ visible: false }); - // wrapper.setState({ visible: true }); - // jest.runAllTimers(); - // wrapper.update(); - // expect(wrapper.find('input').getDOMNode().value).toEqual(''); - // }) + it("destroy on hide should unmount child components on close", () => { + const wrapper = mount( + + + + ); + wrapper.setState({ visible: true }); + jest.runAllTimers(); + wrapper.update(); + document.getElementsByClassName('.test-input').value = 'test'; + expect(document.getElementsByClassName('.test-input').value).toBe('test'); + wrapper.setState({ visible: false }); + jest.runAllTimers(); + wrapper.update(); + wrapper.setState({ visible: true }); + jest.runAllTimers(); + wrapper.update(); + expect(document.getElementsByClassName('.test-input').value).toBeUndefined(); + wrapper.unmount(); + }) it('esc to close', () => { dialog.setState({ visible: true }); From a925939e446d199522d8e95ca3fa82b5e2e77c3d Mon Sep 17 00:00:00 2001 From: Kermit Date: Wed, 26 Aug 2020 23:06:44 +0800 Subject: [PATCH 25/31] fix: click mask to close --- tests/index.spec.js | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/tests/index.spec.js b/tests/index.spec.js index 18e9bc68..ea87d828 100644 --- a/tests/index.spec.js +++ b/tests/index.spec.js @@ -121,23 +121,32 @@ describe('dialog', () => { expect(dialog.find('.rc-dialog-wrap').props().style).toEqual({}); }); - // failed click 没有关闭弹窗 - // it('mask to close', () => { - // dialog.setState({ visible: true }); - // jest.runAllTimers(); - // dialog.update(); - // const mask = dialog.find('.rc-dialog-wrap').first(); - // // mask.props().onClick(); - // mask.simulate('click'); - // jest.runAllTimers(); - // dialog.update(); - // expect(callback).toBe(1); - // expect(dialog.find('.rc-dialog-wrap').props().style).toEqual({}); - // dialog.setState({ visible: true, maskClosable: false }); - // jest.runAllTimers(); - // dialog.update(); - // expect(dialog.find('.rc-dialog-wrap').props().style.display).toEqual(null); - // }); + it('mask to close', () => { + let now = 0; + const originDateNow = Date.now; + + // disable https://github.com/react-component/dialog/blob/d9604fa6ad40e949999456d8c020e47593e48f0d/src/Dialog.tsx#L188 + Date.now = () => { + now += 500 + return now + }; + + dialog.setState({ visible: true }); + jest.runAllTimers(); + dialog.update(); + const mask = dialog.find('.rc-dialog-wrap').first(); + mask.simulate('click'); + jest.runAllTimers(); + dialog.update(); + expect(callback).toBe(1); + expect(dialog.find('.rc-dialog-wrap').props().style).toEqual({}); + dialog.setState({ visible: true, maskClosable: false }); + jest.runAllTimers(); + dialog.update(); + expect(dialog.find('.rc-dialog-wrap').props().style.display).toEqual(null); + + Date.now = originDateNow; + }); it('renderToBody', () => { const d = mount( From e0a7fe1f27375e65e814b827eb8096bc6f876a3a Mon Sep 17 00:00:00 2001 From: Kermit Date: Thu, 27 Aug 2020 10:19:31 +0800 Subject: [PATCH 26/31] fix(test): getContainer --- tests/index.spec.js | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/tests/index.spec.js b/tests/index.spec.js index ea87d828..4bd19bbd 100644 --- a/tests/index.spec.js +++ b/tests/index.spec.js @@ -169,24 +169,19 @@ describe('dialog', () => { expect(d.find('.rc-dialog-wrap').length).toBe(0); }); - // failed parent() 两层获取不到 - // it('getContainer', () => { - // const returnedContainer = document.createElement('div'); - // document.body.appendChild(returnedContainer); - // const d = mount( - // returnedContainer}> - //

Hello world!

- //
- // ); - // d.setState({ visible: true }); - // jest.runAllTimers(); - // d.update(); - // // fix issue #10656, must change this test - // // expect($('.rc-dialog-wrap')[0].parentNode.parentNode).toBe(returnedContainer); - // // expect($('.rc-dialog-wrap')[0].parentNode.parentNode.parentNode).toBe(returnedContainer); - // // expect($('.rc-dialog-wrap')[0].parentNode.parentNode.parentNode).toBe(returnedContainer); - // console.log(d.find('.rc-dialog-wrap').first().parent().parent().props()) - // }); + it('getContainer', () => { + const returnedContainer = document.createElement('div'); + const d = mount( + returnedContainer}> +

Hello world!

+
+ ); + d.setState({ visible: true }); + jest.runAllTimers(); + d.update(); + // fix issue #10656, must change this test + expect(d.find('.rc-dialog-wrap').getDOMNode().parentNode.parentNode.parentNode).toBe(returnedContainer); + }); it('render footer correctly', () => { const d = mount(); From f648048b8d9e7dc9b0ec3398531ef2b5b9de41a8 Mon Sep 17 00:00:00 2001 From: xrkffgg Date: Thu, 27 Aug 2020 10:19:46 +0800 Subject: [PATCH 27/31] fix activeElement --- tests/index.spec.js | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/tests/index.spec.js b/tests/index.spec.js index ea87d828..89858aa3 100644 --- a/tests/index.spec.js +++ b/tests/index.spec.js @@ -195,6 +195,7 @@ describe('dialog', () => { d.update(); expect(d.find('.rc-dialog-footer').length).toBeTruthy(); expect(d.find('.rc-dialog-footer').props().children).toBe('test'); + d.unmount(); }); it('support input autoFocus', () => { @@ -207,23 +208,23 @@ describe('dialog', () => { jest.runAllTimers(); d.update(); expect(document.activeElement).toBe(document.querySelector('input')); + d.unmount(); }); - // failed 激活的不对,可看输出 - // it('trap focus after shift-tabbing', () => { - // dialog.setState({ visible: true }); - // jest.runAllTimers(); - // dialog.update(); - // const shiftTabbingDescriptor = { - // key: 'TAB', - // keyCode: 9, - // which: 9, - // shiftKey: true - // } - // dialog.find('.rc-dialog-wrap').at(0).simulate('keyDown', shiftTabbingDescriptor); - // const sentinelEnd = dialog.find('.rc-dialog-content + div').at(0); - // expect(document.activeElement).toBe(sentinelEnd); - // }); + it('trap focus after shift-tabbing', () => { + dialog.setState({ visible: true }); + jest.runAllTimers(); + dialog.update(); + const shiftTabbingDescriptor = { + key: 'TAB', + keyCode: 9, + which: 9, + shiftKey: true + } + dialog.find('.rc-dialog-wrap').at(0).simulate('keyDown', shiftTabbingDescriptor); + const sentinelEnd = document.querySelectorAll('.rc-dialog-content + div')[0]; + expect(document.activeElement).toBe(sentinelEnd); + }); it('sets transform-origin when property mousePosition is set', () => { const d = mount( From 2f2637ad03bdeb46ab88f42266a0e01969f4c43a Mon Sep 17 00:00:00 2001 From: xrkffgg Date: Thu, 27 Aug 2020 10:35:18 +0800 Subject: [PATCH 28/31] simple tarnsformOrigin --- tests/index.spec.js | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/tests/index.spec.js b/tests/index.spec.js index 6d0cc30f..1a43f648 100644 --- a/tests/index.spec.js +++ b/tests/index.spec.js @@ -229,14 +229,7 @@ describe('dialog', () => { ); jest.runAllTimers(); d.update(); - expect( - d - .find('.rc-dialog') - .at(0) - .html(), - ).toEqual( - '

the dialog

', - ); + expect(d.find('.rc-dialog').at(0).getDOMNode().style['transform-origin']).toBeTruthy(); }); it('can get dom element before dialog first show when forceRender is set true ', () => { From 55e7a844a6a5d2e3afac2362ded725249977f69e Mon Sep 17 00:00:00 2001 From: xrkffgg Date: Thu, 27 Aug 2020 13:30:39 +0800 Subject: [PATCH 29/31] update test --- tests/index.spec.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/index.spec.js b/tests/index.spec.js index 1a43f648..be267faf 100644 --- a/tests/index.spec.js +++ b/tests/index.spec.js @@ -149,10 +149,12 @@ describe('dialog', () => { }); it('renderToBody', () => { + const container = document.createElement('div'); + document.body.appendChild(container); const d = mount(

1

-
, +
, { attachTo: container } ); expect(d.find('.renderToBody').length).toBe(0); expect(d.find('.rc-dialog-wrap').length).toBe(0); @@ -161,9 +163,7 @@ describe('dialog', () => { d.update(); expect(d.find('.rc-dialog-wrap').length).toBeTruthy(); expect(d.find('.renderToBody').length).toBeTruthy(); - // 原来有个这,不知道在测啥??? - // expect($('.rc-dialog-wrap')[0].parentNode.parentNode).not.to.be(container); - // console.log(d.find('.rc-dialog-wrap').first().parent().parent().debug()) + expect(d.find('.rc-dialog-wrap').getDOMNode().parentNode.parentNode).not.toBe(container); d.unmount(); expect(d.find('.renderToBody').length).toBe(0); expect(d.find('.rc-dialog-wrap').length).toBe(0); From 3f701a68fdba0ef78cef6100b5836f536303d1f9 Mon Sep 17 00:00:00 2001 From: xrkffgg Date: Thu, 27 Aug 2020 13:50:32 +0800 Subject: [PATCH 30/31] fix overflow --- tests/index.spec.js | 170 +++++++++++++++++++++++++------------------- 1 file changed, 95 insertions(+), 75 deletions(-) diff --git a/tests/index.spec.js b/tests/index.spec.js index be267faf..7374756b 100644 --- a/tests/index.spec.js +++ b/tests/index.spec.js @@ -181,6 +181,7 @@ describe('dialog', () => { d.update(); // fix issue #10656, must change this test expect(d.find('.rc-dialog-wrap').getDOMNode().parentNode.parentNode.parentNode).toBe(returnedContainer); + d.unmount(); }); it('render footer correctly', () => { @@ -230,6 +231,7 @@ describe('dialog', () => { jest.runAllTimers(); d.update(); expect(d.find('.rc-dialog').at(0).getDOMNode().style['transform-origin']).toBeTruthy(); + d.unmount(); }); it('can get dom element before dialog first show when forceRender is set true ', () => { @@ -239,6 +241,7 @@ describe('dialog', () => {
, ); expect(d.find('.rc-dialog-body > div').props().children).toEqual('forceRender element'); + d.unmount(); }); it('getContainer is false', () => { @@ -254,6 +257,7 @@ describe('dialog', () => { .at(0) .props().style, ).toEqual({}); + d.unmount(); }); it('getContainer is false and visible is true', () => { @@ -264,6 +268,7 @@ describe('dialog', () => { ); expect(d.find('.rc-dialog-body > div').props().children).toEqual('forceRender element'); expect(d.find('.rc-dialog-wrap').props().style.display).toEqual(null); + d.unmount(); }); it('should not close if mouse down in dialog', () => { @@ -277,88 +282,103 @@ describe('dialog', () => { expect(dialog.state().visible).toBe(true); }); - // 感觉是没有渲染到 body 上,所以没有改变 overflow it('Single Dialog body overflow set correctly', () => { + const container = document.createElement('div'); + document.body.appendChild(container); + const d = mount(, { attachTo: container }); document.body.style.overflow = 'scroll'; + d.setState({ visible: true }); + jest.runAllTimers(); + d.update(); + expect(document.body.style.overflow).toBe('hidden'); + d.setState({ visible: false }); + jest.runAllTimers(); + d.update(); + expect(document.body.style.overflow).toBe('scroll'); + d.unmount(); + }); - dialog.setState({ visible: true }); + it('Multiple Dialog body overflow set correctly', () => { + const container = document.createElement('div'); + document.body.style.overflow = "scroll" + + class MultipleDialogWrap extends React.Component { + state = { + visible: false, + visible2: false, + }; + + render() { + return ( +
+ + +
+ ); + } + } + + const d = mount(( + +
forceRender element
+
+ ), { attachTo: container }); + + expect(d.find('.rc-dialog').length).toBe(0); + + d.setState({ visible: true }); jest.runAllTimers(); - dialog.update(); - console.log(document.body.style.overflow); + d.update(); + + expect(d.find('div.rc-dialog').length).toBe(1); + expect(document.body.style.overflow).toBe('hidden'); - dialog.setState({ visible: false }); + d.setState({ visible2: true }); jest.runAllTimers(); - dialog.update(); - }); + d.update(); + + expect(d.find('div.rc-dialog').length).toBe(2); + expect(document.body.style.overflow).toBe('hidden'); + + d.setState({ + visible: false, + visible2: false, + }) + jest.runAllTimers(); + d.update(); - // it('Multiple Dialog body overflow set correctly', () => { - // document.body.style.overflow = "scroll" - - // class MultipleDialogWrap extends React.Component { - // state = { - // visible: false, - // visible2: false, - // }; - - // render() { - // return ( - //
- // - // - //
- // ); - // } - // } - - // const d = ReactDOM.render(( - // - //
forceRender element
- //
- // ),container); - - // expect($('.rc-dialog').length).toBe(0); - - // d.setState({ - // visible: true, - // }) - // expect($('.rc-dialog').length).toBe(1); - // expect(document.body.style.overflow).toBe('hidden'); - - // d.setState({ - // visible2: true, - // }) - // expect($('.rc-dialog').length).toBe(2); - // expect(document.body.style.overflow).toBe('hidden'); - - // d.setState({ - // visible: false, - // visible2: false, - // }) - // expect(document.body.style.overflow).toBe('scroll'); - - // d.setState({ - // visible: true, - // }) - // expect(document.body.style.overflow).toBe('hidden'); - - // d.setState({ - // visible: false, - // visible2: true, - // }) - // expect(document.body.style.overflow).toBe('hidden'); - - // d.setState({ - // visible: false, - // visible2: false, - // }) - // expect(document.body.style.overflow).toBe('scroll'); - // }); + expect(document.body.style.overflow).toBe('scroll'); + + d.setState({ + visible: true, + }) + jest.runAllTimers(); + d.update(); + expect(document.body.style.overflow).toBe('hidden'); + + d.setState({ + visible: false, + visible2: true, + }) + jest.runAllTimers(); + d.update(); + expect(document.body.style.overflow).toBe('hidden'); + + d.setState({ + visible: false, + visible2: false, + }) + jest.runAllTimers(); + d.update(); + expect(document.body.style.overflow).toBe('scroll'); + d.unmount(); + }); it('afterClose', () => { const afterCloseMock = jest.fn(); From 0bcb9d085457ecf0ac0de266faa5950b73329979 Mon Sep 17 00:00:00 2001 From: xrkffgg Date: Thu, 27 Aug 2020 15:29:06 +0800 Subject: [PATCH 31/31] fix eslint --- .eslintrc.js | 2 -- examples/ant-design.tsx | 28 ++++++++++++++-------------- examples/bootstrap.tsx | 2 +- examples/multiple-Portal.tsx | 6 +++--- src/Dialog.tsx | 1 + typings/custom.d.ts | 5 ----- 6 files changed, 19 insertions(+), 25 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 65b14552..54d1afd5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -10,14 +10,12 @@ module.exports = { "@typescript-eslint/no-explicit-any": 0, "@typescript-eslint/no-empty-interface": 0, "@typescript-eslint/no-inferrable-types": 0, - "react/no-find-dom-node": 0, "react/require-default-props": 0, "no-confusing-arrow": 0, "import/no-named-as-default-member": 0, "jsx-a11y/label-has-for": 0, "jsx-a11y/label-has-associated-control": 0, "import/no-extraneous-dependencies": 0, - "react/button-has-type": 0, "jsx-a11y/no-noninteractive-tabindex": 0, "jsx-a11y/no-autofocus": 0, }, diff --git a/examples/ant-design.tsx b/examples/ant-design.tsx index ae7de28e..6e03053c 100644 --- a/examples/ant-design.tsx +++ b/examples/ant-design.tsx @@ -109,15 +109,15 @@ const MyControl = () => { >

basic modal

- - - - +
@@ -132,15 +132,15 @@ const MyControl = () => { >

basic modal

- - - - - + +
@@ -155,12 +155,12 @@ const MyControl = () => { onClose={onClose3} >

initialized with forceRender and visbile true

- - - - + +
@@ -179,7 +179,7 @@ const MyControl = () => { `}

-   diff --git a/examples/bootstrap.tsx b/examples/bootstrap.tsx index c4a52948..03ecdbe8 100644 --- a/examples/bootstrap.tsx +++ b/examples/bootstrap.tsx @@ -115,7 +115,7 @@ const MyControl = () => { return (

- +  

basic modal

-

+

); @@ -38,12 +38,12 @@ const Demo = () => { onClose={onToggleDrawer} level={null} > - + ); return (
- + {dialog} {drawer}
diff --git a/src/Dialog.tsx b/src/Dialog.tsx index 50b3c5b9..485c77d3 100644 --- a/src/Dialog.tsx +++ b/src/Dialog.tsx @@ -114,6 +114,7 @@ export default class Dialog extends React.Component { this.openTime = Date.now(); this.switchScrollingEffect(); this.tryFocus(); + // eslint-disable-next-line react/no-find-dom-node const dialogNode = ReactDOM.findDOMNode(this.dialog); if (mousePosition) { const elOffset = offset(dialogNode); diff --git a/typings/custom.d.ts b/typings/custom.d.ts index d4a32db3..55d05e1a 100644 --- a/typings/custom.d.ts +++ b/typings/custom.d.ts @@ -3,11 +3,6 @@ declare module "rc-util/lib/KeyCode" { export default Ret; } -declare module "rc-util/lib/*" { - const Ret: any; - export default Ret; -} - declare module "rc-animate" { const Ret: any; export default Ret;