popover.stories.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. import React, { useState } from 'react';
  2. import Popover from '../index';
  3. import { strings } from '@douyinfe/semi-foundation/tooltip/constants';
  4. import { Button, Input, Table, IconButton, Modal, Tag } from '@douyinfe/semi-ui';
  5. import SelectInPopover from './SelectInPopover';
  6. import BtnClose from './BtnClose';
  7. import PopRight from './PopRight';
  8. import NestedPopover from './NestedPopover';
  9. import ArrowPointAtCenter from './ArrowPointAtCenter';
  10. import { IconDelete } from '@douyinfe/semi-icons';
  11. export default {
  12. title: 'Popover',
  13. parameters: {
  14. chromatic: { disableSnapshot: true },
  15. },
  16. }
  17. let style = {
  18. display: 'inline-block',
  19. padding: '20px',
  20. };
  21. export const _Popover = () => (
  22. <div>
  23. <div style={style}>
  24. <Popover content="ies vigo" title="bytedance" position="bottom" visible={true} showArrow>
  25. bottom hover
  26. </Popover>
  27. </div>
  28. <div style={style}>
  29. <Popover content="ies vigo" title="bytedance" trigger="click" position="bottom">
  30. bottom click
  31. </Popover>
  32. </div>
  33. <div style={style}>
  34. <Popover content="ies vigo" title="bytedance" trigger="click" position="right">
  35. <Button>Pos:right, trigger: Click</Button>
  36. </Popover>
  37. </div>
  38. <div style={style}>
  39. <Popover
  40. content={<Button type="warning">btn</Button>}
  41. title="bytedance"
  42. trigger="click"
  43. position="right"
  44. >
  45. content is Node
  46. </Popover>
  47. </div>
  48. <div style={style}>
  49. <Popover content={<Input />} title="bytedance" trigger="click" position="right">
  50. content is Node
  51. </Popover>
  52. </div>
  53. </div>
  54. );
  55. _Popover.story = {
  56. name: 'popover',
  57. };
  58. export const Positions = () => (
  59. <div
  60. style={{
  61. width: 480,
  62. height: 360,
  63. boxSizing: 'content-box',
  64. padding: '150px 50px',
  65. display: 'flex',
  66. flexWrap: 'wrap',
  67. justifyContent: 'space-evenly',
  68. }}
  69. >
  70. {strings.POSITION_SET.map(pos => (
  71. <Popover
  72. key={pos}
  73. content={
  74. <div
  75. style={{
  76. padding: 20,
  77. }}
  78. >
  79. <p>Hi Bytedancer!</p>
  80. </div>
  81. }
  82. trigger="click"
  83. position={pos}
  84. >
  85. <Button key={pos}>{pos}</Button>
  86. </Popover>
  87. ))}
  88. </div>
  89. );
  90. Positions.story = {
  91. name: 'positions',
  92. };
  93. export const PopConfirm = () => (
  94. <div>
  95. <div style={style}>
  96. <Popover isConfirmMode content="hi byteddance ies">
  97. <a>IconDelete</a>
  98. </Popover>
  99. </div>
  100. </div>
  101. );
  102. PopConfirm.story = {
  103. name: 'popConfirm',
  104. };
  105. class Demo extends React.Component {
  106. constructor(props) {
  107. super(props);
  108. this.state = {
  109. visible: false,
  110. };
  111. this.changeVisible = this.changeVisible.bind(this);
  112. this.renderContent = this.renderContent.bind(this);
  113. }
  114. changeVisible(visible = true) {
  115. this.setState({
  116. visible,
  117. });
  118. }
  119. renderContent() {
  120. return (
  121. <>
  122. <p>hi byteddance ies</p>
  123. <Button onClick={() => this.changeVisible(false)}>cancel</Button>
  124. <Button onClick={() => this.changeVisible(false)}>confirm</Button>
  125. </>
  126. );
  127. }
  128. render() {
  129. const content = this.renderContent();
  130. const { visible } = this.state;
  131. return (
  132. <Popover trigger="custom" content={content} visible={visible} position="bottomLeft">
  133. <Button onClick={() => this.changeVisible(true)}>show Popover</Button>
  134. </Popover>
  135. );
  136. }
  137. }
  138. export const PopoverCustomVisible = () => <Demo />;
  139. PopoverCustomVisible.story = {
  140. name: 'popover custom visible',
  141. };
  142. CompositeComponent.story = { name: '复合组件' };
  143. export function CompositeComponent() {
  144. class TableApp extends React.Component {
  145. constructor(props) {
  146. super(props);
  147. this.raw = [
  148. {
  149. key: '1',
  150. name: 'John Brown',
  151. age: 32,
  152. address: 'New York No. 1 Lake Park, New York No. 1 Lake Park',
  153. },
  154. {
  155. key: '2',
  156. name: 'Jim Green',
  157. age: 42,
  158. address: 'London No. 1 Lake Park',
  159. },
  160. {
  161. key: '3',
  162. name: 'Joe Black',
  163. age: 32,
  164. address: 'Sidney No. 1 Lake Park',
  165. },
  166. {
  167. key: '4',
  168. name: 'Disabled User',
  169. age: 99,
  170. address: 'Sidney No. 1 Lake Park',
  171. },
  172. ];
  173. this.state = {
  174. dataSource: [...this.raw],
  175. modalVisible: false,
  176. columns: [
  177. {
  178. title: 'Name',
  179. dataIndex: 'name',
  180. render: text => <a href="javascript:;">{text}</a>,
  181. },
  182. {
  183. title: 'Age',
  184. dataIndex: 'age',
  185. },
  186. {
  187. title: 'Address',
  188. dataIndex: 'address',
  189. },
  190. {
  191. title: 'Operation',
  192. render: (text, record) => (
  193. <div>
  194. <Button icon={<IconDelete />} onClick={() => this.removeRecord(record.key)} />
  195. <Button onClick={() => this.toggleModal(true)}>编辑</Button>
  196. </div>
  197. ),
  198. },
  199. ],
  200. };
  201. }
  202. removeRecord(key) {
  203. let dataSource = [...this.state.dataSource];
  204. if (key != null) {
  205. let idx = dataSource.findIndex(data => data.key === key); // console.log(key, dataSource, idx);
  206. if (idx > -1) {
  207. dataSource.splice(idx, 1);
  208. this.setState({
  209. dataSource,
  210. });
  211. }
  212. }
  213. }
  214. resetData() {
  215. let dataSource = [...this.raw];
  216. this.setState({
  217. dataSource,
  218. });
  219. }
  220. toggleModal = modalVisible => {
  221. this.setState({
  222. modalVisible,
  223. });
  224. };
  225. renderModalContent = () => {
  226. const { modalVisible } = this.state;
  227. return (
  228. <Modal
  229. visible={modalVisible}
  230. onCancel={() => this.toggleModal(false)}
  231. onOk={() => this.toggleModal(false)}
  232. >
  233. <p>This is a modal with customized styles.</p>
  234. <p>More content...</p>
  235. <Popover
  236. content={
  237. <div>
  238. <Button>按钮1</Button>
  239. <Button>按钮2</Button>
  240. </div>
  241. }
  242. >
  243. <Button>hover</Button>
  244. </Popover>
  245. </Modal>
  246. );
  247. };
  248. render() {
  249. let { columns, dataSource } = this.state;
  250. return (
  251. <>
  252. <Button onClick={() => this.resetData()}>Reset</Button>
  253. <Table columns={columns} dataSource={dataSource} pagination={false} />
  254. {this.renderModalContent()}
  255. </>
  256. );
  257. }
  258. }
  259. return <TableApp />;
  260. };
  261. const ScrollDemo = function ScrollDemo(props = {}) {
  262. const tops = [
  263. ['topLeft', 'TL'],
  264. ['top', 'Top'],
  265. ['topRight', 'TR'],
  266. ];
  267. const lefts = [
  268. ['leftTop', 'LT'],
  269. ['left', 'Left'],
  270. ['leftBottom', 'LB'],
  271. ];
  272. const rights = [
  273. ['rightTop', 'RT'],
  274. ['right', 'Right'],
  275. ['rightBottom', 'RB'],
  276. ];
  277. const bottoms = [
  278. ['bottomLeft', 'BL'],
  279. ['bottom', 'Bottom'],
  280. ['bottomRight', 'BR'],
  281. ];
  282. const { tagstyle, ...restProps } = props;
  283. return (
  284. <div
  285. style={{
  286. paddingLeft: 40,
  287. }}
  288. >
  289. <div
  290. style={{
  291. marginLeft: 40,
  292. whiteSpace: 'nowrap',
  293. }}
  294. >
  295. {tops.map((pos, index) => (
  296. <Popover
  297. content={
  298. <article>
  299. <p>hi bytedance</p>
  300. <p>hi bytedance</p>
  301. </article>
  302. }
  303. position={Array.isArray(pos) ? pos[0] : pos}
  304. key={index}
  305. trigger={'click'}
  306. {...restProps}
  307. >
  308. <Tag style={tagstyle}>{Array.isArray(pos) ? pos[1] : pos}</Tag>
  309. </Popover>
  310. ))}
  311. </div>
  312. <div
  313. style={{
  314. width: 40,
  315. float: 'left',
  316. }}
  317. >
  318. {lefts.map((pos, index) => (
  319. <Popover
  320. content={
  321. <article>
  322. <p>hi bytedance</p>
  323. <p>hi bytedance</p>
  324. </article>
  325. }
  326. position={Array.isArray(pos) ? pos[0] : pos}
  327. key={index}
  328. trigger={'click'}
  329. {...restProps}
  330. >
  331. <Tag style={tagstyle}>{Array.isArray(pos) ? pos[1] : pos}</Tag>
  332. </Popover>
  333. ))}
  334. </div>
  335. <div
  336. style={{
  337. width: 40,
  338. marginLeft: 180,
  339. }}
  340. >
  341. {rights.map((pos, index) => (
  342. <Popover
  343. content={
  344. <article>
  345. <p>hi bytedance</p>
  346. <p>hi bytedance</p>
  347. </article>
  348. }
  349. position={Array.isArray(pos) ? pos[0] : pos}
  350. key={index}
  351. trigger={'click'}
  352. {...restProps}
  353. >
  354. <Tag style={tagstyle}>{Array.isArray(pos) ? pos[1] : pos}</Tag>
  355. </Popover>
  356. ))}
  357. </div>
  358. <div
  359. style={{
  360. marginLeft: 40,
  361. clear: 'both',
  362. whiteSpace: 'nowrap',
  363. }}
  364. >
  365. {bottoms.map((pos, index) => (
  366. <Popover
  367. content={
  368. <article>
  369. <p>hi bytedance</p>
  370. <p>hi bytedance</p>
  371. </article>
  372. }
  373. position={Array.isArray(pos) ? pos[0] : pos}
  374. key={index}
  375. trigger={'click'}
  376. {...restProps}
  377. >
  378. <Tag style={tagstyle}>{Array.isArray(pos) ? pos[1] : pos}</Tag>
  379. </Popover>
  380. ))}
  381. </div>
  382. </div>
  383. );
  384. };
  385. export const ScrollPopover = () => {
  386. return (
  387. <>
  388. <div id="wrapper">
  389. <div
  390. style={{
  391. height: '200vh',
  392. width: '200vw',
  393. padding: 50,
  394. }}
  395. >
  396. 滚动到下面
  397. </div>
  398. </div>
  399. <div
  400. style={{
  401. padding: 1200,
  402. }}
  403. >
  404. <ScrollDemo
  405. content={
  406. <article
  407. style={{
  408. padding: 12,
  409. }}
  410. >
  411. <p>hi bytedance</p>
  412. <p>hi bytedance</p>
  413. </article>
  414. }
  415. />
  416. </div>
  417. </>
  418. );
  419. };
  420. ScrollPopover.story = {
  421. name: 'scroll popover',
  422. };
  423. export const WithArrow = () => (
  424. <div>
  425. <div
  426. style={{
  427. padding: 120,
  428. }}
  429. >
  430. <ScrollDemo showArrow />
  431. </div>
  432. <div
  433. style={{
  434. padding: 120,
  435. }}
  436. >
  437. <ScrollDemo
  438. showArrow
  439. tagstyle={{
  440. minHeight: 80,
  441. minWidth: 120,
  442. }}
  443. />
  444. </div>
  445. <div
  446. style={{
  447. padding: 120,
  448. }}
  449. >
  450. <ScrollDemo
  451. showArrow
  452. tagstyle={{
  453. minHeight: 80,
  454. minWidth: 120,
  455. }}
  456. style={{
  457. backgroundColor: 'green',
  458. }}
  459. />
  460. </div>
  461. </div>
  462. );
  463. WithArrow.story = {
  464. name: 'with arrow',
  465. };
  466. export const NoContent = () => (
  467. <div>
  468. <div
  469. style={{
  470. padding: 50,
  471. }}
  472. >
  473. <ScrollDemo content={<div></div>} />
  474. </div>
  475. <div
  476. style={{
  477. padding: 50,
  478. }}
  479. >
  480. <ScrollDemo showArrow content={''} />
  481. </div>
  482. <div
  483. style={{
  484. padding: 50,
  485. }}
  486. >
  487. <ScrollDemo
  488. showArrow
  489. content={''}
  490. tagstyle={{
  491. height: 80,
  492. minWidth: 100,
  493. }}
  494. style={{
  495. padding: 20,
  496. }}
  497. />
  498. </div>
  499. </div>
  500. );
  501. NoContent.story = {
  502. name: 'no content',
  503. };
  504. export const _SelectInPopover = () => (
  505. <div
  506. style={{
  507. padding: 50,
  508. }}
  509. >
  510. <SelectInPopover />
  511. </div>
  512. );
  513. _SelectInPopover.story = {
  514. name: 'select in popover',
  515. };
  516. export const CloseBtnInPopover = () => <BtnClose />;
  517. CloseBtnInPopover.story = {
  518. name: 'close btn in popover',
  519. };
  520. export const PopoverFloatRight = () => <PopRight />;
  521. PopoverFloatRight.story = {
  522. name: 'popover float right',
  523. };
  524. export const NestedPopoverDemo = () => <NestedPopover />;
  525. NestedPopoverDemo.story = {
  526. name: 'nested popover'
  527. }
  528. export const ArrowPointAtCenterDemo = () => <ArrowPointAtCenter />;
  529. ArrowPointAtCenterDemo.story = {
  530. name: 'arrow point at center'
  531. }