collapsible.stories.jsx 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590
  1. /* argus-disable unPkgSensitiveInfo */
  2. import React, { useState } from 'react';
  3. import { Button, CheckboxGroup, Upload, Table, Collapse, Tabs } from '../../index';
  4. import Collapsible from '..';
  5. import NestedDemo from './Nested';
  6. import { IconChevronDown, IconChevronRight, IconUpload } from '@douyinfe/semi-icons';
  7. const TabPane = Tabs.TabPane;
  8. export default {
  9. title: 'Collapsible',
  10. }
  11. class Demo extends React.Component {
  12. state = {
  13. isOpen: false,
  14. };
  15. toggle = () => {
  16. this.setState({
  17. isOpen: !this.state.isOpen,
  18. });
  19. };
  20. render() {
  21. const { isOpen } = this.state;
  22. const collapsed = (
  23. <ul>
  24. <li>
  25. <p>Semi Design 以内容优先进行设计。</p>
  26. </li>
  27. <li>
  28. <p>更容易地自定义主题。</p>
  29. </li>
  30. <li>
  31. <p>适用国际化场景。</p>
  32. </li>
  33. <li>
  34. <p>效率场景加入人性化关怀。</p>
  35. </li>
  36. </ul>
  37. );
  38. return (
  39. <div>
  40. <Button onClick={() => this.toggle()}>显示更多</Button>
  41. <Collapsible isOpen={isOpen}>{collapsed}</Collapsible>
  42. </div>
  43. );
  44. }
  45. }
  46. export const RegularCollapsible = () => <Demo />;
  47. class DemoDOM extends React.Component {
  48. state = {
  49. isOpen: false,
  50. };
  51. toggle = () => {
  52. this.setState({
  53. isOpen: !this.state.isOpen,
  54. });
  55. };
  56. render() {
  57. const { isOpen } = this.state;
  58. const collapsed = (
  59. <ul>
  60. <li>
  61. <p>Semi Design 以内容优先进行设计。</p>
  62. </li>
  63. <li>
  64. <p>更容易地自定义主题。</p>
  65. </li>
  66. <li>
  67. <p>适用国际化场景。</p>
  68. </li>
  69. <li>
  70. <p>效率场景加入人性化关怀。</p>
  71. </li>
  72. </ul>
  73. );
  74. return (
  75. <div>
  76. <Button onClick={() => this.toggle()}>显示更多</Button>
  77. <Collapsible keepDOM lazyRender={!!this.props.lazyRender} isOpen={isOpen}>
  78. {collapsed}
  79. </Collapsible>
  80. </div>
  81. );
  82. }
  83. }
  84. export const KeepDom = () => <DemoDOM />;
  85. export const LazyRender = () => <DemoDOM lazyRender={true} />;
  86. class DefaultOpen extends React.Component {
  87. state = {
  88. isOpen: true,
  89. };
  90. toggle = () => {
  91. this.setState({
  92. isOpen: !this.state.isOpen,
  93. });
  94. };
  95. render() {
  96. const { isOpen } = this.state;
  97. const collapsed = (
  98. <ul>
  99. <li>
  100. <p>Semi Design 以内容优先进行设计。</p>
  101. </li>
  102. <li>
  103. <p>更容易地自定义主题。</p>
  104. </li>
  105. <li>
  106. <p>适用国际化场景。</p>
  107. </li>
  108. <li>
  109. <p>效率场景加入人性化关怀。</p>
  110. </li>
  111. </ul>
  112. );
  113. return (
  114. <div>
  115. <Button onClick={() => this.toggle()}>toggle</Button>
  116. <Collapsible isOpen={isOpen}>{collapsed}</Collapsible>
  117. </div>
  118. );
  119. }
  120. }
  121. export const DefaultOpenDemo = () => <DefaultOpen />;
  122. export const NestedCollapsible = () => <NestedDemo />;
  123. class Wrap extends React.Component {
  124. constructor(props) {
  125. super(props);
  126. this.state = {
  127. isOpen: props.isOpen,
  128. options: [
  129. {
  130. label: '抖音',
  131. value: 'dy',
  132. },
  133. {
  134. label: '火山',
  135. value: 'hotsoon',
  136. },
  137. {
  138. label: '皮皮虾',
  139. value: 'pipixia',
  140. },
  141. {
  142. label: '今日头条',
  143. value: 'toutiao',
  144. },
  145. ],
  146. values: [],
  147. };
  148. this.toggle = this.toggle.bind(this);
  149. this.onChange = this.onChange.bind(this);
  150. }
  151. toggle() {
  152. this.setState({
  153. isOpen: !this.state.isOpen,
  154. });
  155. }
  156. onChange(values) {
  157. this.setState({
  158. values,
  159. });
  160. }
  161. render() {
  162. const { isOpen, options, values } = this.state;
  163. return (
  164. <>
  165. <div onClick={this.toggle}>
  166. {isOpen ? <IconChevronDown /> : <IconChevronRight />}
  167. 权限点
  168. <span>
  169. {values.length}/{options.length}
  170. </span>
  171. </div>
  172. <Collapse defaultActiveKey="1" motion={false}>
  173. <Collapse.Panel header="This is panel header 1" itemKey="1">
  174. <p>Hi, bytedance dance dance. This is the docsite of Semi UI. </p>
  175. </Collapse.Panel>
  176. <Collapse.Panel header="This is panel header 2" itemKey="2">
  177. <p>Hi, bytedance dance dance. This is the docsite of Semi UI. </p>
  178. </Collapse.Panel>
  179. <Collapse.Panel header="This is panel header 3" itemKey="3">
  180. <p>Hi, bytedance dance dance. This is the docsite of Semi UI. </p>
  181. </Collapse.Panel>
  182. </Collapse>
  183. {/* <Collapsible isOpen={isOpen}>
  184. <div style={{ height: '40px' }}>
  185. <CheckboxGroup options={options} direction="horizontal" onChange={this.onChange} value={values} />
  186. </div>
  187. </Collapsible> */}
  188. </>
  189. );
  190. }
  191. }
  192. export const CollapsibleTest = () => <Wrap />;
  193. class App extends React.Component {
  194. render() {
  195. const expandColumns = [
  196. {
  197. title: 'Name',
  198. dataIndex: 'name',
  199. key: 'name',
  200. },
  201. {
  202. title: 'Age',
  203. dataIndex: 'age',
  204. key: 'age',
  205. },
  206. {
  207. title: 'Address',
  208. dataIndex: 'address',
  209. key: 'address',
  210. },
  211. {
  212. title: 'Action',
  213. dataIndex: '',
  214. key: 'x',
  215. render: () => <a>Delete</a>,
  216. },
  217. ];
  218. const rowSelection = {
  219. onChange: (selectedRowKeys, selectedRows) => {
  220. // console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
  221. },
  222. getCheckboxProps: record => ({
  223. disabled: record.name === 'Michael James',
  224. // Column configuration not to be checked
  225. name: record.name,
  226. }),
  227. };
  228. const expandData = [
  229. {
  230. name: 'John Brown',
  231. age: 32,
  232. address: 'New York No. 1 Lake Park',
  233. description:
  234. 'My name is John Brown, I am 32 years old, living in New York No. 1 Lake Park.',
  235. },
  236. {
  237. name: 'Jim Green',
  238. age: 42,
  239. address: 'London No. 1 Lake Park',
  240. description: 'My name is Jim Green, I am 42 years old, living in London No. 1 Lake Park.',
  241. },
  242. {
  243. name: 'Joe Black',
  244. age: 32,
  245. address: (
  246. <Collapse defaultActiveKey="1" motion={false}>
  247. <Collapse.Panel header="This is panel header 1" itemKey="1">
  248. <p>Hi, bytedance dance dance. This is the docsite of Semi UI. </p>
  249. </Collapse.Panel>
  250. <Collapse.Panel header="This is panel header 2" itemKey="2">
  251. <p>Hi, bytedance dance dance. This is the docsite of Semi UI. </p>
  252. </Collapse.Panel>
  253. <Collapse.Panel header="This is panel header 3" itemKey="3">
  254. <p>Hi, bytedance dance dance. This is the docsite of Semi UI. </p>
  255. </Collapse.Panel>
  256. </Collapse>
  257. ),
  258. description: 'My name is Joe Black, I am 32 years old, living in Sidney No. 1 Lake Park.',
  259. },
  260. ];
  261. const expandRowRender = (record, index) => <Wrap isOpen={true} />;
  262. return (
  263. <Table
  264. rowKey={'name'}
  265. columns={expandColumns}
  266. rowSelection={rowSelection}
  267. expandedRowRender={expandRowRender}
  268. dataSource={expandData}
  269. />
  270. );
  271. }
  272. }
  273. export const CollapsibleInTable = () => <App />;
  274. class InTab extends React.Component {
  275. constructor() {
  276. super();
  277. this.state = {
  278. isOpenFirst: false,
  279. isOpenSecond: false,
  280. };
  281. }
  282. render() {
  283. const { isOpenFirst, isOpenSecond } = this.state;
  284. return (
  285. <div>
  286. <Tabs
  287. onTabClick={e =>
  288. this.setState({
  289. active: e,
  290. })
  291. }
  292. >
  293. <TabPane tab="第一" itemKey="1">
  294. <h3>第一个tabpane</h3>
  295. <Button
  296. onClick={() => {
  297. this.setState({
  298. isOpenFirst: !isOpenFirst,
  299. });
  300. }}
  301. >
  302. 开关
  303. </Button>
  304. <Collapsible isOpen={isOpenFirst}>
  305. 第一个tabpane下的collapsible的open状态正常
  306. </Collapsible>
  307. </TabPane>
  308. <TabPane tab="第二" itemKey="2">
  309. <h3>第二个tabpane</h3>
  310. <Button
  311. onClick={() => {
  312. this.setState({
  313. isOpenSecond: !isOpenSecond,
  314. });
  315. }}
  316. >
  317. 开关
  318. </Button>
  319. <Collapsible isOpen={isOpenSecond}>
  320. 第二个tabpane下的collapsibleopen状态异常
  321. </Collapsible>
  322. </TabPane>
  323. </Tabs>
  324. </div>
  325. );
  326. }
  327. }
  328. export const CollapsibleInTab = () => <InTab />;
  329. CollapsibleInTab.story = {
  330. name: 'collapsible in tab',
  331. };
  332. class WithUpload extends React.Component {
  333. constructor(props) {
  334. super(props);
  335. this.state = {
  336. isOpen: true,
  337. };
  338. this.toggle = this.toggle.bind(this);
  339. this.action = '//semi.design/api/upload/';
  340. this.defaultFileList = [
  341. {
  342. preview: false,
  343. name: '2D (2).ecpj',
  344. status: 'success',
  345. uid: 'd116a179410eb0ca18e66074509bde93-0',
  346. url:
  347. 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/bag.jpeg',
  348. },
  349. {
  350. preview: false,
  351. name: '2D-sticker-temp.psd',
  352. status: 'success',
  353. uid: 'b7d579069320590ba4b128672eedbae2-1',
  354. url:
  355. 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/bag.jpeg',
  356. },
  357. {
  358. preview: false,
  359. name: '2D-sticker-temp (1).psd',
  360. status: 'success',
  361. uid: 'b7d579069320590ba4b128672eedbae2-2',
  362. url:
  363. 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/bag.jpeg',
  364. },
  365. ];
  366. }
  367. toggle() {
  368. this.setState({
  369. isOpen: !this.state.isOpen,
  370. });
  371. }
  372. render() {
  373. const { isOpen } = this.state;
  374. return (
  375. <div>
  376. <Collapsible isOpen={isOpen} collapseHeight={120}>
  377. <Upload
  378. dragable={true}
  379. name="file" // accept={ALLOW_FILE}
  380. defaultFileList={[
  381. {
  382. preview: false,
  383. name: '2D (2).ecpj',
  384. status: 'success',
  385. uid: 'd116a179410eb0ca18e66074509bde93-0',
  386. url:
  387. 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/bag.jpeg',
  388. },
  389. {
  390. preview: false,
  391. name: '2D-sticker-temp.psd',
  392. status: 'success',
  393. uid: 'b7d579069320590ba4b128672eedbae2-1',
  394. url:
  395. 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/bag.jpeg',
  396. },
  397. {
  398. preview: false,
  399. name: '2D-sticker-temp (1).psd',
  400. status: 'success',
  401. uid: 'b7d579069320590ba4b128672eedbae2-2',
  402. url:
  403. 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/bag.jpeg',
  404. },
  405. ]}
  406. dragMainText="点击上传文件或拖拽文件到这里"
  407. dragSubText="图片、PDF、PPT、Word、视频等"
  408. onError={this.uploadError}
  409. onSuccess={(...args) => this.uploadSuccess(i, ...args)}
  410. onRemove={(...args) => this.onRemoveFile(i, ...args)}
  411. onProgress={() =>
  412. this.setState({
  413. fileLoading: true,
  414. })
  415. }
  416. >
  417. <Button icon={<IconUpload />} theme="light">
  418. 点击上传
  419. </Button>
  420. </Upload>
  421. </Collapsible>
  422. <Button onClick={this.toggle}>{isOpen ? '剩余1项' : '展开'}</Button>
  423. </div>
  424. );
  425. }
  426. }
  427. export const CollapsibleWithUpload = () => <WithUpload />;
  428. class CusHeight extends React.Component {
  429. constructor(props) {
  430. super(props);
  431. this.state = {
  432. isOpen: false,
  433. };
  434. this.toggle = this.toggle.bind(this);
  435. }
  436. toggle() {
  437. this.setState({
  438. isOpen: !this.state.isOpen,
  439. });
  440. }
  441. render() {
  442. const { isOpen } = this.state;
  443. const maskStyle = isOpen
  444. ? {}
  445. : {
  446. WebkitMaskImage:
  447. 'linear-gradient(to bottom, black 0%, rgba(0, 0, 0, 1) 60%, rgba(0, 0, 0, 0.2) 80%, transparent 100%)',
  448. };
  449. const collapsed = (
  450. <ul>
  451. <li>
  452. <p>Semi Design 以内容优先进行设计。</p>
  453. </li>
  454. <li>
  455. <p>更容易地自定义主题。</p>
  456. </li>
  457. <li>
  458. <p>适用国际化场景。</p>
  459. </li>
  460. <li>
  461. <p>效率场景加入人性化关怀。</p>
  462. </li>
  463. </ul>
  464. );
  465. const linkStyle = {
  466. position: 'absolute',
  467. left: 0,
  468. right: 0,
  469. textAlign: 'center',
  470. bottom: -10,
  471. fontWeight: 700,
  472. cursor: 'pointer',
  473. };
  474. console.log('out state', isOpen);
  475. return (
  476. <>
  477. <Button onClick={this.toggle}>Toggle</Button>
  478. <div
  479. style={{
  480. position: 'relative',
  481. }}
  482. >
  483. <Collapsible
  484. isOpen={isOpen}
  485. collapseHeight={40}
  486. style={{ ...maskStyle }}
  487. onInnerStateOpen={bool => {
  488. if (isOpen !== bool) {
  489. this.setState({
  490. isOpen: bool,
  491. });
  492. }
  493. }}
  494. >
  495. {collapsed}
  496. </Collapsible>
  497. {isOpen ? null : (
  498. <a onClick={this.toggle} style={{ ...linkStyle }}>
  499. + Show More
  500. </a>
  501. )}
  502. </div>
  503. </>
  504. );
  505. }
  506. }
  507. export const CollapseHeight = () => <CusHeight />;
  508. const Child = ({ onClick }) => {
  509. const [isCOpen, setIsCOpen] = useState(false);
  510. return (
  511. <div>
  512. <div
  513. style={{
  514. display: isCOpen ? 'block' : 'none',
  515. height: 200,
  516. background: 'green',
  517. }}
  518. >
  519. child
  520. </div>
  521. <Button
  522. onClick={() => {
  523. setIsCOpen(!isCOpen);
  524. onClick();
  525. }}
  526. >
  527. Toggle
  528. </Button>
  529. </div>
  530. );
  531. }; // dynamic update content, children comp need to separate from parent to avoid rerender of entire comp
  532. const DynamDemo = () => {
  533. const [isOpen, setIsOpen] = useState(true);
  534. const [reCalcKey, setReCalcKey] = useState(0);
  535. return (
  536. <div>
  537. <Button onClick={() => setIsOpen(!isOpen)}>折叠</Button>
  538. <Collapsible isOpen={isOpen}>
  539. <div>
  540. <div
  541. style={{
  542. height: 200,
  543. background: 'blue',
  544. }}
  545. >
  546. father
  547. </div>
  548. <Child onClick={() => setReCalcKey(reCalcKey + 1)} />
  549. </div>
  550. </Collapsible>
  551. </div>
  552. );
  553. };
  554. export const DynamicCollapsible = () => <DynamDemo />;