cascader.stories.jsx 64 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632
  1. import React, { useState, useCallback, useEffect, useRef, useMemo } from 'react';
  2. import CustomTrigger from './CustomTrigger';
  3. import { IconChevronDown, IconClose, IconGift, IconTreeTriangleRight } from '@douyinfe/semi-icons';
  4. import { Button, Typography, Toast, Cascader, Checkbox, Input, Tag, TagInput } from '../../index';
  5. const { Text } = Typography;
  6. export default {
  7. title: 'Cascader',
  8. parameters: {
  9. chromatic: { disableSnapshot: true },
  10. },
  11. }
  12. export {
  13. CustomTrigger
  14. };
  15. const treeData1 = [
  16. {
  17. label: 'Node1',
  18. value: '0-0',
  19. children: [
  20. {
  21. label: 'Child Node1',
  22. value: '0-0-1',
  23. disabled: true,
  24. },
  25. {
  26. label: 'Child Node2',
  27. value: '0-0-2',
  28. },
  29. ],
  30. },
  31. {
  32. label: 'Node2',
  33. value: '0-1',
  34. },
  35. ];
  36. const treeData2 = [
  37. {
  38. label: '亚洲',
  39. value: 'yazhou',
  40. children: [
  41. {
  42. label: '中国',
  43. value: 'zhongguo',
  44. children: [
  45. {
  46. label: '北京',
  47. value: 'beijing',
  48. },
  49. {
  50. label: '上海',
  51. value: 'shanghai',
  52. },
  53. ],
  54. },
  55. {
  56. label: '日本',
  57. value: 'riben',
  58. disabled: true,
  59. children: [
  60. {
  61. label: '大阪',
  62. value: 'daban',
  63. },
  64. ],
  65. },
  66. ],
  67. },
  68. {
  69. label: '北美洲',
  70. value: 'beimeizhou',
  71. children: [
  72. {
  73. label: '美国',
  74. value: 'meiguo',
  75. },
  76. {
  77. label: '加拿大',
  78. value: 'jianada',
  79. },
  80. ],
  81. },
  82. ];
  83. const treeData3 = [
  84. {
  85. label: '亚洲',
  86. value: 'yazhou',
  87. children: [
  88. {
  89. label: '中国',
  90. value: 'zhongguo',
  91. children: [
  92. {
  93. label: '北京',
  94. value: 'beijing',
  95. },
  96. {
  97. label: '上海',
  98. value: 'shanghai',
  99. },
  100. ],
  101. },
  102. {
  103. label: '日本',
  104. value: 'riben',
  105. children: [
  106. {
  107. label: '大阪',
  108. value: 'daban',
  109. },
  110. ],
  111. },
  112. ],
  113. },
  114. ];
  115. const treeData4 = [
  116. {
  117. label: '浙江省',
  118. value: 'zhejiang',
  119. children: [
  120. {
  121. label: '杭州市',
  122. value: 'hangzhou',
  123. children: [
  124. {
  125. label: '西湖区',
  126. value: 'xihu',
  127. },
  128. {
  129. label: '萧山区',
  130. value: 'xiaoshan',
  131. },
  132. {
  133. label: '临安区',
  134. value: 'linan',
  135. },
  136. ],
  137. },
  138. {
  139. label: '宁波市',
  140. value: 'ningbo',
  141. children: [
  142. {
  143. label: '海曙区',
  144. value: 'haishu',
  145. },
  146. {
  147. label: '江北区',
  148. value: 'jiangbei',
  149. },
  150. ],
  151. },
  152. ],
  153. },
  154. ];
  155. const treeData5 = [
  156. {
  157. label: 'Node1',
  158. value: '0-0',
  159. children: [
  160. {
  161. label: 'Child Node1',
  162. value: '0-0-1',
  163. },
  164. {
  165. label: 'Child Node2',
  166. value: '0-0-2',
  167. key: '0-0-2',
  168. },
  169. {
  170. label: 'Child Node3',
  171. value: '0-0-3',
  172. },
  173. {
  174. label: 'Child Node4',
  175. value: '0-0-4',
  176. },
  177. {
  178. label: 'Child Node5',
  179. value: '0-0-5',
  180. },
  181. {
  182. label: 'Child Node6',
  183. value: '0-0-6',
  184. },
  185. {
  186. label: 'Child Node7',
  187. value: '0-0-7',
  188. },
  189. {
  190. label: 'Child Node8',
  191. value: '0-0-8',
  192. },
  193. {
  194. label: 'Child Node9',
  195. value: '0-0-9',
  196. },
  197. {
  198. label: 'Child Node10',
  199. value: '0-0-10',
  200. },
  201. ],
  202. },
  203. {
  204. label: 'Node2',
  205. value: '0-1',
  206. },
  207. ];
  208. const treeOrder = [
  209. {
  210. label: '-1',
  211. value: '0-0',
  212. key: '-1',
  213. children: [
  214. {
  215. label: 'Child Node1',
  216. value: '0-0-1',
  217. key: '0-0-1',
  218. },
  219. {
  220. label: 'Child Node2',
  221. value: '0-0-2',
  222. key: '0-0-2',
  223. },
  224. ],
  225. },
  226. {
  227. label: '1',
  228. value: '0-1',
  229. key: '1',
  230. },
  231. ];
  232. const longTreeData = [
  233. {
  234. label: 'udghajsasndanm,',
  235. value: 'A',
  236. children: [
  237. {
  238. label: 'Bsasfads',
  239. value: 'B',
  240. children: [
  241. {
  242. label: 'C',
  243. value: 'C',
  244. children: [
  245. {
  246. label: 'D',
  247. value: 'D',
  248. children: [
  249. {
  250. label: 'E',
  251. value: 'E',
  252. children: [
  253. {
  254. label: 'F',
  255. value: 'F',
  256. }
  257. ]
  258. }
  259. ]
  260. }
  261. ]
  262. }
  263. ],
  264. }
  265. ]
  266. }
  267. ];
  268. const treedataWithNodeLabel = [
  269. {
  270. label: '浙江省',
  271. value: 'zhejiang',
  272. children: [
  273. {
  274. label: '杭州市',
  275. value: 'hangzhou',
  276. children: [
  277. {
  278. label: '西湖市区',
  279. value: 'xihu',
  280. },
  281. {
  282. label: '萧山区',
  283. value: 'xiaoshan',
  284. },
  285. {
  286. label: '临安区',
  287. value: 'linan',
  288. },
  289. ],
  290. },
  291. {
  292. label: <strong>宁波市</strong>,
  293. value: 'ningbo',
  294. children: [
  295. {
  296. label: '海曙区',
  297. value: 'haishu',
  298. },
  299. {
  300. label: '江北区',
  301. value: 'jiangbei',
  302. }
  303. ]
  304. },
  305. ],
  306. }
  307. ];
  308. export const issue703 = () => {
  309. const initialData = [
  310. {
  311. label: 'Node1',
  312. value: '0-0',
  313. },
  314. {
  315. label: 'Node2',
  316. value: '0-1',
  317. },
  318. {
  319. label: 'Node3',
  320. value: '0-2',
  321. isLeaf: true
  322. },
  323. ];
  324. const [data, setData] = useState(initialData);
  325. const updateTreeData = (list, value, children) => {
  326. return list.map(node => {
  327. if (node.value === value) {
  328. return { ...node, children };
  329. }
  330. if (node.children) {
  331. return { ...node, children: updateTreeData(node.children, value, children) };
  332. }
  333. return node;
  334. });
  335. };
  336. const onLoadData = selectedOpt => {
  337. const targetOpt = selectedOpt[selectedOpt.length - 1];
  338. const { label, value } = targetOpt;
  339. return new Promise(resolve => {
  340. if (targetOpt.children) {
  341. resolve();
  342. return;
  343. }
  344. setTimeout(() => {
  345. setData(origin =>
  346. updateTreeData(origin, value, [
  347. {
  348. label: `${label}-1`,
  349. value: `${label}-1`,
  350. isLeaf: selectedOpt.length > 1
  351. },
  352. {
  353. label: `${label}-2`,
  354. value: `${label}-2`,
  355. isLeaf: selectedOpt.length > 1
  356. },
  357. ]),
  358. );
  359. resolve();
  360. }, 1000);
  361. });
  362. };
  363. const [v,setV]=useState([['0-0'], ['0-1', 'Node2-2']]);
  364. useEffect(()=>{
  365. console.log('data change');
  366. setTimeout(()=>setV([['0-0'], ['0-1', 'Node2-2', 'Node2-2-2']]),0);
  367. },[data])
  368. return (
  369. <>
  370. <div>treeData和value动态更新,value中的值在treeData中存在则能够正确显示</div>
  371. <Cascader
  372. multiple
  373. onChange={(a)=>console.log(a)}
  374. value={v}
  375. style={{ width: 300 }}
  376. treeData={data}
  377. loadData={onLoadData}
  378. placeholder="Please select"
  379. />
  380. <div>非受控,动态更新treeData</div>
  381. <Cascader
  382. multiple
  383. onChange={(a)=>console.log(a)}
  384. style={{ width: 300 }}
  385. treeData={data}
  386. loadData={onLoadData}
  387. placeholder="Please select"
  388. />
  389. </>
  390. );
  391. };
  392. export const _Cascader = () => {
  393. return (
  394. <div>
  395. <Cascader
  396. style={{ width: 300 }}
  397. treeData={treeData1}
  398. placeholder="Please select"
  399. motion={false}
  400. />
  401. <br />
  402. <br />
  403. <Cascader
  404. style={{ width: 300 }}
  405. treeData={treeData1}
  406. placeholder="Multiple select"
  407. multiple
  408. motion={false}
  409. />
  410. <br />
  411. <br />
  412. <Cascader
  413. style={{ width: 300 }}
  414. treeData={treeData1}
  415. placeholder="Multiple select enableLeafClick"
  416. multiple
  417. enableLeafClick
  418. motion={false}
  419. />
  420. <br />
  421. <br />
  422. <Cascader
  423. style={{ width: 300 }}
  424. treeData={[]}
  425. motion={false}
  426. placeholder="Please select"
  427. // defaultOpen={true}
  428. />
  429. </div>
  430. );
  431. };
  432. export const ChangeOnSelect = () => {
  433. return (
  434. <div>
  435. <Cascader
  436. style={{ width: 300 }}
  437. treeData={treeData2}
  438. placeholder="Please select"
  439. changeOnSelect={true}
  440. />
  441. </div>
  442. );
  443. };
  444. export const Searchable = () => {
  445. return (
  446. <div>
  447. <Cascader
  448. style={{ width: 300 }}
  449. treeData={treeData2}
  450. placeholder="Please select"
  451. filterTreeNode
  452. motion={false}
  453. />
  454. <br />
  455. <br />
  456. <Cascader
  457. style={{ width: 300 }}
  458. treeData={treeData2}
  459. placeholder="Please select"
  460. filterTreeNode
  461. changeOnSelect
  462. allowHalfPath
  463. />
  464. <br />
  465. <br />
  466. <Cascader
  467. style={{ width: 300 }}
  468. treeData={treeData2}
  469. placeholder="Please select"
  470. filterTreeNode
  471. filterLeafOnly={false}
  472. onChange={e => console.log(e)}
  473. />
  474. <br />
  475. <br />
  476. <div>fix-1449,当 label 为 ReactNode 时,搜索显示结果[object object]</div>
  477. <Cascader
  478. style={{ width: 300 }}
  479. treeData={treedataWithNodeLabel}
  480. placeholder="宁波为 ReactNode"
  481. filterTreeNode
  482. />
  483. <br />
  484. <br />
  485. <div>
  486. filterTreeNode=false,且 label 为 ReactNode
  487. 时,配合displayRender使用,使得回显到input的内容符合预期
  488. </div>
  489. <Cascader
  490. style={{ width: 300 }}
  491. treeData={treedataWithNodeLabel}
  492. placeholder="自定义回填时显示数据的格式"
  493. displayRender={list =>
  494. list.map((v, i) => {
  495. return list.length - 1 === i ? (
  496. <React.Fragment key={i}>{v}</React.Fragment>
  497. ) : (
  498. <React.Fragment key={i}>{v} / </React.Fragment>
  499. );
  500. })
  501. }
  502. defaultValue={['zhejiang', 'ningbo', 'jiangbei']}
  503. />
  504. <br />
  505. <br />
  506. <div>
  507. v2.5 起,filterTreeNode=false,且 label 为 ReactNode
  508. 时,无配合displayRender 使用,回显到input的内容也是符合预期
  509. </div>
  510. <Cascader
  511. style={{ width: 300 }}
  512. treeData={treedataWithNodeLabel}
  513. placeholder="宁波为 ReactNode"
  514. defaultValue={['zhejiang', 'ningbo', 'jiangbei']}
  515. />
  516. </div>
  517. );
  518. };
  519. Searchable.parameters = {
  520. chromatic: { disableSnapshot: false },
  521. }
  522. export const filterTreeNodeAndDisplayRender = () => {
  523. return (
  524. <>
  525. <div>
  526. filterTreeNode=true,配合displayRender 使用,回显到input的内容也是符合预期
  527. </div>
  528. <Cascader
  529. filterTreeNode
  530. style={{ width: 300 }}
  531. treeData={treeData4}
  532. placeholder="自定义回填时显示数据的格式"
  533. defaultValue={['zhejiang', 'ningbo', 'jiangbei']}
  534. displayRender={(item) => {
  535. console.log('item', item);
  536. return <div>
  537. {'已选择:' + item.join(' -> ')}
  538. </div>;}}
  539. />
  540. </>
  541. );
  542. };
  543. export const Disabled = () => {
  544. return (
  545. <div>
  546. <Cascader
  547. style={{ width: 300 }}
  548. treeData={treeData2}
  549. placeholder="Please select"
  550. filterTreeNode
  551. disabled
  552. />
  553. <br /><br />
  554. <Cascader
  555. defaultValue={['yazhou', 'zhongguo']}
  556. style={{ width: 300 }}
  557. treeData={treeData2}
  558. multiple
  559. filterTreeNode
  560. disabled
  561. />
  562. <br /><br />
  563. <Cascader
  564. defaultValue={['yazhou', 'zhongguo']}
  565. style={{ width: 300 }}
  566. treeData={treeData2}
  567. multiple
  568. disabled
  569. />
  570. </div>
  571. );
  572. };
  573. Disabled.parameters = {
  574. chromatic: { disableSnapshot: false },
  575. }
  576. export const DisabledOption = () => {
  577. return (
  578. <div>
  579. <div>common disabled option</div>
  580. <Cascader style={{ width: 300 }} treeData={treeData2} placeholder="Japan node is disabled" />
  581. <br />
  582. <br />
  583. <div>single selection + defaultValue is disabled option + changeOnSelect</div>
  584. <Cascader
  585. style={{ width: 300 }}
  586. treeData={treeData2}
  587. changeOnSelect
  588. defaultValue={['yazhou', 'riben']}
  589. placeholder="Japan node is disabled"
  590. />
  591. <br />
  592. <br />
  593. <div>
  594. single selection + defaultValue is disabled option + changeOnSelect + filterTreeNode
  595. </div>
  596. <Cascader
  597. style={{ width: 300 }}
  598. treeData={treeData2}
  599. changeOnSelect
  600. filterTreeNode
  601. defaultValue={['yazhou', 'riben']}
  602. placeholder="Japan node is disabled"
  603. />
  604. <br />
  605. <br />
  606. <div>multiple selection + defaultValue is disabled option</div>
  607. <Cascader
  608. multiple
  609. filterTreeNode
  610. style={{ width: 300 }}
  611. treeData={treeData2}
  612. defaultValue={['yazhou', 'riben']}
  613. placeholder="Japan node is disabled"
  614. />
  615. <br />
  616. <br />
  617. <div>multiple selection + filterTreeNode + defaultValue is disabled option</div>
  618. <Cascader
  619. filterTreeNode
  620. multiple
  621. style={{ width: 300 }}
  622. treeData={treeData2}
  623. defaultValue={[
  624. ['yazhou', 'riben'],
  625. ['beimeizhou', 'jianada']
  626. ]}
  627. placeholder="Japan node is disabled"
  628. />
  629. </div>
  630. );
  631. };
  632. export const CustomSearch = () => {
  633. return (
  634. <div>
  635. <Cascader
  636. style={{ width: 300 }}
  637. treeData={treeData2}
  638. placeholder="Please select"
  639. filterTreeNode
  640. treeNodeFilterProp="value"
  641. />
  642. </div>
  643. );
  644. };
  645. export const CustomDisplayProp = () => {
  646. return (
  647. <div>
  648. <Cascader
  649. style={{ width: 300 }}
  650. treeData={treeData2}
  651. placeholder="Please select"
  652. changeOnSelect={true}
  653. displayProp="value"
  654. filterTreeNode
  655. />
  656. </div>
  657. );
  658. };
  659. export const DefaultValue = () => {
  660. return (
  661. <div>
  662. <Cascader
  663. style={{ width: 300 }}
  664. treeData={treeData3}
  665. placeholder="Please select"
  666. defaultValue={['yazhou', 'zhongguo', 'shanghai']}
  667. />
  668. <br />
  669. <br />
  670. <Cascader
  671. style={{ width: 300 }}
  672. treeData={treeData3}
  673. placeholder="Please select"
  674. changeOnSelect
  675. defaultValue={['yazhou']}
  676. />
  677. <br />
  678. <br />
  679. <Cascader
  680. style={{ width: 300 }}
  681. treeData={treeData3}
  682. placeholder="Please select"
  683. changeOnSelect
  684. defaultValue={['yazhou', 'zhongguo']}
  685. filterTreeNode
  686. />
  687. <br />
  688. <br />
  689. <Cascader
  690. style={{ width: 300 }}
  691. treeData={treeData3}
  692. placeholder="Please select"
  693. changeOnSelect
  694. defaultValue={'yazhou'}
  695. filterTreeNode
  696. />
  697. <br />
  698. <br />
  699. <Cascader
  700. style={{ width: 300 }}
  701. treeData={treeData3}
  702. placeholder="Please select"
  703. defaultValue={['yazhou', 'zhongguo']}
  704. filterTreeNode
  705. />
  706. </div>
  707. );
  708. };
  709. export const DefaultValueNotExist = () => {
  710. return (
  711. <>
  712. <Cascader
  713. style={{ width: 300 }}
  714. treeData={treeData3}
  715. placeholder="Please select"
  716. changeOnSelect
  717. defaultValue={'yazhou not exist'}
  718. filterTreeNode
  719. />
  720. <br />
  721. <br />
  722. <Cascader
  723. style={{ width: 300 }}
  724. treeData={treeData3}
  725. placeholder="Please select"
  726. defaultValue={'tokyo not exist'}
  727. />
  728. </>
  729. );
  730. };
  731. class ControlledDemo extends React.Component {
  732. constructor() {
  733. super();
  734. this.state = {
  735. value: [],
  736. };
  737. }
  738. onChange(value) {
  739. this.setState({ value });
  740. }
  741. render() {
  742. const treeData = [
  743. {
  744. label: '浙江省',
  745. value: 'zhejiang',
  746. children: [
  747. {
  748. label: '杭州市',
  749. value: 'hangzhou',
  750. children: [
  751. {
  752. label: '西湖区',
  753. value: 'xihu',
  754. },
  755. {
  756. label: '萧山区',
  757. value: 'xiaoshan',
  758. },
  759. {
  760. label: '临安区',
  761. value: 'linan',
  762. },
  763. ],
  764. },
  765. {
  766. label: '宁波市',
  767. value: 'ningbo',
  768. children: [
  769. {
  770. label: '海曙区',
  771. value: 'haishu',
  772. },
  773. {
  774. label: '江北区',
  775. value: 'jiangbei',
  776. },
  777. ],
  778. },
  779. ],
  780. },
  781. ];
  782. return (
  783. <Cascader
  784. multiple
  785. style={{ width: 300 }}
  786. treeData={treeData}
  787. placeholder="请选择所在地区"
  788. value={this.state.value}
  789. changeOnSelect
  790. filterTreeNode
  791. onChangeWithObject
  792. onChange={e => this.onChange(e)}
  793. />
  794. );
  795. }
  796. }
  797. export const ControlledComponent = () => <ControlledDemo />;
  798. export const CascaderOrderTest = () => {
  799. return (
  800. <div>
  801. <Cascader style={{ width: 300 }} treeData={treeOrder} placeholder="Please select" />
  802. </div>
  803. );
  804. };
  805. export const OnFocusAndOnBlur = () => {
  806. return (
  807. <div>
  808. <Cascader
  809. style={{ width: 300 }}
  810. treeData={treeData1}
  811. placeholder="Please select"
  812. onFocus={(val, e) => console.log('focus', e, val)}
  813. onBlur={(val, e) => console.log('blur', e, val)}
  814. />
  815. </div>
  816. );
  817. };
  818. export const ShowClear = () => {
  819. return (
  820. <div>
  821. <Cascader
  822. style={{ marginLeft: 700, width: 300 }}
  823. treeData={treeData1}
  824. placeholder="Please select"
  825. showClear
  826. filterTreeNode
  827. />
  828. <br />
  829. <br />
  830. <Cascader
  831. style={{ marginLeft: 700, width: 300 }}
  832. treeData={treeData1}
  833. placeholder="Please select when multiple"
  834. multiple
  835. showClear
  836. />
  837. <br />
  838. <br />
  839. <div style={{ marginLeft: 700 }}>
  840. <p>有用户反馈,超长列表点击 showClear 后,dropdown错位。1.30.0-beta.1 fixed</p>
  841. <Cascader
  842. style={{ width: 300 }}
  843. treeData={longTreeData}
  844. placeholder="Please select"
  845. showClear
  846. />
  847. </div>
  848. </div>
  849. );
  850. };
  851. const LoadDataDemo = () => {
  852. const initialData = [
  853. {
  854. label: 'Node1',
  855. value: '0-0',
  856. },
  857. {
  858. label: 'Node2',
  859. value: '0-1',
  860. },
  861. {
  862. label: 'Node3',
  863. value: '0-2',
  864. isLeaf: true,
  865. },
  866. ];
  867. const [data, setData] = useState(initialData);
  868. const updateTreeData = (list, value, children) => {
  869. return list.map(node => {
  870. if (node.value === value) {
  871. return { ...node, children };
  872. }
  873. if (node.children) {
  874. return { ...node, children: updateTreeData(node.children, value, children) };
  875. }
  876. return node;
  877. });
  878. };
  879. const onLoadData = selectedOpt => {
  880. const targetOpt = selectedOpt[selectedOpt.length - 1];
  881. const { label, value } = targetOpt;
  882. return new Promise(resolve => {
  883. if (targetOpt.children) {
  884. resolve();
  885. return;
  886. }
  887. setTimeout(() => {
  888. setData(origin =>
  889. updateTreeData(origin, value, [
  890. {
  891. label: `${label} - 1`,
  892. value: `${label}-1`,
  893. isLeaf: selectedOpt.length > 1,
  894. },
  895. {
  896. label: `${label} - 2`,
  897. value: `${label}-2`,
  898. isLeaf: selectedOpt.length > 1,
  899. },
  900. ])
  901. );
  902. resolve();
  903. }, 1000);
  904. });
  905. };
  906. return (
  907. <Cascader
  908. style={{ width: 300 }}
  909. treeData={data}
  910. loadData={onLoadData}
  911. onChangeWithSelect
  912. placeholder="Please select"
  913. />
  914. );
  915. };
  916. const LoadDataWithReset = () => {
  917. const initialData = [
  918. {
  919. label: 'Node1',
  920. value: '0-0',
  921. },
  922. {
  923. label: 'Node2',
  924. value: '0-1',
  925. },
  926. {
  927. label: 'Node3',
  928. value: '0-2',
  929. isLeaf: true,
  930. },
  931. ];
  932. const [data, setData] = useState(initialData);
  933. const [value, setValue] = useState([]);
  934. const updateTreeData = (list, value, children) => {
  935. return list.map(node => {
  936. if (node.value === value) {
  937. return { ...node, children };
  938. }
  939. if (node.children) {
  940. return { ...node, children: updateTreeData(node.children, value, children) };
  941. }
  942. return node;
  943. });
  944. };
  945. const onLoadData = selectedOpt => {
  946. const targetOpt = selectedOpt[selectedOpt.length - 1];
  947. const { label, value } = targetOpt;
  948. return new Promise(resolve => {
  949. if (targetOpt.children) {
  950. resolve();
  951. return;
  952. }
  953. setTimeout(() => {
  954. setData(origin =>
  955. updateTreeData(origin, value, [
  956. {
  957. label: `${label} - 1`,
  958. value: `${label}-1`,
  959. isLeaf: selectedOpt.length > 1,
  960. },
  961. {
  962. label: `${label} - 2`,
  963. value: `${label}-2`,
  964. isLeaf: selectedOpt.length > 1,
  965. },
  966. ])
  967. );
  968. resolve();
  969. }, 1000);
  970. });
  971. };
  972. return (
  973. <>
  974. <Cascader
  975. style={{ width: 300 }}
  976. treeData={data}
  977. loadData={onLoadData}
  978. value={value}
  979. onChangeWithObject
  980. changeOnSelect
  981. onChange={setValue}
  982. placeholder="Please select"
  983. />
  984. <Button onClick={() => setValue([])}>重置</Button>
  985. </>
  986. );
  987. };
  988. export const LoadData = () => (
  989. <>
  990. <LoadDataDemo />
  991. <br />
  992. <br />
  993. <div>fix:1448,重置失效</div>
  994. <LoadDataWithReset />
  995. </>
  996. );
  997. export const DynamicPlaceholder = () => {
  998. const [isSelect, setSelect] = useState(false);
  999. return (
  1000. <>
  1001. <Button onClick={() => setSelect(!isSelect)}>Toggle</Button>
  1002. <Cascader
  1003. style={{ width: 300 }}
  1004. treeData={treeData2}
  1005. placeholder="Please select"
  1006. searchPlaceholder="Search something"
  1007. filterTreeNode={isSelect}
  1008. showClear
  1009. />
  1010. </>
  1011. );
  1012. };
  1013. export const FixDedupOnSelect = () => {
  1014. return (
  1015. <div>
  1016. <Cascader
  1017. style={{ width: 300 }}
  1018. treeData={treeData2}
  1019. placeholder="Please select"
  1020. onSelect={v => console.log(v)}
  1021. />
  1022. <Cascader
  1023. style={{ width: 300 }}
  1024. treeData={treeData2}
  1025. placeholder="Please select"
  1026. onSelect={v => console.log(v)}
  1027. dedupOnSelect={false}
  1028. />
  1029. </div>
  1030. );
  1031. };
  1032. const slotStyle = {
  1033. height: '36px',
  1034. display: 'flex',
  1035. padding: '0 32px',
  1036. alignItems: 'center',
  1037. cursor: 'pointer',
  1038. borderRadius: '0 0 6px 6px',
  1039. };
  1040. export const CascaderWithSlot = () => {
  1041. return (
  1042. <div>
  1043. <Cascader
  1044. style={{ width: 300 }}
  1045. treeData={treeData2}
  1046. placeholder="请选择所在地区"
  1047. topSlot={<Text style={slotStyle}>选择地区</Text>}
  1048. bottomSlot={
  1049. <div style={slotStyle}>
  1050. <Text>找不到相关选项?</Text>
  1051. <Text link>去新建</Text>
  1052. </div>
  1053. }
  1054. />
  1055. </div>
  1056. );
  1057. };
  1058. export const CascaderWithMaxTagCountShowRestTagsPopoverRestTagsPopoverProps = () => {
  1059. return (
  1060. <div>
  1061. <Cascader
  1062. style={{ width: 300 }}
  1063. treeData={treeData4}
  1064. placeholder="请选择所在地区"
  1065. multiple
  1066. maxTagCount={1}
  1067. showRestTagsPopover
  1068. restTagsPopoverProps={{ position: 'bottom' }}
  1069. defaultValue={[
  1070. ['zhejiang', 'ningbo', 'haishu'],
  1071. ['zhejiang', 'hangzhou', 'xihu'],
  1072. ]}
  1073. />
  1074. </div>
  1075. );
  1076. };
  1077. CascaderWithMaxTagCountShowRestTagsPopoverRestTagsPopoverProps.story = {
  1078. name: 'Cascader with maxTagCount/showRestTagsPopover/restTagsPopoverProps',
  1079. };
  1080. CascaderWithMaxTagCountShowRestTagsPopoverRestTagsPopoverProps.parameters = {
  1081. chromatic: { disableSnapshot: false },
  1082. }
  1083. export const CascaderWithShowNext = () => {
  1084. return (
  1085. <div>
  1086. <Cascader
  1087. style={{ width: 300 }}
  1088. treeData={treeData4}
  1089. placeholder="请选择所在地区"
  1090. showNext="hover"
  1091. />
  1092. </div>
  1093. );
  1094. };
  1095. export const CascaderWithMaxOnExceed = () => {
  1096. return (
  1097. <div>
  1098. <div>普通情况</div>
  1099. <Cascader
  1100. style={{ width: 300 }}
  1101. treeData={treeData4}
  1102. placeholder="请选择所在地区"
  1103. multiple
  1104. max={1}
  1105. onExceed={v => {
  1106. Toast.warning('exceed max');
  1107. console.log(v);
  1108. }}
  1109. defaultValue={['zhejiang', 'ningbo', 'haishu']}
  1110. />
  1111. <br />
  1112. <br />
  1113. <div>defaultValue的数量超过max,则只允许减少到合法,不允许再增加</div>
  1114. <Cascader
  1115. style={{ width: 300 }}
  1116. treeData={treeData4}
  1117. placeholder="请选择所在地区"
  1118. multiple
  1119. max={1}
  1120. onExceed={v => {
  1121. Toast.warning('exceed max');
  1122. console.log(v);
  1123. }}
  1124. defaultValue={[
  1125. ['zhejiang', 'ningbo', 'haishu'],
  1126. ['zhejiang', 'hangzhou', 'xihu'],
  1127. ]}
  1128. />
  1129. <br />
  1130. <br />
  1131. <div>autoMergeValue=false时的情况</div>
  1132. <Cascader
  1133. style={{ width: 300 }}
  1134. treeData={treeData4}
  1135. placeholder="请选择所在地区"
  1136. multiple
  1137. max={2}
  1138. autoMergeValue={false}
  1139. onExceed={v => {
  1140. Toast.warning('exceed max');
  1141. console.log(v);
  1142. }}
  1143. defaultValue={[
  1144. ['zhejiang', 'ningbo', 'haishu'],
  1145. ['zhejiang', 'hangzhou', 'xihu'],
  1146. ]}
  1147. />
  1148. </div>
  1149. );
  1150. };
  1151. CascaderWithMaxOnExceed.story = {
  1152. name: 'Cascader with max/onExceed',
  1153. };
  1154. CascaderWithMaxOnExceed.parameters = {
  1155. chromatic: { disableSnapshot: false },
  1156. }
  1157. const ControlledLoadDataWithDefaultValue = () => {
  1158. const [v, setV] = useState('受控 Value');
  1159. const initialData = [
  1160. {
  1161. label: 'Node1',
  1162. value: '0-0',
  1163. },
  1164. {
  1165. label: 'Node2',
  1166. value: '0-1',
  1167. },
  1168. {
  1169. label: 'Node3',
  1170. value: '0-2',
  1171. isLeaf: true,
  1172. },
  1173. ];
  1174. const [data, setData] = useState(initialData);
  1175. const updateTreeData = (list, value, children) => {
  1176. return list.map(node => {
  1177. if (node.value === value) {
  1178. return { ...node, children };
  1179. }
  1180. if (node.children) {
  1181. return { ...node, children: updateTreeData(node.children, value, children) };
  1182. }
  1183. return node;
  1184. });
  1185. };
  1186. const onLoadData = selectedOpt => {
  1187. const targetOpt = selectedOpt[selectedOpt.length - 1];
  1188. const { label, value } = targetOpt;
  1189. return new Promise(resolve => {
  1190. if (targetOpt.children) {
  1191. resolve();
  1192. return;
  1193. }
  1194. setTimeout(() => {
  1195. setData(origin =>
  1196. updateTreeData(origin, value, [
  1197. {
  1198. label: `${label} - 1`,
  1199. value: `${label}-1`,
  1200. isLeaf: selectedOpt.length > 1,
  1201. },
  1202. {
  1203. label: `${label} - 2`,
  1204. value: `${label}-2`,
  1205. isLeaf: selectedOpt.length > 1,
  1206. },
  1207. ])
  1208. );
  1209. resolve();
  1210. }, 1000);
  1211. });
  1212. };
  1213. return (
  1214. <Cascader
  1215. defaultValue="123"
  1216. value={v}
  1217. onChange={v => setV(v)}
  1218. style={{ width: 300 }}
  1219. treeData={data}
  1220. loadData={onLoadData}
  1221. placeholder="Please select"
  1222. />
  1223. );
  1224. };
  1225. const LoadDataWithDefaultValue = () => {
  1226. const initialData = [
  1227. {
  1228. label: 'Node1',
  1229. value: '0-0',
  1230. },
  1231. {
  1232. label: 'Node2',
  1233. value: '0-1',
  1234. },
  1235. {
  1236. label: 'Node3',
  1237. value: '0-2',
  1238. isLeaf: true,
  1239. },
  1240. ];
  1241. const [data, setData] = useState(initialData);
  1242. const updateTreeData = (list, value, children) => {
  1243. return list.map(node => {
  1244. if (node.value === value) {
  1245. return { ...node, children };
  1246. }
  1247. if (node.children) {
  1248. return { ...node, children: updateTreeData(node.children, value, children) };
  1249. }
  1250. return node;
  1251. });
  1252. };
  1253. const onLoadData = selectedOpt => {
  1254. const targetOpt = selectedOpt[selectedOpt.length - 1];
  1255. const { label, value } = targetOpt;
  1256. return new Promise(resolve => {
  1257. if (targetOpt.children) {
  1258. resolve();
  1259. return;
  1260. }
  1261. setTimeout(() => {
  1262. setData(origin =>
  1263. updateTreeData(origin, value, [
  1264. {
  1265. label: `${label} - 1`,
  1266. value: `${label}-1`,
  1267. isLeaf: selectedOpt.length > 1,
  1268. },
  1269. {
  1270. label: `${label} - 2`,
  1271. value: `${label}-2`,
  1272. isLeaf: selectedOpt.length > 1,
  1273. },
  1274. ])
  1275. );
  1276. resolve();
  1277. }, 1000);
  1278. });
  1279. };
  1280. return (
  1281. <Cascader
  1282. defaultValue="defaultValue"
  1283. style={{ width: 300 }}
  1284. treeData={data}
  1285. loadData={onLoadData}
  1286. showClear
  1287. placeholder="Please select"
  1288. />
  1289. );
  1290. };
  1291. export const LoadDataWithDefaultValueDemo = () => {
  1292. return (
  1293. <div>
  1294. <div>fix-1429,检查defaultValue在异步时是否有异常</div>
  1295. <ControlledLoadDataWithDefaultValue />
  1296. <br />
  1297. <br />
  1298. <LoadDataWithDefaultValue />
  1299. </div>
  1300. );
  1301. };
  1302. LoadDataWithDefaultValueDemo.parameters = {
  1303. chromatic: { disableSnapshot: false },
  1304. }
  1305. export const OnChangeWithObject = () => (
  1306. <>
  1307. <div>单选 + onChangeWithObject + defaultValue 为 string []</div>
  1308. <Cascader
  1309. onChangeWithObject
  1310. style={{ width: 300 }}
  1311. treeData={treeData4}
  1312. placeholder="请选择所在地区"
  1313. defaultValue={['zhejiang', 'hangzhou', 'xihu']}
  1314. />
  1315. <br />
  1316. <br />
  1317. <div>多选 + onChangeWithObject + defaultValue 为 string []</div>
  1318. <Cascader
  1319. multiple
  1320. changeOnSelect
  1321. onChangeWithObject
  1322. style={{ width: 300 }}
  1323. treeData={treeData4}
  1324. placeholder="请选择所在地区"
  1325. defaultValue={'zhejiang'}
  1326. />
  1327. <br />
  1328. <br />
  1329. <div>单选 + onChangeWithObject + defaultValue 为 object []</div>
  1330. <Cascader
  1331. onChangeWithObject
  1332. changeOnSelect
  1333. style={{ width: 300 }}
  1334. treeData={treeData2}
  1335. placeholder="请选择所在地区"
  1336. defaultValue={{
  1337. label: '北美洲',
  1338. value: 'beimeizhou',
  1339. children: [
  1340. {
  1341. label: '美国',
  1342. value: 'meiguo',
  1343. },
  1344. {
  1345. label: '加拿大',
  1346. value: 'jianada',
  1347. },
  1348. ],
  1349. }}
  1350. />
  1351. <br />
  1352. <br />
  1353. <div>多选 + onChangeWithObject + defaultValue 为 object []</div>
  1354. <Cascader
  1355. multiple
  1356. onChangeWithObject
  1357. style={{ width: 300 }}
  1358. treeData={treeData2}
  1359. placeholder="请选择所在地区"
  1360. defaultValue={{
  1361. label: '北美洲',
  1362. value: 'beimeizhou',
  1363. children: [
  1364. {
  1365. label: '美国',
  1366. value: 'meiguo',
  1367. },
  1368. {
  1369. label: '加拿大',
  1370. value: 'jianada',
  1371. },
  1372. ],
  1373. }}
  1374. />
  1375. </>
  1376. );
  1377. export const undefinedValueWhileMutipleAndOnChangeWithObject = () => {
  1378. const [value, setValue] = useState(undefined);
  1379. return (
  1380. <>
  1381. <div>多选 + onChangeWithObject + value 为 undefined</div>
  1382. <Cascader
  1383. multiple
  1384. onChangeWithObject
  1385. style={{ width: 300 }}
  1386. treeData={treeData2}
  1387. placeholder="请选择所在地区"
  1388. value={value}
  1389. onChange={(v)=>{
  1390. setValue(v);
  1391. }}
  1392. />
  1393. </>
  1394. )
  1395. }
  1396. export const LeafOnly = () => {
  1397. const [value, setValue] = useState([])
  1398. return (
  1399. <div>
  1400. <div>autoMergeValue=false,leafOnly=false</div>
  1401. <Cascader
  1402. style={{ width: 300 }}
  1403. treeData={treeData4}
  1404. placeholder="请选择所在地区"
  1405. multiple
  1406. autoMergeValue={false}
  1407. leafOnly={false}
  1408. defaultValue={['zhejiang']}
  1409. />
  1410. <br />
  1411. <br />
  1412. <div>autoMergeValue=false,leafOnly=true, leafOnly生效</div>
  1413. <Cascader
  1414. style={{ width: 300 }}
  1415. treeData={treeData4}
  1416. placeholder="请选择所在地区"
  1417. multiple
  1418. autoMergeValue={false}
  1419. leafOnly={true}
  1420. defaultValue={['zhejiang']}
  1421. />
  1422. <br />
  1423. <br />
  1424. <div>受控,autoMergeValue=false,leafOnly=true, leafOnly生效</div>
  1425. <Cascader
  1426. style={{ width: 300 }}
  1427. treeData={treeData4}
  1428. placeholder="请选择所在地区"
  1429. multiple
  1430. onChange={v=>{
  1431. console.log(v);
  1432. setValue(v)
  1433. }}
  1434. autoMergeValue={false}
  1435. leafOnly={true}
  1436. value={value}
  1437. />
  1438. <br />
  1439. <br />
  1440. <div>受控 onChangeWithObject, autoMergeValue=false,leafOnly=true, leafOnly生效</div>
  1441. <Cascader
  1442. style={{ width: 300 }}
  1443. treeData={treeData4}
  1444. placeholder="请选择所在地区"
  1445. multiple
  1446. onChange={v=>{
  1447. console.log(v);
  1448. setValue(v)
  1449. }}
  1450. onChangeWithObject
  1451. autoMergeValue={false}
  1452. leafOnly={true}
  1453. value={value}
  1454. />
  1455. <br />
  1456. <br />
  1457. <div>autoMergeValue=true,leafOnly=false</div>
  1458. <Cascader
  1459. style={{ width: 300 }}
  1460. treeData={treeData4}
  1461. placeholder="请选择所在地区"
  1462. multiple
  1463. autoMergeValue={true}
  1464. leafOnly={false}
  1465. defaultValue={['zhejiang']}
  1466. />
  1467. <br />
  1468. <br />
  1469. <br />
  1470. <div>autoMergeValue=true,leafOnly=true</div>
  1471. <Cascader
  1472. style={{ width: 300 }}
  1473. treeData={treeData4}
  1474. placeholder="请选择所在地区"
  1475. multiple
  1476. autoMergeValue={true}
  1477. leafOnly={true}
  1478. defaultValue={['zhejiang']}
  1479. />
  1480. </div>
  1481. );
  1482. }
  1483. export const DynamicTreeData = () => {
  1484. const [treeDataDemo1,setTreeData1]=useState(treeData2);
  1485. const [treeDataDemo2,setTreeData2]=useState(treeData2);
  1486. const [treeDataDemo3,setTreeData3]=useState(treeData2);
  1487. const [treeDataDemo4,setTreeData4]=useState(treeData2);
  1488. const [treeDataDemo5,setTreeData5]=useState(treeData2);
  1489. const [value3,setValue3]=useState();
  1490. const [value4,setValue4]=useState();
  1491. return (
  1492. <div>
  1493. <div>多选 + 动态更新 tree</div>
  1494. <Cascader
  1495. style={{ width: 300 }}
  1496. treeData={treeDataDemo1}
  1497. multiple
  1498. placeholder="请选择所在地区"
  1499. />
  1500. <Button onClick={()=>{setTreeData1(treeData3)}}>改变treeData</Button>
  1501. <br />
  1502. <br />
  1503. <div>单选 + 动态更新 tree</div>
  1504. <Cascader
  1505. style={{ width: 300 }}
  1506. treeData={treeDataDemo2}
  1507. placeholder="请选择所在地区"
  1508. />
  1509. <Button onClick={()=>{setTreeData2(treeData3)}}>改变treeData</Button>
  1510. <br />
  1511. <br />
  1512. <div>多选 + 动态更新 tree + 受控</div>
  1513. <Cascader
  1514. style={{ width: 300 }}
  1515. treeData={treeDataDemo3}
  1516. multiple
  1517. value={value3}
  1518. onChange={v=>{
  1519. console.log(v);
  1520. setValue3(v);
  1521. }}
  1522. placeholder="请选择所在地区"
  1523. />
  1524. <Button onClick={()=>{setTreeData3(treeData3)}}>改变treeData</Button>
  1525. <br />
  1526. <br />
  1527. <div>单选 + 动态更新 tree + 受控</div>
  1528. <Cascader
  1529. style={{ width: 300 }}
  1530. treeData={treeDataDemo4}
  1531. value={value4}
  1532. onChange={v=>{
  1533. console.log(v);
  1534. setValue4(v);
  1535. }}
  1536. placeholder="请选择所在地区"
  1537. />
  1538. <Button onClick={()=>{setTreeData4(treeData3)}}>改变treeData</Button>
  1539. <br />
  1540. <br />
  1541. <div>多选 + 动态更新 tree + defaultValue 为亚洲</div>
  1542. <Cascader
  1543. style={{ width: 300 }}
  1544. treeData={treeDataDemo5}
  1545. multiple
  1546. defaultValue='yazhou'
  1547. placeholder="请选择所在地区"
  1548. />
  1549. <Button onClick={()=>{setTreeData5(treeData3)}}>改变treeData</Button>
  1550. <br />
  1551. <br />
  1552. </div>
  1553. );
  1554. }
  1555. export const SuperLongList = () => {
  1556. let treeData = new Array(100).fill().map((item, index) => ({ label: `浙江省${index}`, value: `zhejiang${index}` }));
  1557. treeData.push({ label: '到底啦', value: 'bottom' })
  1558. return (
  1559. <Cascader
  1560. style={{ width: 300 }}
  1561. treeData={treeData}
  1562. placeholder="请选择所在地区"
  1563. onListScroll={()=>{console.log(123)}}
  1564. />
  1565. );
  1566. };
  1567. export const size = () => {
  1568. const props = {
  1569. // defaultValue: [
  1570. // ["0-0","0-0-1"],["0-0","0-0-2"],["0-0","0-0-3"],["0-0","0-0-4"],["0-0","0-0-5"],
  1571. // ["0-0","0-0-6"],["0-0","0-0-7"],["0-0","0-0-8"],["0-0","0-0-9"]
  1572. // ],
  1573. defaultValue: [["0-0","0-0-9"]
  1574. ],
  1575. style: { width: 300 },
  1576. treeData: treeData5,
  1577. multiple: true,
  1578. filterTreeNode: true,
  1579. leafOnly: true,
  1580. };
  1581. return (<>
  1582. <Cascader {...props} size={'small'} />
  1583. <br/><br/>
  1584. <Cascader {...props} size={'default'} />
  1585. <br/><br/>
  1586. <Cascader {...props} size={'large'}/>
  1587. </>);
  1588. }
  1589. export const filterSorter = () => {
  1590. const treeData = [
  1591. {
  1592. label: 'Product',
  1593. value: 'Product',
  1594. children: [
  1595. {
  1596. label: 'Semi-Material',
  1597. value: 'Semi-Material',
  1598. },
  1599. {
  1600. label: 'Semi-DSM',
  1601. value: 'Semi-DSM',
  1602. },
  1603. {
  1604. label: 'Semi',
  1605. value: 'Semi',
  1606. },
  1607. {
  1608. label: 'Semi-C2D',
  1609. value: 'Semi-C2D',
  1610. },
  1611. {
  1612. label: 'Semi-D2C',
  1613. value: 'Semi-D2C',
  1614. },
  1615. ],
  1616. }
  1617. ];
  1618. return (
  1619. <div>
  1620. <Cascader
  1621. style={{ width: 300 }}
  1622. treeData={treeData}
  1623. placeholder="输入 s 查看排序效果"
  1624. filterTreeNode
  1625. filterSorter={(first, second, inputValue) => {
  1626. const firstData = first[first.length - 1];
  1627. const lastData = second[second.length - 1];
  1628. if (firstData.label === inputValue) {
  1629. return -1;
  1630. } else if (lastData.label === inputValue) {
  1631. return 1;
  1632. } else {
  1633. return firstData.label < lastData.label ? -1 : 1;
  1634. }
  1635. }}
  1636. />
  1637. </div>
  1638. );
  1639. };
  1640. export const filterRender = () => {
  1641. const treeData = [
  1642. {
  1643. label: 'Semi',
  1644. value: 'Semi',
  1645. children: [
  1646. {
  1647. label: 'Semi-Material Semi-Material Semi-Material Semi-Material',
  1648. value: 'Semi-Material',
  1649. },
  1650. {
  1651. label: 'Semi-DSM Semi-DSM Semi-DSM Semi-DSM',
  1652. value: 'Semi-DSM',
  1653. },
  1654. {
  1655. label: 'Semi Design Semi Design Semi Design Semi Design',
  1656. value: 'Semi',
  1657. },
  1658. {
  1659. label: 'Semi-C2D Semi-C2D Semi-C2D Semi-C2D Semi-C2D',
  1660. value: 'Semi-C2D',
  1661. },
  1662. {
  1663. label: 'Semi-D2C Semi-D2C Semi-D2C Semi-D2C Semi-D2C ',
  1664. value: 'Semi-D2C',
  1665. },
  1666. ],
  1667. }
  1668. ];
  1669. const renderSearchOptionSingle = (props) => {
  1670. const {
  1671. className,
  1672. data,
  1673. onClick,
  1674. selected,
  1675. } = props;
  1676. return (
  1677. <li
  1678. className={className}
  1679. style={{justifyContent: 'flex-start'}}
  1680. role="treeitem"
  1681. onClick={onClick}
  1682. >
  1683. <Text
  1684. ellipsis={{ showTooltip: { opts: { style: { wordBreak: 'break-all'} }}}}
  1685. style={{ width: 270, color: selected ? 'var(--semi-color-primary)': undefined }}
  1686. >
  1687. {data.map(item => item.label ).join(' / ')}
  1688. </Text>
  1689. </li>
  1690. )
  1691. }
  1692. const renderSearchOptionMultiple = (props) => {
  1693. const {
  1694. className,
  1695. data,
  1696. checkStatus,
  1697. onCheck,
  1698. } = props;
  1699. return (
  1700. <li
  1701. className={className}
  1702. style={{justifyContent: 'flex-start'}}
  1703. role="treeitem"
  1704. onClick={onCheck}
  1705. >
  1706. <Checkbox
  1707. onChange={onCheck}
  1708. indeterminate={checkStatus.halfChecked}
  1709. checked={checkStatus.checked}
  1710. style={{ marginRight: 8 }}
  1711. />
  1712. <Text
  1713. ellipsis={{ showTooltip: { opts: { style: { wordBreak: 'break-all'} }}}}
  1714. style={{ width: 270 }}
  1715. >
  1716. {data.map(item => item.label).join(' / ')}
  1717. </Text>
  1718. </li>
  1719. )
  1720. }
  1721. return (
  1722. <div>
  1723. <p>鼠标 hover 到选项可查看被省略文本完整内容</p>
  1724. <br />
  1725. <Cascader
  1726. style={{ width: 300 }}
  1727. treeData={treeData}
  1728. placeholder="单选,自定义搜索选项渲染"
  1729. filterTreeNode
  1730. filterRender={renderSearchOptionSingle}
  1731. />
  1732. <br />
  1733. <Cascader
  1734. multiple
  1735. style={{ width: 300, marginTop: 20 }}
  1736. treeData={treeData}
  1737. placeholder="多选,自定义搜索选项渲染"
  1738. filterTreeNode
  1739. filterRender={renderSearchOptionMultiple}
  1740. />
  1741. </div>
  1742. );
  1743. };
  1744. export const RefMethods = () => {
  1745. const cRef = useRef(null);
  1746. const onClickOpen = useCallback(() => {
  1747. cRef.current.open();
  1748. }, [cRef]);
  1749. const onClickClose = useCallback(() => {
  1750. cRef.current.close();
  1751. }, [cRef]);
  1752. const onClickFocus = useCallback(() => {
  1753. cRef.current.focus();
  1754. }, [cRef]);
  1755. const onClickBlur = useCallback(() => {
  1756. cRef.current.blur();
  1757. }, [cRef]);
  1758. const treeData = [
  1759. {
  1760. label: '浙江省',
  1761. value: 'zhejiang',
  1762. children: [
  1763. {
  1764. label: '杭州市',
  1765. value: 'hangzhou',
  1766. children: [
  1767. {
  1768. label: '西湖区',
  1769. value: 'xihu',
  1770. },
  1771. {
  1772. label: '萧山区',
  1773. value: 'xiaoshan',
  1774. },
  1775. {
  1776. label: <div onClick={onClickClose}> click to hide</div>,
  1777. value: 'linan',
  1778. },
  1779. ],
  1780. },
  1781. ],
  1782. }
  1783. ];
  1784. return (
  1785. <div>
  1786. <Button onClick={onClickOpen}> cascader visible</Button>
  1787. <br /><br />
  1788. <Button onClick={onClickClose}> cascader hidden</Button>
  1789. <br /><br />
  1790. <Button onClick={onClickFocus}> cascader focusable</Button>
  1791. <br /><br />
  1792. <Button onClick={onClickBlur}> cascader blur</Button>
  1793. <br /><br />
  1794. <Cascader
  1795. multiple
  1796. ref={cRef}
  1797. style={{ width: 300 }}
  1798. treeData={treeData}
  1799. placeholder="单选"
  1800. />
  1801. </div>
  1802. );
  1803. };
  1804. export const FixCursorPositionError = () => {
  1805. // https://github.com/DouyinFE/semi-design/issues/1468
  1806. const props = {
  1807. style: { width: 300 },
  1808. treeData: treeData5,
  1809. filterTreeNode: true,
  1810. leafOnly: true,
  1811. };
  1812. const multipleProps = { ...props, multiple: true };
  1813. return (<>
  1814. <p>多选</p>
  1815. <Cascader {...multipleProps} size={'small'} />
  1816. <br/><br/>
  1817. <Cascader {...multipleProps} size={'default'} />
  1818. <br/><br/>
  1819. <Cascader {...multipleProps} size={'large'}/>
  1820. <p>单选</p>
  1821. <Cascader {...props} size={'small'} />
  1822. <br/><br/>
  1823. <Cascader {...props} size={'default'} />
  1824. <br/><br/>
  1825. <Cascader {...props} size={'large'}/>
  1826. </>);
  1827. }
  1828. export const setValueInSearch = () => {
  1829. const treeData = [
  1830. {
  1831. label: '浙江省',
  1832. text: '杭州市',
  1833. value: 'zhejiang',
  1834. children: [
  1835. {
  1836. label: <div>杭州市</div>,
  1837. text: '杭州市',
  1838. value: 'hangzhou',
  1839. children: [
  1840. {
  1841. label: <div>西湖区</div>,
  1842. text: '西湖区',
  1843. value: 'xihu',
  1844. },
  1845. {
  1846. label: <div>萧山区</div>,
  1847. text: '萧山区',
  1848. value: 'xiaoshan',
  1849. },
  1850. {
  1851. label: <div>临安区</div>,
  1852. text: '临安区',
  1853. value: 'linan',
  1854. },
  1855. ],
  1856. },
  1857. {
  1858. label: '宁波市',
  1859. text: '宁波市',
  1860. value: 'ningbo',
  1861. children: [
  1862. {
  1863. label: '海曙区',
  1864. text: '海曙区',
  1865. value: 'haishu',
  1866. },
  1867. {
  1868. label: '江北区',
  1869. text: '江北区',
  1870. value: 'jiangbei',
  1871. }
  1872. ]
  1873. },
  1874. ],
  1875. }
  1876. ];
  1877. const [value, setValue] = useState(['zhejiang', 'hangzhou', 'xiaoshan']);
  1878. const handleMouseIn = () => setValue(['zhejiang', 'hangzhou', 'xihu']);
  1879. return (
  1880. <div>
  1881. {/* 关联issue,https://github.com/DouyinFE/semi-design/issues/1472 */}
  1882. <span id={"mouseIn"} onMouseEnter={handleMouseIn}>changeValueWhenMouseIn</span>
  1883. <Cascader
  1884. value={value}
  1885. style={{ width: 300 }}
  1886. treeData={treeData}
  1887. placeholder="默认对label值进行搜索"
  1888. filterTreeNode
  1889. treeNodeFilterProp='text'
  1890. displayProp='text'
  1891. displayRender={(names) => {
  1892. console.log('names', names)
  1893. return names.join("--");
  1894. }}
  1895. />
  1896. </div>
  1897. );
  1898. }
  1899. export const TriggerAddMethods = () => {
  1900. const treeData = useMemo(() => [
  1901. {
  1902. label: '浙江省',
  1903. value: 'zhejiang',
  1904. children: [
  1905. {
  1906. label: '杭州市',
  1907. value: 'hangzhou',
  1908. children: [
  1909. {
  1910. label: '西湖区',
  1911. value: 'xihu',
  1912. },
  1913. {
  1914. label: '萧山区',
  1915. value: 'xiaoshan',
  1916. },
  1917. {
  1918. label: '临安区',
  1919. value: 'linan',
  1920. },
  1921. ],
  1922. },
  1923. {
  1924. label: '宁波市',
  1925. value: 'ningbo',
  1926. children: [
  1927. {
  1928. label: '海曙区',
  1929. value: 'haishu',
  1930. },
  1931. {
  1932. label: '江北区',
  1933. value: 'jiangbei',
  1934. }
  1935. ]
  1936. },
  1937. ],
  1938. }
  1939. ], []);
  1940. const closeIcon = useCallback((value, onClear) => {
  1941. return value ? <IconClose onClick={onClear} /> : <IconChevronDown />;
  1942. }, []);
  1943. const triggerRenderSingle = ({ value, placeholder, onClear, ...rest }) => {
  1944. return (
  1945. <Button theme={'light'} icon={closeIcon(value, onClear)} iconPosition={'right'}>
  1946. {value && value.length > 0 ? getLabelFromValue(value) : placeholder}
  1947. </Button>
  1948. );
  1949. };
  1950. const getLabelFromValue = useCallback((value) => {
  1951. const valueArr = value.split('-').map(item => Number(item));
  1952. let resultData = treeData;
  1953. valueArr.forEach((item, index) => {
  1954. resultData = index === 0 ? resultData[item] : resultData.children[item];
  1955. });
  1956. return resultData.label;
  1957. }, [treeData]);
  1958. const triggerRenderMultiple = useCallback((props) => {
  1959. const { value, onSearch, onRemove } = props;
  1960. const onCloseTag = (value, e, tagKey) => {
  1961. onRemove(tagKey);
  1962. };
  1963. const renderTagItem = (value) => {
  1964. const label = getLabelFromValue(value);
  1965. return <Tag tagKey={value} key={value} closable onClose={onCloseTag} style={{ marginLeft: 2 }}>{label}</Tag>
  1966. };
  1967. return (
  1968. <TagInput
  1969. value={Array.from(value)}
  1970. onInputChange={onSearch}
  1971. renderTagItem={renderTagItem}
  1972. />
  1973. );
  1974. }, []);
  1975. return (
  1976. <>
  1977. <Cascader
  1978. treeData={treeData}
  1979. placeholder='Custom Trigger'
  1980. triggerRender={triggerRenderSingle}
  1981. />
  1982. <br />
  1983. <Cascader
  1984. triggerRender={triggerRenderMultiple}
  1985. multiple
  1986. filterTreeNode
  1987. treeData={treeData}
  1988. style={{ width: 300 }}
  1989. placeholder='Custom Trigger'
  1990. />
  1991. </>
  1992. );
  1993. }
  1994. export const DisabledAndPlusN = () => {
  1995. const commonProps = {
  1996. multiple: true,
  1997. maxTagCount: 1,
  1998. showRestTagsPopover: true,
  1999. disabled: true,
  2000. style: { width: 300 },
  2001. treeData: treeData4,
  2002. placeholder: "请选择所在地区",
  2003. defaultValue: [
  2004. ['zhejiang', 'ningbo', 'haishu'],
  2005. ['zhejiang', 'hangzhou', 'xihu']
  2006. ]
  2007. }
  2008. return (
  2009. <>
  2010. <span>disabled + maxTagCount + showRestTagsPopover</span><br /><br />
  2011. <Cascader {...commonProps} />
  2012. <br /><br />
  2013. <span>disabled + filterTreeNode + maxTagCount + showRestTagsPopover</span><br /><br />
  2014. <Cascader {...commonProps} filterTreeNode/>
  2015. </>
  2016. )
  2017. }
  2018. export const VirtualizeInSearch = () => {
  2019. const treeData = useMemo(() => (
  2020. ['通用', '场景'].map((label, m) => ({
  2021. label: label,
  2022. value: m,
  2023. children: new Array(100).fill(0).map((item, n)=> ({
  2024. value: `${m}-${n}`,
  2025. label: `${m}-${n} 第二级`,
  2026. children: new Array(20).fill(0).map((item, o)=> ({
  2027. value: `${m}-${n}-${o}`,
  2028. label: `${m}-${n}-${o} 第三级详细内容`,
  2029. })),
  2030. }))
  2031. }))
  2032. ), []);
  2033. let virtualize = {
  2034. // 高度为面板默认高度为 180px 减去上下padding 2 * 8px
  2035. height: 172,
  2036. width: 320,
  2037. itemSize: 36,
  2038. };
  2039. const filterRender = useCallback((props) => {
  2040. const { data, onCheck, checkStatus, className } = props;
  2041. return (
  2042. <div
  2043. key={data.value}
  2044. className={className}
  2045. style={{ justifyContent: 'start', padding: '8px 16px 8px 12px', boxSizing: 'border-box' }}
  2046. >
  2047. <Checkbox
  2048. onChange={onCheck}
  2049. indeterminate={checkStatus.halfChecked}
  2050. checked={checkStatus.checked}
  2051. style={{ marginRight: 8 }}
  2052. />
  2053. <Typography.Text
  2054. ellipsis={{ showTooltip: { opts: { style: { wordBreak: 'break-all' } } } }}
  2055. style={{ maxWidth: 260 }}
  2056. >
  2057. {data.map(item => item.label).join(' | ')}
  2058. </Typography.Text>
  2059. </div>
  2060. );
  2061. }, []);
  2062. return (
  2063. <Cascader
  2064. multiple
  2065. filterTreeNode
  2066. style={{ width: 320 }}
  2067. treeData={treeData}
  2068. placeholder="输入 通用 or 场景 进行搜索"
  2069. virtualizeInSearch={virtualize}
  2070. filterRender={filterRender}
  2071. />
  2072. );
  2073. };
  2074. function generateOptions(arr, level, frontKey) {
  2075. const realLevel = level ?? 0;
  2076. const notLeaf = realLevel !== arr.length - 1;
  2077. const realFrontKey = frontKey ? `${frontKey}-` : '';
  2078. return new Array(arr[realLevel])
  2079. .fill(0)
  2080. .map((_item, index) => {
  2081. const data = {
  2082. label: `label-${realFrontKey}${index}`,
  2083. value: `value-${realFrontKey}${index}`,
  2084. };
  2085. if (notLeaf) {
  2086. data.children = generateOptions(
  2087. arr,
  2088. realLevel + 1,
  2089. `${realFrontKey}${index}`,
  2090. );
  2091. }
  2092. return data;
  2093. });
  2094. }
  2095. export const LeafOnlyPF = () => {
  2096. const treeData = useMemo(() => {
  2097. return generateOptions([4, 10, 10, 10]);
  2098. }, []);
  2099. return (
  2100. <Cascader
  2101. multiple
  2102. leafOnly
  2103. maxTagCount={4}
  2104. treeData={treeData}
  2105. style={{ width: 200 }}
  2106. />
  2107. );
  2108. };
  2109. export const SearchPF = () => {
  2110. const treeData = useMemo(() => {
  2111. return generateOptions([4, 10, 10, 10]);
  2112. }, []);
  2113. return (
  2114. <Cascader
  2115. filterTreeNode
  2116. multiple
  2117. leafOnly
  2118. maxTagCount={4}
  2119. treeData={treeData}
  2120. style={{ width: 200 }}
  2121. />
  2122. );
  2123. };
  2124. export const ControlledPF = () => {
  2125. const [cValue, setCValue] = useState([]);
  2126. const onCascaderChange = useCallback(value => {
  2127. // console.log('cValue', value);
  2128. setCValue(value);
  2129. }, []);
  2130. const treeData = useMemo(() => {
  2131. return generateOptions([4, 10, 10, 10, 10]);
  2132. }, []);
  2133. return (
  2134. <Cascader
  2135. value={cValue}
  2136. onChange={onCascaderChange}
  2137. filterTreeNode
  2138. leafOnly
  2139. multiple
  2140. maxTagCount={4}
  2141. treeData={treeData}
  2142. style={{ width: 200 }}
  2143. />
  2144. )
  2145. }
  2146. export const AutoMergeFalse = () => {
  2147. const [value, setValue] = useState([]);
  2148. const onChange = value => {
  2149. console.log(value);
  2150. setValue(value);
  2151. };
  2152. const treeData = [
  2153. {
  2154. label: '浙江省',
  2155. value: 'zhejiang',
  2156. children: [
  2157. {
  2158. label: '杭州市',
  2159. value: 'hangzhou',
  2160. children: [
  2161. {
  2162. label: '西湖区',
  2163. value: 'xihu',
  2164. },
  2165. {
  2166. label: '萧山区',
  2167. value: 'xiaoshan',
  2168. },
  2169. {
  2170. label: '临安区',
  2171. value: 'linan',
  2172. },
  2173. ],
  2174. },
  2175. {
  2176. label: '宁波市',
  2177. value: 'ningbo',
  2178. children: [
  2179. {
  2180. label: '海曙区',
  2181. value: 'haishu',
  2182. },
  2183. {
  2184. label: '江北区',
  2185. value: 'jiangbei',
  2186. }
  2187. ]
  2188. },
  2189. ],
  2190. }
  2191. ];
  2192. return (
  2193. <Cascader
  2194. style={{ width: 300 }}
  2195. treeData={treeData}
  2196. placeholder="autoMergeValue 为 false"
  2197. value={value}
  2198. multiple
  2199. autoMergeValue={false}
  2200. onChange={e => onChange(e)}
  2201. />
  2202. );
  2203. }
  2204. export const NumberValue = () => {
  2205. const [value, setValue] = useState([[ 39 ]]);
  2206. const onChange = useCallback((val) => {
  2207. console.log('onChange', val);
  2208. setValue(val);
  2209. }, []);
  2210. const treeData = useMemo(() => [
  2211. {
  2212. "label": "奖励",
  2213. "value": 2,
  2214. "children": [
  2215. {
  2216. "label": "短期项目激励",
  2217. "value": 3
  2218. },
  2219. {
  2220. "label": "专项激励",
  2221. "value": 8
  2222. }
  2223. ]
  2224. },
  2225. {
  2226. "label": "补结",
  2227. "value": 39,
  2228. "children": []
  2229. },
  2230. {
  2231. "label": "补扣",
  2232. "value": 40,
  2233. "children": [
  2234. {
  2235. "label": "A",
  2236. "value": 100
  2237. }
  2238. ]
  2239. }
  2240. ]);
  2241. return (
  2242. <Cascader
  2243. multiple
  2244. onChange={onChange}
  2245. value={value}
  2246. style={{ width: 300 }}
  2247. treeData={treeData}
  2248. placeholder="请选择所在地区"
  2249. />
  2250. );
  2251. };
  2252. export const SearchInTopSlot = () => {
  2253. const cascaderRef = useRef();
  2254. const handleInputChange = useCallback((value) => {
  2255. cascaderRef.current.search(value);
  2256. }, [cascaderRef]);
  2257. const topSlot = useMemo(() => {
  2258. return <Input prefix="搜索" onChange={handleInputChange} style={{width: '100%'}}/>
  2259. }, [handleInputChange]);
  2260. return (
  2261. <Cascader
  2262. filterTreeNode
  2263. searchPosition={"custom"}
  2264. ref={cascaderRef}
  2265. style={{ width: 300 }}
  2266. treeData={treeData2}
  2267. topSlot={topSlot}
  2268. placeholder="请选择所在地区"
  2269. />
  2270. );
  2271. }
  2272. export const EmptyContent = () => {
  2273. return (
  2274. <>
  2275. <Cascader
  2276. emptyContent={null}
  2277. style={{ width: 400 }}
  2278. treeData={[]}
  2279. placeholder="点击 trigger 查看 emptyContent 为 null 效果 "
  2280. filterTreeNode
  2281. />
  2282. <br /><br />
  2283. <Cascader
  2284. emptyContent={null}
  2285. style={{ width: 400 }}
  2286. treeData={treeData1}
  2287. placeholder="输入 v 查看搜索状态下 emptyContent 为 null 效果"
  2288. filterTreeNode
  2289. />
  2290. <br /><br />
  2291. <Cascader
  2292. style={{ width: 400 }}
  2293. treeData={[]}
  2294. placeholder="点击 trigger 查看默认 emptyContent 效果"
  2295. filterTreeNode
  2296. />
  2297. </>)
  2298. }
  2299. export const CustomExpandIcon = () => {
  2300. const expandIcon = <IconTreeTriangleRight style={{ color: 'var(--semi-color-text-1)'}} />
  2301. return (
  2302. <>
  2303. <Cascader
  2304. expandIcon={expandIcon}
  2305. style={{ width: 400 }}
  2306. treeData={treeData2}
  2307. placeholder="custom expandIcon"
  2308. filterTreeNode
  2309. />
  2310. </>
  2311. );
  2312. }
  2313. export const UnRelated = () => {
  2314. const [value, setValue] = useState([
  2315. [ "yazhou" ],
  2316. [ "beimeizhou", "meiguo"],
  2317. ]);
  2318. const onChange = useCallback((value) => {
  2319. setValue(value);
  2320. }, [])
  2321. const onSelect = useCallback((value) => {
  2322. console.log('onSelect', value);
  2323. }, [])
  2324. return (
  2325. <Cascader
  2326. style={{ width: 400 }}
  2327. treeData={treeData2}
  2328. value={value}
  2329. filterTreeNode
  2330. multiple
  2331. checkRelation='unRelated'
  2332. onChange={onChange}
  2333. onSelect={onSelect}
  2334. />
  2335. )
  2336. }
  2337. export const PlaceHolderChange = () => {
  2338. const [p, setP] = useState('please select');
  2339. const onButtonClick = useCallback(() => {
  2340. const random = Math.floor(Math.random() * 100 % 10);
  2341. setP(`please select ${random}`)
  2342. }, []);
  2343. return (
  2344. <div>
  2345. <Button onClick={onButtonClick}>Click me change placeholder</Button>
  2346. <br /><br />
  2347. <Cascader
  2348. style={{ width: 300 }}
  2349. treeData={treeData2}
  2350. // placeholder={p}
  2351. searchPlaceholder={p}
  2352. filterTreeNode
  2353. motion={false}
  2354. multiple
  2355. showClear
  2356. />
  2357. </div>
  2358. )
  2359. }
  2360. export const PrefixSuffix = () => {
  2361. return (
  2362. <>
  2363. <Cascader
  2364. prefix={<IconGift />}
  2365. suffix={<IconGift />}
  2366. style={{ width: 300 }}
  2367. treeData={treeData1}
  2368. placeholder="请选择所在地区"
  2369. />
  2370. <br /><br />
  2371. <Cascader
  2372. prefix={"Prefix"}
  2373. suffix={"Prefix"}
  2374. style={{ width: 300 }}
  2375. treeData={treeData2}
  2376. placeholder="请选择所在地区"
  2377. filterTreeNode
  2378. />
  2379. </>
  2380. )
  2381. }
  2382. export const Fixed2831 = () => {
  2383. const [value, setValue] = useState(undefined);
  2384. const [productAndBusinessData, setProductAndBusinessData] = useState([
  2385. {
  2386. label: 'TCS Manager',
  2387. value: 'TCS Manager',
  2388. children: [
  2389. {
  2390. label: '0',
  2391. value: '0',
  2392. },
  2393. {
  2394. label: '1',
  2395. value: '1',
  2396. },
  2397. {
  2398. label: '2',
  2399. value: '2',
  2400. },
  2401. {
  2402. label: '3',
  2403. value: '3',
  2404. },
  2405. ],
  2406. },
  2407. {
  2408. label: 'AAA Manager',
  2409. value: 'AAA Manager',
  2410. children: [
  2411. {
  2412. label: '4',
  2413. value: '4',
  2414. },
  2415. {
  2416. label: '5',
  2417. value: '5',
  2418. },
  2419. {
  2420. label: '6',
  2421. value: '6',
  2422. },
  2423. {
  2424. label: '7',
  2425. value: '7',
  2426. },
  2427. ],
  2428. },
  2429. ]);
  2430. return (
  2431. <Cascader
  2432. value={value}
  2433. field="ss"
  2434. placeholder={('tcs_manager_business_info')}
  2435. treeData={productAndBusinessData}
  2436. showNext="hover"
  2437. changeOnSelect
  2438. showClear
  2439. autoAdjustOverflow={false}
  2440. onChange={(value) => {setValue(value)}}
  2441. loadData={selectedOpt => {
  2442. if (!selectedOpt) {
  2443. return Promise.resolve();
  2444. }
  2445. const targetOpt = selectedOpt[selectedOpt.length - 1];
  2446. const { value } = targetOpt;
  2447. if (!value) {
  2448. return Promise.resolve();
  2449. }
  2450. return new Promise( (res) => {
  2451. setTimeout(() => {
  2452. setProductAndBusinessData(origin => {
  2453. const newData = origin.map(i => {
  2454. const children = (i.children || []).map((j, jIndex) => {
  2455. if (j.children || j.value !== value) {
  2456. return { ...j };
  2457. }
  2458. const subChildren = Array.from({ length: 5 }).map((i, index) => ({
  2459. label: jIndex + '' + index,
  2460. value: jIndex + '' + index,
  2461. disabled: false,
  2462. isLeaf: true,
  2463. }));
  2464. return { ...j, children: subChildren };
  2465. });
  2466. return { ...i, children };
  2467. });
  2468. return newData;
  2469. });
  2470. res();
  2471. }, 2000);
  2472. });
  2473. }}
  2474. />
  2475. );
  2476. }
  2477. export const Fixed2967 = () => {
  2478. const data = [
  2479. { label: '这是一个超长的用于测试的选项', value: '1' },
  2480. ]
  2481. return (
  2482. <Cascader
  2483. multiple
  2484. filterTreeNode
  2485. defaultValue={['1']}
  2486. style={{ width: 200 }}
  2487. treeData={data}
  2488. placeholder="请选择所在地区"
  2489. />
  2490. )
  2491. }