1
0

tree.stories.js 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341
  1. import React, { useRef, useState } from 'react';
  2. import Tree from '../index';
  3. import AutoSizer from '../autoSizer';
  4. import { Button, ButtonGroup, Input, Popover, Toast } from '../../index';
  5. import BigTree from './BigData';
  6. import testData from './data';
  7. import { cloneDeep, difference, isEqual } from 'lodash';
  8. import { IconEdit, IconMapPin, IconMore } from '@douyinfe/semi-icons';
  9. const TreeNode = Tree.TreeNode;
  10. export default {
  11. title: 'Tree'
  12. }
  13. const treeChildren = [
  14. {
  15. label: '北京',
  16. value: 'beijing',
  17. key: 'beijing',
  18. },
  19. {
  20. label: '上海',
  21. value: 'shanghai',
  22. key: 'shanghai',
  23. },
  24. ];
  25. const treeData1 = [
  26. {
  27. label: '亚洲',
  28. value: 'yazhou',
  29. key: 'yazhou',
  30. children: [
  31. {
  32. label: '中国',
  33. value: 'zhongguo',
  34. key: 'zhongguo',
  35. disabled: true,
  36. children: treeChildren,
  37. },
  38. {
  39. label: '日本',
  40. value: 'riben',
  41. key: 'riben',
  42. children: [
  43. {
  44. label: '东京',
  45. value: 'dongjing',
  46. key: 'dongjing',
  47. },
  48. {
  49. label: '大阪',
  50. value: 'daban',
  51. key: 'daban',
  52. },
  53. ],
  54. },
  55. ],
  56. },
  57. {
  58. label: '北美洲',
  59. value: 'beimeizhou',
  60. key: 'beimeizhou',
  61. children: [
  62. {
  63. label: '美国',
  64. value: 'meiguo',
  65. key: 'meiguo',
  66. },
  67. {
  68. label: '加拿大',
  69. value: 'jianada',
  70. key: 'jianada',
  71. },
  72. ],
  73. },
  74. ];
  75. const treeDataWithoutValue = [
  76. {
  77. label: '亚洲',
  78. key: 'yazhou',
  79. children: [
  80. {
  81. label: '中国',
  82. key: 'zhongguo',
  83. disabled: true,
  84. children: treeChildren,
  85. },
  86. {
  87. label: '日本',
  88. key: 'riben',
  89. children: [
  90. {
  91. label: '东京',
  92. key: 'dongjing',
  93. },
  94. {
  95. label: '大阪',
  96. key: 'daban',
  97. },
  98. ],
  99. },
  100. ],
  101. },
  102. {
  103. label: '北美洲',
  104. key: 'beimeizhou',
  105. children: [
  106. {
  107. label: '美国',
  108. key: 'meiguo',
  109. },
  110. {
  111. label: '加拿大',
  112. key: 'jianada',
  113. },
  114. ],
  115. },
  116. ];
  117. const treeDataWithIcon = [
  118. {
  119. label: 'Asia',
  120. value: 'Asia',
  121. key: '0',
  122. icon: <IconMapPin style={{ color: 'var(--semi-color-text-2)' }} />,
  123. children: [
  124. {
  125. label: 'China',
  126. value: 'China',
  127. key: '0-0',
  128. icon: <IconMapPin style={{ color: 'var(--semi-color-text-2)' }} />,
  129. },
  130. {
  131. label: 'Japan',
  132. value: 'Japan',
  133. key: '0-1',
  134. icon: <IconMapPin style={{ color: 'var(--semi-color-text-2)' }} />,
  135. },
  136. ],
  137. },
  138. ];
  139. let opts = {
  140. content: 'Hi, Bytedance dance dance',
  141. duration: 3,
  142. };
  143. const treeDataWithNode = [
  144. {
  145. label: (
  146. <span>
  147. <span style={{ marginRight: 30 }}>亚洲</span>
  148. <Button
  149. style={{ zIndex: 2 }}
  150. onClick={e => {
  151. Toast.info(opts);
  152. e.stopPropagation();
  153. }}
  154. >
  155. Display Toast
  156. </Button>
  157. </span>
  158. ),
  159. value: 'yazhou',
  160. key: 'yazhou',
  161. children: [
  162. {
  163. label: '中国',
  164. value: 'zhongguo',
  165. key: 'zhongguo',
  166. children: [
  167. {
  168. label: '北京',
  169. value: 'beijing',
  170. key: 'beijing',
  171. },
  172. {
  173. label: '上海',
  174. value: 'shanghai',
  175. key: 'shanghai',
  176. },
  177. ],
  178. },
  179. {
  180. label: '日本',
  181. value: 'riben',
  182. key: 'riben',
  183. },
  184. ],
  185. },
  186. {
  187. label: '北美洲',
  188. value: 'beimeizhou',
  189. key: 'beimeizhou',
  190. children: [
  191. {
  192. label: '美国',
  193. value: 'meiguo',
  194. key: 'meiguo',
  195. },
  196. {
  197. label: '加拿大',
  198. value: 'jianada',
  199. key: 'jianada',
  200. },
  201. ],
  202. },
  203. ];
  204. const treeJson = {
  205. Node1: {
  206. Child1: '0-0-1',
  207. Child2: '0-0-2',
  208. },
  209. Node2: '0-1',
  210. };
  211. const benchmarkSet = size => {
  212. console.time('benchmarkSet');
  213. var set = new Set();
  214. for (var i = 0; i < size; i++) set.add(i);
  215. for (var i = 0; i < size; i++) set.has(i);
  216. console.timeEnd('benchmarkSet');
  217. };
  218. const benchmarkArr = size => {
  219. console.time('benchmarkArr');
  220. var arr = [];
  221. for (var i = 0; i < size; i++) arr.push(i);
  222. for (var i = 0; i < size; i++) arr.indexOf(i);
  223. console.timeEnd('benchmarkArr');
  224. };
  225. export const BenchMark = () => {
  226. const size = 100000;
  227. benchmarkSet(size);
  228. benchmarkArr(size);
  229. return <div>check console please</div>;
  230. };
  231. BenchMark.story = {
  232. name: 'bench mark',
  233. };
  234. export const SimpleTree = () => (
  235. <Tree
  236. treeData={treeData1}
  237. // onExpand={(e, { expanded, node }) => console.log('expand', e, expanded, node)}
  238. // onSelect={(e, bool, node) => console.log('select', e, bool, node)}
  239. // onChange={e => console.log('change', e)}
  240. onContextMenu={(e, node) => console.log(e.currentTarget, node)}
  241. onDoubleClick={(e, node) => console.log(e, node)}
  242. motion={true}
  243. />
  244. );
  245. SimpleTree.story = {
  246. name: 'simple tree',
  247. };
  248. export const MultipleTree = () => (
  249. <Tree
  250. treeData={treeData1}
  251. multiple
  252. labelInValue
  253. // onExpand={(e, { expanded, node }) => console.log('expand', e, expanded, node)}
  254. // onSelect={(e, bool) => console.log('select', e, bool)}
  255. onContextMenu={(e, node) => console.log(e, node)}
  256. onDoubleClick={(e, node) => console.log(e, node)}
  257. onChange={e => console.log('change', e)}
  258. />
  259. );
  260. MultipleTree.story = {
  261. name: 'multiple tree',
  262. };
  263. export const SearchableTree = () => (
  264. <Tree
  265. treeData={treeData1}
  266. filterTreeNode
  267. treeNodeFilterProp="value"
  268. multiple
  269. searchStyle={{ width: '300px' }}
  270. />
  271. );
  272. SearchableTree.story = {
  273. name: 'searchable tree',
  274. };
  275. export const DisabledTree = () => (
  276. <Tree treeData={treeData1} defaultValue={['dongjing', 'daban']} multiple disabled />
  277. );
  278. DisabledTree.story = {
  279. name: 'disabled tree',
  280. };
  281. export const DefaultTree = () => (
  282. <div>
  283. <Tree treeData={treeData1} defaultValue={['zhongguo']} />
  284. <br />
  285. <Tree
  286. treeData={treeData1}
  287. multiple
  288. defaultValue={['shanghai', 'dongjing', 'beijing', 'daban']}
  289. onChange={e => console.log(e)}
  290. onSelect={e => console.log(e)}
  291. />
  292. </div>
  293. );
  294. DefaultTree.story = {
  295. name: 'default tree',
  296. };
  297. export const ExpandAction = () => (
  298. <div>
  299. <Tree treeData={treeData1} defaultValue={['zhongguo']} />
  300. <br />
  301. <Tree
  302. treeData={treeData1}
  303. //multiple
  304. defaultValue={['shanghai', 'dongjing', 'beijing', 'daban']}
  305. expandAction="click"
  306. onDoubleClick={e => console.log(e.detail)}
  307. />
  308. <br />
  309. <Tree
  310. treeData={treeData1}
  311. multiple
  312. defaultValue={['shanghai', 'dongjing', 'beijing', 'daban']}
  313. expandAction="doubleClick"
  314. />
  315. </div>
  316. );
  317. ExpandAction.story = {
  318. name: 'expandAction',
  319. };
  320. class Demo extends React.Component {
  321. constructor() {
  322. super();
  323. this.state = {
  324. value: 'shanghai',
  325. };
  326. }
  327. onChange(value) {
  328. this.setState({ value });
  329. }
  330. render() {
  331. return (
  332. <Tree
  333. style={{ width: 300 }}
  334. dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
  335. treeData={treeData1}
  336. value={this.state.value}
  337. placeholder="Please select"
  338. onChange={e => this.onChange(e)}
  339. />
  340. );
  341. }
  342. }
  343. export const ControlledComponentSingle = () => <Demo />;
  344. ControlledComponentSingle.story = {
  345. name: 'controlled Component single',
  346. };
  347. class Demo2 extends React.Component {
  348. constructor() {
  349. super();
  350. this.state = {
  351. value: ['shanghai', 'beijing', 'zhongguo'],
  352. };
  353. }
  354. onChange(value) {
  355. console.log(value);
  356. this.setState({ value });
  357. }
  358. render() {
  359. console.log(this.state.value);
  360. return (
  361. <Tree
  362. style={{ width: 300 }}
  363. multiple
  364. dropdownStyle={{ maxHeight: 200, overflow: 'auto' }}
  365. treeData={treeData1}
  366. value={this.state.value}
  367. placeholder="Please select"
  368. onChange={e => this.onChange(e)}
  369. />
  370. );
  371. }
  372. }
  373. export const ControlledComponentMultiple = () => <Demo2 />;
  374. ControlledComponentMultiple.story = {
  375. name: 'controlled Component multiple',
  376. };
  377. export const JsonTree = () => (
  378. <div>
  379. <Tree
  380. treeDataSimpleJson={treeJson}
  381. onChange={e => console.log('change', e)}
  382. onSelect={e => console.log('select', e)}
  383. />
  384. <br />
  385. <Tree
  386. treeDataSimpleJson={treeJson}
  387. multiple
  388. onChange={e => console.log(e)}
  389. onSelect={e => console.log(e)}
  390. />
  391. </div>
  392. );
  393. JsonTree.story = {
  394. name: 'json tree',
  395. };
  396. export const IconTree = () => (
  397. <div>
  398. <Tree treeData={treeDataWithIcon} />
  399. <br />
  400. <Tree treeData={treeDataWithIcon} multiple blockNode />
  401. </div>
  402. );
  403. IconTree.story = {
  404. name: 'icon tree',
  405. };
  406. export const DirectoryTree = () => <Tree treeData={treeData1} directory multiple blockNode />;
  407. DirectoryTree.story = {
  408. name: 'directory tree',
  409. };
  410. const button = (
  411. <ButtonGroup size="small" theme="borderless">
  412. <Button
  413. onClick={e => {
  414. Toast.info(opts);
  415. e.stopPropagation();
  416. }}
  417. >
  418. 提示
  419. </Button>
  420. <Button>点击</Button>
  421. </ButtonGroup>
  422. );
  423. const style = {
  424. display: 'flex',
  425. justifyContent: 'space-between',
  426. alignItems: 'center',
  427. };
  428. const treeDataWithNode2 = [
  429. {
  430. label: (
  431. <div style={style}>
  432. <span>亚洲</span>
  433. <ButtonGroup size="small" theme="borderless">
  434. {button}
  435. </ButtonGroup>
  436. </div>
  437. ),
  438. value: 'yazhou',
  439. key: 'yazhou',
  440. children: [
  441. {
  442. label: (
  443. <div style={style}>
  444. <span>中国</span>
  445. {button}
  446. </div>
  447. ),
  448. value: 'zhongguo',
  449. key: 'zhongguo',
  450. children: [
  451. {
  452. label: (
  453. <div style={style}>
  454. <span>test</span>
  455. {button}
  456. </div>
  457. ),
  458. value: 'test',
  459. key: 'test',
  460. },
  461. ],
  462. },
  463. {
  464. label: (
  465. <div style={style}>
  466. <span>日本</span>
  467. {button}
  468. </div>
  469. ),
  470. value: 'riben',
  471. key: 'riben',
  472. },
  473. ],
  474. },
  475. ];
  476. export const TreeLabelUsingNode = () => (
  477. <div>
  478. <Tree treeData={treeDataWithNode2} blockNode defaultExpandAll />
  479. </div>
  480. );
  481. TreeLabelUsingNode.story = {
  482. name: 'tree label using node',
  483. };
  484. const treeDataTest = [
  485. {
  486. value: '一级标签1',
  487. label: '一级标签1',
  488. id: 1,
  489. key: '1',
  490. },
  491. ];
  492. class TagSideSheet2 extends React.Component {
  493. constructor() {
  494. super();
  495. this.state = {
  496. tagList: [],
  497. visibles: false,
  498. };
  499. this.onVisible = this.onVisible.bind(this);
  500. this.renderLabel = this.renderLabel.bind(this);
  501. this.transLabel = this.transLabel.bind(this);
  502. }
  503. componentDidMount() {
  504. let tagList = [...treeDataTest];
  505. this.setState({
  506. tagList,
  507. });
  508. }
  509. onVisible(visibles) {
  510. this.setState({
  511. visibles,
  512. });
  513. }
  514. renderLabel(item) {
  515. const { visibles } = this.state;
  516. console.log('rendering label', visibles);
  517. return (
  518. <Popover trigger="custom" position="bottomLeft" visible={visibles} content={'测试popover'}>
  519. <Button
  520. icon={<IconEdit />}
  521. onClick={e => {
  522. e.stopPropagation();
  523. this.onVisible(!visibles);
  524. }}
  525. >
  526. {item.label}
  527. </Button>
  528. </Popover>
  529. );
  530. }
  531. transLabel(list) {
  532. // list = cloneDeep(list);
  533. list.forEach(item => {
  534. item.label = this.renderLabel(item);
  535. // item.key += Math.random().toString().slice(0, 5);
  536. });
  537. return list;
  538. }
  539. render() {
  540. const { tagList = [] } = this.state;
  541. const transformedTags = this.transLabel(cloneDeep(tagList));
  542. console.log('transformedTags', transformedTags, treeDataTest);
  543. return <Tree treeData={transformedTags} />;
  544. }
  545. }
  546. export const TreeLabelUsingPopover = () => <TagSideSheet2 />;
  547. TreeLabelUsingPopover.story = {
  548. name: 'tree label using popover',
  549. };
  550. export const DefaultExpandKeysTree = () => (
  551. <>
  552. <Tree treeData={treeData1} defaultExpandedKeys={['zhongguo', 'beimeizhou']} blockNode />
  553. <Tree treeData={treeData1} defaultExpandAll blockNode />
  554. <Tree treeData={treeData1} defaultExpandAll multiple blockNode />
  555. </>
  556. );
  557. DefaultExpandKeysTree.story = {
  558. name: 'defaultExpandKeys tree',
  559. };
  560. export const LabelInValueTree = () => (
  561. <>
  562. <Tree treeData={treeData1} labelInValue onChange={e => console.log(e)} />
  563. <Tree treeData={treeData1} labelInValue onChange={e => console.log(e)} multiple />
  564. <Tree treeData={treeDataWithIcon} labelInValue onChange={e => console.log(e)} multiple />
  565. </>
  566. );
  567. LabelInValueTree.story = {
  568. name: 'labelInValue tree',
  569. };
  570. class Test extends React.Component {
  571. constructor() {
  572. super();
  573. this.state = {
  574. loading: false,
  575. };
  576. }
  577. componentDidMount() {
  578. setTimeout(() => {
  579. console.log('set loading');
  580. this.setState({ loading: true });
  581. }, 5000);
  582. }
  583. render() {
  584. const treeDataWithNode2 = [
  585. {
  586. label: (
  587. <div style={style}>
  588. <span>亚洲</span>
  589. <ButtonGroup size="small" theme="borderless">
  590. {button}
  591. </ButtonGroup>
  592. </div>
  593. ),
  594. value: 'yazhou',
  595. key: 'yazhou',
  596. children: [
  597. {
  598. label: (
  599. <div style={style}>
  600. <span>中国</span>
  601. {button}
  602. </div>
  603. ),
  604. value: 'zhongguo',
  605. key: 'zhongguo',
  606. children: [
  607. {
  608. label: (
  609. <div style={style}>
  610. <span>test</span>
  611. {button}
  612. </div>
  613. ),
  614. value: 'test',
  615. key: 'test',
  616. },
  617. ],
  618. },
  619. {
  620. label: (
  621. <div style={style}>
  622. <span>日本</span>
  623. {button}
  624. </div>
  625. ),
  626. value: 'riben',
  627. key: 'riben',
  628. },
  629. ],
  630. },
  631. ];
  632. return <Tree treeData={treeDataWithNode2} />;
  633. }
  634. }
  635. export const SetStateAfter5S = () => <Test />;
  636. SetStateAfter5S.story = {
  637. name: 'setState after 5s',
  638. };
  639. class DemoExpandedKeys extends React.Component {
  640. constructor() {
  641. super();
  642. this.state = {
  643. expand: ['zhongguo', 'beimeizhou'],
  644. };
  645. }
  646. onExpand(expand) {
  647. console.log(expand);
  648. this.setState({ expand });
  649. }
  650. render() {
  651. return (
  652. <Tree
  653. style={{ width: 300 }}
  654. dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
  655. treeData={treeData1}
  656. expandedKeys={this.state.expand}
  657. placeholder="Please select"
  658. onExpand={(e, rest) => this.onExpand(e, rest)}
  659. />
  660. );
  661. }
  662. }
  663. class DemoExpandeKeysMulti extends React.Component {
  664. constructor() {
  665. super();
  666. this.state = {
  667. expand: ['zhongguo'],
  668. };
  669. }
  670. onExpand(expand) {
  671. console.log(expand);
  672. this.setState({ expand });
  673. }
  674. render() {
  675. return (
  676. <Tree
  677. style={{ width: 300 }}
  678. multiple
  679. dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
  680. treeData={treeData1}
  681. expandedKeys={this.state.expand}
  682. placeholder="Please select"
  683. onExpand={e => this.onExpand(e)}
  684. />
  685. );
  686. }
  687. }
  688. export const ExpandedKeys = () => (
  689. <>
  690. <DemoExpandedKeys />
  691. <br />
  692. <DemoExpandeKeysMulti />
  693. </>
  694. );
  695. ExpandedKeys.story = {
  696. name: 'expandedKeys',
  697. };
  698. class DmExpandedKeys extends React.Component {
  699. constructor() {
  700. super();
  701. this.state = {
  702. treeData: [
  703. {
  704. key: '0',
  705. label: 'item-0',
  706. value: '0',
  707. },
  708. ],
  709. };
  710. this.add = this.add.bind(this);
  711. }
  712. add() {
  713. let itemLength = Math.floor(Math.random() * 5) + 1;
  714. let treeData = new Array(itemLength).fill(0).map((v, i) => {
  715. let length = Math.floor(Math.random() * 3);
  716. let children = new Array(length).fill(0).map((cv, ci) => {
  717. let child = {
  718. key: `${i}-${ci}`,
  719. label: `Leaf-${i}-${ci}`,
  720. value: `${i}-${ci}`,
  721. };
  722. return child;
  723. });
  724. let item = {
  725. key: `${i}`,
  726. label: `Item-${i}`,
  727. value: `${i}`,
  728. children,
  729. };
  730. return item;
  731. });
  732. this.setState({ treeData });
  733. }
  734. render() {
  735. const { treeData } = this.state;
  736. return (
  737. <>
  738. <Tree treeData={this.state.treeData} expandedKeys={['0', '1']} />
  739. <br />
  740. <Button onClick={this.add}>动态改变数据</Button>
  741. </>
  742. );
  743. }
  744. }
  745. export const DynamicExpandKeys = () => (
  746. <>
  747. <DmExpandedKeys />
  748. </>
  749. );
  750. DynamicExpandKeys.story = {
  751. name: 'dynamic expandKeys',
  752. };
  753. class DmSelectedKeys extends React.Component {
  754. constructor() {
  755. super();
  756. this.state = {
  757. treeData: [
  758. {
  759. key: '0',
  760. label: 'item-0',
  761. value: '0',
  762. },
  763. ],
  764. };
  765. this.add = this.add.bind(this);
  766. }
  767. add() {
  768. let itemLength = Math.floor(Math.random() * 5) + 1;
  769. let treeData = new Array(itemLength).fill(0).map((v, i) => {
  770. let length = Math.floor(Math.random() * 3);
  771. let children = new Array(length).fill(0).map((cv, ci) => {
  772. let child = {
  773. key: `${i}-${ci}`,
  774. label: `Leaf-${i}-${ci}`,
  775. value: `${i}-${ci}`,
  776. };
  777. return child;
  778. });
  779. let item = {
  780. key: `${i}`,
  781. label: `Item-${i}`,
  782. value: `${i}`,
  783. children,
  784. };
  785. return item;
  786. });
  787. this.setState({ treeData });
  788. }
  789. render() {
  790. const { treeData } = this.state;
  791. return (
  792. <>
  793. <Tree treeData={treeData} value={['0-0']} onChange={e => console.log(e)} />
  794. <br />
  795. <Button onClick={this.add}>动态改变数据</Button>
  796. </>
  797. );
  798. }
  799. }
  800. export const DynamicSelectedKey = () => (
  801. <>
  802. <DmSelectedKeys />
  803. </>
  804. );
  805. DynamicSelectedKey.story = {
  806. name: 'dynamic selectedKey',
  807. };
  808. export const LargeAmountOfData = () => (
  809. <>
  810. <BigTree />
  811. </>
  812. );
  813. LargeAmountOfData.story = {
  814. name: 'large amount of data',
  815. };
  816. export const Autosizer = () => (
  817. <div
  818. style={{
  819. boxSizing: 'border-box',
  820. height: 400,
  821. width: 200,
  822. }}
  823. >
  824. <div
  825. style={{
  826. boxSizing: 'border-box',
  827. height: '50%',
  828. width: 200,
  829. }}
  830. >
  831. <AutoSizer
  832. // defaultHeight={defaultHeight}
  833. // defaultWidth={defaultWidth}
  834. >
  835. {({ height, width }) => (
  836. <div
  837. style={{
  838. width: width,
  839. height: height,
  840. }}
  841. >
  842. {`width:${width}, height:${height}`}
  843. </div>
  844. )}
  845. </AutoSizer>
  846. </div>
  847. </div>
  848. );
  849. Autosizer.story = {
  850. name: 'autosizer',
  851. };
  852. const MotionCustomLabelDemo = () => {
  853. const treeData = [
  854. {
  855. label: '亚洲',
  856. value: 'Asia',
  857. key: '0',
  858. children: [
  859. {
  860. label: '中国',
  861. value: 'China',
  862. key: '0-0',
  863. children: [
  864. {
  865. label: '北京',
  866. value: 'Beijing',
  867. key: '0-0-0',
  868. },
  869. {
  870. label: '上海',
  871. value: 'Shanghai',
  872. key: '0-0-1',
  873. },
  874. ],
  875. },
  876. ],
  877. },
  878. {
  879. label: '北美洲',
  880. value: 'North America',
  881. key: '1',
  882. },
  883. ];
  884. const [hoverKey, setHoverKey] = useState();
  885. const cusLabel = (list = []) => {
  886. const recusive = (list = []) => {
  887. if (!list.length) {
  888. return;
  889. }
  890. list.forEach(item => {
  891. const { type, label, key } = item;
  892. item.label = (
  893. <div onMouseEnter={() => setHoverKey(key)}>
  894. {label}
  895. {hoverKey === key ? <IconMore /> : null}
  896. </div>
  897. );
  898. recusive(item.children);
  899. });
  900. };
  901. recusive(list);
  902. return list;
  903. };
  904. return <Tree treeData={cusLabel(treeData)} defaultExpandAll />;
  905. };
  906. export const MotionCustomLabel = () => <MotionCustomLabelDemo />;
  907. MotionCustomLabel.story = {
  908. name: 'motion custom label',
  909. };
  910. const AutoParentDemo = () => {
  911. const [expandedKeys, setExpandedKeys] = useState(['beimeizhou']);
  912. const [selectedKeys, setSelectedKeys] = useState(['beimeizhou']);
  913. const [autoExpandParent, setAutoExpandParent] = useState(true);
  914. const onExpand = expandedKeys => {
  915. console.log('onExpand', expandedKeys);
  916. // if not set autoExpandParent to false, if children expanded, parent can not collapse.
  917. // or, you can remove all expanded children keys.
  918. setExpandedKeys(expandedKeys);
  919. setAutoExpandParent(false);
  920. };
  921. const onSelect = (selectedKeys, info) => {
  922. console.log('onSelect:', info);
  923. setSelectedKeys(selectedKeys);
  924. };
  925. return (
  926. <div>
  927. <Button
  928. onClick={() => {
  929. setSelectedKeys(['riben']);
  930. setExpandedKeys(['riben']);
  931. setAutoExpandParent(true);
  932. }}
  933. >
  934. Update
  935. </Button>
  936. <Tree
  937. onExpand={onExpand}
  938. expandedKeys={expandedKeys}
  939. autoExpandParent={autoExpandParent}
  940. onChange={onSelect}
  941. value={selectedKeys}
  942. treeData={treeData1}
  943. multiple
  944. />
  945. </div>
  946. );
  947. };
  948. export const AutoExpandParent = () => (
  949. <>
  950. <AutoParentDemo />
  951. </>
  952. );
  953. AutoExpandParent.story = {
  954. name: 'autoExpandParent',
  955. };
  956. const findDescendantKeys = node => {
  957. let res = [node.key];
  958. const findChild = item => {
  959. if (!item) return;
  960. const { children } = item;
  961. if (children && children.length) {
  962. children.forEach(child => {
  963. res.push(child.key);
  964. findChild(child);
  965. });
  966. }
  967. };
  968. findChild(node);
  969. return res;
  970. };
  971. class DyTreeWithExpandControlled extends React.Component {
  972. constructor() {
  973. super();
  974. this.state = {
  975. treeData: [
  976. {
  977. key: '0',
  978. label: 'item-0',
  979. value: '0',
  980. },
  981. ],
  982. expandedKeys: [],
  983. autoExpandParent: false,
  984. inputValue: '',
  985. collapsedKeys: new Set([]),
  986. };
  987. }
  988. componentDidUpdate(prevProps, prevState) {
  989. if (
  990. !isEqual(prevState.treeData, this.state.treeData) ||
  991. !isEqual(prevState.inputValue, this.state.inputValue)
  992. ) {
  993. const { treeData, inputValue, collapsedKeys } = this.state;
  994. let filteredKeys = [];
  995. const findFilteredKey = arr => {
  996. arr.forEach(item => {
  997. if (item.label.indexOf(inputValue) > -1) {
  998. filteredKeys.push(item.key);
  999. }
  1000. if (item.children) {
  1001. findFilteredKey(item.children);
  1002. }
  1003. });
  1004. };
  1005. findFilteredKey(treeData);
  1006. const expanded = difference(filteredKeys, [...collapsedKeys]);
  1007. this.setState({
  1008. expandedKeys: expanded,
  1009. autoExpandParent: true,
  1010. });
  1011. }
  1012. }
  1013. add = () => {
  1014. let itemLength = Math.floor(Math.random() * 5) + 1;
  1015. let treeData = new Array(itemLength).fill(0).map((v, i) => {
  1016. let length = Math.floor(Math.random() * 3) + 1;
  1017. let children = new Array(length).fill(0).map((cv, ci) => {
  1018. let child = {
  1019. key: `${i}-${ci}`,
  1020. label: `Leaf-${i}-${ci}`,
  1021. value: `${i}-${ci}`,
  1022. };
  1023. return child;
  1024. });
  1025. let item = {
  1026. key: `${i}`,
  1027. label: `Item-${i}`,
  1028. value: `${i}`,
  1029. children,
  1030. };
  1031. return item;
  1032. });
  1033. this.setState({ treeData });
  1034. };
  1035. search = val => {
  1036. this.setState({ inputValue: val });
  1037. };
  1038. onExpand = (keys, { expanded, node }) => {
  1039. let collapsed = this.state.collapsedKeys;
  1040. let desKeys = findDescendantKeys(node);
  1041. if (!expanded) {
  1042. desKeys.forEach(key => collapsed.add(key));
  1043. } else {
  1044. desKeys.forEach(key => collapsed.has(key) && collapsed.delete(key));
  1045. }
  1046. this.setState({
  1047. expandedKeys: keys,
  1048. autoExpandParent: false,
  1049. collapsedKeys: collapsed,
  1050. });
  1051. };
  1052. render() {
  1053. const { treeData, expandedKeys, autoExpandParent } = this.state;
  1054. return (
  1055. <div>
  1056. <Tree
  1057. treeData={treeData}
  1058. filterTreeNode
  1059. autoExpandParent={autoExpandParent}
  1060. expandedKeys={expandedKeys}
  1061. onSearch={this.search}
  1062. onExpand={this.onExpand}
  1063. />
  1064. <br />
  1065. <Button onClick={this.add} style={{ margin: 20 }}>
  1066. 动态改变数据
  1067. </Button>
  1068. </div>
  1069. );
  1070. }
  1071. }
  1072. export const DynamicTreeDataWithSearchValueAndControlledExpand = () => (
  1073. <DyTreeWithExpandControlled />
  1074. );
  1075. DynamicTreeDataWithSearchValueAndControlledExpand.story = {
  1076. name: 'dynamic treeData with searchValue and controlled expand',
  1077. };
  1078. const CusSearchRender = () => {
  1079. const [inputValue, setInputValue] = useState('');
  1080. const ref = useRef();
  1081. const setValue = value => {
  1082. setInputValue(value);
  1083. ref.current.search(value);
  1084. };
  1085. return (
  1086. <Tree
  1087. ref={ref}
  1088. treeData={treeData1}
  1089. filterTreeNode
  1090. showFilteredOnly
  1091. searchRender={({ prefix, placeholder }) => (
  1092. <Input
  1093. prefix={prefix}
  1094. placeholder={placeholder}
  1095. value={inputValue}
  1096. onChange={value => setValue(value)}
  1097. />
  1098. )}
  1099. />
  1100. );
  1101. };
  1102. export const _CusSearchRender = () => (
  1103. <>
  1104. <CusSearchRender />
  1105. </>
  1106. );
  1107. _CusSearchRender.story = {
  1108. name: 'CusSearchRender',
  1109. };
  1110. const RefSearch = () => {
  1111. const ref = useRef();
  1112. const treeData = [
  1113. {
  1114. label: 'Asia',
  1115. value: 'Asia',
  1116. key: '0',
  1117. children: [
  1118. {
  1119. label: 'China',
  1120. value: 'China',
  1121. key: '0-0',
  1122. children: [
  1123. {
  1124. label: 'Beijing',
  1125. value: 'Beijing',
  1126. key: '0-0-0',
  1127. },
  1128. {
  1129. label: 'Shanghai',
  1130. value: 'Shanghai',
  1131. key: '0-0-1',
  1132. },
  1133. ],
  1134. },
  1135. {
  1136. label: 'Japan',
  1137. value: 'Japan',
  1138. key: '0-1',
  1139. children: [
  1140. {
  1141. label: 'Osaka',
  1142. value: 'Osaka',
  1143. key: '0-1-0',
  1144. },
  1145. ],
  1146. },
  1147. ],
  1148. },
  1149. {
  1150. label: 'North America',
  1151. value: 'North America',
  1152. key: '1',
  1153. children: [
  1154. {
  1155. label: 'United States',
  1156. value: 'United States',
  1157. key: '1-0',
  1158. },
  1159. {
  1160. label: 'Canada',
  1161. value: 'Canada',
  1162. key: '1-1',
  1163. },
  1164. ],
  1165. },
  1166. ];
  1167. return (
  1168. <div>
  1169. <Input aria-label='filter tree' onChange={v => ref.current.search(v)} />
  1170. <Tree
  1171. treeData={treeData}
  1172. defaultValue="Shanghai"
  1173. blockNode={false}
  1174. ref={ref}
  1175. filterTreeNode
  1176. searchRender={() => null}
  1177. />
  1178. </div>
  1179. );
  1180. };
  1181. export const _RefSearch = () => (
  1182. <>
  1183. <RefSearch />
  1184. </>
  1185. );
  1186. _RefSearch.story = {
  1187. name: 'RefSearch',
  1188. };
  1189. const initTreeDate = [
  1190. {
  1191. label: 'Expand to load',
  1192. key: '0',
  1193. },
  1194. {
  1195. label: 'Expand to load',
  1196. key: '1',
  1197. },
  1198. {
  1199. label: 'Tree Node',
  1200. key: '2',
  1201. isLeaf: true,
  1202. },
  1203. ];
  1204. function updateTreeData(list, key, children) {
  1205. return list.map(node => {
  1206. if (node.key === key) {
  1207. return { ...node, children };
  1208. }
  1209. if (node.children) {
  1210. return { ...node, children: updateTreeData(node.children, key, children) };
  1211. }
  1212. return node;
  1213. });
  1214. }
  1215. const LoadingTreeDemo = () => {
  1216. const [treeData, setTreeData] = useState(initTreeDate);
  1217. function onLoadData({ key, children }) {
  1218. return new Promise(resolve => {
  1219. if (children) {
  1220. resolve();
  1221. return;
  1222. }
  1223. setTimeout(() => {
  1224. setTreeData(origin =>
  1225. updateTreeData(origin, key, [
  1226. {
  1227. label: 'Child Node',
  1228. key: `${key}-0`,
  1229. },
  1230. {
  1231. label: 'Child Node',
  1232. key: `${key}-1`,
  1233. },
  1234. ])
  1235. );
  1236. resolve();
  1237. }, 1000);
  1238. });
  1239. }
  1240. return <Tree loadData={onLoadData} treeData={cloneDeep(treeData)} />;
  1241. };
  1242. export const Loading = () => (
  1243. <>
  1244. <LoadingTreeDemo />
  1245. </>
  1246. );
  1247. Loading.story = {
  1248. name: 'loading',
  1249. };
  1250. const LoadingWithSearch = () => {
  1251. const [treeData, setTreeData] = useState(initTreeDate);
  1252. function onLoadData({ key, children }) {
  1253. return new Promise(resolve => {
  1254. if (children) {
  1255. resolve();
  1256. return;
  1257. }
  1258. setTimeout(() => {
  1259. setTreeData(origin =>
  1260. updateTreeData(origin, key, [
  1261. {
  1262. label: 'Child Node',
  1263. key: `${key}-0`,
  1264. },
  1265. {
  1266. label: 'Child Node',
  1267. key: `${key}-1`,
  1268. },
  1269. ])
  1270. );
  1271. resolve();
  1272. }, 1000);
  1273. });
  1274. }
  1275. return <Tree loadData={onLoadData} treeData={cloneDeep(treeData)} filterTreeNode />;
  1276. };
  1277. export const _LoadingWithSearch = () => (
  1278. <>
  1279. <LoadingWithSearch />
  1280. </>
  1281. );
  1282. _LoadingWithSearch.story = {
  1283. name: 'Loading with search',
  1284. };
  1285. const DisabledStrictly = () => {
  1286. return (
  1287. <>
  1288. <span> disable shanghai(checked), China </span>
  1289. <Tree
  1290. treeData={[
  1291. {
  1292. label: 'Asia',
  1293. value: 'Asia',
  1294. key: '0',
  1295. children: [
  1296. {
  1297. label: 'China',
  1298. value: 'China',
  1299. key: '0-0',
  1300. disabled: true,
  1301. children: [
  1302. {
  1303. label: 'Beijing',
  1304. value: 'Beijing',
  1305. key: '0-0-0',
  1306. },
  1307. {
  1308. label: 'Shanghai',
  1309. value: 'Shanghai',
  1310. key: '0-0-1',
  1311. disabled: true,
  1312. },
  1313. ],
  1314. },
  1315. {
  1316. label: 'Japan',
  1317. value: 'Japan',
  1318. key: '0-1',
  1319. children: [
  1320. {
  1321. label: 'Osaka',
  1322. value: 'Osaka',
  1323. key: '0-1-0',
  1324. },
  1325. ],
  1326. },
  1327. ],
  1328. },
  1329. ]}
  1330. defaultValue="Shanghai"
  1331. multiple
  1332. defaultExpandAll
  1333. disableStrictly
  1334. />
  1335. <br />
  1336. <span> disable shanghai(checked), beijing(checked) </span>
  1337. <Tree
  1338. treeData={[
  1339. {
  1340. label: 'Asia',
  1341. value: 'Asia',
  1342. key: '0',
  1343. children: [
  1344. {
  1345. label: 'China',
  1346. value: 'China',
  1347. key: '0-0',
  1348. children: [
  1349. {
  1350. label: 'Beijing',
  1351. value: 'Beijing',
  1352. key: '0-0-0',
  1353. disabled: true,
  1354. },
  1355. {
  1356. label: 'Shanghai',
  1357. value: 'Shanghai',
  1358. key: '0-0-1',
  1359. disabled: true,
  1360. },
  1361. ],
  1362. },
  1363. {
  1364. label: 'Japan',
  1365. value: 'Japan',
  1366. key: '0-1',
  1367. children: [
  1368. {
  1369. label: 'Osaka',
  1370. value: 'Osaka',
  1371. key: '0-1-0',
  1372. },
  1373. ],
  1374. },
  1375. ],
  1376. },
  1377. ]}
  1378. defaultValue={['Shanghai', 'Beijing']}
  1379. multiple
  1380. defaultExpandAll
  1381. disableStrictly
  1382. />
  1383. <span> disable shanghai(checked) </span>
  1384. <Tree
  1385. treeData={[
  1386. {
  1387. label: 'Asia',
  1388. value: 'Asia',
  1389. key: '0',
  1390. children: [
  1391. {
  1392. label: 'China',
  1393. value: 'China',
  1394. key: '0-0',
  1395. children: [
  1396. {
  1397. label: 'Beijing',
  1398. value: 'Beijing',
  1399. key: '0-0-0',
  1400. },
  1401. {
  1402. label: 'Shanghai',
  1403. value: 'Shanghai',
  1404. key: '0-0-1',
  1405. disabled: true,
  1406. },
  1407. ],
  1408. },
  1409. {
  1410. label: 'Japan',
  1411. value: 'Japan',
  1412. key: '0-1',
  1413. children: [
  1414. {
  1415. label: 'Osaka',
  1416. value: 'Osaka',
  1417. key: '0-1-0',
  1418. },
  1419. ],
  1420. },
  1421. ],
  1422. },
  1423. ]}
  1424. defaultValue={['Shanghai']}
  1425. multiple
  1426. defaultExpandAll
  1427. disableStrictly
  1428. />
  1429. <br />
  1430. <span> disable shanghai </span>
  1431. <Tree
  1432. treeData={[
  1433. {
  1434. label: 'Asia',
  1435. value: 'Asia',
  1436. key: '0',
  1437. children: [
  1438. {
  1439. label: 'China',
  1440. value: 'China',
  1441. key: '0-0',
  1442. children: [
  1443. {
  1444. label: 'Beijing',
  1445. value: 'Beijing',
  1446. key: '0-0-0',
  1447. },
  1448. {
  1449. label: 'Chengdu',
  1450. value: 'Chengdu',
  1451. key: '0-0-2',
  1452. },
  1453. {
  1454. label: 'Shanghai',
  1455. value: 'Shanghai',
  1456. key: '0-0-1',
  1457. disabled: true,
  1458. },
  1459. ],
  1460. },
  1461. {
  1462. label: 'Japan',
  1463. value: 'Japan',
  1464. key: '0-1',
  1465. children: [
  1466. {
  1467. label: 'Osaka',
  1468. value: 'Osaka',
  1469. key: '0-1-0',
  1470. },
  1471. ],
  1472. },
  1473. ],
  1474. },
  1475. ]}
  1476. multiple
  1477. defaultExpandAll
  1478. disableStrictly
  1479. />
  1480. <span> disable China(checked) - Shanghai </span>
  1481. <Tree
  1482. treeData={[
  1483. {
  1484. label: 'Asia',
  1485. value: 'Asia',
  1486. key: '0',
  1487. children: [
  1488. {
  1489. label: 'China',
  1490. value: 'China',
  1491. key: '0-0',
  1492. disabled: true,
  1493. children: [
  1494. {
  1495. label: 'Beijing',
  1496. value: 'Beijing',
  1497. key: '0-0-0',
  1498. },
  1499. {
  1500. label: 'Shanghai',
  1501. value: 'Shanghai',
  1502. key: '0-0-1',
  1503. disabled: true,
  1504. },
  1505. ],
  1506. },
  1507. {
  1508. label: 'Japan',
  1509. value: 'Japan',
  1510. key: '0-1',
  1511. children: [
  1512. {
  1513. label: 'Osaka',
  1514. value: 'Osaka',
  1515. key: '0-1-0',
  1516. },
  1517. ],
  1518. },
  1519. ],
  1520. },
  1521. ]}
  1522. defaultValue="China"
  1523. multiple
  1524. defaultExpandAll
  1525. disableStrictly
  1526. />
  1527. <span> disable China </span>
  1528. <Tree
  1529. treeData={[
  1530. {
  1531. label: 'Asia',
  1532. value: 'Asia',
  1533. key: '0',
  1534. children: [
  1535. {
  1536. label: 'China',
  1537. value: 'China',
  1538. key: '0-0',
  1539. disabled: true,
  1540. children: [
  1541. {
  1542. label: 'Beijing',
  1543. value: 'Beijing',
  1544. key: '0-0-0',
  1545. },
  1546. {
  1547. label: 'Shanghai',
  1548. value: 'Shanghai',
  1549. key: '0-0-1',
  1550. },
  1551. ],
  1552. },
  1553. {
  1554. label: 'Japan',
  1555. value: 'Japan',
  1556. key: '0-1',
  1557. children: [
  1558. {
  1559. label: 'Osaka',
  1560. value: 'Osaka',
  1561. key: '0-1-0',
  1562. },
  1563. ],
  1564. },
  1565. ],
  1566. },
  1567. ]}
  1568. multiple
  1569. defaultExpandAll
  1570. disableStrictly
  1571. />
  1572. </>
  1573. );
  1574. };
  1575. export const DisableStrictly = () => <DisabledStrictly />;
  1576. DisableStrictly.story = {
  1577. name: 'disableStrictly',
  1578. };
  1579. const ActionTree = () => {
  1580. let initData = [
  1581. {
  1582. label: 'Asia',
  1583. value: 'Asia',
  1584. key: 'asia',
  1585. children: [
  1586. {
  1587. label: 0,
  1588. value: `${0}`,
  1589. key: `${0}`,
  1590. },
  1591. {
  1592. label: 1,
  1593. value: `${1}`,
  1594. key: `${1}`,
  1595. },
  1596. {
  1597. label: 2,
  1598. value: `${2}`,
  1599. key: `${2}`,
  1600. },
  1601. {
  1602. label: 3,
  1603. value: `${3}`,
  1604. key: `${3}`,
  1605. },
  1606. {
  1607. label: 4,
  1608. value: `${4}`,
  1609. key: `${4}`,
  1610. },
  1611. ],
  1612. },
  1613. ];
  1614. const [data, setData] = useState(initData);
  1615. const remove = key => {
  1616. let ind = data[0].children.findIndex(item => item.key === key);
  1617. if (ind >= 0) {
  1618. let items = cloneDeep(data);
  1619. items[0].children.splice(ind, 1);
  1620. setData(items);
  1621. }
  1622. };
  1623. return (
  1624. <Tree
  1625. treeData={cloneDeep(data)}
  1626. renderLabel={(label, data) => (
  1627. <div>
  1628. {label}
  1629. <Button onClick={() => remove(data.key)}>remove</Button>
  1630. </div>
  1631. )}
  1632. />
  1633. );
  1634. };
  1635. export const DeleteOrAddChildNode = () => <ActionTree />;
  1636. DeleteOrAddChildNode.story = {
  1637. name: 'Delete or Add Child Node',
  1638. };
  1639. const MutipleHLTree = () => {
  1640. const [selected, setSelected] = useState(new Set());
  1641. const [selectedThroughParent, setSelectedThroughParent] = useState(new Set());
  1642. const findDescendantKeys = node => {
  1643. let res = [node.key];
  1644. const findChild = item => {
  1645. if (!item) return;
  1646. const { children } = item;
  1647. if (children && children.length) {
  1648. children.forEach(child => {
  1649. res.push(child.key);
  1650. findChild(child);
  1651. });
  1652. }
  1653. };
  1654. findChild(node);
  1655. return res;
  1656. };
  1657. const handleSelect = (key, bool, node) => {
  1658. setSelected(new Set([key]));
  1659. const descendantKeys = findDescendantKeys(node);
  1660. setSelectedThroughParent(new Set(descendantKeys));
  1661. };
  1662. const renderLabel = ({ className, data, onClick, expandIcon }) => {
  1663. const { label, icon, key } = data;
  1664. const isLeaf = !(data.children && data.children.length);
  1665. const style = {
  1666. backgroundColor: selected.has(key)
  1667. ? 'rgba(var(--semi-blue-0), 1)'
  1668. : selectedThroughParent.has(key)
  1669. ? 'rgba(var(--semi-blue-0), .5)'
  1670. : 'transparent',
  1671. };
  1672. return (
  1673. <li className={className} role="treeitem" onClick={onClick} style={style}>
  1674. {isLeaf ? null : expandIcon}
  1675. {icon ? icon : null}
  1676. <span>{label}</span>
  1677. </li>
  1678. );
  1679. };
  1680. const treeStyle = {
  1681. width: 260,
  1682. height: 420,
  1683. border: '1px solid var(--semi-color-border)',
  1684. };
  1685. return (
  1686. <Tree
  1687. treeData={treeData1}
  1688. renderFullLabel={renderLabel}
  1689. onSelect={handleSelect}
  1690. style={treeStyle}
  1691. />
  1692. );
  1693. };
  1694. export const RenderOuterLable = () => <MutipleHLTree />;
  1695. RenderOuterLable.story = {
  1696. name: 'renderOuterLable',
  1697. };
  1698. export const TreeWithoutValueProps = () => (
  1699. <Tree
  1700. treeData={treeDataWithoutValue}
  1701. value="meiguo"
  1702. defaultExpandAll
  1703. onChange={(...args) => console.log(args)}
  1704. />
  1705. );
  1706. TreeWithoutValueProps.story = {
  1707. name: 'tree without value props',
  1708. };
  1709. const DnDTree = () => {
  1710. const initialData = [
  1711. {
  1712. label: 'Asia',
  1713. value: 'Asia',
  1714. key: '0',
  1715. children: [
  1716. {
  1717. label: 'China',
  1718. value: 'China',
  1719. key: '0-0',
  1720. children: [
  1721. {
  1722. label: 'Beijing',
  1723. value: 'Beijing',
  1724. key: '0-0-0',
  1725. },
  1726. {
  1727. label: 'Shanghai',
  1728. value: 'Shanghai',
  1729. key: '0-0-1',
  1730. },
  1731. ],
  1732. },
  1733. {
  1734. label: 'Japan',
  1735. value: 'Japan',
  1736. key: '0-1',
  1737. children: [
  1738. {
  1739. label: 'Osaka',
  1740. value: 'Osaka',
  1741. key: '0-1-0',
  1742. },
  1743. ],
  1744. },
  1745. ],
  1746. },
  1747. {
  1748. label: 'North America',
  1749. value: 'North America',
  1750. key: '1',
  1751. children: [
  1752. {
  1753. label: 'United States',
  1754. value: 'United States',
  1755. key: '1-0',
  1756. },
  1757. {
  1758. label: 'Canada',
  1759. value: 'Canada',
  1760. key: '1-1',
  1761. },
  1762. ],
  1763. },
  1764. {
  1765. label: 'Europe',
  1766. value: 'Europe',
  1767. key: '2',
  1768. },
  1769. ];
  1770. const [treeData, setTreeData] = useState(initialData);
  1771. // const [expandedKeys, setExpandedKeys] = useState(['zhongguo']);
  1772. function onDragEnter(info) {
  1773. console.log(info);
  1774. // if in controlled expandedKeys mode
  1775. // setExpandedKeys(info.expandedKeys)
  1776. }
  1777. function onDrop(info) {
  1778. const { dropToGap, node, dragNode } = info;
  1779. const dropKey = node.key;
  1780. const dragKey = dragNode.key;
  1781. const dropPos = node.pos.split('-');
  1782. const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);
  1783. const data = [...treeData];
  1784. const loop = (data, key, callback) => {
  1785. data.forEach((item, ind, arr) => {
  1786. if (item.key === key) return callback(item, ind, arr);
  1787. if (item.children) return loop(item.children, key, callback);
  1788. });
  1789. };
  1790. let dragObj;
  1791. loop(data, dragKey, (item, ind, arr) => {
  1792. arr.splice(ind, 1);
  1793. dragObj = item;
  1794. });
  1795. if (!dropToGap) {
  1796. // inset into the dropPosition
  1797. loop(data, dropKey, (item, ind, arr) => {
  1798. item.children = item.children || [];
  1799. item.children.push(dragObj);
  1800. });
  1801. } else if (dropPosition === 1 && node.children && node.expanded) {
  1802. // has children && expanded and drop into the node bottom gap
  1803. // insert to the top 这里我们添加在头部,可以是任意位置
  1804. loop(data, dropKey, item => {
  1805. item.children = item.children || [];
  1806. item.children.unshift(dragObj);
  1807. });
  1808. } else {
  1809. let dropNodeInd;
  1810. let dropNodePosArr;
  1811. loop(data, dropKey, (item, ind, arr) => {
  1812. dropNodePosArr = arr;
  1813. dropNodeInd = ind;
  1814. });
  1815. if (dropPosition === -1) {
  1816. // insert to top
  1817. dropNodePosArr.splice(dropNodeInd, 0, dragObj);
  1818. } else {
  1819. // insert to bottom
  1820. dropNodePosArr.splice(dropNodeInd + 1, 0, dragObj);
  1821. }
  1822. }
  1823. setTreeData(data);
  1824. }
  1825. return (
  1826. <Tree
  1827. treeData={treeData}
  1828. draggable
  1829. //expandedKeys={expandedKeys}
  1830. onDragEnter={onDragEnter}
  1831. onDrop={onDrop}
  1832. />
  1833. );
  1834. };
  1835. export const DraggableTree = () => <DnDTree />;
  1836. DraggableTree.story = {
  1837. name: 'draggable Tree',
  1838. };
  1839. const TestTree = () => {
  1840. return (
  1841. <Tree
  1842. treeData={testData}
  1843. // motion={false}
  1844. style={{ height: '100%' }}
  1845. filterTreeNode
  1846. expandAction="click"
  1847. showFilteredOnly
  1848. />
  1849. );
  1850. };
  1851. export const Draggable = () => <TestTree />;
  1852. Draggable.story = {
  1853. name: 'draggable',
  1854. };
  1855. export const RenderFullLabelWithDraggable = () => {
  1856. const [selected, setSelected] = useState(new Set());
  1857. const [selectedThroughParent, setSelectedThroughParent] = useState(new Set());
  1858. const defaultTreeData = [
  1859. {
  1860. label: '黑色固定按钮',
  1861. key: 'fix-btn-0',
  1862. },
  1863. {
  1864. label: '模块',
  1865. key: 'module-0',
  1866. children: [
  1867. {
  1868. label: '可自由摆放的组件',
  1869. key: 'free-compo-0',
  1870. },
  1871. {
  1872. label: '分栏容器',
  1873. key: 'split-col-0',
  1874. children: [
  1875. {
  1876. label: '按钮组件',
  1877. key: 'btn-0',
  1878. },
  1879. {
  1880. label: '按钮组件',
  1881. key: 'btn-1',
  1882. },
  1883. ],
  1884. },
  1885. ],
  1886. },
  1887. {
  1888. label: '模块',
  1889. key: 'module-1',
  1890. children: [
  1891. {
  1892. label: '自定义组件',
  1893. key: 'cus-0',
  1894. },
  1895. ],
  1896. },
  1897. ];
  1898. const [treeData, setTreeData] = useState(defaultTreeData);
  1899. const onDrop = info => {
  1900. const { dropToGap, node, dragNode } = info;
  1901. const dropKey = node.key;
  1902. const dragKey = dragNode.key;
  1903. const dropPos = node.pos.split('-');
  1904. const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);
  1905. const data = [...treeData];
  1906. const loop = (data, key, callback) => {
  1907. data.forEach((item, ind, arr) => {
  1908. if (item.key === key) return callback(item, ind, arr);
  1909. if (item.children) return loop(item.children, key, callback);
  1910. });
  1911. };
  1912. let dragObj;
  1913. loop(data, dragKey, (item, ind, arr) => {
  1914. arr.splice(ind, 1);
  1915. dragObj = item;
  1916. });
  1917. if (!dropToGap) {
  1918. loop(data, dropKey, (item, ind, arr) => {
  1919. item.children = item.children || [];
  1920. item.children.push(dragObj);
  1921. });
  1922. } else if (dropPosition === 1 && node.children && node.expanded) {
  1923. loop(data, dropKey, item => {
  1924. item.children = item.children || [];
  1925. item.children.unshift(dragObj);
  1926. });
  1927. } else {
  1928. let dropNodeInd;
  1929. let dropNodePosArr;
  1930. loop(data, dropKey, (item, ind, arr) => {
  1931. dropNodePosArr = arr;
  1932. dropNodeInd = ind;
  1933. });
  1934. if (dropPosition === -1) {
  1935. dropNodePosArr.splice(dropNodeInd, 0, dragObj);
  1936. } else {
  1937. dropNodePosArr.splice(dropNodeInd + 1, 0, dragObj);
  1938. }
  1939. }
  1940. setTreeData(data);
  1941. };
  1942. const findDescendantKeys = node => {
  1943. let res = [node.key];
  1944. const findChild = item => {
  1945. if (!item) return;
  1946. const { children } = item;
  1947. if (children && children.length) {
  1948. children.forEach(child => {
  1949. res.push(child.key);
  1950. findChild(child);
  1951. });
  1952. }
  1953. };
  1954. findChild(node);
  1955. return res;
  1956. };
  1957. const handleSelect = (key, bool, node) => {
  1958. setSelected(new Set([key]));
  1959. const descendantKeys = findDescendantKeys(node);
  1960. setSelectedThroughParent(new Set(descendantKeys));
  1961. };
  1962. const renderLabel = ({ className, data, onClick, expandIcon }) => {
  1963. const { label, icon, key } = data;
  1964. const isLeaf = !(data.children && data.children.length);
  1965. const style = {
  1966. backgroundColor: selected.has(key)
  1967. ? 'rgba(var(--semi-blue-0), 1)'
  1968. : selectedThroughParent.has(key)
  1969. ? 'rgba(var(--semi-blue-0), .5)'
  1970. : 'transparent',
  1971. };
  1972. return (
  1973. <li className={className} role="treeitem" onClick={onClick} style={style}>
  1974. {isLeaf ? <span style={{ width: 24 }}></span> : expandIcon}
  1975. {icon ? icon : null}
  1976. <span>{label}</span>
  1977. </li>
  1978. );
  1979. };
  1980. const treeStyle = {
  1981. height: 420,
  1982. border: '1px solid var(--semi-color-border)',
  1983. };
  1984. return (
  1985. <Tree
  1986. treeData={treeData}
  1987. draggable
  1988. onDrop={onDrop}
  1989. renderFullLabel={renderLabel}
  1990. onSelect={handleSelect}
  1991. style={treeStyle}
  1992. defaultExpandAll
  1993. />
  1994. );
  1995. };
  1996. RenderFullLabelWithDraggable.story = {
  1997. name: 'renderFullLabel with draggable',
  1998. };
  1999. export const CheckRelationDemo = () => {
  2000. const treeData = [
  2001. {
  2002. label: 'Asia',
  2003. value: 'Asia',
  2004. key: '0',
  2005. children: [
  2006. {
  2007. label: 'China',
  2008. value: 'China',
  2009. key: '0-0',
  2010. children: [
  2011. {
  2012. label: 'Beijing',
  2013. value: 'Beijing',
  2014. key: '0-0-0',
  2015. },
  2016. {
  2017. label: 'Shanghai',
  2018. value: 'Shanghai',
  2019. key: '0-0-1',
  2020. },
  2021. {
  2022. label: 'Chengdu',
  2023. value: 'Chengdu',
  2024. key: '0-0-2',
  2025. },
  2026. ],
  2027. },
  2028. {
  2029. label: 'Japan',
  2030. value: 'Japan',
  2031. key: '0-1',
  2032. children: [
  2033. {
  2034. label: 'Osaka',
  2035. value: 'Osaka',
  2036. key: '0-1-0'
  2037. }
  2038. ]
  2039. },
  2040. ],
  2041. },
  2042. {
  2043. label: 'North America',
  2044. value: 'North America',
  2045. key: '1',
  2046. children: [
  2047. {
  2048. label: 'United States',
  2049. value: 'United States',
  2050. key: '1-0'
  2051. },
  2052. {
  2053. label: 'Canada',
  2054. value: 'Canada',
  2055. key: '1-1'
  2056. }
  2057. ]
  2058. }
  2059. ];
  2060. const [value, setValue] = useState('China');
  2061. const [value2, setValue2] = useState();
  2062. const [value3, setValue3] = useState();
  2063. const style = {
  2064. width: 260,
  2065. height: 420,
  2066. border: '1px solid var(--semi-color-border)'
  2067. };
  2068. const handleChange = value => {
  2069. console.log(value);
  2070. setValue(value);
  2071. };
  2072. const handleChange2 = value => {
  2073. console.log(value);
  2074. setValue2(value);
  2075. };
  2076. const handleChange3 = value => {
  2077. console.log(value);
  2078. setValue3(value);
  2079. };
  2080. return (
  2081. <>
  2082. <div>checkRelation='unRelated'</div>
  2083. <Tree
  2084. treeData={treeData}
  2085. multiple
  2086. checkRelation='unRelated'
  2087. defaultExpandAll
  2088. style={style}
  2089. />
  2090. <br /><br />
  2091. <div>checkRelation='unRelated' + 中国节点为 disabled</div>
  2092. <Tree
  2093. treeData={treeData1}
  2094. multiple
  2095. checkRelation='unRelated'
  2096. defaultExpandAll
  2097. style={style}
  2098. />
  2099. <br /><br />
  2100. <div>checkRelation='unRelated' + 中国节点为 disabled + 严格禁用</div>
  2101. <Tree
  2102. treeData={treeData1}
  2103. multiple
  2104. checkRelation='unRelated'
  2105. defaultExpandAll
  2106. disableStrictly
  2107. style={style}
  2108. />
  2109. <br /><br />
  2110. <div>checkRelation='unRelated' + defaultValue 为 China</div>
  2111. <Tree
  2112. treeData={treeData}
  2113. multiple
  2114. checkRelation='unRelated'
  2115. defaultExpandAll
  2116. style={style}
  2117. defaultValue='China'
  2118. />
  2119. <br /><br />
  2120. <div>checkRelation='unRelated' + 受控 + value 初始为 China</div>
  2121. <Tree
  2122. treeData={treeData}
  2123. multiple
  2124. checkRelation='unRelated'
  2125. defaultExpandAll
  2126. style={style}
  2127. value={value}
  2128. onChange={handleChange}
  2129. />
  2130. <br /><br />
  2131. <div>checkRelation='unRelated' + 受控 + onChangeWithObject</div>
  2132. <Tree
  2133. treeData={treeData}
  2134. multiple
  2135. checkRelation='unRelated'
  2136. defaultExpandAll
  2137. style={style}
  2138. value={value2}
  2139. onChangeWithObject
  2140. onChange={handleChange2}
  2141. />
  2142. <br /><br />
  2143. <div>checkRelation='unRelated' + 受控 + leafOnly,此时 leafOnly 失效</div>
  2144. <Tree
  2145. leafOnly
  2146. treeData={treeData}
  2147. multiple
  2148. checkRelation='unRelated'
  2149. defaultExpandAll
  2150. style={style}
  2151. value={value3}
  2152. onChange={handleChange3}
  2153. />
  2154. <br /><br />
  2155. <div>checkRelation='unRelated' + onSelect </div>
  2156. <Tree
  2157. treeData={treeData}
  2158. multiple
  2159. checkRelation='unRelated'
  2160. defaultExpandAll
  2161. style={style}
  2162. onSelect={(value,status,node)=>console.log('select', value, status, node)}
  2163. />
  2164. </>
  2165. );
  2166. };