Skip to content

Commit

Permalink
feat: 新增 <Collapse> 折叠面板组件
Browse files Browse the repository at this point in the history
  • Loading branch information
lijinke666 committed Oct 10, 2018
1 parent c83558d commit ce98d42
Show file tree
Hide file tree
Showing 9 changed files with 250 additions and 3 deletions.
27 changes: 27 additions & 0 deletions components/collapse/Collapse.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from "react";
import cls from "classnames";
import PropTypes from "prop-types";

export default class Collapse extends React.PureComponent {
static defaultProps = {
prefixCls: "cuke-collapse"
};
static propTypes = {
prefixCls: PropTypes.string.isRequired
};
render() {
const { className, prefixCls, children, ...attr } = this.props;

const items = React.Children.map(children, (element, index) => {
return React.cloneElement(element, {
key: index
});
});

return (
<div className={cls(prefixCls, className)} {...attr}>
{items}
</div>
);
}
}
49 changes: 49 additions & 0 deletions components/collapse/CollapseItem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React from "react";
import cls from "classnames";
import PropTypes from "prop-types";
import { ArrowRightIcon } from "../icon";

export default class CollapseItem extends React.PureComponent {
state = {
visible: false
};
static defaultProps = {
prefixCls: "cuke-collapse-item"
};
static propTypes = {
prefixCls: PropTypes.string.isRequired
};
toggleContentPanel = () => {
this.setState({
visible: !this.state.visible
});
};
render() {
const { title, children, className, prefixCls, ...attr } = this.props;
const { visible } = this.state;
return (
<div className={cls(prefixCls, className)} {...attr}>
<div
className={cls(`${prefixCls}-header`)}
onClick={this.toggleContentPanel}
>
<span
className={cls(`${prefixCls}-arrow`, {
[`${prefixCls}-arrow-active`]: visible
})}
>
<ArrowRightIcon />
</span>
{title}
</div>
<div
className={cls(`${prefixCls}-content`, {
[`${prefixCls}-hide`]: !visible
})}
>
{children}
</div>
</div>
);
}
}
74 changes: 74 additions & 0 deletions components/collapse/__tests__/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<Collapse/> should render Collapse 1`] = `
<div
class="cuke-collapse"
>
<div
class="cuke-collapse-item"
>
<div
class="cuke-collapse-item-header"
>
<span
class="cuke-collapse-item-arrow"
>
<svg
attr="[object Object]"
fill="none"
height="1em"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="1em"
>
<polyline
points="9 18 15 12 9 6"
/>
</svg>
</span>
标题1
</div>
<div
class="cuke-collapse-item-content cuke-collapse-item-hide"
>
内容1
</div>
</div>
<div
class="cuke-collapse-item"
>
<div
class="cuke-collapse-item-header"
>
<span
class="cuke-collapse-item-arrow"
>
<svg
attr="[object Object]"
fill="none"
height="1em"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="1em"
>
<polyline
points="9 18 15 12 9 6"
/>
</svg>
</span>
标题2
</div>
<div
class="cuke-collapse-item-content cuke-collapse-item-hide"
>
内容2
</div>
</div>
</div>
`;
27 changes: 27 additions & 0 deletions components/collapse/__tests__/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from "react";
import { render, shallow } from "enzyme";
import assert from "power-assert";
import toJson from "enzyme-to-json";
import Collapse from "../index";

describe("<Collapse/>", () => {
it("should render Collapse", () => {
const wrapper = render(
<Collapse>
<Collapse.Item title="标题1">内容1</Collapse.Item>
<Collapse.Item title="标题2">内容2</Collapse.Item>
</Collapse>
);
expect(toJson(wrapper)).toMatchSnapshot();
});

it("should find cuke-collapse class name", () => {
const wrapper = shallow(
<Collapse>
<Collapse.Item title="标题1">内容1</Collapse.Item>
<Collapse.Item title="标题2">内容2</Collapse.Item>
</Collapse>
);
assert(wrapper.find(".cuke-collapse").length === 1);
});
});
6 changes: 6 additions & 0 deletions components/collapse/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Collapse from "./Collapse";
import CollapseItem from "./CollapseItem";

Collapse.Item = CollapseItem;

export default Collapse;
46 changes: 46 additions & 0 deletions components/collapse/styles.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
@import "../styles/vars.less";


@prefixCls : cuke-collapse;
.@{prefixCls} {
border: 1px solid @border-color;
border-radius: @border-radius;
font-size: @font-size;
box-shadow: @default-shadow;
position: relative;

&-item {
border-bottom: 1px solid @border-color;

&-arrow {
font-size: 16px;
vertical-align: middle;
margin-right: 10px;
svg {
transition: @default-transition;
}
}

&-arrow-active {
svg {
transform: rotate(90deg)
}
}
&-header {
padding: 15px 20px;
cursor: pointer;
color: fade(@font-color,90%);
background-color: @bg-color;
}
&-content {
padding: 20px;
color: @font-color;
overflow: hidden;
transition: all @default-transition;
}

&-hide {
display: none;
}
}
}
4 changes: 3 additions & 1 deletion components/icon/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import {
FiAlertCircle,
FiX,
FiChevronUp,
FiChevronDown
FiChevronDown,
FiChevronRight
} from "react-icons/fi";

export const InfoIcon = props => <FiVolume2 {...props} />;
Expand All @@ -18,3 +19,4 @@ export const WarningIcon = props => <FiAlertCircle {...props} />;
export const CloseIcon = props => <FiX {...props} />;
export const UpIcon = props => <FiChevronUp {...props} />;
export const DownIcon = props => <FiChevronDown {...props} />;
export const ArrowRightIcon = props => <FiChevronRight {...props} />;
5 changes: 3 additions & 2 deletions components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export { default as Modal } from "./modal";
export { default as Spin } from "./spin";
export { default as Tooltip } from "./tooltip";
export { default as Progress } from "./progress";
export { default as backTop } from "./backTop";
export { default as BackTop } from "./backTop";
export { default as Tabs } from "./tabs";
export { default as Badge } from "./badge";
export { default as Dropdown } from "./dropdown";
Expand All @@ -30,6 +30,7 @@ export { default as Checkbox } from "./checkbox";
export { default as Icon } from "./icon";
export { default as Switch } from "./switch";
export { default as Tag } from "./tag";
export { default as cityPicker } from "./cityPicker";
export { default as CityPicker } from "./cityPicker";
export { default as Collapse } from "./collapse";

export { default as version } from "./version";
15 changes: 15 additions & 0 deletions stories/dataDisplay.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ import Tag from "../components/tag";
import CityPicker from "../components/cityPicker";
import { SuccessIcon, InfoIcon } from "../components/icon";
import { withInfo } from "@storybook/addon-info";
import Collapse from "../components/collapse";

import "../components/tooltip/styles.less";
import "../components/button/styles.less";
import "../components/tabs/styles.less";
import "../components/timeline/styles.less";
import "../components/tag/styles.less";
import "../components/cityPicker/styles.less";
import "../components/collapse/styles.less";
import "./styles/dataDisplay.less";
import "./styles/tag.less";

Expand Down Expand Up @@ -461,6 +463,19 @@ storiesOf("数据展示", module)
</div>
))
)
.add(
"Collapse 折叠面板",
withInfo()(() => (
<div>
<h2>基本使用</h2>
<Collapse>
<Collapse.Item title="黄瓜ui">内容1xxxxxxxxxxxxx</Collapse.Item>
<Collapse.Item title="即插即用">内容2xxxxxxxxxxx</Collapse.Item>
<Collapse.Item title="标题3">内容3</Collapse.Item>
</Collapse>
</div>
))
)
.add(
"CityPicker 城市选择框",
withInfo(`
Expand Down

0 comments on commit ce98d42

Please sign in to comment.