collapsible.stories.js 15 KB

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