treeSelect.stories.jsx 55 KB

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