diff --git a/.gitignore b/.gitignore index 7e07d527..2e916572 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,7 @@ lib coverage yarn.lock es/ +.prettierrc +.eslintrc.js +tslint.json +tsconfig.json diff --git a/examples/basic.js b/examples/basic.js index dca20674..87b06f55 100644 --- a/examples/basic.js +++ b/examples/basic.js @@ -2,7 +2,6 @@ import 'rc-tree-select/assets/index.less'; import React from 'react'; -import ReactDOM from 'react-dom'; import 'rc-dialog/assets/index.css'; import Dialog from 'rc-dialog'; import TreeSelect, { TreeNode, SHOW_PARENT } from 'rc-tree-select'; @@ -401,4 +400,4 @@ class Demo extends React.Component { } } -ReactDOM.render(, document.getElementById('__react-content')); +export default () => ; diff --git a/examples/big-data.js b/examples/big-data.js index 5dd0fb9c..f42ab409 100644 --- a/examples/big-data.js +++ b/examples/big-data.js @@ -2,7 +2,6 @@ import 'rc-tree-select/assets/index.less'; import React from 'react'; -import ReactDOM from 'react-dom'; import TreeSelect, { SHOW_PARENT } from 'rc-tree-select'; import Gen from './big-data-generator'; import './demo.less'; @@ -83,4 +82,4 @@ class Demo extends React.Component { } } -ReactDOM.render(, document.getElementById('__react-content')); +export default () => ; diff --git a/examples/controlled.js b/examples/controlled.js index 9c3254da..2b368a63 100644 --- a/examples/controlled.js +++ b/examples/controlled.js @@ -2,7 +2,6 @@ import 'rc-tree-select/assets/index.less'; import React from 'react'; -import ReactDOM from 'react-dom'; import 'rc-dialog/assets/index.css'; import TreeSelect, { TreeNode } from 'rc-tree-select'; import './demo.less'; @@ -70,4 +69,4 @@ class Demo extends React.Component { } } -ReactDOM.render(, document.getElementById('__react-content')); +export default () => ; diff --git a/examples/custom-icons.js b/examples/custom-icons.js index 73c9fc99..478ac009 100644 --- a/examples/custom-icons.js +++ b/examples/custom-icons.js @@ -2,13 +2,13 @@ import 'rc-tree-select/assets/index.less'; import React from 'react'; -import ReactDOM from 'react-dom'; import 'rc-dialog/assets/index.css'; import TreeSelect from 'rc-tree-select'; import { gData } from './util'; import './demo.less'; -const bubblePath = 'M632 888H392c-4.4 0-8 3.6-8 8v32c0 ' + +const bubblePath = + 'M632 888H392c-4.4 0-8 3.6-8 8v32c0 ' + '17.7 14.3 32 32 32h192c17.7 0 32-14.3 32-32v-3' + '2c0-4.4-3.6-8-8-8zM512 64c-181.1 0-328 146.9-3' + '28 328 0 121.4 66 227.4 164 284.1V792c0 17.7 1' + @@ -19,13 +19,15 @@ const bubblePath = 'M632 888H392c-4.4 0-8 3.6-8 8v32c0 ' + ' 114.6-256 256-256s256 114.6 256 256c0 92.5-49' + '.4 176.3-128.1 221.8z'; -const clearPath = 'M793 242H366v-74c0-6.7-7.7-10.4-12.9' + +const clearPath = + 'M793 242H366v-74c0-6.7-7.7-10.4-12.9' + '-6.3l-142 112c-4.1 3.2-4.1 9.4 0 12.6l142 112c' + '5.2 4.1 12.9 0.4 12.9-6.3v-74h415v470H175c-4.4' + ' 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h618c35.3 0 64-' + '28.7 64-64V306c0-35.3-28.7-64-64-64z'; -const arrowPath = 'M765.7 486.8L314.9 134.7c-5.3-4.1' + +const arrowPath = + 'M765.7 486.8L314.9 134.7c-5.3-4.1' + '-12.9-0.4-12.9 6.3v77.3c0 4.9 2.3 9.6 6.1 12.6l36' + '0 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6' + '.7 7.7 10.4 12.9 6.3l450.8-352.1c16.4-12.8 16.4-3' + @@ -45,18 +47,21 @@ const getSvg = (path, iStyle = {}, style = {}) => { ); -} - +}; -const switcherIcon = (obj) => { +const switcherIcon = obj => { if (obj.isLeaf) { - return getSvg(arrowPath, + return getSvg( + arrowPath, { cursor: 'pointer', backgroundColor: 'white' }, - { transform: 'rotate(270deg)' }); + { transform: 'rotate(270deg)' }, + ); } - return getSvg(arrowPath, + return getSvg( + arrowPath, { cursor: 'pointer', backgroundColor: 'white' }, - { transform: `rotate(${obj.expanded ? 90 : 0}deg)` }); + { transform: `rotate(${obj.expanded ? 90 : 0}deg)` }, + ); }; const inputIcon = getSvg(bubblePath); @@ -87,7 +92,8 @@ function Demo() { transitionName="rc-tree-select-dropdown-slide-up" style={{ width: 300 }} dropdownStyle={{ maxHeight: 200, overflow: 'auto', zIndex: 1500 }} - showSearch allowClear + showSearch + allowClear {...iconProps} />
@@ -99,11 +105,12 @@ function Demo() { transitionName="rc-tree-select-dropdown-slide-up" style={{ width: 300 }} dropdownStyle={{ maxHeight: 200, overflow: 'auto', zIndex: 1500 }} - showSearch allowClear + showSearch + allowClear {...iconPropsFunction} /> ); } -ReactDOM.render(, document.getElementById('__react-content')); +export default () => ; diff --git a/examples/disable.js b/examples/disable.js index 93e7a9a7..d9e9d062 100644 --- a/examples/disable.js +++ b/examples/disable.js @@ -2,7 +2,6 @@ import 'rc-tree-select/assets/index.less'; import TreeSelect from 'rc-tree-select'; import React from 'react'; -import ReactDOM from 'react-dom'; const SHOW_PARENT = TreeSelect.SHOW_PARENT; @@ -83,4 +82,4 @@ class Demo extends React.Component { } } -ReactDOM.render(, document.getElementById('__react-content')); +export default () => ; diff --git a/examples/dynamic.js b/examples/dynamic.js index 0c9f1620..ed2bd220 100644 --- a/examples/dynamic.js +++ b/examples/dynamic.js @@ -2,7 +2,6 @@ import 'rc-tree-select/assets/index.less'; import React from 'react'; -import ReactDOM from 'react-dom'; import TreeSelect from 'rc-tree-select'; import { getNewTreeData, generateTreeNodes } from './util'; @@ -57,4 +56,4 @@ class Demo extends React.Component { } } -ReactDOM.render(, document.getElementById('__react-content')); +export default () => ; diff --git a/examples/filter.js b/examples/filter.js index 7ba4d7cb..14655ea6 100644 --- a/examples/filter.js +++ b/examples/filter.js @@ -2,7 +2,6 @@ import 'rc-tree-select/assets/index.less'; import React from 'react'; -import ReactDOM from 'react-dom'; import TreeSelect, { SHOW_PARENT } from 'rc-tree-select'; import { gData } from './util'; @@ -103,4 +102,4 @@ class Demo extends React.Component { } } -ReactDOM.render(, document.getElementById('__react-content')); +export default () => ; diff --git a/examples/form.js b/examples/form.js index afebebeb..1fbab731 100644 --- a/examples/form.js +++ b/examples/form.js @@ -2,7 +2,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import ReactDOM from 'react-dom'; import TreeSelect from 'rc-tree-select'; import Select from 'rc-select'; import { createForm } from 'rc-form'; @@ -126,4 +125,4 @@ class Form extends Component { // ReactDOM.render(
, document.getElementById('__react-content')); const NewForm = createForm()(Form); -ReactDOM.render(, document.getElementById('__react-content')); +export default () => ; diff --git a/examples/util.js b/examples/util.js index 7036490a..d021fe9e 100644 --- a/examples/util.js +++ b/examples/util.js @@ -35,7 +35,7 @@ export function generateData(x = 3, y = 2, z = 1, gData = []) { } export function calcTotal(x = 3, y = 2, z = 1) { /* eslint no-param-reassign:0 */ - const rec = (n) => n >= 0 ? x * (y ** (n--)) + rec(n) : 0; + const rec = n => (n >= 0 ? x * y ** n-- + rec(n) : 0); return rec(z + 1); } console.log('总节点数(单个tree):', calcTotal()); @@ -53,9 +53,12 @@ export function generateTreeNodes(treeNode) { function setLeaf(treeData, curKey, level) { const loopLeaf = (data, lev) => { const l = lev - 1; - data.forEach((item) => { - if ((item.key.length > curKey.length) ? item.key.indexOf(curKey) !== 0 : - curKey.indexOf(item.key) !== 0) { + data.forEach(item => { + if ( + item.key.length > curKey.length + ? item.key.indexOf(curKey) !== 0 + : curKey.indexOf(item.key) !== 0 + ) { return; } if (item.children) { @@ -69,9 +72,9 @@ function setLeaf(treeData, curKey, level) { } export function getNewTreeData(treeData, curKey, child, level) { - const loop = (data) => { + const loop = data => { if (level < 1 || curKey.length - 3 > level * 2) return; - data.forEach((item) => { + data.forEach(item => { if (curKey.indexOf(item.key) === 0) { if (item.children) { loop(item.children); @@ -85,7 +88,6 @@ export function getNewTreeData(treeData, curKey, child, level) { setLeaf(treeData, curKey, level); } - function loopData(data, callback) { const loop = (d, level = 0) => { d.forEach((item, index) => { @@ -104,7 +106,7 @@ function isPositionPrefix(smallPos, bigPos) { return false; } // attention: "0-0-1" "0-0-10" - if ((bigPos.length > smallPos.length) && (bigPos.charAt(smallPos.length) !== '-')) { + if (bigPos.length > smallPos.length && bigPos.charAt(smallPos.length) !== '-') { return false; } return bigPos.substr(0, smallPos.length) === smallPos; @@ -123,8 +125,8 @@ export function getFilterValue(val, sVal, delVal) { } }); const newPos = []; - delPos.forEach((item) => { - allPos.forEach((i) => { + delPos.forEach(item => { + allPos.forEach(i => { if (isPositionPrefix(item, i) || isPositionPrefix(i, item)) { // 过滤掉 父级节点 和 所有子节点。 // 因为 node节点 不选时,其 父级节点 和 所有子节点 都不选。 diff --git a/package.json b/package.json index aa98051a..a96ad831 100644 --- a/package.json +++ b/package.json @@ -38,16 +38,18 @@ } }, "scripts": { - "build": "rc-tools run build", + "build": "rc-tools run storybook-build", "compile": "rc-tools run compile --babel-runtime", - "gh-pages": "rc-tools run gh-pages", - "start": "rc-tools run server", + "gh-pages": "npm run build && rc-tools run storybook-gh-pages", + "start": "rc-tools run storybook", "pub": "rc-tools run pub", "lint": "rc-tools run lint", + "init-lint": "rc-tools run gen-lint-config", "test": "rc-tools run test", "coverage": "rc-tools run test --coverage", "pre-commit": "rc-tools run pre-commit", - "lint-staged": "lint-staged" + "lint-staged": "lint-staged", + "genStorybook": "rc-tools run genStorybook" }, "dependencies": { "classnames": "^2.2.1", @@ -67,7 +69,7 @@ "rc-dialog": "^7.0.0", "rc-form": "^2.4.2", "rc-select": "^8.8.3", - "rc-tools": "^9.3.5", + "rc-tools": "^9.3.11", "react": "^16.0.0", "react-dom": "^16.0.0" }, diff --git a/src/Base/BasePopup.jsx b/src/Base/BasePopup.jsx index 9d96b52a..80d4539d 100644 --- a/src/Base/BasePopup.jsx +++ b/src/Base/BasePopup.jsx @@ -20,10 +20,7 @@ class BasePopup extends React.Component { treeIcon: PropTypes.bool, treeLine: PropTypes.bool, treeNodeFilterProp: PropTypes.string, - treeCheckable: PropTypes.oneOfType([ - PropTypes.bool, - PropTypes.node, - ]), + treeCheckable: PropTypes.oneOfType([PropTypes.bool, PropTypes.node]), treeCheckStrictly: PropTypes.bool, treeDefaultExpandAll: PropTypes.bool, treeDefaultExpandedKeys: PropTypes.array, @@ -53,10 +50,7 @@ class BasePopup extends React.Component { constructor(props) { super(); - const { - treeDefaultExpandAll, treeDefaultExpandedKeys, - keyEntities, - } = props; + const { treeDefaultExpandAll, treeDefaultExpandedKeys, keyEntities } = props; // TODO: make `expandedKeyList` control let expandedKeyList = treeDefaultExpandedKeys; @@ -76,8 +70,12 @@ class BasePopup extends React.Component { static getDerivedStateFromProps(nextProps, prevState) { const { prevProps = {}, loadedKeys, expandedKeyList, cachedExpandedKeyList } = prevState || {}; const { - valueList, valueEntities, keyEntities, - treeExpandedKeys, filteredTreeNodes, upperSearchValue + valueList, + valueEntities, + keyEntities, + treeExpandedKeys, + filteredTreeNodes, + upperSearchValue, } = nextProps; const newState = { @@ -123,7 +121,7 @@ class BasePopup extends React.Component { return newState; } - onTreeExpand = (expandedKeyList) => { + onTreeExpand = expandedKeyList => { const { treeExpandedKeys, onTreeExpand, onTreeExpanded } = this.props; // Set uncontrolled state @@ -136,7 +134,7 @@ class BasePopup extends React.Component { } }; - onLoad = (loadedKeys) => { + onLoad = loadedKeys => { this.setState({ loadedKeys }); }; @@ -153,12 +151,12 @@ class BasePopup extends React.Component { * This method pass to Tree component which is used for add filtered class * in TreeNode > li */ - filterTreeNode = (treeNode) => { + filterTreeNode = treeNode => { const { upperSearchValue, treeNodeFilterProp } = this.props; const filterVal = treeNode.props[treeNodeFilterProp]; if (typeof filterVal === 'string') { - return upperSearchValue && (filterVal).toUpperCase().indexOf(upperSearchValue) !== -1; + return upperSearchValue && filterVal.toUpperCase().indexOf(upperSearchValue) !== -1; } return false; @@ -167,29 +165,28 @@ class BasePopup extends React.Component { renderNotFound = () => { const { prefixCls, notFoundContent } = this.props; - return ( - - {notFoundContent} - - ); + return {notFoundContent}; }; render() { const { keyList, expandedKeyList, loadedKeys } = this.state; const { prefixCls, - treeNodes, filteredTreeNodes, - treeIcon, treeLine, treeCheckable, treeCheckStrictly, multiple, + treeNodes, + filteredTreeNodes, + treeIcon, + treeLine, + treeCheckable, + treeCheckStrictly, + multiple, ariaId, renderSearch, switcherIcon, searchHalfCheckedKeys, } = this.props; - const { rcTreeSelect: { - onPopupKeyDown, - onTreeNodeSelect, - onTreeNodeCheck, - } } = this.context; + const { + rcTreeSelect: { onPopupKeyDown, onTreeNodeSelect, onTreeNodeCheck }, + } = this.context; const loadData = this.getLoadData(); @@ -254,12 +251,7 @@ class BasePopup extends React.Component { } return ( -
+
{renderSearch ? renderSearch() : null} {$tree}
diff --git a/src/Base/BaseSelector.jsx b/src/Base/BaseSelector.jsx index ba07d30e..5ba65283 100644 --- a/src/Base/BaseSelector.jsx +++ b/src/Base/BaseSelector.jsx @@ -38,7 +38,7 @@ export const selectorContextTypes = { onSelectorClear: PropTypes.func.isRequired, }; -export default function (modeName) { +export default function(modeName) { class BaseSelector extends React.Component { static propTypes = { ...selectorPropTypes, @@ -57,7 +57,7 @@ export default function (modeName) { static defaultProps = { tabIndex: 0, - } + }; constructor() { super(); @@ -67,7 +67,9 @@ export default function (modeName) { onFocus = (...args) => { const { onFocus, focused } = this.props; - const { rcTreeSelect: { onSelectorFocus } } = this.context; + const { + rcTreeSelect: { onSelectorFocus }, + } = this.context; if (!focused) { onSelectorFocus(); @@ -80,7 +82,9 @@ export default function (modeName) { onBlur = (...args) => { const { onBlur } = this.props; - const { rcTreeSelect: { onSelectorBlur } } = this.context; + const { + rcTreeSelect: { onSelectorBlur }, + } = this.context; // TODO: Not trigger when is inner component get focused onSelectorBlur(); @@ -92,28 +96,27 @@ export default function (modeName) { focus = () => { this.domRef.current.focus(); - } + }; blur = () => { this.domRef.current.focus(); - } + }; renderClear() { const { prefixCls, allowClear, selectorValueList, clearIcon } = this.props; - const { rcTreeSelect: { onSelectorClear } } = this.context; + const { + rcTreeSelect: { onSelectorClear }, + } = this.context; if (!allowClear || !selectorValueList.length || !selectorValueList[0].value) { return null; } return ( - - {typeof clearIcon === 'function' ? - React.createElement(clearIcon, { ...this.props }) : clearIcon} + + {typeof clearIcon === 'function' + ? React.createElement(clearIcon, { ...this.props }) + : clearIcon} ); } @@ -125,27 +128,32 @@ export default function (modeName) { } return ( - - {typeof inputIcon === 'function' ? - React.createElement(inputIcon, { ...this.props }) : inputIcon} + + {typeof inputIcon === 'function' + ? React.createElement(inputIcon, { ...this.props }) + : inputIcon} ); } render() { const { - prefixCls, className, style, - open, focused, disabled, allowClear, + prefixCls, + className, + style, + open, + focused, + disabled, + allowClear, onClick, ariaId, - renderSelection, renderPlaceholder, + renderSelection, + renderPlaceholder, tabIndex, } = this.props; - const { rcTreeSelect: { onSelectorKeyDown } } = this.context; + const { + rcTreeSelect: { onSelectorKeyDown }, + } = this.context; let myTabIndex = tabIndex; if (disabled) { @@ -156,17 +164,13 @@ export default function (modeName) { {renderSelection()} {this.renderClear()} diff --git a/src/Popup/SinglePopup.jsx b/src/Popup/SinglePopup.jsx index 2c0cd7fa..0e6e1914 100644 --- a/src/Popup/SinglePopup.jsx +++ b/src/Popup/SinglePopup.jsx @@ -22,7 +22,7 @@ class SinglePopup extends React.Component { onPlaceholderClick = () => { this.inputRef.current.focus(); - } + }; renderPlaceholder = () => { const { searchPlaceholder, searchValue, prefixCls } = this.props; @@ -63,12 +63,7 @@ class SinglePopup extends React.Component { }; render() { - return ( - - ); + return ; } } diff --git a/src/SearchInput.jsx b/src/SearchInput.jsx index 90954c38..0cb3d5f0 100644 --- a/src/SearchInput.jsx +++ b/src/SearchInput.jsx @@ -56,7 +56,6 @@ class SearchInput extends React.Component { this.focus(); } - if (needAlign && searchValue !== prevProps.searchValue) { this.alignInputWidth(); } @@ -67,14 +66,13 @@ class SearchInput extends React.Component { * ref: https://github.com/react-component/tree-select/issues/65 */ alignInputWidth = () => { - this.inputRef.current.style.width = - `${this.mirrorInputRef.current.clientWidth}px`; + this.inputRef.current.style.width = `${this.mirrorInputRef.current.clientWidth}px`; }; /** * Need additional timeout for focus cause parent dom is not ready when didMount trigger */ - focus = (isDidMount) => { + focus = isDidMount => { if (this.inputRef.current) { this.inputRef.current.focus(); if (isDidMount) { @@ -93,9 +91,9 @@ class SearchInput extends React.Component { render() { const { searchValue, prefixCls, disabled, renderPlaceholder, open, ariaId } = this.props; - const { rcTreeSelect: { - onSearchInputChange, onSearchInputKeyDown, - } } = this.context; + const { + rcTreeSelect: { onSearchInputChange, onSearchInputKeyDown }, + } = this.context; return ( @@ -107,16 +105,12 @@ class SearchInput extends React.Component { value={searchValue} disabled={disabled} className={`${prefixCls}-search__field`} - aria-label="filter select" aria-autocomplete="list" aria-controls={open ? ariaId : undefined} aria-multiline="false" /> - + {searchValue}  diff --git a/src/SelectNode.jsx b/src/SelectNode.jsx index edbefa83..15b2efb9 100644 --- a/src/SelectNode.jsx +++ b/src/SelectNode.jsx @@ -7,9 +7,7 @@ import { valueProp } from './propTypes'; * Let's use SelectNode instead of TreeNode * since TreeNode is so confuse here. */ -const SelectNode = (props) => ( - -); +const SelectNode = props => ; SelectNode.propTypes = { ...TreeNode.propTypes, diff --git a/src/SelectTrigger.jsx b/src/SelectTrigger.jsx index 0eef6305..5324386f 100644 --- a/src/SelectTrigger.jsx +++ b/src/SelectTrigger.jsx @@ -75,10 +75,17 @@ class SelectTrigger extends React.Component { render() { const { - disabled, isMultiple, - dropdownPopupAlign, dropdownMatchSelectWidth, dropdownClassName, - dropdownStyle, onDropdownVisibleChange, getPopupContainer, - dropdownPrefixCls, popupElement, open, + disabled, + isMultiple, + dropdownPopupAlign, + dropdownMatchSelectWidth, + dropdownClassName, + dropdownStyle, + onDropdownVisibleChange, + getPopupContainer, + dropdownPrefixCls, + popupElement, + open, children, } = this.props; @@ -105,13 +112,10 @@ class SelectTrigger extends React.Component { popupVisible={open} getPopupContainer={getPopupContainer} stretch={stretch} - popupClassName={classNames( - dropdownClassName, - { - [`${dropdownPrefixCls}--multiple`]: isMultiple, - [`${dropdownPrefixCls}--single`]: !isMultiple, - }, - )} + popupClassName={classNames(dropdownClassName, { + [`${dropdownPrefixCls}--multiple`]: isMultiple, + [`${dropdownPrefixCls}--single`]: !isMultiple, + })} popupStyle={dropdownStyle} > {children} diff --git a/src/Selector/MultipleSelector/Selection.jsx b/src/Selector/MultipleSelector/Selection.jsx index 556287f4..b2197c71 100644 --- a/src/Selector/MultipleSelector/Selection.jsx +++ b/src/Selector/MultipleSelector/Selection.jsx @@ -1,9 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { - toTitle, - UNSELECTABLE_ATTRIBUTE, UNSELECTABLE_STYLE, -} from '../../util'; +import { toTitle, UNSELECTABLE_ATTRIBUTE, UNSELECTABLE_STYLE } from '../../util'; class Selection extends React.Component { static propTypes = { @@ -16,7 +13,7 @@ class Selection extends React.Component { removeIcon: PropTypes.oneOfType([PropTypes.node, PropTypes.func]), }; - onRemove = (event) => { + onRemove = event => { const { onRemove, value } = this.props; onRemove(event, value); @@ -24,10 +21,7 @@ class Selection extends React.Component { }; render() { - const { - prefixCls, maxTagTextLength, - label, value, onRemove, removeIcon, - } = this.props; + const { prefixCls, maxTagTextLength, label, value, onRemove, removeIcon } = this.props; let content = label || value; if (maxTagTextLength && typeof content === 'string' && content.length > maxTagTextLength) { @@ -42,18 +36,14 @@ class Selection extends React.Component { className={`${prefixCls}-selection__choice`} title={toTitle(label)} > - {onRemove && - - {typeof removeIcon === 'function' ? - React.createElement(removeIcon, { ...this.props }) : removeIcon} + {onRemove && ( + + {typeof removeIcon === 'function' + ? React.createElement(removeIcon, { ...this.props }) + : removeIcon} - } - - {content} - + )} + {content} ); } diff --git a/src/propTypes.js b/src/propTypes.js index 08c66f47..d1f4858c 100644 --- a/src/propTypes.js +++ b/src/propTypes.js @@ -1,16 +1,10 @@ import PropTypes from 'prop-types'; import { isLabelInValue } from './util'; -const internalValProp = PropTypes.oneOfType([ - PropTypes.string, - PropTypes.number, -]); +const internalValProp = PropTypes.oneOfType([PropTypes.string, PropTypes.number]); export function genArrProps(propType) { - return PropTypes.oneOfType([ - propType, - PropTypes.arrayOf(propType), - ]); + return PropTypes.oneOfType([propType, PropTypes.arrayOf(propType)]); } /** @@ -22,14 +16,16 @@ export function valueProp(...args) { const [props, propName, Component] = args; if (isLabelInValue(props)) { - const err = genArrProps(PropTypes.shape({ - label: PropTypes.node, - value: internalValProp, - }))(...args); + const err = genArrProps( + PropTypes.shape({ + label: PropTypes.node, + value: internalValProp, + }), + )(...args); if (err) { return new Error( `Invalid prop \`${propName}\` supplied to \`${Component}\`. ` + - `You should use { label: string, value: string | number } or [{ label: string, value: string | number }] instead.` + `You should use { label: string, value: string | number } or [{ label: string, value: string | number }] instead.`, ); } return null; @@ -39,7 +35,7 @@ export function valueProp(...args) { if (err) { return new Error( `Invalid prop \`${propName}\` supplied to \`${Component}\`. ` + - `You should use string or [string] instead.` + `You should use string or [string] instead.`, ); } return null; diff --git a/storybook/index.js b/storybook/index.js new file mode 100644 index 00000000..aac87207 --- /dev/null +++ b/storybook/index.js @@ -0,0 +1,89 @@ +/* eslint-disable import/no-webpack-loader-syntax */ +import React from 'react'; +import Markdown from 'react-markdown'; +import { checkA11y } from '@storybook/addon-a11y'; +import { storiesOf } from '@storybook/react'; +import { withConsole } from '@storybook/addon-console'; +import { withViewport } from '@storybook/addon-viewport'; +import { withInfo } from '@storybook/addon-info'; +import BasicSource from 'rc-source-loader!../examples/basic'; +import BigDataSource from 'rc-source-loader!../examples/big-data'; +import ControlledSource from 'rc-source-loader!../examples/controlled'; +import CustomIconsSource from 'rc-source-loader!../examples/custom-icons'; +import DisableSource from 'rc-source-loader!../examples/disable'; +import DynamicSource from 'rc-source-loader!../examples/dynamic'; +import FilterSource from 'rc-source-loader!../examples/filter'; +import FormSource from 'rc-source-loader!../examples/form'; +import Basic from '../examples/basic'; +import BigData from '../examples/big-data'; +import Controlled from '../examples/controlled'; +import CustomIcons from '../examples/custom-icons'; +import Disable from '../examples/disable'; +import Dynamic from '../examples/dynamic'; +import Filter from '../examples/filter'; +import Form from '../examples/form'; +import READMECode from '../README.md'; + +storiesOf('rc-tree-select', module) + .addDecorator(checkA11y) + .addDecorator(withInfo) + .addDecorator((storyFn, context) => withConsole()(storyFn)(context)) + .addDecorator(withViewport()) + .add( + 'readMe', + () => ( +
+ +
+ ), + { + source: { + code: READMECode, + }, + }, + ) + .add('basic', () => , { + source: { + code: BasicSource, + }, + }) + .add('big-data', () => , { + source: { + code: BigDataSource, + }, + }) + .add('controlled', () => , { + source: { + code: ControlledSource, + }, + }) + .add('custom-icons', () => , { + source: { + code: CustomIconsSource, + }, + }) + .add('disable', () => , { + source: { + code: DisableSource, + }, + }) + .add('dynamic', () => , { + source: { + code: DynamicSource, + }, + }) + .add('filter', () => , { + source: { + code: FilterSource, + }, + }) + .add('form', () => , { + source: { + code: FormSource, + }, + }); diff --git a/tests/Select.SearchInput.spec.js b/tests/Select.SearchInput.spec.js index 3615f4d0..327f8de7 100644 --- a/tests/Select.SearchInput.spec.js +++ b/tests/Select.SearchInput.spec.js @@ -9,28 +9,27 @@ describe('TreeSelect.SearchInput', () => { resetAriaId(); }); - const createSelect = (props) => { + const createSelect = props => { return mount(
- + -
+
, ); - } + }; describe('click placeholder to get focus', () => { - it('single', (done) => { + it('single', done => { const wrapper = createSelect({ showSearch: true }); setTimeout(() => { // Focus outside - wrapper.find('.pre-focus').instance().focus(); + wrapper + .find('.pre-focus') + .instance() + .focus(); // Click placeholder wrapper.find('.rc-tree-select-search__field__placeholder').simulate('click'); @@ -42,12 +41,15 @@ describe('TreeSelect.SearchInput', () => { }, 10); }); - it('multiple', (done) => { + it('multiple', done => { const wrapper = createSelect({ multiple: true }); setTimeout(() => { // Focus outside - wrapper.find('.pre-focus').instance().focus(); + wrapper + .find('.pre-focus') + .instance() + .focus(); // Click placeholder wrapper.find('.rc-tree-select-search__field__placeholder').simulate('click'); @@ -66,7 +68,7 @@ describe('TreeSelect.SearchInput', () => { const wrapper = mount( - + , ); wrapper.find('.rc-tree-select-search__field').simulate('change', { target: { value: 'test' } }); diff --git a/tests/__mocks__/rc-animate.js b/tests/__mocks__/rc-animate.js index 4021d109..faa32a92 100644 --- a/tests/__mocks__/rc-animate.js +++ b/tests/__mocks__/rc-animate.js @@ -11,6 +11,4 @@ export function setMock(useTransitionMock) { const MockAnimateChild = genAnimateChild(true); const MockAnimate = genAnimate(MockAnimateChild); -export default (props) => ( - mockTransition ? : -); +export default props => (mockTransition ? : ); diff --git a/tests/propTypes.spec.js b/tests/propTypes.spec.js index ae8b33ab..44fa5bd5 100644 --- a/tests/propTypes.spec.js +++ b/tests/propTypes.spec.js @@ -5,40 +5,68 @@ import { valueProp } from '../src/propTypes'; // Use native Type to check the validate. describe('TreeSelect.propTypes', () => { it('warns on invalid value when labelInValue', () => { - const error = valueProp({ - labelInValue: true, - value: 'foo', - }, 'value', 'TreeSelect', '', '', ReactPropTypesSecret); + const error = valueProp( + { + labelInValue: true, + value: 'foo', + }, + 'value', + 'TreeSelect', + '', + '', + ReactPropTypesSecret, + ); expect(error.message).toBe( - 'Invalid prop `value` supplied to `TreeSelect`. You should use { label: string, value: string | number } or [{ label: string, value: string | number }] instead.' + 'Invalid prop `value` supplied to `TreeSelect`. You should use { label: string, value: string | number } or [{ label: string, value: string | number }] instead.', ); }); it('warns on invalid value when treeCheckable and treeCheckStrictly', () => { - const error = valueProp({ - treeCheckable: true, - treeCheckStrictly: true, - value: 'foo', - }, 'value', 'TreeSelect', '', '', ReactPropTypesSecret); + const error = valueProp( + { + treeCheckable: true, + treeCheckStrictly: true, + value: 'foo', + }, + 'value', + 'TreeSelect', + '', + '', + ReactPropTypesSecret, + ); expect(error.message).toBe( - 'Invalid prop `value` supplied to `TreeSelect`. You should use { label: string, value: string | number } or [{ label: string, value: string | number }] instead.' + 'Invalid prop `value` supplied to `TreeSelect`. You should use { label: string, value: string | number } or [{ label: string, value: string | number }] instead.', ); }); it('warns on invalid value when multiple', () => { - const error = valueProp({ - multiple: true, - value: '', - }, 'value', 'TreeSelect', '', '', ReactPropTypesSecret); + const error = valueProp( + { + multiple: true, + value: '', + }, + 'value', + 'TreeSelect', + '', + '', + ReactPropTypesSecret, + ); expect(error).toBeNull(); }); it('warns on invalid value when type is not string', () => { - const error = valueProp({ - value: true, - }, 'value', 'TreeSelect', '', '', ReactPropTypesSecret); + const error = valueProp( + { + value: true, + }, + 'value', + 'TreeSelect', + '', + '', + ReactPropTypesSecret, + ); expect(error.message).toBe( - 'Invalid prop `value` supplied to `TreeSelect`. You should use string or [string] instead.' + 'Invalid prop `value` supplied to `TreeSelect`. You should use string or [string] instead.', ); }); }); diff --git a/tests/setup.js b/tests/setup.js index 7e2e2535..1c6e4cf0 100644 --- a/tests/setup.js +++ b/tests/setup.js @@ -1,7 +1,8 @@ - -global.requestAnimationFrame = global.requestAnimationFrame || function requestAnimationFrame(cb) { - return setTimeout(cb, 0); -}; +global.requestAnimationFrame = + global.requestAnimationFrame || + function requestAnimationFrame(cb) { + return setTimeout(cb, 0); + }; const Enzyme = require('enzyme'); const Adapter = require('enzyme-adapter-react-16'); @@ -15,6 +16,8 @@ Object.assign(Enzyme.ReactWrapper.prototype, { this.update(); }, selectNode(index) { - this.find('.rc-tree-select-tree-node-content-wrapper').at(index).simulate('click'); + this.find('.rc-tree-select-tree-node-content-wrapper') + .at(index) + .simulate('click'); }, }); diff --git a/tests/shared/focusTest.js b/tests/shared/focusTest.js index 10a2cafe..77d740f5 100644 --- a/tests/shared/focusTest.js +++ b/tests/shared/focusTest.js @@ -17,35 +17,22 @@ export default function focusTest(mode) { it('focus()', () => { const handleFocus = jest.fn(); - const treeData = [ - { key: '0', value: '0', title: '0 label' }, - ]; + const treeData = [{ key: '0', value: '0', title: '0 label' }]; const wrapper = mount( - , - { attachTo: container } + , + { attachTo: container }, ); wrapper.instance().focus(); expect(handleFocus).toBeCalled(); }); - it('blur()', () => { const handleBlur = jest.fn(); - const treeData = [ - { key: '0', value: '0', title: '0 label' }, - ]; + const treeData = [{ key: '0', value: '0', title: '0 label' }]; const wrapper = mount( - , - { attachTo: container } + , + { attachTo: container }, ); wrapper.instance().focus(); wrapper.instance().blur(); @@ -54,17 +41,10 @@ export default function focusTest(mode) { it('autoFocus', () => { const handleFocus = jest.fn(); - const treeData = [ - { key: '0', value: '0', title: '0 label' }, - ]; + const treeData = [{ key: '0', value: '0', title: '0 label' }]; mount( - , - { attachTo: container } + , + { attachTo: container }, ); expect(handleFocus).toBeCalled(); });